The text interpreter reads from the input stream, which can come from
several sources (see Input Sources). Some words, in particular
defining words, but also words like '
, read parameters from the
input stream instead of from the stack.
Such words are called parsing words, because they parse the input stream. Parsing words are hard to use in other words, because it is hard to pass program-generated parameters through the input stream. They also usually have an unintuitive combination of interpretation and compilation semantics when implemented naively, leading to various approaches that try to produce a more intuitive behaviour (see Combined Words).
It should be obvious by now that parsing words are a bad idea. If you want to implement a parsing word for convenience, also provide a factor of the word that does not parse, but takes the parameters on the stack. To implement the parsing word on top if it, you can use the following words:
parse
( xchar "ccc<xchar>" – c-addr u ) core-ext,xchar-ext “parse”
Parse ccc, delimited by xchar, in the parse area. c-addr u specifies the parsed string within the parse area. If the parse area was empty, u is 0.
string-parse
( c-addr1 u1 "ccc<string>" – c-addr2 u2 ) gforth-1.0 “string-parse”
Parse ccc, delimited by the string c-addr1 u1, in the parse area. c-addr2 u2 specifies the parsed string within the parse area. If the parse area was empty, u2 is 0.
parse-name
( "name" – c-addr u ) core-ext “parse-name”
Get the next word from the input buffer
parse-word
( – c-addr u ) gforth-obsolete “parse-word”
old name for parse-name
; this word has a conflicting
behaviour in some other systems.
name
( – c-addr u ) gforth-obsolete “name”
old name for parse-name
word
( char "<chars>ccc<char>– c-addr ) core “word”
We recommend to use parse-name
instead of word
.
Skip leading delimiters. Parse ccc, delimited by
char, in the parse area. c-addr is the address of a
transient region containing the parsed string in
counted-string format. If the parse area was empty or
contained no characters other than delimiters, the resulting
string has zero length. A program may replace characters within
the counted string. OBSOLESCENT: the counted string has a
trailing space that is not included in its length.
refill
( – flag ) core-ext,block-ext,file-ext “refill”
Attempt to fill the input buffer from the input source. When
the input source is the user input device, attempt to receive
input into the terminal input device. If successful, make the
result the input buffer, set >IN
to 0 and return true;
otherwise return false. When the input source is a block, add 1
to the value of BLK
to make the next block the input
source and current input buffer, and set >IN
to 0;
return true if the new value of BLK
is a valid block
number, false otherwise. When the input source is a text file,
attempt to read the next line from the file. If successful,
make the result the current input buffer, set >IN
to 0
and return true; otherwise, return false. A successful result
includes receipt of a line containing 0 characters.
If you have to deal with a parsing word that does not have a
non-parsing factor, you can use execute-parsing
to pass a
string to it:
execute-parsing
( ... addr u xt – ... ) gforth-0.6 “execute-parsing”
Make addr u the current input source, execute xt (
... -- ... )
, then restore the previous input source.
Example:
5 s" foo" ' constant execute-parsing \ equivalent to 5 constant foo
A definition of this word in Standard Forth is provided in compat/execute-parsing.fs.
If you want to run a parsing word on a file, the following word should help:
execute-parsing-file
( i*x fileid xt – j*x ) gforth-0.6 “execute-parsing-file”
Make fileid the current input source, execute xt ( i*x
-- j*x )
, then restore the previous input source.