Implememnt standard word INCLUDED
[pforth] / fth / system.fth
index 0223ab0..c33f40b 100644 (file)
-: FIRST_COLON ;\r
-\r
-: LATEST context @ ;\r
-\r
-: FLAG_IMMEDIATE 64 ;\r
-\r
-: IMMEDIATE\r
-        latest dup c@ flag_immediate OR\r
-        swap c!\r
-;\r
-\r
-: (   41 word drop ; immediate\r
-( That was the definition for the comment word. )\r
-( Now we can add comments to what we are doing! )\r
-( Note that we are in decimal numeric input mode. )\r
-\r
-: \ ( <line> -- , comment out rest of line )\r
-        EOL word drop\r
-; immediate\r
-\r
-\ 1 echo !  \ Uncomment this line to echo Forth code while compiling.\r
-\r
-\ *********************************************************************\r
-\ This is another style of comment that is common in Forth.\r
-\ pFORTH - Portable Forth System\r
-\ Based on HMSL Forth\r
-\\r
-\ Author: Phil Burk\r
-\ Copyright 1994 3DO, Phil Burk, Larry Polansky, Devid Rosenboom\r
-\\r
-\ The pForth software code is dedicated to the public domain,\r
-\ and any third party may reproduce, distribute and modify\r
-\ the pForth software code or any derivative works thereof\r
-\ without any compensation or license.  The pForth software\r
-\ code is provided on an "as is" basis without any warranty\r
-\ of any kind, including, without limitation, the implied\r
-\ warranties of merchantability and fitness for a particular\r
-\ purpose and their equivalents under the laws of any jurisdiction.\r
-\ *********************************************************************\r
-\r
-: COUNT  dup 1+ swap c@ ;\r
-\r
-\ Miscellaneous support words\r
-: ON ( addr -- , set true )\r
-        -1 swap !\r
-;\r
-: OFF ( addr -- , set false )\r
-        0 swap !\r
-;\r
-\r
-: CELL+ ( n -- n+cell )  cell + ;\r
-: CELL- ( n -- n+cell )  cell - ;\r
+: FIRST_COLON ;
+
+: LATEST context @ ;
+
+: FLAG_IMMEDIATE 64 ;
+
+: IMMEDIATE
+        latest dup c@ flag_immediate OR
+        swap c!
+;
+
+: (   41 word drop ; immediate
+( That was the definition for the comment word. )
+( Now we can add comments to what we are doing! )
+( Note that we are in decimal numeric input mode. )
+
+: \ ( <line> -- , comment out rest of line )
+        EOL word drop
+; immediate
+
+\ 1 echo !  \ Uncomment this line to echo Forth code while compiling.
+
+\ *********************************************************************
+\ This is another style of comment that is common in Forth.
+\ pFORTH - Portable Forth System
+\ Based on HMSL Forth
+\
+\ Author: Phil Burk
+\ Copyright 1994 3DO, Phil Burk, Larry Polansky, Devid Rosenboom
+\
+\ The pForth software code is dedicated to the public domain,
+\ and any third party may reproduce, distribute and modify
+\ the pForth software code or any derivative works thereof
+\ without any compensation or license.  The pForth software
+\ code is provided on an "as is" basis without any warranty
+\ of any kind, including, without limitation, the implied
+\ warranties of merchantability and fitness for a particular
+\ purpose and their equivalents under the laws of any jurisdiction.
+\ *********************************************************************
+
+: COUNT  dup 1+ swap c@ ;
+
+\ Miscellaneous support words
+: ON ( addr -- , set true )
+        -1 swap !
+;
+: OFF ( addr -- , set false )
+        0 swap !
+;
+
+: CELL+ ( n -- n+cell )  cell + ;
+: CELL- ( n -- n+cell )  cell - ;
 : CELL* ( n -- n*cell )  cells ;
 : CELL* ( n -- n*cell )  cells ;
-\r
-: CHAR+ ( n -- n+size_of_char ) 1+ ;\r
-: CHARS ( n -- n*size_of_char , don't do anything)  ; immediate\r
-\r
-\ useful stack manipulation words\r
-: -ROT ( a b c -- c a b )\r
-        rot rot\r
-;\r
-: 3DUP ( a b c -- a b c a b c )\r
-        2 pick 2 pick 2 pick\r
-;\r
-: 2DROP ( a b -- )\r
-        drop drop\r
-;\r
-: NIP ( a b -- b )\r
-        swap drop\r
-;\r
-: TUCK ( a b -- b a b )\r
-        swap over\r
-;\r
-\r
-: <= ( a b -- f , true if A <= b )\r
-        > 0=\r
-;\r
-: >= ( a b -- f , true if A >= b )\r
-        < 0=\r
-;\r
-\r
-: INVERT ( n -- 1'comp )\r
-    -1 xor\r
-;\r
-\r
-: NOT ( n -- !n , logical negation )\r
-        0=\r
-;\r
-\r
-: NEGATE ( n -- -n )\r
-        0 swap -\r
-;\r
-\r
-: DNEGATE ( d -- -d , negate by doing 0-d )\r
-        0 0 2swap d-\r
-;\r
-\r
-\r
-\ --------------------------------------------------------------------\r
-\r
-: ID.   ( nfa -- )\r
-    count 31 and type\r
-;\r
-\r
-: DECIMAL   10 base !  ;\r
-: OCTAL      8 base !  ;\r
-: HEX       16 base !  ;\r
-: BINARY     2 base !  ;\r
-\r
-: PAD ( -- addr )\r
-        here 128 +\r
-;\r
-\r
-: $MOVE ( $src $dst -- )\r
-        over c@ 1+ cmove\r
-;\r
-: BETWEEN ( n lo hi -- flag , true if between lo & hi )\r
-        >r over r> > >r\r
-        < r> or 0=\r
-;\r
-: [ ( -- , enter interpreter mode )\r
-        0 state !\r
-; immediate\r
-: ] ( -- enter compile mode )\r
-        1 state !\r
-;\r
-\r
-: EVEN-UP  ( n -- n | n+1 , make even )  dup 1 and +  ;\r
-: ALIGNED  ( addr -- a-addr )\r
-        [ cell 1- ] literal +\r
-        [ cell 1- invert ] literal and\r
-;\r
-: ALIGN ( -- , align DP )  dp @ aligned dp ! ;\r
-: ALLOT ( nbytes -- , allot space in dictionary ) dp +! ( align ) ;\r
-\r
-: C,    ( c -- )  here c! 1 chars dp +! ;\r
-: W,    ( w -- )  dp @ even-up dup dp !    w!  2 chars dp +! ;\r
-: , ( n -- , lay into dictionary )  align here !  cell allot ;\r
-\r
-\ Dictionary conversions ------------------------------------------\r
-\r
-: N>NEXTLINK  ( nfa -- nextlink , traverses name field )\r
-        dup c@ 31 and 1+ + aligned\r
-;\r
-\r
-: NAMEBASE  ( -- base-of-names )\r
-        Headers-Base @\r
-;\r
-: CODEBASE  ( -- base-of-code dictionary )\r
-        Code-Base @\r
-;\r
-\r
-: NAMELIMIT  ( -- limit-of-names )\r
-        Headers-limit @\r
-;\r
-: CODELIMIT  ( -- limit-of-code, last address in dictionary )\r
-        Code-limit @\r
-;\r
-\r
-: NAMEBASE+   ( rnfa -- nfa , convert relocatable nfa to actual )\r
-        namebase +\r
-;\r
-\r
-: >CODE ( xt -- secondary_code_address, not valid for primitives )\r
-        codebase +\r
-;\r
-\r
-: CODE> ( secondary_code_address -- xt , not valid for primitives )\r
-        codebase -\r
-;\r
-\r
-: N>LINK  ( nfa -- lfa )\r
-        2 CELLS -\r
-;\r
-\r
-: >BODY   ( xt -- pfa )\r
-    >code body_offset +\r
-;\r
-\r
-: BODY>   ( pfa -- xt )\r
-    body_offset - code>\r
-;\r
-\r
-\ convert between addresses useable by @, and relocatable addresses.\r
-: USE->REL  ( useable_addr -- rel_addr )\r
-        codebase -\r
-;\r
-: REL->USE  ( rel_addr -- useable_addr )\r
-        codebase +\r
-;\r
-\r
-\ for JForth code\r
-\ : >REL  ( adr -- adr )  ; immediate\r
-\ : >ABS  ( adr -- adr )  ; immediate\r
-\r
-: X@ ( addr -- xt , fetch execution token from relocatable )   @ ;\r
-: X! ( addr -- xt , store execution token as relocatable )   ! ;\r
-\r
-\ Compiler support ------------------------------------------------\r
-: COMPILE, ( xt -- , compile call to xt )\r
-        ,\r
-;\r
-\r
-( Compiler support , based on FIG )\r
-: [COMPILE]  ( <name> -- , compile now even if immediate )\r
-    ' compile,\r
-;  IMMEDIATE\r
-\r
-: (COMPILE) ( xt -- , postpone compilation of token )\r
-        [compile] literal       ( compile a call to literal )\r
-        ( store xt of word to be compiled )\r
-        \r
-        [ ' compile, ] literal   \ compile call to compile,\r
-        compile,\r
-;\r
-        \r
-: COMPILE  ( <name> -- , save xt and compile later )\r
-    ' (compile)\r
-; IMMEDIATE\r
-\r
-\r
-: :NONAME ( -- xt , begin compilation of headerless secondary )\r
-        align\r
-        here code>   \ convert here to execution token\r
-        ]\r
-;\r
-\r
-\ Error codes defined in ANSI Exception word set.\r
-: ERR_ABORT         -1 ;   \ general abort\r
-: ERR_EXECUTING    -14 ;   \ compile time word while not compiling\r
-: ERR_PAIRS        -22 ;   \ mismatch in conditional\r
-: ERR_DEFER       -258 ;  \ not a deferred word\r
-\r
-: ABORT ( i*x -- )\r
-       ERR_ABORT throw\r
-;\r
-\r
-\ Conditionals in '83 form -----------------------------------------\r
-: CONDITIONAL_KEY ( -- , lazy constant ) 29521 ;\r
-: ?CONDITION   ( f -- )  conditional_key - err_pairs ?error ;\r
-: >MARK      ( -- addr )   here 0 ,  ;\r
-: >RESOLVE   ( addr -- )   here over - swap !  ;\r
-: <MARK      ( -- addr )   here  ;\r
-: <RESOLVE   ( addr -- )   here - ,  ;\r
-\r
-: ?COMP  ( -- , error if not compiling )\r
-        state @ 0= err_executing ?error\r
-;\r
-: ?PAIRS ( n m -- )\r
-        - err_pairs ?error\r
-;\r
-\ conditional primitives\r
-: IF     ( -- f orig )  ?comp compile 0branch  conditional_key >mark     ; immediate\r
-: THEN   ( f orig -- )  swap ?condition  >resolve   ; immediate\r
-: BEGIN  ( -- f dest )  ?comp conditional_key <mark   ; immediate\r
-: AGAIN  ( f dest -- )  compile branch  swap ?condition  <resolve  ; immediate\r
-: UNTIL  ( f dest -- )  compile 0branch swap ?condition  <resolve  ; immediate\r
-: AHEAD  ( -- f orig )  compile branch   conditional_key >mark     ; immediate\r
-\r
-\ conditionals built from primitives\r
-: ELSE   ( f orig1 -- f orig2 )\r
-       [compile] AHEAD  2swap [compile] THEN  ; immediate\r
-: WHILE  ( f dest -- f orig f dest )  [compile]  if   2swap ; immediate\r
-: REPEAT ( -- f orig f dest ) [compile] again  [compile] then  ; immediate\r
-\r
-: [']  ( <name> -- xt , define compile time tick )\r
-        ?comp ' [compile] literal\r
-; immediate\r
-\r
-\ for example:\r
-\ compile time:  compile create , (does>) then ;\r
-\ execution time:  create <name>, ',' data, then patch pi to point to @\r
-\    : con create , does> @ ;\r
-\    345 con pi\r
-\    pi\r
-\ \r
-: (DOES>)  ( xt -- , modify previous definition to execute code at xt )\r
-        latest name> >code \ get address of code for new word\r
-        cell + \ offset to second cell in create word\r
-        !      \ store execution token of DOES> code in new word\r
-;\r
-\r
-: DOES>   ( -- , define execution code for CREATE word )\r
-        0 [compile] literal \ dummy literal to hold xt\r
-        here cell-          \ address of zero in literal\r
-        compile (does>)     \ call (DOES>) from new creation word\r
-               >r                  \ move addrz to return stack so ; doesn't see stack garbage\r
-        [compile] ;         \ terminate part of code before does>\r
-               r>\r
-        :noname       ( addrz xt )\r
-        swap !              \ save execution token in literal\r
-; immediate\r
-\r
-: VARIABLE  ( <name> -- )\r
-    CREATE 0 , \ IMMEDIATE\r
-\       DOES> [compile] aliteral  \ %Q This could be optimised\r
-;\r
-\r
-: 2VARIABLE  ( <name> -c- ) ( -x- addr )\r
-        create 0 , 0 ,\r
-;\r
-\r
-: CONSTANT  ( n <name> -c- ) ( -x- n )\r
-        CREATE , ( n -- )\r
-        DOES> @ ( -- n )\r
-;\r
-\r
-\r
-\r
-0 1- constant -1\r
-0 2- constant -2\r
-\r
-: 2! ( x1 x2 addr -- , store x2 followed by x1 )\r
-        swap over ! cell+ !\r
-;\r
-: 2@ ( addr -- x1 x2 )\r
-        dup cell+ @ swap @\r
-;\r
-\r
-\r
-: ABS ( n -- |n| )\r
-        dup 0<\r
-        IF negate\r
-        THEN\r
-;\r
-: DABS ( d -- |d| )\r
-        dup 0<\r
-        IF dnegate\r
-        THEN\r
-;\r
-\r
-: S>D  ( s -- d , extend signed single precision to double )\r
-        dup 0<\r
-        IF -1\r
-        ELSE 0\r
-        THEN\r
-;\r
-\r
-: D>S ( d -- s ) drop ;\r
-\r
-: /MOD ( a b -- rem quo , unsigned version, FIXME )\r
-        >r s>d r> um/mod\r
-;\r
-\r
-: MOD ( a b -- rem )\r
-        /mod drop\r
-;\r
-\r
-: 2* ( n -- n*2 )\r
-        1 lshift\r
-;\r
-: 2/ ( n -- n/2 )\r
-        1 arshift\r
-;\r
-\r
-: D2*  ( d -- d*2 )\r
-        2* over 
-        cell 8 * 1- rshift or  swap\r
-        2* swap\r
-;\r
-\r
-\ define some useful constants ------------------------------\r
-1 0= constant FALSE\r
-0 0= constant TRUE\r
-32 constant BL\r
-\r
-\r
-\ Store and Fetch relocatable data addresses. ---------------\r
-: IF.USE->REL  ( use -- rel , preserve zero )\r
-        dup IF use->rel THEN\r
-;\r
-: IF.REL->USE  ( rel -- use , preserve zero )\r
-        dup IF rel->use THEN\r
-;\r
-\r
-: A!  ( dictionary_address addr -- )\r
-    >r if.use->rel r> !\r
-;\r
-: A@  ( addr -- dictionary_address )\r
-    @ if.rel->use\r
-;\r
-\r
-: A, ( dictionary_address -- )\r
-    if.use->rel ,\r
-;\r
-\r
-\ Stack data structure ----------------------------------------\r
-\ This is a general purpose stack utility used to implement necessary\r
-\ stacks for the compiler or the user.  Not real fast.\r
-\ These stacks grow up which is different then normal.\r
-\   cell 0 - stack pointer, offset from pfa of word\r
-\   cell 1 - limit for range checking\r
-\   cell 2 - first data location\r
-\r
-: :STACK   ( #cells -- )\r
-        CREATE  2 cells ,          ( offset of first data location )\r
-                dup ,              ( limit for range checking, not currently used )\r
-                cells cell+ allot  ( allot an extra cell for safety )\r
-;\r
-\r
-: >STACK  ( n stack -- , push onto stack, postincrement )\r
-        dup @ 2dup cell+ swap ! ( -- n stack offset )\r
-        + !\r
-;\r
-\r
-: STACK>  ( stack -- n , pop , predecrement )\r
-        dup @ cell- 2dup swap !\r
-        + @\r
-;\r
-\r
-: STACK@ ( stack -- n , copy )\r
-        dup @ cell- + @ \r
-;\r
-\r
-: STACK.PICK ( index stack -- n , grab Nth from top of stack )\r
-        dup @ cell- +\r
-        swap cells -   \ offset for index\r
-        @ \r
-;\r
-: STACKP ( stack -- ptr , to next empty location on stack )\r
-       dup @ +\r
-;\r
-\r
-: 0STACKP  ( stack -- , clear stack)\r
-    8 swap !\r
-;\r
-\r
-32 :stack ustack\r
-ustack 0stackp\r
-\r
-\ Define JForth like words.\r
-: >US ustack >stack ;\r
-: US> ustack stack> ;\r
-: US@ ustack stack@ ;\r
-: 0USP ustack 0stackp ;\r
-\r
-\r
-\ DO LOOP ------------------------------------------------\r
-\r
-3 constant do_flag\r
-4 constant leave_flag\r
-5 constant ?do_flag\r
-\r
-: DO    ( -- , loop-back do_flag jump-from ?do_flag )\r
-        ?comp\r
-        compile  (do)\r
-        here >us do_flag  >us  ( for backward branch )\r
-; immediate\r
-\r
-: ?DO    ( -- , loop-back do_flag jump-from ?do_flag  , on user stack )\r
-        ?comp\r
-        ( leave address to set for forward branch )\r
-        compile  (?do)\r
-        here 0 ,\r
-        here >us do_flag  >us  ( for backward branch )\r
-        >us ( for forward branch ) ?do_flag >us\r
-; immediate\r
-\r
-: LEAVE  ( -- addr leave_flag )\r
-        compile (leave)\r
-        here 0 , >us\r
-        leave_flag >us\r
-; immediate\r
-\r
-: LOOP-FORWARD  ( -us- jump-from ?do_flag -- )\r
-        BEGIN\r
-                us@ leave_flag =\r
-                us@ ?do_flag =\r
-                OR\r
-        WHILE\r
-                us> leave_flag =\r
-                IF\r
-                        us> here over - cell+ swap !\r
-                ELSE\r
-                        us> dup\r
-                        here swap -\r
-                        cell+ swap !\r
-                THEN\r
-        REPEAT\r
-;\r
-\r
-: LOOP-BACK  (  loop-addr do_flag -us- )\r
-        us> do_flag ?pairs\r
-        us> here -  here\r
-        !\r
-        cell allot\r
-;\r
-\r
-: LOOP    ( -- , loop-back do_flag jump-from ?do_flag )\r
-   compile  (loop)\r
-   loop-forward loop-back\r
-; immediate\r
-\r
-\ : DOTEST 5 0 do 333 . loop 888 . ;\r
-\ : ?DOTEST0 0 0 ?do 333 . loop 888 . ;\r
-\ : ?DOTEST1 5 0 ?do 333 . loop 888 . ;\r
-\r
-: +LOOP    ( -- , loop-back do_flag jump-from ?do_flag )\r
-   compile  (+loop)\r
-   loop-forward loop-back\r
-; immediate\r
-        \r
-: UNLOOP ( loop-sys -r- )\r
-        r> \ save return pointer\r
-        rdrop rdrop\r
-        >r\r
-;\r
-\r
-: RECURSE ( ? -- ? , call the word currently being defined )\r
-        latest  name> compile,\r
-; immediate\r
-\r
-\r
-\r
-: SPACE  bl emit ;\r
-: SPACES  512 min 0 max 0 ?DO space LOOP ;\r
-: 0SP depth 0 ?do drop loop ;\r
-\r
-: >NEWLINE ( -- , CR if needed )\r
-        out @ 0>\r
-        IF cr\r
-        THEN\r
-;\r
-\r
-\r
-\ Support for DEFER --------------------\r
-: CHECK.DEFER  ( xt -- , error if not a deferred word by comparing to type )\r
-    >code @\r
-        ['] emit >code @\r
-        - err_defer ?error\r
-;\r
-\r
-: >is ( xt -- address_of_vector )\r
-        >code\r
-        cell +\r
-;\r
-\r
-: (IS)  ( xt_do xt_deferred -- )\r
-        >is !\r
-;\r
-\r
-: IS  ( xt <name> -- , act like normal IS )\r
-        '  \ xt\r
-        dup check.defer \r
-        state @\r
-        IF [compile] literal compile (is)\r
-        ELSE (is)\r
-        THEN\r
-; immediate\r
-\r
-: (WHAT'S)  ( xt -- xt_do )\r
-        >is @\r
-;\r
-: WHAT'S  ( <name> -- xt , what will deferred word call? )\r
-        '  \ xt\r
-        dup check.defer\r
-        state @\r
-        IF [compile] literal compile (what's)\r
-        ELSE (what's)\r
-        THEN\r
-; immediate\r
-\r
-: /STRING   ( addr len n -- addr' len' )\r
-   over min  rot over   +  -rot  -\r
-;\r
-: PLACE   ( addr len to -- , move string )\r
-   3dup  1+  swap cmove  c! drop\r
-;\r
-\r
-: PARSE-WORD   ( char -- addr len )\r
-   >r  source tuck >in @ /string  r@ skip over swap r> scan\r
-   >r  over -  rot r>  dup 0<> + - >in !\r
-;\r
-: PARSE   ( char -- addr len )\r
-   >r  source >in @  /string  over swap  r> scan\r
-   >r  over -  dup r> 0<>  -  >in +!\r
-;\r
-\r
-: LWORD  ( char -- addr )\r
-        parse-word here place here \ 00002 , use PARSE-WORD\r
-;\r
-\r
-: ASCII ( <char> -- char , state smart )\r
-        bl parse drop c@\r
-        state @\r
-        IF [compile] literal\r
-        THEN\r
-; immediate\r
-\r
-: CHAR ( <char> -- char , interpret mode )\r
-        bl parse drop c@\r
-;\r
-\r
-: [CHAR] ( <char> -- char , for compile mode )\r
-        char [compile] literal\r
-; immediate\r
-\r
-: $TYPE  ( $string -- )\r
-        count type\r
-;\r
-\r
-: 'word   ( -- addr )   here ;\r
-\r
-: EVEN    ( addr -- addr' )   dup 1 and +  ;\r
-\r
-: (C")   ( -- $addr , some Forths return addr AND count, OBSOLETE?)\r
-        r> dup count + aligned >r\r
-;\r
-: (S")   ( -- c-addr cnt )\r
-        r> count 2dup + aligned >r\r
-;\r
-\r
-: (.")  ( -- , type following string )\r
-        r> count 2dup + aligned >r type\r
-;\r
-\r
-: ",  ( adr len -- , place string into dictionary )\r
-         tuck 'word place 1+ allot align\r
-;\r
-: ,"   ( -- )\r
-   [char] " parse ",\r
-;\r
-\r
-: .(  ( <string> -- , type string delimited by parentheses )\r
-       [CHAR] ) PARSE TYPE\r
-; IMMEDIATE\r
-\r
-: ."   ( <string> -- , type string )\r
-        state @\r
-        IF      compile (.")  ,"\r
-        ELSE [char] " parse type\r
-        THEN\r
-; immediate\r
-\r
-\r
-: .'   ( <string> -- , type string delimited by single quote )\r
-        state @\r
-        IF    compile (.")  [char] ' parse ",\r
-        ELSE [char] ' parse type\r
-        THEN\r
-; immediate\r
-\r
-: C"    ( <string> -- addr , return string address, ANSI )\r
-        state @\r
-        IF compile (c")   ,"\r
-        ELSE [char] " parse pad place pad\r
-        THEN\r
-; immediate\r
-\r
-: S"    ( <string> -- , -- addr , return string address, ANSI )\r
-        state @\r
-        IF compile (s")   ,"\r
-        ELSE [char] " parse pad place pad count\r
-        THEN\r
-; immediate\r
-\r
-: "    ( <string> -- , -- addr , return string address )\r
-        [compile] C"\r
-; immediate\r
-: P"    ( <string> -- , -- addr , return string address )\r
-        [compile] C"\r
-; immediate\r
-\r
-: ""  ( <string> -- addr )\r
-        state @\r
-        IF \r
-                compile (C")\r
-                bl parse-word  ",\r
-        ELSE\r
-                bl parse-word pad place pad\r
-        THEN\r
-; immediate\r
-\r
-: SLITERAL ( addr cnt -- , compile string )\r
-       compile (S")\r
-       ",\r
-; IMMEDIATE\r
-\r
-: $APPEND ( addr count $1 -- , append text to $1 )\r
-    over >r\r
-        dup >r\r
-    count +  ( -- a2 c2 end1 )\r
-    swap cmove\r
-    r> dup c@  ( a1 c1 )\r
-    r> + ( -- a1 totalcount )\r
-    swap c!\r
-;\r
-\r
-\r
-\ ANSI word to replace [COMPILE] and COMPILE ----------------\r
-: POSTPONE  ( <name> -- )\r
-       bl word find\r
-       dup 0=\r
-       IF\r
-               ." Postpone could not find " count type cr abort\r
-       ELSE\r
-               0>\r
-               IF compile,  \ immediate\r
-               ELSE (compile)  \ normal\r
-               THEN\r
-       THEN\r
-; immediate\r
-\r
-\ -----------------------------------------------------------------\r
-\ Auto Initialization\r
-: AUTO.INIT  ( -- )\r
-\ Kernel finds AUTO.INIT and executes it after loading dictionary.\r
-\      ." Begin AUTO.INIT ------" cr\r
-;\r
-: AUTO.TERM  ( -- )\r
-\ Kernel finds AUTO.TERM and executes it on bye.\r
-\      ." End AUTO.TERM ------" cr\r
-;\r
-\r
-\ -------------- INCLUDE ------------------------------------------\r
-variable TRACE-INCLUDE\r
-\r
-: INCLUDE.MARK.START  ( $filename -- , mark start of include for FILE?)\r
-       " ::::"  pad $MOVE\r
-       count pad $APPEND\r
-       pad ['] noop (:)\r
-;\r
-\r
-: INCLUDE.MARK.END  ( -- , mark end of include )\r
-       " ;;;;" ['] noop (:)\r
-;\r
-\r
-: $INCLUDE ( $filename -- )\r
-\ Print messages.\r
-        trace-include @\r
-        IF\r
-                >newline ." Include " dup count type cr\r
-        THEN\r
-        here >r\r
-        dup\r
-        count r/o open-file \r
-        IF  ( -- $filename bad-fid )\r
-                drop ." Could not find file " $type cr abort\r
-        ELSE ( -- $filename good-fid )\r
-                swap include.mark.start\r
-                dup >r   \ save fid for close-file\r
-                depth >r\r
-                include-file\r
-                depth 1+ r> -\r
-                IF\r
-                        ." Warning: stack depth changed during include!" cr\r
-                        .s cr\r
-                        0sp\r
-                THEN\r
-                r> close-file drop\r
-                include.mark.end\r
-        THEN\r
-        trace-include @\r
-        IF\r
-                ."     include added " here r@ - . ." bytes,"\r
-                codelimit here - . ." left." cr\r
-        THEN\r
-        rdrop\r
-;\r
-\r
-create INCLUDE-SAVE-NAME 128 allot\r
-: INCLUDE ( <fname> -- )\r
-        BL lword\r
-        dup include-save-name $move  \ save for RI\r
-        $include\r
-;\r
-\r
-: RI ( -- , ReInclude previous file as a convenience )\r
-        include-save-name $include\r
-;\r
-\r
-: INCLUDE? ( <word> <file> -- , load file if word not defined )\r
-        bl word find\r
-        IF drop bl word drop  ( eat word from source )\r
-        ELSE drop include\r
-        THEN\r
-;\r
-\r
-\ desired sizes for dictionary loaded after SAVE-FORTH\r
-variable HEADERS-SIZE  \r
-variable CODE-SIZE\r
-\r
-: AUTO.INIT\r
-       auto.init\r
-       codelimit codebase - code-size !\r
-       namelimit namebase - headers-size !\r
-;\r
-auto.init\r
-\r
-: SAVE-FORTH ( $name -- )\r
-    0                                    \ Entry point\r
-    headers-ptr @ namebase - 65536 +     \ NameSize\r
-    headers-size @ MAX\r
-    here codebase - 131072 +              \ CodeSize\r
-    code-size @ MAX\r
-    (save-forth)\r
-    IF\r
-               ." SAVE-FORTH failed!" cr abort\r
-    THEN\r
-;\r
-\r
-: TURNKEY ( $name entry-token-- )\r
-    0     \ NameSize = 0, names not saved in turnkey dictionary\r
-    here codebase - 131072 +             \ CodeSize, remember that base is HEX\r
-    (save-forth)\r
-    IF\r
-               ." TURNKEY failed!" cr abort\r
-    THEN\r
-;\r
-\r
-\ Now that we can load from files, load remainder of dictionary.\r
-\r
-trace-include on\r
-trace-stack on\r
-\r
-include loadp4th.fth\r
-\r
-decimal\r
-\r
-: ;;;; ;  \ Mark end of this file so FILE? can find things in here.\r
-FREEZE    \ prevent forgetting below this point\r
-\r
-.( Dictionary compiled, save in "pforth.dic".) cr\r
-c" pforth.dic" save-forth\r
-\r
-\ Save the dictionary in "pfdicdat.h" file so pForth can be compiled for standalone mode.\r
-SDAD\r
+
+: CHAR+ ( n -- n+size_of_char ) 1+ ;
+: CHARS ( n -- n*size_of_char , don't do anything)  ; immediate
+
+\ useful stack manipulation words
+: -ROT ( a b c -- c a b )
+        rot rot
+;
+: 3DUP ( a b c -- a b c a b c )
+        2 pick 2 pick 2 pick
+;
+: 2DROP ( a b -- )
+        drop drop
+;
+: NIP ( a b -- b )
+        swap drop
+;
+: TUCK ( a b -- b a b )
+        swap over
+;
+
+: <= ( a b -- f , true if A <= b )
+        > 0=
+;
+: >= ( a b -- f , true if A >= b )
+        < 0=
+;
+
+: INVERT ( n -- 1'comp )
+    -1 xor
+;
+
+: NOT ( n -- !n , logical negation )
+        0=
+;
+
+: NEGATE ( n -- -n )
+        0 swap -
+;
+
+: DNEGATE ( d -- -d , negate by doing 0-d )
+        0 0 2swap d-
+;
+
+
+\ --------------------------------------------------------------------
+
+: ID.   ( nfa -- )
+    count 31 and type
+;
+
+: DECIMAL   10 base !  ;
+: OCTAL      8 base !  ;
+: HEX       16 base !  ;
+: BINARY     2 base !  ;
+
+: PAD ( -- addr )
+        here 128 +
+;
+
+: $MOVE ( $src $dst -- )
+        over c@ 1+ cmove
+;
+: BETWEEN ( n lo hi -- flag , true if between lo & hi )
+        >r over r> > >r
+        < r> or 0=
+;
+: [ ( -- , enter interpreter mode )
+        0 state !
+; immediate
+: ] ( -- enter compile mode )
+        1 state !
+;
+
+: EVEN-UP  ( n -- n | n+1 , make even )  dup 1 and +  ;
+: ALIGNED  ( addr -- a-addr )
+        [ cell 1- ] literal +
+        [ cell 1- invert ] literal and
+;
+: ALIGN ( -- , align DP )  dp @ aligned dp ! ;
+: ALLOT ( nbytes -- , allot space in dictionary ) dp +! ( align ) ;
+
+: C,    ( c -- )  here c! 1 chars dp +! ;
+: W,    ( w -- )  dp @ even-up dup dp !    w!  2 chars dp +! ;
+: , ( n -- , lay into dictionary )  align here !  cell allot ;
+
+\ Dictionary conversions ------------------------------------------
+
+: N>NEXTLINK  ( nfa -- nextlink , traverses name field )
+        dup c@ 31 and 1+ + aligned
+;
+
+: NAMEBASE  ( -- base-of-names )
+        Headers-Base @
+;
+: CODEBASE  ( -- base-of-code dictionary )
+        Code-Base @
+;
+
+: NAMELIMIT  ( -- limit-of-names )
+        Headers-limit @
+;
+: CODELIMIT  ( -- limit-of-code, last address in dictionary )
+        Code-limit @
+;
+
+: NAMEBASE+   ( rnfa -- nfa , convert relocatable nfa to actual )
+        namebase +
+;
+
+: >CODE ( xt -- secondary_code_address, not valid for primitives )
+        codebase +
+;
+
+: CODE> ( secondary_code_address -- xt , not valid for primitives )
+        codebase -
+;
+
+: N>LINK  ( nfa -- lfa )
+        2 CELLS -
+;
+
+: >BODY   ( xt -- pfa )
+    >code body_offset +
+;
+
+: BODY>   ( pfa -- xt )
+    body_offset - code>
+;
+
+\ convert between addresses useable by @, and relocatable addresses.
+: USE->REL  ( useable_addr -- rel_addr )
+        codebase -
+;
+: REL->USE  ( rel_addr -- useable_addr )
+        codebase +
+;
+
+\ for JForth code
+\ : >REL  ( adr -- adr )  ; immediate
+\ : >ABS  ( adr -- adr )  ; immediate
+
+: X@ ( addr -- xt , fetch execution token from relocatable )   @ ;
+: X! ( addr -- xt , store execution token as relocatable )   ! ;
+
+\ Compiler support ------------------------------------------------
+: COMPILE, ( xt -- , compile call to xt )
+        ,
+;
+
+( Compiler support , based on FIG )
+: [COMPILE]  ( <name> -- , compile now even if immediate )
+    ' compile,
+;  IMMEDIATE
+
+: (COMPILE) ( xt -- , postpone compilation of token )
+        [compile] literal       ( compile a call to literal )
+        ( store xt of word to be compiled )
+
+        [ ' compile, ] literal   \ compile call to compile,
+        compile,
+;
+
+: COMPILE  ( <name> -- , save xt and compile later )
+    ' (compile)
+; IMMEDIATE
+
+
+: :NONAME ( -- xt , begin compilation of headerless secondary )
+        align
+        here code>   \ convert here to execution token
+        ]
+;
+
+\ Error codes defined in ANSI Exception word set.
+: ERR_ABORT         -1 ;   \ general abort
+: ERR_ABORTQ        -2 ;   \ for abort"
+: ERR_EXECUTING    -14 ;   \ compile time word while not compiling
+: ERR_PAIRS        -22 ;   \ mismatch in conditional
+: ERR_DEFER       -258 ;  \ not a deferred word
+
+: ABORT ( i*x -- )
+    ERR_ABORT throw
+;
+
+\ Conditionals in '83 form -----------------------------------------
+: CONDITIONAL_KEY ( -- , lazy constant ) 29521 ;
+: ?CONDITION   ( f -- )  conditional_key - err_pairs ?error ;
+: >MARK      ( -- addr )   here 0 ,  ;
+: >RESOLVE   ( addr -- )   here over - swap !  ;
+: <MARK      ( -- addr )   here  ;
+: <RESOLVE   ( addr -- )   here - ,  ;
+
+: ?COMP  ( -- , error if not compiling )
+        state @ 0= err_executing ?error
+;
+: ?PAIRS ( n m -- )
+        - err_pairs ?error
+;
+\ conditional primitives
+: IF     ( -- f orig )  ?comp compile 0branch  conditional_key >mark     ; immediate
+: THEN   ( f orig -- )  swap ?condition  >resolve   ; immediate
+: BEGIN  ( -- f dest )  ?comp conditional_key <mark   ; immediate
+: AGAIN  ( f dest -- )  compile branch  swap ?condition  <resolve  ; immediate
+: UNTIL  ( f dest -- )  compile 0branch swap ?condition  <resolve  ; immediate
+: AHEAD  ( -- f orig )  compile branch   conditional_key >mark     ; immediate
+
+\ conditionals built from primitives
+: ELSE   ( f orig1 -- f orig2 )
+    [compile] AHEAD  2swap [compile] THEN  ; immediate
+: WHILE  ( f dest -- f orig f dest )  [compile]  if   2swap ; immediate
+: REPEAT ( -- f orig f dest ) [compile] again  [compile] then  ; immediate
+
+: [']  ( <name> -- xt , define compile time tick )
+        ?comp ' [compile] literal
+; immediate
+
+\ for example:
+\ compile time:  compile create , (does>) then ;
+\ execution time:  create <name>, ',' data, then patch pi to point to @
+\    : con create , does> @ ;
+\    345 con pi
+\    pi
+\
+: (DOES>)  ( xt -- , modify previous definition to execute code at xt )
+        latest name> >code \ get address of code for new word
+        cell + \ offset to second cell in create word
+        !      \ store execution token of DOES> code in new word
+;
+
+: DOES>   ( -- , define execution code for CREATE word )
+        0 [compile] literal \ dummy literal to hold xt
+        here cell-          \ address of zero in literal
+        compile (does>)     \ call (DOES>) from new creation word
+        >r                  \ move addrz to return stack so ; doesn't see stack garbage
+        [compile] ;         \ terminate part of code before does>
+        r>
+        :noname       ( addrz xt )
+        swap !              \ save execution token in literal
+; immediate
+
+: VARIABLE  ( <name> -- )
+    CREATE 0 , \ IMMEDIATE
+\       DOES> [compile] aliteral  \ %Q This could be optimised
+;
+
+: 2VARIABLE  ( <name> -c- ) ( -x- addr )
+        create 0 , 0 ,
+;
+
+: CONSTANT  ( n <name> -c- ) ( -x- n )
+        CREATE , ( n -- )
+        DOES> @ ( -- n )
+;
+
+
+
+0 1- constant -1
+0 2- constant -2
+
+: 2! ( x1 x2 addr -- , store x2 followed by x1 )
+        swap over ! cell+ !
+;
+: 2@ ( addr -- x1 x2 )
+        dup cell+ @ swap @
+;
+
+
+: ABS ( n -- |n| )
+        dup 0<
+        IF negate
+        THEN
+;
+: DABS ( d -- |d| )
+        dup 0<
+        IF dnegate
+        THEN
+;
+
+: S>D  ( s -- d , extend signed single precision to double )
+        dup 0<
+        IF -1
+        ELSE 0
+        THEN
+;
+
+: D>S ( d -- s ) drop ;
+
+: /MOD ( a b -- rem quo , unsigned version, FIXME )
+        >r s>d r> um/mod
+;
+
+: MOD ( a b -- rem )
+        /mod drop
+;
+
+: 2* ( n -- n*2 )
+        1 lshift
+;
+: 2/ ( n -- n/2 )
+        1 arshift
+;
+
+: D2*  ( d -- d*2 )
+        2* over
+        cell 8 * 1- rshift or  swap
+        2* swap
+;
+
+\ define some useful constants ------------------------------
+1 0= constant FALSE
+0 0= constant TRUE
+32 constant BL
+
+
+\ Store and Fetch relocatable data addresses. ---------------
+: IF.USE->REL  ( use -- rel , preserve zero )
+        dup IF use->rel THEN
+;
+: IF.REL->USE  ( rel -- use , preserve zero )
+        dup IF rel->use THEN
+;
+
+: A!  ( dictionary_address addr -- )
+    >r if.use->rel r> !
+;
+: A@  ( addr -- dictionary_address )
+    @ if.rel->use
+;
+
+: A, ( dictionary_address -- )
+    if.use->rel ,
+;
+
+\ Stack data structure ----------------------------------------
+\ This is a general purpose stack utility used to implement necessary
+\ stacks for the compiler or the user.  Not real fast.
+\ These stacks grow up which is different then normal.
+\   cell 0 - stack pointer, offset from pfa of word
+\   cell 1 - limit for range checking
+\   cell 2 - first data location
+
+: :STACK   ( #cells -- )
+        CREATE  2 cells ,          ( offset of first data location )
+                dup ,              ( limit for range checking, not currently used )
+                cells cell+ allot  ( allot an extra cell for safety )
+;
+
+: >STACK  ( n stack -- , push onto stack, postincrement )
+        dup @ 2dup cell+ swap ! ( -- n stack offset )
+        + !
+;
+
+: STACK>  ( stack -- n , pop , predecrement )
+        dup @ cell- 2dup swap !
+        + @
+;
+
+: STACK@ ( stack -- n , copy )
+        dup @ cell- + @
+;
+
+: STACK.PICK ( index stack -- n , grab Nth from top of stack )
+        dup @ cell- +
+        swap cells -   \ offset for index
+        @
+;
+: STACKP ( stack -- ptr , to next empty location on stack )
+    dup @ +
+;
+
+: 0STACKP  ( stack -- , clear stack)
+    8 swap !
+;
+
+32 :stack ustack
+ustack 0stackp
+
+\ Define JForth like words.
+: >US ustack >stack ;
+: US> ustack stack> ;
+: US@ ustack stack@ ;
+: 0USP ustack 0stackp ;
+
+
+\ DO LOOP ------------------------------------------------
+
+3 constant do_flag
+4 constant leave_flag
+5 constant ?do_flag
+
+: DO    ( -- , loop-back do_flag jump-from ?do_flag )
+        ?comp
+        compile  (do)
+        here >us do_flag  >us  ( for backward branch )
+; immediate
+
+: ?DO    ( -- , loop-back do_flag jump-from ?do_flag  , on user stack )
+        ?comp
+        ( leave address to set for forward branch )
+        compile  (?do)
+        here 0 ,
+        here >us do_flag  >us  ( for backward branch )
+        >us ( for forward branch ) ?do_flag >us
+; immediate
+
+: LEAVE  ( -- addr leave_flag )
+        compile (leave)
+        here 0 , >us
+        leave_flag >us
+; immediate
+
+: LOOP-FORWARD  ( -us- jump-from ?do_flag -- )
+        BEGIN
+                us@ leave_flag =
+                us@ ?do_flag =
+                OR
+        WHILE
+                us> leave_flag =
+                IF
+                        us> here over - cell+ swap !
+                ELSE
+                        us> dup
+                        here swap -
+                        cell+ swap !
+                THEN
+        REPEAT
+;
+
+: LOOP-BACK  (  loop-addr do_flag -us- )
+        us> do_flag ?pairs
+        us> here -  here
+        !
+        cell allot
+;
+
+: LOOP    ( -- , loop-back do_flag jump-from ?do_flag )
+   compile  (loop)
+   loop-forward loop-back
+; immediate
+
+\ : DOTEST 5 0 do 333 . loop 888 . ;
+\ : ?DOTEST0 0 0 ?do 333 . loop 888 . ;
+\ : ?DOTEST1 5 0 ?do 333 . loop 888 . ;
+
+: +LOOP    ( -- , loop-back do_flag jump-from ?do_flag )
+   compile  (+loop)
+   loop-forward loop-back
+; immediate
+
+: UNLOOP ( loop-sys -r- )
+        r> \ save return pointer
+        rdrop rdrop
+        >r
+;
+
+: RECURSE ( ? -- ? , call the word currently being defined )
+        latest  name> compile,
+; immediate
+
+
+
+: SPACE  bl emit ;
+: SPACES  512 min 0 max 0 ?DO space LOOP ;
+: 0SP depth 0 ?do drop loop ;
+
+: >NEWLINE ( -- , CR if needed )
+        out @ 0>
+        IF cr
+        THEN
+;
+
+
+\ Support for DEFER --------------------
+: CHECK.DEFER  ( xt -- , error if not a deferred word by comparing to type )
+    >code @
+        ['] emit >code @
+        - err_defer ?error
+;
+
+: >is ( xt -- address_of_vector )
+        >code
+        cell +
+;
+
+: (IS)  ( xt_do xt_deferred -- )
+        >is !
+;
+
+: IS  ( xt <name> -- , act like normal IS )
+        '  \ xt
+        dup check.defer
+        state @
+        IF [compile] literal compile (is)
+        ELSE (is)
+        THEN
+; immediate
+
+: (WHAT'S)  ( xt -- xt_do )
+        >is @
+;
+: WHAT'S  ( <name> -- xt , what will deferred word call? )
+        '  \ xt
+        dup check.defer
+        state @
+        IF [compile] literal compile (what's)
+        ELSE (what's)
+        THEN
+; immediate
+
+: /STRING   ( addr len n -- addr' len' )
+   over min  rot over   +  -rot  -
+;
+: PLACE   ( addr len to -- , move string )
+   3dup  1+  swap cmove  c! drop
+;
+
+: PARSE-WORD   ( char -- addr len )
+   >r  source tuck >in @ /string  r@ skip over swap r> scan
+   >r  over -  rot r>  dup 0<> + - >in !
+;
+: PARSE   ( char -- addr len )
+   >r  source >in @  /string  over swap  r> scan
+   >r  over -  dup r> 0<>  -  >in +!
+;
+
+: LWORD  ( char -- addr )
+        parse-word here place here \ 00002 , use PARSE-WORD
+;
+
+: ASCII ( <char> -- char , state smart )
+        bl parse drop c@
+        state @
+        IF [compile] literal
+        THEN
+; immediate
+
+: CHAR ( <char> -- char , interpret mode )
+        bl parse drop c@
+;
+
+: [CHAR] ( <char> -- char , for compile mode )
+        char [compile] literal
+; immediate
+
+: $TYPE  ( $string -- )
+        count type
+;
+
+: 'word   ( -- addr )   here ;
+
+: EVEN    ( addr -- addr' )   dup 1 and +  ;
+
+: (C")   ( -- $addr , some Forths return addr AND count, OBSOLETE?)
+        r> dup count + aligned >r
+;
+: (S")   ( -- c-addr cnt )
+        r> count 2dup + aligned >r
+;
+
+: (.")  ( -- , type following string )
+        r> count 2dup + aligned >r type
+;
+
+: ",  ( adr len -- , place string into dictionary )
+         tuck 'word place 1+ allot align
+;
+: ,"   ( -- )
+   [char] " parse ",
+;
+
+: .(  ( <string> -- , type string delimited by parentheses )
+    [CHAR] ) PARSE TYPE
+; IMMEDIATE
+
+: ."   ( <string> -- , type string )
+        state @
+        IF      compile (.")  ,"
+        ELSE [char] " parse type
+        THEN
+; immediate
+
+
+: .'   ( <string> -- , type string delimited by single quote )
+        state @
+        IF    compile (.")  [char] ' parse ",
+        ELSE [char] ' parse type
+        THEN
+; immediate
+
+: C"    ( <string> -- addr , return string address, ANSI )
+        state @
+        IF compile (c")   ,"
+        ELSE [char] " parse pad place pad
+        THEN
+; immediate
+
+: S"    ( <string> -- , -- addr , return string address, ANSI )
+        state @
+        IF compile (s")   ,"
+        ELSE [char] " parse pad place pad count
+        THEN
+; immediate
+
+: "    ( <string> -- , -- addr , return string address )
+        [compile] C"
+; immediate
+: P"    ( <string> -- , -- addr , return string address )
+        [compile] C"
+; immediate
+
+: ""  ( <string> -- addr )
+        state @
+        IF
+                compile (C")
+                bl parse-word  ",
+        ELSE
+                bl parse-word pad place pad
+        THEN
+; immediate
+
+: SLITERAL ( addr cnt -- , compile string )
+    compile (S")
+    ",
+; IMMEDIATE
+
+: $APPEND ( addr count $1 -- , append text to $1 )
+    over >r
+        dup >r
+    count +  ( -- a2 c2 end1 )
+    swap cmove
+    r> dup c@  ( a1 c1 )
+    r> + ( -- a1 totalcount )
+    swap c!
+;
+
+
+\ ANSI word to replace [COMPILE] and COMPILE ----------------
+: POSTPONE  ( <name> -- )
+    bl word find
+    dup 0=
+    IF
+        ." Postpone could not find " count type cr abort
+    ELSE
+        0>
+        IF compile,  \ immediate
+        ELSE (compile)  \ normal
+        THEN
+    THEN
+; immediate
+
+\ -----------------------------------------------------------------
+\ Auto Initialization
+: AUTO.INIT  ( -- )
+\ Kernel finds AUTO.INIT and executes it after loading dictionary.
+\   ." Begin AUTO.INIT ------" cr
+;
+: AUTO.TERM  ( -- )
+\ Kernel finds AUTO.TERM and executes it on bye.
+\   ." End AUTO.TERM ------" cr
+;
+
+\ -------------- INCLUDE ------------------------------------------
+variable TRACE-INCLUDE
+
+: INCLUDE.MARK.START  ( c-addr u -- , mark start of include for FILE?)
+    " ::::"  pad $MOVE
+    pad $APPEND
+    pad ['] noop (:)
+;
+
+: INCLUDE.MARK.END  ( -- , mark end of include )
+    " ;;;;" ['] noop (:)
+;
+
+: INCLUDED ( c-addr u -- )
+       \ Print messages.
+        trace-include @
+        IF
+                >newline ." Include " 2dup type cr
+        THEN
+        here >r
+        2dup r/o open-file
+        IF  ( -- c-addr u bad-fid )
+                drop ." Could not find file " type cr abort
+        ELSE ( -- c-addr u good-fid )
+               -rot include.mark.start
+                depth >r
+                include-file    \ will also close the file
+                depth 1+ r> -
+                IF
+                        ." Warning: stack depth changed during include!" cr
+                        .s cr
+                        0sp
+                THEN
+                include.mark.end
+        THEN
+        trace-include @
+        IF
+                ."     include added " here r@ - . ." bytes,"
+                codelimit here - . ." left." cr
+        THEN
+        rdrop
+;
+
+: $INCLUDE ( $filename -- ) count included ;
+
+create INCLUDE-SAVE-NAME 128 allot
+: INCLUDE ( <fname> -- )
+        BL lword
+        dup include-save-name $move  \ save for RI
+        $include
+;
+
+: RI ( -- , ReInclude previous file as a convenience )
+        include-save-name $include
+;
+
+: INCLUDE? ( <word> <file> -- , load file if word not defined )
+        bl word find
+        IF drop bl word drop  ( eat word from source )
+        ELSE drop include
+        THEN
+;
+
+\ desired sizes for dictionary loaded after SAVE-FORTH
+variable HEADERS-SIZE
+variable CODE-SIZE
+
+: AUTO.INIT
+    auto.init
+    codelimit codebase - code-size !
+    namelimit namebase - headers-size !
+;
+auto.init
+
+: SAVE-FORTH ( $name -- )
+    0                                    \ Entry point
+    headers-ptr @ namebase - 65536 +     \ NameSize
+    headers-size @ MAX
+    here codebase - 131072 +              \ CodeSize
+    code-size @ MAX
+    (save-forth)
+    IF
+        ." SAVE-FORTH failed!" cr abort
+    THEN
+;
+
+: TURNKEY ( $name entry-token-- )
+    0     \ NameSize = 0, names not saved in turnkey dictionary
+    here codebase - 131072 +             \ CodeSize, remember that base is HEX
+    (save-forth)
+    IF
+        ." TURNKEY failed!" cr abort
+    THEN
+;
+
+\ Now that we can load from files, load remainder of dictionary.
+
+trace-include on
+\ Turn this OFF if you do not want to see the contents of the stack after each entry.
+trace-stack off
+
+include loadp4th.fth
+
+decimal
+
+: ;;;; ;  \ Mark end of this file so FILE? can find things in here.
+FREEZE    \ prevent forgetting below this point
+
+.( Dictionary compiled, save in "pforth.dic".) cr
+c" pforth.dic" save-forth