jvale wrote
We're completing the second half of the Jack compiler (project 11) where we'll output VM code. However, I am still not quite sure where to start. I am not expecting the project solution but instead, wanting to know if the XML code that we generated in chapter 10 will ever be used in this project. I mean, when building the symbol tables, are we getting the identifiers, class names, etc... from the XML output or straight from the .jack files that we feed into the Syntax Analyzer? Thanks.
The first thing I did was add a command line option -x so that my chapter 11 compiler could still output the XMLfile as an option. (This can be helpful if you break something in the overall structure of the compile engine, which I did several times...) The default is, of course, not to output the XMLfile.
All my XML was written using functions named _WriteXml and _WriteXmlTag so it was easy to add the option.
For the most part, all I had to do to the various CompileEngine.CompileWhatever functions was to add calls to the appropriate SymbolTable and VMWriter functions. For instance, here's the diff between my project 10 and project 11 CompileExpression function:
def _CompileExpression(self):
"""
Compiles <expression> :=
<term> (op <term>)*
The tokenizer is expected to be positioned on the expression.
ENTRY: Tokenizer positioned on the expression.
EXIT: Tokenizer positioned after the expression.
"""
self._WriteXmlTag('<expression>\n')
self._CompileTerm()
+ # first term on stack
while (self.tokenizer.TokenType() == TK_SYMBOL and \
self.tokenizer.Symbol() in '+-*/&|<>='):
+ operator = self.tokenizer.Symbol()
self._WriteXml('symbol', self.tokenizer.Symbol())
self._NextToken()
self._CompileTerm()
+ # next term on stack
+
+ if operator == '+':
+ self.vmWriter.WriteArithmetic(OP_ADD)
+ elif operator == '-':
+ self.vmWriter.WriteArithmetic(OP_SUB)
+ elif operator == '*':
+ self.vmWriter.WriteCall('Math.multiply', 2)
+ elif operator == '/':
+ self.vmWriter.WriteCall('Math.divide', 2)
+ elif operator == '&':
+ self.vmWriter.WriteArithmetic(OP_AND)
+ elif operator == '|':
+ self.vmWriter.WriteArithmetic(OP_OR)
+ elif operator == '<':
+ self.vmWriter.WriteArithmetic(OP_LT)
+ elif operator == '>':
+ self.vmWriter.WriteArithmetic(OP_GT)
+ elif operator == '=':
+ self.vmWriter.WriteArithmetic(OP_EQ)
+ # result on stack
self._WriteXmlTag('</expression>\n')
--Mark