Diff for /gforth/Attic/kernal.fs between versions 1.19 and 1.27

version 1.19, 1994/09/05 17:36:20 version 1.27, 1995/01/30 18:47:52
Line 1 Line 1
 \ KERNAL.FS    ANS figFORTH kernal                     17dec92py  \ KERNAL.FS    GNU FORTH kernal                        17dec92py
 \ $ID:  \ $ID:
 \ Idea and implementation: Bernd Paysan (py)  \ Idea and implementation: Bernd Paysan (py)
 \ Copyright 1992 by the ANSI figForth Development Group  \ Copyright 1992 by the ANSI figForth Development Group
Line 66  DOES> ( n -- )  + c@ ; Line 66  DOES> ( n -- )  + c@ ;
       bl c,        bl c,
   LOOP ;    LOOP ;
   
   : chars ; immediate
   
 : A!    ( addr1 addr2 -- )  dup relon ! ;  : A!    ( addr1 addr2 -- )  dup relon ! ;
 : A,    ( addr -- )     here cell allot A! ;  : A,    ( addr -- )     here cell allot A! ;
Line 154  Defer source Line 154  Defer source
   
 \ name                                                 13feb93py  \ name                                                 13feb93py
   
 : capitalize ( addr -- addr )  : capitalize ( addr len -- addr len )
   dup count chars bounds    2dup chars chars bounds
   ?DO  I c@ toupper I c! 1 chars +LOOP ;    ?DO  I c@ toupper I c! 1 chars +LOOP ;
 : (name)  ( -- addr )  bl word ;  : (name) ( -- c-addr count )
 : sname ( -- c-addr count )  
     source 2dup >r >r >in @ /string (parse-white)      source 2dup >r >r >in @ /string (parse-white)
     2dup + r> - 1+ r> min >in ! ;      2dup + r> - 1+ r> min >in ! ;
 \    name count ;  \    name count ;
Line 174  Defer source Line 173  Defer source
 : [char] ( 'char' -- n )  char postpone Literal ; immediate  : [char] ( 'char' -- n )  char postpone Literal ; immediate
 ' [char] Alias Ascii immediate  ' [char] Alias Ascii immediate
   
 : (compile) ( -- )  r> dup cell+ >r @ A, ;  : (compile) ( -- )  r> dup cell+ >r @ compile, ;
 : postpone ( "name" -- )  : postpone ( "name" -- )
   name find dup 0= abort" Can't compile "    name sfind dup 0= abort" Can't compile "
   0> IF  A,  ELSE  postpone (compile) A,  THEN ;    0> IF  compile,  ELSE  postpone (compile) A,  THEN ;
                                              immediate restrict                                               immediate restrict
   
 \ Use (compile) for the old behavior of compile!  \ Use (compile) for the old behavior of compile!
Line 245  decimal Line 244  decimal
 Create spaces  bl 80 times \ times from target compiler! 11may93jaw  Create spaces  bl 80 times \ times from target compiler! 11may93jaw
 DOES>   ( u -- )  swap  DOES>   ( u -- )  swap
         0 max 0 ?DO  I' I - &80 min 2dup type  +LOOP  drop ;          0 max 0 ?DO  I' I - &80 min 2dup type  +LOOP  drop ;
   Create backspaces  08 80 times \ times from target compiler! 11may93jaw
   DOES>   ( u -- )  swap
           0 max 0 ?DO  I' I - &80 min 2dup type  +LOOP  drop ;
 hex  hex
 : space   1 spaces ;  : space   1 spaces ;
   
Line 342  Defer notfound ( c-addr count -- ) Line 344  Defer notfound ( c-addr count -- )
   
 : interpret  : interpret
     BEGIN      BEGIN
         ?stack sname dup          ?stack name dup
     WHILE      WHILE
         parser          parser
     REPEAT      REPEAT
     2drop ;      2drop ;
   
 \ sinterpreter scompiler                                 30apr92py  \ interpreter compiler                                 30apr92py
   
 : sinterpreter  ( c-addr u -- )   : interpreter  ( c-addr u -- ) 
     \ interpretation semantics for the name/number c-addr u      \ interpretation semantics for the name/number c-addr u
     2dup sfind dup      2dup sfind dup
     IF      IF
