by booting up multiple instancees of saxon, waiting for a signal
This doesn't really help much, since most of our tests are very small
however, it does lower the overall boot time (assuming travis can do
real concurrency)
Atoms still need some ironing out, something is not updating them
properly
Also unknown is an issue where `def!` is not updating the env, probably
related to the above problem
Issue: yanking out the replEnv from closures has an adverse effect in
that symbols meant to be captured from it will not be captured
We could get around this by copying all the used symbols, but
find-all-lexically-bound-symbols is quite complex
Implementations don't generally deliberately emit CR, so any CR we see
was introduced either by the host language runtime or the OS terminal
driver, neither of which we're trying to test.
Some of the complexity of runtest is in the way that it insists on
checking whether the implementation managed to echo its input line
correctly. This isn't really an important part of the implementation,
though, and when using friendly line-editing libraries the echoing can
often end up containing escape sequences. Simplify things by just
assuming that anything up to the first newline is our input being echoed
back.
This also means that various pre-processing of input is no longer
required.
PostScript's exception handling doesn't restore the dictionary or
operand stacks to the state they were in when the "stopped" operator
started, so mal's EVAL needs to do that itself. To do this, it records
the current height of the stacks, but of course it does that in a
dictionary. This means that when catching at exception, it relies on
the highest instance of "dictcnt" on the dictionary stack being the
correct one. EVAL, however, was failing to restore the dictionary stack
at the right time.
For instance, conside this code (from the tests):
(try* (try* (throw "e1") (catch* e (throw "e2"))) (catch* e "c2"))
Each "try*" clause saves "dictcnt" into a dictionary on the dictionary
stack. When the inner "catch*" clause fires, it pops the dictionary and
operand stacks to the correct point, but then calls the second "throw"
with the wrong value of "dictcnt" still visible. The result is that the
"catch*" clause ends up running with the wrong value of "dictcnt" and
restoring the stacks to the wrong place, essentially executing the
_inner_ "catch*" clause again, whereupon the error doesn't get caught
because there's no "stopped" left on the PostScript execution stack.
The fix is to add another dictionary that's just used to hold "dictcnt"
and "stackcnt", and to pop that from the dictionary stack as soon as the
stacks have been restored (or when it becomes unnecessary because the
"try*" clause has returned normally).
When implementing exceptions on top of longjmp() or similar, it's
necessary to make sure that exception handlers get properly restored
after the try* clause, and none of the existing step 9 tests covered
this.
There are two cases covered here: throwing an exception after a
successful try*, and throwing and exception from within a catch*. In
both cases we make sure that an outer catch* does its job.