Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Conklin E.K.Forth programmer's handbook.2000.pdf
Скачиваний:
321
Добавлен:
23.08.2013
Размер:
2.04 Mб
Скачать

Forth Programmer’s Handbook

Dictionary searches, Section 4.1.3

IMMEDIATE, Section 4.4.1

Input number conversion, Section 4.1.4

Interrupts, Section 5.11

4.3.4 Use of Literals and Constants in : Definitions

When the Forth compiler encounters a number in a : definition, the number is converted to binary and is compiled as a literal. The compiled form of a literal in a : definition has two parts: the number itself, and a reference to code which, when executed, will push the number onto the stack. When Forth is compiling a definition and a number is encountered, this form is automatically compiled. There are other ways in which a literal in a definition may be generated (discussed in the following section), but this is the most common situation.

On many systems, the size of a literal is optimized by the compiler (for example, a literal less than 256 will be compiled as a byte).

Because a literal requires both an in-line number and a reference to run-time code for it, it usually is larger than a CONSTANT, which needs only the reference. Therefore, a generic number that will be used frequently (e.g., more than six times) should be defined as a CONSTANT to save space. There is not much difference between the time required to execute a CONSTANT and a literal. Numbers which have specific meanings (e.g., 86400 CONSTANT SECONDS/DAY) should always be defined as CONSTANTs for program readability.

References Explicit literals, Section 4.3.5

Literal addresses, Section 4.3.6

4.3.5 Explicit Literals

The word LITERAL compiles into a definition the number that was placed on the stack at compile time. When the definition is executed, that number will be pushed onto the stack. The compiled result of LITERAL is identical to that of a literal number, described in the previous section. LITERAL is useful for compiling a reference to an address or to a number that may be computed at compile time.

154 The Forth Interpreter and Compiler

Forth Programmer’s Handbook

A common usage of [ and ] (leaving and entering compiling state) combined with LITERAL is to compile the results of complex calculations that only need to be performed once. As a trivial example, disk status information might be stored in the third cell of an array of disk data named DISK. A word to retrieve that information could be:

 

 

 

: STATUS

[ DISK 2 CELLS + ]

LITERAL @ ;

 

 

 

The [ stops compilation, and ] restarts compilation. During this hiatus, the

 

 

 

words DISK 2 CELLS + are interpreted and executed, leaving on the stack the

 

 

 

address of the status cell, which, after compilation resumes, is compiled into

 

 

 

the definition by LITERAL. If the calculations are in an inner loop, time sav-

 

 

 

ings can be large compared to performing them at run time.

 

 

 

The word 2LITERAL functions exactly the same as LITERAL but requires two

 

 

 

values on the stack at compile time and will return those values, in the same

 

 

 

order on the stack, at execution time.

 

 

 

 

SLITERAL is for use with strings. This word requires an address and length of

 

 

 

a string on the stack at compile time. The string is compiled into the definition

 

 

 

and, at execution time, SLITERAL returns the address where the string was

 

 

 

compiled and its length. See Section 4.3.7 below for a fuller description.

 

 

 

 

 

 

Glossary

 

 

 

 

LITERAL

 

( — x )

Core

 

 

 

At compile time, remove the number that is on top of the stack and compile it

 

 

 

into the current definition. At run time, return the number to the stack.

2LITERAL

 

( — x1 x2 )

Double

 

 

 

At compile time, remove the top two items on the stack and compile them into

 

 

 

the current definition. At run time, return the items to the stack in the same

 

 

 

order. “two-literal”

 

 

 

 

 

[ and ], Section 4.3.3

 

References

 

 

 

 

Compilation of literals, Section 4.3.4

 

The Forth Interpreter and Compiler 155

Forth Programmer’s Handbook

4.3.6 Use of ['] to Compile Literal Addresses

The word ['] (“bracket-tick”) is used inside a definition to compile as a literal the execution token of the word that follows it at compile time. The most common use of ['] is to obtain the address of either a CONSTANT or a 2CONSTANT (on systems that have the 32-bit option or on 32-bit machines). Consider the following example:

0 500 2CONSTANT LIMITS

: RANGE ( d -- ) ['] LIMITS >BODY 2! ;

Given these definitions, the phrase:

0 2000 RANGE

resets the values of LIMITS to zero and 2000. The address of the beginning of the double-precision parameter field for LIMITS is compiled as a literal in RANGE and is pushed onto the stack when RANGE is executed, to provide the address for 2!.

References ['], Section 4.1.3

4.3.7 Compiling Strings

Forth provides two methods for compiling strings. The most generally useful word is S" (pronounced “s-quote”). It compiles a string, using a quotation mark as a delimiter, and stores it in the dictionary. When the word containing this string is executed, the address and length of the string are pushed on the stack.

A similar word, C", compiles a counted string (compiled with its count in the first byte, a common practice in Forth). At execution time, C" returns the address of the length byte. Therefore, frequently it is useful to use COUNT to fetch the address of the first byte of the string and the string’s length.

For example, consider a word ?NO that compares a data string—whose address and length are on the stack—to a string that is compiled as part of the definition of ?NO, and returns true if they match:

: ?NO ( addr n -- flag)

C" no" COUNT COMPARE ;

156 The Forth Interpreter and Compiler

Forth Programmer’s Handbook

?NO takes the address and length of an input string. When ?NO is executed, C" will push the address of a compiled counted string on the stack. COUNT converts that address to a string address and length, leaving the appropriate arguments for COMPARE (which performs the comparison).

Here is a word which will search for a compiled string in a longer string whose address and count are on the stack:

: ?DUCK (

addr

n -- flag)

S" duck"

SEARCH

NIP

NIP ;

 

The NIPs discard the address and character count where the match (may have) occurred.

In cases similar to the examples above, you might need to allow the test string to contain an arbitrary mixture of upperand lower-case characters. If so, you should set or clear the appropriate bit in each byte of the test string, to standardize on all upper or all lower case, before making your comparison.

SLITERAL is the low-level compiling word used by S", C", and similar stringhandling words. Just as LITERAL compiles into a definition the number found on the stack at compile time, and returns that number at execution time, SLITERAL compiles into a definition a string, characterized by an address and length on the stack at compile time, and returns the string’s address and length at execution time. The address at compile time is not the same as the address at execution time—the former typically is an address in the input buffer, and the latter is an address connected with the definition using SLITERAL.

Consider how you might define the word S" to begin compiling a string, which will be terminated by a second quote, and which will leave the string’s address and count on the stack at execution time. It could be used as follows:

: ALARM-MESSAGE

S" Too Hot!" TYPE ;

A possible definition for S" would be:

: S" [CHAR] " WORD COUNT POSTPONE SLITERAL ; IMMEDIATE

When S" executes (which is at compile time, since it is marked IMMEDIATE), the phrase [CHAR] " returns the ASCII value for the quote character, which is passed to WORD for use as the delimiter. WORD parses the input stream and returns the address of a counted string in the input buffer consisting of all the

The Forth Interpreter and Compiler 157

Соседние файлы в предмете Электротехника