home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / forth / compiler / fpc / source / kernel3.seq < prev    next >
Text File  |  1991-02-05  |  26KB  |  807 lines

  1. \ KERNEL3.SEQ   More kernel stuff
  2.  
  3. FILES DEFINITIONS
  4.  
  5. VARIABLE KERNEL3.SEQ
  6.  
  7. FORTH DEFINITIONS
  8.  
  9. : >TYPE         ( adr len -- )
  10.                 TUCK PAD SWAP CMOVE   PAD SWAP TYPE  ;
  11.  
  12. : .(            ( -- )  ASCII ) PARSE >TYPE  ; IMMEDIATE
  13.  
  14. : (             ( -- )  ASCII ) PARSE 2DROP  ; IMMEDIATE
  15.  
  16. CODE TRAVERSE   ( addr direction -- addr' )
  17.                 POP CX          POP BX
  18.                 ADD BX, CX      PUSH ES
  19.                 MOV ES, YSEG
  20.           BEGIN
  21.                 MOV ES: AL, 0 [BX]      AND AL, # 128
  22.        0= WHILE
  23.                 ADD BX, CX
  24.           REPEAT
  25.                 POP ES          PUSH BX
  26.                 NEXT            END-CODE
  27.  
  28. CODE DONE?      ( n -- f )
  29.                 POP AX
  30.                 CMP AX, STATE
  31.             0<> IF
  32.                         MOV END? # 0 WORD
  33.                         MOV AX, # -1
  34.                         1PUSH
  35.                 THEN
  36.                 PUSH END?
  37.                 MOV END? # 0 WORD
  38.                 NEXT
  39.                 END-CODE
  40.  
  41. \ : DONE?         ( n -- f )
  42. \                 STATE @ <>   END? @ OR   END? OFF   ;
  43.  
  44. : CNHASH        ( cfa -- ya )
  45.                 $0FE00 AND FLIP ;
  46.  
  47. CODE CNSRCH     ( cfa ya maxya -- nfa failf )
  48.                 pop dx          \ maxya
  49.                 pop bx          \ ya
  50.                 add bx, # 4
  51.                 pop di          \ cfa
  52.                 mov ds, yseg
  53.         HERE    cmp dx, bx
  54.              U> IF      mov ax, 0 [bx]
  55.                         and ax, # 31
  56.                         add bx, ax
  57.                         inc bx
  58.                         mov ax, 0 [bx]
  59.                         cmp ax, di      \ if they match, then we found it
  60.                      0= if      sub bx, # 2             \ 1 before last chr
  61.                                 begin   mov al, 0 [bx]  \ test high bit
  62.                                         and al, # 128   \ loop till high set
  63.                              0= while   dec bx          \ backup one char
  64.                                 repeat
  65.                                 push bx                 \ push pointer to chr
  66.                                 mov ax, cs              \ restore DS
  67.                                 mov ds, ax
  68.                                 mov ax, # false         \ push false flag
  69.                                 1push
  70.                         then
  71.                         add bx, # 6     \ step to next header
  72.                         JMP ROT         \ bring HERE around Branch resolution
  73.                                         \ used by IF and THEN
  74.                 THEN
  75.                 mov ax, cs      mov ds, ax
  76.                 mov ax, # true
  77.                 push ax
  78.                 1push           end-code
  79.  
  80. : N>LINK        ( anf -- alf)
  81.                 2-   ;
  82.  
  83. : L>NAME        ( alf -- anf )
  84.                 2+   ;
  85.  
  86. : BODY>         ( apf -- acf )
  87.                 3 -  ;
  88.  
  89. : NAME>         ( anf -- acf )
  90.                 1 TRAVERSE   1+ Y@  ;
  91.  
  92. : LINK>         ( alf -- acf )
  93.                 L>NAME   NAME>   ;
  94.  
  95. : >BODY         ( acf -- apf )
  96.                 3 +  ;
  97.  
  98. HERE-Y 4 +     \ Step from view field to name field
  99.  
  100. : NO-NAME       ( -- )  
  101.                 ;
  102.  
  103. : >NAME         ( cfa -- nfa )
  104.                 DUP CNHASH DUP Y@ SWAP
  105.                 2+ Y@ ( cfa sya mxya ) CNSRCH
  106.                 IF      DROP (LIT) [ ROT ,-X ] THEN    ;
  107.  
  108. : >LINK         ( acf -- alf )
  109.                 >NAME   N>LINK   ;
  110.  
  111. : >VIEW         ( acf -- avf )
  112.                 >LINK   2-   ;
  113.  
  114. : VIEW>         ( avf -- acf )
  115.                 2+   LINK>   ;
  116.  
  117. COMMENT:
  118.  
  119.   The hash algorithm used is as follows:
  120.  
  121.         ((firstchar*2)+secondchar)*2)+count
  122.  
  123.   This seems to provide a good distribution across the 64 threads in
  124. 1000 word FORTH vocabulary.
  125.  
  126. COMMENT;
  127.  
  128. CODE HASH       ( str-addr voc-ptr -- thread )
  129.                 POP CX          POP BX
  130.                 MOV AX, 1 [BX]          \ Get first and second chars
  131.                 SHL AL, # 1             \ Shift first char left one
  132.                 ADD AL, AH              \ Plus second char
  133.                 SHL AX, # 1             \ The sum shifted left one again
  134.                 ADD AL, 0 [BX]          \ Plus count byte
  135.                 AND AX, # #THREADS 1-
  136.                 SHL AX, # 1     ADD AX, CX
  137.                 1PUSH           END-CODE
  138.  
  139. CODE (FIND)     ( here alf -- cfa flag | here false )
  140.                 POP BX
  141.                 OR BX, BX
  142.              0= IF
  143.                         SUB AX, AX
  144.                         1PUSH
  145.                 THEN
  146.                 POP CX
  147.                 PUSH ES
  148.                 MOV ES, YSEG
  149.                 MOV DI, CX
  150.             BEGIN
  151.                 MOV ES: AX, 2 [BX]
  152.                 XOR AX, 0 [DI]
  153.                 AND AX, # ( 63 ) $7F3F
  154.              0= IF
  155.                         MOV DX, BX
  156.                         ADD BX, # 2
  157.                         BEGIN
  158.                                 INC BX  INC DI
  159.                                 MOV ES: AL, 0 [BX]
  160.                                 XOR AL, 0 [DI]
  161.                     0<> UNTIL
  162.                         AND AL, # 127
  163.                      0= IF
  164.                                 MOV ES: CX, 1 [BX]      \ pick up CFA
  165.                                 MOV BX, DX
  166.                                 MOV ES: AL, 2 [BX]
  167.                                 AND AL, # 64
  168.                                 0<> IF
  169.                                     MOV AX, # 1
  170.                                 ELSE
  171.                                     MOV AX, # -1
  172.                                 THEN
  173.                                 POP ES
  174.                                 PUSH CX
  175.                                 1PUSH
  176.                         THEN
  177.                         MOV BX, DX
  178.                         MOV DI, CX
  179.                 THEN
  180.                 MOV ES: BX, 0 [BX]
  181.                 OR BX, BX
  182.         0= UNTIL
  183.                 POP ES
  184.                 PUSH CX
  185.                 SUB AX, AX
  186.                 1PUSH           END-CODE
  187.  
  188. HEADERLESS      \ Disable generation of headers
  189.  
  190. CODE DROP.CONTEXT.I2*+@DUP   ( a1 -- n1 )
  191.                 ADD SP, # 2
  192.                 MOV AX, 0 [RP]
  193.                 ADD AX, 2 [RP]
  194.                 SHL AX, # 1
  195.                 MOV BX, # CONTEXT
  196.                 ADD BX, AX
  197.                 MOV AX, 0 [BX]
  198.                 PUSH AX
  199.                 1PUSH
  200.                 END-CODE
  201.  
  202.                                 \ DUP PRIOR @ OVER PRIOR ! =
  203. CODE PRIOR.CHECK ( n1 -- n1 f1 )
  204.                 MOV   BX, SP
  205.                 MOV   AX, 0 [BX]
  206.                 MOV BX, PRIOR
  207.                 MOV PRIOR AX
  208.                 CMP BX, AX
  209.             0<> IF
  210.                         SUB AX, AX
  211.                         1PUSH
  212.                 THEN
  213.                 MOV AX, # TRUE
  214.                 1PUSH
  215.                 END-CODE
  216.  
  217. CODE OVER.SWAP.HASH.@     ( n1 n2 -- n1 n3 )
  218.                 POP AX
  219.                 MOV BX, SP
  220.                 MOV BX, 0 [BX]
  221.                 MOV CL, 0 [BX]
  222.                 MOV BX, 1 [BX]
  223.                 SHL BL, # 1
  224.                 ADD BL, BH
  225.                 SHL BL, # 1
  226.                 ADD BL, CL
  227.                 AND BX, # #THREADS 1-
  228.                 SHL BX, # 1
  229.                 ADD BX, AX
  230.                 PUSH 0 [BX]
  231.                 NEXT            END-CODE
  232.  
  233. HEADERS         \ Restore generation of TARGET HEADERS
  234.  
  235. : %%FIND        ( addr false #vocs 0 -- cfa flag | addr false )
  236.                 DO      DROP.CONTEXT.I2*+@DUP
  237.                         IF      PRIOR.CHECK
  238.                                 IF      DROP FALSE
  239.                                 ELSE    OVER.SWAP.HASH.@ (FIND)
  240.                                         DUP ?LEAVE
  241.                                 THEN
  242.                         THEN
  243.                 LOOP    ;
  244.  
  245. CODE %FIND      ( addr -- cfa flag | addr false )
  246.                 MOV DI, SP
  247.                 MOV BX, 0 [DI]
  248.                 CMP 0 [BX], # 0 BYTE
  249.             0<> IF
  250.                         MOV PRIOR # 0 WORD                      \ prior off
  251.                         MOV BX, # 0             PUSH BX         \ false
  252.                         MOV CX, # #VOCS         PUSH CX         \ #vocs
  253.                                                 PUSH BX         \ 0
  254.                         MOV AX, # ' %%FIND
  255.                         JMP AX
  256.                 THEN
  257.                 MOV END? # TRUE WORD
  258.                 MOV 0 [DI], # ' NOOP WORD
  259.                 MOV AX, # 1
  260.                 1PUSH           END-CODE
  261.  
  262. DEFER FIND      ' %FIND IS FIND
  263.  
  264. CODE SKIP'C'    ( a1 - a1 )             \ conditionally skip following word
  265.                                         \ if word at a1 is 'letter'.
  266.                 POP BX
  267.                 PUSH BX
  268.                 CMP 0 [BX], # ASCII ' FLIP 3 + WORD  \ check cnt & first char
  269.             0<> IF      NEXT
  270.                 THEN    CMP 3 [BX], # ASCII ' BYTE   \ check last char is '
  271.             0<> IF      NEXT
  272.                 THEN    ADD SI, # $02 WORD           \ skip following word
  273.                 NEXT            END-CODE
  274.  
  275. : DEFINED       ( -- here 0 | cfa [ -1 | 1 ] )
  276.                 BL WORD  SKIP'C' ?UPPERCASE  FIND   ;
  277.  
  278. HEADERLESS
  279.  
  280. : STACKUNDER    ( -- )
  281.                 TRUE ABORT" Stack Underflow" ;
  282.  
  283. : STACKOVER     ( -- )
  284.                 TRUE ABORT" Stack Overflow" ;
  285.  
  286. : WARNOVER      ( -- )
  287.                 CR ."  Running out of CODE memory! " ;
  288.  
  289. HEADERS
  290.  
  291. CODE (?STACK)   ( -- )
  292.                 MOV CX, SP
  293.                 MOV BX, UP
  294.                 MOV DX, SP0 [BX]
  295.                 CMP DX, CX
  296.              U< IF
  297.                         MOV AX, # ' STACKUNDER
  298.                         JMP AX
  299.                 THEN
  300.                 MOV DX, DP [BX]
  301.                 ADD DX, # 80
  302.                 CMP CX, DX
  303.              U< IF
  304.                         MOV AX, # ' STACKOVER
  305.                         JMP AX
  306.                 THEN
  307.                 ADD DX, # 200
  308.                 CMP CX, DX
  309.              U< IF
  310.                         MOV AX, # ' WARNOVER
  311.                         JMP AX
  312.                 THEN
  313.                 NEXT            END-CODE
  314.  
  315. DEFER ?STACK    ' (?STACK) IS ?STACK
  316.  
  317. : INTERP        ( -- )
  318.                 BEGIN   ?STACK DEFINED
  319.                         IF     EXECUTE
  320.                         ELSE   NUMBER  DOUBLE? NOT IF  DROP  THEN
  321.                         THEN   FALSE DONE?
  322.                 UNTIL   ;
  323.  
  324. DEFER STATUS    ( -- )
  325.  
  326. DEFER INTERPRET ' INTERP IS INTERPRET
  327.  
  328. : PRINT         ( -- ) PRINTING ON INTERPRET PRINTING OFF ;
  329.  
  330. : ALLOT         ( n -- )      DP +!   ;
  331.  
  332. CODE ,          ( n -- )
  333.                 MOV BX, UP
  334.                 MOV AX, DP [BX]
  335.                 ADD DP [BX], # 2 WORD
  336.                 MOV BX, AX
  337.                 POP CX
  338.                 MOV 0 [BX], CX
  339.                 NEXT
  340.                 END-CODE
  341.  
  342. CODE C,         ( n -- )
  343.                 MOV BX, UP
  344.                 MOV AX, DP [BX]
  345.                 INC DP [BX] WORD
  346.                 MOV BX, AX
  347.                 POP CX
  348.                 MOV 0 [BX], CL
  349.                 NEXT
  350.                 END-CODE
  351.  
  352. : ALIGN         ( -- )
  353.                 ( HERE 1 AND IF  BL C,  THEN )  ; IMMEDIATE
  354.  
  355. : EVEN          ( n1 -- n2 )
  356.                 ( DUP 1 AND + ) ;  IMMEDIATE
  357.  
  358. : COMPILE       ( -- )   
  359.                 2R@ R> 2+ >R @L X,   ;
  360.  
  361. : IMMEDIATE     ( -- )   
  362.                 64 ( Precedence bit ) LAST @ YCSET  ;
  363.  
  364. : LITERAL       ( n -- )  
  365.                 COMPILE (LIT) X, ; IMMEDIATE
  366.  
  367. : DLITERAL      ( d# -- ) 
  368.                 SWAP [COMPILE] LITERAL [COMPILE] LITERAL ; IMMEDIATE
  369.  
  370. : ASCII         ( -- n )   
  371.                 BL WORD   1+ C@
  372.                 STATE @ IF   [COMPILE] LITERAL   THEN   ; IMMEDIATE
  373.  
  374. : CONTROL       ( -- n )   
  375.                 BL WORD   1+ C@  31 AND
  376.                 STATE @ IF   [COMPILE] LITERAL   THEN   ; IMMEDIATE
  377.  
  378. : CRASH         ( -- ) 
  379.                 2R@ 2- @L >NAME CR .ID TRUE
  380.                 ABORT" <- is an Uninitialized execution vector."  ;
  381.  
  382. : ?MISSING      ( f -- )
  383.                 IF      SPACE HERE COUNT TYPE
  384.                         TRUE ABORT"  <- What? "
  385.                 THEN    ;
  386.  
  387. : '             ( -- cfa )      
  388.                 DEFINED 0= ?MISSING   ;
  389.  
  390. : [']           ( -- )          
  391.                 ' COMPILE <'> X, ; IMMEDIATE
  392.  
  393. : [COMPILE]     ( -- )          
  394.                 ' X,   ; IMMEDIATE
  395.  
  396. VARIABLE  "BUF 132 ALLOT
  397.  
  398. : XEVEN         ( xdp -- xdp_even ) 
  399.                 DUP 1 AND + ;
  400.  
  401. : XALIGN        ( -- ) 
  402.                 XHERE NIP 1 AND XDP +! ;
  403.  
  404. : X>"BUF        ( -- "buf )
  405.                 2R>
  406.                 2R@ 2DUP C@L 1+ DUP XEVEN R> + >R
  407.                         ?CS: "BUF ROT CMOVEL
  408.                 2>R "BUF ;
  409.  
  410. : (")           ( -- addr len )
  411.                 2R@ @L COUNT R> 2+ >R ;
  412.  
  413. : (X")           ( -- addr len )
  414.                 X>"BUF COUNT ;
  415.  
  416. : %(.")         ( -- )
  417.                 2R@ 2DUP C@L >R 1+ R@ TYPEL R> 1+ XEVEN R> + >R ;
  418.  
  419. DEFER (.")      ' %(.") IS (.")
  420.  
  421. : ,"            ( -- )
  422.                 ASCII " PARSE TUCK HERE PLACE 1+ ALLOT ;
  423.  
  424. : X,"           ( -- )
  425.                 ASCII " PARSE HERE PLACE
  426.                 ?CS: HERE DUP C@ 1+ >R XHERE R@ CMOVEL
  427.                 R> XEVEN XDP +! ;
  428.  
  429. : ."            ( -- )          COMPILE (.") X,"   ;   IMMEDIATE
  430.  
  431. : "             ( -- )          COMPILE (")  HERE X, ,"   ;   IMMEDIATE
  432.  
  433. : ""            ( -- )          COMPILE (X")  X,"   ;   IMMEDIATE
  434.  
  435. : ">$           ( a1 -- a2 )    
  436.                 DROP 1- ;
  437.  
  438. VARIABLE FENCE
  439.  
  440. : TRIM          ( faddr voc-addr -- )
  441.                 #THREADS 0
  442.                 DO      2DUP @ BEGIN   2DUP U> NOT WHILE Y@ REPEAT
  443.                         NIP OVER ! 2+
  444.                 LOOP    2DROP   ;
  445.  
  446. : (FRGET)       ( code-addr view-addr -- )
  447.                 DUP FENCE @ U< ABORT" Below fence"  ( ca va )
  448.                 OVER VOC-LINK @ BEGIN   2DUP U< WHILE   @ REPEAT
  449.                 DUP VOC-LINK !  ( ca va ca pt ) NIP
  450.                 BEGIN   DUP WHILE   2DUP #THREADS 2* - TRIM   @   REPEAT
  451.                 DROP    YDP !
  452.                 DUP 1+ @ OVER >BODY +
  453.                 (LIT)   TRIM DUP 1+ @ SWAP >BODY + =    \ If it's a : def
  454.                 IF      DUP >BODY @ +XSEG XDPSEG !   \ Set back XHERE too!
  455.                         XDP OFF
  456.                 THEN    DP !  ;
  457.  
  458. DEFER ?ERROR
  459.  
  460.                                         \ 07/03/89 TJZ
  461. : (ABORT")      ( f -- )                \ if f1 true, then display inline
  462.                 ?DUP                    \ compiled message from LIST space
  463.                 IF
  464.                         X>"BUF COUNT ROT ?ERROR
  465.                 ELSE    2R@ C@L 1+ XEVEN R> + >R
  466.                 THEN    ;
  467.  
  468. : ABORT"        ( -- )   
  469.                 COMPILE (ABORT") X," ;   IMMEDIATE
  470.  
  471. : ABORT         ( -- )   
  472.                 TRUE ABORT" "  ;
  473.  
  474. : FORGET        ( -- )
  475.                 BL WORD ?UPPERCASE DUP CURRENT @ HASH @
  476.                 (FIND) 0= ?MISSING DUP >VIEW (FRGET) ;
  477.  
  478. : ?CONDITION    ( f -- )        
  479.                 NOT ABORT" Conditionals Wrong"   ;
  480.  
  481. : >MARK         ( -- addr )     
  482.                 XHERE NIP 0 X,   ;
  483.  
  484. : >RESOLVE      ( addr -- )     
  485.                 XHERE -ROT SWAP !L   ;
  486.  
  487. : <MARK         ( -- addr )     
  488.                 XHERE NIP ;
  489.  
  490. : <RESOLVE      ( addr -- )     
  491.                 X, ;
  492.  
  493. : ?>MARK        ( -- f addr )   
  494.                 TRUE >MARK   ;
  495.  
  496. : ?>RESOLVE     ( f addr -- )   
  497.                 SWAP ?CONDITION >RESOLVE  ;
  498.  
  499. : ?<MARK        ( -- f addr )   
  500.                 TRUE   <MARK   ;
  501.  
  502. : ?<RESOLVE     ( f addr -- )   
  503.                 SWAP ?CONDITION <RESOLVE  ;
  504.  
  505. comment:
  506.         LEAVE and ?LEAVE could be non-immediate in this system, but the 83
  507.         standard specifies an immediate LEAVE, so they  both are for
  508.         uniformity.
  509. comment;
  510.  
  511. : LEAVE         ( -- )
  512.                 COMPILE (LEAVE)  ; IMMEDIATE
  513.  
  514. : ?LEAVE        ( f1 -- )
  515.                 COMPILE (?LEAVE) ; IMMEDIATE
  516.  
  517. comment:
  518.         BEGIN, THEN, DO ?DO, LOOP, +LOOP, UNTIL, AGAIN, REPEAT, IF ELSE,
  519.         WHILE: These are the compiling words needed to properly compile the
  520.         Forth Conditional Structures. Each of them is immediate and they
  521.         must compile their runtime routines along withwhatever addresses
  522.         they need. A modest amount of errorchecking is done. If you want to
  523.         rip out the error checking change the ?> and ?< words to > and <
  524.         words, and all of the 2DUPs to DUPs and the 2SWAPs to SWAPs. The
  525.         rest should stay the same.
  526.  
  527.         DOAGAIN, DOTHEN, DOBEGIN, ?UNTIL & ?WHILE are words that are NOOPs
  528.         , or equivalant to ?BRANCH. They are provided to make it easier for
  529.         the Decompiler to know where the control structures start and end.
  530. comment;
  531.  
  532. : BEGIN         ( -- )
  533.                 COMPILE DOBEGIN ?<MARK                          ; IMMEDIATE
  534.  
  535. : AGAIN         ( -- ) 
  536.                 COMPILE DOAGAIN ?<RESOLVE                       ; IMMEDIATE
  537.  
  538. : UNTIL         ( n -- )
  539.                 COMPILE ?UNTIL  ?<RESOLVE                       ; IMMEDIATE
  540.  
  541. : WHILE         ( n -- )
  542.                 COMPILE ?WHILE ?>MARK 2SWAP ( <- added )        ; IMMEDIATE
  543.  
  544. : REPEAT        ( -- )       ( 2SWAP removed ) 
  545.                 COMPILE DOREPEAT ?<RESOLVE ?>RESOLVE            ; IMMEDIATE
  546.  
  547. : DO            ( lim start -- )
  548.                 COMPILE (DO)   ?>MARK                           ; IMMEDIATE
  549.  
  550. : ?DO           ( lim start -- ) 
  551.                 COMPILE (?DO)  ?>MARK                           ; IMMEDIATE
  552.  
  553. : LOOP          ( -- )
  554.                 COMPILE (LOOP)  2DUP 2+ ?<RESOLVE ?>RESOLVE     ; IMMEDIATE
  555.  
  556. : +LOOP         ( n -- )
  557.                 COMPILE (+LOOP) 2DUP 2+ ?<RESOLVE ?>RESOLVE     ; IMMEDIATE
  558.  
  559. : IF            ( n -- ) 
  560.                 COMPILE  ?BRANCH  ?>MARK                        ; IMMEDIATE
  561.  
  562. : ELSE          ( -- ) 
  563.                 COMPILE  BRANCH ?>MARK  2SWAP ?>RESOLVE         ; IMMEDIATE
  564.  
  565. : THEN          ( -- ) 
  566.                 COMPILE DOTHEN ?>RESOLVE                        ; IMMEDIATE
  567.  
  568. : FORWARD       ( -- )
  569.                 COMPILE BRANCH ?>MARK                           ; IMMEDIATE
  570.  
  571. : CONTINUE      ( -- )
  572.                 2OVER [COMPILE] REPEAT                          ; IMMEDIATE
  573.  
  574. : BREAK         ( -- ) 
  575.                 COMPILE EXIT [COMPILE] THEN                     ; IMMEDIATE
  576.  
  577. : AFT           ( -- )
  578.                 2DROP [COMPILE] FORWARD ?<MARK 2SWAP            ; IMMEDIATE
  579.  
  580. : FOR           ( n1 -- )
  581.                 COMPILE >R ?<MARK                               ; IMMEDIATE
  582.  
  583. : NEXT          ( -- )
  584.                 COMPILE NEXT| ?<RESOLVE                         ; IMMEDIATE
  585.  
  586. : ,VIEW         ( -- )  
  587.                 LOADLINE @ Y, ;
  588.  
  589. HEADERLESS
  590.  
  591. : NOHEADROOM    ( -- )
  592.                 TRUE ABORT" Out of HEAD memory!" ;
  593.  
  594. : NOLISTROOM    ( -- )
  595.                 TRUE ABORT" Out of LIST memory!" ;
  596.  
  597. HEADERS
  598.  
  599. CODE SPCHECK    ( -- f1 f2 )           \ HEAD AND LIST SPACE CHECK
  600.                 MOV AX, YDP             \ get head DP
  601.                 SHR AX, # 1             \ convert to ssegment
  602.                 SHR AX, # 1
  603.                 SHR AX, # 1
  604.                 SHR AX, # 1
  605.                 ADD AX, # 6             \ add 6 segments for headroom
  606.                 CMP AX, ' #HEADSEGS >BODY \ are we out of space yet
  607.              >  IF      MOV AX, # ' NOHEADROOM
  608.                         JMP AX
  609.                 THEN
  610.                 MOV AX, XDPSEG          \ load up LIST segment
  611.                 SUB AX, XSEG            \ convert to size of list so far
  612.                 ADD AX, # 6             \ add 6 for headroom
  613.                 CMP AX, ' #LISTSEGS >BODY \ are we out of space yet
  614.              >  IF      MOV AX, # ' NOLISTROOM
  615.                         JMP AX
  616.                 THEN
  617.                 NEXT
  618.                 END-CODE
  619.  
  620. : %ALREADY_DEF  ( a1 -- a1 )   \ Is the word at A1 already defined?
  621.                 WARNING @
  622.                 IF      DUP FIND NIP
  623.                         IF      DUP  CR  COUNT TYPE ."  isn't unique "
  624.                         THEN
  625.                 THEN    ;       ( str )
  626.  
  627. DEFER ?ALREADY_DEF      ' %ALREADY_DEF IS ?ALREADY_DEF
  628.  
  629. : "HEADER       ( str-addr -- )
  630.                 SPCHECK
  631.                 DUP C@ 31 > ABORT" Name TOO LONG, > 31 chars!"
  632.                 ?ALREADY_DEF
  633.                 ALIGN  YHERE 2- Y@ CNHASH  HERE CNHASH  <>
  634.                 IF      YHERE HERE CNHASH DUP Y@ ROT UMIN SWAP
  635.                         Y! ( >NAME hash entry )
  636.                 THEN    ,VIEW
  637.                 YHERE OVER CURRENT @ HASH DUP @  Y,  ( link  ) ! ( current )
  638.                 YHERE LAST ! ( remember nfa )
  639.                 YHERE ?CS: ROT  DUP C@  WIDTH @  MIN 1+ >R  ( yh cs str )
  640.                 YHERE YS: R@ CMOVEL ( copy str ) R> YDP +! ALIGN ( nam )
  641.                 128 SWAP YCSET   128 YHERE 1- YCSET   ( delimiter Bits )
  642.                 HERE Y, ( CFA in header )
  643.                 YHERE HERE CNHASH 2+ Y! ( valid stopper in next n hash entry)
  644.                 ;
  645.  
  646. : ,CALL         ( -- )
  647.                 232 C, 0 HERE 2+ - , ;        \ Compiles addr 0000 !!!!
  648.  
  649. : ,JUMP         ( -- )
  650.                 233 C, 0 HERE 2+ - , ;
  651.  
  652. : <HEADER>      ( | name -- )
  653.                 BL WORD ?UPPERCASE "HEADER ;
  654.  
  655. DEFER HEADER    ' <HEADER> IS HEADER
  656.  
  657. : "CREATE       ( str-addr -- )
  658.                 "HEADER ,CALL ;USES >NEXT ,-X
  659.  
  660. : CREATE        ( | name -- )  
  661.                 HEADER ,CALL ;USES >NEXT ,-X
  662.  
  663. : !CSP          ( -- )  
  664.                 SP@ CSP !   ;
  665.  
  666. : ?CSP          ( -- )  
  667.                 SP@ CSP @ <> ABORT" Stack Changed"   ;
  668.  
  669. : HIDE          ( -- )  
  670.                 LAST @ DUP N>LINK Y@ SWAP CURRENT @ YHASH ! ;
  671.  
  672. : REVEAL        ( -- )  
  673.                 LAST @ DUP N>LINK    SWAP CURRENT @ YHASH ! ;
  674.  
  675. : (;USES)       ( -- )
  676.                 2R> @L LAST @ NAME> dup>r 3 + - R> 1+ ! ;
  677.  
  678. : (;CODE)       ( -- )
  679.                 2R> @L LAST @ NAME>
  680.                 dup>r 232 ( CALL ) R@ C!       \ Make a CALL not JUMP
  681.                 3 + - R> 1+ !  ;
  682.  
  683. : DOES>         ( -- )
  684.                 COMPILE (;CODE) HERE X, 232 ( CALL ) C,
  685.                 [ [FORTH] ASSEMBLER DODOES META ] LITERAL
  686.                 HERE 2+ - , XHERE PARAGRAPH + DUP XDPSEG !
  687.                 XSEG @ - , XDP OFF ; IMMEDIATE
  688.  
  689. VOCABULARY ASSEMBLER
  690.  
  691. DEFER SETASSEM  \ Setup for assembly stuff to follow
  692.  
  693. ' NOOP IS SETASSEM
  694.  
  695. : [             ( -- )  
  696.                 STATE OFF   ;   IMMEDIATE
  697.  
  698. : ;USES         ( -- )  
  699.                 ?CSP   COMPILE  (;USES)
  700.                 [COMPILE] [   REVEAL   ASSEMBLER   ; IMMEDIATE
  701.  
  702. : ;CODE         ( -- )  
  703.                 ?CSP   COMPILE  (;CODE) HERE X,
  704.                 [COMPILE] [   REVEAL   SETASSEM ; IMMEDIATE
  705.  
  706. : (])           ( -- )
  707.                 STATE ON
  708.                 BEGIN   ?STACK  DEFINED DUP
  709.                         IF      0>
  710.                                 IF      EXECUTE   ELSE   X,   THEN
  711.                         ELSE    DROP    NUMBER  DOUBLE?
  712.                                 IF           [COMPILE] DLITERAL
  713.                                 ELSE    DROP [COMPILE] LITERAL
  714.                                 THEN
  715.                         THEN    TRUE    DONE?
  716.                 UNTIL   ;
  717.  
  718. DEFER ]         ' (]) IS ]
  719.  
  720. : MAKEDUMMY     ( name -- )
  721.                 HEADER ,JUMP
  722.                 XHERE PARAGRAPH +       \ absolute paragraph of new def
  723.                 DUP XDPSEG !            \ set new XHERE segment
  724.                 XSEG @ - ,              \ compile relative paragraph of def
  725.                 XDP OFF
  726.                 COMPILE UNNEST
  727.                 ;USES  NEST ,-X
  728.  
  729. : ANEW          ( name -- )
  730.                 >IN @ >R DEFINED NIP  R@ >IN !
  731.                 IF      FORGET
  732.                 THEN    R> >IN !  MAKEDUMMY   ;
  733.                                                         \ Add if needed
  734. : (:)           ( -- )
  735.                 !CSP   CURRENT @ CONTEXT !
  736.                 HEADER ,JUMP
  737.                 XHERE PARAGRAPH +
  738.                 DUP XDPSEG !
  739.                 XSEG @ - ,
  740.                 XDP OFF
  741.                 HIDE
  742.                 ;USES   NEST ,-X
  743.  
  744. : :             ( -- )
  745.                 (:) ] ;
  746.  
  747. : ;             ( -- )
  748.                 STATE @ 0= ABORT" Not Compiling!"
  749.                 ?CSP   COMPILE UNNEST   REVEAL   [COMPILE] [  ; IMMEDIATE
  750.  
  751. : RECURSIVE     ( -- )   
  752.                 REVEAL ;   IMMEDIATE
  753.  
  754. : CONSTANT      ( n -- ) 
  755.                 HEADER ,JUMP ,     ;USES DOCONSTANT ,-X
  756.  
  757. : VALUE         ( n -- ) 
  758.                 HEADER ,JUMP ,     ;USES DOVALUE    ,-X
  759.  
  760. : VARIABLE      ( -- )   
  761.                 CREATE 0 ,         ;USES >NEXT      ,-X
  762.  
  763. : ARRAY         ( n1 -- )
  764.                 CREATE ALLOT       ;USES >NEXT      ,-X
  765.  
  766. : DEFER         ( -- )
  767.                 CREATE ['] CRASH , ;USES DODEFER    ,-X
  768.  
  769. DODEFER RESOLVES <DEFER>
  770.  
  771. : VOCABULARY    ( -- )  
  772.                 CREATE   #THREADS 0 DO   0 ,  LOOP
  773.                 HERE  VOC-LINK @ ,  VOC-LINK !
  774.                 DOES> CONTEXT !  ;
  775.  
  776.  RESOLVES <VOCABULARY>
  777.  
  778. : DEFINITIONS   ( -- ) 
  779.                 CONTEXT @ CURRENT !   ;
  780.  
  781. : 2CONSTANT     ( d1 | <name> -- )
  782.                 CREATE   , ,    ( d# -- )
  783.                 DOES> 2@   ;    ( -- d# )   DROP
  784.  
  785. : 2VARIABLE     ( | <name> -- )
  786.                 0 0 2CONSTANT   ( -- )
  787.                 DOES> ;         ( -- addr )   DROP
  788.  
  789. : <RUN>         ( -- )
  790.         STATE @ IF      ]
  791.                         STATE @ NOT
  792.                         IF   INTERPRET   THEN
  793.                 ELSE    INTERPRET   THEN   ;
  794.  
  795. DEFER RUN       ' <RUN> IS RUN
  796.  
  797. DEFER ERRFIX    ' NOOP IS ERRFIX
  798.  
  799. : (?ERROR)      ( adr len f -- )
  800.                 IF      ['] <RUN> IS RUN ERRFIX
  801.                         2>R SP0 @ SP!   PRINTING OFF
  802.                         2R> SPACE TYPE SPACE   QUIT
  803.                 ELSE    2DROP  THEN  ;
  804.  
  805. ' (?ERROR) IS ?ERROR
  806.  
  807.