home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / PROG / MISC / FPC355_4.ZIP / TCOMSRC.ZIP / COMPILER.SEQ < prev    next >
Encoding:
Text File  |  1991-04-25  |  104.9 KB  |  2,552 lines

  1. \ COMPILE.SEQ           Compiler test code              by Tom Zimmer
  2.  
  3. comment:
  4.  
  5.           An optimizing target compiler for the Public Domain Forth
  6.         system F-PC by Tom Zimmer.
  7.  
  8.           Released to the Public Domain this date 10/11/89 by the
  9.         author Tom Zimmer.
  10.  
  11.  
  12. comment;
  13.  
  14. \ ***************************************************************************
  15. \ Automatic local label generator for assembler labels
  16.  
  17. only forth also assembler definitions also
  18.  
  19. $180 !> max-llabs               \ we want upto about 300 local labels
  20.  
  21. create %tllab[] max-llabs b/llab * allot
  22.        %tllab[] max-llabs b/llab * erase        \ clear the array
  23.  
  24. %tllab[] !> llab[]               \ set new array to %tllab[]
  25.  
  26. forth definitions also
  27.  
  28. $40 constant lab1#                      \ first local label number to use
  29. lab1#  value lab#                       \ branch label depth
  30.  
  31. : 0lab#         ( -- )
  32.                 lab1# !> lab#
  33.                 llab[] max-llabs b/llab * erase  ;      \ clear the array
  34.  
  35. : +lab#         ( -- n1 )
  36.                 lab#
  37.                 incr> lab# ;
  38.  
  39. : init_labels   ( -- )     \ initializes temp labels ONLY, leave locals alone
  40.                 llab[]  lab1# 1- b/llab * erase
  41.                 false !> ll-used? ;
  42.  
  43. : labdoassem    ( --- )
  44.                 @> run =: arunsave
  45.                   ['] run-a; is run
  46.                 0 ['] drop a;!
  47.                 aprior 4 + 2@ aprior 2!
  48.                 lihere =: linestrt
  49.                 ll-global? 0=
  50.                 if      init_labels             \ in case labels used
  51.                 then
  52.                 also assembler ;
  53.  
  54. ' labdoassem is setassem
  55.  
  56. only forth also definitions hidden also
  57.  
  58. \ ***************************************************************************
  59. \ Buffered printing words to increase performance when creating a listing
  60. \ ***************************************************************************
  61.  
  62.      4096 constant pr_max               \ actual buffer size
  63. pr_max 1- constant pr_limit             \ highest allowable char count
  64.  
  65. create pr_buf pr_max 2+ allot           \ listing output buffer
  66.  
  67. 0 value pr_cnt                          \ listing buffer output counter
  68. 0 value ?lst                            \ true if we are in listing mode?
  69.  
  70. : buf_prinit    ( -- )                  \ initialize the print buffer
  71.                 pr_buf pr_max blank
  72.                 off> pr_cnt ;
  73.  
  74. : buf_prflush   ( -- )                  \ flush the contents of the print
  75.                                         \ buffer to printer
  76.                 save> #out
  77.                 ?cs: pr_buf pr_cnt prntypel
  78.                 off> pr_cnt
  79.                 restore> #out ;         \ keep #OUT at its previous value
  80.  
  81. : bye_lst_flush ( -- )                  \ flush listing file buffer
  82.                 ?lst
  83.                 if      buf_prflush
  84.                 then    defers byefunc ;
  85.  
  86. ' bye_lst_flush is byefunc              \ link into things to be done on exit
  87.  
  88. : buf_premit    ( c1 -- )               \ put char c1 in print buffer
  89.                 pr_cnt pr_limit >=
  90.                 if      buf_prflush
  91.                 then
  92.                 pr_buf pr_cnt + c!
  93.                 incr> pr_cnt
  94.                 incr> #out ;
  95.  
  96. : buf_prtypel   ( seg a1 n1 -- )        \ type text to print buffer from
  97.                                         \ far segment location
  98.                 pr_cnt over + pr_limit >=
  99.                 if      buf_prflush
  100.                 then
  101.                 >r ?cs: pr_buf pr_cnt + r@ cmovel
  102.                 r@ +!> pr_cnt
  103.                 r> +!> #out
  104. \+ ?.prlines    ?.prlines
  105.                 ;
  106.  
  107. only forth also
  108.  
  109. \ ***************************************************************************
  110. \ Create some aliases to allow their use while in the compiler
  111. \ ***************************************************************************
  112.  
  113.                         ' forth     alias [forth]     immediate
  114.                         ' assembler alias [assembler] immediate
  115. vocabulary target       ' target    alias [target]    immediate
  116. vocabulary htarget      ' htarget   alias [htarget]   immediate \ h = HIDDEN
  117. vocabulary compiler     ' compiler  alias [compiler]  immediate
  118. defer tversion  ' noop is tversion
  119. compiler also definitions
  120.  
  121.         ' here alias fhere              \ make fhere an alias for HERE
  122. \+ sys  ' sys  alias /dos
  123.  
  124. defer "errmsg2
  125. defer .alist     ' noop is .alist       \ default to no more help
  126. defer line-done  ' noop is line-done    \ action at the end of every line
  127.  
  128. \ In case no disassembler is present, discard the a1,n1 parameters
  129.  
  130. defer ?.#dis    ' 2drop is ?.#dis
  131.  
  132. \ ***************************************************************************
  133. \ Target assembly and access words
  134.  
  135. $10000. 2constant codebytes             \ max target program is 64k bytes
  136.  
  137. codebytes pointer seg-code              \ target origin code segment
  138.  
  139.  $100 value code-start                  \ start of compiled code
  140.  $000 value data-start                  \ start of compiled data
  141.    variable dp-t code-start dp-t !      \ target dictionary pointer
  142.    variable dp-d data-start dp-d !      \ target DATA dictionary pointer
  143. $FFFF value ram-seg                     \ physical segment in target of ram
  144.                                         \ $FFFF signifies whole system is
  145.                                         \ ram based, and no move from ROM
  146.                                         \ is needed at initialization time.
  147.   $00 value target-origin               \ origin in memory for target code
  148. $C000 value data-origin                 \ origin in memory for target data
  149. $FFEE value rptop                       \ where we will initialize return stk
  150.  $100 value rpsize                      \ return stack size in bytes
  151.     0 value >in-t                       \ a place to save >IN
  152.     5 value data-seg+                   \ Offset to the instruction that
  153.                                         \ adjusts DS to where data really is.
  154.     0 value cold_start                  \ Offset to CALL instruction to
  155.                                         \ out cold entry point in application
  156.  
  157. : /code-start   ( | <addr> -- )         \ set target CODE starting address
  158.                 bl word number drop =: code-start ;
  159.  
  160. : /code-limit   ( | <addr> -- )         \ set max size of CODE compiled
  161.                 bl word number drop =: data-origin ;
  162.  
  163. : /data-start   ( | <addr> -- )         \ set target data starting address
  164.                 bl word number drop =: data-start ;
  165.  
  166. : /ram-start    ( | <addr> -- )         \ set the segment in target memory
  167.                                         \ where ram really is, data is them
  168.                                         \ moved into that ram from ROM
  169.                 bl word number drop =: ram-seg ;
  170.  
  171. : /ram-end      ( | <n1> -- )           \ set amount of available ram
  172.                 bl word number drop =: rptop ;
  173.  
  174.  
  175. ' DP-T @REL>ABS CONSTANT 'DOVAR         \ pointer to DOVAR
  176.  
  177. \ ***************************************************************************
  178. \ Target CODE space memory operators
  179.  
  180. : ?sizecheck    ( -- )
  181.                 dp-t @       data-origin   u>
  182.                 if      0 " TOO MUCH CODE!"        "errmsg2 abort then
  183.                 dp-d @ $FD00 data-origin - u>
  184.                 if      0 " TOO MUCH STATIC DATA!" "errmsg2 abort then ;
  185.  
  186. defer c!-t      \ defered for flexibility with Mike Mayo's index compiler
  187. defer !-t
  188. defer c@-t
  189. defer @-t
  190. defer c,-t
  191. defer ,-t
  192.  
  193. : cs:           ( taddr -- taddr tseg ) seg-code swap ;
  194. : erase-t       ( a1 n1 --- )           >r cs: r> 0 lfill ;
  195. : there         ( taddr -- addr )       target-origin +   ;
  196. : %c@-t         ( taddr -- char )       there cs: c@l ;
  197. : %@-t          ( taddr -- n )          there cs: @l  ;
  198. : %c!-t         ( char taddr -- )       there cs: c!l ;
  199. : %!-t          ( n taddr -- )          there cs: !l  ;
  200. : here-t        ( -- taddr )            dp-t @   ;
  201. : allot-t       ( n -- )                dp-t +! ;
  202. : %c,-t         ( char -- )             here-t c!-t   1 allot-t   ;
  203. : %,-t          ( n -- )                here-t  !-t   2 allot-t   ;
  204. : s,-t          ( addr len -- )         0max 0 ?do count c,-t loop drop ;
  205. : cset-t        ( n1 addr -- )          dup c@-t rot or swap c!-t ;
  206.  
  207. ' %c!-t is c!-t         \ link defered functions to defered word
  208. ' %!-t  is !-t
  209. ' %c@-t is c@-t
  210. ' %@-t  is @-t
  211. ' %c,-t is c,-t
  212. ' %,-t  is ,-t
  213.  
  214. : %data-seg-fix ( -- )
  215.                 here-t paragraph 16 * dp-t !    \ paragraph align here
  216.                 data-seg+ @-t $E4F6 -           \ verify SYSINIT compiled
  217.                                                 \ and is NOT changed
  218.                 if      0 " TARGET-INIT MUST be first in TARGET" "errmsg2
  219.                         abort
  220.                 then
  221.                 here-t paragraph                \ calc end of CODE used
  222.                 data-seg+ !-t ;                 \ set real DATA seg offset
  223.  
  224. defer data-seg-fix
  225.  
  226. ' %data-seg-fix is data-seg-fix         \ install default function
  227.  
  228. \ ***************************************************************************
  229. \ Target DATA space memory operators
  230.  
  231. : here-d        ( -- taddr )            dp-d @   ;
  232. : allot-d       ( n -- )                dp-d +! ;
  233. : dhere         ( taddr -- addr )       data-origin + ;
  234. : @-d           ( taddr -- n )          dhere cs: @l  ;
  235. : c@-d          ( taddr -- c1 )         dhere cs: c@l ;
  236. : c!-d          ( char taddr -- )       dhere cs: c!l ;
  237. : !-d           ( n taddr -- )          dhere cs: !l  ;
  238. : c,-d          ( char -- )             here-d c!-d   1 allot-d   ;
  239. : ,-d           ( n -- )                here-d  !-d   2 allot-d   ;
  240. : s,-d          ( addr len -- )         0max 0 ?do count c,-d loop drop ;
  241.  
  242. : dp-set        ( -- )          \ adjust target DP to next free data space
  243.                 here-d 0 !-d ;  \ DP is always at address zero (0) in target
  244.  
  245. ' here-t alias here             \ HERE is now a target word.
  246.                                 \ Use fhere for host if you need it.
  247.  
  248. 0 value ?targeting
  249.  
  250. : >TARGET-MEM   ( -- )
  251.                 ?targeting ?exit
  252.                 [ASSEMBLER]
  253.                 [']   c,-t  is  c,
  254.                 [']    ,-t  is   ,
  255.                 [']   c@-t  is tc@
  256.                 [']    @-t  is t@
  257.                 [']   c!-t  is tc!
  258.                 [']    !-t  is t!
  259.                 ['] here-t  is here
  260.                 on> ?targeting ;
  261.  
  262. : >FORTH-MEM    ( -- )
  263.                 ?targeting 0= ?exit
  264.                 [forth] [']    c, [assembler] is   c,
  265.                 [forth] [']     , [assembler] is    ,
  266.                 [forth] [']    c@ [assembler] is  tc@
  267.                 [forth] [']     @ [assembler] is   t@
  268.                 [forth] [']    c! [assembler] is  tc!
  269.                 [forth] [']     ! [assembler] is   t!
  270.                 [forth] ['] fhere [assembler] is here
  271.                 off> ?targeting ;
  272.  
  273. \ ***************************************************************************
  274. \ Target segment list creation and maintenance words for CODE & DATA
  275.  
  276. \  SEGMENTS array
  277. \
  278. \       +0            +2          +4            +6
  279. \       nxt-code-ptr, curseg-ptr, nxt-data-ptr, curseg-ptr
  280. \        \                         \
  281. \         (points to)                (data chain same as code chain)
  282. \                    \
  283. \                      \ +0            +2          +4
  284. \   (segment)->          nxt-code-ptr, start-code, end-code
  285. \                          \
  286. \                            \ +0            +2          +4
  287. \   (segment)->                nxt-code-ptr, start-code, end-code
  288. \                                \
  289. \                                  \
  290. \                                    0 (zero)
  291. \
  292. \ ***************************************************************************
  293.  
  294. create segments 8 allot         \ an array to hold the code and
  295.        segments 8 erase         \ data segment pointer chain
  296.  
  297. 0 value ccseg                           \ current code segment
  298. 0 value cdseg                           \ current data segment
  299.  
  300. : end-cseg      ( -- )
  301.                 segments 2+ @ ?dup              \ if prev seg not NULL
  302.                 if      here-t swap 4 + !       \ save end addr in struct
  303.                 then    ;
  304.  
  305. : org           ( a1 -- )                       \ define a headerless segment
  306.                 end-cseg                        \ close previous segment
  307.                 fhere segments @ ,              \ link previous to this seg
  308.                 dup   segments !                \ this seg into segment list
  309.                       segments 2+ !             \ make this, current segment
  310. ( +2 )          dup ,                           \ start of segment
  311. ( +4 )          dup ,                           \ current address in segment
  312.                 dup dp-t !                      \ adjust code pointer
  313.                     !> linestrt ;               \ no code yet compiled here
  314.  
  315. : cseg!         ( seg -- )              \ set the current code segment
  316.                 end-cseg                        \ finish current segment
  317.                 dup segments 2+ !               \ link me into segments
  318.                 4 + @ dup dp-t !                \ set HERE-T to my segment
  319.                 !> linestrt ;                   \ no more code here yet
  320.  
  321. : cseg          ( a1 | <name> -- )      \ create memory CODE segments words
  322.                 create  org
  323.                 does>   cseg! ;
  324.  
  325. : dseg>         ( -- )                  \ return from the data segment
  326.                 ccseg cseg! ;
  327.  
  328. : >dseg         ( -- )                  \ select the current data segment
  329.                 segments 2+ @ !> ccseg
  330.                 cdseg cseg! ;
  331.  
  332. : %dorg         ( a1 -- )               \ create a data segment in code space
  333.                 end-cseg
  334.                 segments 2+ @ >r                \ save current code segment
  335.                 org                             \ set the data origin
  336.                 segments 2+ @ !> cdseg          \ save current data segment
  337.                            r> !> ccseg          \ reset saved code segment
  338.                 dseg> ;                         \ return to the code segment
  339.  
  340. : %dseg         ( a1 | <name> -- )      \ create data code segment word
  341.                 create  %dorg
  342.                 does>   !> cdseg ;
  343.  
  344. : end-vseg      ( -- )
  345.                 segments 6 + @ ?dup             \ if prev seg not NULL
  346.                 if      here-d swap 4 + !       \ save end addr in struct
  347.                 then    ;
  348.  
  349. : vorg          ( a1 -- )
  350.                 end-vseg                        \ close prevous segment
  351.                 fhere segments 4 + @ ,          \ link previous to this seg
  352.                 dup   segments 4 + !            \ this seg into segment list
  353.                       segments 6 + !            \ make this, current segment
  354. ( +2 )          dup ,                           \ start of segment
  355. ( +4 )          dup ,                           \ current address in segment
  356.                 dp-d ! ;                        \ adjust data pointer
  357.  
  358. : vseg          ( a1 | <name> -- )      \ create memory DATA segments words
  359.                 create  vorg
  360.                 does>   end-vseg
  361.                         dup segments 6 + !      \ link me into segments
  362.                         4 + @ dp-d ! ;          \ set HERE-T to my segment
  363.  
  364. defer end-dseg  ' end-vseg is end-dseg
  365. defer dorg      ' vorg     is dorg
  366. defer dseg      ' vseg     is dseg
  367.  
  368. : /data_in_ram  ( -- )                  \ put data in with variables
  369.                 ['] end-vseg is end-dseg
  370.                 ['] vorg     is dorg
  371.                 ['] vseg     is dseg ;
  372.  
  373. : /data_in_rom  ( -- )                  \ put data in with code in rom
  374.                                         \ but in its own place
  375.                 ['] end-cseg is end-dseg
  376.                 ['] %dorg    is dorg
  377.                 ['] %dseg    is dseg ;
  378.  
  379. : /data_in_code ( -- )                  \ put data in with the code in rom
  380.                                         \ actually lay it inline with code
  381.                 ['] end-cseg is end-dseg
  382.                 ['] org      is dorg
  383.                 ['] cseg     is dseg ;
  384.  
  385. \ ***************************************************************************
  386. \ Target image save function
  387.  
  388. handle targethndl
  389.  
  390. forth definitions
  391.  
  392. : NOTI          ( -- )
  393.                 TRUE ABORT" No Target initialization function installed" ;
  394.  
  395. DEFER TARGET-INITIALIZE         ' NOTI IS TARGET-INITIALIZE
  396. DEFER TARGET-FINISH             ' NOOP IS TARGET-FINISH
  397.  
  398. 0 value #unres
  399. 0 value cerrors
  400. 0 value does-addr
  401. handle image.name
  402. handle symbol.name
  403. handle listing.name
  404. handle lines.name
  405. create image.ext  ," COM" 0 ,   \ default to .COM extension
  406.  
  407. : set.filenames ( -- )          \ set the filenames for various files
  408.              seqhandle image.name   $>handle image.ext  image.name   $>ext
  409.              seqhandle symbol.name  $>handle " SYM" ">$ symbol.name  $>ext
  410.              seqhandle listing.name $>handle " LST" ">$ listing.name $>ext
  411.              seqhandle lines.name   $>handle " LIN" ">$ lines.name   $>ext ;
  412.  
  413. : ?cerrors      ( -- f1 )
  414.                 cerrors dup
  415.         if      cr ." \3 Image not saved \2 COMPILE ERRORS! "
  416.                 cr here-t code-start -
  417.                    here-d data-start - + 5 .r ."  Bytes compiled" cr
  418.         then    ;
  419.  
  420. : %save-image.com ( | -- )
  421.                 [compiler]
  422.                 ?cerrors ?exit
  423.                 #unres
  424.         if      cr ." \3 Image not saved \0, some symbols \2 UNRESOLVED! "
  425.                 cr here-t code-start -
  426.                    here-d data-start - + 5 .r ."  Bytes compiled"
  427.         else    image.name targethndl $>handle
  428.                 targethndl hcreate                      \ make image.com
  429.                 if      0 " Error while creating executable file." "errmsg2
  430.                         abort
  431.                 then
  432.                 cr cr ." Created executable file - " targethndl count type
  433.                 data-seg-fix                    \ adjust HERE-T and fix
  434.                                                 \ DATA segment alignment
  435.                 dp-set                          \ set targets DP
  436.                 code-start here-t over - dup>r
  437.                 targethndl seg-code exhwrite r> -       \ write CODE
  438.                 if      0 " Error while saving CODE to executable file."
  439.                         "errmsg2 abort
  440.                 then
  441.                 cr ." Wrote " here-t code-start - dup>r 5 u.r
  442.                 ."  Bytes of CODE rounded up to Paragraph."
  443.                 data-origin here-d
  444.                 targethndl seg-code exhwrite here-d -
  445.                 if      0 " Error while saving DATA to executable file."
  446.                         "errmsg2 abort
  447.                 then
  448.                 cr ." Wrote " here-d data-start - 5 u.r ."  Bytes of DATA, "
  449.                 here-d r> + 5 u.r ."  Bytes total.
  450.         then    cr ;
  451.  
  452. DEFER SAVE-IMAGE.COM    ' %SAVE-IMAGE.COM IS SAVE-IMAGE.COM
  453.  
  454. compiler definitions
  455.  
  456. \ ***************************************************************************
  457. \ Initialize the target compiler code space and link in the new target words
  458. \ to the assembler.
  459.  
  460. : tseg_init     ( -- )          \ switch assembler to target space
  461. \+ unedit       unedit
  462.                 seg-code 0=             \ allocate the space needed for
  463.                                         \ the target compile process
  464.                 if      0 " Not enough memory for compile buffer"
  465.                         "errmsg2 abort
  466.                 then
  467.                 seg-code 0 codebytes $FFFF. dmin drop 0 lfill
  468.                                                 \ Zero out 64k of code area
  469. \+ dumpseg      seg-code =: dumpseg             \ preset dumpseg
  470.                 [assembler]                     \ assembler defered words
  471.                 global_ref                      \ use global references
  472.                 >TARGET-MEM ;
  473.  
  474. \ ***************************************************************************
  475. \ Mark the current CODE dictionary address as the current cold program
  476. \ entry point.
  477.  
  478. : %set_cold_entry       ( -- )          \ mark HERE-T as the cold entry point
  479.                         here-t cold_start - 2-
  480.                         cold_start !-t ;
  481.  
  482. DEFER SET_COLD_ENTRY    ' %SET_COLD_ENTRY IS SET_COLD_ENTRY
  483.  
  484. \ ***************************************************************************
  485. \ Automatic local variable generator for assembler macros
  486.  
  487. 0 value br#val          \ branch label depth
  488.  
  489. : 0br#          ( -- )
  490.                 off> br#val ;
  491.  
  492. : +br#          ( -- n1 )
  493.                 br#val
  494.                 incr> br#val ;
  495.  
  496. : -br#          ( -- n1 )
  497.                 decr> br#val
  498.                 br#val dup 0<
  499.                 if      0 " Attempt to resolve an branch label" "errmsg2
  500.                         abort
  501.                 then    ;
  502.  
  503. : br#           ( -- )
  504.                 br#val 1- 0max ;
  505.  
  506. \ ***************************************************************************
  507. \ Compiler control words
  508.  
  509. variable ?fnddoes>              \ dis CREATE DOES> have a DOES> portion?
  510.  
  511.    0 value ?unres               \ unresolved flag
  512.    0 value ?lib                 \ library flag
  513.    0 value ?0opt1
  514.    0 value ?opt
  515.    0 value ?code
  516.    0 value ?show
  517.    0 value ?definit
  518. true value ?bye
  519.    0 value opt_limit
  520.    0 value ?quiet
  521.    0 value ?interpretive
  522.  
  523. : /opt          ( -- )          \ enable optimization for this compile
  524.                 on> ?opt
  525.                 on> ?0opt1 ;
  526.  
  527. : /optoff       ( -- )          \ disable optimization for this compile,
  528.                                 \ this is the default mode
  529.                 off> ?opt
  530.                 off> ?0opt1 ;
  531.  
  532. ' /optoff alias /noopt
  533.  
  534. : .?opt         ( -- )
  535.                 cr >rev ." Status of ?OPT is " ?opt . >norm cr ;
  536.  
  537. /optoff
  538.  
  539. : opt_off1      ( -- )          \ turn off the optimizers for a while
  540.                                 \ after compiling a branch destination
  541.                 off> ?opt
  542.                 here-t 1- =: opt_limit ;
  543.  
  544. : ?reopt        ( -- )          \ re-enable the optimizers if they were
  545.                                 \ turned off for a while
  546.                 ?0opt1 =: ?opt ;
  547.  
  548. : /definit      ( -- )         \ include the TYPE & SPACES initialization
  549.                                 \ code in the compiled image file
  550.                 on> ?definit ;
  551.  
  552. : /definitoff     ( -- )          \ don't initialize TYPE and SPACES
  553.                 ?interpretive ?exit
  554.                 off> ?definit ;
  555.  
  556. ' /definitoff alias /noinit
  557.  
  558. /definit
  559.  
  560. : check_/noinit ( -- )          \ verify the /NOINIT option is in effect
  561.                 ?definit
  562.                 if      cr beep
  563.                         cr seqhandle count type
  564.                            ."  should be used with the /NOINIT option."
  565.                         cr cr beep
  566.                 then    ;
  567.  
  568. : check_/definit ( -- )         \ verify the /DEFINIT option is in effect
  569.                 ?definit 0=
  570.                 if      cr beep
  571.                         cr seqhandle count type
  572.                            ."  should be used with the /DEFINIT option."
  573.                         cr cr beep
  574.                 then    ;
  575.  
  576. ' showlines alias /src          \ this MUST be here so /LST can use it!
  577. ' hidelines alias /srcoff
  578. ' hidelines alias /nosrc
  579.  
  580. /srcoff
  581.  
  582. : /show         ( -- )          \ show the symbols on the screen as they
  583.                                 \ are compiled
  584.                 on> ?show ;
  585.  
  586. ' /show alias /sho
  587.  
  588. : /showoff      ( -- )          \ don't show the symbols on the screen
  589.                                 \ as they are compiled. This is the default
  590.                                 \ mode.
  591.                 off> ?show ;
  592.  
  593. ' /showoff alias /noshow
  594.  
  595. /showoff
  596.  
  597. : /quiet        ( -- )
  598.                 on> ?quiet
  599.                 slow
  600. \+ statoff      statoff
  601.                 ;
  602.  
  603. ' /quiet alias /q
  604.  
  605. : defaultattrib ( -- )          \ set the compilers screen attributes to
  606.                                 \ match the current screen attributes.
  607.                 video-seg @ at? 160 * swap 2* + 1+ c@L attrib ! ;
  608.  
  609. code #bye       ( n1 -- )       \ terminate to DOS with errorcode n1
  610.                 pop ax
  611.                 mov ah, # $4C
  612.                 int $21
  613.                 next            end-code
  614.  
  615. : newbye        ( -- )          \ return to dos after performing cleanup
  616.                 ['] qtypel is typel
  617.                 ['] (emit) is emit
  618.                 ['] (print) is pemit
  619.                 printing off
  620.                 RESTORE_VECTORS
  621.                 BYEFUNC
  622.                 ?cerrors drop
  623.                 cerrors #bye ;
  624.  
  625. ' newbye >body @ ' bye >body !  \ link NEWBYE into BYE
  626.  
  627. : /bye          ( -- )          \ leave compiler after the compile
  628.                 newbye ;
  629.  
  630. : /stay         ( -- )
  631.                 off> ?bye ;
  632.  
  633. ' /stay alias /sta
  634.  
  635. \+ newfile : /edit ( <filename> -- )    \ edit file specified, don't compile
  636. \+ newfile         newfile newbye ;
  637.  
  638. \+ newfile      ' /edit alias /e
  639.  
  640. \ ***************************************************************************
  641. \ Interpret the "TCOM=" string from the environment.
  642.  
  643. create env$ 256 allot
  644.  
  645. : env@          ( a1 n1 --- )         \ extract the command spec
  646.                 dup>r   "envfind 0=
  647.                 if      drop env$ off
  648.                 else    r@ + envsize swap
  649.                         env$ dup clr-hcb >nam -rot
  650.                         do      evseg i c@l 0= ?leave
  651.                                 evseg i c@l over c! 1+
  652.                                 1 env$ c+!
  653.                         loop    drop
  654.                 then    r>drop ;
  655.  
  656. : env_interpret ( -- )
  657.                 " TCOM=" env@           \ get the "TCOM=" string from environ
  658.                 env$ c@ 0= ?exit        \ leave if nothing to interpret
  659.                 save> 'tib
  660.                 save> #tib
  661.                 save> >in
  662.                 env$ count #tib ! 'tib ! >in off        \ set to interpret
  663.                 interpret                               \ an interpret it
  664.                 restore> >in
  665.                 restore> #tib                           \ restore everything
  666.                 restore> 'tib ;
  667.  
  668. : tcom_path@    ( -- )
  669.                 " TPATH=" env@
  670.                 env$ count fpath$ place ;
  671.  
  672. \ ***************************************************************************
  673. \ A display word so user has something to watch while compiling
  674.  
  675. 0 value spinval
  676.  
  677. : spinner       ( -- )
  678.                 ?lst ?code or ?show or ?quiet or ?exit
  679.                 incr> spinval
  680.                 spinval 1 and ?exit
  681.                 at?
  682.                 " |/-\" drop spinval 2/ 3 and + 1 type
  683.                 at ;
  684.  
  685. : spinner2      ( -- )
  686.                 ?lst ?code or ?show or ?quiet or ?exit
  687.                 incr> spinval
  688.                 spinval 1 and ?exit
  689.                 attrib @ >r
  690.                 at? over 2+ over at
  691.                 " |/-\" drop spinval 2/ 3 and + 1 type
  692.                 spinval 7 and 0=
  693.                 if      save> base decimal
  694.                         40 sp>col >attrib3 3 spaces
  695.                         here-t code-start - dup 1  u.r ." _Code+"
  696.                         here-d data-start - dup 1  u.r ." _Data="
  697.                                      0 tuck d+  1 ud.r ." _Total   "
  698.                         restore> base
  699.                         r@ attrib !
  700.                         78 sp>col
  701.                 then    at r> attrib ! ;
  702.  
  703. \ ***************************************************************************
  704. \ Zero out one local label, so we can have more than one set of
  705. \ conditionals in a colon definition. Used with -BR# above.
  706. \ See MACRO REPEAT for an example of usage.
  707.  
  708. : 01lab         ( n1 -- )       \ zero out one label for re-use
  709.                 [assembler]
  710.                 a;
  711.                 llab>line b/llab erase ;
  712.  
  713. : BR#SWAP       ( -- )          \ exchange two most recent branch array
  714.                                 \ elements.
  715.                 [assembler]
  716.                 a;
  717.                 br#val 2- dup
  718.                 [forth]
  719.                 0<
  720.                 if      0 " Attempt to resolve an branch label" "errmsg2
  721.                         abort
  722.                 then
  723.                 [assembler]
  724.                 llab>line dup>r pad b/llab 2* cmove
  725.                 pad    b/llab + r@  b/llab    cmove
  726.                 pad r> b/llab +     b/llab    cmove ;
  727.  
  728. \ ***************************************************************************
  729. \ Define the fields of the BODY of a target compiler provided function.
  730. \
  731. \ here is the structure of a function BODY:
  732. \
  733. \   +0     +1         +6            +8          +10         +12
  734. \   ┌──────┬──────────┬─────────────┬───────────┬───────────┬───────────┐
  735. \   │ type │ JMP NEST │ res-address │ res-chain │ Ref-count │ Data-size │
  736. \   └──────┴──────────┴─────────────┴───────────┴───────────┴───────────┘
  737. \
  738. \ FIELD builds words that adjust to the various fields of the body
  739.  
  740.  
  741. : field         ( n1 n2 -- n3 )         \ compile time
  742.                 ( a1 -- a2 )
  743.                 create over c, +        \ compile offset & increment to next
  744.                 ;code   pop bx          \ get pointer to
  745.                         sub ax, ax      \ clear AX
  746.                         mov al, 0 [bx]  \ get byte field offset into AL
  747.                         add ax, # 3     \ offset to body
  748.                         mov di, sp      \ get a copy of stack pointer
  749.                         add 0 [di], ax  \ add AX to address on stack
  750.                         next
  751.                 end-code
  752.  
  753. \ Equivelant high level code for above assembly ;code.
  754. \
  755. \               does> c@ swap >body +   \ adjust a1 to field address a2
  756. \                                       \ from CFA
  757.  
  758. 0                       \ starting at field offset zero (0),
  759.                         \ define field operators
  760.   1 field >dtype        \ definition type byte
  761.   5 field >execute      \ execution address to compile word
  762.   2 field >resaddr      \ resolution address
  763.   2 field >chain        \ chain of unresolved references
  764.   2 field >count        \ count of times used
  765.   2 field >dsize        \ size of data symbol
  766.   2 field >dinitial     \ initial value of VALUEs
  767.   2 field >inited       \ has value been initialized yet
  768. drop                    \ cleanup stack
  769.  
  770. \ ***************************************************************************
  771. \ Make data type constants for target objects
  772.  
  773. : dtype         ( n1 | <name> -- n2 )
  774.                 dup constant 1+ ;
  775.  
  776. \    !!!!  DO NOT CHANGE THE ORDER OF ANY OF THE FOLLOWING WORDS !!!!
  777. \ These constants also specify the execution order in the later "EXEC:"
  778. \ words LIB_COMPILE and TARG_COMPILE.
  779.  
  780. 0       \ these must start with ZERO for the EXEC: in TARG_COMPILE later
  781.         \ in this file to work properly.
  782.  
  783.         ( Macro )       dtype {M}       \    ─┐
  784.         ( Constant )    dtype {C}       \     ├─ these MUST to be together,
  785.         ( 2Constant )   dtype {2C}      \     │  between statments are used
  786.         ( FConstant )   dtype {F}       \    ─┘  later to check for a range
  787.         ( Data )        dtype {D}       \        of types.
  788.         ( Value )       dtype {V}
  789.         ( Subroutine )  dtype {S}
  790.         ( dEfer )       dtype {E}
  791.         ( Table )       dtype {T}
  792. drop
  793.  
  794. \ ***************************************************************************
  795. \ Debug support for target compiler
  796.  
  797. \+ (see)        : tsee          ( | <name> -- )
  798. \+ (see)                        ' >execute (see) ;
  799.  
  800. \+ ldump        : tdump         ( a1 n1 -- )
  801. \+ ldump                        seg-code -rot ldump ;
  802.  
  803. \       ONLY make TDIS if the disassembler is available
  804.  
  805. \+ =seg         : tdis  ( a1 --- ) seg-code =seg dis ;
  806.  
  807. \+ adebug       : tdebug        ( | <name> -- )
  808. \+ adebug                       ' >execute adebug ;
  809.  
  810. \ ***************************************************************************
  811. \ Symbol write routines, builds a simple symbol table for BXDEBUG.
  812.  
  813. 1024 constant symwsize
  814.   handle symhndl                \ file handle for symbol writing
  815.   create symbuf  32 allot       \ symbol name buffer
  816.   create symwbuf symwsize allot \ symbol write buffer
  817. 0 value  symwcnt                \ symbol write buffer character count
  818. 0 value  ?sym
  819. 0 value  ?typed                 \ include data type flag bit in symbol name?
  820. 0 value  ?lin
  821. 0 value  ?noredef               \ allow redefinitions
  822. 0 value  ?dis                   \ load disassembler?
  823. 0 value  ?dbg                   \ load debugger?
  824.  
  825.   defer  symheader      ' noop is symheader
  826.   defer  symfooter      ' noop is symfooter
  827.   defer  symwrite       ' noop is symwrite
  828.  
  829. : /symoff       ( -- )          \ don't create a symbol table
  830.                 off> ?sym ;
  831.  
  832. ' /symoff alias /nosym
  833.  
  834. /symoff                         \ default is no symbol table file
  835.  
  836. : ?symopen      ( -- f1 )       \ is symbol file open, if not make it
  837.                                 \ return f1=true if symbol file is open
  838.                 symhndl >hndle @ 0<
  839.                 if      off> symwcnt                    \ reset buffer len
  840.                         symbol.name symhndl $>handle
  841.                         symhndl hcreate dup
  842.                         if      0 " Could not make symbol file." "errmsg2
  843.                                 off> ?sym
  844.                         else    symheader
  845.                         then 0=
  846.                 else    true
  847.                 then    ;
  848.  
  849. : symwflush     ( -- )          \ write symbol buffer contents to disk
  850.                 symwbuf symwcnt symhndl hwrite drop
  851.                 off> symwcnt ;
  852.  
  853. : symbwrite     ( a1 n1 -- )    \ buffered write to symbol file
  854.                 >r                              \ preserve len on return stk
  855.                 symwcnt r@ + symwsize >=        \ write buffer full?
  856.                 if      symwflush               \ then flush buffer
  857.                 then
  858.                 symwbuf symwcnt + r@ cmove      \ append data
  859.                 r> +!> symwcnt ;                \ adj count
  860.  
  861. : symcr         ( -- )          \ write a CRLF to symbol file
  862.                 $0A0D sp@ 2 symbwrite drop ;     \ write CRLF
  863.  
  864. : symclose      ( -- )          \ close the symbol file if it was open
  865.                 ?sym
  866.                 if      symfooter
  867.                         symwflush                       \ write any remaining stuff
  868.                         symhndl hclose drop             \ and close the file
  869.                         off> ?sym
  870.                 then    ;
  871.  
  872. : symbye        ( -- )          \ function to perform when leaving forth
  873.                 symclose
  874.                 defers byefunc ;
  875.  
  876. ' symbye is byefunc
  877.  
  878. \ ***************************************************************************
  879. \ The following four words can be redefined to allow building a symbol table
  880. \ in a different format than is provided. You will need to know the format
  881. \ of the symbol table you want to generate.
  882.  
  883. : %symheader    ( -- )          \ write header for debugger symbol file
  884.                 ;
  885.  
  886. : %symfooter    ( -- )          \ write footer for debugger symbol file
  887.                 symcr
  888.                 $001A sp@ 2 symbwrite drop ;     \ write Ctrl Z & null
  889.  
  890. : %symwrite     ( a1 -- a1 )    \ a1 = CFA of symbol
  891.                 ?sym 0= ?exit
  892.                 ?symopen
  893.                 if      dup>r
  894.                         symcr
  895.                         save> base hex
  896.                         dup >resaddr @ 0 <# # # # # #>  symbwrite
  897.                         restore> base
  898.                         spcs 1                          symbwrite
  899.                         yseg @ over >name ?cs: symbuf 32 cmovel
  900.                         symbuf c@ 31 and symbuf c!
  901.                         symbuf count + 1- dup c@ 127 and swap c!
  902.                         ?typed
  903.                         if      r@ >dtype c@ dup  {S} =
  904.                                              swap {M} = or
  905.                                 if      $80 symbuf 1+ c+!   then
  906.                         then    r>drop
  907.                         symbuf count                    symbwrite
  908.                 then    ;
  909.  
  910. : /sym          ( -- )          \ create a symbol table file for BXDEBUG
  911.                 " SYM" ">$ symbol.name  $>ext   \ set the file extension
  912.                 ['] %symheader is symheader     \ install the defered
  913.                 ['] %symfooter is symfooter     \ symbol table building
  914.                 ['] %symwrite  is symwrite      \ words.
  915.                 on> ?sym                        \ turn on symbol generation
  916.                 off> ?typed                     \ don't include type flag
  917.                 on> ?lin ;                      \ and line table generation
  918.  
  919. ' /sym    alias /symbols
  920.  
  921. : /redefok      ( -- )  off> ?noredef ;
  922. : /noredef      ( -- )  on> ?noredef ;
  923.  
  924. /noredef        \ default to no redefinition allowed
  925.  
  926. : /forth        ( -- )          \ enable interpretive Forth in target
  927.                 on> ?interpretive
  928.                 /sym
  929.                 on> ?typed
  930.                 /definit ;
  931.  
  932. : /dis          ( -- )          \ enable disassembly in target
  933.                 on> ?dis
  934.                 /forth ;
  935.  
  936. : /nodis        ( -- )  off> ?dis ;
  937.  
  938. : /debug        ( -- )          \ enable debugging in target
  939.                 on> ?dbg
  940.                 /dis ;
  941.  
  942. ' /debug alias /dbg
  943.  
  944. : /nodebug      ( -- )  off> ?dbg ;
  945.  
  946. \ ***************************************************************************
  947. \ perform the compile
  948.  
  949. : ?$fload       ( a1 f1 -- f2 )
  950.                 if      $fload
  951.                 else    drop false
  952.                 then    ;
  953.  
  954. : do_ok         ( -- )
  955.                 fhere off               \ clear out anything at HERE
  956.                 target-initialize       \ initialize the target compiler
  957.                 ok                      \ compile the currently open file
  958.                 ?interpretive
  959.                 if      /redefok        \ allow redefinitions
  960.                         " DIS.SEQ" ">$ ?dis ?$fload
  961.                         if      cr ." Couldn't open " seqhandle count type
  962.                                 ." , no disassembler will be available."
  963.                         then
  964.                         " TDEBUG.SEQ" ">$ ?dbg ?$fload
  965.                         if      cr ." Couldn't open " seqhandle count type
  966.                                 ." , no debugger will be available."
  967.                         then
  968.                         " TFORTH.SEQ" ">$ $fload
  969.                         if      cr ." Couldn't open " seqhandle count type
  970.                                 ." , can't append a Forth environment."
  971.                         then
  972.                 then    target-finish ;
  973.  
  974. \ ***************************************************************************
  975.  
  976. 0 value prevline
  977. handle linhndl
  978.  
  979. : /lin          ( -- )
  980.                 on> ?lin ;
  981.  
  982. : /linoff       ( -- )
  983.                 off> ?lin ;
  984.  
  985. : ?linopen      ( -- )
  986.                 linhndl >hndle @ 0<
  987.                 if      lines.name linhndl $>handle
  988.                         linhndl hcreate
  989.                         if      0 " Could not make lines file." "errmsg2
  990.                                 off> ?lin
  991.                         then
  992.                         -1 =: prevline
  993.                 then    ;
  994.  
  995. : linclose      ( -- )          \ close the lines file if it was open
  996.                 ?lin
  997.                 if      $0A0D sp@ 2 linhndl hwrite 2drop
  998.                         $001A sp@ 2 linhndl hwrite 2drop
  999.                         linhndl hclose drop             \ and close the file
  1000.                         off> ?lin
  1001.                 then    ;
  1002.  
  1003. : linbye        ( -- )          \ function to perform when leaving forth
  1004.                 linclose
  1005.                 defers byefunc ;
  1006.  
  1007. ' linbye is byefunc
  1008.  
  1009. : line->srcfile ( -- )
  1010.                 ?lin 0= ?exit
  1011.                 prevline loadline @ = ?exit     \ leave if already written
  1012.                 ?linopen
  1013.                 save> base hex
  1014.                 here-t          0 <# bl hold # # # # #> linhndl hwrite drop
  1015.                 loadline @ 1 =
  1016.                 if      seqhandle count linhndl hwrite drop
  1017.                 then
  1018.                 loadline @ =: prevline
  1019.                 $0A0D sp@ 2 linhndl hwrite 2drop
  1020.                 restore> base ;
  1021.  
  1022. : srcrun        ( -- )
  1023.                 line->srcfile
  1024.                 defers interpret ;
  1025.  
  1026. ' srcrun is interpret
  1027.  
  1028. : srcloading    ( -- a1 )       \ to be plugged into LOADING of comment
  1029.                                 \ functions.
  1030.                 line->srcfile
  1031.                 loading ;
  1032.  
  1033. ' srcloading ' <comment:>  >body @ xseg @ + 0 !L        \ fix COMMENT:
  1034. ' srcloading ' <.comment:> >body @ xseg @ + 0 !L        \ fix .COMMENT:
  1035. ' srcloading ' <#if>       >body @ xseg @ + 0 !L        \ fix #IF
  1036.  
  1037. \ ***************************************************************************
  1038. \ output error messages
  1039.  
  1040. true
  1041. \+ >pathend"    drop false      \ load following if >PATHEND" not defined
  1042. #IF
  1043. : >pathend"     ( a1 --- a2 n1 )        \ return a2 and count=n1 of filename
  1044.                 count
  1045.                 begin   2dup '\' scan ?dup
  1046.                 while   2swap 2drop 1 -1 d+
  1047.                 repeat  drop ;
  1048. #ENDIF
  1049.  
  1050. : "errmsg       ( cfa a1 n1 -- )        \ display error message
  1051.                 [ hidden ]
  1052.                 cr seqhandle >pathend" type     \ display filename
  1053.                 ." (" loadline @ 1 .r ." ) "    \ and line number where found
  1054.                 rot ?dup                        \ display cfa if non-zero
  1055.                 if      dup >name .id ." at " h.
  1056.                 else    fhere count dup 1 31 between
  1057.                         if      2dup type
  1058.                         then    2drop space
  1059.                 then    type                    \ display message
  1060.                 incr> cerrors  ;                \ bump found error count
  1061.  
  1062.                 ' "errmsg is "errmsg2
  1063. \+ "errmsg3     ' "errmsg is "errmsg3
  1064.  
  1065. \ ***************************************************************************
  1066. \ Make a header in target
  1067.  
  1068. 0 value ?header
  1069.  
  1070. : /header       ( -- )                  \ enable building headers in target
  1071.                 on> ?header ;
  1072.  
  1073. : /nohead       ( -- )                  \ disable building headers in target
  1074.                 off> ?header ;
  1075.  
  1076. /nohead                                 \ default to no headers in target
  1077.  
  1078. defer comp_header       ' drop is comp_header   \ default to nothing
  1079.  
  1080. : make_header   ( a1 -- )
  1081.                 ?header
  1082.                 if      yseg @ over >name ?cs: symbuf 32 cmovel
  1083.                         symbuf c@ 31 and symbuf c!
  1084.                         symbuf count + 1- dup c@ 127 and swap c!
  1085.                         symbuf comp_header
  1086.                 then    drop ;
  1087.  
  1088. \ ***************************************************************************
  1089. \ Create a new symbol of type c1.
  1090.  
  1091. : new_symbol    ( c1 -- )       \ add a new symbol  of type c1 to symbol list
  1092.                 current @ context !             \ initialize things
  1093.                 create
  1094.                 ( c1 ) c,                       \ +0 type BYTE "C"all
  1095.                 !csp                            \ save stack
  1096.                 233 C,                          \ +1      BYTE JMP
  1097.                 >nest fhere 2+ - ,              \ +2      WORD DOCOL relative
  1098.                 xhere paragraph + dup xdpseg !  \ align LIST
  1099.                 xseg @ - ,                      \ +4      WORD LIST relative
  1100.                 xdp off ;                       \ reset OFFSET
  1101.  
  1102. \ ***************************************************************************
  1103. \ Display a symbol
  1104.  
  1105. : %.asymbol     ( a1 -- )       \ a1 = CFA of symbol
  1106.                 save> base hex
  1107.                 ?code
  1108.                 if      cr
  1109.                         dup >resaddr @ 0 <# # # # # #> type
  1110.                         space 7 0 do ." -----" loop space
  1111.                         dup >name .id
  1112.                 else    ?show
  1113.                         if      ?cr
  1114.                                 dup >resaddr @ 0 <# # # # # #> type
  1115.                                 2 spaces dup >name .id
  1116.                                 tab
  1117.                         then
  1118.                 then    drop restore> base ;
  1119.  
  1120. defer .asymbol  ' %.asymbol is .asymbol
  1121.  
  1122. : out_symbol    ( a1 -- )       \ a1 = cfa of symbol
  1123.                 dup .asymbol
  1124.                 symwrite drop
  1125.                 spinner2 ;
  1126.  
  1127. \ ***************************************************************************
  1128. \ Display a macro name when used
  1129.  
  1130. : %?.macro      ( a1 -- )       \ a1 = CFA of symbol
  1131.                 ?code
  1132.                 if      cr ." --M-- "
  1133.                         dup >name .id
  1134.                 then    drop ;
  1135.  
  1136. defer ?.macro   ' %?.macro is ?.macro
  1137.  
  1138. \ ***************************************************************************
  1139. \ Display a call name when used
  1140.  
  1141. : %?.call       ( a1 -- )
  1142.                 ?code
  1143.                 if      save> base hex
  1144.                         cr
  1145.                         here-t 3 - 0 <# # # # # #> type 4 spaces
  1146.                         ." CALL "
  1147.                         dup >name .id
  1148.                         restore> base
  1149.                 then    drop ;
  1150.  
  1151. defer ?.call    ' %?.call is ?.call
  1152.  
  1153. \ ***************************************************************************
  1154. \ Stack for items to be resolved at the end of the current definition compile.
  1155.  
  1156. 128 constant max_res    \ maximum number of symbols to resolve at one time
  1157.  
  1158. create res_stack max_res 2+ 2* allot
  1159.        res_stack max_res 2+ 2* erase  \ clear stack
  1160.  
  1161. 0 value resptr          \ resolution stack pointer
  1162.  
  1163. : >res          ( a1 -- )       \ add symbol a1 to symbols to be resolved
  1164.                 res_stack resptr + !
  1165.                 resptr 2+ max_res 2* >
  1166.                 if      0 " Exceeded allowed depth of Resolution Stack!"
  1167.                         "errmsg abort
  1168.                 then
  1169.                 2 +!> resptr ;
  1170.  
  1171. : res>          ( -- a1 )       \ get an item from the resolution stack
  1172.                 resptr 2 <
  1173.                 if      0 " Resolve Stack Underflow!" "errmsg abort
  1174.                 then
  1175.                 -2 +!> resptr
  1176.                 resptr res_stack + @ ;
  1177.  
  1178. : ?resdepth     ( -- n1 )       \ return depth of resolution stack in items
  1179.                 resptr 2/ ;
  1180.  
  1181. \ ***************************************************************************
  1182. \ Macro defining words. MACRO's compile IN-LINE assembly code when
  1183. \ executed at their ">EXECUTE" address. Compiled ONLY if referenced,
  1184. \ and EVERY time referenced.
  1185.  
  1186. DEFER MACRO-START
  1187.  
  1188. : MACRO         ( | <name> -- )
  1189.                 fhere >r
  1190.                 {M}  new_symbol                 \ +0    BYTE "M"acro
  1191.                 -1 ,                            \ +6    WORD unresolved sym
  1192.                 0 ,                             \ +8    WORD unresolved chain
  1193.                 0 ,                             \ +10   WORD reference count
  1194.                 compile (lit)                   \ compile (lit)
  1195.                 r> x,                           \ followed by addr of symbol
  1196.                 compile ?.macro
  1197.                 macro-start
  1198. \ ****          hide
  1199.                 ] ;                        \ compile remaining portion
  1200.  
  1201. DEFER END-MACRO IMMEDIATE       \ see the library for this definition
  1202.  
  1203. \ ***************************************************************************
  1204. \ Add a symbol that is being used, but is not yet defined.
  1205.  
  1206. : add_symbol    ( a1 -- )               \ add a symbol not yet resolved
  1207.                 >r                      \ Save a1 out of the way of !CSP
  1208.                                         \ in NEW_SYMBOL.
  1209.                 {S}  new_symbol         \ +0    BYTE type "S" a SUBROUTINE
  1210.                 -1 ,                    \ +6    WORD resolved address
  1211.                 r> ,                    \ +8    WORD unresolved chain
  1212.                 0 ,                     \ +10   WORD reference count
  1213.                 0 ,
  1214.                 0 , ;
  1215.  
  1216. \ ***************************************************************************
  1217. \ resolve one symbol a1 to here-t
  1218.  
  1219. 0 value ?inline
  1220.  
  1221. DEFER RESOLVE_1 ( a1 -- )
  1222.  
  1223. : %resolve_1    ( a1 -- )               \ resolve one reverence to HERE-T
  1224.                 here-t over 2+ - swap !-T ;
  1225.  
  1226. ' %resolve_1 is resolve_1               \ link in default resolver
  1227.  
  1228. : res_symbol    ( a1 -- )               \ resolve here-t to a1
  1229.                 ?inline         \ don't resolve if compiled INLINE
  1230.                 if      out_symbol
  1231.                 else    dup >resaddr @ -1 =
  1232.                         if      dup make_header
  1233.                                 here-t over >resaddr !  \ resolve symbol
  1234.                                 dup out_symbol
  1235.                                 >chain  dup @ swap off  \ resolve chain
  1236.                                 begin   ?dup
  1237.                                 while   dup @-t swap resolve_1
  1238.                                                         \ resolve one ref
  1239.                                 repeat
  1240.                         else    drop
  1241.                         then
  1242.                         init_labels
  1243.                 then    ;
  1244.  
  1245. \ ***************************************************************************
  1246. \ Either resolve a symbol already defined, or make a new symbol if its not
  1247. \ yet defined.  Flag if already defined and resolved.
  1248.  
  1249. 0 value tcomlow         \ lowest allowable target definition in TCOM
  1250.  
  1251. : do_symbol     ( | <name> -- )
  1252.                 >in @ >r                        \ save >IN for later
  1253.                 defined dup
  1254.                 if      drop                    \ discard flag
  1255.                         dup tcomlow u>          \ is it a real symbol
  1256.                 then
  1257.                 if      dup  >resaddr @ -1 <>   \ already resolved or
  1258.                                                 \ its a MACRO, CONSTANT or
  1259.                                                 \ 2CONSTANT
  1260.                         over >dtype c@ {M} {F} between or
  1261.                         ?noredef and
  1262.                         if      " Attempt to REDEFINE a symbol! " "errmsg
  1263.                         else    res_symbol
  1264.                         then
  1265.                 else    drop
  1266.                         r@ >in !
  1267.                         fhere >r
  1268.                         0 add_symbol            \ add a new symbol
  1269.                         r@ make_header
  1270.                         here-t r@ >resaddr !    \ resolve address
  1271.                         r> out_symbol
  1272.                 then    r>drop ;
  1273.  
  1274. \ ***************************************************************************
  1275. \ When actually target compiling code, compile a call to a routine
  1276.  
  1277.                         \ see the library for this definition
  1278. DEFER COMP_CALL         ( a1 -- )       \ a1 = CFA of symbol
  1279. DEFER COMP_JMP_IMM      ( a1 -- )       \ a1 = actual code addr
  1280. DEFER SUB_RET           ( -- )          \ subtract one RET instruction
  1281.  
  1282. : compile_call  ( a1 -- )               \ compile call to routine
  1283.                 dup comp_call ?.call ;
  1284.  
  1285. \ ***************************************************************************
  1286. \ resolver for the data type definitions
  1287.  
  1288. : ?dresolve     ( a1 -- a1 )            \ resolve symbol if needed
  1289.                                         \ not CONSTANT or 2CONSTANT
  1290.                 dup >dtype c@ {C} {F} between 0=
  1291.                 over >resaddr @ -1 = and        \ not yet resolved
  1292.                 if      here-d over >resaddr !  \ set start address
  1293.                         dup >dsize @ allot-d    \ allocate needed space
  1294.                         dup out_symbol          \ show symbols name
  1295.                 then    ;                       \ return address in DS:
  1296.  
  1297. \ ***************************************************************************
  1298. \ resolver for the TABLE type definition
  1299.  
  1300. : ?tresolve     ( a1 -- a1 )            \ resolve symbol if needed
  1301.                                         \ NOT CONSTANT OR 2CONSTANT
  1302.                 dup >dtype c@ {C} {F} between 0=
  1303.                 over >resaddr @ -1 = and        \ not yet resolved
  1304.                 if      here-d over >resaddr !  \ set start address
  1305.                         dup >dsize length s,-d  \ move table to target
  1306.                         dup out_symbol          \ show symbols name
  1307.                 then    ;                       \ return address in DS:
  1308.  
  1309. \ ***************************************************************************
  1310. \ perform the in-line compiling/handling of numbers
  1311.  
  1312.                         \ see the library for these definitions
  1313. DEFER COMP_SINGLE       \ compile a single precision number
  1314. DEFER COMP_FETCH        \ see library
  1315. DEFER COMP_STORE        \ see library
  1316. DEFER COMP_PERFORM      \ see library
  1317. DEFER COMP_OFF          \ see library
  1318. DEFER COMP_ON           \ see library
  1319. DEFER COMP_INCR         \ see library
  1320. DEFER COMP_DECR         \ see library
  1321. DEFER COMP_PSTORE       \ see library
  1322. DEFER COMP_SAVE         \ see library
  1323. DEFER COMP_SAVEST       \ see library
  1324. DEFER COMP_REST         \ see library
  1325. DEFER COMP_FPUSH        \ see library
  1326.  
  1327.                                         \ resolve and compile a single number
  1328. : res_comp_single ( a1 -- )             \ a1 = address of symbol
  1329.                 ?dresolve
  1330.                 dup >count incr
  1331.                 >resaddr @ comp_single ;
  1332.  
  1333. : res_comp_double ( a1 -- )             \ compile a double number, is already
  1334.                 dup >count incr         \ resolved, since used only for
  1335.                 dup >dinitial @ comp_single     \ 2CONSTANT's
  1336.                     >resaddr  @ comp_single ;
  1337.  
  1338. : res_comp_fconst ( a1 -- )             \ compile a floating constant
  1339.                 dup >count incr
  1340.                 dup >dinitial @ comp_single
  1341.                     >resaddr  @ comp_single
  1342.                                 comp_fpush ;
  1343.  
  1344. : res_comp_value  ( a1 -- )             \ resolve and compile single, plus
  1345.                                         \ move initial VALUE into target
  1346.                 dup res_comp_single
  1347.                 comp_fetch                      \ follow with a fetch
  1348.                 dup >inited @ 0=                \ value initialized?
  1349.                 if      dup >dinitial @         \ get initial value
  1350.                         over >resaddr @ !-d     \ store in target
  1351.                         dup >inited on          \ mark as initialized
  1352.                 then    drop ;
  1353.  
  1354. : res_comp_defer ( a1 -- )
  1355.                 res_comp_single comp_perform ;
  1356.  
  1357. : res_comp_macro    ( a1 -- )
  1358.                 dup >count   incr
  1359.                     >execute execute ;
  1360.  
  1361. : res_comp_call ( a1 -- )
  1362.                 dup >count incr compile_call ;
  1363.  
  1364. : res_comp_table ( a1 -- )
  1365.                 execute comp_single ;
  1366.  
  1367. \ ***************************************************************************
  1368. \ These words expect a literal to follow compiled inline. They pick up the
  1369. \ literal and pass it as a parameter to the function specified.  This
  1370. \ technique saves two bytes per occurance of the specified operation, for
  1371. \ a savings of about 2k in the target compiler .EXE file size.
  1372.  
  1373. : inlines       ( a1 | <name> -- )      \ make words that pick up inline
  1374.                                         \ literals and pass them to
  1375.                                         \ functions as parameters
  1376.                 create ,
  1377.                 does> 2r@ @L r> 2+ >r swap perform ;
  1378.  
  1379. ' res_comp_single inlines res_comp_lit
  1380. ' res_comp_double inlines res_comp_dbl
  1381. ' res_comp_fconst inlines res_comp_fcn
  1382. ' res_comp_value  inlines res_comp_val
  1383. ' res_comp_call   inlines res_comp_cll
  1384. ' res_comp_defer  inlines res_comp_def
  1385. ' res_comp_table  inlines res_comp_tbl
  1386. ' comp_single     inlines comp_lit
  1387.  
  1388. \ ***************************************************************************
  1389. \ Resolve forward references by executing the unresolved resolution stack
  1390. \ until it is empty. As each CFA on the resolution stack is executed, its
  1391. \ definition is compiled, possibly putting additional words on the
  1392. \ resolution stack.
  1393.  
  1394. : do_resolve    ( -- )                  \ execute the resolve stack
  1395.                 ?inline ?exit
  1396. \+ ?long        ?long_lib save!> ?long  \ use short branches for library
  1397.                 begin   ?resdepth       \ do it till its empty
  1398.                 while   res>
  1399.                         dup >count incr
  1400.                         dup >resaddr @ -1 =
  1401.                         if      >execute execute
  1402.                         else    drop
  1403.                         then
  1404.                 repeat
  1405. \+ ?long        restore> ?long
  1406.                 ;
  1407.  
  1408. \ ***************************************************************************
  1409. \ Library code routines, used for CODE definitions that are accessed by
  1410. \ CALL rather than MACRO. An LCODE routine is only included in the
  1411. \ target if it is referenced.
  1412.  
  1413. DEFER LCODE-START
  1414.  
  1415. : LCODE         ( | <name> -- )         \ Library CODE routine
  1416.                 fhere >r                \ save here for later
  1417.                 0 add_symbol            \ make a symbol not yet used
  1418.                 compile (lit)           \ compile (lit)
  1419.                 r> x,                   \ followed by addr of symbol
  1420.                 compile res_symbol      \ resolve usage of symbol
  1421.                 lcode-start
  1422.                 ] ;                \ compile remaining portion
  1423.  
  1424. DEFER END-LCODE IMMEDIATE       \ see the library for this definition
  1425.  
  1426. : LLABEL        ( | <name> -- )         \ Library LABEL routine
  1427.                 LCODE
  1428.                 does> body>
  1429.                 dup >resaddr @ 0<
  1430.                 if      dup >chain @ swap       \ link chain @ to here
  1431.                         here-t 1+ over >chain ! \ link here+1 into chain
  1432.                         >res                    \ add to resolution stack
  1433.                 else    >resaddr @
  1434.                 then    ;
  1435.  
  1436. \ ***************************************************************************
  1437. \ Library and Target compiler functions. These words either compile actual
  1438. \ code into the target "TARG_COMPILE", or compiler functions into the library
  1439. \ "LIB_COMPILE" that will LATER compile code into the target.
  1440.  
  1441. : LIB_COMPILE   ( a1 -- )
  1442.                 dup >dtype c@   \ body contains TYPE byte
  1443.                 case
  1444. ( Macro )       {M}  of  >execute x,                            endof
  1445. ( Constant )    {C}  of  compile res_comp_lit    x,             endof
  1446. ( 2Constant )  {2C}  of  compile res_comp_dbl    x,             endof
  1447. ( FConstant )   {F}  of  compile res_comp_fcn    x,             endof
  1448. ( Data )        {D}  of  compile res_comp_lit    x,             endof
  1449. ( Value )       {V}  of  compile res_comp_val    x,             endof
  1450. ( Subroutine )  {S}  of  compile res_comp_cll    x,             endof
  1451. ( dEfer )       {E}  of  compile res_comp_def    x,             endof
  1452. ( Table )       {T}  of  compile res_comp_tbl    x,             endof
  1453.                   ( elseof )
  1454.                         drop
  1455.                         " is NOT a target symbol! " "errmsg
  1456.                 endcase ;
  1457.  
  1458. : TARG_COMPILE  ( a1 -- )       \ Compile a target symbol
  1459.                                 \ body contains TYPE byte
  1460.                 dup >dtype c@ dup {M} {T} between
  1461.                 if      EXEC:
  1462. ( Macro )               res_comp_macro
  1463. ( Constant)             res_comp_single
  1464. ( 2Constant )           res_comp_double
  1465. ( FConstant )           res_comp_fconst
  1466. ( Data )                res_comp_single
  1467. ( Value )               res_comp_value
  1468. ( Subroutine)           res_comp_call
  1469. ( dEfer )               res_comp_defer
  1470. ( Table )               res_comp_table
  1471.                 else    drop
  1472.                         " is an invalid symbol! " "errmsg
  1473.                 then    ;
  1474.  
  1475. \ ***************************************************************************
  1476. \ Lookup a word from input stream, with auto TIB refill if needed.
  1477.  
  1478. : TDEFINED      ( | <name> -- a1 f1 )   \ get a word from input stream
  1479.                 begin   @> >in =: >in-t
  1480.                         bl word dup c@ 0=       \ if nothing in line
  1481.                         ?fillbuff               \ optionally refill buffer
  1482.                 while   drop a;
  1483.                         line-done
  1484.                         0 >in !
  1485.                         filltib                 \ refill the buffer
  1486.                         line->srcfile
  1487.                         #tib @ 0=
  1488.                         if      0 " End of file reached while compiling!"
  1489.                                 "errmsg abort
  1490.                         then
  1491.                         spinner                 \ something to watch
  1492.                 repeat  skip'c' ?uppercase find ;
  1493.  
  1494. : target?       ( a1 f1 -- a2 f2 )      \ must be target word
  1495.                 dup
  1496.                 if      over tcomlow u<                 \ found too low?
  1497.                         over 0< and                     \ not immediate
  1498.                         if      2drop here false        \ not target word
  1499.                         then
  1500.                 then    ;
  1501.  
  1502. \ ***************************************************************************
  1503. \ Library COLON definitions. L: words are only included in the target
  1504. \ dictionary if they are referenced They are accessed with a CALL.
  1505. \ No forward references are allowed while creating Library definitions.
  1506. \ When L: words are later referenced, they are auto-resolving.
  1507.  
  1508. DEFER START-T:  ' NOOP IS START-T:
  1509.  
  1510. : (L:)          ( | <name> .. ;F -- )   \ define a function in host
  1511.                 ?exec
  1512.                 on> ?lib                \ librarying
  1513.                 fhere >r                \ save here for later
  1514.                 0 add_symbol            \ make a symbol not yet used
  1515.                 compile (lit)           \ compile (lit)
  1516.                 r> x,                   \ followed by addr of symbol
  1517.                 compile res_symbol      \ resolve usage of symbol
  1518.                 compile start-t:        \ start a colon definition
  1519.                 spinner2                \ something to look at
  1520.                 ;
  1521.  
  1522. : (LM:)         ( | <name> .. ;F -- )   \ define a function in host
  1523.                 ?exec
  1524.                 on> ?lib                \ librarying
  1525.                 0 add_symbol            \ make a symbol not yet used
  1526.                 spinner2                \ something to look at
  1527.                 ;
  1528.  
  1529. : (L])          ( -- )
  1530.                 state on
  1531.                 begin   ?stack  tdefined target? ?dup
  1532.                         if      0>
  1533.                                 if      execute     \ execute immediate words
  1534.                                 else    lib_compile \ compile into library
  1535.                                 then
  1536.                         else    number  double?
  1537.                                 if      swap dup
  1538.                                         compile comp_lit x,
  1539.                                 then    drop
  1540.                                         compile comp_lit x,
  1541.                         then    true    done?
  1542.                 until   off> ?lib ;
  1543.  
  1544. : [;]           ( --- )                 \ turn off compiling, but don't
  1545.                                         \ actually compile anything.
  1546.                 state @ 0=
  1547.                 if      0 " Not Compiling!" "errmsg
  1548.                 then
  1549.                 ?csp
  1550.                 [compile] [  ; immediate
  1551.  
  1552. DEFER END-L:                    \ See the library for this definition
  1553. DEFER END-LM:
  1554.  
  1555. : L:            ( | <name> -- )
  1556.                 (L:) (L])
  1557.                 END-L: ; immediate
  1558.  
  1559. : LM:           ( | <name> -- )
  1560.                 fhere >r
  1561.                 (LM:) (L])
  1562.                 END-LM:
  1563.                 {M} r> >dtype c! ;      \ data type is macro
  1564.  
  1565. : LALLOT        ( n1 -- )
  1566.                 drop
  1567.                 0 " Can't use ALLOT in the library!" "errmsg ;
  1568.  
  1569. : LASCII        ( | <letter> -- )       \ compile inline an ascii letter
  1570.                 bl word 1+ c@
  1571.                 compile comp_lit x, ; immediate
  1572.  
  1573. \ ***************************************************************************
  1574. \ A couple of variables used to determine how to resolve LOOPing branches
  1575. \ in the compiler.
  1576.  
  1577. VARIABLE ?DOING         ?DOING   OFF
  1578. VARIABLE ?LEAVING       ?LEAVING OFF
  1579.  
  1580. \ ***************************************************************************
  1581. \ Forward store and fetch words
  1582.  
  1583. : ?vvd          ( a1 -- <a1> f1 )       \ is it a value, variable or defered
  1584.                 dup >dtype c@            \ TYPE must be
  1585.                 dup  {V}  =              \ a VALUE or
  1586.                 over {D}  = or           \ a VARIABLE
  1587.                 swap {E}  = or 0=        \ a DEFERed word
  1588.         if      " Attempt to use !> type operator on an invalid symbol"
  1589.                 "errmsg true
  1590.         else    false
  1591.         then    ;
  1592.  
  1593. \ define words that pickup the following word and use it like a variable
  1594.  
  1595. defer for_does>
  1596.  
  1597. : %for_does>    ( a1 -- )
  1598.                 ' ?vvd
  1599.                 if      drop
  1600.                 else    ?lib
  1601.                         if      compile res_comp_lit x, @ x,
  1602.                         else            res_comp_single perform
  1603.                         then
  1604.                 then    ;
  1605.  
  1606. ' %for_does> is for_does>
  1607.  
  1608. : for>word      ( a1 | <name> -- )
  1609.                 create , immediate
  1610.                 does> for_does> ;
  1611.  
  1612. \ ***************************************************************************
  1613. \ Directs TCOM to compile the definition following inline in the current
  1614. \ colon definition being built. INLINE only works when preceeding references
  1615. \ to LIBRARY definitions.
  1616. \ ***************************************************************************
  1617.  
  1618. : INLINE        ( | <name> -- )
  1619.                 ' DUP >DTYPE C@ {S} =
  1620.                 IF      ON> ?INLINE             \ make it compile inline
  1621.                         >EXECUTE EXECUTE        \ compile it inline
  1622.                         SUB_RET
  1623.                         OFF> ?INLINE            \ restore NON-inline
  1624.                 ELSE    TARG_COMPILE
  1625.                 THEN    ; IMMEDIATE
  1626.  
  1627. \ Use NO_INLINE at the beginning of LIBRARY words that have multiple
  1628. \ exits. Note that NO_INLINE will only work in CODE words, NOT IN ICODE
  1629. \ words. Make sure that your ICODE words DON'T HAVE MULTIPLE EXITS!
  1630.  
  1631. : %NO_INLINE    ( -- )
  1632.                 ?INLINE
  1633.                 IF      0 " This word cannot be used INLINE!" "errmsg
  1634.                 THEN    ;
  1635.  
  1636. : NO_INLINE     ( -- )
  1637.                 COMPILE %NO_INLINE ; IMMEDIATE
  1638.  
  1639. : NO_TINLINE    ( -- )
  1640.                 0 " ONLY Library words can be INLINE" "errmsg ;
  1641.  
  1642. \ ***************************************************************************
  1643. \ New target CODE to create the proper target header and symbol.
  1644.  
  1645. : %TLABEL       ( | <name> -- )         \ define an unresolved lacal label
  1646.                 save> context
  1647.                 {S}  new_symbol
  1648.                 restore> context
  1649.                 -1 ,                    \ not yet resolved
  1650.                 0 ,                     \ clear dummy unresolved chain
  1651.                 0 ,                     \ clear reference counter
  1652.                 0 ,                     \ data size is 0
  1653.                 +lab# dup ,             \ save the label number
  1654.                                         \ in ">DINITIAL" field
  1655.                 [assembler]
  1656.                 $                       \ an unresolved local label
  1657.                 [compiler]
  1658.                 does> body>
  1659.                       dup >count incr         \ bump usage
  1660.                           >dinitial @
  1661.                 [assembler]
  1662.                 $                       \ an unresolved local label
  1663.                 [compiler]
  1664.                 ;
  1665.  
  1666. : TINTERP       ( -- )
  1667.                 line->srcfile
  1668.                 begin   ?stack
  1669.                         @> >in !> >in-t
  1670.                         defined
  1671.                         if      execute
  1672.                         else    %number
  1673.                                 if      double? 0=
  1674.                                         if      drop
  1675.                                         then
  1676.                                 else    2drop           \ discard double zero
  1677.                                         >in-t !> >in    \ reset >IN
  1678.                                         fhere >r
  1679.                                         %tlabel         \ add label to syms
  1680.                                         r> >count incr
  1681.                                 then
  1682.                         then    false done?
  1683.                 until   a; line-done ;
  1684.  
  1685. DEFER TCODE-START
  1686. 0 VALUE INTERPSAVE
  1687. 0 VALUE ?TCODING
  1688.  
  1689. : TCODE         ( | <name> -- )         \ a target CODE word
  1690.                 on> ?tcoding
  1691.                 tdefined target? 0=             \ if not already defined
  1692.                 if      drop                    \ cleanup stack
  1693.                         >in-t !> >in
  1694.                         do_symbol
  1695.                 else    dup res_symbol
  1696.                         dup >name last !        \ for DOES> below
  1697.                         >dinitial @
  1698.                         [assembler]
  1699.                         $$:f                    \ else resolve local label
  1700.                         [compiler]
  1701.                 then
  1702.                 @> interpret !> interpsave
  1703.                 ['] tinterp is interpret
  1704.                 tcode-start
  1705.                                         \ "DO_SYMBOL" above marks this
  1706.                                         \ header as "LAST" wheather it makes
  1707.                                         \ a new header, or uses one that is
  1708.                                         \ already defined as in a forward
  1709.                                         \ reference resolution.
  1710.                 does> body> >resaddr @ ;
  1711.  
  1712. : TEND-CODE     ( -- )                  \ finish a target code definition
  1713.                 ?tcoding 0= abort" Code words must start with CODE or LABEL"
  1714.                 [assembler]
  1715.                 end-code
  1716.                 [forth]
  1717.                 off> ?tcoding
  1718.                 interpsave ?dup if !> interpret then ;
  1719.  
  1720. : TLABEL        ( | <name> -- )      \ Define a new code label
  1721.                 ?tcoding 0=          \ if not in a code word, then use CODE
  1722.                 if      TCODE exit
  1723.                 then
  1724.                 tdefined target? 0=
  1725.                 if      >in-t =: >in            \ reset >IN
  1726.                         save> context
  1727.                         {S}  new_symbol
  1728.                         restore> context
  1729.                         here-t ,
  1730.                         0 ,                     \ clear dummy unresolved chain
  1731.                         0 ,                     \ clear reference counter
  1732.                         0 ,                     \ data size is 0
  1733.                         +lab# dup ,             \ save the label number
  1734.                                                 \ in ">DINITIAL" field
  1735.                         [assembler]
  1736.                         $:|                     \ define a local label
  1737.                         [compiler]
  1738.                 else    here-t over >resaddr !  \ resolve to HERE
  1739.                                                 \ word was already defined,
  1740.                         dup >name last !        \ so setup for DOES> later?
  1741.                         dup >dinitial @
  1742.                         true save!> ?long       \ backward branch is allowed
  1743.                                                 \ to be long is $E9 type JMP
  1744.                         [assembler]
  1745.                         $:|                     \ else resolve local label
  1746.                         [compiler]
  1747.                         restore> ?long
  1748.                 then    out_symbol              \ display the symbol
  1749.                 does>   body>
  1750.                         dup >count incr         \ bump usage
  1751.                             >dinitial @
  1752.                         [assembler]
  1753.                         $                       \ reference local label
  1754.                         [compiler] ;
  1755.  
  1756. \ ***************************************************************************
  1757. \ Immediately compile either the CODE word or the MACRO being defined
  1758. \ after these words ICODE, or IMACRO. If the CODE word or MACRO being
  1759. \ defined contains no references to external symbols, then we can compile
  1760. \ the function now and simply move the compiled code into the target when
  1761. \ it is referenced rather than waiting until it is referenced and then
  1762. \ compiling it into the target. Use of these words makes the target
  1763. \ compiler somewhat faster and smaller. Again, the ICODE and IMACRO words
  1764. \ MUST CONTAIN ONLY STRAIGHT ASSEMBLY, WITH NO EXTERNAL REFERENCES!!
  1765.  
  1766. \ NOTE#1: The sequence "$FAEB fhere 5 - !" below is a short jump from the
  1767. \       second CFA of the ICODE and IMACRO words to the first CFA of the
  1768. \       ICODE and IMACRO words. In a normal CODE or MACRO word the second
  1769. \       CFA is executed to compile the function into the target. In these
  1770. \       words the first CFA needs to be executed to move the functions
  1771. \       object code into the target. Thus the jump is needed for proper
  1772. \       operation of the function.
  1773.  
  1774. : ICODE         ( | <name> -- a1 )      \ Immediate compiled Library CODE
  1775.                 {S}  new_symbol
  1776. ( see NOTE#1)   $FAEB fhere 5 - !       \ link target body to normal body
  1777.                                         \ make resolver just execute this
  1778.                                         \ DOES word
  1779.                 -1 ,                    \ mark unresolved sym
  1780.                 0 ,                     \ resolution chain
  1781.                 0 ,                     \ referenced count
  1782.                 fhere 0 ,               \ holds length of generated CODE
  1783.                 tcode-start
  1784. \ ****          hide
  1785.                 does>   body>
  1786.                 dup >resaddr @ -1 =             \ if not yet resolved
  1787.                 if      dup res_symbol          \ resolve symbol
  1788.                         here-t                  \ where code will lay down
  1789.                         over >dsize length s,-t \ move CODE to target
  1790.                         over >dsize @ ?.#dis    \ dissasem a1,n1
  1791.                 then        >count incr ;       \ bump usage
  1792.  
  1793. : IMACRO        ( | <name> -- a1 )      \ Immediate compiled Library MACRO
  1794.                 {M}  new_symbol
  1795. ( see NOTE#1)   $FAEB fhere 5 - !       \ link target body to normal body
  1796.                                         \ make resolver just execute this
  1797.                                         \ DOES word
  1798.                 -1 ,                    \ mark unresolved symbol
  1799.                 0 ,                     \ unresolved resolution chain
  1800.                 0 ,                     \ referenced count
  1801.                 fhere 0 ,               \ holds length of generated CODE
  1802.                 tcode-start
  1803.                 does>   body>
  1804.                         dup ?.MACRO             \ display MACRO name
  1805.                         here-t
  1806.                         over >dsize length s,-t \ move CODE to target
  1807.                         over >dsize @ ?.#dis    \ dissasem a1,n1
  1808.                              >count incr ;      \ bump usage
  1809.  
  1810. : END-ICODE     ( a1 -- )                       \ complete Imm compile CODE
  1811.                 [assembler]
  1812.                 end-code
  1813.                 fhere over - 2- swap !  ;       \ store len in table header
  1814.  
  1815. ' end-icode alias END-IMACRO    ( a1 -- )       \ complete Imm compile MACRO
  1816.  
  1817. \ ***************************************************************************
  1818. \ Data type definitions.
  1819.  
  1820. : VARIABLE      ( | <name> -- )         \ Variable Data
  1821.                 {D}  new_symbol
  1822.                 -1 ,                    \ mark as unresolved symbol
  1823.                 0 ,                     \ clear unresolved chain
  1824.                 0 ,                     \ clear reference counter
  1825.                 2 ,                     \ data size of a variable
  1826.                 does>   body>
  1827.                         ?dresolve               \ resolve it if used
  1828.                         dup >count incr         \ bump usage
  1829.                             >resaddr @ ;        \ return address in DS:
  1830.  
  1831. : 2VARIABLE     ( | <name> -- )         \ Variable Data
  1832.                 {D}  new_symbol
  1833.                 -1 ,                    \ mark as unresolved symbol
  1834.                 0 ,                     \ clear unresolved chain
  1835.                 0 ,                     \ clear reference counter
  1836.                 4 ,                     \ data size of a 2variable
  1837.                 does>   body>
  1838.                         ?dresolve               \ resolve it if used
  1839.                         dup >count incr         \ bump usage
  1840.                             >resaddr @ ;        \ return address in DS:
  1841.  
  1842. ' 2variable alias FVARIABLE             \ a floating var is like a double var
  1843.  
  1844. : VALUE         ( n1 | <name> -- )      \ variable constant
  1845.                 {V}  new_symbol
  1846.                 -1 ,                    \ mark as unresolved symbol
  1847.                 0 ,                     \ clear unresolved chain
  1848.                 0 ,                     \ clear reference counter
  1849.                 2 ,                     \ data size of a value
  1850.                 ,                       \ place to hold initial value
  1851.                 0 ,                     \ 0 = haven't initialized it yet
  1852.                 does>   body>
  1853.                         ?dresolve               \ resolve it if used
  1854.                         dup >count incr         \ bump usage
  1855.                         dup >inited @ 0=        \ if not initialized
  1856.                         if      dup  >dinitial @        \ get initial value
  1857.                                 over >resaddr @ !-d     \ set it in target
  1858.                                 dup >inited on          \ mark initialized
  1859.                         then
  1860.                             >resaddr @ @-d ;    \ return contents of
  1861.                                                 \ address in target DS:
  1862.  
  1863. : DEFER         ( n1 | <name> -- )      \ a defered word
  1864.                 {E}  new_symbol
  1865.                 -1 ,                    \ mark as unresolved symbol
  1866.                 0 ,                     \ clear unresolved chain
  1867.                 0 ,                     \ clear reference counter
  1868.                 2 ,                     \ data size of a defered word
  1869.                 does>   drop
  1870.                 0 " Can't use target DEFERed words in interpret mode!"
  1871.                 "errmsg abort ;
  1872.  
  1873. \ As in  "32 ARRAY <name>".
  1874.  
  1875. : ARRAY         ( N1 | <name> -- )      \ An Array of Data
  1876.                 {D}  new_symbol
  1877.                 -1 ,                    \ mark as unresolved symbol
  1878.                 0 ,                     \ clear unresolved chain
  1879.                 0 ,                     \ clear referenced counter
  1880.                   ,                     \ save array size word
  1881.                 does>   body>
  1882.                         ?dresolve               \ resolve it if used
  1883.                         dup >count incr         \ bump usage
  1884.                             >resaddr @ ;        \ return address in DS:
  1885.  
  1886. : CONSTANT      ( n1 | <name> -- )      \ Literal Data
  1887.                 {C}  new_symbol
  1888.                   ,                     \ save constant value HIGH
  1889.                 0 ,                     \ clear dummy unresolved chain
  1890.                 0 ,                     \ clear reference counter
  1891.                 does>   body>
  1892.                         dup >count incr        \ bump usage
  1893.                             >resaddr @ ;        \ return actual value
  1894.  
  1895. : 2CONSTANT     ( d1 | <name> -- )      \ Literal double Data
  1896.                 {2C} new_symbol
  1897.                   ,                     \ save constant value
  1898.                 0 ,                     \ clear dummy unresolved chain
  1899.                 0 ,                     \ clear reference counter
  1900.                 0 ,                     \ clear dummy data length
  1901.                   ,                     \ save const value LOW in >DINITIAL
  1902.                 does>   body>
  1903.                         dup  >count incr        \ bump usage
  1904.                         dup  >dinitial @
  1905.                         swap >resaddr  @ ;      \ return actual double value
  1906.  
  1907. forth
  1908. defer float_pop
  1909.  
  1910. : FCONSTANT     ( d1 | <name> -- )      \ floating point constant
  1911.                 {F} new_symbol
  1912.                 float_pop
  1913.                   ,                     \ save constant value
  1914.                 0 ,                     \ clear dummy unresolved chain
  1915.                 0 ,                     \ clear reference counter
  1916.                 0 ,                     \ clear dummy data length
  1917.                   ,                     \ save const value LOW in >DINITIAL
  1918.                 does>   drop
  1919.                 0 " Can't use floating constants in interpret mode!"
  1920.                 "errmsg abort ;
  1921.  
  1922. ' FCONSTANT ALIAS FCON
  1923.  
  1924. : CREATE        ( | <name> -- )         \ create a pointer to free data space
  1925.                 {D}  new_symbol
  1926.                 here-d ,                \ set resolution address to here-d
  1927.                 0 ,                     \ clear unresolved chain
  1928.                 0 ,                     \ clear reference counter
  1929.                 does>   body>
  1930.                         dup >count incr         \ bump usage
  1931.                             >resaddr @ ;        \ return offset into DS:
  1932.  
  1933. : HANDLE        ( | <name> -- )         \ An array for a handle data struct
  1934.                 {D}  new_symbol
  1935.                 -1 ,                    \ mark as unresolved symbol
  1936.                 0 ,                     \ clear unresolved chain
  1937.                 0 ,                     \ clear referenced counter
  1938.                 b/hcb ,                 \ data size is B/HCB bytes
  1939.                 does>   body>
  1940.                         ?dresolve               \ resolve it if used
  1941.                         dup >count incr         \ bump usage
  1942.                             >resaddr @ ;        \ return address in DS:
  1943.  
  1944. \ Allow definition of a table of data in the target or library, used as
  1945. \ follows:
  1946. \
  1947. \       TABLE NUMBERS
  1948. \               0 C,    1 C,    2 C,    3 C,    4 C,
  1949. \               5 C,    6 C,    7 C,    8 C,    9 C,
  1950. \       END-TABLE
  1951. \
  1952. \ When "NUMBERS" is first referenced in the target, the table will be
  1953. \ moved into the target data space, and the data address of "NUMBERS"
  1954. \ will be compiled into the target. Later references simply compile the
  1955. \ address of the table.
  1956.  
  1957. : TABLE         ( | <name> -- a1 )      \ Define a Table of data
  1958.                 {T}  new_symbol
  1959.                 -1 ,                    \ mark as unresolved symbol
  1960.                 0 ,                     \ clear unresolved chain
  1961.                 0 ,                     \ clear reference counter
  1962.                 fhere 0 ,               \ leaves here on stack for later
  1963.                                         \ resolution by END-TABLE
  1964.                 forth                   \ select the FORTH vocabulary
  1965.                 does>   body>
  1966.                         ?tresolve               \ resolve table when used
  1967.                         dup >count incr         \ bump usage
  1968.                             >resaddr @ ;        \ return address in DS:
  1969.  
  1970. : END-TABLE     ( a1 -- )               \ complete the definition of a table
  1971.                 fhere over - 2- swap !  \ store length in table header
  1972.                 target ;                \ reselect target vocabulary
  1973.  
  1974. \ ***************************************************************************
  1975. \ This word is used to follow target library definitions that need to have
  1976. \ an interpret time function.
  1977. \ See the 11/25/89 note in TCOM.TXT for a usage example.
  1978.  
  1979. : EXECUTES>     ( | <name> -- )         \ make word do name
  1980.                 LAST @ NAME>
  1981.                 DUP @REL>ABS 'DOVAR <>
  1982.                 OVER >DTYPE C@ {E} <> AND       \ not a DEFERED word
  1983.                 if      "  Is an ICODE/IMACRO word, can't use EXECUTE>"
  1984.                         "errmsg
  1985.                         also forth ' drop previous beep exit
  1986.                 then    dup 1+
  1987.                 fhere over - 2- swap !   \ make it jump to new function
  1988.                 233 SWAP C!             \ change CALL to JMP
  1989.                 ?TARGETING >R
  1990.                 SETASSEM
  1991.                 >FORTH-MEM      \ set to assemble for FORTH memory
  1992.                 [ASSEMBLER]
  1993.                 MOV AX, # ALSO FORTH ' PREVIOUS   \ lookup word following
  1994.                 JMP AX
  1995.                 END-CODE
  1996.                 [FORTH]
  1997.                 R>              \ if we were targeting, back to TARGET
  1998.                 IF      >TARGET-MEM
  1999.                 THEN    ;
  2000.  
  2001. \ ***************************************************************************
  2002. \ This word NO-INTERPRET is used to prevent some target words from being used
  2003. \ while in interpret mode.
  2004.  
  2005. : %NO-INTERP2   ( a1 -- )       \ error abort if we try to interpret
  2006.                                 \ the word defined preceeding NO-INTERPRET
  2007.                 body>
  2008.                 " Can't use this TARGET word in INTERPRET mode!" "errmsg
  2009.                 abort ;
  2010.  
  2011. CODE %NO-INTERP ( -- )          \ get here from a CALL
  2012.                 MOV AX, # ' %NO-INTERP2
  2013.                 JMP AX          END-CODE
  2014.  
  2015. : NO-INTERPRET  ( -- )
  2016.                 last @ name> dup @rel>abs 'dovar <>
  2017.                 if      " is an ICODE/IMACRO word, can't use NO-INTERPRET"
  2018.                         "errmsg
  2019.                         also forth ' drop previous beep exit
  2020.                 then    1+
  2021.                 ['] %NO-INTERP OVER - 2- SWAP ! ; \ go to %NO-INTERP
  2022.  
  2023. \ ***************************************************************************
  2024.  
  2025. : TASCII        ( | <letter> -- )       \ compile inline an ascii letter
  2026.                 ( | <letter> -- c1 )    \ interpret time
  2027.                 bl word 1+ c@ state @
  2028.                 if      comp_single
  2029.                 then    ; immediate
  2030.  
  2031. : %%T,"         ( | string" -- )        \ compile string data
  2032.                 '"' word dup c@ 1+ s,-d ;
  2033.  
  2034. FORTH
  2035. DEFER ,"        COMPILER ' %%T," IS ,"
  2036.  
  2037. \ ***************************************************************************
  2038. \ Display the target words that have been referenced, along with their
  2039. \ resolution addresses or values
  2040.  
  2041. : .unsym        ( link -- )
  2042.                 dup link> dup >execute @rel>abs 'docol =
  2043.                 if      dup >count @
  2044.                         if      save> base
  2045.                                 dup >resaddr @ -1 =
  2046.                                 if      \ not MACRO, CONSTANT or 2CONSTANT
  2047.                                         dup >dtype c@ {M} {F} between 0=
  2048.                                         if      ?quiet
  2049.                                                 if      dup
  2050.                                                         " is Unresolved"
  2051.                                                         "errmsg
  2052.                                                 else    dup >name .id tab
  2053.                                                         ." \2  UNRES    "
  2054.                                                 then
  2055. \+ totalwords                                   totalwords incr
  2056.                                                 #unres 1+ =: #unres
  2057.                                         then
  2058.                                 then    restore> base
  2059.                                 ?cr
  2060.                         then
  2061.                 then    2drop   ;
  2062.  
  2063. : l.name        ( link -- )
  2064.                 dup link> dup >execute @rel>abs 'docol =
  2065.                 if      dup >count @
  2066.                         if      save> base
  2067.                                 dup  >resaddr @ -1 =
  2068.                                 if      dup >dtype c@ {M} <>
  2069.                                         if      ." \2 UNRES"
  2070.                                         else    ." \1 MACRO"
  2071.                                         then
  2072.                                 else    dup >resaddr @ hex      5 .r SPACE
  2073.                                 then    restore> base
  2074.                                 dup >dtype c@ {D}  =
  2075.                                 if ." \1v"  else space then
  2076.                                 dup >name .id tab ?cr
  2077. \+ totalwords                   totalwords incr
  2078.                         then
  2079.                 then    2drop   ;
  2080.  
  2081. : %.labels      ( -- )
  2082. \+ totalwords   totalwords off
  2083.                 0 =: #unres
  2084.                 savestate
  2085.                 cols 10 - rmargin !
  2086.                 20 tabsize !
  2087.                 0  lmargin !
  2088.                 ['] target >body
  2089.                 fhere 500 + #threads 2* cmove    \ copy threads
  2090.                 cr
  2091.                 begin   fhere 500 + #threads
  2092.                         largest dup             \ search thread copy
  2093.                         ?lst 0=
  2094.                         if      ?keypause
  2095.                         then
  2096.                 while   dup     ?unres
  2097.                         if      .unsym
  2098.                         else    l.name
  2099.                         then    y@ swap !       \ insert last link to thread
  2100.                 repeat 2drop
  2101.                 decimal
  2102.                 restorestate ;
  2103.  
  2104. : .labels       ( -- )
  2105.                 cr ." Referenced words ----- "
  2106.                 cr
  2107.                 0 =: ?unres
  2108.                 %.labels
  2109. \+ totalwords   cr totalwords @ . ." Words Referenced"
  2110.                 cr ;
  2111.  
  2112. ' .labels alias .symbols
  2113.  
  2114. : .unres        ( -- )
  2115.                 cr ." --------------------"
  2116.                 true =: ?unres
  2117.                 %.labels
  2118. \+ totalwords   cr totalwords @ . ." Unresolved References"
  2119.                 ;
  2120.  
  2121. \ ***************************************************************************
  2122. \ Compile the definition of " for inline strings in target and library
  2123.  
  2124. : %%T"          ( a1 -- )               \ compile string into target
  2125.                 here-d 1+ comp_single   \ address of first char of $
  2126.                 dup c@    comp_single   \ compile length of $
  2127.                 dup c@ 1+ s,-d          \ compile string to data area
  2128.                 ;
  2129.  
  2130. FORTH
  2131. DEFER %T"       ' %%T"  IS %T"
  2132.  
  2133. : T"            ( | string" -- )        \ compile a string into target
  2134.                 ( -- a1 n1 )            \ runtime - return address and length
  2135.                 '"' word                \ get the string to HERE
  2136.                 %T" ; immediate         \ compile it into target
  2137.  
  2138. : L"            ( | string" -- )        \ compile a string later compiled
  2139.                                         \ into the target
  2140.                 [compile] " compile ">$
  2141.                 compile %T" ; immediate
  2142.  
  2143. \ ***************************************************************************
  2144. \ Define and compile the target definition of a colon word. Automatic
  2145. \ forward reference resolution is performed on these definitions.
  2146.  
  2147. FORTH
  2148. DEFER END-T:    ( -- )          \ See the library for this definition
  2149.  
  2150. : (T:)          ( | <name> .. ; -- )            \ new defining word
  2151.                 ?exec
  2152.                 0 =: ?lib
  2153.                 !csp
  2154.                 current @ context !
  2155.                 fhere >r
  2156.                 do_symbol
  2157.                 ['] no_tinline >body @ r> >execute >body !
  2158.                                                 \ no target inline allowed
  2159.                                                 \ relink to error routine
  2160.                 set_cold_entry                  \ mark as program entry point
  2161.                 start-t:
  2162.                 init_labels ;
  2163.  
  2164. : (T])          ( -- )
  2165.                 state on
  2166.         begin   ?stack  tdefined target? ?dup   \ find the word
  2167.                 if      0>
  2168.                         if      execute         \ execute immediate words
  2169.                         else    targ_compile    \ compile the rest
  2170.                         then
  2171.                 else    %number                 \ a number?
  2172.                         if      ( d1 -- )       \ compile literal number
  2173.                                 double?         \ double if '.' found
  2174.                                 if      swap
  2175.                                         comp_single
  2176.                                 else    drop
  2177.                                 then    comp_single
  2178.                         else    2drop           \ discard double zero
  2179.                                 >in-t =: >in    \ reset >IN to before word
  2180.                                 fhere >r
  2181.                                 0 add_symbol    \ or add to symbol table
  2182.                                 compile unnest  \ undefined, so NOOP it
  2183.                                 r@ >count incr
  2184.                                 r> compile_call
  2185.                         then
  2186.                 then    state @ 0=
  2187.         until   ?sizecheck ;            \ check the space used sofar
  2188.  
  2189. : T:            ( | <name> .. ; -- )    \ TARGET : defining word
  2190.                 (T:) (T])
  2191.                 end-t:
  2192.                 do_resolve ;            \ resolve all new referenced symbols
  2193.  
  2194. : TM:           ( | <NAME> .. ; -- )    \ Target MACRO : defining word
  2195.                 LM:
  2196.                 do_resolve ;
  2197.  
  2198. \ make some aliases for the normal Forth definitions of these words
  2199.  
  2200. assembler also
  2201.  
  2202. ' :        alias for:
  2203. ' ;        alias for;           immediate
  2204. ' allot    alias fallot
  2205. ' code     alias fcode
  2206. ' label    alias flabel
  2207. ' end-code alias fend-code
  2208. ' ascii    alias fascii         immediate
  2209. ' "        alias f"             immediate
  2210. ' ."       alias f."            immediate
  2211. ' abort"   alias fabort"        immediate
  2212. ' [']      alias f[']           immediate
  2213.  
  2214. here !> tcomlow         \ lower limit for TCOM target words
  2215.  
  2216. \ new target compiler defered words
  2217.  
  2218. FORTH defer :                   immediate       ' for: compiler is :
  2219. FORTH defer ;                   immediate       ' for; compiler is ;
  2220. FORTH
  2221. defer m:                        immediate
  2222. defer allot
  2223. defer code                      immediate
  2224. defer label                     immediate
  2225. assembler definitions forth
  2226. defer end-code                  immediate
  2227. target definitions forth
  2228. defer ascii                     immediate
  2229. defer "                         immediate
  2230. defer ."                        immediate
  2231. defer abort"                    immediate
  2232. defer [']                       immediate
  2233. defer l."                       immediate
  2234. defer t."                       immediate
  2235. defer labort"                   immediate
  2236. defer tabort"                   immediate
  2237. defer l[']                      immediate
  2238. defer t[']                      immediate
  2239.  
  2240. \ Compiler MODE selection words
  2241.  
  2242. : >library      ( -- )                          \ Select Library
  2243.                 F['] L:          =: :
  2244.                 F['] [;]         =: ;
  2245.                 F['] LM:         =: M:
  2246.                 F['] LCODE       =: CODE
  2247.                 F['] LLABEL      =: LABEL
  2248.                 F['] END-LCODE   =: END-CODE
  2249.                 F['] L"          =: "
  2250.                 F['] L."         =: ."
  2251.                 F['] LABORT"     =: ABORT"
  2252.                 F['] LALLOT      =: ALLOT
  2253.                 F['] LASCII      =: ASCII
  2254.                 F['] L[']        =: ['] ;
  2255.  
  2256. : >target       ( -- )                          \ Select Target compiler
  2257.                 F['] T:          =: :
  2258.                 F['] [;]         =: ;
  2259.                 F['] TM:         =: M:
  2260.                 F['] TCODE       =: CODE
  2261.                 F['] TLABEL      =: LABEL
  2262.                 F['] TEND-CODE   =: END-CODE
  2263.                 F['] T"          =: "
  2264.                 F['] T."         =: ."
  2265.                 F['] TABORT"     =: ABORT"
  2266.                 F['] ALLOT-D     =: ALLOT
  2267.                 F['] TASCII      =: ASCII
  2268.                 F['] T[']        =: ['] ;
  2269.  
  2270. : >forth        ( -- )                          \ select Forth
  2271.                 F['] FOR:        =: :
  2272.                 F['] FOR;        =: ;
  2273.                 F['] FOR:        =: M:
  2274.                 F['] FCODE       =: CODE
  2275.                 F['] FLABEL      =: LABEL
  2276.                 F['] FEND-CODE   =: END-CODE
  2277.                 F['] F"          =: "
  2278.                 F['] F."         =: ."
  2279.                 F['] FABORT"     =: ABORT"
  2280.                 F['] FALLOT      =: ALLOT
  2281.                 F['] FASCII      =: ASCII
  2282.                 F['] F[']        =: ['] ;
  2283.  
  2284. >FORTH          \ Select FORTH for now
  2285.  
  2286. \ ***************************************************************************
  2287. \ Allow new user created defining words to be added and used in the target
  2288. \ compiler.
  2289.  
  2290. : TDOES>        ( | -- )
  2291.                 ?exec
  2292.                 0 =: ?lib
  2293.                 !csp
  2294.                 current @ context !
  2295.                 init_labels
  2296.                 HERE-T =: DOES-ADDR
  2297.                 (T]) END-T: DO_RESOLVE ;        \ resolve all new symbols
  2298.  
  2299. : ::            ( | <name> -- )         \ make a new defining word
  2300.         >FORTH
  2301.         [FORTH]
  2302.         ?FNDDOES> OFF
  2303.         (:)                             \ make a : def
  2304.         STATE ON
  2305.         BEGIN   ?STACK  TDEFINED ?DUP
  2306.                 IF      >R
  2307.                         CASE
  2308.                         [TARGET]
  2309.                         F['] CREATE OF  COMPILE (T:)
  2310.                                         COMPILE HERE-D
  2311.                                         COMPILE COMP_SINGLE
  2312.                                         HERE-T [COMPILE] LITERAL
  2313.                                         COMPILE COMP_JMP_IMM
  2314. \ ****                                  COMPILE REVEAL
  2315.                                                                  ENDOF
  2316.                         F['] DOES>  OF  [COMPILE] ; ?FNDDOES> ON ENDOF
  2317.                         F['] ,      OF  COMPILE ,-D              ENDOF
  2318.                         F['] C,     OF  COMPILE C,-D             ENDOF
  2319.                         F['] ALLOT  OF  COMPILE ALLOT-D          ENDOF
  2320.                         [FORTH]
  2321.                              R@ 0>  IF  EXECUTE   ELSE   X,   THEN
  2322.                         ENDCASE R>DROP
  2323.                 ELSE    NUMBER  DOUBLE?
  2324.                         IF           [COMPILE] DLITERAL
  2325.                         ELSE    DROP [COMPILE] LITERAL
  2326.                         THEN
  2327.                 THEN    TRUE    DONE?
  2328.         UNTIL   ?FNDDOES> @ [FORTH] 0=
  2329.         IF      0 " No DOES> portion specified" "errmsg abort
  2330.         THEN    [TARGET] >TARGET TDOES> ;
  2331.  
  2332. \ ***************************************************************************
  2333. \ Do the target compile.
  2334.  
  2335. compiler definitions
  2336.  
  2337. : targ          ( -- )
  2338.                 [FORTH]
  2339.                 ?quiet 0=
  2340.                 if      cr
  2341.                         ." Compiling.. "
  2342.                         ?opt
  2343.                         if      ." with Optimization.. "
  2344.                         then
  2345.                 then
  2346.                 set.filenames           \ init file handle names
  2347.                 0lab#                   \ init local label array
  2348.                 ?lst
  2349.         if      listing.name $pfile
  2350.                 if      0 " Could not create listing file." "errmsg abort
  2351.                 then
  2352.                 buf_prinit
  2353.                 [ also hidden ]
  2354.                 savescr
  2355. \+ #prbytes     savecursor
  2356. \+ #prbytes     20 8 60 10 box&fill
  2357. \+ #prbytes     ."  \1  Building listing file......   "
  2358. \+ #prbytes     restcursor
  2359. \+ #prbytes     0.0 #prbytes 2!
  2360. \+ #prsave      0.0 #prsave  2!
  2361. \+ oldfix       @> errfix =: oldfix
  2362.                 F['] pemit  save!> emit
  2363.                 F['] buf_prtypel save!> typel
  2364. \+ outfix       F['] outfix is errfix
  2365.                 F['] buf_premit save!> pemit
  2366.                 printing on ( cr )
  2367.                 do_ok
  2368.                 at? 2>r
  2369.                 cr cr
  2370.                 .symbols
  2371.                 cr cr
  2372.                 2r> at
  2373.                 restscr
  2374.                 printing off
  2375.                 buf_prflush
  2376.                 pclose
  2377.                 restore> pemit
  2378.                 restore> typeL
  2379.                 restore> emit
  2380. \+ oldfix       oldfix =: errfix
  2381.         else    do_ok
  2382.                 -1 =: spinval spinner2  \ show spinner one final time
  2383.         then    end-cseg                \ end the code & data segments
  2384.                 end-dseg
  2385.                 .unres                  \ Display any unresolved references
  2386.                 [ previous ]
  2387.                 symclose                \ close symbol file
  2388.                 save-image.com          \ write .COM file to disk
  2389.                 ?bye
  2390.                 if      /bye            \ leave now or
  2391.                 else
  2392.                 cr
  2393. ." Type \`PRINT .SYMBOLS\` to make a printed copy of your programs SYMBOLS."
  2394.                 cr
  2395. ." Type \`/BYE\` to leave."
  2396.                 then
  2397.                 forth decimal ;
  2398.  
  2399. false \+ words drop true        \ true if "WORDS" is defined
  2400. #IF
  2401.  
  2402. : .compiler     ( -- )
  2403.  
  2404. cr ." /definit     = Include the default initialization from file DEFINIT.SEQ."
  2405. cr ." /noinit      = Don't include any default initialization, user does it."
  2406. \+ newfile cr ." /edit <file> = Start as editor on <file>. Not in small version.(no compile)"
  2407. cr ." /lst         = Generate a listing file with source, asm & symbols."
  2408. cr ." /lstoff      = Don't generate a listing file ............ (default)."
  2409. cr ." /opt         = Enable compiler optimization."
  2410. cr ." /optoff      = Disable compile optimization ............. (default)."
  2411. cr ." /show        = Show symbols as they are compiled."
  2412. cr ." /showoff     = Don't show symbols as they are compiled .. (default)."
  2413. cr ." /src         = Enable  the listing of source lines."
  2414. cr ." /srcoff      = Disable the listing of source lines ...... (default)."
  2415. cr ." /stay        = Stay in Forth after the compile finishes."
  2416. cr ." /sym         = Generate a symbol file for BXDEBUG."
  2417. cr ." /symoff      = Don't generate a symbol file ............. (default)."
  2418. cr ." /help        = Re-display help screen. Press the \2 F1 \0 key for MORE HELP."
  2419. cr ." /help2       = Display second help screen."
  2420. ;
  2421.  
  2422. : /help         ( -- )
  2423.                 cr ." Command line format:    "
  2424.                 ." \`TCOM <filename> <option> <option> <...>\`"
  2425.                 cr
  2426.                 .alist
  2427.                 .compiler
  2428.                 cr ." \3 *** Type /BYE to leave the compiler *** " ;
  2429.  
  2430. : /help2        ( -- )          \ second set of command line options
  2431.                 cr ." Command line options Help screen two."
  2432.                 cr
  2433. cr ." /forth            = Append an interactive Forth to program. (need TFORTH.SEQ)"
  2434. cr ." /dis              = Also append the disassembler.           (need DIS.SEQ)"
  2435. cr ." /debug            = Also append the debugger.               (need TDEBUG.SEQ)"
  2436. cr ." /quiet            = Reduce visual output, use with I/O redirection."
  2437. cr ." /code-start <adr> = Start compiling code at <adr>."
  2438. cr ." /data-start <adr> = Start compiling data at <adr>."
  2439. cr ." /code-limit <n1>  = Size limit between CODE and DATA.       (default=$C000)"
  2440. cr ." /ram-start  <adr> = Set the RAM segment in target memory.   (ROMable)"
  2441. cr ." /ram-end    <n1>  = Set the end of target ram.              (default=$FFEE)"
  2442. cr ." /bye              = Return to DOS ....... (NOT a command line option)."
  2443. cr ." /DOS              = Shell out to DOS .....(NOT a command line option)."
  2444. cr ." /help             = Re-display first help screen."
  2445. cr ." /help2            = Display this help screen again."
  2446.                 ;
  2447.  
  2448. #ELSE
  2449.  
  2450. : /help
  2451.         cr ." Command line format:    "
  2452.         ." \`TCOM <filename> <option> <option> <...>\`"
  2453.         cr ." Options avaliable:      "
  2454.         ." \`/opt /sym /lst /code /src /show\`"
  2455.         cr cr
  2456.         ." Type \`/BYE <enter>\` to return to DOS (don't include the \`s)."
  2457.         cr ;
  2458.  
  2459. #THEN
  2460.  
  2461. : .public       ( -- )
  2462.                 cr
  2463.                 ." \3 TCOM \0 the Target COMpiler by Tom Zimmer "
  2464.                 ." \3 Version 1.35 " tversion cr
  2465.                 ." \1 ******** All TCOM Compilers are Public Domain ******* "
  2466.                 eeol at? eeol at ;
  2467.  
  2468. : ?.instruct    ( -- )
  2469.                 [ also forth ]
  2470.                 seqhandle >hndle @ 0<
  2471.                 if      dark
  2472.                         .public
  2473.                         /help
  2474.                         false =: ?bye
  2475.                         forth
  2476.                         interpret
  2477.                         off> cerrors
  2478.                         quit
  2479.                 then    ;
  2480.  
  2481. : ?cmd_err      ( a1 n1 f1 -- )
  2482.                 [forth]
  2483.                 if      0 -rot "errmsg cr
  2484.                         ?bye if /bye then
  2485.                         ."    Type \1 /BYE \0 to leave"
  2486.                         F['] <run> is run errfix
  2487.                         sp0 @ sp!   printing off
  2488.                         forth
  2489.                         quit
  2490.                 then    ;
  2491.  
  2492. : ?compile_err  ( a1 n1 f1 -- )
  2493.                 [forth]
  2494.                 if      0 -rot "errmsg cr
  2495.                         ?bye if /bye then       \ leave if not in "/STAY"
  2496.                         F['] (?serror) is ?error \ reset ?ERROR to normal
  2497.                         abort                   \ and abort
  2498.                 else    2drop
  2499.                 then    ;
  2500.  
  2501. : DOTARG        ( -- )
  2502.                 [forth]
  2503.                 sp0 @  'tib !
  2504.                 >in     off
  2505.                 span    off
  2506.                 #tib    off
  2507.                 loading off
  2508.                 only forth also definitions
  2509.                 defaultstate
  2510.                 defaultattrib           \ set the default attributes to screen
  2511.                 tcom_path@              \ get the environment specified path
  2512.                 default                 \ open a file if one is present
  2513.                 20 tabsize !            \ adjust the tab size
  2514.                 warning off
  2515. \+ autoeditoff  autoeditoff             \ no autoedit on error
  2516.                 only
  2517.                 forth     also
  2518.                 compiler  also
  2519.                 target    also  definitions
  2520.                 assembler also
  2521.                 off> cerrors
  2522.                 F['] ?cmd_err save!> ?error
  2523.                 env_interpret           \ get the default command line args
  2524.                 interpret               \ get the overridding args
  2525.                 restore> ?error
  2526.                 .public
  2527.                 ?.instruct
  2528.                 F['] ?compile_err save!> ?error
  2529.                 targ
  2530.                 restore> ?error ;
  2531.  
  2532. ' DOTARG IS BOOT                \ Make TARG the Initializer
  2533.  
  2534. \ ***************************************************************************
  2535. \ Some immediate words to handle values in the target
  2536.  
  2537. target definitions
  2538.  
  2539. ' noop        for>word &>
  2540. ' comp_store  for>word !>
  2541. ' comp_fetch  for>word @>
  2542. ' comp_off    for>word off>
  2543. ' comp_on     for>word on>
  2544. ' comp_incr   for>word incr>
  2545. ' comp_decr   for>word decr>
  2546. ' comp_pstore for>word +!>
  2547. ' comp_save   for>word save>
  2548. ' comp_savest for>word save!>
  2549. ' comp_rest   for>word restore>
  2550.  
  2551.  
  2552.