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