CoreForth-0

p3216/compiler.ft.md


vim:ft=forth:ts=2:sw=2:expandtab

$0040 constant immediate-flag
$0080 constant visible-flag

: depth         s0 sp@ - /cell 1- ;
: rdepth        r0 rp@ - /cell 1- ;
: .s            sp@ depth 1- begin ?dup while
                  swap dup @ hex. space cell+ swap 1-
                repeat drop cr ;

: .r            rp@ rdepth 1- begin ?dup while
                  swap dup @ hex. space cell+ swap 1-
                repeat drop cr ;

: align         here aligned org ;
: link>name     2 cells + ;
: link>flags    cell+ ;
: link>         link>name dup c@ + 1+ aligned ;
: >body         4 cells + ;
: visible?      link>flags @ visible-flag and 0> ;
: immediate?    link>flags @ immediate-flag and 0> ;
: ,link         , ;
: ,call         , ;
: ,enter        $0000f92c , ;
: ,dodoes       $000cf92c , ;
: ,next         $0020ea0c , $0000fe03 , ;
: ,exit         ['] exit ,call ;

: ,dodata       $000c0f28 , $00300c0d , ,next ;
: ,docon        $000c0f2c , $00300c0d , ,next ;

: (s")          r> count 2dup + aligned >r ;

: latest-flags  ( -- addr f ) get-current @ link>flags dup @ ;
: immediate     latest-flags immediate-flag or swap ! ;
: hide          latest-flags visible-flag invert and swap ! ;
: reveal        latest-flags visible-flag or swap ! ;

: literal       postpone lit , ; immediate
: parse-name    bl word count ;

variable state

: [             false state ! ; immediate
: ]             true state ! ;
: compiling?    state @ ;
: interpreting? state @ 0= ;

: stri=         ( c-addr1 u1 c-addr2 u2 -- f )
                rot over <> if drop 2drop 0 exit then
                >r begin
                  2dup ci@= r@ 0<> and while
                  1+ swap 1+ swap
                  r> 1- >r
                repeat
                2drop r> 0=
                ;

: str=          ( c-addr1 u1 c-addr2 u2 -- f )
                rot over <> if drop 2drop 0 exit then
                >r begin
                  2dup c@ swap c@ = r@ 0<> and while
                  1+ swap 1+ swap
                  r> 1- >r
                repeat
                2drop r> 0=
                ;

: search-wordlist               ( c-addr u wid -- 0 | xt -1 | xt 1 )
                @ >r begin
                  2dup r@ link>name count stri= r@ visible? and
                  dup 0= if r> @ dup >r 0= or then
                until 2drop r>
                dup if
                  dup link>
                  swap immediate? not 1 or
                then ;

: find          0                               ( c-addr 0 )
                #order @ 0 do
                  over count                    ( c-addr 0 c-addr' u )
                  i cells context + @           ( c-addr 0 c-addr' u wid )
                  search-wordlist               ( c-addr 0; 0 | w 1 | q -1 )
                  ?dup if                       ( c-addr 0; w 1 | w -1 )
                    2swap 2drop leave           ( w 1 | w -1 )
                  then                          ( c-addr 0 )
                loop                            ( c-addr 0 | w 1 | w -1 )
                ;

: '             bl word find dup 0= if drop count type space $3F emit
                else drop then ;
: words         context @ begin @ ?dup while
                  dup link>name count type space
                repeat ;

: postpone      bl word find 0< if literal postpone ,call
                else ,call then ; immediate
: [']           ' postpone literal ; immediate

$100 buffer: (s#)

: s"            interpreting? if [char] " word count >r (s#) r@ cmove (s#) r> exit then
                postpone (s")
                [char] " word dup dup c@ 1+ here swap move
                c@ 1+ allot align ; immediate
: ."            postpone s" postpone type ; immediate

: (link)        align here get-current dup @ ,link 0 , ! ;

: <builds       (link) bl word
                dup dup c@ 1+ here swap move
                c@ 1+ allot align ;

: :             <builds ,enter hide ] ;
: ;             ,exit reveal [ ; immediate
: :noname       0 , here ,enter ] ; immediate

: create        <builds ,dodata reveal ;
: constant      <builds ,docon , reveal ;
: variable      <builds ,dodata cell allot reveal ;
: buffer:       <builds ,dodata allot reveal ;

: (does>)       here get-current @ link> #8 + org ,dodoes r> ,call org ;
: does>         postpone (does>) ; immediate
: recurse       get-current @ link> ,call ; immediate
: [char]        char postpone literal ; immediate

: value         <builds ,dodata , reveal does> @ ;
: to            bl word find 0= throw 4 cells + ! ;

: undefined     ." *** undefined deferred word called ***" bye ;
: defer         <builds ,dodata ['] undefined , reveal does> @ execute ;
: is            to ;