Be careful using global variables in a recursive program.
Your compiler needs to be able to handle structures like
if (a) {
if (b) {
do thing1();
} else {
do thing2();
}
} else {
...
}
In this case, compiling the inner
if/else needs jump labels for the if part, else part and endif. These labels must not interfere the outer
if/else jump labels.
Another problematic case can be in expressions like
f(a, g(b), c)
where a call is encountered while compiling a call. The
nArgs for the call to
g must not interfere with the
nArgs for the call to
f.
The solution to these problems is to use function local variables for things like the if labels and
nArgs.
Note that this does not require you you to inline things like parsing
expressionList. The return value from a function is effectively a local variable since it is on the stack.
// in compileSubroutineCall
name = ...;
...
nArgs = compileExpressionList();
...
vmWriter.writeCall(name, nArgs);
Since the XML output is just a useful side effect of the compiler, it is better to change the signatures of a few of the compileXxx() routines if required to improve the readability (and correctness!) of the main objective.
--Mark