Copyright 1984 by ABComputing July 15, 1984 ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º Using FORTH º º º º by º º º º Guy M. Kelly º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Introduction ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ "For best results . . . " It's much more satisfying to experiment at the keyboard and receive immediate feedback, so print this file, make a self-booting copy of the FORTH program provided in the previous issue of PCFL/PCUG, and have fun! ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ FORTHcoming Facts ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Things we need to know: 1. FORTH requires that all words (instructions, commands, data, etc.) be separated by one or more delimiting characters - normally space(s). 2. FORTH requires that all parameters (addresses, data, etc.) be available before an action can be performed upon them. (Parameters first, operations next!) 3. FORTH has all its words arranged in a dictionary. The dictionary is subdivided into vocabularies. The vocabularies are named. Entering the name of a vocabulary causes it to be the first vocabulary searched. 4. FORTH interprets a word by finding the definition of the word in a dictionary and executing that word's definition. 5. FORTH tries to find anything separated by delimiters. If it can't find the item in its dictionary, FORTH tries to convert it to a number. If the item doesn't convert properly, FORTH quits and displays the offending item followed by a ?. Rule: first, look it up, then try to convert it to a number, then give up. 6. FORTH puts items that it converts to numbers onto its parameter stack. 7. FORTH can work in any number base from 2 through 71, and is normally used in base 10. The words DECIMAL, HEX, OCTAL, and BINARY are available to change the current number-base. The base will remain as set until explicitly changed. EDITOR'S NOTE: FORTH is as picky as Pascal regarding punctuation and capitalization. When asked to type EDITOR, typing "editor" (lower case) will not work! (unless case is off.) If asked to type 7 -5 + . then 7 -5 +. is not acceptable. (The period should be separated from the plus sign by one or more blanks, as indicated in the original statement.) ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Hands-on Experience ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ In the following discussion, pressing the Enter key will be indicated by: . When booted, FORTH is in the interpret mode. That is, it will accept and execute words (programs or procedures) entered via the keyboard. Let's try a few. Type: BOZO FORTH searches for this word in the FORTH vocabulary, and will not find it. FORTH then tries converting it to a number, fails, and finally echoes BOZO back to the screen, followed by a "?": BOZO BOZO ? Next, type: VOCS FORTH looks for this word in its dictionary and finds it, and the word is executed. Its function is to output the names of all the vocabularies available in the dictionary. Type: WORDS Executing this word causes FORTH to list all the words in the FORTH vocabulary. The listing process can be stopped at any time by pressing any key. Type: ORDER This outputs the list of all the vocabularies to be searched and the order in which they will be searched. Type: EDITOR This selects the editor vocabulary and causes it to be the first vocabulary to be searched. Type: ORDER Note the new search order. Type WORDS again, then FORTH WORDS , then WORDS . Experiment with VOCS, WORDS, ORDER and the various vocabulary names. Type: 7 -5 + . The Enter key signals FORTH to start interpreting the sequence of characters: 7 -5 + . (from left to right). FORTH tries to find 7 in the dictionary, fails, then tries to convert 7 to a number and succeeds, and then puts the converted number onto the parameter stack. The -5 receives the same processing and also is placed on the parameter stack. The "+" is looked for and found, so it is executed. Its function is to take the top two numbers off the parameter stack, add them together, and place the resulting sum back onto the parameter stack. Finally the period (.) is sought and found (it's also a word in FORTH). The function of the period is to remove the top stack item, to convert it to an ASCII string, and to send it to the display. This sequence displays the answer 2. This version of FORTH has a number-conversion routine which processes a variety of different punctuation characters. For instance, a leading double quote (") means that the number is treated as hexadecimal. Similarly, a leading apostrophe (') means the number is regarded as octal. A comma (,) is ignored and can be used to improve the operator's perception of what has been typed, as can a leading +. Examples: (Assume the number-base is decimal.) "100 . gives the answer 256. '10 . gives the answer 8, BINARY 100 DECIMAL . gives the answer 4, and 1024 H. gives the answer 400 (H. outputs the answer in hexadecimal). Also, 1,000 . gives 1000, as will 1000 . . But, 1,000,000 . gives the nonsense answer 16960, because FORTH normally treats numbers as single-precision integers (15-bit precision, 1-bit sign), and 1,000,000 causes an overflow - with NO warning message. If you want to operate on double-precision integers (31-bits precision, 1-bit sign), use 1,000,000. D. . (Notice the period trailing the number 1,000,000. It signals double precision - a trailing # or a period anywhere within the number will also signal double precision in this version of the number routine.) The answer will be 1000000. The D. is required to output a double-precision number. Try a variety of numbers, and experiment with the operators: - * / and MOD. For example, type 3 4 * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Adding Words ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ FORTH stays in the interpret mode until it encounters a word causing it to enter the compile mode. It stays in the compile mode until it encounters a word returning it to the interpret mode. The FORTH word : (colon) changes the mode from interpret to compile (and will also start to enter a new word definition into the dictionary.) The FORTH word ; (semicolon) changes the mode from compile to interpret and thereby terminates the process of entering a new word definition into the dictionary. The words : and ; are normally used in matched pairs for exactly this purpose. Example: : DO-NOTHING ; This causes a new word, named DO-NOTHING, to be added to the dictionary. DO-NOTHING is a null operation. Type: DO-NOTHING The answer should be: ok. Type FORTH WORDS and notice that the first word in the FORTH vocabulary is DO-NOTHING. To remove this useless word, type: FORGET DO-NOTHING Type: WORDS The offending word is no longer with us! Type: FORGET FORTH The message "Can't forget below fence!" is issued, as FORTH protects itself from "forgetting" any words which were in the dictionary when FORTH was booted. Let's do something a little more useful. Type : 2X ( n -- 2n ) DUP + ; This is a little more interesting. Let's dissect it. : start a new definition 2X give it the name 2X (two times) ( start a comment (in this case the comment is a stack picture) n represents a signed number on the stack before using 2X -- separates the before and after stack entries 2n the result of using 2X ) end a comment DUP a FORTH word which duplicates the stack entry + add the n to the copy made by the DUP operation to itself ; end the definition To use 2X, let's multiply the number 3 by 2: 3 2X . 6 ok This is all very well, but if the power is turned off, then on, and we reboot FORTH, the word 2X is no longer in the dictionary. In this case we don't mind, as 2X is not that wonderful a word, and anyway, we already have the word 2* as a permanent part of FORTH. But what if we want to save the definition of a more complex word? Fear not! There are at least two solutions to the problem. One is to use the word SAVE-FORTH (which is not in the present copy of FORTH); the other is to use the editor to save a copy of the word on the disk and to LOAD it from the disk into the dictionary whenever we need it. (SAVE-FORTH is not usually included as part of the running FORTH system - it normally resides on the disk as a loadable module. Its function is to save an augmented version of FORTH back onto the boot section of the disk, so when FORTH is next booted from the disk, all additions made to the original version are saved.) Another word (or FORTH definition) which may be of interest is: : O. ( u -- ) BASE @ SWAP OCTAL U. BASE ! ; Let's dissect this word: : start a new definition O. name it O. ( u -- ) a comment which shows the stack contents before and after (This word leaves no elements on the stack.) BASE @ get the contents of the variable BASE (The current number-base, such as decimal, is stored in the variable BASE.) SWAP exchange the contents of BASE and u, so u is on top OCTAL set BASE to octal U. output the top of stack as an unsigned number BASE ! restore the original contents of BASE ; end the definition This word outputs the top stack item (the u) as an unsigned octal number without changing the current number base. Example: 10 O. 12 ok The decimal number 10 is converted to 12 octal (base eight). The word H. is similar to O. Try defining a word to output the top stack item as a binary number. Incidentally, it is not necessary to type the stack-picture comment, especially when entering a definition interactively from the keyboard. However, it is highly recommended to include stack pictures as comments when entering source code with the editor. Having prefix punctuation (example: "FF and '77) for number entry and H. and O. for number output, allows very convenient number conversion to hexadecimal, decimal, and octal. If you want to try other number bases, use: n BASE ! where n is between 2 and 71. Type: 36 BASE ! "!" denotes a store operation, and the statement 36 BASE ! causes all further numbers to be regarded as base 36 numbers. Type: ZOT . The answer -EVN indicates an overflow. Type: ZOT U. There is no overflow; the same number is returned. (U. treats numbers as unsigned with 16 bits of precision.) Type: ZOT DECIMAL U. The decimal equivalent of ZOT (base 36) is 46253. Type: ZOT ZOT is no longer convertible - it's not a base 10 number. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Words of Advice ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ For those wishing to practice using the editor, I have one word (well, many words) of caution. Start editing at screen 61 or above. Block 0 is the boot-sector and error messages, blocks 1 through 59 are used for an up to 59K version of FORTH, and block 60 is reserved for a table of contents. (The 1K chunks of storage on the disk are called blocks and are numbered from 0 to 319 on a double-sided disk. These same blocks are called screens when they are displayed by the editor. That is, block 61 on the disk is displayed as screen 61 on the CRT. Why the different names for the same size unit? Because in earlier versions of FORTH a block was 128 bytes of disk storage and 8 blocks made up a screen. The 79 and 83 Standards specify a block as 1024 bytes of storage.) ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ The Future ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ In my next column we investigate the process of interpreting FORTH words from the disk as well as from the keyboard. (Hint: there is almost no difference!) Again, to quote Henry Laxen, "may the FORTH be with you". ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ File Name: ÛÛ forth2.txt ÛÛ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