home *** CD-ROM | disk | FTP | other *** search
FORTH Source | 2006-10-19 | 4.5 KB | 307 lines |
-
- \
- \ Interpreter
- \
-
- [IFUNDEF] (
- : (
- $39 parse 2drop
- ; immediate
- [THEN]
-
- [IFUNDEF] >IN
- user >IN
- [THEN]
-
- [IFUNDEF] CHAR
- : CHAR ( -- c )
- bl (parse-word)
- drop c@
- ;
- [THEN]
-
- [IFUNDEF] REFILL
- : REFILL ( -- flag )
-
- \ Attempt to fill the input buffer from the input source, returning a true flag if successful.
- \
- \ When the input source is the user input device, attempt to receive input into the terminal input buffer. If successful,
- \ make the result the input buffer, set >IN to zero, and return true. Receipt of a line containing no characters is
- \ considered successful. If there is no input available from the current input source, return false.
- \
- \ When the input source is a string from EVALUATE, return false and perform no other action.
-
- source-id
- dup -1 = if \ evaluate string
- drop false \ end.
- else ?dup 0= if \ user input device
- (tib0) $100 accept #tib !
- (tib0) >tib !
- 0 >in !
- bl emit
- true
- else
- ( fileid )
- (tib0) $100 rot read-line s" file read error" (abort")
- if
-
- \ ." [" (tib0) over type ." ]" cr
-
- #tib !
- (tib0) >tib !
- 0 >in !
- true
- else
- \ ." end of file" cr
- drop false
- then
- then then
- ;
- [THEN]
-
- [IFUNDEF] QUERY
- \ : QUERY
- \ ;
- [THEN]
-
- [IFUNDEF] RESTORE-INPUT
- : RESTORE-INPUT ( xn ... x1 n -- )
- 6 <> abort" invalid restore-input"
- >in !
- blk !
- #tib ! >tib !
- loadline ! loadfile !
- ;
- [THEN]
-
- [IFUNDEF] SAVE-INPUT
- : SAVE-INPUT ( -- xn ... x1 n )
- loadfile @ loadline @
- >tib @ #tib @
- blk @
- >in @
- 6
- ;
- [THEN]
-
- [IFUNDEF] SOURCE-ID
- : SOURCE-ID
- loadline @ 0< if
- -1
- else
- loadfile @
- then
- ;
- [THEN]
-
- [IFUNDEF] TIB
- User >tib
- : TIB
- >tib @
- ;
- [THEN]
-
-
- [IFUNDEF] INTERPRET
-
- \ INTERPRETER
- \ ===========
-
- \ Source state is represented as follows:
- \ If blk=0, 'source-id' is 0 for keyboard, -1 for evaluate string, >0 for text file.
- \ else blk=blk # for source.
- \ For non-block stuff, we use loadfile/loadline to keep track of file source,
- \ and >tib/#tib for all input strings.
- \ loadfile=0 for user input, loadline<0 for evaluate string.
-
- User loadfile
- User loadline
-
- \ Push the input state.
- : <input ( xn ... x1 n -- R: xn ... x1 n )
- r>
- loadfile @ >r loadline @ >r
- >tib @ >r #tib @ >r
- blk @ >r
- >in @ >r
- >r
- ;
-
- : input>
- r>
- r> >in !
- r> blk !
- r> #tib ! r> >tib !
- r> loadline ! r> loadfile !
- >r
- ;
-
- : (>c) ( caddr u naddr -- )
- \ make counted string at naddr
- 2dup c! \ set length byte
- 1+ swap cmove> \ move data
- ;
-
- : (lookup) ( c-addr u -- 0 | nfa 1|-1 )
- here (>c) \ make counted string + NFA
- \ context @ @ (find) dup 0= if ...
-
- [ 1 [if] ]
- here latest \ ( here nfa )
- (find)
- [ [else] ]
- here find dup >r if xt>nfa else drop then r>
-
- [ [then] ]
- ;
-
- : ?stack
- depth 0< if
- ." stack empty!" cr
- abort
- then
- ;
-
- : huh? ( caddr -- )
- count type space
- ." undefined" cr
- ;
-
- \ Interpret counted string as number,
- \ and store decimal point location in DPL.
-
- User dpl
- : number ( addr -- ud )
- \ .s
- 0.0 rot count
-
- \ check for base conversion
- base @ >r \ save original base
- over c@ [char] $ = if
- hex (skip) \ use hex for '$'
- else over c@ [char] & = if
- decimal (skip) \ use decimal for '&'
- then then
-
- \ see if first char is '-'
- over c@ [char] - = dup
- >r \ store sign flag
- if (skip) then
-
- -1 dpl !
-
- \ .s
- >number
- dup if \ any invalid chars?
- over c@ $2E = if \ did we stop at '.'?
- over dpl ! \ don't store offset... too much work ;)
- (skip) \ skip '.'
- >number
- then
- dup if
- here huh? 2drop 2drop quit \ error
- then
- then
- 2drop
-
- r> \ sign flag
- if dnegate then
-
- r> base ! \ original base
- \ .s
- ;
-
- : interpreter
- \ ( i*x c-addr u -- j*x )
- \
- \ Interpret one word
-
- (lookup) \ ( 0 | nfa 1 )
- if
- dup nfa>imm? 0=
- state @ and \ compiling and not immediate?
- if
- nfa>xt compile,
- else
- nfa>xt execute
- then
- else
- here number dpl @ 1+ if
- postpone dliteral
- else
- d>s postpone literal
- then
- then
- ;
-
- : interpret
- begin
- ?stack
- bl (parse-word)
- dup
- while
- interpreter
- repeat
- 2drop
- ;
-
- : EVALUATE ( i*x c-addr u -- j*x )
- <input
- -1 loadline !
- 0 loadfile !
- 0 blk !
- #tib ! >tib !
- 0 >in !
- interpret
- input>
- ;
- [THEN]
-
- [IFUNDEF] QUIT
-
- : QUIT
- begin
- (clrsrc)
- postpone [
- rp0 @ rp!
- .s cr
- begin
- refill
- while
- interpret
-
- \ print comments only when using user input
- source-id 0= if
- state @ if
- cr
- else
- ." ok" .s
- then
- cr
- then
- repeat
- again
- ;
- [THEN]
-
- [IFUNDEF] SOURCE
- : SOURCE ( -- caddr u )
- blk @ ?dup if
- 0 chars/block \ block chars/block \ !!!
- else
- >tib @ #tib @
- then
- ;
- [THEN]
-
- [IFUNDEF] [CHAR]
- : [CHAR]
- state @ if
- postpone [char]
- else
- bl parse drop c@
- then
- ;
- [THEN]
-
-