**** STACK MANIPULATION **** DUP n -- n n 79 "dupe" Duplicate n. DROP n -- 79 n is removed from the stack. SWAP n1 n2 -- n2 n1 79 The top two stack entries are exchanged. OVER n1 n2 -- n1 n2 n1 79 The second stack item is copied to the top. ROT n1 n2 n3 --- n2 n3 n1 79 "rote" The top three stack entries are rotated, bringing the deepest to the top. PICK n1 -- n2 83 n2 is a copy of the +n1th stack value, not counting +n1 itself. +n1 must be between 0 and the number of elements on the stack-1 inclusive. 0 PICK is equivalent to DUP 1 PICK is equivalent to OVER Note: For readability's sake, the use of PICK should be minimized. ROLL n -- 83 The +nth stack value, not counting +n itself is first removed and then transferred to the top of the stack, moving the remaining values into the vacated position. +n must be between 0 and the number of elements on the stack-1, inclusive. 2 ROLL is equivalent to ROT 1 ROLL is equivalent to SWAP 0 ROLL is a null operation Note: For readability's sake, the use of ROLL should be minimized. ?DUP n -- n n 79 "question-dupe" or 0 -- 0 Duplicate n if it is non-zero. >R n -- C,79 "to-r" Transfers n from the data stack to the return stack. See: "Return Stack" R> -- n C,79 "r-from" n is removed from the return stack and transferred to the data stack. See: "Return Stack" R@ -- n C,79 "r-fetch" n is a copy of the top of the return stack. DEPTH -- +n 79 +n is the number of entries contained in the data stack before +n was placed on the stack. SP@ -- addr 79 "s-p-fetch" addr is the address of the top of the data stack just before SP@ was executed. **** COMPARISON **** < n1 n2 -- flag 83 "less-than" flag is true if n1 is less than n2. n1 and n2 are signed integers, so if n1 is negative and n2 is positive, n1 n2 < returns true. = n1 n2 -- flag 83 "equals" flag is true if n1 is equal to n2. > n1 n2 -- flag 83 "greater-than" flag is true if n1 is greater than n2, using signed comparison. 0< n -- flag 83 "zero-less" flag is true if n is less than zero (negative). 0= n -- flag 83 "zero-equals" flag is true if n is zero. 0> n -- flag 83 "zero-greater" flag is true if n is greater than zero. U< u1 u2 -- flag 83 "u-less-than" flag is true if u1 < u2 where u1 and u2 are treated as unsigned integers. **** ARITHMETIC **** 1+ n1 -- n2 79 "one-plus" n2 is the result of adding one to n1 according to the operation of + . 1- n1 -- n2 79 "one-minus" n2 is the result of subtracting one from n1 according to the operation of - . 2+ n1 -- n2 79 "two-plus" n2 is the result of adding two to n1 according to the operation of + . Note: This should not be used to increment a pointer to a "normal" length item, since that is not portable to 32 bit machines. Use NA1+ instead. 2- n1 -- n2 79 "two-minus" n2 is the result of subtracting two from n1 according to the operation of - . Note: This should not be used to decrement a pointer to a "normal" length item, since that is not portable to 32 bit machines. Use the phrase "/N -" instead. 2* n1 -- n2 83 "two-times" n2 is the result of shifting n1 left one bit. A zero is shifted into the vacated bit position. Note: This should not be used to convert an index into an offset, since that is not portable to 32 bit machines. Use the phrase "/N *" instead. 2/ n1 -- n2 83 "two-divide" n2 is the result of arithmetically shifting n1 right one bit. The sign is included in the shift and remains unchanged. + n1 n2 -- n3 79 "plus" n3 is the arithmetic sum of n1 plus n2. - n1 n2 -- n3 79 "minus" n3 is the result of subtracting n2 from n1. * n1 n2 -- n3 79 "times" n3 is the arithmetic product of n1 times n2. If the result cannot be represented in one stack entry, the least significant bits are kept. / n1 n2 -- n3 83 "divide" n3 is the floor of the quotient (n1 divided by the divisor n2). An error condition results if the divisor is zero. See: "division, floored" MOD n1 n2 -- n3 83 n3 is the remainder after dividing n1 by the divisor n2. n3 has the same sign as n2 or is zero. An error condition results if the divisor is zero. See: "division, floored" /MOD n1 n2 -- n3 n4 83 "divide-mod" n3 is the remainder and n4 the floor of the quotient of n1 divided by the divsor n2. n3 has the same sign as n2 or is zero. An error condition results if the divisor is zero. */ n1 n2 n3 -- n4 n1 is first multiplied by n2 producing an intermediate 32-bit result. n4 is the floor of the quotient of the intermediate 32-bit result divided by the divisor n3. The product of n1 times n2 is maintained as an intermediate 32-bit result for greater precision than the otherwise equivalent sequence: n1 n2 * n3 / . An error condition results if the divisor is zero or if the quotient falls outside of the range {-32768..32767}. See: "division, floored" Implementation note: Regardless of the size of a stack item (16 or 32 bits), this operation is always carried out using 16-bits times 16-bits gives 32-bits divided by 16-bits gives 16-bits. If greater range is desired on the 32 bit system, use separate * and / . This is a feature, not a bug. This operation is very efficient on the 68000, so you can use this word for scaling and know that it will run very fast. Full 32 bit arithmetic is at least an order of magnitude slower. */MOD n1 n2 n3 -- n4 n5 83 n1 is first multiplied by n2 producing an intermediate 32-bit result. n4 is the remainder and n5 is the floor of the quotient of the intermediate 32-bit result divided by the divisor n3. A 32-bit intermediate product is used as for */ . n4 has the same sign as n3 or is zero. An error condition results if the divisor is zero or if the quotient falls outside of the range {-32768..32767}. See: "division, floored" Implementation note: Regardless of the size of a stack item (16 or 32 bits), this operation is always carried out using 16-bits times 16-bits gives 32-bits divided by 16-bits gives 16-bits. If greater range is desired on the 32 bit system, use separate * and /MOD . This is a feature, not a bug. This operation is very efficient on the 68000, so you can use this word for scaling and know that it will run very fast. Full 32 bit arithmetic is at least an order of magnitude slower. U* u1 u2 -- ul3 Local "u-times" Perform an unsigned multiplication of u1 by u2, leaving the 32 bit unsigned product ul3. All values are unsigned. MAX n1 n2 -- n3 79 "max" n3 is the greater of n1 and n2 according to the operation of > . MIN n1 n2 -- n3 79 "min" n3 is the lesser of n1 and n2 according to the operation of < . ABS n -- u 79 "absolute" u is the absolute value of n. If n is the maximum negative number, u is the same value (since the maximum negative number in two's complement notation has no positive equivalent). NEGATE n1 -- n2 79 n2 is the two's complement of n1, i.e., the difference of zero less n1. This is the same as the (ones complement of n1) plus 1. **** LOGICAL OPERATORS **** AND n1 n2 -- n3 79 n3 is the bit-by-bit logical 'and' of n1 with n2. OR n1 n2 -- n3 n3 is the bit-by-bit inclusive-or of n1 with n2. XOR n1 n2 -- n3 79 "x-or" n3 is the bit-by-bit exclusive-or of n1 with n2. NOT n1 -- n2 83 n2 is the ones complement of n1 **** MEMORY REFERENCE **** @ addr -- n "fetch" n is the value at address addr. The size of the item fetched is "normal", that is the same width as the data stack. ! n addr -- 79 "store" n is stored at address as a "normal" (a "normal" is the same width as the data stack) C@ addr -- n 79 "c-fetch" n is the contents of the byte at address addr (with the higher bits of the "normal" length stack entry padded with zeroes). C! n -- addr 79 "c-store" The least significant 8 bits of n are stored at addr. +! n addr -- 79 "plus-store" n is added to the "normal" length value at addr using the convention for + . This sum replaces the original value at addr. **** Byte Array Manipulation **** CMOVE addr1 addr2 u -- 79 "c-move" Move the u bytes at address addr1 to addr2. The byte at addr1 is moved first, proceeding toward high memory. If u is zero nothing is moved. If addr1 < addr2 < (addr1+u) the data will be corrupted because the first few bytes of the destination (addr2) range are part of the source (addr1) range. CMOVE> may be used in this case to prevent data corruption. It is always safe to used CMOVE when addr1 > addr2 CMOVE> addr1 addr2 u -- 79 "c-move-up" Move the u bytes at address addr1 to addr2. The move begins by moving the byte at (addr1 plus u minus 1) to (addr2 plus u minus 1) and proceeds to successively lower addresses for u bytes. If u is zero nothing is moved. (Useful for sliding a string towards higher addresses when the ranges overlap). It is always safe to use CMOVE> when addr1 < addr2. MOVE addr1 addr2 u -- The u bytes at address addr1 are moved to address addr2. The data are moved such that the u bytes remaining at address addr2 are the same data as was originally at address addr1. If u is zero nothing is moved. If addr1 > addr2 then the first byte of addr1 is moved first, otherwise the last byte (`u'th) of addr1 is moved first. FILL addr u byte -- 83 u bytes of memory beginning at addr are set to byte. No action is taken if u is zero. ERASE addr u -- 79 u bytes of memory beginning at addr are set to zero. No action is taken if u is zero. BLANK addr u -- 83 u bytes of memory beginning at addr are set to the ASCII character value for space (hex 20). No action is taken if u is zero. COUNT addr1 -- addr2 +n 79 addr2 is addr1+1 and +n is the length of the counted string at addr1. The byte at addr1 contains the byte count +n. Range of +n is {0..255}. See: "string, counted" -TRAILING addr +n1 -- addr +n2 79 "dash-trailing" The character count +n1 of a text string beginning at addr is adjusted to exclude trailing spaces. If +n1 is zero, then +n2 is also 0. If the entire string consists of spaces, then +n2 is zero. DUMP addr u -- M,79 List the contents of u bytes starting at addr. Note: There is a very simple implementation of DUMP which is compiled into the kernel. A more sophisticated version, which formats the dump nicely and displays both the hex and ascii representations of the data, is usually loaded along with other utilities. The simple version is useful for debugging changes to the kernel. **** Control Structures **** IF flag -- C,I,79 -- sys (compiling) Used in a colon definition in the form: flag IF ... ELSE ... THEN or flag IF ... THEN If flag is true, the words folowing IF are executed and the words following ELSE are skipped. The ELSE part is optional. If flag is false, words from IF through ELSE, or from IF through THEN (when no ELSE is used), are skipped. IF-ELSE-THEN conditionals may be nested. sys is balanced with its corresponding ELSE or THEN . See: "9.9 Control Structures" ELSE -- C,I,79 sys1 -- sys2 (compiling) Used in a colon-definition in the form: IF ... ELSE ... THEN ELSE executes after the part clause following IF . ELSE forces execution to continue at just after THEN . sys1 is balanced with its corresponding IF . sys2 is balanced with its corresponding THEN . See: IF THEN THEN -- C,I,79 sys -- (compiling) Used in a colon-definition in the form: IF ... ELSE ... THEN or IF ... THEN THEN is the point where execution continues after ELSE , or IF when no ELSE is present. sys is balanced with its corresponding IF or ELSE . See: IF ELSE BEGIN -- C,I,79 -- sys Used in a colon-definition in the form: BEGIN ... flag UNTIL or BEGIN ... flag WHILE ... REPEAT BEGIN marks the start of a word sequence for repetive execution. A BEGIN-UNTIL loop will be repeated until flag is true. A BEGIN- WHILE-REPEAT loop will be repeated until flag is false. The words after UNTIL or REPEAT will be executed when either loop is finished. sys is balanced with its corresponding UNTIL or WHILE . See: "9.9 Control Structures" WHILE flag -- C,I,79 sys1 -- sys2 (compiling) Used in a colon-definition in the form: BEGIN ... flag WHILE ... REPEAT Select conditional execution based on the flag. When the flag is true, execution continues to just after the WHILE through to the REPEAT which then continues execution back to just after the BEGIN . When flag is false, execution continues to just after the REPEAT , exiting the control structure. sys1 is balanced with its corresponding REPEAT . See: BEGIN REPEAT -- C,I,79 sys -- (compiling) Used in a colon-definition in the form: BEGIN ... WHILE ... REPEAT At execution time, REPEAT continues execution to just after the corresponding BEGIN . sys is balanced with its corresponding WHILE . See: BEGIN UNTIL flag -- C,I,79 sys -- (compiling) Used in a colon definition in the formL BEGIN ... flag UNTIL Marks the end of a BEGIN-UNTIL loop which will terminate based on flag. If flag is true, the loop is terminated. If flag is false, execution continues to just after the corresponding BEGIN . BEGIN-UNTIL structures may be nested. sys is balanced with its corresponding BEGIN . See: BEGIN DO n1 n2 -- C,I,83 -- sys Used in a colon-definition in the form: DO ... LOOP or DO ... +LOOP Begin a loop which terminates based on control parameters. The loop index begins at n2, and terminates based on the limit n1. See LOOP and +LOOP for details on how the loop is terminated. The loop is always executed at least once. For example: n DUP DO ... LOOP executes either 65,536 times or 4,294,967,295 times, depending on the width of the data stack. sys is balanced with its corresponding LOOP or +LOOP . See: "9.9 Control Structures" LOOP -- C,I,83 sys -- (compiling) Increments the DO-LOOP index by one. If the new index was incremented across the boundary between limit-1 and limit the loop is terminated and loop control parameters are discarded. When the loop is not terminated, execution continues to just after the corresponding DO . sys is balanced with its corresponding LOOP or +LOOP . See: DO +LOOP n -- C,I,83 "plus-loop" sys -- (compiling) n is added to the loop index. If the new index was incremented across the boundary between limit-1 and limit then the loop is terminated and loop control parameters are discarded. When the loop is not terminated, execution continues to just after the corresponding DO . sys is balanced with its corresponding DO . See: DO I -- n C,79 n is a copy of the loop index. May only be used in the form: DO ... I ... LOOP or DO ... I ... +LOOP J -- n C,79 n is a copy of the index of the next outer loop. May only be used within a nested DO-LOOP or DO-+LOOP in the form, for example: DO ... DO ... J ... LOOP ... LOOP K -- n C,83 n is a copy of the index of the second outer loop. May only be used within a nested DO-LOOP or DO-+LOOP in the form, for example: DO ... DO ... DO ... K ... LOOP ... +LOOP ... LOOP LEAVE -- C,I,83 -- (compiling) Transfers execution to just beyond the next LOOP or +LOOP . The loop is terminated and loop control parameters are discarded. May only be used in the form: DO ... LEAVE ... LOOP or DO ... LEAVE ... +LOOP LEAVE may appear within other control structures which are nested within the do-loop structure. More than one LEAVE may appear within a do-loop. See: "9.3 Return Stack" LEAVE may not be used within BEGIN ... UNTIL or BEGIN ... WHILE ... REPEAT constructs. EXECUTE addr -- 79 The word definition indicated by addr is executed. An error condition exists if addr is not a compilation address. (The Forth system will either crash, or if you're lucky, ABORT back to the text interpreter). EXIT -- C,79 Compiled within a colon definition such that when executed, that colon definition returns control to the definition that passed control to it by returning control to the return point on the top of the return stack. AN error condition exists if the top of the return stack does not contain a valid return point. May not be used within a do-loop. See: ; "stack, return" "9.3 Return Stack" QUIT -- Deferred 79 (QUIT -- Default Clears the return stack, sets interpret state, accepts new input from the current input device, and begins text interpretation. No message is displayed. In this implementation, QUIT is deferred so that a different implementation may be substituted. (QUIT is the default implementation which implements the behavior described above. ABORT -- Deferred 79 (ABORT -- Default Clears the data stack and performs the function of QUIT . No message is displayed. In this implementation, ABORT is deferred so that a different implementation may be substituted. (ABORT is the default implementation which implements the behavior described above. ABORT" flag -- C,I,83 "abort-quote" -- (compiling) Used in the form: flag ABORT" ccc" When later executed, if flag is true the characters ccc, delimited by " (close-quote), are displayed and then a system dependent error abort sequence, including the function of ABORT , is performed. If flag is false, the flag is dropped and execution continues. The blank following ABORT" is not part of ccc. This is equivalent to the sequence: IF ." ccc" ABORT THEN **** I/O **** **** CHARACTER I/O **** KEY -- char Deferred M,83 (KEY -- char Default Local char is the next ASCII character received from the input stream. All valid ASCII characters can be received. Control characters are not processed by the system for any editing purpose. Characters received by KEY will not be displayed. See: "9.5.1 KEY" Implementation Notes: KEY is deferred so that the Forth system may be easily configured to run in different environments (e.g. under Unix or stand-alone) by changing the words that are installed in KEY and (EMIT . (KEY is the default implementation, which performs the key function for Unix. When running under Unix, the normal tty mode is "cooked", which does process control characters for editing purposes and does echo the characters, thus violating the strict definition of KEY . If it is necessary to faithfully implement the correct behavior of KEY , the tty driver may be put into "raw" mode with the Unix command "stty raw". EMIT char -- Deferred M,83 EMIT1 char -- Default Local Transmit the character char to the output stream. Other system-dependent action may also be taken, such as keeping track of where the cursor is on the screen. (EMIT char -- Deferred Local UNIX-EMIT char -- Default Local Transmit the character char to the output stream, with no other actions. UNIX-EMIT is the implementation of this for Unix. Porting this Forth system to other 68000 systems is often as easy as implementing words to install in (EMIT , KEY , and KEY? The hierarchy of different EMIT's works as follows: EMIT is the word called by most applications. By default, EMIT executes EMIT1 , which updates the variable #OUT (#OUT keeps track of the current cursor position on the screen) and calls (EMIT to actually send the character to the output stream. SPACE -- M,79 Transmits an ASCII space to the current output stream. CR -- Deferred M,79 "c-r" LF -- Default (Unix) Local CRLF -- Default (Stand-alone) Local Transmits a carriage-return and line-feed or equivalent sequence to the current output stream. Implementation Note: CR is a deferred word so that different implementations may be substituted in order to cope with different output devices. Under Unix, LF is the default implementation. LF just transmits a "newline" (actually linefeed, decimal 10) character, since the normal state of the Unix tty driver maps newlines into whatever the terminal needs. When running stand-alone, the default is CRLF, which transmits both a carriage return and a linefeed. **** String I/O **** SPACES +n -- Transmits +n spaces to the current output device. Nothing is transmitted if +n is zero. TYPE addr +n -- M,79 +n characters are transferred to the current output stream from memory beginning with the character at address addr and continuing through consequetive addresses. No action is taken if +n is zero. See: "9.5.4 TYPE" ." -- C,I,83 "dot-quote" -- (compiling) Used inside colon definitions in the form: ." ccc" Later execution will display the characters ccc up to but not including the delimiting " (close-quote". The blank following ." is not part of ccc. .( -- I,M,83 "dot-paren" -- (compiling) Used in the form: .( ccc) The characters ccc up to but not including the delimiting ) (closing parenthesis) are displayed. The blank following .( is not part of ccc. This may be used either inside or outside of colon definitions. When .( is encountered, it will immediately display the message, whether the system is interpreting or compiling. EXPECT addr +n -- Deferred M,83 (EXPECT addr +n -- Default Receive characters and store each into memory. The transfer begins at addr proceeding towards higher addresses one byte per character until either a "return" is received or until +n characters have been transferred. No more than +n characters will be stored. The "return" is not stored into memory. No characters are received or transferred if +n is zero. All characters actually received and stored into memory will be displayed, with the "return" displaying as a space (see note). See: SPAN "9.5.2" EXPECT Implementation Note: In this implementation, EXPECT is a deferred word so that the user may substitute another implementation if desired. The default implementation is (EXPECT . EXPECT traditionally is the word which implements keyboard line editing, such as erasing characters, etc. The default implementation (EXPECT is intended to be used under Unix, with the Unix tty driver in "cooked" mode, so the Unix tty driver does the line editing. The only special character recognized by (EXPECT is newline, which is the character that Unix puts at the end of a line when a return is typed. There is another implementation of EXPECT called (NEWEXPECT . (NEWEXPECT is defined in the file forth/emacs-line-edit.f, and provides a very powerful Emacs-like line editing facility. (NEWEXPECT is the default when running stand-alone. It may also be used under Unix, but when run under Unix it requires that the Unix tty driver be set in cbreak mode, with -echo and nl. stty cbreak -echl nl SPAN -- addr U,83 The address of a variable containing the count of characters actually received and stored by the last execution of EXPECT . See: EXPECT QUERY -- Deferred M,83 (QUERY -- Default Local Characters are received and transferred into the memory area addressed by TIB . The transfer terminates when either a "return" is received or the number of characters transferred reaches the size of the area addressed by TIB . THe values of >IN and BLK are set to zero and the value of #TIB is set to the value of SPAN . WORD may be used to accept text from this buffer. See: EXPECT "input stream" Implementation Note: In this implementation, QUERY is a deferred word so that the user may substitute another implementation of QUERY if desired. The default implementation is (QUERY . TIB -- addr 83 "t-i-b" The address of the text input buffer. This buffer is used to hold characters when the input stream is coming from the current input device. The minimum capacity of TIB is 80 characters. #TIB -- addr U,83 "number-t-i-b" The address of a variable containing the number of bytes in the text input buffer. #TIB is accessed by WORD when BLK is zero. {{0..capacity of TIB}} See: TIB "input stream" **** Numeric I/O **** <# -- 79 "less-sharp" Initialize pictured numeric output conversion. The words: <# # #S SIGN #> can be used to specify the conversion of a 32 bit number into an ASCII character string stored in right-to-left order. See #> for a usage example. # +l1 -- +l2 79 "sharp" The remainder of +l1 divided by the value of BASE is converted to an ASCII character and appended to the output string toward lower memory addresses. +l2 is the quotient and is maintained for further processing. Typically used between <# and #> . See #> for a usage example. #S +l -- 0 0 79 "sharp-s" +l is converted appending each resultant character into the pictured numeric output string until the quotient (see: # ) is zero. A single zero is added to output string if the number was initially zero. Typically used between <# and #> . See #> for a usage example. HOLD char -- 79 char is inserted into a pictured numeric output string. Typically used between <# and #> . See #> for a usage example. #> l -- addr +n 79 "sharp-greater" Pictured numeric output conversion is ended dropping l. addr is the address of the resulting output string. +n is the number of characters in the output string. addr and +n together are suitable for TYPE . For example, suppose you want to print a number in dollars and cents format. On the stack you have a number that is the number of cents. Here's how to print it: N->L <# # # ASCII . HOLD # #S ASCII $ HOLD #> TYPE The first thing to do is to convert the number to a 32 bit number, since the number conversion operators # and #S always work on a 32 bit number. N->L converts a normal stack item (16 or 32 bits, depending on the implementation) to a 32 bit number. <# initializes the conversion. The conversion starts with the least significant digits, the two cents digits ( # # ). Then HOLD is used to insert a decimal point ( ASCII . HOLD ). The dollars digits are then converted, always printing at least one digit to the left of the decimal point ( # #S ). A dollar sign is added to the string ( ASCII $ HOLD ). The conversion is finished and the result is printed ( #> TYPE ). SIGN n -- 83 If n is negative, an ASCII "-" (minus sign) is appended to the pictured numeric output string. Typically used between <# and #> . The example for #> showed the printing of a number in dollars and cents format. That number was implicitly assumed to be positive. If the number is allowed to be negative, here's how to print it: DUP ABS N->L ( n l ) <# # # ASCII . HOLD # #S NLSWAP ASCII $ HOLD SIGN #> TYPE A copy of the number is made with DUP, then the absolute value is taken. The numberic conversion operators thus get to work on a positive number. After all the digits are converted, NLSWAP SIGN grabs the copy of the original number and tests its sign. PAD -- addr 83 The lower address of a scratch area used to hold data for intermediate processing. The address or contents of PAD may change and the data lost if the address of the next available dictionary location is changed. The minimum capacity of PAD is 84 characters. . n -- M,79 "dot" The absolute value of n is displayed in a free field format with a leading minus sign if n is negative. Implementation Note: If the base is hex, . displays the number in unsigned format, since signed hex display is hardly ever what you want. There is word S. to use if you ever should want to display signed hex numbers. U. u -- M,79 "u-dot" u is displayed as an unsigned number in a free-field format. .R n +n -- M,83 "dot-r" n is converted using the value of BASE and then displayed right aligned in a field +n characters wide. A leading minus sign is displayed if n is negative. If the number of characters required to display u is greater than +n, an error condition exists. See: "number condition" Implementation note: If the number of characters required to display u is greater than +n, all the characters required will be displayed, making the resulting field larger than +n. U.R u +n -- M,83 "u-dot-r" u is converted using the value of BASE and then displayed as an unsigned number right aligned in a field +n characters wide. If the number of characters required to display u is greater than +n, an error condition exists. See: "number condition" Implementation note: If the number of characters required to display u is greater than +n, all the characters required will be displayed, making the resulting field larger than +n. CONVERT +L1 addr1 -- +L2 addr2 +L2 is the 32 bit result of converting the characters within the text beginning at addr1+1 into digits, using the balue of BASE , and accumulating each into +L1 after multiplying +L1 by the value of BASE . Conversion continues until an unconvertible character is encountered, addr2 is the location of the first unconvertible character. BASE -- addr U,115 The address of a variable containing the current numeric conversion radix. {{2..72}} DECIMAL 79 Set the input-output numeric conversion base to ten. HEX 79 Set the input-output numeric conversion base to sixteen. **** INTERPRETING **** WORD char -- addr Deferred M,83 (WORD char -- addr Default Generates a counted string by non-destructively accepting characters from the input stream until the delimiting character char is encountered or the input stream is exhausted. Leading delimiters are ignored. The entire character string is stored in memory beginning at addr as a sequence of bytes. The string is followed by a blank which is not included in the count. The first byte of the string is the number of characters {0..255}. If the string is longer than 255 characters, the count is unspecifie. It the input stream is already exhausted as WORD is called, then a zero length character string will result. If the delimiter is not found the value of >IN is the size of the input stream. If the delimiter is found >IN is adjusted to indicate the offset to the character following the delimiter. #TIB is unmodified. The counted string returned by WORD may reside in the "free" dictionary area at HERE or above. Note that the text interpreter may also use this area. See: "input stream" Local Implementation notes: 1) The location of the packed string is always a few bytes above HERE, the beginning of free memory. 2) The actual delimiter encountered is left in the user varible DELIMITER . If the end of the input stream was encountered before a delimiter, DELIMITER contains the constant EOF . 3) WORD is deferred so that it may be replaced with a different implementation. The default implementation is (WORD. The file system replaces (WORD with its own implementation to allow loading from files. While loading from files, the "non-destructive" aspect of WORD is not complied with; this means that saving >IN, executing WORD, and then restoring >IN to its previous value will NOT rewind the input stream when loading from files (but it will work when interpreting from the input stream). >IN -- addr U,79 "to-in" The address of a variable which contains the present character offset within the input stream {{0..the number of characters in the input stream}}. See: WORD BLK -- addr U,79 "b-l-k" The address of a variable containing the number of the mass storage block being interpreted as the input stream. If the value of BLK is zero the input stream is taken from the text input buffer. {{0..then number of blocks available -1}} See: TIB "input stream" Implementation Note: While this variable exists, its value is uninteresting because mass storage BLOCK's are not implemented. ( -- I,M,83 "paren" -- (compiling) Used in the form: ( ccc) The characters ccc, delimited by ) (closing parenthesis), are considered comments. Comments are not otherwise processed. The blank following ( is not part of ccc. ( may be freely used while interpreting or compiling. The number of characters in ccc may be from zero to the number of characters remaining in the input stream up to the closing parenthesis. FIND addr1 -- addr2 n 83 addr1 is the address of a counted string. The string contains a word name to be located in the currently active search order. It the word is not found, addr2 is the string address1, and n is zero. If the word is found, addr2 is the compilation address and n is set to one of two non-zero values. If the word found has the immediate attribute, n is set to one. If the word is non-immediate, n is set to minus one (true). ' -- addr M,83 "tick" Used in the form: ' addr is the compilation address of . An error condition exists if is not found in the currently active search order. ' is similar to find, except: a) ' takes it's argument from the input stream, FIND from the stack. b) ' causes an error condition if the word is not found, FIND returns a false flag. c) ' does not tell you if the word found was immediate, FIND does ' is generally used when you are fairly certain that the word will be found. INTERPRET -- Deferred M,83 (INTERPRET -- Default Begin text interpretation at the character indexed by the contents of >IN relative to the block number contained in BLK , continuing until the input stream is exhausted. If BLK contains zero, interpret characters from the text input buffer. See: "input stream" Implementation Notes: In this implementation, INTERPRET is a deferred word so that the user may substitute another implementation if desired. The default implementation is (INTERPRET . Since the standard mass storage words BLOCK, BUFFER, etc are not used in this Forth system, the stuff about BLK is ignored. There are two ways of interpreting from files: 1) The C wrapper program (wrapper.c) which connects the Forth system into Unix can connect files to the standard input stream that Forth sees as its input stream. 2) When the portable file system is being used, files may be loaded using LOAD , which actually replaces WORD with a version that gets its input from the file. **** COMPILING *** : -- sys M,79 "colon" A defining word used in the form: : . . . ; Create a word definition for in the compilation vocabulary (CURRENT) and set compilation state. The search order is changed so that the first vocabulary in the search order is replaced by the compilation vocabulary. The compilation vocabulary is unchanged. The text from the input stream is subsequently compiled. is called a "colon definition". The newly created word definition for cannot be found in the dictionary until the corresponding ; or ;CODE is successfully processed. An error condition exists if a word is not found and cannot be converted to a number or if, during compilation from mass storage, the input stream is exhausted before encountering ; or ;CODE . sys is balanced with its corresponding ; . See: "compilation" Sun Implementation Note: The error condition described above actually results in the word LOSE being compiled into the dictionary, and compilation continues after an error message is printed. The word LOSE, if executed, will print an error message and ABORT. DOES> -- addr C,I,83 "does" Defines the execution-time action of a word created by a high-level defining word. Used in the form: : ... ... DOES> ... ; and then where is CREATE or any user defined word which executes CREATE . Marks the termination of the defining part of the defining word and then begins the definition of the execution-time action for words that will later be defined by . When is later executed, the address of 's parameter field is placed on the stack and then the sequence of words between DOES> and ; are executed. ; -- C,I,79 "semi-colon" sys -- ( compiling ) Stops compilation of a colon-definition, allows the of this colon definition to be found in the dictionary, set interpret state and compiles EXIT (or a system dependent word which performs an equivalent function). sys is balanced with its corresponding : . See: EXIT : "stack" "return" CONSTANT n -- M,83 A defining word used in the form: n CONSTANT to create a dictionary entry for so that when is later executed, n will be left on the stack. VARIABLE -- M,83 A defining word executed in the form: VARIABLE A dictionary entry for is created and enough storage for a "normal" stack item is ALLOTted in its parameter field. This parameter field is to be used for the contents of the variable. The application is responsible for initializing the contents of the variable which it creates. When is later executed, the address of its parameter field is placed on the stack. , n -- 79 "comma" Allot enough space for a "normal" stack item (a "normal" stack item is 16 bits if the stack is 16 bits wide, or 32 bits if the stack is 32 bits wide) in the dictionary and store n there. C, n -- 83 "c-comma" ALLOT one byte then store the least-significant 8 bits of n in the space just allotted. (Which will be at HERE 1- ). IMMEDIATE -- 79 Marks the most recently created dictionary entry as a word which will be executed when encountered during compilation rather than compiled. For instance, the word IF is immediate, since when it is encountered during compilation, it is executed right then instead of being compiled into the dictionary like a non-immediate word. When IF executes, it compiles a conditional branch into the dictionary. CREATE -- M,79 A defining word executed in the form: CREATE Creates a dictionary entry for . After is created, the next available dictionary location is the first byte of 's parameter field. When is subsequently executed, the address of the first byte of 's parameter field is left on the stack. CREATE does not allocate space in 's parameter field. [ -- I,79 "left-bracket" Sets interpret state. The text from the input stream is subsequently executed. See: ] ] 79 "right-bracket" Set the compilation state. The text from the input stream is subsequently compiled. For typical usage see LITERAL . See [ Example: : NUMBERS [ DECIMAL ] 1234 5678 [ HEX ] FF00 0080 ; Since DECIMAL and HEX are enclosed in brackets, they will be executed right away, instead of being compiled into the definition. Brackets give you a means for temporarily escaping from the compilation state. Another common use is to pre-calculate some complicated number, then put that number in a definition. See LITERAL for an example. ['] -- addr C,I,M,83 "bracket-tick" -- (compiling) Used in the form: ['] Compiles the compilation address of as a literal. When the colon definition is later executed addr is left on the stack. An error condition exists if is not found in the currently active search order. See: LITERAL [COMPILE] -- C,I,M,79 "bracket-compile" -- (compiling) Used in the form: [COMPILE] Compiles the compilation address addr of as a literal. When the colon definition is later executed addr is left on the stack. An error condition exists if is not found in the currently active search order. See: LITERAL COMPILE -- C,83 Typically used in the form: : ... COMPILE ... ; When is executed, the compilation address compiled for is compiled and not executed. is typically immediate and is typically not immediate. See: "compilation" Example: : FOO COMPILE HERE COMPILE . ; IMMEDIATE Now, if you later compile: : PRINT-HERE FOO ; the effect will be exactly the same as: : PRINT-HERE HERE . ; LITERAL -- n C,I,79 n -- (compiling) Typically used in the form: [ number ] LITERAL Compiles a system dependent operation so that when later executed, a "normal" sized number will be left on the stack. Example: : SKIP-BUFS ( addr1 -- addr2 ) [ 123 55 * ] LITERAL + ; SKIP-BUFS adds the number 6765 to whatever is on the stack. The calculation of 123 times 55 is done at compile time. HERE -- addr 79 addr is the address of the next available dictionary location. ALLOT n -- Allocates n bytes in the dictionary. The address of the next available dictionary location is adjusted accordingly. STATE -- addr U,79 The address of a variable containing the compilation state. A non-zero content indicates compilation is occurring, but the value itself is system dependent. A Standard Program may not modify this variable. In this implementation STATE = TRUE indicates compilation. **** Dictionary/Vocabulary Maintenance **** FORTH I,187 The name of the primary vocabulary. Execution replaces the first vocabulary in the search order with FORTH . FORTH is initially the compilation vocabulary and the first vocabulary in the search order. Initially, new definitions become part of the FORTH vocabulary until a different compiliation vocabulary is established (with DEFINITIONS). See: VOCABULARY FORGET M,83 Executed in the form: FORGET If is found in the compilation vocabulary, delet from the dictionary and all words added to dictionary after regardless of their vocabulary. Failure to find is an error condition. An error condition also exists if the compilation vocabulary is deleted. See: "10.2 General Error Conditions" VOCABULARY M,83 A defining word executed in the form: VOCABULARY A dictionary entry for is created which specifies a new ordered list of word definitions. Subsequent execution of replaces the first vocabulary in the search order with . When becomes the compilation vocabulary, new definitions will be appended to 's list. See: DEFINITIONS "search order" DEFINITIONS -- 79 The compilation vocabulary (CURRENT) is changed to be the same as the first vocabulary in the search order. See: "vocabulary", "compilation". **** DICTIONARY SEARCH ORDER **** CONTEXT -- addr U,79 The address of a variable which determines the dictionary search order. CURRENT -- addr U,79 The address of a variable specifying the vocabulary in which new word definitions are appended. WORDS -- M List the word names of the CONTEXT vocabulary starting with the most recent definition. ONLY -- ONLY Select just the ROOT vocabulary as both the transient vocabulary and resident vocabulary in the search order. ALSO -- ONLY The transient vocabulary becomes the first vocabulary in the resident protion of the search order. Up to the last two resident vocabularies will alse be reserved, in order, forming the resident search order. ORDER -- ONLY Display the vocabulary names forming the search order in their present search order sequence. Then show the vocabulary into which new definitions will be placed. SEAL -- ONLY Delete all occurrences of ROOT from the search order. The effect is that only specified application vocabularies will be searched. **** BOILERPLATE **** FORTH-83 -- 83 Assures that a FORTH-83 Standard System is available, otherwise an error condition exists. This implementation is not strictly 83-Standard. It lacks the required mass storage words (BLOCK, BUFFER, etc), has a non-standard behavior for the word LOAD, and has 32 bit stack operators instead of the required 16 bit ones. In all other respects it is believed to comply to the standard. Since this system is not strictly standard, the word FORTH-83 prints a message then aborts. **** DOUBLE NUMBERS **** 2! n1 n2 addr -- 79,32 "two-store" n1 and n2 are stored in consequetive locations starting at addr. n2 is stored at the lower address. 2@ addr -- n1 n2 79,32 "two-fetch" n1 and n2 are the two consequetive numbers stored at addr. n2 is the number which was stored at the lower address. 2CONSTANT n1 n2 -- M,83 "two-constant" A defining word used in the form: n1 n2 2CONSTANT Creates a dictionary entry for so that when is later executed, n1 and n2 will be left on the stack in the same order as when 2CONSTANT was executed. 2DROP n1 n2 -- 79,32 "two-drop" n1 and n2 are removed from the stack. 2DUP n1 n2 -- n1 n2 n1 n2 79,32 "two-dupe" Duplicate n1 and n2. 2OVER n1 n2 n3 n4 -- n1 n2 n3 n4 n5 n6 79,32 "two-over" n5 and n6 are a copy of n1 and n2. 2ROT n1 n2 n3 n4 n5 n6 -- n3 n4 n5 n6 n1 n2 79,32 "two-rote" The top three pairs of numbers are rotated, bringing the third pair to the top of the stack. 2SWAP n1 n2 n3 n4 -- n3 n4 n1 n2 79,32 "two-swap" The top two pairs of numbers are exchanged. 2VARIABLE -- M,79 "two-variable" A defining word used in the form: 2VARIABLE A dictionary entry for is created and space for two "normal" sized number is ALLOTted in its parameter field. This parameter field is to be used for contents of the variable. THe application is responsible for initializing the contents of the variable which it creates. When is later executed, the address of its parameter field is placed on the stack. See: VARIABLE **** DOUBLE NUMBER ARITHMETIC, OBSOLETE **** D+ wd1 wd2 -- wd3 79 "d-plus" wd3 is the arithmetic sum of wd1 plus wd2. See: "32-bit Compatibility" Warning: This word is not recommended. The appropriate word to use for 32-bit addition is L+ . The behavior of D+ for 32-bit Forth systems is not specified by the standard, and in some 32-bit Forth systems, D+ is taken to mean 64-bit addition. In the 32-bit version of this Forth system, D+ is not implemented. D- wd1 wd2 -- wd3 79 "d-minus" wd3 is the result of subtracting wd1 from wd2. See: "32-bit Compatibility" Warning: This word is not recommended. The appropriate word to use for 32-bit subtraction is L- . The behavior of D- for 32-bit Forth systems is not specified by the standard, and in some 32-bit Forth systems, D- is taken to mean 64-bit subtraction. In the 32-bit version of this Forth system, D- is not implemented. DNEGATE d1 -- d2 79 "d-negate" d2 is the two's complement of d1. See: "32-bit Compatibility" Warning: This word is not recommended. The appropriate word to use for 32-bit negation is LNEGATE . The behavior of DNEGATE for 32-bit Forth systems is not specified by the standard, and in some 32-bit Forth systems, DNEGATE is taken to mean 64-bit negation. In the 32-bit version of this Forth system, DNEGATE is not implemented. DABS d -- ud 79 "d-absolute" ud is the absolute value of d. If d is -2,147,483,648 then ud is the same value. See: "arithmetic, two's complement" Warning: This word is not recommended. The appropriate word to use for 32-bit absolute value is LABS . The behavior of DABS for 32-bit Forth systems is not specified by the standard, and in some 32-bit Forth systems, DABS is taken to mean 64-bit negation. In the 32-bit version of this Forth system, DABS is not implemented. D2/ d1 -- d2 83 "d-two-divide" d2 is the result of d1 arithmetically shifted right one bit. The sign is included in the shift and remains unchanged. Warning: This word is not recommended. The appropriate word to use for 32-bit haoving is L2/ . The behavior of D2/ for 32-bit Forth systems is not specified by the standard, and in some 32-bit Forth systems, D2/ is taken to mean 64-bit halving. In the 32-bit version of this Forth system, D2/ is not implemented. S->D n -- d "signed-to-double" In a 16-bit Forth system, d is a 32-bit representation of the 16-bit n which is obtained by sign extension. Warning: This word is not recommended. The appropriate word to use for converting "normal" size numbers to 32 bits is S->L . In the 32-bit version of this Forth system, S->D is not implemented. DMIN d1 d2 -- d3 79 "d-min" d3 is the lesser of d1 and d2. Warning: This word is not recommended. The appropriate word to use for 32-bit minimum is LMIN . The behavior of DMIN for 32-bit Forth systems is not specified by the standard, and in some 32-bit Forth systems, DMIN is taken to mean 64-bit negation. In the 32-bit version of this Forth system, DMIN is not implemented. DMAX d1 d2 -- d3 79 "d-max" d3 is the greater of d1 and d2. Warning: This word is not recommended. The appropriate word to use for 32-bit minimum is LMIN . The behavior of DMIN for 32-bit Forth systems is not specified by the standard, and in some 32-bit Forth systems, DMIN is taken to mean 64-bit negation. In the 32-bit version of this Forth system, DMIN is not implemented. D< d1 d2 -- flag 83 "d-less-than" flag is true if d1 is less than d2 according to the operation of < except extended to 32 bits. Warning: This word is not recommended. The appropriate word to use for 32-bit less than is L< . The behavior of D< for 32-bit Forth systems is not specified by the standard, and in some 32-bit Forth systems, D< is taken to mean 64-bit negation. In the 32-bit version of this Forth system, D< is not implemented. D. d -- M,79 "d-dot" The absolute value of d is displayed in a free field format. A leading negative sign is displayed if d is negative. Warning: This word is not recommended. The appropriate word to use for 32-bit printing is L. . The behavior of D. for 32-bit Forth systems is not specified by the standard, and in some 32-bit Forth systems, D. is taken to mean 64-bit printing . In the 32-bit version of this Forth system, D. is not implemented. D.R d +n-- M,83 "d-dot-r" d is converted using the value of BASE and then displayed right aligned in a field +n characters wide. A leading minus sign is displayed if k is negative. If the number of characters required to display d is greater than +n, an error condition exists. See: "number conversion" Warning: This word is not recommended. The appropriate word to use for 32-bit printing is L.R . The behavior of D.R for 32-bit Forth systems is not specified by the standard, and in some 32-bit Forth systems, D.R is taken to mean 64-bit printing . In the 32-bit version of this Forth system, D.R is not implemented. D= d1 d2 -- flag 83 "d-equal" flag is true if d1 equals d2. Warning: This word is not recommended. The appropriate word to use for 32-bit equal is L= . The behavior of D= for 32-bit Forth systems is not specified by the standard, and in some 32-bit Forth systems, D= is taken to mean 64-bit equal. In the 32-bit version of this Forth system, D= is not implemented. DU< d1 d2 -- flag 83 "d-u-less" flag is true if d1 is less than d2. Both numbers are unsigned. Warning: This word is not recommended. The appropriate word to for 32-bit comparison is LU< . The behavior of DU< for 32-bit Forth systems is not specified by the standard, and in some 32-bit Forth systems, DU< is taken to mean 64-bit comparison. In the 32-bit version of this Forth system, DU< is not implemented. D0= d -- flag 83 "d-zero-equals" flag is true if d is zero. Warning: This word is not recommended. The appropriate word to for 32-bit zero-equals is L0= . The behavior of D0= for 32-bit Forth systems is not specified by the standard, and in some 32-bit Forth systems, D0= is taken to mean 64-bit zero-equals. In the 32-bit version of this Forth system, D0= is not implemented. **** BLOCK I/O, Not Implemented **** BUFFER u -- addr M,83 Assigns a block buffer to block n. addr is the address of the first byte of the block within the buffer. This function is fully specified by the definition for BLOCK except that if the block is not already in memory it might not be transferred from mass storage. The contents of the block buffer assigned to block u by BUFFER are unspecified. Implementation Note: This word is NOT implemented. UPDATE -- 79 The currently valid block buffer is marked as modified. Blocks marked as modified will subsequently be automatically transferred to mass storage should its memory buffer be needed for storage of a different block or upon execution of FLUSH or SAVE-BUFFERS. Implementation Note: This word is NOT implemented. BLOCK u -- addr M,83 addr is the address of the assigned buffer of the first byte of block u. If the block occupying that buffer is not block u and has been UPDATEed it is transferred to mass storage before assigning the buffer. If block u is not already in memory, it is transferred from mass storage into an assigned block buffer. A block may not be assigned to more than one buffer. If u is not an available block number, an error condition exists. Only data within the last buffer referenced by BLOCK or BUFFER is valid. The contents of a block buffer must not be changed unless the change may be transferred to mass storage. Implementation Note: This word is NOT implemented. EMPTY-BUFFERS -- M,79 Unassigns all block buffers. UPDATEed blocks are not written to mass storage. See: BLOCK FLUSH -- M,83 Performs the function of SAVE-BUFFERS then unassigns all block buffers. (This may be useful for mounting or changing mass storage media). Implementation Note: This word is NOT implemented. SAVE-BUFFERS -- M,79 "save-buffers" The contents of all block buffers marked as UPDATEed are written to their corresponding mass storage blocks. All buffers are marked as not longer being modified, but may remain assigned. Implementation Note: This word is NOT implemented. LIST u -- M,79 The contents of screen u are displayed. SCR is set to u. See: BLOCK Not Implemented SCR -- addr U,79 "s-c-r" The address of a variable containing the number of the screen most recently LISTed. Implementation Note: This variable exists, but since LIST is not implemented, its contents are uninteresting. EDITOR -- 83 Execution replaces the first vocabulary in the search order with the EDITOR vocabulary. See: VOCABULARY Not Implemented. Since this Forth implementation runs under Unix and uses normal Unix files, it is assumed that the user would rather use one of the editors available under Unix (vi, Emacs) than the comparatively primitive Forth editors. LOAD u -- M,79 The contents of >IN and BLK, which locate the current input stream, are saved. The input stream is the redirected to the beginning of screen u by setting >IN to zero and BLK to u. The screen is then interpreted. If interpretation is not terminated explicitly it will be terminated when the input stream is exhausted an then the contents of >IN and BLK will be restored. An error condition exists if u is zero. See: >IN BLK Implementation Note: This word is implemented in a different form (yes, I know this is a bad thing). Since this Forth implementation uses Unix files as its mass storage medium, LOAD is used for interpreting the contents of a Unix file, as described below. **** File Input **** LOAD -- Local Used in the form: LOAD If the interpreter is currently taking its input from the input stream, the contents of >IN and BLK, which locate the input stream, are saved. If the interpreter is currently taking its input from a file under control of a previous LOAD command, the file descriptor is saved. The interpreter's input is then taken from the file . When the end of that file is reached, the previous interpreter input source is restored. An error condition exists if the specified file cannot be accessed. Note: This word is a non-standard definition of an 83-Standard word of the same name, whose definition is repeated above for reference. **** Assembler **** ASSEMBLER 83 Execution replaces the first vocabulary in the search order with the ASSEMBLER vocabulary. CODE -- sys M,83 A defining word executed in the form: CODE ... END-CODE Creates a dictionary entry for to be defined by a following sequence of assembly language words. Words thus defined are called code definitions. This newly created word definition for cannot be found in the dictionary until the corresponding END-CODE is successfully processed (see: END-CODE). Executes ASSEMBLER. sys is balanced with its corresponding END-CODE. See: Assembler Documentation. ;CODE C,I,206 Used in the form: : . . . ;CODE Stop compilation and terminate a defining word . ASSEMBLER becomes the CONTEXT vocabulary. When is executed in the form: to define the new , the execution address of will contain the address of the code sequence following the ;CODE in . Execution of any will cause this machine code sequence to be executed. "semi-colon-code" END-CODE sys -- 79 "end-code" Terminates a code definition and allows the of the corresponding code definition to be found in the dictionary. sys is balanced with its corresponding CODE or ;CODE . See: CODE Assembler Documentation Implementation Note: In this implementation, there is an alternate word for this function which is highly recommended. The alternate word is C; , which is like END-CODE except that it automatically executes NEXT before executing END-CODE. With END-CODE, it is quite easy to forget to do the NEXT , and if you forget, the code definition will probably crash the system if you try to execute it. **** EXTENSIBLE CONTROL STRUCTURES **** The following words are used for "rolling your own" custom control structures. The normal control structures IF ... ELSE ... THEN , BEGIN ... WHILE ... REPEAT , and BEGIN ... UNTIL are defined in terms of these words. For example, here are the definitions for IF ELSE THEN : : IF COMPILE ?BRANCH >MARK ; IMMEDIATE : ELSE COMPILE BRANCH >MARK 2SWAP >RESOLVE ; IMMEDIATE : THEN >RESOLVE ; IMMEDIATE >MARK -- addr C,83 "forward-mark" Used at the source of a forward branch. Typically used after either BRANCH or ?BRANCH . Compiles space in the dictionary for a branch address which will later be resolved by >RESOLVE . >RESOLVE addr -- C,83 "forward-resolve" Used at the destination of a forward branch. Calculates the branch address (to the current location in the dictionary) using addr and places this branch address inot the space left by >MARK. MARK . Implementation Note: Branch addresses are actually 16 bit offsets. **** Definition Field Address Conversion **** >BODY addr1 -- addr2 83 "to-body" addr2 is the parameter field address corresponding to the compilation address addr1. See: "9.2 Addressable Memory" BODY> addr1 -- addr2 "from-body" addr2 is the compilation address corresponding to the parameter field address addr1. >NAME addr1 -- addr2 "to-name" addr2 is the name field address corresponding to the compilation address addr1 NAME> addr1 -- addr2 "from-name" addr2 is the compilation address corresponding to the name field address addr1 >LINK addr1 -- addr2 "to-link" addr2 is the link field address corresponding to the compilation address addr1 LINK> addr1 -- addr2 "from-link" addr2 is the compilation address corresponding to the link field address addr1 N>LINK addr1 -- addr2 "name-to-link" addr2 is the link field address corresponding to the name field address addr1 L>NAME addr1 -- addr2 "link-to-name" addr2 is the name field address corresponding to the link field address addr1