- ABORT
- ABORT"
- ABS
- ACCEPT
- ACTION-OF
- AGAIN
- ALIGN
- ALIGNED
- ALLOT
- AND
- BASE
- BEGIN
- BL
- BUFFER:
- [
- [CHAR]
- [COMPILE]
- [']
- CASE
- C,
- CELL+
- CELLS
- C@
- CHAR
- CHAR+
- CHARS
- COMPILE,
- CONSTANT
- COUNT
- CR
- CREATE
- C!
- :
- :NONAME
- ,
- C"
- DECIMAL
- DEFER
- DEFER@
- DEFER!
- DEPTH
- DO
- DOES>
- DROP
- DUP
- /
- /MOD
- .R
- .(
- ."
- ELSE
- EMIT
- ENDCASE
- ENDOF
- ENVIRONMENT?
- ERASE
- EVALUATE
- EXECUTE
- EXIT
- =
- FALSE
- FILL
- FIND
- FM/MOD
- @
- HERE
- HEX
- HOLD
- HOLDS
- I
- IF
- IMMEDIATE
- INVERT
- IS
- J
- KEY
- LEAVE
- LITERAL
- LOOP
- LSHIFT
- MARKER
- MAX
- MIN
- MOD
- MOVE
- M*
- -
- NEGATE
- NIP
- OF
- OR
- OVER
- 1-
- 1+
- PAD
- PARSE-NAME
- PARSE
- PICK
- POSTPONE
- +
- +LOOP
- +!
- QUIT
- RECURSE
- REFILL
- REPEAT
- RESTORE-INPUT
- R@
- ROLL
- ROT
- RSHIFT
- R>
- SAVE-INPUT
- SIGN
- SM/REM
- SOURCE-ID
- SOURCE
- SPACE
- SPACES
- STATE
- SWAP
- ;
- S\"
- S"
- S>D
- !
- THEN
- TO
- TRUE
- TUCK
- TYPE
- '
- *
- */
- */MOD
- 2DROP
- 2DUP
- 2/
- 2@
- 2OVER
- 2R@
- 2R>
- 2SWAP
- 2!
- 2*
- 2>R
- U.R
- UM/MOD
- UM*
- UNLOOP
- UNTIL
- UNUSED
- U.
- U<
- U>
- VALUE
- VARIABLE
- WHILE
- WITHIN
- WORD
- XOR
- 0=
- 0<
- 0>
- 0<>
- \
- .
- <
- >
- <>
- #>
- <#
- #
- #S
- (
- ?DO
- ?DUP
- >BODY
- >IN
- >NUMBER
- >R
6.1.2050 QUIT CORE
Empty the return stack, store zero in SOURCE-ID if it is present, make the user input device the input source, and enter interpretation state. Do not display a message. Repeat the following:
- Accept a line from the input source into the input buffer, set >IN to zero, and interpret.
- Display the implementation-defined system prompt if in interpretation state, all processing has been completed, and no ambiguous condition exists.
See:
Implementation:
( empty the return stack and set the input source to the user input device )
POSTPONE [
REFILL
WHILE
['] INTERPRET CATCH
CASE
0 OF STATE @ 0= IF ." OK" THEN CR ENDOF
-1 OF ( Aborted ) ENDOF
-2 OF ( display message from ABORT" ) ENDOF
( default ) DUP ." Exception # " .
ENDCASE
REPEAT BYE
;
INTERPRET
that embodies the text interpreter semantics
described in 3.4 The Forth text interpreter.
Further discussion of the interpret loop can be found in
A.6.2.0945 COMPILE,.
ContributeContributions
alextangent [76] The reference implementation is incorrectSuggested reference implementation2019-03-16 14:59:29
: QUIT ( empty the return stack and ) ( set the input source to the user input device ) POSTPONE [ BEGIN ( missing in the reference implementation) REFILL WHILE ['] INTERPRET CATCH CASE 0 OF STATE @ 0= IF ." OK" THEN CR ENDOF -1 OF ( Aborted) ENDOF -2 OF ( display message from ABORT" ) ENDOF ( default ) DUP ." Exception # " . ENDCASE REPEAT BYE ;
Reported by marek.brunda at gmail.com
ruv [259] Should QUIT propagate exceptions?Request for clarification2022-08-18 12:09:37
After a recent ForthHub discussion Is QUIT expected to THROW? the following question arises.
In the presence of the following facts:
QUIT
is not updated in the Exception word setQUIT
empties the return stack, but doesn't empty the exception stack.THROW
restores depth of the return stack when there is an exception frame on the exception stack.
How the code :noname ['] quit catch . ." test-passed "; execute
should work if the user pass abort
from the user input device to the Forth text interpreter?
Does the Standard implies that the return stack is emptied, and then its depth is restored, and it's content is not garbled? Or that QUIT should not empty the return stack in presence of an exception frame? And, should the system eventually print "-1 test-passed"?
lmr [324] control stack clearing?Request for clarification2023-12-24 03:10:07
QUIT
must clear the return stack. But is there any part of the spec that mentions clearing the control stack? I don't see any mention of that in QUIT
, THROW
, ABORT
or :
.
lmr [330] "make the user input device the input source"Example2024-01-06 15:25:11
Since QUIT
is bound to reset the input source, what's a "clean" way to handle, say, command-line arguments (like -e
or file arguments in Gforth)? Of course there are plenty of hacks to come up with.
lmr [334] INTERPRETSuggested reference implementation2024-01-30 22:30:13
This is a simple way to fulfill the INTERPRET
part of the reference implementation, plus ]]
… [[
via a special STATE
of -2. FWIW, it relies on as few predefined words as possible. It computes "actions" to undertake for each token/state, with a single EXECUTE
in the main loop. I think it might be useful; there are other sections of the spec that are relevant but (1) I haven't seen a self-contained version of INTERPRET
and (2) those sections are rather large, so I thought I'd leave this here. I've tested it in GForth (with a suitable prelude). Prerequisites:
- compile(ish) words:
: ; [ ] PARSE-NAME NAME>COMPILE NAME>INTERPRET COMPILE,
: FIND-NAME ( c-addr u -- nt ) ( find a name in search order ) ;
: LIT, ( n -- ) ( ... ) ; \ non-immediate, non-STATE-bound LITERAL
: PARSE-NUM?#-13 ( c-addr u -- n ) ( parse num or #-13 THROW ) ;
: LITERAL ( n -- ) LIT, ; IMMEDIATE RESTRICT
: FIND-NAME?#-13 ( c-addr u -- nt ) \ FIND-NAME or #-13 THROW
FIND-NAME DUP 0= #-13 AND THROW
;
: PARSE-NAME?#-16 ( "name" -- c-addr u ) \ PARSE-NAME or #-16 THROW
PARSE-NAME DUP 0= #-16 AND THROW
;
: NAME' ( c-addr u -- nt ) PARSE-NAME?#-16 FIND-NAME?#-13 ;
: ' ( "name" -- ixt ) NAME' NAME>INTERPRET ;
: NAME>COMPILED ( nt -- cxt ) NAME>COMPILE DROP ;
: COMPILE' ( "name" -- cxt ) NAME' NAME>COMPILED ;
: [NAME'] ( c-addr u -- nt ) NAME' LIT, ; IMMEDIATE RESTRICT
: ['] ( "name" -- ixt ) ' LIT, ; IMMEDIATE RESTRICT
: [COMPILE'] ( "name" -- xt ) COMPILE' LIT, ; IMMEDIATE RESTRICT
: [COMPILE] ( "name" -- xt ) COMPILE' COMPILE, ; IMMEDIATE RESTRICT
: SWAP&LIT&COMP ( x xt -- )
DUP ['] EXECUTE =
IF DROP \ optimization
ELSE SWAP LIT,
THEN COMPILE,
;
: POSTPONE-NAME ( nt -- ) NAME>COMPILE SWAP&LIT&COMP ;
: POSTPONE ( "name" -- ) NAME' POSTPONE-NAME ; IMMEDIATE RESTRICT
: NAME>STATE?ACTION ( nt -- x xt )
STATE @ IF
NAME>COMPILE
ELSE
NAME>INTERPRET DUP 0= #-14 AND THROW
['] EXECUTE
THEN
;
: NUMBER>STATE?ACTION ( n -- n xt )
STATE @ IF ['] LIT,
ELSE ['] NOOP
THEN
;
: ]] #-2 STATE ! ; IMMEDIATE RESTRICT
: [[ TRUE STATE ! ; IMMEDIATE RESTRICT
: _XT_[[ [COMPILE'] [[ ; \ CONSTANT ...
: POSTPONE?ACTION ( x xt -- x xt pxt )
\ takes an \<x xt\> pair as produced by NAME>COMPILE
\ adds SWAP&LIT&COMP if STATE = -2 and word <> [[
OVER _XT_[[ <>
STATE @ #-2 =
AND IF ['] SWAP&LIT&COMP
ELSE ['] EXECUTE
THEN
;
: STRING>STATE?ACTION ( c-addr u -- x xt pxt )
2DUP FIND-NAME
?DUP 0= IF
PARSE-NUM?#-13 NUMBER>STATE?ACTION
ELSE NIP NIP NAME>STATE?ACTION
THEN
POSTPONE?ACTION
;
: INTERPRET
BEGIN
PARSE-NAME DUP 0= IF 2DROP EXIT THEN
STRING>STATE?ACTION EXECUTE
AGAIN
;