Line 368  Defer notfound ( c-addr count -- ) Line 370  Defer notfound ( c-addr count -- )
         2r> notfound          2r> notfound
     THEN ;      THEN ;
   
 ' sinterpreter  IS  parser  ' interpreter  IS  parser
   
 : scompiler     ( c-addr u -- )  : compiler     ( c-addr u -- )
     \ compilation semantics for the name/number c-addr u      \ compilation semantics for the name/number c-addr u
     2dup sfind dup      2dup sfind dup
     IF      IF
Line 393  Defer notfound ( c-addr count -- ) Line 395  Defer notfound ( c-addr count -- )
         drop notfound          drop notfound
     THEN ;      THEN ;
   
 : [     ['] sinterpreter  IS parser state off ; immediate  : [     ['] interpreter  IS parser state off ; immediate
 : ]     ['] scompiler     IS parser state on  ;  : ]     ['] compiler     IS parser state on  ;
   
 \ locals stuff needed for control structures  \ locals stuff needed for control structures
   
 : compile-lp+! ( n -- )  : compile-lp+! ( n -- )
     dup negate locals-size +!      dup negate locals-size +!
     0 over = if      0 over = if
     else -4 over = if postpone -4lp+!      else -1 cells  over = if postpone lp-
     else  8 over = if postpone  8lp+!      else  1 floats over = if postpone lp+
     else 16 over = if postpone 16lp+!      else  2 floats over = if postpone lp+2
     else postpone lp+!# dup ,      else postpone lp+!# dup ,
     then then then then drop ;      then then then then drop ;
   
Line 418  AConstant locals-list \ acts like a vari Line 420  AConstant locals-list \ acts like a vari
   
   
 variable dead-code \ true if normal code at "here" would be dead  variable dead-code \ true if normal code at "here" would be dead
   variable backedge-locals
 : unreachable ( -- )      \ contains the locals list that BEGIN will assume to be live on
 \ declares the current point of execution as unreachable      \ the back edge if the BEGIN is unreachable from above. Set by
  dead-code on ;      \ ASSUME-LIVE, reset by UNREACHABLE.
   
   : UNREACHABLE ( -- )
       \ declares the current point of execution as unreachable
       dead-code on
       0 backedge-locals ! ; immediate
   
   : ASSUME-LIVE ( orig -- orig )
       \ used immediateliy before a BEGIN that is not reachable from
       \ above.  causes the BEGIN to assume that the same locals are live
       \ as at the orig point
       dup orig?
       2 pick backedge-locals ! ; immediate
       
 \ locals list operations  \ locals list operations
   
 : common-list ( list1 list2 -- list3 )  : common-list ( list1 list2 -- list3 )
Line 547  variable dead-code \ true if normal code Line 561  variable dead-code \ true if normal code
 \ Structural Conditionals                              12dec92py  \ Structural Conditionals                              12dec92py
   
 : AHEAD ( -- orig )  : AHEAD ( -- orig )
  POSTPONE branch >mark unreachable ; immediate restrict   POSTPONE branch >mark POSTPONE unreachable ; immediate restrict
   
 : IF ( -- orig )  : IF ( -- orig )
  POSTPONE ?branch >mark ; immediate restrict   POSTPONE ?branch >mark ; immediate restrict
Line 561  variable dead-code \ true if normal code Line 575  variable dead-code \ true if normal code
   
 : THEN ( orig -- )  : THEN ( orig -- )
     dup orig?      dup orig?
     dead-code @      dead-orig =
     if      if
         dead-orig =          >resolve drop
         if  
             >resolve drop  
         else  
             >resolve set-locals-size-list dead-code off  
         then  
     else      else
         dead-orig =          dead-code @
         if          if
             >resolve drop              >resolve set-locals-size-list dead-code off
         else \ both live          else \ both live
             over list-size adjust-locals-size              over list-size adjust-locals-size
             >resolve              >resolve
