http://t3x.org/t3xforth/t3xforth.html   (light|dark)

T3XFORTH Logo

T3XFORTH

 
\ T3XFORTH High-Level Words
\ Nils M Holm, 2021
\ Public domain / CC0 License

: ?DUP ( w -- w w | w ) DUP IF DUP THEN ;

: NIP ( w1 w2 -- w2 ) SWAP DROP ;
    
: ROT ( w1 w2 w3 -- w2 w3 w1 ) >R SWAP R> SWAP ;

: -ROT ( w1 w2 w3 -- w3 w1 w2 ) ROT ROT ;

: 2DROP ( d -- ) DROP DROP ;
      
: 2DUP ( d -- d d ) OVER OVER ;

: 2SWAP ( d1 d2 -- d2 d1 ) >R -ROT R> -ROT ;

-1 CONSTANT -1
 0 CONSTANT  0
 1 CONSTANT  1
 2 CONSTANT  2

: INVERT ( w -- w ) -1 XOR ;

: + ( n n -- n ) UM+ DROP ;

: 1+ ( n -- n ) 1 + ;
: 2+ ( n -- n ) 2 + ;

: NEGATE ( n -- n ) INVERT 1+ ;

: DNEGATE ( d -- d ) INVERT >R INVERT 1 UM+ R> + ;

: - ( n n -- n ) NEGATE + ;

: 1- ( n -- n ) 1 - ;
: 2- ( n -- n ) 2 - ;

: ABS ( n -- n ) DUP 0< IF NEGATE THEN ;

: 0= ( w -- f ) IF 0 EXIT THEN -1 ;

: NOT ( w -- f ) 0= ;

:  = ( w w -- f ) XOR 0= ;
: <> ( w w -- f ) = 0= ;

: U< ( u u -- f ) 2DUP XOR 0< IF  NIP 0< EXIT THEN - 0< ;
:  < ( n n -- f ) 2DUP XOR 0< IF DROP 0< EXIT THEN - 0< ;

: U> ( u u -- f ) SWAP U< ;
:  > ( n n -- f ) SWAP < ;

: 0> ( n -- f ) 0 > ;

: D+ ( d d -- d ) >R ROT UM+ ROT + R> + ;

: D< ( d d -- f ) ROT SWAP < IF 2DROP -1 EXIT THEN U< ;

: MAX ( n n -- n ) 2DUP < IF SWAP THEN DROP ;
: MIN ( n n -- n ) 2DUP > IF SWAP THEN DROP ;

: WITHIN ( u ul uh -- f ) OVER - >R - R> U< ;

: UM* ( u1 u2 -- ud )
  0 SWAP ( u1 v=0 u2 ) 16 0 DO
    DUP UM+ >R >R     \ u1 v         ; cu2 2u2
    DUP UM+  R> +     \ u1 2v 2u2+cv ; cu2
    R> IF             \ u1 2v 2u2+cv cu2
    >R OVER           \ u1 2v u1     ; 2u2+cv
    UM+  R> + THEN    \ u1 2v+u1 2u2+cv+c
  LOOP ROT DROP ;

: * ( w w -- w ) UM* DROP ;

: M* ( n n -- d )
  2DUP XOR 0< >R  ABS SWAP ABS UM*  R> IF DNEGATE THEN ;

: 2* ( w -- w ) 1 LSHIFT ;
: 2/ ( w -- w ) 1 RSHIFT ;

: UM/MOD ( ul uh u -- um uq )
  2DUP U<                    \ uh < u
  IF  NEGATE                 \ ul uh -u
    16 0 DO
      >R DUP  UM+  >R >R     \ ul          ;  -u ch 2uh
      DUP UM+  R> +          \ 2ul 2uh+cl  ;  -u ch
      DUP R> R@ SWAP >R      \ 2ul 2uh+cl 2uh+cl -u  ; -u ch
          UM+ R> OR          \ 2ul 2uh+cl 2uh+cl-u c|ch ; -u
      IF >R DROP 1+ R> ELSE  \ 2ul+1 2uh+cl-u ; -u
         DROP THEN           \ 2ul 2uh+cl     ; -u
    R> LOOP DROP SWAP EXIT
  THEN  DROP 2DROP  -1 DUP ;

