/GEN-HELPNOTATION ARITHMETICINTEGERS+-*/1+1-2+2-2//MODABSMAXMINMODNEGATESHLSHRCSHRCSHL F_NOTATION FOPERATORSF+F-F*F/F<F>FSQRTFEXPFLOGFSINFCOSFATANP->R FTRANSFORM FSTACK_OPFSWAPFOVERFDUPFDROPFSTACK FCONSTANT FVARIABLEF!F@F,FLITERALF.F->EMA->FF->II->FF->SS->FS+S-S*S/ COMPARISON<<==>=>0>0=0<ANDNOTORU<XOR COMPILATIONPARSING\('TEXTH#`WORD[']>INCODE-GENC,W,,2, IMMEDIATELITERAL][ [COMPILE]COMPILESTATECOMPEXECUTEABORTABORT"CREATEALLOT::SHELL INTERPRET CONDITIONALDO{}LOOPBEGIN{}UNTIL}WHILE{}REPEAT}ENDIF}ELSE{IF{ DICTIONARYBROWSER DIR-DISPLAY MOVE-MODULE SAVES-N-LOADS SELECTIONEDITENV!PACKAGEFINDGETNAMEGETSIZEUPCHILDNEXTERRORSERRORERROR-01ERROR-02ERROR-03ERROR-04ERROR-05ERROR-06ERROR-07ERROR-08ERROR-09ERROR-10ERROR-11ERROR-12ERROR-13ERROR-14ERROR-15ERROR-16ERROR-17ERROR-18ERROR-19ERROR-20ERROR-21ERROR-22ERROR-23MOREERROR-24ERROR-25ERROR-26 SCREEN_I/O..".(.S<#U.COUNTTYPESPACESSPACESCREENQUERYPOPBOXKEYGOTOXYGETXYEXPECTEMITCRCLS?TERMCLREOLDISK_I/OWRITESEEKRENAMEREADOPENDELETE CREATEFILECLOSESTRINGS"##>#S#TIBA->IPADHOLDSIGNTIBSTR=MISCTRACETURNKEYI->DC!!C@@INOUTR@R>MEMORYDECIMALHEXBYEBASE>R:=STACK_OP?DUPSWAPOVERDEPTHPICKDUPDROP?STACKSTACK STRUCTURESDYNAMICDISPOSENEW DATA_STRUCT>BODYFILLERASEMOVEDOES>HERESCANCONSTANTVARIABLE!+!2!2@W!C!W@C@@ CTL_STRUCTBEGINWHILEREPEATUNTILIFELSEENDIFDOIJLEAVE+LOOPLOOPEXIT VMODE TEXTVMODEPALETTEPGETPSETPAINTMOVETOMOVETO?LINETOFILLBOXBOX CHANGED... INTERRUPTSINT:INTINT;INT[]INTCTRL-CSNAPSHOTSAVELOADSTDINSTDOUTGETOBJSIZEOBJFREEOBJCPUMATHCPU j@ By i c!!"")##!()+,X,,,i--3.r...)/i//122B3336^778q8 :::;<O==>>9??@v@DD;EEF/GG7HHdIIJ~L8MOGQQQTTU1VrW(YY[v]7_abXeeg]ikmmAn|n;ooKqru1yy{ }2~f ρW҅<esK-|צ5XkKT=I!vZZZ:xfc FZT%2Eo3)cs\j">G  c   4   s   c2tG}F!!!'""J& ((8,../Q///001X1b33k44U58 9|9f:: ;a;5<3=W> AoAA$B^BBB:CuCCDBD FJKMxP+STTUXrZZ[o\]^_ General Help 1-20-89 The HELP module provides an easy to use quick reference on primitives in the system. HELP can be called from the interactive mode by typing HELP followed by the module's name for which help is sought. Apropos HELP is available from within the text editor by placing the cursor on or before a module and pressing the F2 key. This screen may be displayed from within the text editor by placing the cursor past the last module in the text. If F2 is pressed on a User defined module, the dictionary editor is called with the User defined module as the local module. When you leave the dictionary editor, you will return to the text editor. (Be warned! An error before you return will cause the loss of the editing session.) A) NOTATION B) ARITHMETIC C) COMPARISON D) COMPILATION E) CONDITIONAL F) DICTIONARY G) ERRORS H) SCREEN_I/O I) DISK_I/O J) STRINGS K) MISC L) STACK_OP M) STRUCTURES N) O) CHANGED... Enter a letter for further help, or space to return. NOTATION ARITHMETIC COMPARISON COMPILATION CONDITIONAL DICTIONARYERRORS SCREEN_I/ODISK_I/OSTRINGSMISCSTACK_OP STRUCTURES CHANGED... Fifth is a powerful, truly functional language. As such, the most important documentation is that of the inputs and outputs of each function. We suggest the following notation be used on the first line of each module; this notation is also used through out the help facility. ( 32b1 32b2 -> 32b3 ) MOD returns the remainder 32b3 of 32b1 divided by 32b2. The inputs expected on the stack are given prior to the arrow, and the outputs are given after the arrow. Each input is described by a type and a number (to make it unique). The description of MOD given above says that MOD expects two 32 bit integers. These two 32 bit integers are replaced by a third 32 bit integer. This third integer is defined as the remainder left over when the first integer is divided by the second integer. We use the following types through out the help facility: 8b - an 8 bit integer addr - a valid Fifth address 16b - a 16 bit integer flag - a 32 bit integer, value 0 or -1 32b - a 32 bit integer A) F_NOTATION Enter a letter for further help, or space to return.  F_NOTATION Fifth supports 32-bit integer arithmetic, i.e. Fifth has a 32 bit stack. The floating point operators use their own stack and rely on the math coprocessor, and thus will not work on some systems. (If your system lacks the math coprocessor, you will get a Math Coprocessor Missing error when you attempt to use a floating point operator.) A) INTEGERS B) C) F. D) F->EM E) A->F F) F->I G) I->F H) F->S I) S->F J) S+ K) S- L) S* M) S/ Enter a letter for further help, or space to return. INTEGERSF.F->EMA->FF->II->FF->SS->FS+S-S*S/ Integers in Fifth are usually 32 bits in length. This gives a effective range of -2147483648 to 2147483647. Each element on Fifth's stack is 32 bits in length. Fifth provides the following integer operators. A) + B) - C) * D) / E) 1+ F) 1- G) 2+ H) 2- I) 2/ J) /MOD K) ABS L) MAX M) MIN N) MOD O) NEGATE P) SHL Q) SHR R) CSHR S) CSHL Enter a letter for further help, or space to return. +-*/1+1-2+2-2//MODABSMAXMINMODNEGATESHLSHRCSHRCSHL (32b1 32b2 -> 32b3) Add 32b1 to 32b2 yielding 32b3. (32b1 32b2 -> 32b3) Subtract 32b2 from 32b1 yielding 32b3. (32b1 32b2 -> 32b3) Signed multiply of 32b1 times 32b2 yielding 32b3. (32b1 32b2 -> 32b3) Divide 32b1 by 32b2, leaving quotient 32b3. A numerical overflow will occur if 32b2 is zero or 32b3 out of range. (32b1 -> 32b2) Increment 32b1 yielding 32b2. (32b1 -> 32b2) Decrement 32b1 yielding 32b2. (32b1 -> 32b2) Add 2 to 32b1 yielding 32b2. (32b1 -> 32b2) Subtract 2 from 32b1 yielding 32b2. (32b1 -> 32b2) Arithmetically shift 32b1 right 1 yielding 32b2. (32b1 32b2 -> 32b3 32b4) Divide 32b1 by 32b2, leaving quotient 32b4 and remainder 32b3. 32b3 has same sign as 32b2. A numerical overflow will occur if 32b2 is zero or 32b4 out of range. (32b -> u32b) Signed 32b is replaced by it's absolute value. (32b1 32b2 -> 32b3) Leave the larger of 32b1 and 32b2 on the stack as 32b3. (32b1 32b2 -> 32b3) Leave the lesser of 32b1 and 32b2 on the stack as 32b3. (32b1 32b2 -> 32b3) Divide 32b1 by 32b2 yielding remainder 32b3. 32b3 has same sign as 32b2, forces an error if 32b2 is zero or quotient out of range. (32b1 -> 32b2) Two's complement 32b1 yielding 32b2. (32b1 32b2 -> 32b3) 32b1 is shifted left 32b2 places, zeros are shifted in on the right. The result is 32b3. (32b1 32b2 -> 32b3) 32b1 is shifted right 32b2 places, zeros are shifted in on the left. The result is 32b3. (32b1 32b2 -> 32b3) 32b1 is shifted right 32b2 bits. Bits shifted out on the right are shifted back in on the left. 32b3 is the result. (32b1 32b2 -> 32b3) 32b1 is shifted left 32b2 bits. Bits shifted off the left are shifted in on the right. The result is 32b3. Fifth provides floating point using the 8087 math coprocessor family. If you do not have a math coprocessor, Fifth's floating point routines will not work on your machine. To use the floating point routines, you must use the package called . See the help on PACKAGE. Fifth uses 80 bit floating point arithmetic internally, but current I/O is limited to 32 bit accuracy. This gives six digits accuracy, with an exponent range of roughly +/- 10 to the 36. All floating point operations work with the separate floating point stack. This stack is limited to roughly 100 10-byte floating point numbers. When using inline assembly with the 8087, you can treat the 8087 as having a very large stack - underflow and overflow errors are handled by Fifth. A) F_NOTATION B) FOPERATORS C) FSTACK_OP D) FCONSTANT E) FVARIABLE F) F! G) F@ H) F, I) FLITERAL J) PACKAGE Enter a letter for further help, or space to return. F_NOTATION FOPERATORS FSTACK_OP FCONSTANT FVARIABLEF!F@F,FLITERALPACKAGE When the parameters of a floating point primitive are displayed, the integer stack parameters will be shown as usual, with a separate display for the floating point numbers. For example: (f1 f2 -> f3) Adds two floating point numbers. implies that the operation does not effect the integer stack, while (addr -> ) (f1 -> ) Stores a floating point value (10 bytes) at the address. implies that both stacks are effected. These are the basic floating point arithmetic operators: A) F+ B) F- C) F* D) F/ E) F< F) F> G) FSQRT H) FEXP I) FLOG J) FSIN K) FCOS L) FATAN M) P->R N) FTRANSFORM Enter a letter for further help, or space to return. F+F-F*F/F<F>FSQRTFEXPFLOGFSINFCOSFATANP->R FTRANSFORM (f1 f2 -> f3 ) Adds two floating point numbers. (f1 f2 -> f3 ) Subtracts two floating point numbers. (f1 f2 -> f3 ) Multiplies two floating point numbers. (f1 f2 -> f3 ) Divides two floating point numbers. (f1 f2 -> ) ( -> flag ) Compares two floating point numbers. If f1 is less than f2, flag is true (-1), otherwise flag is false (0). (f1 f2 -> ) ( -> flag ) Compares two floating point numbers. If f1 is greater than f2, flag is true (-1), otherwise flag is false (0). (f1 -> f2) Returns the square root of f1. (f1 -> f2) Returns e^X on floating point number f1. (f1 -> f2) Returns the natural log of f1. (f1 -> f2) Returns the SINE of angle f1, in degrees. (f1 -> f2) Returns the COSINE of angle f1, in degrees. (f1 -> f2) Returns the arctangent of f1, in degrees. (theta radius -> x y) Converts polar coordinates to rectangular. Theta is in degrees. (addr -> ) (f1 f2 f3 -> f1' f2' f3') Performs a 3x3 matrix transformation. Addr points to 9 floating point values which define the matrix. For example: create ident 1. f, 0. f, 0. f, 0. f, 1. f, 0. f, 0. f, 0. f, 1. f, creates an identity matrix. Then : x 1. 2. 3. ident ftransform f. f. f. ; transforms 1, 2 and 3 with the identity matrix (no change) and prints them. FTRANSFORM is useful for fast 3-D graphics. These stack operators manipulate the floating point stack: A) FSWAP B) FOVER C) FDUP D) FDROP E) FSTACK Enter a letter for further help, or space to return. FSWAPFOVERFDUPFDROPFSTACK (f1 f2 -> f2 f1) Top two stack elements are swapped. (f1 f2 -> f1 f2 f1) Stack is modified according to stack diagram. (f1 -> f1 f1) Duplicate the top-of-stack element. (f1 -> ) A floating point value is dropped from the stack. (32b1 32b2 ... -> ... ) fstack AB|ABAB (f1 f2 -> f1 f2 f1 f2) fstack ABC|CAB (f1 f2 f3 -> f3 f1 f2) fstack ABCDE|EE (f1 f2 f3 f4 f5 -> f5 f5) Let me explain the last example. A is deepest, E is on on the top of the stack on the `before' side of |. On the after side, E is the only thing left; ABCD were all thrown away, and E is DUPed, giving two copies of E. FSTACK can simplify understanding of complicated stack manipulations. However, for simple operations it is quite a bit slower, e.g. use FDUP instead of FSTACK A|AA. FSTACK is limited to no more than 26 elements on the before side, no limit on the after side. It is not case sensitive, but the letters on the before side must be in order "ABC..." . (f1 -> ) Next module in the input stream is compiled into the dictionary. Later execution of this name leaves f1 on the floating point stack. ( -> ) The next module in the input stream is CREATE'd, and 10 bytes reserved for it's use. (addr -> ) (f1 -> ) Store floating point value (10 bytes) at the address. (addr -> ) ( -> f1) The floating point value at the address is fetched. (f1 -> ) Floating point comma adds 10 bytes to the local module (the module currently under compilation) and initializes the 10 bytes to the value f1. For example, a variable PI could be defined and initialized to 4.5 by the code: create PI 3.14 f, The following code would print a the value of PI. PI f@ f. The value of PI could be changed to 3.1417 by the code 3.1417 PI f! (f1 -> ) Causes the top-of-stack value to be compiled just as if it where an inline number. (f1 -> ) Prints the floating point number. ( -> 32b1 32b2) (f1 -> ) Converts the floating point f1 to exponent 32b1 and mantissa 32b2. Mantissa is adjusted by RADIX to the 6th power, to allow six #'s to be used on it within a formatted string command sequence. (addr1 -> addr2 f1) The string whose length byte is pointed to by address #1 is converted to f1. Address #2 points to the first non-convertible character. f1 is a 32bit floating point value on the integer stack, use S->F to move it to the floating point stack for further work. (f1 -> ) ( -> 32b2) Converts floating point to integer, numerical overflow if f1 cannot be represented as an integer. ( -> f1) (32b1 -> ) Convert integer to floating point. (f1 -> ) ( -> s1) Move floating point number to the integer stack, where it is treated as a 32 bit real number. Such numbers can be dealt with the normal stack operators like DUP, and !, but .S will not print them properly. ( -> f1) (s1 -> ) Move 32 bit real number to the floating point stack. (s1 s2 -> s3 ) Adds two 32 bit real numbers, which are kept on the normal integer stack. (s1 s2 -> s3 ) Subtracts two 32 bit real numbers, which are kept on the normal integer stack. (s1 s2 -> s3 ) Multiplies two 32 bit real numbers, which are kept on the normal integer stack. (s1 s2 -> s3 ) Divides two 32 bit real numbers, which are kept on the normal integer stack. Flags in Fifth are integers where 0 is false and -1 is true. Logical operations can be done using AND, OR, NOT, and XOR with flags that are strictly true (-1) or strictly false (0), even though AND, OR, NOT, and XOR are bitwise operators. (This is because -1 has all bits set, and 0 has all bits clear; bitwise operators operate on all bits identically.) Many primitives that take a flag as an input (such as IF) will consider any non zero flag to be true, and 0 to be false. A) < B) <= C) = D) >= E) > F) 0> G) 0= H) 0< I) AND J) F< K) F> L) NOT M) OR N) U< O) XOR Enter a letter for further help, or space to return. <<==>=>0>0=0<ANDF<F>NOTORU<XOR (32b1 32b2 -> flag) The flag returned is true (-1) if 32b1 is less than 32b2, otherwise the flag is false (0). (32b1 32b2 -> flag) A true flag (-1) replaces 32b1 and 32b2 on the stack if 32b1 is less than or equal to 32b2, otherwise 32b1 and 32b2 is replaced with a false flag (0). (32b1 32b2 -> flag) A true flag (-1) replaces 32b1 and 32b2 on the stack if 32b1 is equal to 32b2, otherwise 32b1 and 32b2 is replaced with a false flag (0). (32b1 32b2 -> flag) A true flag (-1) replaces 32b1 and 32b2 on the stack if 32b1 is greater than or equal to 32b2, otherwise 32b1 and 32b2 is replaced with a false flag (0). (32b1 32b2 -> flag) Compares 32b1 with 32b2; if 32b1 is greater than 32b2, the flag is true (-1) otherwise the flag is false (0). (32b -> flag) Replace 32b with a true flag (-1) if 32b is greater than zero, otherwise replace 32b with a false flag (0). (32b -> flag) Replace 32b with a true flag (-1) if 32b is equal to zero, otherwise replace 32b with a false flag (0). (32b -> flag) Replace 32b with a true flag (-1) if n is less than zero, otherwise replace 32b with a false flag (0). (32b1 32b2 -> 32b3) 32b1 is bit-wise anded with 32b2 yielding 32b3. AND can be used to logically AND a flag so long as it is strictly true (-1) or false (0). (32b1 -> 32b2) One's complement 32b1 yielding 32b2. NOT can be used to logically NOT a flag so long as it is strictly true (-1) or false (0). (32b1 32b2 -> 32b3) Bitwise or 32b1 to 32b2 yielding 32b3. OR can be used to logically OR two flags so long as the flags are strictly true (-1) or false (0). (u32b1 u32b2 -> flag) flag is true (-1) if unsigned integer u32b1 is less than u32b2, otherwise flag is false (0). This primitive is especially useful in doing range checks where the lower bound is zero. For example: : x dup 10 u< ; X is defined to take a number as an input and return the number and a flag. The flag will be true (-1) if the number 0 or greater and less than 10; otherwise the flag will be false (0); (32b1 32b2 -> 32b3) Exclusive OR 32b1 bitwise with 32b2 yielding 32b3. XOR can be used to logically XOR two flags so long as the flags are strictly true (-1) or false (0). The Fifth compiler is unlike most compilers; It is made up of various bits and pieces that the programmer invokes as needed. Thus we can talk about modules being immediate, (They execute at COMPILE time!!) and modules generating code. The following is a list of compiling modules in Fifth: A) PARSING B) CODE-GEN C) COMP D) EXECUTE E) ABORT F) ABORT" G) CREATE H) ALLOT I) : J) : K) SHELL L) INTERPRET Enter a letter for further help, or space to return. PARSINGCODE-GENCOMPEXECUTEABORTABORT"CREATEALLOT::SHELL INTERPRET The following modules are used to parse the input stream. A) \ B) ( C) ' D) TEXT E) H# F) ` G) WORD H) ['] I) >IN Enter a letter for further help, or space to return. \('TEXTH#`WORD[']>IN ( -> ) Skip comments to the end of the line. ( -> ) All characters up to the closing ')' paren are ignored. This is the comment module. ( -> 32b ) "Tick" parses the input stream for the next token. If the next token is a number, the value of the number is pushed onto the stack. If the next token is a module, then the execution address of the module is pushed onto the stack. ' forces compilation (If the module is compiled if necessary). If you type the following code in the interactive mode: ' help getname count type then you will get the output HELP Note that ' is not immediate; You may define modules that call ' . Also see the module ['] . ( 8b -> ) Clears the PAD buffer, then reads from the input stream to the PAD buffer until the 8b delimiter is found. ( -> 32b1) The next token in the input stream is interpreted as a hexadecimal number. For example: h# A . 10 . will print 10 10 since A is hexadecimal for decimal 10. Note that the effect is only for the number immediately following h#. ( -> 8b1) Returns the ASCII value of the following character. For example ` A . will print 65 (8b -> addr) Parses the next module in the input stream delimited by the character specified by 8b, tabs, blanks, carriage-returns, line-feeds or nulls. Leading whitespace and delimiters are skipped, the word is left at address+1, with a count at address. The count is zero if the input stream is empty. ( -> ) Compiles the execution address of next module in input stream as a literal, later execution of code leaves the address on the stack. ['] is often used to obtain a pointer to a function. For example, : x ['] + ; The module X as defined above returns a pointer to the function + . Given this definition of X, the following typed in the interactive environment would print a 3. 1 2 x execute ( -> addr ) Leaves the address of the hardware pointer in the text input buffer. Use @ and ! to get this hardware pointer, but C@@ to read the buffer. Code Generation. Fifth provides these modules to give control over code generation. A) F, B) FLITERAL C) C, D) W, E) , F) 2, G) IMMEDIATE H) LITERAL I) ] J) [ K) [COMPILE] L) COMPILE M) STATE Enter a letter for further help, or space to return. F,FLITERALC,W,,2, IMMEDIATELITERAL][ [COMPILE]COMPILESTATE ( 8b -> ) "C-Comma" adds 1 byte to the local module (the module currently under compilation) and initializes the byte to the value 8b. For example, a buffer ABC could initialized to the counted string "abc" by the code: create abc 3 c, ` a c, ` b c, `c c, If ABC is defined as shown above, and you type: abc count type at the interactive prompt, Fifth would respond by printing: abc ( 16b -> ) "W-Comma" adds 2 bytes to the local module (the module currently under compilation) and initializes the 2 bytes to the value 16b. For example, a 2 byte variable LIFE-U&E could be defined and initialized to 42 by the code: create life-u&e 42 w, The following code would print a the value 42. life-u&e w@ . The value of life-u&e could be changed to 43 by the code 43 length-of-rain w! (32b -> ) "Comma" adds 4 bytes to the local module (the module currently under compilation) and initializes the 4 bytes to the value 32b. For example, a variable LENGTH-OF-RAIN could be defined and initialized to 40 by the code: create length-of-rain 40 , The following code would print a the value 40. length-of-rain @ . The value of length-of-rain could be changed to 10 by the code 10 length-of-rain ! (64b -> ) "Two-Comma" adds 8 bytes to the local module (the module currently under compilation) and initializes the 8 bytes to the value 64b. For example, a variable GRAINS-OF-SAND could be defined and initialized by the code: create GRAINS-OF-SAND 123456789 978654321 2, The following code would get the value of GRAINS-OF-SAND: GRAINS-OF-SAND 2@ The value could be changed by the code: 1 2 GRAINS-OF-SAND 2! ( -> ) IMMEDIATE sets the immediate flag on the local module. Immediate modules are executed whenever they are encountered, even if the compiler is on. For example, we could define a module [hex] that changes the base used by the compiler to hexadecimal as follows: : [hex] hex ; immediate If [hex] is defined as shown above, the code : print-a-number [hex] 20 . ; causes [hex] to be executed, changing the base used by the compiler to hexadecimal. The 20 is then interpreted as 20 base 16, or 32 in decimal. If you run PRINT-A-NUMBER from the interactive environment, fifth will print a 32. (32b -> ) Causes the top-of-stack value to be compiled just as if it where an inline number. ( -> ) The compiler is turned on. ] is normally used in conjunction with [ to change the base during compilation or to compute a constant. For example: : x [ .( Hit a key: ) key ] literal emit ; When the module X is compiled, the programmer is prompted to strike a key. Whatever key is struck by the programmer during the compilation of X is printed when ever X is executed (without any prompting; that's done at compile time). ( -> ) The compiler is turned off. [ is normally used in conjunction with ] to change the base during compilation or to compute a constant. For example: : x [ decimal ] 10 [ hex ] 10 + . ; The module X as defined above would print 26 if executed, since the first 10 was interpreted while the base was decimal, and the second 10 was interpreted while the base was hexadecimal. ( -> ) Causes a call to the next module in the input stream to be generated even if the next module is immediate; i.e. this allows an immediate module to be called. Here is a much needed example: \ ( -> ) When LIMIT is executed, a push of a 10 is generated (by \ literal). Note that just calling literal would not work, since \ literal is immediate. : limit 10 [compile] literal ; immediate \ ( -> ) Y will print the numbers 0 through 9, given x defined above. : y limit 0 do i . loop ; ( -> ) Causes a call to the next module in the input stream to be generated when the module containing COMPILE is run. For example: : plus compile + ; immediate : b 10 20 plus . ; Since PLUS is immediate, PLUS executes during the compilation of B. PLUS compiles a call to the module + and returns. The execution of B will then do the following: Push 10 on the data stack, Push 20 on the data stack, call + (adding 10 and 20), print the result (30) and return. ( -> flag ) Leaves the current value of the compiler flag. 0 is off, anything else is on. ( addr -> ) Compiles the module with execution address addr. (addr -> ) The code at the address is executed. ( -> ) All stacks are reset, all buffers are cleared, all files are closed, the radix is set to 10, input is from keyboard, the screen mode is reset and the compiler turned off. ( flag -> ) If the flag is true, the following message is printed, and ABORT is called. ( -> ) CREATE is used to define a data module. When executed, a data module pushes the address of its data area onto the stack. CREATE does not allocate any memory, however. For example, the following code allocates and initializes 12 bytes. create buff 10 , 12 , 20 , If BUFF is defined as shown above, the code buff @ . buff 4 + @ . buff 8 + @ . would print 10 12 20 ( 16b -> ) ALLOT allocates 16b bytes to the end of the current local module (a module under compilation becomes the local module). For example, a 1024 byte buffer could be defined with the code create buff 1024 allot The memory added to a module by ALLOT is not initialized to any particular value. ( -> ) : is used to begin a colon definition. Colon turns the compiler on; Semicolon turns the compiler off and compiles a return. This is best illustrated by an example: \ ( -> ) ADD-THREE&FOUR adds two numbers ( 3 and 4 ) and \ prints the result. : add-three&four 3 4 + . ; In this example, colon turns the compiler on. The next token is the name given to the colon definition. (In the text for a module, this name must match the name given in the dictionary editor.) Since the compiler is on, the code to push a 3 and a 4 onto the stack is generated, followed by code to call the + and the . modules. The semicolon turns the compiler off, and compiles a return. The net result is a module defined such that typing add-three&four in the interactive mode will print 7 ( -> ) : is used to end a colon definition. Colon turns the compiler on; Semicolon turns the compiler off and compiles a return. This is best illustrated by an example: \ ( -> ) PRINT-KEY waits for a key, then prints the numeric value \ corresponding to the key pressed. : print-key key . ; In this example, colon turns the compiler on. The next token is the name given to the colon definition. (In the text for a module, this name must match the name given in the dictionary editor.) Since the compiler is on, the code to call the KEY and . modules is generated. The semicolon turns the compiler off, and compiles a return. The net result is a module defined such that typing print-key in the interactive mode then pressing the Shift A key should print 65 ( -> ) In an infinite loop, prompts and reads from the keyboard, then calls INTERPRET on the input buffer. Use EXIT to leave a SHELL. SHELLs may be nested, or called from TRACE. ( -> ) Parses from the input buffer. Does the appropriate action based on what was parsed. Numbers get their value pushed on the stack; modules get executed. If the compiler is on, code to do the previous is executed instead. INTERPRET exits when the input buffer is exhausted. Fifth allows conditional compilation. These modules are written in Fifth themselves. They allow the program to make decisions at compile time, or in the interactive environment. A) DO{ B) }LOOP C) BEGIN{ D) }UNTIL E) }WHILE{ F) }REPEAT G) }ENDIF H) }ELSE{ I) IF{ Enter a letter for further help, or space to return. DO{}LOOPBEGIN{}UNTIL}WHILE{}REPEAT}ENDIF}ELSE{IF{ ( 32b1 32b2 -> ) The index is set to 32b2, and increments to 32b1. Text upto the enclosing }LOOP is repeated (reparsed). The value of the index, terminator and loop address is kept on the return stack. NOTE: DO{ is immediate. The Fifth file COND.FIV must be loaded to use DO{ ( -> ) Bumps the index provided by DO{, and checks it versus the terminator. If index equals the terminator, processing continues. If not, the text pointer is reset to just after the DO{. Use R@ to get the index. NOTE: }LOOP is immediate. The Fifth file COND.FIV must be loaded to use }LOOP ( -> ) Saves the text pointer on the return stack, used with }UNTIL or }WHILE{ and }REPEAT. NOTE BEGIN{ is immediate. The Fifth file COND.FIV must be loaded to use BEGIN{ ( flag -> ) If the flag is true, the return stack is popped and execution continues. If false, the text pointer is reset to just after an enclosing BEGIN{. The Fifth file COND.FIV must be loaded to use }UNTIL ( flag -> ) If the flag is true, execution proceeds. If false, the return stack is popped, and execution proceeds after the enclosing }REPEAT. The file COND.FIV must be loaded to use }WHILE{ ( -> ) The text pointer is reset to just after an enclosing BEGIN{. The Fifth file COND.FIV must be loaded to use }REPEAT ( -> ) Place marker for IF{ and }ELSE{ modules. This module does nothing. ( -> ) Skips text to the next }ENDIF. NOTE: }ELSE{ is immediate. ( flag -> ) If the flag is true, execution proceeds. If the flag is false, text is skipped till the next }ELSE{ or }ENDIF. NOTE: IF{ is immediate. The fifth dictionary is a complex data structure which contains the source, execution code, and data of a number of programs. Fifth provides the following primitives to give the programmer access to the dictionary structure. A) BROWSER B) EDIT C) ENV! D) PACKAGE E) FIND F) GETNAME G) GETSIZE H) UP I) CHILD J) NEXT Enter a letter for further help, or space to return. BROWSEREDITENV!PACKAGEFINDGETNAMEGETSIZEUPCHILDNEXT The following functions are available from the Browser (also referred to as the Dictionary Editor). Pressing the indicated key invokes the function. ESC - Exits the Browser. L - Loads a text file previously A - Makes a TURNKEY application. saved using 'S'. C - Forces the local module to Q - Quit to MS-DOS. compile. R - Renames the local module. E - Edits the local module. S - Saves a text file for a D - Deletes the selected module. later 'L'. G - Executes the local module. T - Toggles TRACE mode on or off. I - Inserts a new module before the F8 - Duplicate the module and it's selected module. children. The following categories provide more indepth help: A) DIR-DISPLAY B) MOVE-MODULE C) SAVES-N-LOADS D) SELECTION E) TRACE F) TURNKEY G) GEN-HELP Enter a letter for further help, or space to return.  DIR-DISPLAY MOVE-MODULE SAVES-N-LOADS SELECTIONTRACETURNKEYGEN-HELP [Local Module] F1-Help, Trace is OFF, Mem: 256000 Submodules.... Local module text Submodule text The browser allows inspection and editing of program structure. The name of the local module is displayed in the top left corner of the browser display. The local module's text is displayed under the first double line. The right and left arrows are used to select a submodule, or child, of the local module. As room on the screen permits, the text for the selected child is displayed beneath the second double line. (No matter how long the local module's text may be, at least the first line of the selected child's text is always displayed; by convention, this line should be a comment that gives the inputs and outputs for module. See NOTATION). A) NOTATION Enter a letter for further help, or space to return. NOTATION Moving Modules [X] F1-Help, Trace is OFF, Mem: = 25602 A B [C] D E PgUp : x a b c d e ;  : c 20 . ; PgDn If you hold the CTRL key down and press the left arrow key, the currently selected module will be moved to the left. CTRL-right arrow will move the currently select module to the right. CTRL-PgUp moves the selected module up the dictionary structure, just to the left of the local module; CTRL-PgDn moves it beneath the module left of the selected module. Given the display above, CTRL-left would make B and C change positions. CTRL-right would swap C with D. CTRL-down would move C under B. CTRL-up would move C up in the dictionary, just to the right of X. Suppose we wished to move A under E. The keys to do so would be (given the display above) left arrow (select B), left arrow (select A), CTRL-right (swap A & B), CTRL-right (swap A & C), CTRL-right (swap A & D), CTRL-right (swap A & E), CTRL-down (move A beneath E). The browser provides for saving and loading text to and from files. These files contain only printable ASCII characters. To save a particular module and its children, make sure this module is the local module (the module shown in the top left hand corner of the browser's display). Then press 'S'; the browser will prompt you for a file name. To reload the file, press 'L'; the browser will prompt you for the file name. The file will be loaded in after the last child of the current local module. A few notes are in order. First, we recommend that you give fifth programs a .FIV extension; this convention is not enforced however. Also note that the browser will save all the children of the local module (that are not primitives). Saving your programs with the root module as the local module will save the HELP module and a few others in addition to your modules. After a few saves and loads, you will notice your files growing rather large. To avoid this effect, we recommend you do your work beneath a appropriately named module; Saving this module will save only your work. Select Module [X] F1-Help, Trace is OFF, Mem: = 25602 A B C [D] E  : x a b c d e ;  : d 10 . ;  The arrow keys allow you to follow the structure of your programs. The left and right arrows change the selected submodule (or child) of the local module. Pressing the down arrow key makes the currently selected child the local module. Pressing the up arrow key moves you up in the dictionary; the old local module becomes the selected sub module, and its parent becomes the local module. Given the display above, the left arrow would change the selected module from D to C. The right would select E. The up arrow would make X the selected module, and X's parent the local module. The down arrow would make D the local module, with no child selected (The position just right of the last module). Edits the text of the local module. Key Function Key Function Home - Left on line F1 - This help text End - End of line F2 - Help on module under cursor PgUp - Up 23 lines F3 - Insert blank line PgDn - Down 23 lines F7 - Delete line Ins - Toggle insert mode F8 - Undelete line Del - Delete right F9 - Split line Ctrl-PgUp - Drag line up F10 - Join line Ctrl-PgDn - Drag line down Backspace - Delete left ESC - Exits the editor Return - Move down and left on line TAB - Skip to next column Shift-TAB - Skip backwards to previous column ^C - Abort the edit session, changes are NOT kept ^E - Scroll up 1 line ^G - Delete right ^N - Split line ^W - Toggle word wrap mode ^X - Scroll down 1 line ^Y - Delete line (addr -> ) Sets the local environment to the given module. The search path starts at this module. Unlike F83-FORTH, code is also generated in this module. ( -> ) Creates a module as a package; marks it as immediate. Later execution of the module puts it's children in the search path, before the normal search. For example, assume module X has children A, B and C: package x In module JOE we use X to allow access to it's children: : joe x a b c ; PACKAGE expands the normal scoping of Fifth. The floating point operators can only be reached by using a package called FLOAT. Up to 6 packages can be used for any module, they are searched in the reverse order of definition (i.e. the last package to be used in a module is searched first). A) B) Enter a letter for further help, or space to return.  (addr1 -> addr2 n) For a string with count byte at address #1, search for matching module name in dictionary. If found addr2 is the indirect execution address, n is 1 if immediate, -1 otherwise. If it's not found, then addr2 = addr1 and n=0. The search is first made through any active packages in reverse order of definition (packages added later are searched first), then the standard search up the tree to the root is made. (addr1 -> addr2) Returns the indirect address of the name of module addr1 points to. The name has a leading length byte. This is a READ-ONLY value. (addr -> 32b1) Returns the size of the given module. ( -> ) Raises the environment level, does nothing if at ROOT level. (addr1 -> addr2) Returns the address addr2 of the first child of module addr1. (addr1 -> addr2) Returns the address addr2 of the next module after module addr1. Errors and System messages are displayed in small pop-up boxes in the center of your screen. When an error occurs you have three choices: Press Return to enter the Dictionary Editor. Press ESC to enter the Interactive Mode. Press F1 for a description of the error (the description below that applies). Select help on ERROR for how to redefine Fifth's error handling. The other entries give descriptions of the causes of particular errors. In a turnkey program, errors just print the error number, and exit to DOS. A) ERROR B) ERROR-01 C) ERROR-02 D) ERROR-03 E) ERROR-04 F) ERROR-05 G) ERROR-06 H) ERROR-07 I) ERROR-08 J) ERROR-09 K) ERROR-10 L) ERROR-11 M) ERROR-12 N) ERROR-13 O) ERROR-14 P) ERROR-15 Q) ERROR-16 R) ERROR-17 S) ERROR-18 T) ERROR-19 U) ERROR-20 V) ERROR-21 W) ERROR-22 X) ERROR-23 Y) MORE Enter a letter for further help, or space to return. ERRORERROR-01ERROR-02ERROR-03ERROR-04ERROR-05ERROR-06ERROR-07ERROR-08ERROR-09ERROR-10ERROR-11ERROR-12ERROR-13ERROR-14ERROR-15ERROR-16ERROR-17ERROR-18ERROR-19ERROR-20ERROR-21ERROR-22ERROR-23MORE ( -> addr) Returns the address of the system-wide error handler. By default this is ABORT. If a different executable address is stored here, it will be passed a 8bit value in machine register AL as the error number, whenever an error occurs. If the error handler ever returns, it will be called again with error #1 (the ABORT error). This can quickly lead to infinite loops. User defined error handlers CANNOT just return. If you want to access the system after the error, call ABORT or SHELL from the handler. (ABORT cleans up the system state; we therefore advise the use of ABORT.) The value stored in ERROR needs to be a hardware address, it will be called directly. For example: ' user_error_handler i->d error ! would set up USER_ERROR_HANDLER as the user's own error handler. The module ABORT has been called, either by a user's program, or by Fifth's initialization code. At this point you may enter a key for more help, or hit a space bar to return to the error box (if that is where you came from). After you return to the error box, you may press: F1 for this text, RETURN to enter the Dictionary Editor, ESC to enter the Interactive Environment. In general, F1 gives context sensitive help. A) ABORT B) GEN-HELP Enter a letter for further help, or space to return. ABORTGEN-HELP You have loaded a text file from the Dictionary Editor. You typed Control-C or Control-Break. Typing Control-C will often stop a running Fifth program. The ABORT code is called to initialize the system state. This includes freeing all dynamically allocated memory, closing all open files, and clearing the stacks. The token displayed as the title of the message box was not found in the dictionary, nor could it be converted into a number. This error is usually caused by a typo, or a reference to a module not yet defined. You tried to use floating point operations without having an 8087 math chip in your system. Underflow is caused by using more items on the data stack than the data stack contains. Check the logic of your program; you probably forgot to DUP something. ?STACK checks for this condition at run time. Severely underflowing the stack can be fatal to your system. You may want to save your text, reboot, run Fifth and reload your text. Overflow is caused by pushing more items on the data stack than the data stack can hold (500 values). Usually means your program has pushed a value on the stack for every iteration of a long loop. This condition can be fatal. You may want to save your text, reboot, run Fifth and reload your text. Return Stack underflow is caused by pulling too many items off the return stack, probably with R>. This condition is fatal; you are lucky to be alive. You should save your text, reboot, run Fifth and reload your text. Return Stack overflow is caused by pushing too many items on the return stack, probably with >R, or by calling a module recursively. This condition is fatal; you are lucky to be alive. You should save your text, reboot, run Fifth and reload your text. Floating Point Stack underflow is caused by pulling too many items off the floating point stack. Floating Point Stack overflow is caused by pushing too many items on the floating point stack. This module can only be executed when the compiler is on. It probably generates code when it executes, and there's no place to put code in the interactive mode. You'll have to use this module from inside a colon definition. IF's must have matching ENDIF's, ELSE's belong inside IF - ENDIF pairs. DO's must have matching LOOP's or +LOOP's. LEAVE's and I's must be inside a DO - LOOP. J's must be nested inside two DO - LOOP pairs. Any BEGIN's must have an UNTIL or a WHILE and a REPEAT. Control structures nest inside each other; you cannot start one, start another, then finish the first one. Check your program for forgotten or misplaced control structures. In addition, the data stack must be balanced across the compilation of a module. This means that the compilation of a module cannot leave items on the data stack. You have more IF's, BEGIN's, and DO's currently under compilation than the internal compiler stack can hold. This is probably caused by trying to compile a large program all at once; the nested compilations overflowed the compiler stack. Try using the Browser to compile your program in pieces. Out of Memory! You may have the memory you need, but it could be too fragmented to make use of it. This error causes the heap to be compressed, so you could try the operation again. If it fails twice, you may have to try more drastic measures. You could delete unused, space consuming primitives - the graphics or floating point routines, for example. You could remove the text from pieces of your program that are working. You could expand the memory in your system (up to the limit of the hardware). Finally you could shrink your application. You attempted to execute a module that wasn't compiled and didn't have any text. When the Fifth system tried to compile it, there wasn't anything to compile! Add some text, or quit trying to use this module. This error commonly happens to newcomers to Fifth, when they try to use the Go key from the Dictionary Editor on a module without text (such as the root module). This is a tricky one! The text for the module that tried to compile CREATE'ed a module with a different name. The text for module needs to create its own name. You probably typo'ed the name in the text, or tried to define a module other than `FIFTH' at the root module. Change the name of the module your defining (the Rename function from the Dictionary Editor) or edit your text, and change the text name to match the module name. For example if your screen looks like this: Ŀ [FIFTH] F1 - Help, List of primitives.... : x ." Hello, world" ; You're trying to create a module X in a module named Fifth. Fifth was in the middle of compiling when it ran out of text. Probably caused by forgetting the `;' to end a colon definition. If you are doing tricky things with the compiler, make sure you turn it off before you run out of text. You used ' (tic) or some other parsing module, but didn't have a token to parse. Make sure your using the module right - ' (tic) executes at run-time, but ['] executes at compile time. Whenever the module executes, the input stream needs to have a token in it to be parsed. You used a string parsing module, but failed to close the string literal. Probably you forgot the closing quote in a " (quote) string literal, or the closing parenthesis in a ( comment. This is an error MS-DOS returns. You probably got it when trying to load text from DIR or when saving the system. On a load it probably means you misspelled the name. On a save it probably means you ran out of disk space. MS-DOS returns a number of other errors, of which Fifth does not report properly. If you don't think your error was caused by one of the above conditions, you'll have to use your intuition to figure out what's wrong. Ouch! This one's really complicated. You have got a set of modules which all use each other to compile. To compile any one of them means that another one has to be compiled. If Fifth can compile any one of them, then the loop is broken and they all can be compiled. The problem is that to compile one module requires the execution of another. Before you can execute it, it must also be compiled, and to compile it requires the execution of another module... Get the picture? Try simplifying things somewhat, pick a module and remove the references to the other modules from it. You attempted to store a value at a bad address. This error is similar to range checking done by some systems. This is probably caused by an array index being out of bounds or an address calculation gone bad. More Errors are listed here... A) ERROR-24 B) ERROR-25 C) ERROR-26 Enter a letter for further help, or space to return. ERROR-24ERROR-25ERROR-26 The parameter to a STACK module was poorly formed or you attempted to load a damaged text file. See HELP on STACK or LOAD, as appropiate. The Math Coprocessor signaled some exception. Typically this is the result of taking the square root of a negative number, or other illegal operation. Your program could not be converted to a standalone application. Either some needed primitives had been deleted from the system, or your program tried to include the FIND module. Some of the primitives are cross-linked internally. For instance, FCOS uses FSIN. If you delete FSIN from the system, but use FCOS in a program, the created program will not work, and cannot be made into a standalone application. If you think this is the problem, exit to DOS, and load a fresh Fifth system with all primitives intact. Standalone programs cannot include the FIND module. Some primitives use FIND internally, these include INTERPRET, SHELL, COMP, ' (tic), CREATE, COLON, .S and TRACE. These primitives provide for screen management and for reading the keyboard. A) . B) ." C) .( D) .S E) <# F) U. G) F. H) COUNT I) TYPE J) SPACES K) SPACE L) SCREEN M) QUERY N) POPBOX O) KEY P) GOTOXY Q) GETXY R) EXPECT S) EMIT T) CR U) CLS V) ?TERM W) CLREOL Enter a letter for further help, or space to return. ..".(.S<#U.F.COUNTTYPESPACESSPACESCREENQUERYPOPBOXKEYGOTOXYGETXYEXPECTEMITCRCLS?TERMCLREOL (32b -> ) Signed integer number is printed in the current radix with a trailing blank. For example, typing: 1 . -2 . 10 . 300 . would produce the results: 1 -2 10 300 The . operator makes use of the current base, so if you want to know what the value of a number in hex might be, you could type: 34534 hex . which would print the value 34534 converted to hexidecimal, or 86E6. A) HEX B) DECIMAL C) BASE Enter a letter for further help, or space to return. HEXDECIMALBASE ( -> ) Builds the code inline to print the following string up to the terminating quote. i.e. if X were defined as: : x ." Hello World!" ; Then executing X would result in the output: Hello World! ( -> ) Following string is immediately displayed, until the terminating parenthesis. .( is an immediate operator, meaning that it is executed at compile time. One use of .( is to leave messages to yourself in your code. Then whenever your code is compiled, these messages will remind you of patches or temporary code still present in your code. For example, if I need to compute a value in my final program, but for debugging I hard code the value to 10, I might write the code: : myprogram 10 .( When you get to it, compute a value in myprogram!) ; When myprogram COMPILES it will print the message in the parenthesis. At run time (when myprogram is executed), it will return a 10, but will print no message. (32b1 32b2 ... -> ) (f1 f2 ... -> ) Non-destructive print of all values on stack as signed integer values. Valid addresses are also printed as ModuleName+Offset. If the address is an execution address, a tic is printed before the ModuleName. You will notice when using string literals that they are interpreted as a value offset into the module in which they are defined. The floating point stack is displayed on the next line (Not allowed on machines lacking a coprocessor). For example, a routine defined as : x 1 2 " hello" 1.3 .s ; will print something like: 1 2 777345643 ('x+39 ) -TOS- 2.399999e0 -float TOS- ( -> ) Reset the formatted string length and pointer. Subsequent use of #, hold, and sign can be used to build a number in the PAD buffer. For example: 1022 <# # # # # # #> type Will print: 01022 The pad buffer at this point would contain the length of the string at the byte prior to the PAD address, followed by the ASCII codes '1022'. A) SIGN B) HOLD C) # Enter a letter for further help, or space to return. SIGNHOLD# (u32b -> ) The unsigned integer u32b is printed. (addr1 -> addr2 8b) The string whose length byte is pointed to by address #1 has it's length byte pushed onto the stack, address #1 is incremented yielding address #2. (addr +n -> ) +n characters from the string at address are echoed to the terminal. (32b -> ) Output 32b spaces to the terminal. ( -> ) Output a space to the terminal. ( -> 32b) Returns the indirect address of the current video text screen. SCREEN is compatible with such primitives as FILL and MOVE. On the IBM, SCREEN keeps track of the correct screen for both black & white and color screens. ( -> ) Causes the input buffer to be flushed and read. ( x1 y1 x2 y2 border interior title contents -> 8b) Displays a popbox from x1,y1 to x2,y2, with specified border and interior colors. The title must be a null terminated (NOT length byte) string. The contents is also a null terminated string. No error checking is done, so bad x,y values, or strings that are too long will look bad. ( -> 8b) Wait for a character from the standard input stream, do not echo it. Single CR's and CR/LF pairs are mapped to LF's. ( 32b1 32b2 -> ) Moves the cursor to column 32b1, row 32b2. ( -> 8b1 8b2 ) Returns the cursor position as column 8b1 (0-79), row 8b2 (0-24). (addr 8b1 -> addr 8b2) Read 8b1 characters at addr or until a CR, with backspace editing. 8b2 is the number of characters read. If ESC is pressed, editing is aborted immediately and 8b2 is -1. If a function key is pressed, editing is aborted immediately and 8b2 is 0. The returned string is null terminated. (8b -> ) The 8b value is sent to the standard output stream. LF's are mapped to CR/LF pairs. ( -> ) Sends a carriage-return/line-feed pair to the standard output stream. ( -> ) Clear the screen and home the cursor. ( -> flag) Leave a true flag if a character is available from the standard input stream, otherwise leave a false flag. ( -> ) Clears from the cursor position to the end of the line. The following primitives are used to read and write to files. A) WRITE B) SEEK C) RENAME D) READ E) OPEN F) DELETE G) CREATEFILE H) CLOSE Enter a letter for further help, or space to return. WRITESEEKRENAMEREADOPENDELETE CREATEFILECLOSE (addr 32b1 32b2 -> 32b3 -1) or (addr 32b1 32b2 -> 32b3 0) Write buffer at address. Buffer length written is 32b1 bytes. File handle is 32b2. 32b3 is the number of bytes written followed by -1, or 32b3 is an error number followed by 0. (32b1 8b 32b2 -> 32b3 -1) or (32b1 8b 32b2 -> 32b4 0) Moves file pointer 32b1 bytes from offset specified in 8b, in file with handle 32b2. Returns new file pointer position 32b3 and a true flag, or error code 32b4 and a false flag. If 8b = 0 then offset is from file beginning, if 8b = 1 then offset is from the current position, if 8b = 2 then offset is from end of file. (addr1 addr2 -> -1) or (addr1 addr2 -> 32b1 0) File with name at addr1 is renamed to name at addr2. Returns a true flag, or error code 32b1 and false flag. Note that addr1 and addr2 are expected to be null terminated strings; if using string literals to specify the files, the addresses must be incremented to skip the count bytes. i.e. " FILE.NEW" 1+ " FILE.OLD" 1+ rename Will attempt to rename FILE.NEW to FILE.OLD. (addr 32b1 32b2 -> 32b3 -1) or (addr 32b1 32b2 -> 32b3 0) The buffer at address is filled with 32b1 bytes from file with handle 32b2. 32b3 is the number of bytes actually read, unless an error occurred. Then 32b3 is the error code. (addr 8b -> 32b1 -1) or (addr 8b -> 32b2 0) Opens existing file with name at address. 8b is 0 for read, 1 for write, 2 for read and write. Returns 32b1 as file handle and true flag, or 32b2 as error code and false flag. The 32b1 handle will be used in all I/O with the file. Note that if you use a string literal to specify a file name, it must be incremented to skip the count byte. i.e. " file.old" 1+ 0 open Would open the file FILE.OLD for read access. (addr -> -1) or (addr -> 32b1 0) Deletes file with name at address. Returns a true flag, or error code 32b1 and a false flag. Note that addr points to a null terminated string. If you are using a string literal to specify the file name, it must be incremented to skip the count byte. i.e. " trash.jnk" 1+ delete Would attempt to delete the file TRASH.JNK. (addr 32b1 -> 32b2 -1) or (addr 32b1 -> 32b2 0) Create file with name at address and attributes 32b1. 32b1 is 1 = read only, 2 = hidden, 4 = system, 20h = archive. Sum bits for multiple attributes. 32b2 is the file handle, unless an error occurred, then 32b2 is the error code. Note that CREATEFILE expects addr to point to a null terminated string; if using a string literal to specify the file name, it must be incremented to skip the count byte. i.e. " FILE.NEW" 1+ 0 createfile Would attempt to create a file named FILE.NEW. (32b1 -> -1) or (32b1 -> 32b2 0) Close file with handle 32b1. Returns true flag if no error. Returns false flag and error code 32b2 if error. The following primitives are used to manipulate strings A) " B) # C) #> D) #S E) #TIB F) A->I G) PAD H) HOLD I) SIGN J) TIB K) STR= Enter a letter for further help, or space to return. "##>#S#TIBA->IPADHOLDSIGNTIBSTR= ( -> addr ) Compiles a string literal inline, up to the terminating quote. Returns the address of the length byte of the literal. Note that if you are using string literals to specify file names, you need to increment the address returned by the literal to skip the count byte. Also note that even though the count for the string literal will only be accurate for strings less than 255 characters in length, longer literals are allowed, since string literals are null terminated as well as counted. (+32b1 -> +32b2 ) Positive number +32b1 is divided by the current radix. The remainder is converted to a digit and stuffed into the formatted string buffer. The quotient is left on the stack. Notice that all values already present in the formatted string buffer PAD are moved right before the new value is stuffed in. So the following code: 1024 <# # #> type 4 1024 <# # # #> type 24 1024 <# # # # #> type Will print -> 024 1024 <# # # # # #> type 1024 1024 <# # # # # # #> type 01024 A) <# B) #> C) #S D) HOLD Enter a letter for further help, or space to return. <##>#SHOLD (32b -> addr +n ) Number on stack is replaced by the address and length of the formatted string buffer. (+32b -> 0 ) All remaining digits of 32b are placed in the formatted string buffer. ( -> addr) Leaves address of terminal input buffer, first byte is length, next is buffer. Use C@ or COUNT to get the length. (addr1 -> addr2 32b) The string whose length byte is pointed to by address #1 is converted to 32b. Address #2 points to the first non-convertible character. ( -> addr) Leaves the address of the start of the formatted string buffer on the stack. (8b -> ) Pushes the 8b character into the formatted string buffer. (32b -> ) Place a sign '-' character in the formatted string buffer if 32b is less than zero. ( -> addr) Leaves the address the start of the terminal input buffer on the stack. (addr1 addr2 -> flag ) Compares two null terminated strings. Returns a true flag (-1) if all characters match, a false flag (0) otherwise. This section describes primitives that do not lump into any one category. A) TRACE B) TURNKEY C) I->D D) C!! E) C@@ F) IN G) OUT H) R@ I) R> J) MEMORY K) DECIMAL L) HEX M) BYE N) BASE O) >R P) := Enter a letter for further help, or space to return. TRACETURNKEYI->DC!!C@@INOUTR@R>MEMORYDECIMALHEXBYEBASE>R:= ( -> ) TRACE moves the cursor to the screen top, and prints the stack and the module about to be executed. If F1 is hit, this message is shown. If the space bar is hit, execution proceeds normally. If ESC is hit, ABORT is called. If return is hit, a nested SHELL is invoked. Other keys are ignored. If Trace is set on from the DIR command, TRACE is called before each module in the module being traced. If TRACE is used in a module, it functions as a breakpoint. If you have nested a SHELL, use EXIT to quit the SHELL. Module .S is used to display the stack contents; they are displayed symbolically. See the .S help for a description. A) .S B) SHELL Enter a letter for further help, or space to return. .SSHELL ( -> ) Builds a stand alone out of the local module. This program is given an .EXE extension and includes only the executable code of the modules actually called directly or indirectly by the local module. Unused modules, unused portions of the Fifth kernel, and text are not included in this file. Some code optimization is also done. Complete range checking on all stores and fetches is done so long as a program is executed under the Fifth environment. When a turnkey program is generated, this range checking is not done, under the assumption that a turnkey program has been thoroughly debugged. In addition, the error handler is changed to one that just prints the message 'Fifth error' and exits to DOS, setting the DOS error code. If you want more extensive error handling see ERROR. TURNKEY can be called directly from the Browser by making the desired module the local module and pressing 'A' for Application Generator. TURNKEY will recompile your program several times, and may take a moment to complete. A) ERROR Enter a letter for further help, or space to return. ERROR (addr -> 32b) Convert indirect address to a direct hardware 32b address. ( 8b 32b -> ) Store the 8b value at the 32b direct hardware address. (32b -> 8b) The 8b value at the direct hardware address 32b is fetched. (32b -> 8b) Input 8b from port number 32b. (8b 32b -> ) The 8b value is outputted thru port number 32b. ( -> 32b) Copies a value from the return stack and places it on the data stack. ( -> 32b) Pulls a value from the return stack and places it on the data stack. ( -> 32b) Returns the amount of free memory. Memory could be fragmented, saving and reloading Fifth will compress the HEAP. ( -> ) Force the radix to base 10. ( -> ) Force the radix to base 16. ( -> ) Exits to calling procedure. (MSDOS) ( -> addr) Leaves the address of the radix. Valid radix are in the range 2 to 72. (32b -> ) 32b value is pushed onto the return stack. ( addr -> ) To use this word, you must load ASSIGN.FIV. This word allows conventional expressions to be written in Fifth. It expects an address on the stack. This is where the results of the expression will be stored. For example, a := ( 5.0 + 6.0 ) * ( b / ( d - e [ 3 ] ) ; will assign to A the value of the given expression. Notice that spaces ARE required between each operator, variable, etc. Also notice the use of the array E. Its subscript, 3, is inclosed by square brackets. E must be defined as an array using DOES>. Each element in the array must be four bytes long. A two dimensional array can be included by inclosing each subscript in square brackets. For example, b := a [ 4 ] [ 6 ] ; Every statement must be ended with a semicolon. Notice that mixed mode arithmetic is NOT supported. If you want the n+1 element of an array, you must write something like: n @ 1+ tmp ! b := e [ tmp ] + 8.0 ; Single integer constants are allowed, but a := 3 + b ; is the same as 3 b @ f+ a ! These stack operators manipulate the data stack: A) ?DUP B) SWAP C) OVER D) DEPTH E) PICK F) DUP G) DROP H) ?STACK I) STACK Enter a letter for further help, or space to return. ?DUPSWAPOVERDEPTHPICKDUPDROP?STACKSTACK (32b -> 32b 32b) or (0 -> 0) If the top-of-stack value is zero, nothing occurs, otherwise it is duplicated. (32b1 32b2 -> 32b2 32b1) Top two stack elements are swapped. (32b1 32b2 -> 32b1 32b2 32b1) Stack is modified according to stack diagram. ( -> n) Return the depth of the stack, not counting n. (+n -> 32b) Leave a copy of the nth stack location over +n. +n is zero based so DUP is the same as 0 PICK and OVER the same as 1 PICK. (32b -> 32b 32b) Duplicate the top-of-stack element. (32b -> ) A 32b is dropped from the stack. ( -> flag) Returns a true flag if the stack has underflowed. (32b1 32b2 ... -> ... ) stack AB|ABAB (32b1 32b2 -> 32b1 32b2 32b1 32b2) stack ABC|CAB (32b1 32b2 32b3 -> 32b3 32b1 32b2) stack ABCDE|EE (32b1 32b2 32b3 32b4 32b5 -> 32b5 32b5) Let me explain the last example. A is deepest, E is on on the top of the stack on the `before' side of |. On the after side, E is the only thing left; ABCD were all thrown away, and E is DUPed, giving two copies of E. STACK can simplify understanding of complicated stack manipulations. STACK is limited to no more than 26 elements on the before side, no limit on the after side. It is not case sensitive, but the letters on the before side must be in order "ABC..." . Fetching and storing data is how Fifth deals with variables. The looping and testing constructs let Fifth programs make decisions. The block operations are fast primitives. A) DYNAMIC B) DATA_STRUCT C) CTL_STRUCT Enter a letter for further help, or space to return. DYNAMIC DATA_STRUCT CTL_STRUCT Primitives for allocating and deallocating memory from Fifth's heap. A) DISPOSE B) NEW Enter a letter for further help, or space to return. DISPOSENEW (addr -> ) Deletes module with parameter area address, and all sub-modules and related text. Does not mark following modules as 'Not Compiled' , therefore it should not be used to delete code modules. Usually used to remove modules created by NEW. ( -> addr) Creates a module, exactly as CREATE does, except the name is always a '' a special character). Returns addr as the parameter area. Used for dynamic storage allocation to the HEAP. The local environment is changed to the new module. This allows ALLOT to allocate storage to the new object. Use UP to restore the local environment, after all allocations are done. A) UP Enter a letter for further help, or space to return. UP These primitives are used to build and maintain data structures. A) FCONSTANT B) FVARIABLE C) F! D) F@ E) >BODY F) FILL G) ERASE H) MOVE I) DOES> J) HERE K) SCAN L) CONSTANT M) VARIABLE N) ! O) +! P) 2! Q) 2@ R) W! S) C! T) W@ U) C@ V) @ Enter a letter for further help, or space to return.  FCONSTANT FVARIABLEF!F@>BODYFILLERASEMOVEDOES>HERESCANCONSTANTVARIABLE!+!2!2@W!C!W@C@@ (addr1 -> addr2) Convert the execution address addr1 to a parameter field address addr2. (addr 32b 8b -> ) From address, 32b bytes are filled with 8b. (addr 32b -> ) Zeros 32b bytes at addr. (addr1 addr2 32b -> ) 32b characters from addr1 are moved to addr2. MOVE is smart, i.e. if addr1 and addr2 overlap data is moved such that it is not destroyed. (If you wish a fill effect, use FILL). ( -> ) Causes the address of the code following the DOES> to be placed in the current module's indirect parameter address. Later execution of a module CREATE'd with this module will execute the code following the DOES>. The current module's compilation is completed without executing this code. For example, if one wished to build a general routine for defining arrays: : array allot does> swap 4 * + ; Could be used to define an array of 32bit numbers. It would be used create x 100 array Note that the create is done in the module to avoid problems in building stand alone applications. the code " 0 X " would return the address of the first element of X, a 100 element array of 32 bit numbers. " 1 X " would return the address of the second element, etc. ( -> addr ) Returns the address of the end of the executable/data area. For example, if Y and Z are defined to be variables, and X is defined as: create x 10 , here y ! 20 , here z ! 30 , Then after x is compiled, the code: y @ @ . z @ @ . would result in the output: 20 30 Here can also be used to patch up references in data structures or executable code. ( addr 32b1 8b -> 32b2 ) Scan 32b1 bytes at addr for 8b. Return 32b2 as offset + 1 of first occurrence of byte 8b in addr. Return 0 if byte not found in 32b1 characters. If byte is first character, 32b2 is 1. (32b -> ) Defines a named constant. Hard coded magic numbers should be avoided since such values make maintaining and modifing code difficult. The code: 1000 constant limit defines a module LIMIT which may be used anywhere you would have used the number 1000. Now if the value of LIMIT were changed, the new value would automaticly be reflected through out your program. Note that changing a constant is one of the few things one can do to mess up Fifth's incremental compilation scheme. Constants compile a push of their value at compile time; all modules that reference a constant must be recompiled to reflect a change in the value of a constant. This can be done by moving a module (forcing all modules left and below the modules to be uncompiled), or by saving, deleteing and reloading your program. ( -> ) Defines a variable of 4 bytes in length. For example, if X were defined as: variable x then x could be used in conection with @ and ! to fetch and store 32bit values. The initial value of X would be undefined. If you wish to give X a defined value at compile time, you would use CREATE to define X: create x 10 , This second definition of X has the same effect as the first except that in the second case, X is initialized to a value of 10 at compile time. A) CREATE Enter a letter for further help, or space to return. CREATE ( 32b addr -> ) Store the 32b value at the address. (32b addr -> ) Add 32b to the value at the address. (64b addr -> ) Store the 64b value into the address. (addr -> 64b ) Fetch the 64b value stored at the address. (16b addr -> ) 16b value is stored at address. (8b addr -> ) 8b value is stored at address. (addr -> 16b) 16b value is fetched from the address, the high bytes are set to zero and placed on the stack as a 32b value. (addr -> 8b) 8b value is fetched from the address, the high bytes are set to zero and placed on the stack as a 32b value. (addr -> 32b) The 32b value at the address is fetched. Control Structures. These primitives provide for building loops and conditional branches. A) BEGIN B) WHILE C) REPEAT D) UNTIL E) IF F) ELSE G) ENDIF H) DO I) I J) J K) LEAVE L) +LOOP M) LOOP N) EXIT Enter a letter for further help, or space to return. BEGINWHILEREPEATUNTILIFELSEENDIFDOIJLEAVE+LOOPLOOPEXIT ( -> ) Marks the beginning of a BEGIN body test UNTIL loop or a BEGIN test WHILE body REPEAT loop. (flag -> ) Used to test for loop termination in a BEGIN test WHILE body REPEAT loop. If the flag is false the loop is exited past the REPEAT. ( -> ) Causes a loop to an enclosing BEGIN in a BEGIN test WHILE body REPEAT construct. (flag -> ) Loops to enclosing BEGIN if flag is false, otherwise the loop terminates. Used in BEGIN body test UNTIL loops. (flag -> ) Used in a test IF true-body ENDIF or test IF true-body ELSE false-body ENDIF construct. Branches according to whether the flag is non-zero (true) or zero (false). For example: -1 if \ Tests the -1 (which is trivially true) ." Howdy" \ True body (which will be executed in else \ this example) ." Hello" \ False body (which will be skipped in endif \ this example) would print "Howdy". The ELSE clause is not required. This example could be coded as follows as well, with the same results: -1 if \ Tests the -1 (which is trivially true) ." Howdy" \ True body (which will be executed in endif \ this example) ( -> ) Used in a test IF true-body ELSE false-body ENDIF construct. ( -> ) Used inside a test IF true-body ENDIF or test IF true-body ELSE false- body ENDIF construct. (32b1 32b2 -> ) Move 32b1 and 32b2 to the return stack. 32b2 is the initial value and 32b1 is the limit. All code between the DO and the LOOP or +LOOP is repeat until the index crosses the (limit-1) to (limit) boundary. ( -> 32b) Leaves the value of the innermost DO index on the stack. ( -> 32b) Leaves the value of the second innermost DO index on the stack. ( -> ) Causes the innermost DO body LOOP construct to be exited immediately. (n -> ) Add the value n to the loop index, if the index crossed the (limit - 1) to (limit) boundary terminate, otherwise loop to the enclosing DO. The index and limit values are on the return stack. ( -> ) Increments the loop index by one, in a DO body LOOP construct. If the index crosses the (limit-1) to (limit) boundary, then the index and limit are removed from the return stack and the loop is terminated, otherwise loops to the DO. ( -> ) If encountered with the compiler on, EXIT generates code to exit the current module. >R and R> modules must be balanced, but DO/LOOP's do not. If the compiler is off, EXIT exits the currently nested SHELL. If a SHELL was invoked from TRACE, use EXIT to continue tracing. Fifth supports IBM CGA style graphics, with a resolution of 320x200 with 4 colors. If you have this type of display adapter a 4 VMODE will put you in graphics mode. Color is a number from 0 to 3. To use these words you need to use the package called . See help on PACKAGE. A) VMODE B) TEXTVMODE C) PALETTE D) PGET E) PSET F) PAINT G) MOVETO H) MOVETO? I) LINETO J) FILLBOX K) BOX L) PACKAGE Enter a letter for further help, or space to return. VMODE TEXTVMODEPALETTEPGETPSETPAINTMOVETOMOVETO?LINETOFILLBOXBOXPACKAGE ( mode -> ) Set the video display mode, both black & white and color modes are supported. ( -> ) Set the video display mode to the default video mode, generally a text mode. ( 32b1 32b2 -> ) 32b1 is the background color, and 32b2 is either 0 or 1. ( x y -> color ) Returns the color of a point. ( color x y -> ) Set a point. ( x y color1 color2 -> ) Starting at (x,y), fill the screen with color1, stopping on both color boundaries. (x y -> ) Sets the current graphics draw point. ( -> x y) Gets the current graphics draw point. ( color x y ) Draws a line from the current draw point to x,y. Sets x,y as the new draw point. ( color x1 y1 x2 y2 -> ) Fills a box. ( color x1 y1 x2 y2 -> ) Draws a box. The following entries have been altered recently. A) INTERRUPTS B) SNAPSHOT C) SAVE D) LOAD E) STATE F) STDIN G) STDOUT H) GETOBJ I) SIZEOBJ J) FREEOBJ K) CPU L) MATHCPU Enter a letter for further help, or space to return. INTERRUPTSSNAPSHOTSAVELOADSTATESTDINSTDOUTGETOBJSIZEOBJFREEOBJCPUMATHCPU Fifth has the ability to nicely handle interrupts. Interrupt handling routines are built in a different way than normal colon definitions, and there are limits to what they can safely do. Interrupt handlers handle the appropiate interrupt as long as they are compiled. Thus compiling a timer interrupt handler will cause the timer interrupt to be handled by your routine immediately. During interrupts, the stacks are swapped. Thus parameters cannot be passed between an interrupt routine running in an interrupt and the Fifth system. To communicate interrupt events set flags in variables which are polled in foreground. When making a turnkey application that handles interrupts, be sure to reference the handler in the main routine somewhere, or the application generator may not include it in the final application. ['] works nicely. Interrupt routines can be executed in the foreground as normal routines. A) INT B) :INT C) INT; D) INT[ E) ]INT F) CTRL-C Enter a letter for further help, or space to return. INT:INTINT;INT[]INTCTRL-C (Registers Int -> Registers Flags) The registers are 8 16b values in this order: ES DS SI DI DX CX BX AX . Stack them as 4 32b values. Push all registers on the stack prior to using INT. The registers are loaded and the interrupt is called. The registers are pushed back on the stack with the flags. ( -> ) :INT is used to begin an interrupt handler. It takes the interrupt number from the stack, but otherwise behaves like `:'. The created module begins handling the named interrupt as long as it's compiled. For example: 28 :int x 1 screen +! ; makes an interrupt handler named X, which handles interrupt 28 - the timer interrupt. Now, 18 times a second, the character in the upper left corner of the screen will change. This continues until the module X is uncompiled. ( -> ) INT; is used to end an interrupt handler that should NOT pass control on the next interrupt handler in the chain. It otherwise behaves like `;'. For example: 28 :int x 1 screen +! int; makes an interrupt handler named X, which handles interrupt 28 - the timer interrupt. Now, 18 times a second, the character in the upper left corner of the screen will change. This continues until the module X is uncompiled. However, the previous interrupt routine is NOT called. This means that the time-of-day clock will NOT be updated. When X is uncompiled or deleted, the orginal interrupt handler is re-installed, updating the time-of-day clock again. ( -> ) INT[ turns interrupts off. It is dangerous to leave interrupts disabled for any length of time. You should restore interrupts with ]INT as soon as possible. Using INT[ and ]INT it is possible to guard a structure against simultaneous access by a foreground routine, and an interrupt handler. For instance, to build a circular queue of keystrokes you don't want the keyboard interrupt disturbing the foreground routine as it pulls characters out of the queue. : safe-access int[ \ No interrupts do-queue \ Access queue, update queue tail pointer ]int \ Allow keyboard interrupt again ; ( -> ) ]INT turns interrupts on. It is dangerous to leave interrupts disabled for any length of time. If you disabled interrupts with INT[, you should restore interrupts with ]INT as soon as possible. ( -> ) Causes a control-C interrupt to occur. Fifth intercepts this interrupt and causes a Ctrl-C error to occur. ( -> ) Saves the current Fifth environment to a disk file under the local module's name, with an .EXE extension. To re-load the environment, type it's name to MSDOS. If a .EXE file already exists when saving, it is renamed to .BAK. To make a turn-key application, use TURNKEY. (addr -> ) Saves the Fifth system in text-file format with a filename as the null-terminated string passed. The local environment and all his children are saved. This format is capable of fast loading, using the LOAD module. The SAVE format is: Module-name !00000000 ( Text length in hexidecimal ) Text... ( Module's text ) -*- ( End of text signature ) Then 1 of several symbols are possible: > - The next module is a brother to the previous. A module must follow. v - The next module is a child of the previous. A module must follow. ^ - No more children in the module. Can be followed by a `>' or another `^'. (addr -> ) Loads into the Fifth system a text-file format with a filename as the null-terminated string passed. The load starts at the last child of the local environment. This form of loading is much faster than the old form. If you are attempting to load a source file that has been damaged, you can edit the file with a normal text editor. See the help on SAVE for the file format. ( -> handle) Returns the handle of the standard input stream. ( -> handle) Returns the handle of the standard output stream. (size -> obj) Returns a dynamically allocated Fifth object of the given size. The object is NOT part of the dictionary structure (as is true with NEW). The object may be resized with SIZOBJ, or deleted with FREEOBJ. An error will free up all dynamically allocated objects. GETOBJ is intended as an eventual replacement for the NEW module. (obj size -> ) Resizes an object allocated with GETOBJ. If the object grows in size, it's previous contents will be preserved. If it shrinks as much of the contents as possible are preserved. SIZEOBJ is fairly well optimized, so repeated uses of SIZEOBJ to incrementally grow an object are not too slow. (obj -> ) Returns an object allocated with GETOBJ back to the free heap. Do not use DISPOSE on objects allocated with GETOBJ, nor use FREEOBJ on objects allocated with NEW. Any error will also free all dynmically allocated objects. FREEOBJ is designed to be an eventual replacement for DISPOSE. ( -> cpu-type) Returns the CPU type. Currently supported are 8088, 8086, 80186, 80286, 80386 (all flavors return 8088) and 68000, 68010, 68020, 68030 (returning 68000 or 68010). ( -> math-coprocessor) Returns the math coprocessor. Currently supported are 8087, 80287, 80387 (all flavors return 8087). No, or unrecognized math coprocessors return a zero.