Line 594  variable dead-code \ true if normal code Line 603  variable dead-code \ true if normal code
   
 : BEGIN ( -- dest )  : BEGIN ( -- dest )
     dead-code @ if      dead-code @ if
         \ set up an assumption of the locals visible here          \ set up an assumption of the locals visible here.  if the
         \ currently we just take the top cs-item          \ users want something to be visible, they have to declare
         \ it would be more intelligent to take the top orig          \ that using ASSUME-LIVE
         \   but that can be arranged by the user          backedge-locals @ set-locals-size-list
         dup defstart <> if  
             dup cs-item?  
             2 pick  
         else  
             0  
         then  
         set-locals-size-list  
     then      then
     cs-push-part dest      cs-push-part dest
     dead-code off ; immediate restrict      dead-code off ; immediate restrict
Line 620  variable dead-code \ true if normal code Line 622  variable dead-code \ true if normal code
     POSTPONE branch      POSTPONE branch
     <resolve      <resolve
     check-begin      check-begin
     unreachable ; immediate restrict      POSTPONE unreachable ; immediate restrict
   
 \ UNTIL (the current control flow may join an earlier one or continue):  \ UNTIL (the current control flow may join an earlier one or continue):
 \ Similar to AGAIN. The new locals-list and locals-size are the current  \ Similar to AGAIN. The new locals-list and locals-size are the current
Line 752  Avariable leave-sp  leave-stack 3 cells Line 754  Avariable leave-sp  leave-stack 3 cells
 : EXIT ( -- )  : EXIT ( -- )
     0 adjust-locals-size      0 adjust-locals-size
     POSTPONE ;s      POSTPONE ;s
     unreachable ; immediate restrict      POSTPONE unreachable ; immediate restrict
   
 : ?EXIT ( -- )  : ?EXIT ( -- )
      POSTPONE if POSTPONE exit POSTPONE then ; immediate restrict       POSTPONE if POSTPONE exit POSTPONE then ; immediate restrict
Line 797  Avariable leave-sp  leave-stack 3 cells Line 799  Avariable leave-sp  leave-stack 3 cells
 \ information through global variables), but they are useful for dealing  \ information through global variables), but they are useful for dealing
 \ with existing/independent defining words  \ with existing/independent defining words
   
 defer header  defer (header)
   defer header     ' (header) IS header
   
 : name,  ( "name" -- )  : name,  ( "name" -- )
     name c@      name
     dup $1F u> -&19 and throw ( is name too long? )      dup $1F u> -&19 and throw ( is name too long? )
     1+ chars allot align ;      dup c,  here swap chars  dup allot  move  align ;
 : input-stream-header ( "name" -- )  : input-stream-header ( "name" -- )
     \ !! this is f83-implementation-dependent      \ !! this is f83-implementation-dependent
     align here last !  -1 A,      align here last !  -1 A,
Line 810  defer header Line 813  defer header
   
 : input-stream ( -- )  \ general  : input-stream ( -- )  \ general
 \ switches back to getting the name from the input stream ;  \ switches back to getting the name from the input stream ;
     ['] input-stream-header IS header ;      ['] input-stream-header IS (header) ;
   
 ' input-stream-header IS header  ' input-stream-header IS (header)
   
 \ !! make that a 2variable  \ !! make that a 2variable
 create nextname-buffer 32 chars allot  create nextname-buffer 32 chars allot
Line 830  create nextname-buffer 32 chars allot Line 833  create nextname-buffer 32 chars allot
     dup $1F u> -&19 and throw ( is name too long? )      dup $1F u> -&19 and throw ( is name too long? )
     nextname-buffer c! ( c-addr )      nextname-buffer c! ( c-addr )
     nextname-buffer count move      nextname-buffer count move
     ['] nextname-header IS header ;      ['] nextname-header IS (header) ;
   
 : noname-header ( -- )  : noname-header ( -- )
     0 last !      0 last !
