> On Mon, 2008-01-21 at 17:15 -0500, Tom Breton (Tehom) wrote:
>
>> I'm going to look at it further. I'm afraid that the fix may require
>> splitting the top-level case OP_T0LVL, ie adding another operator in
>> op-defines.h That's more adventurous than I would prefer in a project
>> like this, but making it load right is important.
I have some semblance of an answer now. The hairiest problem is that
inchar can be called after it has encountered EOF but before the read
operators have reacted, for instance within "token" after "skipspace"
encounters EOF.
This can cause input to wrongly try to resume reading the first file while
still parsing the second, and if it reads past the end of that too, it
will call file_pop much too early.
Also, file_pop has no way to communicate that it has popped past the first
file, since setting sc->file_i to -1 causes problems (in fact, segfaults).
Several pieces of code, for instance some contingent calls to OP_QUIT,
try to distinguish true quit from EOF on load, but lacking the actual
information, they guess on the basis of whether loadport is the same as
inport.
And as Ray showed, load wasn't causing evals. It appeared to be, but only
because the real top-level loop *outside* of load handled those evals.
These problems somewhat cancelled each other, but caused the subtle bugs
reported.
My code is in a bit of a messy state right now, but I have Ray's example
and my own doing the right thing. I'll clean it up and commit it.
Basically what I'm doing is:
Change the logic of OP_T0LVL so that each call to load has its own read
loop which ends when the file has been read, and interactive top level is
different.
Add to scheme a flag (top_EOF) indicating whether it has seen EOF for the
topmost file.
Make all the direct and indirect calls to inchar check for EOF and react
accordingly.
> That will almost certainly be required. While you are there, check that
> OP_T0LVL isn't resetting the eval stack under the (mistaken) assumption
> that LOAD is being run from top level. At one point there was an error
> of this form in the logic of the machine. It may have subsequently been
> fixed, or I may be mis-recollecting where it was.
Yes, it was, and since I have to change OP_T0LVL anyways, I'll fix it.
> However, note that there is an inherent ambiguity about what LOAD means
> when it is called from any place that is not top level. Specifically:
> the LOAD will internally execute a REPL loop, and it is not obvious what
> environment that REPL loop runs in? In particular, does it's environment
> (if not specified explicitly as an argument to LOAD) include any
> non-globals that were bound in the procedure calling LOAD?
>
> I don't know the answer, and the standard does not take a position.
I don't know, but what makes sense to me is to use the environment load
was called in.
Tom
|