feat(v4.0.0): every error is raised and ends the line (D-18)
Ruled 2026-10-04: guard all errors. The errors that set NODE-ERROR and let the line run on now stop it at once, with a message. - A store of a non-zero code to NODE-ERROR is a trap, a sixth kind of fault: nothing after it executes, the return stack is emptied, and the data stack is left as the word left it. Not attached, NODE-ERROR is plain memory, as the tests below the prompt use it. - The capsule's words store a code where they stored -1, and the prompt's (RAISED) prints its message: Negative count, Not a number, Number too long, Not a character, Dictionary full, Name missing, Control structure mismatch, Control structures too deep. - ' and COMPILE and [COMPILE] of a word that is not there say UNKNOWN WORD: 'xxx', as the interpreter does. - tests: the trap in test_exec.c; every message from the prompt, with the rest of the line not run and the stack kept, in test_host_quit.c. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
644bfc0a25
commit
dc7e37ba5c
+12
-10
@@ -35,6 +35,7 @@
|
||||
\ (C)+5 what a loop's end lays after its test
|
||||
\ (C)+6 (C)+7 a branch and a tag a control word is holding
|
||||
\ (C)+8 whether a data word's entry was made
|
||||
\ (C)+9 the error code a line is being abandoned with
|
||||
\ (CFP) word address of the control-flow stack's pointer
|
||||
\ CFBASE CFEND word addresses of its first cell and of the cell past its last
|
||||
|
||||
@@ -47,11 +48,15 @@ macro ROT push SWAP pop SWAP endmacro
|
||||
\ NODE-ERROR. A definition that was under way stays hidden. It returns to
|
||||
\ whatever called INTERPRET, which is QUIT (quit.v4): QUIT sees NODE-ERROR
|
||||
\ and prints ERROR.
|
||||
: (ABANDON)
|
||||
\ (ABANDON-AS) is the same with an error code (core.v4) for the prompt to
|
||||
\ print the message of.
|
||||
: (ABANDON-AS) ( code -- )
|
||||
(C)+9 a! !
|
||||
0 STATE a! ! (CG-RESET)
|
||||
CFBASE (CFP) a! !
|
||||
SPAN a! @ >IN a! !
|
||||
NODE-ERROR b! -1 !b ;
|
||||
(C)+9 a! @ NODE-ERROR b! !b ;
|
||||
: (ABANDON) -1 jump (ABANDON-AS)
|
||||
|
||||
\ ---- the control-flow stack ----------------------------------------------------
|
||||
|
||||
@@ -59,7 +64,7 @@ macro ROT push SWAP pop SWAP endmacro
|
||||
: >CF
|
||||
(CFP) a! @ CFEND xor if FULL
|
||||
drop (CFP) a! @ dup 1 + ! a! ! ;
|
||||
FULL: drop drop jump (ABANDON)
|
||||
FULL: drop drop 8 jump (ABANDON-AS) \ control structures too deep
|
||||
|
||||
\ ( -- x ) pop; 0 from an empty stack, which no opening word leaves
|
||||
: CF>
|
||||
@@ -153,10 +158,7 @@ header INTERPRET
|
||||
drop
|
||||
STATE a! @ if KEEP drop (LIT,) jump L
|
||||
KEEP: drop jump L
|
||||
BAD: drop drop \ "UNKNOWN WORD: '"
|
||||
$4E4B4E55 (EMIT4) $204E574F (EMIT4) $44524F57 (EMIT4) $27203A (EMIT4)
|
||||
(.WORD) 39 EMIT CR
|
||||
jump (ABANDON)
|
||||
BAD: drop drop (UNKNOWN) drop jump (ABANDON)
|
||||
EOL: drop drop ;
|
||||
|
||||
\ ---- state ---------------------------------------------------------------------
|
||||
@@ -206,13 +208,13 @@ header COMPILE immediate compile-only
|
||||
: COMPILE
|
||||
32 WORD (LOOKUP) if MISSING
|
||||
(LIT,) &(COMPILE,) jump (CALL,)
|
||||
MISSING: drop jump (ABANDON)
|
||||
MISSING: drop (UNKNOWN) drop jump (ABANDON)
|
||||
|
||||
\ [COMPILE] xxx FORTH-79: compile xxx even though it is immediate
|
||||
header [COMPILE] immediate compile-only
|
||||
: BRACKET-COMPILE
|
||||
32 WORD (LOOKUP) if MISSING jump (COMPILE,)
|
||||
MISSING: drop jump (ABANDON)
|
||||
MISSING: drop (UNKNOWN) drop jump (ABANDON)
|
||||
|
||||
\ ---- data words ---------------------------------------------------------------------
|
||||
\ A data word's code is one call to its run-time routine; the call leaves the
|
||||
@@ -267,7 +269,7 @@ header DOES> immediate compile-only
|
||||
\ ( tag wanted -- ) if they differ, abandon the line and leave the control
|
||||
\ word that called this as well: its return address is dropped, so the
|
||||
\ abandoning returns to the interpreter and nothing more is laid down.
|
||||
: (PAIR) xor if OK drop pop drop jump (ABANDON) OK: drop ;
|
||||
: (PAIR) xor if OK drop pop drop 7 jump (ABANDON-AS) OK: drop ;
|
||||
|
||||
\ ( ref -- ) the branch at ref lands here
|
||||
: (HERE!) (FLUSH) HERE SWAP jump (RESOLVE)
|
||||
|
||||
+11
-2
@@ -6,6 +6,15 @@
|
||||
\
|
||||
\ Constants the loader supplies: N-1 (cell bits - 1), NODE-ERROR, CONSOLE-TX,
|
||||
\ CONSOLE-RX, CONSOLE-STATUS, BASE.
|
||||
\
|
||||
\ ERRORS (D-18). A word that finds an error takes its arguments off the stack
|
||||
\ and stores a code in NODE-ERROR. On a node with a prompt that store is a
|
||||
\ trap: the word goes no further, and the prompt prints the message for the
|
||||
\ code and ERROR (quit.v4, (RAISED)). The codes:
|
||||
\ 1 Negative count 2 Not a number 3 Number too long
|
||||
\ 4 Not a character 5 Dictionary full 6 Name missing
|
||||
\ 7 Control structure mismatch 8 Control structures too deep
|
||||
\ -1 the word has printed its own message
|
||||
|
||||
macro SWAP over push push drop pop pop endmacro
|
||||
macro - push inv pop + inv endmacro \ x y -- x-y
|
||||
@@ -72,7 +81,7 @@ header C!
|
||||
\ ---- section 5.9: strings ------------------------------------------------
|
||||
header CMOVE
|
||||
: CMOVE ( src dst u -- )
|
||||
-if OK drop drop drop NODE-ERROR b! -1 !b ;
|
||||
-if OK drop drop drop NODE-ERROR b! 1 !b ;
|
||||
OK: if DONE push
|
||||
over C@ over C! 1 + push 1 + pop pop -1 + jump OK
|
||||
DONE: drop drop drop ;
|
||||
@@ -93,7 +102,7 @@ header COUNT
|
||||
: COUNT ( baddr -- baddr+1 c ) dup C@ push 1 + pop ;
|
||||
header TYPE
|
||||
: TYPE ( baddr u -- )
|
||||
-if OK drop drop NODE-ERROR b! -1 !b ;
|
||||
-if OK drop drop NODE-ERROR b! 1 !b ;
|
||||
OK: if DONE over C@ EMIT push 1 + pop -1 + jump OK
|
||||
DONE: drop drop ;
|
||||
|
||||
|
||||
+11
-4
@@ -41,7 +41,7 @@ macro OR over inv and xor endmacro
|
||||
\ they are storing in A while the space is taken: nothing of theirs is then
|
||||
\ on the data stack under (DP+), which itself needs three cells (D-2).
|
||||
|
||||
: (DERR) ( -- 0 ) NODE-ERROR b! -1 !b 0 ;
|
||||
: (DERR) ( -- 0 ) NODE-ERROR b! 5 !b 0 ; \ dictionary full
|
||||
|
||||
\ ( n -- flag ) move DP by n bytes if it stays inside the dictionary space
|
||||
\ and say -1; otherwise leave it, set NODE-ERROR and say 0. The two
|
||||
@@ -66,7 +66,7 @@ header ,
|
||||
a!
|
||||
DP b! @b 3 + -4 and \ the next whole cell, as a byte address
|
||||
dup inv DLIMIT + -3 + -if ROOM \ DLIMIT - (it + 4)
|
||||
drop drop NODE-ERROR b! -1 !b ;
|
||||
drop drop NODE-ERROR b! 5 !b ;
|
||||
ROOM: drop dup 4 + !b \ DP is past it
|
||||
4/ b! a !b ;
|
||||
header C,
|
||||
@@ -148,7 +148,7 @@ header HIDDEN
|
||||
0 , (D) a! @ , LATEST ,
|
||||
HERE (LATEST) a! ! ;
|
||||
FULL: drop ; \ (DP+) has set NODE-ERROR
|
||||
EMPTY: drop NODE-ERROR b! -1 !b ;
|
||||
EMPTY: drop NODE-ERROR b! 6 !b ; \ name missing
|
||||
|
||||
\ ---- looking a name up -----------------------------------------------------
|
||||
|
||||
@@ -186,5 +186,12 @@ header FIND
|
||||
\ ( -- addr ) FORTH-79: the parameter field address of the next word in the
|
||||
\ input stream. Not found is an error: 0, and NODE-ERROR is set. This is '
|
||||
\ when interpreting; compile.v4 adds what ' does when compiling.
|
||||
\ ( -- 0 ) say that the word WORD has just left is not known, as v3 does:
|
||||
\ UNKNOWN WORD: 'xxx'
|
||||
: (UNKNOWN)
|
||||
$4E4B4E55 (EMIT4) $204E574F (EMIT4) $44524F57 (EMIT4) $27203A (EMIT4)
|
||||
WBUF COUNT TYPE 39 EMIT CR
|
||||
NODE-ERROR b! -1 !b 0 ;
|
||||
|
||||
: (') 32 WORD (LOOKUP) if MISSING jump PFA
|
||||
MISSING: drop jump (DERR)
|
||||
MISSING: drop jump (UNKNOWN)
|
||||
|
||||
+1
-1
@@ -183,7 +183,7 @@ header CONVERT
|
||||
header NUMBER
|
||||
: NUMBER
|
||||
(NUMBER?) if BAD drop ;
|
||||
BAD: drop NODE-ERROR b! -1 !b ;
|
||||
BAD: drop NODE-ERROR b! 2 !b ;
|
||||
|
||||
\ ---- comments (5.15) -------------------------------------------------------
|
||||
\ PAREN skips to the closing parenthesis; BACKSLASH skips the rest of the line.
|
||||
|
||||
@@ -43,9 +43,9 @@ header <#
|
||||
: <# ( -- ) HEND HLD b! !b ;
|
||||
header HOLD
|
||||
: HOLD ( c -- )
|
||||
dup -256 and if OKC drop jump ERR
|
||||
OKC: drop HLD b! @b -HFLOOR + -if ROOM drop
|
||||
ERR: drop NODE-ERROR b! -1 !b ;
|
||||
dup -256 and if OKC drop drop NODE-ERROR b! 4 !b ; \ not a character
|
||||
OKC: drop HLD b! @b -HFLOOR + -if ROOM
|
||||
drop drop NODE-ERROR b! 3 !b ; \ the buffer is full
|
||||
ROOM: drop HLD b! @b -1 + dup !b jump C!
|
||||
header SIGN
|
||||
: SIGN ( n -- ) -if L1 drop 45 jump HOLD L1: drop ;
|
||||
|
||||
+21
-2
@@ -87,11 +87,30 @@ header ABORT
|
||||
$75746552 (EMIT4) $73206E72 (EMIT4) $6B636174 (EMIT4) $646E7520 (EMIT4) $6C667265 (EMIT4) $776F (EMIT4) CR
|
||||
2 jump (REPL)
|
||||
|
||||
\ The table the loader gives the node: five words, one for each kind of
|
||||
\ A word has stored an error code in NODE-ERROR (D-18; the codes are listed
|
||||
\ in core.v4). Print its message -- a negative code means the word printed
|
||||
\ its own -- and end the line with ERROR. The return stack has been
|
||||
\ emptied; the data stack is as the word left it.
|
||||
: (RAISED)
|
||||
NODE-ERROR b! @b
|
||||
-if POS drop 2 jump (REPL)
|
||||
POS: -1 + if M1 -1 + if M2 -1 + if M3 -1 + if M4
|
||||
-1 + if M5 -1 + if M6 -1 + if M7 -1 + if M8
|
||||
drop 2 jump (REPL)
|
||||
M1: drop $6167654E (EMIT4) $65766974 (EMIT4) $756F6320 (EMIT4) $746E (EMIT4) CR 2 jump (REPL)
|
||||
M2: drop $20746F4E (EMIT4) $756E2061 (EMIT4) $7265626D (EMIT4) CR 2 jump (REPL)
|
||||
M3: drop $626D754E (EMIT4) $74207265 (EMIT4) $6C206F6F (EMIT4) $676E6F (EMIT4) CR 2 jump (REPL)
|
||||
M4: drop $20746F4E (EMIT4) $68632061 (EMIT4) $63617261 (EMIT4) $726574 (EMIT4) CR 2 jump (REPL)
|
||||
M5: drop $74636944 (EMIT4) $616E6F69 (EMIT4) $66207972 (EMIT4) $6C6C75 (EMIT4) CR 2 jump (REPL)
|
||||
M6: drop $656D614E (EMIT4) $73696D20 (EMIT4) $676E6973 (EMIT4) CR 2 jump (REPL)
|
||||
M7: drop $746E6F43 (EMIT4) $206C6F72 (EMIT4) $75727473 (EMIT4) $72757463 (EMIT4) $696D2065 (EMIT4) $74616D73 (EMIT4) $6863 (EMIT4) CR 2 jump (REPL)
|
||||
M8: drop $746E6F43 (EMIT4) $206C6F72 (EMIT4) $75727473 (EMIT4) $72757463 (EMIT4) $74207365 (EMIT4) $64206F6F (EMIT4) $706565 (EMIT4) CR 2 jump (REPL)
|
||||
|
||||
\ The table the loader gives the node: six words, one for each kind of
|
||||
\ fault in the node's order, each a jump. A jump fills its word, so they
|
||||
\ are one after another.
|
||||
: (FAULTS)
|
||||
jump (FAULT) jump (D-OVER) jump (D-UNDER) jump (R-OVER) jump (R-UNDER)
|
||||
jump (FAULT) jump (D-OVER) jump (D-UNDER) jump (R-OVER) jump (R-UNDER) jump (RAISED)
|
||||
|
||||
\ ---- text in the source ---------------------------------------------------------
|
||||
\ ." and ABORT" take the text up to the next " , which may be none at all
|
||||
|
||||
Reference in New Issue
Block a user