Page 22 of 25
Re: Fleet Forth design considerations
Posted: Thu Aug 24, 2023 7:08 pm
by JimBoyd
I've only used code page 437, which clearly the C64 doesn't use. I haven't thought about how I'd use the C64 character set (including function keys), but CP437 is sure nice for the special characters, drawing boxes, and the Greek letters we use all the time in engineering (since that's what I'm always using Forth for).
I remember code page 437. I haven't seen it since my days of using DOS.
The visual appearance of text windows can be created on the C64 using reverse video. Ctrl-R on the C64 selects reverse video and Ctrl-0 ( control zero) selects normal video.
Here is were I selected a black background and white text and played around on the screen by selecting and deselecting reverse video. I typed the text with spaces to achieve the look of windows.
I normally use reverse video on the C64 to highlight important information.Fleet Forth has the words RON to switch reverse video on and ROFF to switch to normal video. A carriage return also switches reverse video off.
Re: Fleet Forth design considerations
Posted: Thu Aug 24, 2023 9:48 pm
by JimBoyd
I've removed the words <LIST <L LIST> L> and their editor words 0[ through F[ and 0] through F] because they were unsatisfactory.
I also mentioned a solution which seems satisfactory.
A new LIST word which use an editing window VALUE for a displacement to the right, EW , and a corresponding set of editing words 0[ through F[ which also use EW.
I would like to mention that the word // is Fleet Forth's word to comment to the end of a line. It will also skip the rest of the line when used at the command line or in an EVALUATEed string.
The comments in the listing which have a backslash were added to this post for clarity.
Code: Select all
0 VALUE EW
: LISTW ( SCR -- )
EW #28 UMIN (IS) EW \ be certain EW is from 0 - 28
\ inclusive.
PAGE EDITOR R# OFF DUP SCR ! \ clear the screen, select EDITOR
\ vocabulary & misc. housekeeping.
." SCR# " DUP U. SPACE BLK> . . \ show screen number.
\ BLK> breaks that number down
\ to a screen number relative to
\ the drive it is from and the
\ drive number.
10 SPACES EW . \ show displacement to the right
#16 0 CR
DO
I 0 H.R ." [ "
I LINE EW /STRING #36 UMIN \ only show 36 columns
QTYPE CR \ type in 'quote mode'
DONE? ?LEAVE
LOOP ;
EDITOR DEFINITIONS
: XED2 ( N -- )
CREATE ( N -- )
C,
DOES> ( -- )
C@ LINE 0 TEXT PAD 1+ -ROT
EW #28 UMIN /STRING #36 UMIN
MOVE UPDATE
3 RC ! QUIT -;
: LW ( -- )
SCR @ LISTW ;
0 XED2 0[ 1 XED2 1[ 2 XED2 2[
3 XED2 3[ 4 XED2 4[ 5 XED2 5[
6 XED2 6[ 7 XED2 7[ 8 XED2 8[
9 XED2 9[ $A XED2 A[ $B XED2 B[
$C XED2 C[ $D XED2 D[ $E XED2 E[
$F XED2 F[
FORTH DEFINITIONS
LINE takes an number from 0 to 15 and returns the address, in the block buffer, of that line for the current screen, the one which has its block number stored in SCR .
0 TEXT reads the rest of the line in the text input buffer and stores it at PAD . After -ROT the stack has the following three parameters on top.
The address of the text to copy.
The address of the line of the current screen for this child word.
A count of 64.
The line
increments the destination address by EW bytes and clips the length of the transfer to 36 bytes, the length of the edit window.
The string is MOVEd to the block buffer and the buffer updated.
Fleet Forth's EXPECT starts at the beginning of a line on the view screen and will perform a carriage return if necessary. Setting the variable RC to 3 will cause EXPECT to move the cursor right by three.
That reversed video colon after 2[ is a snapshot of the blinking cursor. It was placed there after pressing the return key anywhere on the previous line.
Fleet Forth's EXPECT was modified to test for function keys. The function key words can be executed without the need to scroll down from the text being edited.
Some sample function key words I was trying. This is how the screen appears when listing with LISTW and EW is zero. The listings are sent to a printer, or in my case, a print.dump file.
Code: Select all
\ ----------------------- actual screen number
\ | ------------------- drive number
\ | | ---------------- screen number relative to drive
\ v v v
SCR# 4719 2 623 0 -- editor window displacement
0[ // EDITOR FKEYS
1[ EDITOR DEFINITIONS
2[ : F1KEY ( -- ) // MOV
3[ 0 TO EW [ HERE >A ]
4[ XY 1 MAX 16 MIN LW AT-XY ;
5[ : F3KEY ( -- ) // MOV
6[ EW 7 - 0 MAX TO EW
7[ BRANCH [ A@ , ] -;
8[ : F5KEY ( -- ) // MOV
9[ EW 7 + #28 MIN TO EW
A[ BRANCH [ A@ , ] -;
B[ : F7KEY ( -- ) #28 TO EW // MOV
C[ BRANCH [ A> , ] -;
D[ : F2KEY ( -- ) // MOV
E[ 0 18 AT-XY ;
F[ FORTH DEFINITIONS
And when EW is 14.
Code: Select all
SCR# 4719 2 623 14
0[ S
1[ IONS
2[ ) // MOVE EDIT WINDOW
3[ HERE >A ]
4[ MIN LW AT-XY ;
5[ ) // MOVE WINDOW LEFT
6[ X TO EW
7[ , ] -;
8[ ) // MOVE WINDOW RIGHT
9[ MIN TO EW
A[ , ] -;
B[ ) #28 TO EW // MOVE EDIT WINDOW
C[ , ] -;
D[ ) // MOVE CURSOR TO BE
E[ ;
F[ ONS
When listing with LIST .
Code: Select all
SCR# 4719 2 623
0: // EDITOR FKEYS
1: EDITOR DEFINITIONS
2: : F1KEY ( -- ) // MOVE EDIT WINDOW TO BEGINNING
3: 0 TO EW [ HERE >A ]
4: XY 1 MAX 16 MIN LW AT-XY ;
5: : F3KEY ( -- ) // MOVE WINDOW LEFT 7 COLUMNS
6: EW 7 - 0 MAX TO EW
7: BRANCH [ A@ , ] -;
8: : F5KEY ( -- ) // MOVE WINDOW RIGHT 7 COLUMNS
9: EW 7 + #28 MIN TO EW
A: BRANCH [ A@ , ] -;
B: : F7KEY ( -- ) #28 TO EW // MOVE EDIT WINDOW TO END
C: BRANCH [ A> , ] -;
D: : F2KEY ( -- ) // MOVE CURSOR TO BELOW EDIT AREA
E: 0 18 AT-XY ;
F: FORTH DEFINITIONS
And with what I normally use to list screens to a print.dump file, PLIST , plain list.
Code: Select all
SCR# 623
// EDITOR FKEYS
EDITOR DEFINITIONS
: F1KEY ( -- ) // MOVE EDIT WINDOW TO BEGINNING
0 TO EW [ HERE >A ]
XY 1 MAX 16 MIN LW AT-XY ;
: F3KEY ( -- ) // MOVE WINDOW LEFT 7 COLUMNS
EW 7 - 0 MAX TO EW
BRANCH [ A@ , ] -;
: F5KEY ( -- ) // MOVE WINDOW RIGHT 7 COLUMNS
EW 7 + #28 MIN TO EW
BRANCH [ A@ , ] -;
: F7KEY ( -- ) #28 TO EW // MOVE EDIT WINDOW TO END
BRANCH [ A> , ] -;
: F2KEY ( -- ) // MOVE CURSOR TO BELOW EDIT AREA
0 18 AT-XY ;
FORTH DEFINITIONS
Although with the last two, there will be a line wrap on the Commodore 64's video screen.
F1KEY moves the editing window all the way to the left by setting EW to zero. XY returns the X (from left to right) and Y (from top to bottom) coordinates of the text cursor. AT-XY sets the coordinates, which places the cursor at those coordinates.
Suppose I wish to add a comment for the definition of F1KEY . While in the editor vocabulary, I press the F1 key and scroll up to the line with the name F1KEY . I press the F7 key and the listing is updated to show the last 36 columns of the screen, but the cursor is on the same line as it was before pressing the F7 key. I can now add a comment knowing it is on the correct line.
Re: Fleet Forth design considerations
Posted: Tue Sep 12, 2023 5:26 pm
by JimBoyd
In the Fleet Forth kernel there are eighteen headerless words. Words like the one formerly named TRAVERSE or some of the words used by the sector read/write word, SR/W . These headerless words have no use outside the kernel, which is why they are headerless. There is another group of words which are not directly used outside the kernel, the run-time words of other words.
Here are some of the compiling words and associated run-time words
Code: Select all
DO (DO)
?DO (?DO)
LOOP (LOOP)
+LOOP (+LOOP)
" (")
." (.")
ABORT" (ABORT")
IS (IS)
TO (IS)
I may change the names of some of these run-time words but these words will not be made headerless. The few dozen bytes saved would not justify the increased complexity in the design of the decompiler, SEE .
Re: Fleet Forth design considerations
Posted: Tue Sep 26, 2023 6:38 pm
by JimBoyd
I've mentioned Fleet Forth's TRACE and the ability to change what information is displayed by setting the DEFERred word .STEP to a step display word more appropriate for the trace.
Here is yet another example of how TRACE's step display can be customized. I recently made a modification to Fleet Forth's metacompiler. One of the words copies a string to HERE and modifies it, if necessary. The reason PAD isn't used is because Fleet Forth has the word >HERE in the kernel.
I wanted to see what was happening at HERE when tracing that word.
Code: Select all
: .STMETA
(.ST1) CR HERE $10 DUMP ;
' .STMETA IS .STEP
(.ST1) is the default step display word. .STMETA calls (.ST1) for the usual display for the current step and then dumps the first sixteen bytes at HERE .
Re: Fleet Forth design considerations
Posted: Sun Oct 01, 2023 8:18 pm
by JimBoyd
I may have given Fleet Forth's EXPECT nonstandard behavior.
The Forth-83 Standard states the following concerning EXPECT .
Code: Select all
9.5.2 EXPECT
Control characters may be processed to allow system dependent
editing of the characters prior to receipt. Therefore, a
Standard Program may not anticipated that control characters can
be received.
It doesn't seem to say anything about intercepting function keys; however, I thought such a capability would be useful.
I have found nothing in the Forth-83 Standard for or against this extra functionality in EXPECT .
The closest I've seen is this excerpt for the Forth 2012 Standard's ACCEPT .
It is recommended that all non-graphic characters be reserved for editing or control functions and not be stored in the input string.
Fleet Forth is a Forth-83 Standard Forth for the most part; however, when there is something not covered in the Forth-83 Standard I will check the other standards for the least objectionable approach to minimizing divergent behavior in my Forth when adding new functionality to the kernel. One such example is renaming Fleet Forth's UNDO to UNLOOP .
ACCEPT is the Forth 2012 Standard version of EXPECT with slightly different behavior. As such, where the Forth-83 Standard is quiet concerning the use of function keys in EXPECT , I'll accept the Forth 2012 Standard's recommendations for ACCEPT . The relevant phrase describing ACCEPT is "or control functions" which would indicate that it is acceptable for ACCEPT , and therefore EXPECT , to intercept function keys and use them for control purposes.
Re: Fleet Forth design considerations
Posted: Tue Oct 24, 2023 9:25 pm
by JimBoyd
FSAVE is Fleet Forth's word to save the Forth system as a Commodore program file. FSAVE would prompt for a file name and use EXPECT to read in the file name to use; however, I have found that I would occasionally type a file name right after FSAVE when I already had a file name in mind and I was in a hurry. This made me wonder if having the file name inline was a more natural way to do things. The file name used by FSAVE now follows it in the text stream. FSAVE uses 0 WORD so file names with spaces can be used.
Re: Fleet Forth design considerations
Posted: Wed Oct 25, 2023 3:29 pm
by BruceRMcF
I may have given Fleet Forth's EXPECT nonstandard behavior.
The Forth-83 Standard states the following concerning EXPECT .
Code: Select all
9.5.2 EXPECT
Control characters may be processed to allow system dependent
editing of the characters prior to receipt. Therefore, a
Standard Program may not anticipated that control characters can
be received.
It doesn't seem to say anything about intercepting function keys; however, I thought such a capability would be useful.
I have found nothing in the Forth-83 Standard for or against this extra functionality in EXPECT .
The closest I've seen is this excerpt for the Forth 2012 Standard's ACCEPT .
It is recommended that all non-graphic characters be reserved for editing or control functions and not be stored in the input string.
Forth-94 slightly generalized the Forth-83 EXPECT specification by specifying that author of Forth-94 source could not depend on being able to receive non-graphical characters, which is more explicit about setting aside what is returned by a function key unless it returns one or more graphical characters.
However, function keys themselves do not come into scope until Forth-2012, which is also when "a source cannot depend on non-graphical characters being stored" was strengthened to "it is recommended that a system refrain from storing non-graphical characters".
Fleet Forth is a Forth-83 Standard Forth for the most part; however, when there is something not covered in the Forth-83 Standard I will check the other standards for the least objectionable approach to minimizing divergent behavior in my Forth when adding new functionality to the kernel. One such example is renaming Fleet Forth's UNDO to UNLOOP .
ACCEPT is the Forth 2012 Standard version of EXPECT with slightly different behavior. As such, where the Forth-83 Standard is quiet concerning the use of function keys in EXPECT , I'll accept the Forth 2012 Standard's recommendations for ACCEPT . The relevant phrase describing ACCEPT is "or control functions" which would indicate that it is acceptable for ACCEPT , and therefore EXPECT , to intercept function keys and use them for control purposes.
I'd say it is good for sanity if EXPECT is implemented in a way that allows a set of Forth-94 / Forth-2012 portability screens to define ACCEPT as "EXPECT SPAN @".
Re: Fleet Forth design considerations
Posted: Tue Nov 07, 2023 11:42 pm
by JimBoyd
One feature of VICE I have used in moderation is the ability to paste text into the simulator. Fleet Forth behaves as though the text is typed in. This does introduce a problem. When loading source from screens on blocks or even from a Commodore sequential file, an ABORT stops the load and returns control to Forth's QUIT loop. When text is pasted into the simulator the QUIT loop still has control. an ABORT stops interpreting text which has already been EXPECTed, or ACCEPTed; however, the simulator continues to fill the keyboard buffer until all pasted text has been inserted into the keyboard buffer. The behavior is exactly as if a programmer typing in source ignores errors and continues typing.
Fleet Forth's ABORT , which is called by ABORT" , is extensible.
Code: Select all
: ABORT ( -- )
SINGLE ERR SP! AP! QUIT -;
SINGLE switches off multitasking.
SP! and AP! clear the data and auxiliary stacks.
ERR is a deferred word which normally executes NOOP a Forth no-op.
I set ERR to the word PURGE when I wish to paste Forth source from a Linux text file.
Code: Select all
: PURGE // EMPTY KEYBOARD
BEGIN // BUFFER
BEGIN
KEY? // ANY KEYSTROKES?
WHILE
KEY DROP
REPEAT
1 JIFFIES // WAIT 1/60 SEC
KEY? 0= // BUFFER EMPTY?
UNTIL ;
KEY? is an AnsiForth word which returns TRUE if a character is available.
The 1 jiffy delay is to give VICE time to refill the keyboard buffer. The inner loop empties the keyboard buffer fast enough that without the delay, PURGE returns before VICE is finished adding pasted text to the buffer.
Re: Fleet Forth design considerations
Posted: Sun Nov 12, 2023 8:01 pm
by JimBoyd
I should have mentioned that keyboard input in Fleet Forth causes the cursor to blink while waiting for input. When PURGE is used to purge the pasted text after an error occurs, I know it is done when the cursor resumes blinking at a steady rate.
Re: Fleet Forth design considerations
Posted: Thu Nov 23, 2023 4:55 am
by JimBoyd
In the Fleet Forth kernel there are eighteen headerless words. Words like the one formerly named TRAVERSE or some of the words used by the sector read/write word, SR/W . These headerless words have no use outside the kernel, which is why they are headerless. There is another group of words which are not directly used outside the kernel, the run-time words of other words.
Some of the run-time words now have the same name as the associated compiling word.
Code: Select all
DO DO
?DO ?DO
LOOP LOOP
+LOOP +LOOP
" "
." ."
ABORT" ABORT"
(IS) is still the run-time for IS and TO .
The run-time words are defined before the word FORTH-83 and the compiling words are defined after. This made updating the source for SEE easier.
To find the run-time words, the FORTH vocabulary is set as both the CONTEXT and CURRENT vocabularies. Create a false vocabulary on the auxiliary stack with FORTH-83 as the latest word with the following:
and make it the CONTEXT vocabulary.
The false vocabulary, the portion of the FORTH vocabulary from FORTH-83 to the beginning is searched. If the sought word is not found in this false CONTEXT vocabulary, the CURRENT vocabulary, which is all of the FORTH vocabulary, is searched.
Code: Select all
OK
SEE DO
DO IMMEDIATE
2DA2 20A6 COMPILE
2DA4 912 DO
2DA6 2CAE >MARK
2DA8 12E6 2+
2DAA 2CC2 <MARK
2DAC 12E6 2+
2DAE 9A8 EXIT
E
OK
0 ' FORTH-83 >LINK 2>A AP0 @ @ CONTEXT ! OK
SEE DO
DO
914 INY
915 FB )Y LDA IP
917 PHA
918 DEY
919 FB )Y LDA IP
91B PHA
91C CLC
91D 3 ,X LDA
91F 80 # ADC
921 PHA
922 3 ,X STA
924 2 ,X LDA
926 PHA
927 SEC
928 0 ,X LDA
92A 2 ,X SBC
92C TAY
92D 1 ,X LDA
92F 3 ,X SBC
931 PHA
932 TYA
933 PHA
934 INX
935 INX
936 INX
937 INX
938 8ED ^^ BPL ' ?BRANCH >BODY 8 +
93A 839 JMP ' ! >BODY 14 +
29
OK
CONSOLE
[Edit: Corrected explanation of the vocabulary search.]
Re: Fleet Forth design considerations
Posted: Fri Nov 24, 2023 12:30 am
by JimBoyd
Leo Brodie introduced the word \S in his book Thinking Forth. \S stops the rest of a screen from loading.
The Forth-83 Standard has the uncontrolled reference word ;S which does the same thing.
Code: Select all
;S -- Interpret only"semi-s"
Stop interpretation of a block.
Re: Fleet Forth design considerations
Posted: Sat Nov 25, 2023 8:53 pm
by JimBoyd
I have another word to parse strings. It is used by the following words.
I call this word CHAR ; however, the Ansi Forth standard has a word by that name which, along with [CHAR] , does what ASCII does in a Forth-83 system so I may rename Fleet Forth's CHAR . It works a lot like the Ansi Forth word PARSE in that it does not skip initial occurrences of the delimiter and it returns an address and count. It is different in that it will ABORT if the delimiter is not found.
I do not wish to change this word's name to PARSE for two reasons. It does more than ANSI Forth's PARSE by aborting if the delimiter is not found and I do not think PARSE is a good name for extracting a string from a text stream. The word PARSE implies some kind of analysis, such as is performed by the parser of some language compilers.
I think the name PLUCK would be a good one. PLUCK a string from the text stream.
Re: Fleet Forth design considerations
Posted: Mon Nov 27, 2023 2:44 am
by BruceRMcF
... The word PARSE implies some kind of analysis, such as is performed by the parser of some language compilers. ...
The dictionary definition I find of parsing has it as a synonym of syntatic analysis and does indeed refer to analyzing a string of symbols, but if the underlying syntax is as simple as Forth ... tokens and separators with the tokens referring to tags if they are present in a dictionary, if not referring to numbers under the current base, ... then the location and the length of the token is much of the syntactic analysis that is required.
Forth 200x PARSE-NAME then is an action to implement the syntactic analysis required for the default syntax, working well with whitespace by skipping leading delimiters, and Forth94 PARSE is an action to support additional syntax to terminate a substring in the string of symbols by defining an explicit terminator, while allowing for empty substrings by not skipping leading delimiters.
In any event, neither Forth94 PARSE nor Forth200x PARSE-NAME have an abort or error on delimiter not found, but both implicitly take the end of the input buffer as matching any parsing delimiter, so if there is an abort on the delimiter not found, perhaps it's best to not call it PARSE or PARSE-NAME to avoid confusion.
... I think the name PLUCK would be a good one. PLUCK a string from the text stream.
Is that pluck as in chicken feathers or pluck as in a harp string?
Given that the Forth style syntax is just slicing up the input buffer into tokens, I like SLICE if you want to name it in terms of the action or TOKEN or STRING if you want to name it by the result it is going to give.
Re: Fleet Forth design considerations
Posted: Sat Dec 02, 2023 8:46 pm
by JimBoyd
Is that pluck as in chicken feathers or pluck as in a harp string?
Harp string.
Given that the Forth style syntax is just slicing up the input buffer into tokens, I like SLICE if you want to name it in terms of the action or TOKEN or STRING if you want to name it by the result it is going to give.
I'm avoiding the name STRING. It seems more suitable for a word which creates string variables. Scott Ballantyne's Blazin' Forth has the word STRING which does exactly that. Fleet Forth's word in question returns an address and count of the text so I am going with the name 'TEXT ( address of text ).
Re: Fleet Forth design considerations
Posted: Tue Dec 26, 2023 9:32 pm
by JimBoyd
Fleet Forth has been revised since I last posted how it handles the text stream. This is how the current version of Fleet Forth handles the text stream.
First, Fleet Forth's QUIT loop.
Fleet Forth has a word WHERE which shows where an error occurred. The first thing WHERE does is store the address of EXIT in its first cell. This prevents recursive error handling if WHERE should cause an error; however, this means QUIT must restore the first cell of WHERE .
Code: Select all
: QUIT ( -- )
[COMPILE] [
BEGIN
RP! // CLEAR RETURN STACK
['] LIT (IS) WHERE // RESTORE WHERE
CR QUERY INTERPRET
STATE @ 0=
CS-DUP UNTIL // CONTINUE IF COMPILING
." OK"
AGAIN -; // LOOP FOREVER
QUERY is the Forth-83 Standard word to read text from the input device (usually the keyboard) and store it in the text input buffer.
QUERY is the only word which places text in the text input buffer. Fleet Forth's QUERY has support for any word which may point TIB to an address other than the text input buffer by pointing TIB to the actual text input buffer before using TIB .
Code: Select all
: QUERY ( -- )
'TIB IS TIB TIB #80 EXPECT
SPAN C@ #TIB !
0 0
LABEL BLK.2!
BLK 2! ;
'TIB is a metacompiler macro which evaluates to $2A7, the address for the text input buffer.
BLK is actually a double variable. The first cell is normally accessed by words using BLK . >IN is a constant which points to the second cell of BLK . The ability to fetch the values of both BLK and >IN with a single 2@ and store both values with a single 2! results in a smaller Fleet Forth kernel.
QUERY uses EXPECT to read text into the text input buffer ( TIB ) and stores the value of SPAN in #TIB . EXPECT does not store a terminating zero byte.
QUERY then stores a zero in both BLK and >IN .
LOAD and LINELOAD .
Code: Select all
: LINELOAD ( LINE# BLK# -- )
DUP 0=
ABORT" CAN'T LOAD 0"
BLK 2@ 2>R
BLK ! C/L * >IN !
INTERPRET 2R>
BRANCH [ BLK.2! , ] -;
: LOAD ( U -- )
0 SWAP BRANCH
[ ' LINELOAD >BODY , ] -;
LINELOAD aborts if the block to load is zero. For any other block number, LINELOAD saves the contents of BLK and >IN to the return stack. It then stores the block number on the data stack in BLK then multiplies the line number by C/L and stores that value in >IN . LINELOAD uses INTERPRET to interpret the contents of the block before restoring the previous contents of BLK and >IN .
LOAD places zero on the stack, swaps this number with the block number and branches to LINELOAD .
EVALUATE is a word in ANSI Forth which will interpret the contents of a string. It takes an address and the length of a string. I have found it to be a useful addition to the Fleet Forth system.
Code: Select all
: EVALUATE ( ADR CNT -- )
TIB #TIB @ 2>R
LIT [ >MARK ] ENTER
0 0 LIT
[ ' LINELOAD >BODY DUP TRUE
" LOAD 0" COUNT MATCH ?HUH
+ , ]
ENTER
2R>
[ >RESOLVE ]
#TIB ! (IS) TIB ;
This source is for a very compact version of EVALUATE ; however, it is relatively straight forward. Save the contents of TIB and #TIB to the return stack. Point TIB at the string to be evaluated and save the string length in #TIB . Place two zeroes on the data stack and use ENTER to perform the equivalent of a GOSUB into the body of LINELOAD just past LINELOAD's inline error string "CAN'T LOAD 0." LINELOAD will save and restore the contents of BLK and >IN . Since EVALUATE supplies a block number of zero, INTERPRET will actually interpret the contents of the string pointed to by TIB and #TIB .
Finally, restore the original contents of TIB and #TIB .
INTERPRET interprets (and/or compiles) the text from the text stream. It exits when the text stream is exhausted. INTERPRET uses NAME which uses WORD to process strings from the text stream one blank delimited string at a time.
WORD uses 'STREAM to get the address and length of the remaining text stream.
Code: Select all
: 'STREAM ( -- ADR N )
BLK @ ?DUP
IF
BLOCK B/BUF
ELSE
TIB #TIB @
THEN
>IN @
OVER UMIN /STRING ;
'STREAM places the address of a block buffer and $400 on the data stack if a non zero block number is stored in BLK or it will place the address of the text input buffer and its length on the data stack.
'STREAM then duplicates the length of the text stream. The unsigned minimum of the length and the value of >IN is used with /STRING to return the address and length of the portion of the text stream which has not yet been processed. If the value of >IN is equal to or greater than the length of the text stream, the text stream has been exhausted and 'STREAM will return an address just past the text stream and a length of zero.
WORD uses 'STREAM so it has access to the address of the unprocessed portion of the text stream as well as the remaining length. WORD stores a string at HERE as a count byte followed by the text of the string and a trailing blank. The trailing blank is needed by NUMBER? .
Fleet Forth has no word called ENCLOSE . Fleet Forth's WORD uses two primitives named SKIP and SCAN . Both words take the address of a string, its length and a character (the delimiter). SKIP returns the address of the first character which is not the delimiter and the remaining length of the string. SCAN returns the address of the first delimiter encountered and the remaining length of the string. If SKIP only encounters delimiter characters or SCAN can not find a delimiter, the address just past the string and a length of zero is returned. Neither word alters the string. Both SKIP and SCAN can handle strings of arbitrary size.
The source for INTERPRET .
Code: Select all
: INTERPRET
BEGIN
PAUSE NAME C@ 0EXIT
HERE I/C
AGAIN -;
PAUSE is the task switcher, which is set to NOOP when not multitasking. PAUSE is included in INTERPRET's loop to allow multitasking while the text stream is being interpreted.
There is no special word with a blank name to stop interpretation. If the text stream is exhausted, WORD returns a string with a length of zero. INTERPRET checks the length of the string and exits if it is zero.
If the length of the string is not zero, INTERPRET places the address of HERE on the stack for I/C , the word which interprets or compiles one word.
This is why Fleet Forth's text input buffer, block buffers and evaluated strings do not need a trailing zero.