Digest #188 2022-07-06
Contributions
Are these supposed to support RECURSE?
Replies
A small remark to the POSTPONE test.
We can factor postpone in two parts with state-execute similiar to base-execute:
: state-execute ( xt s -- ) state@ >r state ! catch r> state ! throw ;
: POSTPONE ( "name" -- ) parse-name forth-recognizer -2 state-execute ; immediate
That's not very difficult anymore.
IMHO the idea to use a deferred forth-recognize is good and more flexible than a stack of recognizers. But the translator xt makes postpone more difficult. But we can factor postpone into two parts. One that restores the stack contents at runtime similar to lit,
, and one that does the compilation. If we use rectype, similar to the proposal of recognizers from 2018, but with lit,
as third method, we get an easy postpone
and '
. Here, we can reuse the compile method directly by the second factor of postpone.
variable state
: translate>interpret @ ;
: translate>compile cell+ @ ;
: translate>lit, cell+ cell+ @ ;
\ Well, its translate>*lit, in fact; i.e. regenerate ( i*x ) at runtime.
Defer forth-recognizer ( addr u -- i*x translator / notfound )
Defer perform ( i*x translator -- j*x )
: perform>interpret translate>interpret execute ;
: perform>compile translate>compile execute ;
: on -1 swap ! ;
: off 0 swap ! ;
: [ ['] perform>interpret is perform state off ; IMMEDIATE
: ] ['] perform>compile is perform state on ;
\ alternativly:
\ :noname is perform state ; dup
\ : [ ['] perform>interpret [ compile, ] off ; IMMEDIATE
\ : ] ['] perform>compile [ compile, ] on ;
\ another alternative:
\ : perform state @ IF translator>compile ELSE translator>interpret THEN execute ;
' [ execute \ initialize state and perform
: interpret ( i*x -- j*x )
BEGIN
?stack parse-name dup WHILE
forth-recognizer perform
REPEAT ;
: lit, ( n -- ) lit lit , , ; \ or postpone literal
: throw-13 -13 throw ;
: translator ( xt-*lit, xt-compile xt-interpret "name" -- )
create , , , ;
' throw-13 dup dup translator notfound
' lit,
:noname ( nt -- xt-execute | xt-compile, ) dup >cfa swap immediate? IF execute ELSE compile, THEN ;
:noname ( i*x nt -- j*x ) >cfa execute ;
translator translate-nt
' lit,
' lit,
:name ; \ noop
translator translate-const-cell
: rec-nt ( addr u -- nt translate-nt | notfound )
forth-wordlist find-name-in dup IF translate-nt ELSE drop notfound THEN ;
: rec-num ( addr u -- n translate-const-cell | notfound )
0. 2swap >number 0= IF 2drop translate-const-cell ELSE 2drop drop notfound THEN ;
: minimal-recognizer ( addr u -- nt nt-translator | n num-translator | notfound )
2>r 2r@ rec-nt dup notfound = IF drop 2r@ rec-num THEN 2rdrop ;
' minimal-recognizer is forth-recognizer
\ simple postpone
: postpone ( "name" -- )
parse'n'recognize
dup translator>compile >r translator>lit, execute r> compile,
; IMMEDIATE
\ postpone optimized for immedate words
: postpone ( "name" -- ) \ optimized for immediate words
parse'n'recognize \ ( i*x translator )
dup translate-nt = IF ( nt translator )
over immediate? IF drop >cfa compile, exit THEN
THEN
dup translator>compile >r translator>lit, execute r> compile, ;
; IMMEDIATE
: ' ( "name" -- xt ) parse'n'recognize translate-nt <> IF throw-13 THEN >cfa ; IMMEDIATE