home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
forth
/
fifth.arc
/
BLD.FIV
< prev
next >
Wrap
Text File
|
1986-05-27
|
43KB
|
1,928 lines
CREATE BUILD
CREATE |
CREATE FILENAME
EDIT
create filename 80 allot
~UP
CREATE HN
EDIT
\ handle for the Helpfile New...
variable hn
~UP
CREATE HT
EDIT
\ Handle for Helpfile Temporary.
variable ht
~UP
CREATE TABLE.LENGTH
EDIT
\ Variable holding the table length.
variable table.length
~UP
CREATE LEN
EDIT
\ Used to keep track of offsets into the definitions.
variable len
~UP
CREATE OPENFILES
CREATE NEWFILE
EDIT
\ ( filename -> handle )
\ Aborts the program if can not open file.
: newfile
dup delete if else drop endif \ Delete old file.
32 createfile if else \ Create file. If an error then:
0 24 gotoxy \ Goto bottom of screen.
." Cannot create file!" \ Error message
abort \ End program.
endif
;
~UP
EDIT
\ Open the files.
: openfiles
cls 10 10 gotoxy
." I need a simple file name. No extention, please!"
10 11 gotoxy ." Enter a filename: "
filename 1+ 75 expect swap 1- c! \ Get help file name.
" .hlp" count 1+ 0 do \ Add a .hlp extention.
dup i + c@ filename dup c@ + i 1+ + c!
loop
drop filename 1+ newfile hn ! \ Open helpfile, save handle.
" .tmp" count 1+ 0 do \ Add a .tmp extention.
dup i + c@ filename dup c@ + i 1+ + c!
loop
drop filename 1+ newfile ht ! \ Open tmpfile, save handle.
20 table.length ! \ First entry is bogus.
0 len ! \ Reset offset to zero.
" hold" 1+ 4 hn @ write drop drop \ Save place for table length.
" " 1+ 16 hn @ write drop drop \ First entry null.
len 4 hn @ write drop drop \ Save a zero length
; \ for first entry.
~UP
CREATE BUFFER
EDIT
\ An entry is limited to 32K.
create buffer 1024 32 * allot
~UP
CREATE CLEANUP
EDIT
\ Merges files, deletes intermediate files, fixes up table length, etc.
: cleanup
0 0 ht @ seek
if drop else ." Seek error (build)" abort endif
buffer 1024 32 * ht @ read drop
buffer swap hn @ write
if else
." Write error! (build)" abort
endif
drop
0 0 hn @ seek
if drop else ." Seek error (build)" abort endif
table.length 4 hn @ write drop drop
" text.hlp" 1+ delete if else drop endif
hn @ close if else drop endif \ Close files.
ht @ close if else drop endif
filename 1+ delete if else drop endif \ Delete tmp file.
;
~UP
CREATE TRY
EDIT
| try
TRY
This is a test of the American broadcast system.
~UP
CREATE PRINT
CREATE SKIPWHITE
EDIT
\ ( Hard.addr -> Hard.addr )
\ Skips to first non white character.
: skipwhite
begin
dup c@@ 32 =
over c@@ 13 = or
over c@@ 10 = or
over c@@ 09 = or
while
1+
repeat
;
~UP
CREATE WRITE.KEY
EDIT
\ Write out the key to the entry.
\ ( Hard.addr -> hard.addr )
: write.key
40 0 do 32 buffer i + c! loop \ Space-out the buffer...
0 buffer c! \ Start at buffer beginning.
begin
dup c@@ 13 = \ While not whitespace,
over c@@ 10 = or
over c@@ 9 = or
over c@@ 32 = or
over c@@ 0 = or
not while
dup c@@ \ Get a character,
dup 96 > over 123 < and if 32 - endif \ Convert to upper case.
buffer dup c@ + 1+ c! \ Add to the buffer.
1+ \ Inc the hard address.
1 buffer c@ + buffer c! \ Inc the Buffer count.
repeat
buffer 16 hn @ write drop drop \ Write out the key.
20 table.length +! \ Increment table length.
;
~UP
CREATE WRITE.DEF
EDIT
\ Write out the definition to the temp file.
\ ( Hard.addr -> hard.addr )
: write.def
0 buffer ! \ Start at buffer beginning.
begin
dup c@@ \ While not null...
while
dup c@@ buffer dup @ + 4 + c! \ Add to the buffer.
1+ \ Inc the hard address.
1 buffer +! \ Inc the Buffer count.
repeat
buffer 4 + buffer @ ht @ write drop drop \ Write out the definition.
buffer @ len +! \ Increment length.
len 4 hn @ write drop drop \ Write out offset into the table.
;
~UP
EDIT
( execution.address -> )
: print
>body \ Goto data area.
dup @ 77777777 = not if \ Test Marker.
." Invalid entry found!!"
abort endif
8 + @ \ Get HARDWARE address of text.
skipwhite \ Skip Whitespace.
dup c@@ 0= if \ If no token follows, ignore the entry.
drop exit
endif
write.key \ Write out the Entry name.
write.def \ Write out the definition.
drop
;
~UP
CREATE PRINT.ALL
EDIT
\ Prints recursively all entries below and beside the given entry.
\ ( exececution.addr -> )
: print.all
dup 0= if drop exit endif \ Test if execution address is good.
dup comp \ If so, compile this module,
dup print \ print this module,
dup child print.all \ print its children,
next print.all \ print the next module.
;
~UP
EDIT
\ Used to define an entry into the help file. Executing an entry will
\ generate a helpfile consisting of the particular entry, and all its
\ children.
: |
>in @ \ Save the start of the module.
create \ Create the module.
>in ! \ Reset the start of the module.
77777777 , \ Save a marker for Print to use as a validity test.
' , \ Save the execution address of the module.
>in @ , \ Save a HARDWARE pointer to the text of the module.
0 buffer ! \ Kill the compilation.
buffer i->d >in ! \
does>
openfiles
4 + @ dup print \ Write out this module
child print.all \ Print out all children.
cleanup \ Fix up the files.
;
~UP
CREATE BUILD-HELP-FILE
CREATE ARITHMETIC
CREATE MAX
EDIT
| MAX
MAX
(32b1 32b2 -> 32b3) Leave the larger of 32b1 and 32b2 on the stack as 32b3."
~UP
CREATE MIN
EDIT
| MIN
MIN
(32b1 32b2 -> 32b3) Leave the lesser of 32b1 and 32b2 on the stack as 32b3."
~UP
CREATE F->I
EDIT
| F->I
F->I
(32b1 -> 32b2) Converts floating point to integer, numerical overflow if
32b1 cannot be represented as an integer."
~UP
CREATE I->F
EDIT
| I->F
I->F
(32b1 -> 32b2 ) Convert integer to floating point."
~UP
CREATE ABS
EDIT
| ABS
ABS
(32b -> u32b) Signed 32b is replaced by it's absolute value."
~UP
CREATE -
EDIT
| -
-
(32b1 32b2 -> 32b3) Subtract 32b2 from 32b1 yielding 32b3."
~UP
CREATE SHL
EDIT
| SHL
SHL
(32b1 32b2 -> 32b3) 32b1 is shifted left 32b2 places, zeros are shifted in on
the right. The result is 32b3."
~UP
CREATE SHR
EDIT
| SHR
SHR
(32b1 32b2 -> 32b3) 32b1 is shifted right 32b2 places, zeros are shifted in on
the left. The result is 32b3."
~UP
CREATE MOD
EDIT
| MOD
MOD
(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."
~UP
CREATE NEGATE
EDIT
| NEGATE
NEGATE
(32b1 -> 32b2) Two's complement 32b1 yielding 32b2."
~UP
CREATE 2/
EDIT
| 2/
2/
(32b1 -> 32b2) Arithmetically shift 32b1 right 1 yielding 32b2."
~UP
CREATE 2-
EDIT
| 2-
2-
(32b1 -> 32b2) Subtract 2 from 32b1 yielding 32b2."
~UP
CREATE 2+
EDIT
| 2+
2+
(32b1 -> 32b2) Add 2 to 32b1 yielding 32b2."
~UP
CREATE 1-
EDIT
| 1-
1-
(32b1 -> 32b2) Decrement 32b1 yielding 32b2."
~UP
CREATE 1+
EDIT
| 1+
1+
(32b1 -> 32b2) Increment 32b1 yielding 32b2."
~UP
CREATE *
EDIT
| *
*
(32b1 32b2 -> 32b3) Signed multiply of 32b1 times 32b2 yielding 32b3."
~UP
CREATE +
EDIT
| +
+
(32b1 32b2 -> 32b3) Add 32b1 to 32b2 yielding 32b3."
~UP
CREATE /MOD
EDIT
| /MOD
/MOD
(32b1 32b2 -> 32b3 32b4) Divide 32b1 by 32b2, leaving quotient 32b4 and
remainder 32b3. 32b3 has same sign as 32b2 Numerical overflow if 32b2 is zero
or 32b4 out of range."
~UP
CREATE /
EDIT
| /
/
(32b1 32b2 -> 32b3) Divide 32b1 by 32b2, leaving quotient 32b3. Numerical
overflow if 32b2 is zero or 32b3 out of range."
~UP
CREATE F/
EDIT
| F/
F/
(32b1 32b2 -> 32b3 ) Divides two floating point numbers."
~UP
CREATE F*
EDIT
| F*
F*
(32b1 32b2 -> 32b3 ) Multiplies two floating point numbers."
~UP
CREATE F-
EDIT
| F-
F-
(32b1 32b2 -> 32b3 ) Subtracts two floating point numbers."
~UP
CREATE F+
EDIT
| F+
F+
(32b1 32b2 -> 32b3 ) Adds two floating point numbers."
~UP
CREATE FEXP
EDIT
| FEXP
FEXP
(32b1 -> 32b2) Returns e^X on floating point number 32b1."
~UP
CREATE FLOG
EDIT
| FLOG
FLOG
(32b1 -> 32b2) Returns the natural log of 32b1."
~UP
EDIT
| arithmetic
arithmetic
Fifth supports 32-bit integer and floating point
arithmetic. The floating point operators rely
on the math coprocessor, and thus will not work
on some Systems. The following is a summary of
the Fifth arithmetic primitives:
INTEGER: + - * / /MOD
2* 2/ 1+ 1- 2+
2- SHR SHL ABS NEGATE
MAX MIN
FLOATING POINT: F+ F- F* F/
FLOG FEXP
CONVERSION: F->I I->F
~UP
CREATE I/O
CREATE CLOSE
EDIT
| CLOSE
CLOSE
(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."
~UP
CREATE CREATEFILE
EDIT
| CREATEFILE
CREATEFILE
(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."
~UP
CREATE DELETE
EDIT
| DELETE
DELETE
(addr -> -1) or (addr -> 32b1 0) Deletes file with name at address. Returns
a true flag, or error code 32b1 and a false flag."
~UP
CREATE OPEN
EDIT
| OPEN
OPEN
(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."
~UP
CREATE READ
EDIT
| READ
READ
(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."
~UP
CREATE RENAME
EDIT
| RENAME
RENAME
(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."
~UP
CREATE SEEK
EDIT
| SEEK
SEEK
(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."
~UP
CREATE WRITE
EDIT
| WRITE
WRITE
(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."
~UP
CREATE ?TERM
EDIT
| ?TERM
?TERM
( -> flag) Leave a true flag if a character is available at the keyboard,
otherwise leave a false flag."
~UP
CREATE CLS
EDIT
| CLS
CLS
( -> ) Clear the screen and home the cursor."
~UP
CREATE CR
EDIT
| CR
CR
( -> ) Sends a carriage-return line-feed pair to the terminal."
~UP
CREATE EMIT
EDIT
| EMIT
EMIT
(8b -> ) The 8b value is sent to the terminal."
~UP
CREATE EXPECT
EDIT
| EXPECT
EXPECT
(addr 8b1 -> addr 8b2) Read 8b1 characters at addr or until a CR, with
backspace editing. 8b2 is the number of characters read."
~UP
CREATE GOTOXY
EDIT
| GOTOXY
GOTOXY
( 32b1 32b2 -> ) Moves the cursor to column 32b1, row 32b2."
~UP
CREATE KEY
EDIT
| KEY
KEY
( -> 8b) Wait for a character from the keyboard, do not echo it."
~UP
CREATE QUERY
EDIT
| QUERY
QUERY
( -> ) Causes the input buffer to be flushed and read."
~UP
CREATE SCREEN
EDIT
| SCREEN
SCREEN
( -> 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."
~UP
CREATE SPACE
EDIT
| SPACE
SPACE
( -> ) Output a space to the terminal."
~UP
CREATE SPAN
EDIT
| SPAN
SPAN
( -> addr) Addr is the address of the length of the last data read with
EXPECT."
~UP
CREATE SPACES
EDIT
| SPACES
SPACES
(32b -> ) Output 32b spaces to the terminal."
~UP
CREATE TIB
EDIT
| TIB
TIB
( -> addr) Leaves the address the start of the terminal input buffer on the
stack."
~UP
CREATE CONVERT
EDIT
| CONVERT
CONVERT
(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.
DPL is a -1 for a integer, and >= 0 for a floating point number."
~UP
CREATE COUNT
EDIT
| COUNT
COUNT
(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."
~UP
CREATE DPL
EDIT
| DPL
DPL
( -> addr ) The address of the number of trailing digits in the last double
precision number, or a -1 if integer, is left on the stack."
~UP
CREATE TYPE
EDIT
| TYPE
TYPE
(addr +n -> ) +n characters from the string at address are echoed to the
terminal."
~UP
CREATE SIGN
EDIT
| SIGN
SIGN
(32b -> ) Place a sign '-' character in the formatted string buffer if 32b is
less than zero."
~UP
CREATE HOLD
EDIT
| HOLD
HOLD
(8b -> ) Pushes the 8b character into the formatted string buffer."
~UP
CREATE PAD
EDIT
| PAD
PAD
( -> addr) Leaves the address of the start of the formatted string buffer on
the stack."
~UP
CREATE F->EM
EDIT
| F->EM
F->EM
(32b1 -> 32b2 32b3) Converts the floating point 32b1 to exponent 32b2 and
mantissa 32b3. Mantissa is adjusted by RADIX to the 6th power, to allow six #'s
to be used on it within a formatted string command sequence."
~UP
CREATE F.
EDIT
| F.
F.
(32b -> ) Prints the floating point number."
~UP
CREATE U.
EDIT
| U.
U.
(u32b -> ) The unsigned integer u32b is printed."
~UP
CREATE <#
EDIT
| <#
<#
( -> ) Reset the formatted string length and pointer."
~UP
CREATE .S
EDIT
| .S
.S
(32b1 32b2 ... -> ) Print all values on stack as signed integer values."
~UP
CREATE .(
EDIT
| .(
.(
( -> ) Following string is immediately displayed, until the terminating
parenthesis."
~UP
CREATE .
EDIT
| .
.
(32b -> ) Signed integer number is printed in the current radix with a
trailing blank."
~UP
CREATE ."
EDIT
| ."
."
( -> ) Following string is compiled inline for later display. String is
terminated by a quote."
~UP
CREATE -TRAILING
EDIT
| -TRAILING
-TRAILING
(addr +8b1 -> addr +8b2) All trailing blanks from string at address are
removed, the new length is left on the stack."
~UP
CREATE #TIB
EDIT
| #TIB
#TIB
( -> addr) Leaves address of terminal input buffer, first byte is length,
next is buffer. Use C@ or COUNT to get the length."
~UP
CREATE #S
EDIT
| #S
#S
(+32b -> 0 ) All remaining digits of 32b are placed in the formatted string
buffer."
~UP
CREATE #>
EDIT
| #>
#>
(32b -> addr +n ) Number on stack is replaced by the address and
length of the formatted string buffer."
~UP
CREATE #
EDIT
| #
#
(+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."
~UP
EDIT
| i/o
I/O
I/O is a diverse subject, Fifth lumps I/O primitives under these headings:
Disk I/O: CLOSE CREATEFILE DELETE
OPEN READ RENAME
SEEK WRITE
Screen I/O: ?TERM CLS CONVERT
CR DPL EMIT
EXPECT GOTOXY KEY
QUERY SCREEN SPACE
SPACES SPAN TIB
#TIB
String
formatting: <# # #>
#S HOLD F->EM
PAD SIGN -TRAILING
Printing: . .( ."
.S COUNT F.
TYPE U.
~UP
CREATE GRAPHICS
CREATE VMODE
EDIT
| VMODE
VMODE
( 32b1 -> ) On the IBM, the 32b1 is the screen mode, both black & white and
color screens are supported. On the TI, 32b1 is ignored, and the screen palette
is reset."
~UP
CREATE PALETTE
EDIT
| PALETTE
PALETTE
( 32b1 32b2 -> ) On the IBM, 32b1 is the background color, and 32b2 is either
0 or 1. On the TI 32b1 is pixel value (0-7) and 32b2 is the color it is being
mapped to (0-7)."
~UP
CREATE PGET
EDIT
| PGET
PGET
( x1 y2 -> color ) Returns the color of a point."
~UP
CREATE PSET
EDIT
| PSET
PSET
( color x1 y1 -> ) Set a point."
~UP
CREATE PAINT
EDIT
| PAINT
PAINT
( x1 y1 color1 color2 -> ) Starting at x1,y1, fill the screen with color1,
stopping on both color boundaries."
~UP
CREATE MOVETO
EDIT
| moveto
MOVETO
(x y -> ) Sets the current graphics draw point.
~UP
CREATE POINT
EDIT
| point
POINT
( -> x y) Gets the current graphics draw point.
~UP
CREATE LINETO
EDIT
| LINETO
LINETO
( color x y ) Draws a line from the current draw point to x,y. Sets x,y
as the new draw point.
~UP
CREATE FILLBOX
EDIT
| FILLBOX
FILLBOX
( color x1 y1 x2 y2 -> ) Fills a box."
~UP
CREATE BOX
EDIT
| BOX
BOX
( color x1 y1 x2 y2 -> ) Draws a box."
~UP
EDIT
| graphics
GRAPHICS
The following words are available for graphics in Fifth:
BOX FILLBOX PAINT
PALETTE PSET PGET
MOVETO POINT LINETO
VMODE
~UP
CREATE COND_COMP
CREATE }REPEAT
EDIT
| }REPEAT
}REPEAT
( -> ) The text pointer is reset to just after an enclosing BEGIN{.
NOTE: }REPEAT is immediate."
~UP
CREATE }WHILE{
EDIT
| }WHILE{
}WHILE{
( flag -> ) If the flag is true, execution proceeds. If false, the return stack
is popped, and execution proceeds after the enclosing }REPEAT.
NOTE: }WHILE{ is immediate."
~UP
CREATE }UNTIL
EDIT
| }UNTIL
}UNTIL
( 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{. NOTE }UNTIL is immediate."
~UP
CREATE BEGIN{
EDIT
| BEGIN{
BEGIN{
( -> ) Saves the text pointer on the return stack, used with }UNTIL or }WHILE{
}REPEAT. NOTE BEGIN{ is immediate."
~UP
CREATE }LOOP
EDIT
| }LOOP
}LOOP
( -> ) 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.
"
~UP
CREATE DO{
EDIT
| DO{
DO{
( 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."
~UP
CREATE }ENDIF
EDIT
| }ENDIF
}ENDIF
( -> ) Place marker for IF{ and }ELSE{ modules. This module does nothing."
~UP
CREATE }ELSE{
EDIT
| }ELSE{
}ELSE{
( -> ) Skips text to the next }ENDIF. NOTE: }ELSE{ is immediate."
~UP
CREATE IF{
EDIT
| IF{
IF{
( 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."
~UP
EDIT
| cond_comp
CONDITIONAL
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.
BEGIN{ }WHILE{ }REPEAT }UNTIL
DO{ }LOOP
IF{ }ELSE{ }ENDIF
~UP
CREATE STRUCTURES
CREATE @
EDIT
| @
@
(addr -> 32b) The 32b value at the address is fetched."
~UP
CREATE C@
EDIT
| C@
C@
(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."
~UP
CREATE C@@
EDIT
| C@@
C@@
(32b -> 8b) The 8b value at the direct hardware address 32b is fetched."
~UP
CREATE C!!
EDIT
| C!!
C!!
( 8b 32b -> ) Store the 8b value at the 32b direct hardware address."
~UP
CREATE C!
EDIT
| C!
C!
(8b addr -> ) 8b value is stored at address."
~UP
CREATE 2@
EDIT
| 2@
2@
(addr -> 64b ) Fetch the 64b value stored at the address."
~UP
CREATE 2!
EDIT
| 2!
2!
(64b addr -> ) Store the 64b value into the address."
~UP
CREATE +!
EDIT
| +!
+!
(32b addr -> ) Add 32b to the value at the address."
~UP
CREATE !
EDIT
| !
!
( 32b addr -> ) Store the 32b value at the address."
~UP
CREATE I->D
EDIT
| I->D
I->D
(addr -> 32b) Convert indirect address to a direct hardware 32b address."
~UP
CREATE IF
EDIT
| IF
IF
(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 zero or non-
zero."
~UP
CREATE ELSE
EDIT
| ELSE
ELSE
( -> ) Used in a test IF true-body ELSE false-body ENDIF construct."
~UP
CREATE ENDIF
EDIT
| ENDIF
ENDIF
( -> ) Used inside a test IF true-body ENDIF or test IF true-body ELSE false-
body ENDIF construct."
~UP
CREATE BEGIN
EDIT
| BEGIN
BEGIN
( -> ) Marks the beginning of a BEGIN body test UNTIL loop or a BEGIN test
WHILE body REPEAT loop."
~UP
CREATE WHILE
EDIT
| WHILE
WHILE
(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."
~UP
CREATE UNTIL
EDIT
| UNTIL
UNTIL
(flag -> ) Loops to enclosing BEGIN if flag is false, otherwise the loop
terminates. Used in BEGIN body test UNTIL loops."
~UP
CREATE REPEAT
EDIT
| REPEAT
REPEAT
( -> ) Causes a loop to an enclosing BEGIN in a BEGIN test WHILE body REPEAT
construct."
~UP
CREATE VARIABLE
EDIT
| VARIABLE
VARIABLE
( -> ) The next module in the input stream is CREATE'd, and 4 bytes reserved
for it's use."
~UP
CREATE CONSTANT
EDIT
| CONSTANT
CONSTANT
(32b -> ) Next module in the input stream is compiled into the dictionary.
Later execution of this name leaves 32b on the stack."
~UP
CREATE NEW
EDIT
| NEW
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."
~UP
CREATE DISPOSE
EDIT
| DISPOSE
DISPOSE
(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."
~UP
CREATE SCAN
EDIT
| SCAN
SCAN
( addr 32b1 8b -> 32b2 ) Scan 32b1 bytes at addr for 8b. Return 32b2 as offset
+ 1 of first occurance of byte 8b in addr. Return 0 if byte not found in 32b1
characters. If byte is first character, 32b2 is 1."
~UP
CREATE DO
EDIT
| DO
DO
(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."
~UP
CREATE I
EDIT
| I
I
( -> 32b) Leaves the value of the innermost DO index on the stack."
~UP
CREATE J
EDIT
| J
J
( -> 32b) Leaves the value of the second innermost DO index on the stack."
~UP
CREATE LEAVE
EDIT
| LEAVE
LEAVE
( -> ) Causes the innermost DO body LOOP construct to be exited immediately."
~UP
CREATE LOOP
EDIT
| LOOP
LOOP
( -> ) 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."
~UP
CREATE +LOOP
EDIT
| +LOOP
+LOOP
(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."
~UP
CREATE EXIT
EDIT
| EXIT
EXIT
( -> ) Exits the current module, >R and R> modules must be balanced, but
DO/LOOP's do not."
~UP
CREATE HERE
EDIT
| HERE
HERE
( -> addr ) Leaves the address of the current top of dictionary."
~UP
CREATE DOES>
EDIT
| DOES>
DOES>
( -> ) Causes the address of the code following the DOES> to be placed in the
current module's indirect parameter address. UP is called, to restore the local
module from a previous CREATE. 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. "
~UP
CREATE CMOVE>
EDIT
| CMOVE>
CMOVE>
(addr1 addr2 32b -> ) Move 32b bytes starting at (addr1 + 32b - 1) to (addr2
+ 32b - 1) and proceeding toward low memory."
~UP
CREATE CMOVE
EDIT
| CMOVE
CMOVE
(addr1 addr2 32b -> ) 32b characters from address #1 are moved to address
#2."
~UP
CREATE ERASE
EDIT
| ERASE
ERASE
(addr 32b -> ) Zeros 32b bytes at addr."
~UP
CREATE FILL
EDIT
| FILL
FILL
(addr 32b 8b -> ) From address, 32b bytes are filled with 8b."
~UP
CREATE BLANK
EDIT
| BLANK
BLANK
(addr 32b -> ) Fills 32b bytes at addr with blanks."
~UP
CREATE MOVE
EDIT
| MOVE
MOVE
(addr1 addr2 n -> ) Copy n words (32b values) from address #1 to address #2.
Do nothing if n is less than or equal to zero."
~UP
CREATE >BODY
EDIT
| >BODY
>BODY
(addr1 -> addr2) Convert the execution address addr1 to a parameter field
address addr2."
~UP
CREATE "
EDIT
| "
"
( -> addr ) Compiles a string literal inline, up to the terminating quote.
Returns the address of the length byte of the literal."
~UP
EDIT
| structures
STRUCTURES
Fetching and storing data is how Fifth deals with variables. The looping and
testing contructs let Fifth programs make decisions. The block operations are
fast primitives. The miscellanous sections contains CONSTANT and VARIABLE.
Fetching &
Storing: +! 2! 2@
! C! C!!
@ C@ C@@
I->D
If & looping: +LOOP BEGIN DO
ELSE ENDIF I
IF J LOOP
LEAVE REPEAT UNTIL
WHILE
Block
Operations: >BODY BLANK CMOVE
CMOVE> ERASE FILL
MOVE SCAN
Misc: " CONSTANT DISPOSE
DOES> EXIT HERE
NEW VARIABLE
~UP
CREATE COMPILING
CREATE WORD
EDIT
| WORD
WORD
(8b -> addr) Parses the next module in the input stream delimited 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."
~UP
CREATE [
EDIT
| [
[
( -> ) The compiler is turned off."
~UP
CREATE ]
EDIT
| ]
]
( -> ) The compiler is turned on."
~UP
CREATE [COMPILE]
EDIT
| [COMPILE]
[COMPILE]
( -> ) Causes a call to the next module in the input stream to be generated
when the module containing [COMPILE] is run."
~UP
CREATE [']
EDIT
| [']
[']
( -> ) Compiles the execution address of next module in input stream as a
literal, later execution of code leaves the address on the stack."
~UP
CREATE TRACE
EDIT
| TRACE
TRACE
( -> ) TRACE moves the cursor to the screen top, and prints the stack and the
module about to be executed. If a space bar is hit, execution proceeds
normally, if ESC is hit ABORT is called. Other keys are ignored. If Trace is
set on from the DIR command, TRACE is called before each module in the module
being traced."
~UP
CREATE TEXT
EDIT
| TEXT
TEXT
( 8b -> ) Clears the PAD buffer, then reads from the input stream to the PAD
buffer until the 8b delimiter is found."
~UP
CREATE STATE
EDIT
| STATE
STATE
( -> addr ) Leaves the address of the compiler state. 0 is off, anything else
is on. This value must NOT be modified."
~UP
CREATE FIND
EDIT
| FIND
FIND
(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 not found but the string is an
integer, then addr2 is the 32b value, and n is 2. If string is a floating point
number, addr2 is the value, and n is 3. If none of the above, then
addr2 = addr1 and n=0."
~UP
CREATE LITERAL
EDIT
| LITERAL
LITERAL
(32b -> ) Causes the top-of-stack value to be compiled just as if it where an
inline number."
~UP
CREATE EXECUTE
EDIT
| EXECUTE
EXECUTE
(addr -> ) The code at the address is executed."
~UP
CREATE CHILD
EDIT
| CHILD
CHILD
(addr1 -> addr2) Returns the address addr2 of the first child of module
addr1."
~UP
CREATE NEXT
EDIT
| NEXT
NEXT
(addr1 -> addr2) Returns the address addr2 of the next module after module
addr1."
~UP
CREATE COMP
EDIT
| COMP
COMP
( addr -> ) Compiles the module with execution address addr."
~UP
CREATE ABORT
EDIT
| ABORT
ABORT
( -> ) 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."
~UP
CREATE QUIT
EDIT
| QUIT
QUIT
( -> ) Does a full reset like ABORT except the data stack is left untouched."
~UP
CREATE ABORT"
EDIT
| ABORT"
ABORT"
( flag -> ) If the flag is true, the following message is printed, and ABORT
is called."
~UP
CREATE >IN
EDIT
| >IN
>IN
( -> 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."
~UP
CREATE '
EDIT
| '
'
( -> 32b ) The input stream is parsed, a number's value is placed on the
stack, a known module's execution address pointer is placed on the stack, an
unknown module generates an error."
~UP
CREATE IMMEDIATE
EDIT
| IMMEDIATE
IMMEDIATE
( -> ) Causes the local module to become immediate, it executes even if the
compiler is turned on."
~UP
CREATE .CREATE
EDIT
| .CREATE
CREATE
( -> ) The next module in the input stream has a dictionary entry and a code
segment created for it. In the code segment the name and code to push the
indirect address after the code (the new parameter area) is generated, followed
by a return. When the new module is executed, the parameter area indirect
address will be left on the data stack.
The module is created at the end of the local dictionary, unless the module is
the same as the name of the local dictionary. In that case, the module is
(re)created. None of the pointers are lost, but the code is reset as above. The
F$CRH bit is also set on a re-creation."
~UP
CREATE ,
EDIT
| ,
,
(32b -> ) The 32b value is placed at the end of the local dictionary."
~UP
CREATE C,
EDIT
| C,
C,
(8b -> ) 8b value is compiled into the top-of-dictionary."
~UP
CREATE ALLOT
EDIT
| ALLOT
ALLOT
(32b -> ) Top-of-dictionary pointer is advanced by 32b."
~UP
CREATE :
EDIT
| :
:
( -> ) CREATE is called to (re)create a header for the following module. The
compiler is turned on."
~UP
CREATE ;
EDIT
| ;
;
( -> ) A return is compiled, then the compiler is turned off. Nesting of
control structures is also checked."
~UP
CREATE (
EDIT
| (
(
( -> ) All characters up to the closing ')' paren are ignored. This is the
comment module."
~UP
CREATE \
EDIT
| \
\
( -> ) Skip comments to the end of the line."
~UP
CREATE GETSIZE
EDIT
| getsize
GETSIZE
(addr -> 32b1) Returns the size of the given module.
~UP
EDIT
| compiling
COMPILATION
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:
['] ' [
] ; :
, ( \
ABORT ABORT" C,
COMP [COMPILE] CONSTANT
CREATE CHILD EXECUTE
FIND >IN LITERAL
NEXT STATE TEXT
TRACE VARIABLE WORD
GETSIZE
~UP
CREATE COMPARISON
CREATE XOR
EDIT
| XOR
XOR
(32b1 32b2 -> 32b3) Exclusive or 32b1 to 32b2 yielding 32b3."
~UP
CREATE U<
EDIT
| U<
U<
(u32b1 u32b2 -> flag) Leave a true flag if unsigned integer u32b1 is less
than u32b2."
~UP
CREATE F<
EDIT
| F<
F<
(32b1 32b2 -> flag ) Compares two floating point numbers."
~UP
CREATE OR
EDIT
| OR
OR
(32b1 32b2 -> 32b3) Bitwise or 32b1 to 32b2 yielding 32b3."
~UP
CREATE NOT
EDIT
| NOT
NOT
(32b1 -> 32b2) One's complement 32b1 yielding 32b2."
~UP
CREATE AND
EDIT
| AND
AND
(32b1 32b2 -> 32b3) 32b1 is bit-wise anded with 32b2 yielding 32b3."
~UP
CREATE >
EDIT
| >
>
(32b1 32b2 -> flag) A true flag is left if 32b1 is greater than 32b2,
otherwise a zero."
~UP
CREATE =
EDIT
| =
=
(32b1 32b2 -> flag) A true flag is left if 32b1 equals 32b2, otherwise a
zero."
~UP
CREATE <
EDIT
| <
<
(32b1 32b2 -> flag) A true flag is left if 32b1 is less than 32b2, otherwise
a zero."
~UP
CREATE 0>
EDIT
| 0>
0>
(32b -> flag) Replace 32b with a true flag (-1) if 32b is greater than zero,
otherwise replace 32b with a false flag (0)."
~UP
CREATE 0=
EDIT
| 0=
0=
(32b -> flag) Replace 32b with a true flag (-1) if 32b is equal to zero,
otherwise replace 32b with a false flag (0)."
~UP
CREATE 0<
EDIT
| 0<
0<
(32b -> flag) Replace 32b with a true flag (-1) if n is less than zero,
otherwise replace 32b with a false flag (0)."
~UP
EDIT
| comparison
COMPARISON
These primitives manipulate boolean and logical values:
< = >
0< 0= 0>
AND F< NOT
OR U< XOR
~UP
CREATE STACKOP
CREATE ?DUP
EDIT
| ?DUP
?DUP
(32b -> 32b 32b) or (0 -> 0) If the top-of-stack value is zero, nothing
occurs, otherwise it is duplicated."
~UP
CREATE SWAP
EDIT
| SWAP
SWAP
(32b1 32b2 -> 32b2 32b1) Top two stack elements are swapped."
~UP
CREATE OVER
EDIT
| OVER
OVER
(32b1 32b2 -> 32b1 32b2 32b1) Stack is modified according to stack diagram."
~UP
CREATE DEPTH
EDIT
| DEPTH
DEPTH
( -> n) Return the depth of the stack, not counting n."
~UP
CREATE PICK
EDIT
| PICK
PICK
(+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."
~UP
CREATE DUP
EDIT
| DUP
DUP
(32b -> 32b 32b) Duplicate the top-of-stack element."
~UP
CREATE DROP
EDIT
| DROP
DROP
(32b -> ) A 32b is dropped from the stack."
~UP
CREATE ?STACK
EDIT
| ?STACK
?STACK
( -> flag) Returns a true flag if the stack has underflowed."
~UP
CREATE SSTACK
EDIT
| sstack
STACK (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 compilcated 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..." .
~UP
EDIT
| stackop
STACK_OP
These stack operators manipulate the data stack:
DEPTH ?DUP OVER ?STACK SWAP
DROP DUP PICK STACK
~UP
CREATE MISC
CREATE IN
EDIT
| IN
IN
(32b -> 8b) Input 8b from port number 32b."
~UP
CREATE OUT
EDIT
| OUT
OUT
(8b 32b -> ) The 8b value is outputted thru port number 32b."
~UP
CREATE .UP
EDIT
| .UP
UP
( -> ) Raises the environment level, does nothing if at ROOT level."
~UP
CREATE SAVE
EDIT
| SAVE
SAVE
( -> ) Saves the current Fifth environment to a disk file under the ROOT
name, with a .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 ."
~UP
CREATE R@
EDIT
| R@
R@
( -> 32b) Copies a value from the return stack and places it on the data
stack."
~UP
CREATE R>
EDIT
| R>
R>
( -> 32b) Pulls a value from the return stack and places it on the data
stack."
~UP
CREATE MEMORY
EDIT
| MEMORY
MEMORY
( -> 32b) Returns the size of the largest HEAP block. Saving and reloading
Fifth will compress the HEAP."
~UP
CREATE INT
EDIT
| INT
INT
(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."
~UP
CREATE .EDIT
EDIT
| .EDIT
EDIT
( -> ) Edits the text of a single module. (Edits the local module.) Use DIR to
edit program structure. See the Text Editor section of the Fifth manual."
~UP
CREATE .DIR
EDIT
| .DIR
DIR
( -> ) Invokes the dictionary editor. This is the word that is used to edit
the structure of Fifth programs. DIR is invoked by typing `DIR' in the
interactive environment. Use the arrow keys to move around in your program.
See the full description in the Dictionary Editor section in the manual.
To load a file, use the 'L' key, type the filename (EX: TOWERS.FIV) and a
carrige return. During loading, a series of '>' symbols will appear. After
loading you will be in the interactive environment again. Typing DIR returns
you to the dictionary editor.
~UP
CREATE DECIMAL
EDIT
| DECIMAL
DECIMAL
( -> ) Force the radix to base 10."
~UP
CREATE BYE
EDIT
| BYE
BYE
( -> ) Exits to calling procedure. (MSDOS)"
~UP
CREATE BASE
EDIT
| BASE
BASE
( -> addr) Leaves the address of the radix. Valid radix are in the range 2
to 72."
~UP
CREATE >R
EDIT
| >R
>R
(32b -> ) 32b value is pushed onto the return stack."
~UP
CREATE :=
EDIT
| :=
:=
( 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 statment 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 !
~UP
CREATE ENVIRON
EDIT
| environ
ENVIRON
(addr -> ) Moves to the local environment of the given module.
~UP
EDIT
| misc
MISC
This section describes primitives that do not lump into any one category.
>R BASE BYE
DECIMAL DIR EDIT
IN INT MEMORY
OUT R@ R>
SAVE UP :=
ENVIRON
~UP
EDIT
| build-help-file
help ( -> )
The HELP module returns information on the modules in
the system. The syntax for using HELP is:
HELP <module-name>
Try HELP out on the Fifth primitives DIR and BYE.
In addition, you can request help with:
ARITHMETIC COMPARISON COMPILATION
CONDITIONAL GRAPHICS I/O
MISC STACK_OP STRUCTURES
Some of the language extensions require loading of a .FIV file. These files are
similiar to .H files in the "C" language. To load a .FIV file, check the help
on the DIR command, i.e. "HELP DIR".
~UP
EDIT
\ Executing any entry will build a helpfile
\ Containing the executed entry and all entries beneath it.
\
\ (Normally, you will execute BUILD-HELP-FILE...)
\
create build
~UP
ABORT