: U/ ( u1 u2 -- u ) 0 SWAP UM/MOD NIP ;

: EXTEND ( n -- d ) DUP 0< ;

: M/MOD ( d n -- nm nq ) \ floored
  EXTEND  DUP >R  IF NEGATE >R DNEGATE R> THEN
  >R DUP 0< IF R@ + THEN  R> UM/MOD
  R> IF SWAP NEGATE SWAP THEN ;

: /MOD ( n n -- nm nq ) SWAP EXTEND ROT M/MOD ;
: MOD ( n n -- n ) /MOD DROP ;
: / ( n n -- n ) /MOD NIP ;

: */MOD ( n n n -- r q ) >R M* R> M/MOD ;
: */ ( n n n -- q ) */MOD NIP ;

VARIABLE H
VARIABLE HLD
VARIABLE UP      [HEX] F380 ' UP !
VARIABLE BASE            10 ' BASE !
VARIABLE 'EMIT        ' TX! ' 'EMIT !
VARIABLE '?KEY        ' RX? ' '?KEY !
VARIABLE SPAN
VARIABLE >IN
VARIABLE BLK
VARIABLE #TIB
VARIABLE FENCE

  32 CONSTANT BL

   2 CONSTANT CELL

1024 CONSTANT B/BUF
  64 CONSTANT B/LINE

[HEX] F000 CONSTANT S0
[HEX] F000 CONSTANT TIB
[HEX] F380 CONSTANT R0

: HERE ( -- a ) H @ ;

: PAD ( -- a ) HERE B/LINE 2* + ;

: CELL+ ( n -- n ) CELL + ;

: CELL- ( n -- n ) CELL - ;

: CELLS ( n -- n ) 1 LSHIFT ( CELL * ) ;

: >CHAR ( n -- c )
  127 AND  DUP BL 127 WITHIN 0= IF DROP [CHAR] _ THEN ;

: DEPTH ( -- n ) SP@ S0 SWAP - 1 RSHIFT ( CELL / ) ;

: PICK ( u -- w ) 1+ CELLS SP@ + @ ;

: 2OVER ( d1 d2 -- d1 d2 d1 ) 3 PICK 3 PICK ;

: +! ( n a -- ) SWAP OVER @ + SWAP ! ;

: 2! ( d a -- ) SWAP OVER ! CELL+ ! ;
: 2@ ( a -- d ) DUP CELL+ @ SWAP @ ;

: ?0>DUP ( n -- 0 | n n ) DUP 0> IF DUP EXIT THEN DROP 0 ;

: @EXECUTE ( a -- ) @ ?DUP IF EXECUTE THEN ;

: EMIT ( c -- ) 'EMIT @EXECUTE ;

: ?KEY ( -- c T | F ) '?KEY @EXECUTE ;

