Annotation of gforth/kernel/input.fs, revision 1.2

1.1       pazsan      1: \ Input handling (object oriented)                      22oct00py
                      2: 
                      3: \ Copyright (C) 2000 Free Software Foundation, Inc.
                      4: 
                      5: \ This file is part of Gforth.
                      6: 
                      7: \ Gforth is free software; you can redistribute it and/or
                      8: \ modify it under the terms of the GNU General Public License
                      9: \ as published by the Free Software Foundation; either version 2
                     10: \ of the License, or (at your option) any later version.
                     11: 
                     12: \ This program is distributed in the hope that it will be useful,
                     13: \ but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14: \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15: \ GNU General Public License for more details.
                     16: 
                     17: \ You should have received a copy of the GNU General Public License
                     18: \ along with this program; if not, write to the Free Software
                     19: \ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
                     20: 
                     21: \ input handling structure:
                     22: 
                     23: | : input-method ( m "name" -- m' )  Create dup , cell+
                     24: DOES> ( ... -- ... ) @ current-input @ @ + perform ;
                     25: | : input-var ( v size "name" -- v' )  Create  over , +
                     26: DOES> ( -- addr ) @ current-input @ + ;
                     27: 
                     28: 0
                     29: input-method source ( -- 0 | -1 | fileid ) \ core-ext,file source-i-d
                     30:     \G Return 0 (the input source is the user input device), -1 (the
                     31:     \G input source is a string being processed by @code{evaluate}) or
                     32:     \G a @i{fileid} (the input source is the file specified by
                     33:     \G @i{fileid}).
                     34: input-method refill ( -- flag ) \ core-ext,block-ext,file-ext
                     35:     \G Attempt to fill the input buffer from the input source.  When
                     36:     \G the input source is the user input device, attempt to receive
                     37:     \G input into the terminal input device. If successful, make the
                     38:     \G result the input buffer, set @code{>IN} to 0 and return true;
                     39:     \G otherwise return false. When the input source is a block, add 1
                     40:     \G to the value of @code{BLK} to make the next block the input
                     41:     \G source and current input buffer, and set @code{>IN} to 0;
                     42:     \G return true if the new value of @code{BLK} is a valid block
                     43:     \G number, false otherwise. When the input source is a text file,
                     44:     \G attempt to read the next line from the file. If successful,
                     45:     \G make the result the current input buffer, set @code{>IN} to 0
                     46:     \G and return true; otherwise, return false.  A successful result
                     47:     \G includes receipt of a line containing 0 characters.
                     48: input-method source-id ( -- 0 | -1 | fileid ) \ core-ext,file source-i-d
                     49:     \G Return 0 (the input source is the user input device), -1 (the
                     50:     \G input source is a string being processed by @code{evaluate}) or
                     51:     \G a @i{fileid} (the input source is the file specified by
                     52:     \G @i{fileid}).
                     53: | input-method (save-input) ( -- x1 .. xn n ) \ gforth
                     54: | input-method (restore-input) ( x1 .. xn n -- ) \ gforth
                     55: drop
                     56: 
                     57: cell \ the first cell points to the method table
                     58: cell input-var >in \ core to-in
                     59:     \G @code{input-var} variable -- @i{a-addr} is the address of a
                     60:     \G cell containing the char offset from the start of the input
                     61:     \G buffer to the start of the parse area.
                     62: cell input-var #tib \ core-ext number-t-i-b
                     63:     \G @code{input-var} variable -- @i{a-addr} is the address of a
                     64:     \G cell containing the number of characters in the terminal input
                     65:     \G buffer. OBSOLESCENT: @code{source} superceeds the function of
                     66:     \G this word.
                     67: cell input-var max#tib \ gforth max-number-t-i-b
                     68:     \G @code{input-var} variable -- This cell contains the maximum
                     69:     \G size of the current tib.
                     70: cell input-var old-input \ gforth
                     71:     \G @code{input-var} variable -- This cell contains the pointer to
                     72:     \G the previous input buffer
                     73: cell input-var loadline \ gforth
                     74:     \G @code{input-var} variable -- This cell contains the line that's
                     75:     \G currently loaded from
                     76: has? file [IF]
                     77: cell input-var loadfile \ gforth
                     78:     \G @code{input-var} variable -- This cell contains the file the
                     79:     \G input buffer is associated with (0 if none)
                     80: cell input-var blk \ block
                     81:     \G @code{input-var} variable -- This cell contains the current
                     82:     \G block number
                     83: cell input-var #fill-bytes \ gforth
                     84:     \G @code{input-var} variable -- number of bytes read via
                     85:     \G (read-line) by the last refill
                     86: cell input-var loadfilename# \ gforth
                     87:     \G @code{input-var} variable -- This cell contains the index into
                     88:     \G the file name array and allows to identify the loaded file.
                     89: [THEN]
                     90: 0 input-var tib
                     91: 
                     92: Constant tib+
                     93: 
                     94: \ terminal input implementation
                     95: 
                     96: :noname  1 <> -12 and throw >in ! ;
                     97:                        \ restore-input
                     98: :noname  >in @ 1 ;     \ save-input
1.2     ! pazsan     99: ' false                \ source-id
1.1       pazsan    100: :noname  tib max#tib @ accept #tib !
                    101:     >in off true 1 loadline +! ;     \ refill
                    102: :noname  tib #tib @ ;  \ source
                    103: 
                    104: | Create terminal-input   A, A, A, A, A,
1.2     ! pazsan    105: :noname  tib @ #tib @ ; \ source
1.1       pazsan    106: | Create evaluate-input
1.2     ! pazsan    107:     A,                  \ source
        !           108:     ' false A,          \ refill
        !           109:     ' true A,           \ source-id
        !           110:     terminal-input 3 cells + @ A, \ terminal::restore-input
        !           111:     terminal-input 4 cells + @ A, \ terminal::save-input
1.1       pazsan    112: 
                    113: \ file input implementation
                    114: 
                    115: has? file [IF]
                    116: :noname  4 <> -12 and throw
                    117:     loadfile @ reposition-file throw
                    118:     refill 0= -36 and throw \ should never throw
                    119:     loadline ! >in ! ; \ restore-input
                    120: :noname  >in @ sourceline#
                    121:     loadfile @ file-position throw #fill-bytes @ 0 d-
                    122:     4 ;                \ save-input
                    123: :noname  loadfile @ ;  \ source-id
                    124: :noname  tib max#tib @ loadfile @ (read-line) throw #fill-bytes !
                    125:     swap #tib ! >in off 1 loadline +! ;
                    126:                        \ refill
                    127: terminal-input @       \ source -> terminal-input::source
                    128: 
                    129: | Create file-input  A, A, A, A, A,
                    130: [THEN]
                    131: 
                    132: \ push-file, pop-file
                    133: 
                    134: : new-tib ( method n -- ) \ gforth
                    135:     \G Create a new entry of the tib stack, size @i{n}, method table
                    136:     \G @i{method}.
                    137:     dup >r tib+ + dup allocate throw tuck swap 0 fill
                    138:     current-input @ swap current-input ! old-input ! r> max#tib !
                    139:     current-input @ ! ;
                    140: has? file [IF]
                    141: : push-file  ( -- ) \ gforth
                    142:     \G Create a new file input buffer
                    143:     file-input def#tib new-tib ;
                    144: [THEN]
                    145: : pop-file ( throw-code -- throw-code ) \ gforth
                    146:     \G pop and free the current top input buffer
                    147:     dup IF
                    148:        source >in @ sourceline#
                    149:        [ has? file [IF] ] sourcefilename [ [THEN] ]
                    150:        >error
                    151:     THEN
                    152:     current-input @ old-input @ current-input ! free throw ;
                    153: 
                    154: \ save-input, restore-input
                    155: 
                    156: : save-input ( -- x1 .. xn n ) \ core-ext
                    157:     \G The @i{n} entries @i{xn - x1} describe the current state of the
                    158:     \G input source specification, in some platform-dependent way that can
                    159:     \G be used by @code{restore-input}.
                    160:     (save-input) current-input @ swap 1+ ;
                    161: : restore-input ( x1 .. xn n -- flag ) \ core-ext
                    162:     \G Attempt to restore the input source specification to the state
                    163:     \G described by the @i{n} entries @i{xn - x1}. @i{flag} is true if
                    164:     \G the restore fails.  In Gforth with the new input code, it fails
                    165:     \G only with a flag that can be used to throw again; it is also
                    166:     \G possible to save and restore between different active input
                    167:     \G streams. Note that closing the input streams must happen in the
                    168:     \G reverse order as they have been opened, but in between
                    169:     \G everything is allowed.
                    170:     current-input @ >r swap current-input ! 1- dup >r
                    171:     ['] (restore-input) catch
                    172:     dup IF  r> 0 ?DO  nip  LOOP  r> current-input !  EXIT  THEN
                    173:     rdrop rdrop ;
                    174: 
                    175: \ create terminal input block
                    176: 
                    177: : create-input ( -- )
                    178:     \G create a new terminal input
                    179:     terminal-input def#tib new-tib ;
                    180:     ( loadfilename# off ) \ "*the terminal*"
                    181: 
                    182: : evaluate ( addr u -- ) \ core,block
                    183:     \G Save the current input source specification. Store @code{-1} in
                    184:     \G @code{source-id} and @code{0} in @code{blk}. Set @code{>IN} to
                    185:     \G @code{0} and make the string @i{c-addr u} the input source
                    186:     \G and input buffer. Interpret. When the parse area is empty,
                    187:     \G restore the input source specification.
1.2     ! pazsan    188:     evaluate-input cell new-tib
1.1       pazsan    189: [ has? file [IF] ]
                    190:     1 loadfilename# ! \ "*evaluated string*"
                    191: [ [THEN] ]
1.2     ! pazsan    192:     -1 loadline ! #tib ! tib !
1.1       pazsan    193:     ['] interpret catch pop-file throw ;
                    194: 
                    195: \ clear tibstack
                    196: 
                    197: : clear-tibstack ( -- ) \ gforth
                    198:     \G clears the tibstack; if there is none, create the bottom entry:
                    199:     \G the terminal input buffer.
                    200:     current-input @ 0= IF  create-input  THEN
                    201:     BEGIN  old-input @  WHILE  0 pop-file drop  REPEAT ;
                    202: 
                    203: : query ( -- ) \ core-ext
                    204:     \G Make the user input device the input source. Receive input into
                    205:     \G the Terminal Input Buffer. Set @code{>IN} to zero. OBSOLESCENT:
                    206:     \G superceeded by @code{accept}.
                    207:     clear-tibstack  refill drop ;
                    208: 
                    209: \ load a file
                    210: 
                    211: has? file [IF]
                    212: : read-loop ( i*x -- j*x ) \ gforth
                    213:     \G refill and interpret a file until EOF
                    214:     BEGIN  refill  WHILE  interpret  REPEAT ;
                    215: 
                    216: : include-file2 ( i*x wfileid loadfilename# -- j*x )
                    217:     push-file \ dup 2* cells included-files 2@ drop + 2@ type
                    218:     loadfilename# !  loadfile !
                    219:     ['] read-loop catch
                    220:     loadfile @ close-file swap 2dup or
                    221:     pop-file  drop throw throw ;
                    222: 
                    223: : include-file ( i*x wfileid -- j*x )
                    224:     \G Interpret (process using the text interpreter) the contents of
                    225:     \G the file @var{wfileid}.
                    226:     3 include-file2 ;
                    227: [THEN]

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