Line 838  create nextname-buffer 32 chars allot Line 841  create nextname-buffer 32 chars allot
   
 : noname ( -- ) \ general  : noname ( -- ) \ general
 \ the next defined word remains anonymous. The xt of that word is given by lastxt  \ the next defined word remains anonymous. The xt of that word is given by lastxt
     ['] noname-header IS header ;      ['] noname-header IS (header) ;
   
 : lastxt ( -- xt ) \ general  : lastxt ( -- xt ) \ general
 \ xt is the execution token of the last word defined. The main purpose of this word is to get the xt of words defined using noname  \ xt is the execution token of the last word defined. The main purpose of this word is to get the xt of words defined using noname
Line 1024  Variable warnings  G -1 warnings T ! Line 1027  Variable warnings  G -1 warnings T !
   
 : rehash  ( wid -- )  dup cell+ @ cell+ cell+ @ execute ;  : rehash  ( wid -- )  dup cell+ @ cell+ cell+ @ execute ;
   
 : '    ( "name" -- addr )  name find 0= if drop -&13 bounce then ;  : '    ( "name" -- addr )  name sfind 0= if -&13 bounce then ;
 : [']  ( "name" -- addr )  ' postpone ALiteral ; immediate  : [']  ( "name" -- addr )  ' postpone ALiteral ; immediate
 \ Input                                                13feb93py  \ Input                                                13feb93py
   
Line 1038  Variable warnings  G -1 warnings T ! Line 1041  Variable warnings  G -1 warnings T !
   
 : bell  #bell emit ;  : bell  #bell emit ;
   
 : backspaces  0 ?DO  #bs emit  LOOP ;  \ : backspaces  0 ?DO  #bs emit  LOOP ;
 : >string  ( span addr pos1 -- span addr pos1 addr2 len )  : >string  ( span addr pos1 -- span addr pos1 addr2 len )
   over 3 pick 2 pick chars /string ;    over 3 pick 2 pick chars /string ;
 : type-rest ( span addr pos1 -- span addr pos1 back )  : type-rest ( span addr pos1 -- span addr pos1 back )
Line 1055  Variable warnings  G -1 warnings T ! Line 1058  Variable warnings  G -1 warnings T !
 : back  dup  IF  1- #bs emit  ELSE  #bell emit  THEN 0 ;  : back  dup  IF  1- #bs emit  ELSE  #bell emit  THEN 0 ;
 : forw 2 pick over <> IF  2dup + c@ emit 1+  ELSE  #bell emit  THEN 0 ;  : forw 2 pick over <> IF  2dup + c@ emit 1+  ELSE  #bell emit  THEN 0 ;
   
 Create crtlkeys  Create ctrlkeys
   ] false false back  false  false false forw  false    ] false false back  false  false false forw  false
     ?del  false (ret) false  false (ret) false false      ?del  false (ret) false  false (ret) false false
     false false false false  false false false false      false false false false  false false false false
     false false false false  false false false false [      false false false false  false false false false [
   
   defer everychar
   ' noop IS everychar
   
 : decode ( max span addr pos1 key -- max span addr pos2 flag )  : decode ( max span addr pos1 key -- max span addr pos2 flag )
     everychar
   dup #del = IF  drop #bs  THEN  \ del is rubout    dup #del = IF  drop #bs  THEN  \ del is rubout
   dup bl <   IF  cells crtlkeys + @ execute  EXIT  THEN    dup bl <   IF  cells ctrlkeys + @ execute  EXIT  THEN
   >r 2over = IF  rdrop bell 0 EXIT  THEN    >r 2over = IF  rdrop bell 0 EXIT  THEN
   r> (ins) 0 ;    r> (ins) 0 ;
   
Line 1164  create nl$ 1 c, A c, 0 c, \ gnu includes Line 1171  create nl$ 1 c, A c, 0 c, \ gnu includes
 : include-file ( i*x fid -- j*x )  : include-file ( i*x fid -- j*x )
   push-file  loadfile !    push-file  loadfile !
   0 loadline ! blk off  ['] read-loop catch    0 loadline ! blk off  ['] read-loop catch
   loadfile @ close-file swap    loadfile @ close-file swap 2dup or
   pop-file  throw throw ;    pop-file  drop throw throw ;
   
 create pathfilenamebuf 256 chars allot \ !! make this grow on demand  create pathfilenamebuf 256 chars allot \ !! make this grow on demand
   
Line 1190  create pathfilenamebuf 256 chars allot \ Line 1197  create pathfilenamebuf 256 chars allot \
     0<> -&38 and throw ( file-id u2 )      0<> -&38 and throw ( file-id u2 )
     pathfilenamebuf swap ;      pathfilenamebuf swap ;
   
 : included ( i*x addr u -- j*x )  create included-files 0 , 0 , ( pointer to and count of included files )
   
   : included? ( c-addr u -- f )
       \ true, iff filename c-addr u is in included-files
       included-files 2@ 0
       ?do ( c-addr u addr )
           dup >r 2@ 2over compare 0=
           if
               2drop rdrop unloop
               true EXIT
           then
           r> cell+ cell+
       loop
       2drop drop false ;
   
   : add-included-file ( c-addr u -- )
       \ add name c-addr u to included-files
       included-files 2@ tuck 1+ 2* cells resize throw
       swap 2dup 1+ included-files 2!
       2* cells + 2! ;
   
   : save-string           ( addr1 u -- addr2 u )
       swap >r
       dup allocate throw
       swap 2dup r> -rot move ;
   
   : included1 ( i*x file-id c-addr u -- j*x )
       \ include the file file-id with the name given by c-addr u
     loadfilename 2@ >r >r      loadfilename 2@ >r >r
     open-path-file ( file-id c-addr2 u2 )      save-string 2dup loadfilename 2! add-included-file ( file-id )
     dup allocate throw over loadfilename 2! ( file-id c-addr2 u2 )      ['] include-file catch
     drop loadfilename 2@ move      r> r> loadfilename 2!  throw ;
     include-file      
     \ don't free filenames; they don't take much space  : included ( i*x addr u -- j*x )
     \ and are used for debugging      open-path-file included1 ;
     r> r> loadfilename 2! ;  
   : required ( i*x addr u -- j*x )
       \ include the file with the name given by addr u, if it is not
       \ included already. Currently this works by comparing the name of
       \ the file (with path) against the names of earlier included
       \ files; however, it would probably be better to fstat the file,
       \ and compare the device and inode. The advantages would be: no
       \ problems with several paths to the same file (e.g., due to
       \ links) and we would catch files included with include-file and
       \ write a require-file.
       open-path-file 2dup included?
       if
           2drop close-file throw
       else
           included1
       then ;
   
 \ HEX DECIMAL                                           2may93jaw  \ HEX DECIMAL                                           2may93jaw
   
Line 1208  create pathfilenamebuf 256 chars allot \ Line 1257  create pathfilenamebuf 256 chars allot \
 \ DEPTH                                                 9may93jaw  \ DEPTH                                                 9may93jaw
   
 : depth ( -- +n )  sp@ s0 @ swap - cell / ;  : depth ( -- +n )  sp@ s0 @ swap - cell / ;
   : clearstack ( ... -- )  s0 @ sp! ;
   
 \ INCLUDE                                               9may93jaw  \ INCLUDE                                               9may93jaw
   
 : include  ( "file" -- )  : include  ( "file" -- )
   bl word count included ;    name included ;
   
   : require  ( "file" -- )
     name required ;
   
 \ RECURSE                                               17may93jaw  \ RECURSE                                               17may93jaw
   
Line 1289  DEFER DOERROR Line 1342  DEFER DOERROR
   ELSE    ELSE
      type ." :" dec.       type ." :" dec.
      cr dup 2over type cr drop       cr dup 2over type cr drop
      nip -trailing ( line-start index2 )       nip -trailing 1- ( line-start index2 )
      0 >r  BEGIN       0 >r  BEGIN
                   1- 2dup + c@ bl >  WHILE                    2dup + c@ bl >  WHILE
                   r> 1+ >r  dup 0<  UNTIL  THEN  1+                    r> 1+ >r  1- dup 0<  UNTIL  THEN  1+
      ( line-start index1 )       ( line-start index1 )
      typewhite       typewhite
      r> 1 max 0 ?do \ we want at least one "^", even if the length is 0       r> 1 max 0 ?do \ we want at least one "^", even if the length is 0
Line 1377  Variable argc Line 1430  Variable argc
     2drop      2drop
     here r> tuck - 2 cells / ;      here r> tuck - 2 cells / ;
   
 : ">tib  ( addr len -- )  dup #tib ! >in off tib swap move ;  
   
 : do-option ( addr1 len1 addr2 len2 -- n )  2swap  : do-option ( addr1 len1 addr2 len2 -- n )  2swap
   2dup s" -e"        compare  0= >r    2dup s" -e"        compare  0= >r
   2dup s" -evaluate" compare  0= r> or    2dup s" -evaluate" compare  0= r> or
   IF  2drop ">tib interpret  2 EXIT  THEN    IF  2drop dup >r ['] evaluate catch
         ?dup IF  dup >r DoError r> negate (bye)  THEN
         r> >tib +!  2 EXIT  THEN
   ." Unknown option: " type cr 2drop 1 ;    ." Unknown option: " type cr 2drop 1 ;
   
 : process-args ( -- )  : process-args ( -- )  >tib @ >r
     argc @ 1      argc @ 1
     ?DO      ?DO
         I arg over c@ [char] - <>          I arg over c@ [char] - <>
Line 1394  Variable argc Line 1447  Variable argc
         ELSE          ELSE
             I 1+ arg  do-option              I 1+ arg  do-option
         THEN          THEN
     +LOOP ;      +LOOP
       r> >tib ! ;
   
   Defer 'cold ' noop IS 'cold
   
 : cold ( -- )  : cold ( -- )
     pathstring 2@ process-path pathdirs 2!      pathstring 2@ process-path pathdirs 2!
       'cold
     argc @ 1 >      argc @ 1 >
     IF      IF
         ['] process-args catch ?dup          ['] process-args catch ?dup
Line 1409  Variable argc Line 1466  Variable argc
     ." GNU Forth 0.0alpha, Copyright (C) 1994 Free Software Foundation, Inc." cr      ." GNU Forth 0.0alpha, Copyright (C) 1994 Free Software Foundation, Inc." cr
     ." GNU Forth comes with ABSOLUTELY NO WARRANTY; for details type `license'" cr      ." GNU Forth comes with ABSOLUTELY NO WARRANTY; for details type `license'" cr
     ." Type `bye' to exit"      ." Type `bye' to exit"
     quit ;      loadline off quit ;
   
 : license ( -- ) cr  : license ( -- ) cr
  ." This program is free software; you can redistribute it and/or modify" cr   ." This program is free software; you can redistribute it and/or modify" cr
Line 1428  Variable argc Line 1485  Variable argc
   
 : boot ( path **argv argc -- )  : boot ( path **argv argc -- )
   argc ! argv ! cstring>sstring pathstring 2!  main-task up!    argc ! argv ! cstring>sstring pathstring 2!  main-task up!
   sp@ dup s0 ! $10 + >tib ! rp@ r0 !  fp@ f0 !  cold ;    sp@ dup s0 ! $10 + >tib ! #tib off >in off
     rp@ r0 !  fp@ f0 !  cold ;
   
 : bye  script? 0= IF  cr  THEN  0 (bye) ;  : bye  script? 0= IF  cr  THEN  0 (bye) ;
   

Removed from v.1.19  
changed lines
  Added in v.1.27


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>