: CONSOLE ( -- ) ['] TX! 'EMIT !  ['] RX? '?KEY ! ;

: KEY ( -- c ) BEGIN ?KEY UNTIL ;

: COUNT ( a -- a n ) DUP 1+ SWAP C@ ;

: TYPE ( a n -- ) ?0>DUP IF 0 DO COUNT EMIT LOOP THEN DROP ;

: CR ( -- ) 13 EMIT 10 EMIT ;

: BELL ( -- ) 7 EMIT ;

: BACKSPACE ( -- ) 8 DUP EMIT BL EMIT EMIT ;

: PAGE ( -- ) 50 0 DO CR LOOP ;

: SPACE ( -- ) BL EMIT ;

: SPACES ( n -- ) ?0>DUP IF 0 DO SPACE LOOP THEN ;

: HEX     ( -- ) 16 BASE ! ;
: DECIMAL ( -- ) 10 BASE ! ;
: BINARY  ( -- )  2 BASE ! ;

: DIGIT ( u -- c ) DUP 9 > IF 55 + EXIT THEN [CHAR] 0 + ;

: <# ( ud -- u ) DROP PAD HLD ! ;

: HOLD ( c -- ) -1 HLD +!  HLD @ C! ;

: # ( u -- u ) BASE @  0 SWAP UM/MOD  SWAP DIGIT HOLD ;

: #S ( u -- 0 ) BEGIN # DUP WHILE REPEAT ;

: SIGN ( n u -- u ) SWAP 0< IF [CHAR] - HOLD THEN ;

: #> ( u -- a u ) DROP HLD @ PAD OVER - ;

: (PAD) ( u1 u2 -- u1 )
  2DUP < IF OVER - SPACES EXIT THEN DROP ;

:  .  ( n -- )    DUP ABS 0 <# #S SIGN #>          TYPE SPACE ;
: U.  ( u -- )            0 <# #S      #>          TYPE SPACE ;
:  .R ( nu-- ) >R DUP ABS 0 <# #S SIGN #> R> (PAD) TYPE ;
: U.R ( uu-- ) >R         0 <# #S      #> R> (PAD) TYPE ;

: H. ( u -- ) BASE @ HEX SWAP U. BASE ! ;

: ? ( a -- ) @ . ;

VARIABLE TMP

: EXPECT ( a u -- ) DUP TMP !  BEGIN
    DUP 0= IF DROP BL SWAP C!  TMP @ SPAN ! EXIT THEN
    KEY DUP 13 = IF DROP  TMP @ SWAP - SPAN !
                    BL SWAP C!  SPACE EXIT           ELSE
        DUP  8 = OVER 127 = OR
                 IF DROP DUP TMP @ <> IF
                    SWAP 1- SWAP 1+ BACKSPACE THEN   ELSE
        DUP 24 = IF DROP 2DROP 0 SPAN ! EXIT         ELSE
        DUP BL 127 WITHIN IF DUP EMIT
                 SWAP >R OVER C! R>  1- SWAP 1+ SWAP ELSE
    DROP BELL THEN THEN THEN THEN  AGAIN ;

: QUERY ( -- )
  TIB 80 EXPECT  SPAN @ #TIB !  0 >IN !  0 BLK ! ;

[HEX] F400 CONSTANT B0ADDR
[HEX] F800 CONSTANT B1ADDR

VARIABLE ACTIVE   -1 ' ACTIVE !
VARIABLE B0BLK    -1 ' B0BLK !
VARIABLE B1BLK    -1 ' B1BLK !
VARIABLE B0UPD     0 ' B0UPD !
VARIABLE B1UPD     0 ' B1UPD !

: ACTIVATE ( u -- ) B0BLK @ = 0= ACTIVE ! ;

: FIND-BLOCK ( u -- a T | 0 )
  DUP B0BLK @ = IF DROP B0ADDR -1 EXIT THEN
      B1BLK @ = IF      B1ADDR -1 EXIT THEN 0 ;

: SOURCE ( -- a )
  BLK @ ?DUP IF FIND-BLOCK DROP EXIT THEN TIB ;

: EXTRACT ( -- c ) SOURCE >IN @ + C@ ;

: ?MORE ( -- f ) >IN @ #TIB @ < ;

: WORD ( c -- a ) TMP !  HERE 1+
  BEGIN ?MORE EXTRACT TMP @ = AND WHILE
    1 >IN +! REPEAT
  BEGIN ?MORE EXTRACT TMP @ <> AND WHILE
    EXTRACT OVER C! 1+  1 >IN +!  REPEAT
  EXTRACT OVER C!  1 >IN +!  HERE 1+ - HERE C!  HERE ;

: .S ( -- ) S0 SP@ CELL+ = IF EXIT THEN
  S0 SP@ CELL+ DO I @ . CELL /LOOP ;

: CMOVE ( a a n -- ) ?0>DUP IF
    0 DO >R COUNT R@ C! R> 1+ LOOP 2DROP  THEN ;

: <CMOVE ( a a n -- ) ?0>DUP IF >R SWAP R@ + 1- SWAP R@ + 1- R>
    0 DO >R COUNT R@ C! 2 - R> 1- LOOP 2DROP  THEN ;

: MOVE ( a a n -- ) CELLS CMOVE ;

: UNLOOP ( -- ) R> R> R> 2DROP >R ;

: -TRAILING ( a n -- a n ) ?0>DUP IF
  1 SWAP 1- NEGATE DO DUP I - C@
      BL XOR IF I 1- NEGATE UNLOOP EXIT THEN
      LOOP 0 THEN ;

: -TEXT ( a1 u a2 -- n )
  SWAP DUP 0= IF 2DROP DROP 0 EXIT THEN
  0 DO OVER C@ OVER C@ - DUP IF
      -ROT 2DROP UNLOOP EXIT THEN
    DROP 1+ SWAP 1+ SWAP LOOP 2DROP 0 ;

: FILL ( a n c -- ) OVER 0> IF
    -ROT 0 DO 2DUP C! 1+ LOOP ELSE
    DROP THEN  2DROP ;

: ERASE ( a n -- ) 0 FILL ;

: BLANK ( a n -- ) BL FILL ;

: ?DIGIT ( c -- u T | F )
  DUP 64 > IF 55 - ELSE
  DUP 47 > IF 48 - THEN THEN
  DUP BASE @ U< IF -1 EXIT THEN DROP 0 ;

: CONVERT ( u a -- u a ) 1+
  BEGIN DUP C@ ?DIGIT WHILE ( u a digit )
    ROT BASE @ * + SWAP 1+ REPEAT ;

VARIABLE LAST
VARIABLE CONTEXT
VARIABLE CURRENT
VARIABLE (FORTH)

: FORTH ( -- ) (FORTH) CONTEXT ! ;

: DEFINITIONS ( -- ) CONTEXT @ CURRENT ! ;

: >NFA ( a -- a ) 10 - ;
: >LFA ( a -- a )  6 + ;
: >CFA ( a -- a )  8 + ;
: >PFA ( a -- a ) 10 + ;

: LOOKUP ( a a -- a f )
  BEGIN ?DUP WHILE
    2DUP ?SAME IF NIP -1 EXIT THEN
    >LFA @ REPEAT 0 ;

: UPCASE ( a -- ) COUNT 0 DO
    COUNT DUP [CHAR] a [CHAR] { WITHIN IF BL - THEN
    OVER 1- C! LOOP DROP ;

: ?FIND ( a -- a f ) DUP UPCASE
  CONTEXT @ @ LOOKUP IF >PFA -1 EXIT THEN
  (FORTH) CONTEXT @ = IF 0 EXIT THEN
  (FORTH) @ LOOKUP IF >PFA -1 EXIT THEN  0 ;

: FIND ( -- a ) BL WORD ?FIND IF >NFA >CFA EXIT THEN DROP 0 ;

: ?NUMBER ( a -- n T | F )
  DUP 1+ C@ [CHAR] - = DUP >R IF 1+ THEN
  0 SWAP CONVERT  C@ BL = IF -1 ELSE DROP 0 THEN
  R> OVER AND IF SWAP NEGATE SWAP THEN ;

VARIABLE STATE 0 ' STATE !

DEFER QUIT

: ABORT ( -- ) S0 SP!  0 STATE !  QUIT ;

: ?WHAT ( a -- ) COUNT TYPE [CHAR] ? EMIT CR ABORT ;

: $+ ( a1 -- a1 a2 ) DUP DUP C@ + 1+ ;

: ($") ( -- a ) R> $+ >R ; COMPILE-ONLY

: ?STACK ( -- ) SP@ S0 U>  SP@ PAD B/BUF + U< OR
  IF $" STK ERR" ?WHAT THEN ;

:  ( ( -- ) [CHAR] ) WORD DROP ; IMMEDIATE
: .( ( -- ) [CHAR] ) WORD COUNT TYPE ; IMMEDIATE
:  \ ( -- ) BLK @ 0= IF #TIB @ >IN ! EXIT THEN
   >IN @ B/LINE + 1- DUP B/LINE MOD - >IN ! ; IMMEDIATE

: ?ENOUGH ( -- ) [CHAR] : EMIT KEY BACKSPACE [CHAR] q = ;

: WORDS ( -- ) 0 TMP !  CR  CONTEXT @ @ BEGIN ?DUP WHILE
    DUP COUNT [HEX] 1F AND 5 MIN DUP >R TYPE 8 R> - SPACES
    1 TMP +!  TMP @ 199 > IF
      0 TMP ! ?ENOUGH IF DROP EXIT THEN THEN  >LFA @ REPEAT ;

: ?COMPILE-ONLY ( a -- a ) DUP >NFA C@ [HEX] 40 AND IF
    $" COMP ONLY" ?WHAT THEN ;

: ?IMMEDIATE ( a -- a w ) DUP >NFA C@ [HEX] 80 AND ;

:  , ( w -- ) H @  ! CELL H +! ;
: C, ( c -- ) H @ C!    1 H +! ;

: ' ( -- a ) BL WORD ?FIND 0= IF ?WHAT THEN ;

: COMPILE ( -- ) R> DUP @ , CELL+ >R ; COMPILE-ONLY

: LITERAL ( w -- ) COMPILE (LIT) , ; IMMEDIATE COMPILE-ONLY

: DUMP ( a -- ) BASE @ >R HEX
    DUP 16 0 DO COUNT 0 <# # # #> TYPE SPACE LOOP
  DROP  16 0 DO COUNT >CHAR EMIT LOOP  R> BASE ! SPACE ;

: HD ( a n -- ) BASE @ >R HEX
  0 DO CR DUP 0 <# # # # # #> TYPE
    SPACE DUMP LOOP  R> BASE ! ;

: PFA>CFA ( a -- a ) CELL- ;
: CFA>PFA ( a -- a ) CELL+ ;

: NUMBER ( a -- n )
  DUP ?NUMBER IF NIP EXIT THEN ?WHAT ;

VARIABLE DBL
VARIABLE 'NUMBER  ' NUMBER ' 'NUMBER !

: NUMBER 'NUMBER @EXECUTE ;

: DLITERAL ( d -- )
  SWAP [COMPILE] LITERAL [COMPILE] LITERAL ;
  IMMEDIATE COMPILE-ONLY

: INTERPRET ( -- ) BEGIN BL WORD DUP C@ WHILE
    STATE @ IF  ?FIND IF
        ?IMMEDIATE IF EXECUTE ELSE PFA>CFA , THEN ELSE
        NUMBER DBL @ IF
          [COMPILE] DLITERAL ELSE
          [COMPILE] LITERAL  THEN THEN
    ELSE ?FIND IF
        ?COMPILE-ONLY EXECUTE ELSE
        NUMBER THEN
    THEN ?STACK REPEAT DROP ;

: .OK ( -- )
  STATE @ 0= IF [CHAR] O EMIT [CHAR] K EMIT THEN CR ;

: ['] ( -- a ) ' [COMPILE] LITERAL ; IMMEDIATE COMPILE-ONLY

: [HEX] ( -- w ) BASE @ >R  BL WORD DUP UPCASE
  DUP HEX ?NUMBER 0= IF R> BASE ! ?WHAT THEN  NIP
  R> BASE !  STATE @ IF [COMPILE] LITERAL THEN ; IMMEDIATE

: [CHAR] ( -- c ) BL WORD 1+ C@
  STATE @ IF [COMPILE] LITERAL THEN ; IMMEDIATE

: [COMPILE] ( -- ) ' PFA>CFA , ; IMMEDIATE COMPILE-ONLY

: ALLOT ( n -- ) HERE + H ! ;

: ENTRY ( a -- ) DUP UPCASE
  COUNT 5 SWAP DO DUP I + BL SWAP C! LOOP DROP ;

: CREATE ( -- ) BL WORD ENTRY  6 ALLOT
  CURRENT @ @ ,  ['] (VAR) ,  HERE >NFA LAST ! ;

: PERFORMS ( -- ) R>  DUP @ CFA>PFA LAST @ >CFA !
  CELL+ >R ; COMPILE-ONLY

: LINK ( -- ) LAST @ CURRENT @ ! ;

: VARIABLE ( -- ) CREATE 0 , LINK ;

: CONSTANT ( w -- ) CREATE , PERFORMS (CONST) LINK ;

: [ ( -- )  0 STATE ! ; IMMEDIATE
: ] ( -- ) -1 STATE ! ;

: : ( -- ) CREATE PERFORMS (COLON) ] ;
: ; ( -- ) COMPILE EXIT [COMPILE] [ LINK ; IMMEDIATE
           COMPILE-ONLY

: (DEFER) ( -- ) $" DEFER ERR" ?WHAT ; COMPILE-ONLY

: DEFER ( -- ) CREATE PERFORMS (COLON) COMPILE (DEFER)
  COMPILE EXIT LINK ;

: IS ( -- ) LAST @ >CFA ' ! ;

: MARK ( -- a ) HERE 0 , ; COMPILE-ONLY

: RESOLVE ( a -- ) HERE SWAP ! ; COMPILE-ONLY

: IF ( f -- ) COMPILE (0BRANCH) MARK ; IMMEDIATE COMPILE-ONLY
: ELSE ( -- ) COMPILE (BRANCH) MARK SWAP RESOLVE ; IMMEDIATE
              COMPILE-ONLY
: THEN ( -- ) RESOLVE ; IMMEDIATE COMPILE-ONLY

: DO ( n n -- ) COMPILE (DO) HERE ; IMMEDIATE COMPILE-ONLY
: LOOP ( -- ) COMPILE (LOOP) , ; IMMEDIATE COMPILE-ONLY
: +LOOP ( n -- ) COMPILE (+LOOP) , ; IMMEDIATE COMPILE-ONLY
: /LOOP ( u -- ) COMPILE (/LOOP) , ; IMMEDIATE COMPILE-ONLY
: LEAVE ( -- ) R> R> R> DROP DUP >R >R >R ; COMPILE-ONLY

: BEGIN ( -- ) HERE ; IMMEDIATE COMPILE-ONLY
: WHILE ( f -- ) [COMPILE] IF ; IMMEDIATE COMPILE-ONLY
: REPEAT ( -- ) COMPILE (BRANCH) SWAP , RESOLVE ; IMMEDIATE
                COMPILE-ONLY
: AGAIN ( f -- ) COMPILE (BRANCH) , ; IMMEDIATE COMPILE-ONLY
: UNTIL ( f -- ) COMPILE (0BRANCH) , ; IMMEDIATE COMPILE-ONLY

: IMMEDIATE    ( -- ) LAST @ C@ [HEX] 80 OR LAST @ C! ;
: COMPILE-ONLY ( -- ) LAST @ C@ [HEX] 40 OR LAST @ C! ;

: RECURSE ( -- ) LAST @ >CFA , ; IMMEDIATE COMPILE-ONLY

: I' ( -- w )    R> R> R@ -ROT >R >R ;
: J  ( -- w ) R> R> R> R@ -ROT >R >R SWAP >R ;

: $, ( -- ) [CHAR] " WORD C@ 1+ ALLOT ; COMPILE-ONLY

: $" ( -- a ) COMPILE ($") $, ; IMMEDIATE COMPILE-ONLY

: (.") ( -- ) R> $+ >R COUNT TYPE ; COMPILE-ONLY

: ." ( -- ) COMPILE (.") $, ; IMMEDIATE COMPILE-ONLY

: (ABORT") ( f -- ) R> $+ >R SWAP IF ?WHAT THEN DROP ;
           COMPILE-ONLY

: ABORT" ( f -- ) COMPILE (ABORT") $, ; IMMEDIATE
                  COMPILE-ONLY

: <BUILDS ( -- ) VARIABLE ; COMPILE-ONLY

: DOES> ( -- ) PERFORMS (DOES>) R> LAST @ >PFA ! ; COMPILE-ONLY

: ARRAY ( u -- ) <BUILDS CELLS ALLOT DOES> SWAP CELLS + ;

: USER ( u -- ) <BUILDS CELLS , DOES> @ UP @ + ;

: VOCABULARY ( -- ) <BUILDS 0 , DOES> CONTEXT ! ;

: EMPTY ( -- ) FORTH DEFINITIONS  FENCE @ DUP DUP
  CONTEXT @ !  CURRENT @ !  >PFA CELL+ H ! ;

: FORGET ( -- )
  CURRENT @ CONTEXT @ <>    ABORT" CURRENT"
  ' >NFA DUP  FENCE @ U> 0= ABORT" FENCE"
        DUP CONTEXT @ U> 0= ABORT" CONTEXT"
  DUP H !  >LFA @ CONTEXT @ ! ;

VARIABLE SCR

: EMPTY-BUFFERS ( -- ) -1 ACTIVE !
  0 DUP B0UPD ! B1UPD !  -1 DUP B0BLK ! B1BLK ! ;

: ?I/O ( f -- ) DUP 0= IF EMPTY-BUFFERS THEN
  0= ABORT" I/O ERR" ;

: ?EXIT-CACHED ( u -- a | u )
  DUP FIND-BLOCK IF SWAP ACTIVATE R> DROP THEN ;

: 0SAVE ( -- f )
  B0UPD @ IF B0ADDR B0BLK @ WRITE-BLOCK EXIT THEN -1 ;

: 1SAVE ( -- f )
  B1UPD @ IF B1ADDR B1BLK @ WRITE-BLOCK EXIT THEN -1 ;

: BUFFER ( u -- a ) ?EXIT-CACHED ACTIVE @ IF
    0SAVE ?I/O  B0BLK !  0 ACTIVE ! 0 B0UPD ! B0ADDR ELSE
    1SAVE ?I/O  B1BLK !  1 ACTIVE ! 0 B1UPD ! B1ADDR THEN ;

: BLOCK ( u -- a ) ?EXIT-CACHED
  DUP BUFFER DUP ROT READ-BLOCK ?I/O ;

: UPDATE ( -- ) ACTIVE @ 0< IF EXIT THEN
  -1 ACTIVE @ IF B1UPD ELSE B0UPD THEN ! ;

: WIPE ( -- ) ACTIVE @ 0< IF EXIT THEN
  ACTIVE @ IF B1ADDR ELSE B0ADDR THEN B/BUF BLANK ;

: COPY ( usrc udest -- ) SWAP BLOCK DROP
  ACTIVE @ IF B1BLK ELSE B0BLK THEN ! ;

: SAVE-BUFFERS ( -- )
  0SAVE 1SAVE AND ?I/O  0 DUP B0UPD ! B1UPD ! ;

: FLUSH ( -- ) SAVE-BUFFERS ;

: LIST ( u -- ) DUP SCR !  BLOCK  16 0 DO CR
    I 1+ 2 .R [CHAR] : EMIT SPACE
    DUP I B/LINE * + B/LINE TYPE  [CHAR] : EMIT
  LOOP DROP SPACE ;

: LOAD ( u -- )
  BLK @ >R  >IN @ >R  #TIB @ >R  ACTIVE @ >R
  DUP BLOCK DROP BLK !  B/BUF #TIB !  0 >IN !  INTERPRET
  R> ACTIVE !  R> #TIB !  R> >IN !  R> BLK ! ;

: THRU ( u1 u2 -- ) 1+ SWAP DO I . I LOAD LOOP ;

: INDEX ( n1 n2 -- ) 0 -ROT
  1+ SWAP DO CR I 0 .R [CHAR] : EMIT SPACE
    I BLOCK B/LINE TYPE  1+ DUP 20 > IF
      ?ENOUGH IF UNLOOP DROP EXIT THEN
      DROP 0 THEN
    LOOP DROP ;

: RESET ( -- ) FORTH DEFINITIONS
  EMPTY-BUFFERS  DECIMAL  [HEX] F380 UP !
  $" T3XFORTH" COUNT TYPE CR  ABORT ;

: (QUIT) ( -- )
  BEGIN R0 RP!  CONSOLE  QUERY INTERPRET .OK AGAIN ;
  IS QUIT  COMPILE-ONLY

: (FENCE) ;
' (FENCE) >NFA ' FENCE !
 

contact | privacy