fix(v4.0.0): EXPECT, QUERY and WORD follow FORTH-79
Ruled 2026-10-04: standard words follow the standard where v3 did not. EXPECT takes up to n characters (v3 took n-1) and does nothing for n <= 0. QUERY takes up to 80 (v3: 1024). WORD stores the delimiter it met, or a zero at the end of the text, after the word, and leaves >IN just past that one delimiter (v3 skipped them all and stored a zero); the word may be up to 255 characters (v3: 62). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
443439c3d2
commit
7b42a9b6c1
+29
-23
@@ -7,12 +7,11 @@
|
||||
\ capsule: it runs on the host node. Rests on core.v4.
|
||||
\
|
||||
\ Constants the loader supplies:
|
||||
\ TIB byte address of the text input buffer, #TIB bytes long
|
||||
\ #TIB 1025: 1024 characters and a terminating zero, as v3
|
||||
\ TIB byte address of the text input buffer; QUERY fills at most 81 bytes
|
||||
\ >IN word address of the variable: offset in TIB of the next character
|
||||
\ SPAN word address of the variable: how many characters the last
|
||||
\ EXPECT or QUERY read
|
||||
\ WBUF byte address of WORD's buffer, 64 bytes
|
||||
\ WBUF byte address of WORD's buffer, 257 bytes
|
||||
\ (P) word address of six cells of scratch for this file
|
||||
\ TIB >IN SPAN and BL are in-line: written in a definition they are literals.
|
||||
|
||||
@@ -21,25 +20,26 @@ macro BL 32 endmacro
|
||||
\ ( -- baddr u ) the input buffer and how much of it is in use
|
||||
: SOURCE TIB SPAN a! @ -if P drop 0 P: ;
|
||||
|
||||
\ ( baddr u -- ) read a line into u bytes at baddr, as v3's fgets did: at
|
||||
\ most u-1 characters, stopping after a new-line, which is taken but not
|
||||
\ stored; then a zero. A line of u-1 characters or more leaves what did not
|
||||
\ fit, its new-line included, to be read next. SPAN is the number of characters stored. With u = 0
|
||||
\ nothing is read or stored; u < 0 does nothing and sets NODE-ERROR.
|
||||
\ ( baddr n -- ) FORTH-79: characters from the terminal are stored from
|
||||
\ baddr upward until a new-line or until n have been received; the new-line
|
||||
\ is taken but not stored. A zero is added after the text, so the buffer
|
||||
\ must hold n + 1 bytes. No action for n <= 0. SPAN is how many characters
|
||||
\ were stored (SPAN is not FORTH-79; v3 has it). A line longer than n leaves
|
||||
\ the rest, its new-line included, to be read next.
|
||||
: EXPECT
|
||||
-if OK drop drop NODE-ERROR b! -1 !b ;
|
||||
OK: if ZERO
|
||||
-if NN drop drop ; \ n < 0
|
||||
NN: if ZERO
|
||||
over push \ p n R: start
|
||||
L: -1 + if END \ room for the zero only
|
||||
L: if END
|
||||
push KEY dup -10 + if NL \ p c x R: start n
|
||||
drop over C! 1 + pop jump L
|
||||
drop over C! 1 + pop -1 + jump L
|
||||
NL: drop drop pop
|
||||
END: drop 0 over C! \ p
|
||||
pop - SPAN a! ! ;
|
||||
ZERO: drop drop 0 SPAN a! ! ;
|
||||
ZERO: drop drop ;
|
||||
|
||||
\ ( -- ) read a line into TIB and start at its beginning
|
||||
: QUERY TIB #TIB EXPECT 0 >IN a! ! ;
|
||||
\ ( -- ) FORTH-79: up to 80 characters, or a line, into TIB; >IN to 0.
|
||||
: QUERY TIB 80 EXPECT 0 >IN a! ! ;
|
||||
|
||||
\ ---- WORD ------------------------------------------------------------------
|
||||
\ (P)+0 the delimiter, (P)+1 the length of the text in TIB.
|
||||
@@ -56,21 +56,26 @@ macro (WLEN) (P) 1 + endmacro
|
||||
L: (LEFT) -if E drop (CH) if E drop 1 + jump L
|
||||
E: drop ;
|
||||
|
||||
\ ( c -- baddr ) the next word of TIB delimited by c, as a counted string
|
||||
\ in WBUF with a zero after it. Leading delimiters are skipped; so, as in
|
||||
\ v3, are all those that follow the word. A word longer than 62 characters
|
||||
\ is cut to 62. At the end of the text the count is 0.
|
||||
\ ( c -- baddr ) FORTH-79: characters are taken from TIB until the
|
||||
\ delimiter c or the end of the text, leading delimiters ignored, and stored
|
||||
\ in WBUF as a counted string. The delimiter met -- c, or a zero if the text
|
||||
\ ran out -- is stored after them and is not counted. >IN is left just past
|
||||
\ that delimiter. With nothing left the count is 0. The count is a byte,
|
||||
\ so a word longer than 255 characters is cut to 255.
|
||||
: WORD
|
||||
255 and (WDELIM) a! !
|
||||
SPAN a! @ -if A drop 0 A: (WLEN) a! !
|
||||
>IN a! @ -if B drop 0 B:
|
||||
(SKIP) dup push (SCAN) \ end R: start
|
||||
pop over over - \ end start len
|
||||
dup -63 + -if CAP drop jump FITS CAP: drop drop 62 FITS:
|
||||
dup -256 + -if CAP drop jump FITS CAP: drop drop 255 FITS:
|
||||
dup WBUF C!
|
||||
dup push push TIB + WBUF 1 + pop CMOVE \ end R: len
|
||||
0 pop WBUF + 1 + C!
|
||||
(SKIP) >IN a! ! WBUF ;
|
||||
(LEFT) -if RANOUT
|
||||
drop (WDELIM) a! @ pop WBUF + 1 + C! \ the delimiter after the text
|
||||
1 + >IN a! ! WBUF ;
|
||||
RANOUT: drop 0 pop WBUF + 1 + C!
|
||||
>IN a! ! WBUF ;
|
||||
|
||||
\ ---- ENCLOSE ---------------------------------------------------------------
|
||||
\ (P)+0 the delimiter, (P)+1 the string's address.
|
||||
@@ -120,7 +125,8 @@ macro (WLEN) (P) 1 + endmacro
|
||||
\ the current BASE; it may begin with a minus sign. If it is empty, is only
|
||||
\ a sign, or holds anything that is not a digit, the result is 0 and
|
||||
\ NODE-ERROR is set. The character after the string must not be a digit
|
||||
\ (WORD puts a zero there); if it is, that too is reported as an error. (P)+3 the address of its last character, (P)+4 the sign.
|
||||
\ (WORD puts the delimiter or a zero there); if it is, that too is reported
|
||||
\ as an error. (P)+3 the address of its last character, (P)+4 the sign.
|
||||
: NUMBER
|
||||
dup C@ if ERR2
|
||||
over + (P) 3 + a! ! \ baddr
|
||||
|
||||
Reference in New Issue
Block a user