>>I've seen discussions on this deficiency (IMHO at least) in the
>>ANS standard in the c.l.f archives but they all seem rather
>>inconclusive. The fundamental problem is that all words, such as
>>INCLUDED, that change the input source also invoke the Forth
>>text interpreter and there is no standard way of overcoming
>>this.
>
> Yes. To overcome this problem, Gforth provides
>
> |execute-parsing-file ( i*x fileid xt - j*x )
> | Make fileid the current input source, execute xt `( i*x -- j*x )',
> |then restore the previous input source.
>
> I find that pretty conclusive.
>
I was aware of EXECUTE-PARSING but not EXECUTE-PARSING-FILE.
Initially I thought I could use EXECUTE-PARSING to solve the
problem, but I was wrong.
I think that EXECUTE-PARSING-FILE provides a partial solution,
it is an ingenious way of achieving an equivalent to my solution
2 in the original post but with the advantage of not having to
insert the word to be executed at the start of the file. The
reason I say it is a partial solution is because you have to
define a word to parse and process the file, if another file is
to be processed by nesting, that word may have to be called
again so it may need to be re-entrant. Also it precludes a
design where an application opens a file source and then returns
to whatever called it to parse and process the file. These
are fairly minor considerations but EXECUTE-PARSING-FILE does
constrain a program design somewhat.
>>To overcome this problem I've been experimenting with a couple
>>of definitions called FILE-SOURCE and CLOSE-SOURCE:
>
>>FILE-SOURCE ( fileid -- ) is like INCLUDE-FILE but does not
>>invoke the Forth text interpreter i.e. it saves the current
>>input source specification and makes the file specified by
>>fileid the new input source. Hence REFILL can be used to read
>>the file from the file position existing at the time FILE-SOURCE
>>is called.
>
>>CLOSE-SOURCE ( -- ) simply closes the current input source and
>>restores the previous one.
>
> Until Jonah Thomas came up with the glorious idea that lead to
> EXECUTE-PARSING and EXECUTE-PARSING-FILE, I was also thinking along
> similar lines. However, the problem with such words is that they do
> not fit in the usual nesting of INCLUDED, EVALUATE and LOAD.
I don't understand why you say this. As FILE-SOURCE simply
stacks another input source and switches to a new input source,
I see no reason, in principle, why it couldn't fit into the
scheme of things. To take a simple example suppose the system is
in interpret mode and the user types in s" filename" FILE-
SOURCE. Having executed FILE-SOURCE control returns to the text
interpreter which could simply use the stream attached to the
new input source (of course this assumes that the different
input sources use the same text interpreter which, in practice
for a given system, may not be true, but I'm talking in
principle). While interpreting the file there is no reason why
another file could not be INCLUDED or a string EVALUATEd, when
they finished the file source could be returned to. When the
file source reached the end or CLOSE-SOURCE was executed, the
system would return to the original input source. In this simple
example it would therefore behave much like INCLUDE-FILE. Are
there any conceptual problems with this?
Words
> like EXECUTE-PARSING and EXECUTE-PARSING-FILE avoid this problem.
>
>>: xyz ( caddr u -- )
>> r/o open-file throw file-source cr
>> begin refill while source type cr repeat
>> close-source
>>;
>
> The equivalent using EXECUTE-PARSING-FILE:
>
> : xyz-helper ( -- )
> cr begin refill while source type cr repeat ;
>
> : xyz ( c-addr u -- )
> r/o open-file throw ['] xyz-helper execute-parsing-file ;
>
I can't see a way to define FILE-SOURCE using ANS Forth only,
presumably this is also true for EXECUTE-PARSING-FILE?
As this topic is perceived as a problem by more than one person
perhaps we should consider standardising a solution, if it was
the EXECUTE-PARSING-FILE solution I would prefer a better name.
Gerry