On page 8 of Modern Compiler Construction in Java, Appel states that:
displays the values of all the expressions, evaluated left to right, separated by spaces, terminated by a newline.
A problem arises when ei contains a print statement. (An expression can be an EseqExp, which contains statements.) In that case, the semantics of the print statement seem to require that the output from the print statement inside ei must occur on a previous line, and not be embedded in the line due to the current print statement.
Since the expressions are evaluated left to right, their values must be saved until the end of the print statement and then output as a single line of text. The obvious data structure to use for saving the values is a vector of integers. When the end of the print statement is reached, an iterator can be used to retrieve the values in the order in which they were inserted:
This macro is invoked in definition 28.
void Interpreter::VisitPrintStm(PrintStm* node)
{ vector<int> line;
vector<int>::iterator i;
Compute all of the values on the print line[19]
for (i = line.begin(); i != line.end(); i++) cout << *i << ' ';
cout << '\n';
}
The expressions whose values are to be printed are not directly available at the PrintStm node. They appear only as children of PairExpList and LastExpList nodes. Thus the interpreter must use a stack to pass a pointer to line down through the tree to the VisitPairExpList and VisitLastExpList method invocations:
This macro is invoked in definition 11.
stack<vector<vector<int>* > > PrintLine;
Note that if there is a print statement nested in the child of a print statement, the interpreter for that print statement will create and push a new vector before proceeding to evaluate its own child. Moreover, the complete line for the nested statement will be output before any of the elements of the line for the outer statement are printed.
This macro is invoked in definition 17.
PrintLine.push(&line); (node->Child1())->Accept(this); PrintLine.pop();
Each expression value in the print statement's expression list is simply attached to the current print line:
This macro is invoked in definition 28.
void Interpreter::VisitPairExpList(PairExpList* node)
{ (node->Child1())->Accept(this);
(PrintLine.top())->push_back(ExpValues.top()); ExpValues.pop();
(node->Child2())->Accept(this);
}
void Interpreter::VisitLastExpList(LastExpList* node)
{ (node->Child1())->Accept(this);
(PrintLine.top())->push_back(ExpValues.top()); ExpValues.pop();
}