class CompilationEngine(): def __init__(self, jack_file, xml_file): self._jack_tokenizer = JackTokenizer(jack_file) self._xml_file = xml_file self._xml_text = '' def compile_class(self): self._write_start('class') self._compile_keyword() self._compile_identifier() self._compile_symbol() while self._what_next_token([Keyword.STATIC, Keyword.FIELD]): self.compile_class_var_dec() while self._what_next_token( [Keyword.CONSTRUCTOR, Keyword.FUNCTION, Keyword.METHOD]): self.compile_subroutine_dec() self._compile_symbol() self._write_end('class') def compile_class_var_dec(self): self._write_start('classVarDec') self._compile_keyword() if self._what_next_token([Keyword.INT, Keyword.CHAR, Keyword.BOOLEAN]): self._compile_keyword() elif self._what_next_token_type([Type.IDENTIFIER]): self._compile_identifier() self._compile_identifier() while self._what_next_token([Symbol.COMMA]): self._compile_symbol() self._compile_identifier() self._compile_symbol() self._write_end('classVarDec') def compile_subroutine_dec(self): self._write_start('subroutineDec') self._compile_keyword() if self._what_next_token([Keyword.VOID]): self._compile_keyword() else: if self._what_next_token( [Keyword.INT, Keyword.CHAR, Keyword.BOOLEAN]): self._compile_keyword() elif self._what_next_token_type([Type.IDENTIFIER]): self._compile_identifier() self._compile_identifier() self._compile_symbol() self.compile_parameter_list() self._compile_symbol() self.compile_subroutine_body() self._write_end('subroutineDec') def compile_parameter_list(self): self._write_start('parameterList') if (self._what_next_token([Keyword.INT, Keyword.CHAR, Keyword.BOOLEAN]) or self._what_next_token_type([Type.IDENTIFIER])): if self._what_next_token( [Keyword.INT, Keyword.CHAR, Keyword.BOOLEAN]): self._compile_keyword() elif self._what_next_token_type([Type.IDENTIFIER]): self._compile_identifier() self._compile_identifier() while self._what_next_token([Symbol.COMMA]): self._compile_symbol() if self._what_next_token( [Keyword.INT, Keyword.CHAR, Keyword.BOOLEAN]): self._compile_keyword() elif self._what_next_token_type([Type.IDENTIFIER]): self._compile_identifier() self._compile_identifier() self._write_end('parameterList') def compile_subroutine_body(self): self._write_start('subroutineBody') self._compile_symbol() while self._what_next_token([Keyword.VAR]): self.compile_var_dec() self.compile_statements() self._compile_symbol() self._write_end('subroutineBody') def compile_var_dec(self): self._write_start('varDec') self._compile_keyword() if self._what_next_token([Keyword.INT, Keyword.CHAR, Keyword.BOOLEAN]): self._compile_keyword() elif self._what_next_token_type([Type.IDENTIFIER]): self._compile_identifier() self._compile_identifier() while self._what_next_token([Symbol.COMMA]): self._compile_symbol() self._compile_identifier() self._compile_symbol() self._write_end('varDec') def compile_statements(self): self._write_start('statements') while self._what_next_token([ Keyword.LET, Keyword.IF, Keyword.WHILE, Keyword.DO, Keyword.RETURN ]): if self._what_next_token([Keyword.LET]): self.compile_let() elif self._what_next_token([Keyword.IF]): self.compile_if() elif self._what_next_token([Keyword.WHILE]): self.compile_while() elif self._what_next_token([Keyword.DO]): self.compile_do() elif self._what_next_token([Keyword.RETURN]): self.compile_return() self._write_end('statements') def compile_let(self): self._write_start('letStatement') self._compile_keyword() self._compile_identifier() if self._what_next_token([Symbol.LEFT_BOX_BRACKET]): self._compile_symbol() self.compile_expression() self._compile_symbol() self._compile_symbol() self.compile_expression() self._compile_symbol() self._write_end('letStatement') def compile_if(self): self._write_start('ifStatement') self._compile_keyword() self._compile_symbol() self.compile_expression() self._compile_symbol() self._compile_symbol() self.compile_statements() self._compile_symbol() if self._what_next_token([Keyword.ELSE]): self._compile_keyword() self._compile_symbol() self.compile_statements() self._compile_symbol() self._write_end('ifStatement') def compile_while(self): self._write_start('whileStatement') self._compile_keyword() self._compile_symbol() self.compile_expression() self._compile_symbol() self._compile_symbol() self.compile_statements() self._compile_symbol() self._write_end('whileStatement') def compile_do(self): self._write_start('doStatement') self._compile_keyword() if self._what_next_token([Symbol.LEFT_ROUND_BRACKET], 1): self._compile_identifier() self._compile_symbol() self.compile_expression_list() self._compile_symbol() else: self._compile_identifier() self._compile_symbol() self._compile_identifier() self._compile_symbol() self.compile_expression_list() self._compile_symbol() self._compile_symbol() self._write_end('doStatement') def compile_return(self): self._write_start('returnStatement') self._compile_keyword() if not self._what_next_token([Symbol.SEMI_COLON]): self.compile_expression() self._compile_symbol() self._write_end('returnStatement') def compile_expression(self): self._write_start('expression') self.compile_term() while self._what_next_token([ Symbol.PLUS, Symbol.MINUS, Symbol.MULTI, Symbol.DIV, Symbol.AND, Symbol.PIPE, Symbol.LESS_THAN, Symbol.GREATER_THAN, Symbol.EQUAL ]): self._compile_symbol() self.compile_term() self._write_end('expression') def compile_term(self): self._write_start('term') if self._what_next_token_type([Type.INT_CONST]): self._compile_integer_constant() elif self._what_next_token_type([Type.STRING_CONST]): self._compile_string_constant() elif self._what_next_token( [Keyword.NULL, Keyword.THIS, Keyword.TRUE, Keyword.FALSE]): self._compile_keyword() elif self._what_next_token_type([Type.IDENTIFIER]): if self._what_next_token([Symbol.LEFT_BOX_BRACKET], 1): self._compile_identifier() self._compile_symbol() self.compile_expression() self._compile_symbol() elif self._what_next_token([Symbol.LEFT_ROUND_BRACKET, Symbol.DOT], 1): if self._what_next_token([Symbol.LEFT_ROUND_BRACKET], 1): self._compile_identifier() self._compile_symbol() self.compile_expression_list() self._compile_symbol() else: self._compile_identifier() self._compile_symbol() self._compile_identifier() self._compile_symbol() self.compile_expression_list() self._compile_symbol() else: self._compile_identifier() elif self._what_next_token([Symbol.LEFT_ROUND_BRACKET]): self._compile_symbol() self.compile_expression() self._compile_symbol() elif self._what_next_token([Symbol.TILDE, Symbol.MINUS]): self._compile_symbol() self.compile_term() self._write_end('term') def compile_expression_list(self): self._write_start('expressionList') if not self._what_next_token([Symbol.RIGHT_ROUND_BRACKET]): self.compile_expression() while self._what_next_token([Symbol.COMMA]): self._compile_symbol() self.compile_expression() self._write_end('expressionList') def save(self): self._xml_file.write(self._xml_text) def _what_next_token(self, values, index=0): return self._jack_tokenizer.next_token(index) in values def _what_next_token_type(self, values, index=0): return self._jack_tokenizer.next_token_type(index) in values def _compile_symbol(self): self._jack_tokenizer.advance() self._write('symbol', self._jack_tokenizer.token()) def _compile_keyword(self): self._jack_tokenizer.advance() self._write('keyword', self._jack_tokenizer.token()) def _compile_identifier(self): self._jack_tokenizer.advance() self._write('identifier', self._jack_tokenizer.token()) def _compile_integer_constant(self): self._jack_tokenizer.advance() self._write('integerConstant', self._jack_tokenizer.token()) def _compile_string_constant(self): self._jack_tokenizer.advance() self._write('stringConstant', self._jack_tokenizer.token()) def _write(self, element, value): self._xml_text += '<{}> {} </{}>\n'.format(element, value, element) def _write_start(self, element): self._xml_text += '<%s>\n' % element def _write_end(self, element): self._xml_text += '</%s>\n' % element
class CompilationEngine(): def __init__(self, jack_file, vm_file): self._jack_tokenizer = JackTokenizer(jack_file) self._vm_file = vm_file self._vm_text = '' self._xml_text = '' self._symbol_table = SymbolTable() self._vm_writer = VmWriter(self._vm_file) self._class_name = None self._label_count = 0 self._compiled_class_name = '' def compile_class(self): self._write_start('class') self._compile_keyword() self._write('IdentifierInfo', 'category: class') self._compiled_class_name = self._compile_identifier() self._compile_symbol() while self._what_next_token([Keyword.STATIC, Keyword.FIELD]): self.compile_class_var_dec() while self._what_next_token( [Keyword.CONSTRUCTOR, Keyword.FUNCTION, Keyword.METHOD]): self.compile_subroutine_dec() self._compile_symbol() self._write_end('class') def compile_class_var_dec(self): self._write_start('classVarDec') token = self._compile_keyword() kind = None if token == Keyword.STATIC: kind = Kind.STATIC elif token == Keyword.FIELD: kind = Kind.FIELD type_token = self._jack_tokenizer.next_token() if self._what_next_token([Keyword.INT, Keyword.CHAR, Keyword.BOOLEAN]): self._compile_keyword() else: self._write('IdentifierInfo', 'category: class') self._compile_identifier() self._compile_var_name(declaration=True, type=type_token, kind=kind) while self._what_next_token([Symbol.COMMA]): self._compile_symbol() self._compile_var_name(declaration=True, type=type_token, kind=kind) self._compile_symbol() self._write_end('classVarDec') def compile_subroutine_dec(self): self._symbol_table.start_subroutine() self._write_start('subroutineDec') token = self._compile_keyword() if self._jack_tokenizer.next_token() == Keyword.VOID: self._compile_keyword() else: self._jack_tokenizer.next_token() if self._what_next_token( [Keyword.INT, Keyword.CHAR, Keyword.BOOLEAN]): self._compile_keyword() else: self._write('IdentifierInfo', 'category: class') self._compile_identifier() self._write('IdentifierInfo', 'category: subroutine') subroutine_name = self._compile_identifier() self._compile_symbol() if token == Keyword.METHOD: self._symbol_table.define('$this', self._compiled_class_name, Kind.ARG) self.compile_parameter_list() self._compile_symbol() self.compile_subroutine_body(subroutine_name, token) self._write_end('subroutineDec') def compile_parameter_list(self): self._write_start('parameterList') if (self._jack_tokenizer.next_token() in [Keyword.INT, Keyword.CHAR, Keyword.BOOLEAN] or self._jack_tokenizer.next_token_type() == Type.IDENTIFIER): type_token = self._jack_tokenizer.next_token() if self._what_next_token( [Keyword.INT, Keyword.CHAR, Keyword.BOOLEAN]): self._compile_keyword() else: self._write('IdentifierInfo', 'category: class') self._compile_identifier() self._compile_var_name(declaration=True, type=type_token, kind=Kind.ARG) while self._what_next_token([Symbol.COMMA]): self._compile_symbol() type_token = self._jack_tokenizer.next_token() if self._what_next_token( [Keyword.INT, Keyword.CHAR, Keyword.BOOLEAN]): self._compile_keyword() else: self._write('IdentifierInfo', 'category: class') self._compile_identifier() self._compile_var_name(declaration=True, type=type_token, kind=Kind.ARG) self._write_end('parameterList') def compile_subroutine_body(self, subroutine_name, subroutine_token): self._write_start('subroutineBody') self._compile_symbol() local_num = 0 while self._what_next_token([Keyword.VAR]): var_num = self.compile_var_dec() local_num += var_num self._vm_writer.write_function( '%s.%s' % (self._compiled_class_name, subroutine_name), local_num) if subroutine_token == Keyword.METHOD: self._vm_writer.write_push(Segment.ARG, 0) self._vm_writer.write_pop(Segment.POINTER, 0) elif subroutine_token == Keyword.CONSTRUCTOR: self._vm_writer.write_push( Segment.CONST, self._symbol_table.var_count(Kind.FIELD)) self._vm_writer.write_call('Memory.alloc', 1) self._vm_writer.write_pop(Segment.POINTER, 0) elif subroutine_token == Keyword.FUNCTION: pass self.compile_statements() self._compile_symbol() self._write_end('subroutineBody') return local_num def compile_var_dec(self): self._write_start('varDec') self._compile_keyword() type_token = self._jack_tokenizer.next_token() if self._what_next_token([Keyword.INT, Keyword.CHAR, Keyword.BOOLEAN]): self._compile_keyword() else: self._write('IdentifierInfo', 'category: class') self._compile_identifier() self._compile_var_name(declaration=True, type=type_token, kind=Kind.VAR) var_num = 1 # TODO while self._what_next_token([Symbol.COMMA]): self._compile_symbol() self._compile_var_name(declaration=True, type=type_token, kind=Kind.VAR) var_num += 1 self._compile_symbol() self._write_end('varDec') return var_num def compile_statements(self): self._write_start('statements') while self._what_next_token([ Keyword.LET, Keyword.IF, Keyword.WHILE, Keyword.DO, Keyword.RETURN ]): if self._what_next_token([Keyword.LET]): self.compile_let() elif self._what_next_token([Keyword.IF]): self.compile_if() elif self._what_next_token([Keyword.WHILE]): self.compile_while() elif self._what_next_token([Keyword.DO]): self.compile_do() elif self._what_next_token([Keyword.RETURN]): self.compile_return() self._write_end('statements') def compile_let(self): self._write_start('letStatement') self._compile_keyword() let_var = self._compile_var_name(let=True) if self._what_next_token([Symbol.LEFT_BOX_BRACKET]): self._compile_symbol() self.compile_expression() self._compile_symbol() self._compile_symbol() kind = self._symbol_table.kind_of(let_var) if kind == Kind.ARG: self._vm_writer.write_push( Segment.ARG, self._symbol_table.index_of(let_var)) elif kind == Kind.VAR: self._vm_writer.write_push( Segment.LOCAL, self._symbol_table.index_of(let_var)) elif kind == Kind.FIELD: self._vm_writer.write_push( Segment.THIS, self._symbol_table.index_of(let_var)) elif kind == Kind.STATIC: self._vm_writer.write_push( Segment.STATIC, self._symbol_table.index_of(let_var)) self._vm_writer.write_arithmetic(Command.ADD) self._vm_writer.write_pop(Segment.TEMP, 2) self.compile_expression() self._vm_writer.write_push(Segment.TEMP, 2) self._vm_writer.write_pop(Segment.POINTER, 1) self._vm_writer.write_pop(Segment.THAT, 0) self._compile_symbol() else: self._compile_symbol() self.compile_expression() self._compile_symbol() kind = self._symbol_table.kind_of(let_var) if kind == Kind.VAR: self._vm_writer.write_pop(Segment.LOCAL, self._symbol_table.index_of(let_var)) elif kind == Kind.ARG: self._vm_writer.write_pop(Segment.ARG, self._symbol_table.index_of(let_var)) elif kind == Kind.FIELD: self._vm_writer.write_pop(Segment.THIS, self._symbol_table.index_of(let_var)) elif kind == Kind.STATIC: self._vm_writer.write_pop(Segment.STATIC, self._symbol_table.index_of(let_var)) self._write_end('letStatement') def compile_if(self): self._write_start('ifStatement') self._compile_keyword() self._compile_symbol() self.compile_expression() self._compile_symbol() self._vm_writer.write_arithmetic(Command.NOT) l1 = self._new_label() l2 = self._new_label() self._vm_writer.write_if(l1) self._compile_symbol() self.compile_statements() self._compile_symbol() self._vm_writer.write_goto(l2) self._vm_writer.write_label(l1) if self._what_next_token([Keyword.ELSE]): self._compile_keyword() self._compile_symbol() self.compile_statements() self._compile_symbol() self._vm_writer.write_label(l2) self._write_end('ifStatement') def compile_while(self): self._write_start('whileStatement') l1 = self._new_label() l2 = self._new_label() self._compile_keyword() self._vm_writer.write_label(l1) self._compile_symbol() self.compile_expression() self._compile_symbol() self._vm_writer.write_arithmetic(Command.NOT) self._vm_writer.write_if(l2) self._compile_symbol() self.compile_statements() self._compile_symbol() self._vm_writer.write_goto(l1) self._vm_writer.write_label(l2) self._write_end('whileStatement') def compile_do(self): self._write_start('doStatement') self._compile_keyword() if self._what_next_token([Symbol.LEFT_ROUND_BRACKET], 1): self._write('IdentifierInfo', 'category: subroutine') subroutine_name = self._compile_identifier() self._compile_symbol() self._vm_writer.write_push(Segment.POINTER, 0) arg_num = self.compile_expression_list() self._compile_symbol() self._vm_writer.write_call( '%s.%s' % (self._compiled_class_name, subroutine_name), arg_num + 1) else: identifier_str = self._jack_tokenizer.next_token() if self._symbol_table.kind_of(identifier_str): instance_name = self._compile_var_name(call=True) self._compile_symbol() self._write('IdentifierInfo', 'category: subroutine') subroutine_name = self._compile_identifier() self._compile_symbol() kind = self._symbol_table.kind_of(instance_name) if kind == Kind.ARG: self._vm_writer.write_push( Segment.ARG, self._symbol_table.index_of(instance_name)) elif kind == Kind.VAR: self._vm_writer.write_push( Segment.LOCAL, self._symbol_table.index_of(instance_name)) elif kind == Kind.FIELD: self._vm_writer.write_push( Segment.THIS, self._symbol_table.index_of(instance_name)) elif kind == Kind.STATIC: self._vm_writer.write_push( Segment.STATIC, self._symbol_table.index_of(instance_name)) arg_num = self.compile_expression_list() self._compile_symbol() self._vm_writer.write_call( '%s.%s' % (self._symbol_table.type_of(instance_name), subroutine_name), arg_num + 1) else: self._write('IdentifierInfo', 'category: class') class_name = self._compile_identifier() self._compile_symbol() self._write('IdentifierInfo', 'category: subroutine') subroutine_name = self._compile_identifier() self._compile_symbol() arg_num = self.compile_expression_list() self._compile_symbol() self._vm_writer.write_call( '%s.%s' % (class_name, subroutine_name), arg_num) self._compile_symbol() self._write_end('doStatement') self._vm_writer.write_pop(Segment.TEMP, 0) def compile_return(self): self._write_start('returnStatement') self._compile_keyword() if not self._what_next_token([Symbol.SEMI_COLON]): self.compile_expression() else: self._vm_writer.write_push(Segment.CONST, 0) self._compile_symbol() self._vm_writer.write_return() self._write_end('returnStatement') def compile_expression(self): self._write_start('expression') self.compile_term() while self._what_next_token([ Symbol.PLUS, Symbol.MINUS, Symbol.MULTI, Symbol.DIV, Symbol.AND, Symbol.PIPE, Symbol.LESS_THAN, Symbol.GREATER_THAN, Symbol.EQUAL ]): token = self._compile_symbol() self.compile_term() if token == Symbol.PLUS: self._vm_writer.write_arithmetic(Command.ADD) elif token == Symbol.MINUS: self._vm_writer.write_arithmetic(Command.SUB) elif token == Symbol.MULTI: self._vm_writer.write_call('Math.multiply', 2) elif token == Symbol.DIV: self._vm_writer.write_call('Math.divide', 2) elif token == Symbol.AND: self._vm_writer.write_arithmetic(Command.AND) elif token == Symbol.PIPE: self._vm_writer.write_arithmetic(Command.OR) elif token == Symbol.LESS_THAN: self._vm_writer.write_arithmetic(Command.LT) elif token == Symbol.GREATER_THAN: self._vm_writer.write_arithmetic(Command.GT) elif token == Symbol.EQUAL: self._vm_writer.write_arithmetic(Command.EQ) self._write_end('expression') def compile_term(self): self._write_start('term') if self._what_next_token_type([Type.INT_CONST]): value = self._compile_integer_constant() self._vm_writer.write_push(Segment.CONST, value) elif self._what_next_token_type([Type.STRING_CONST]): value = self._compile_string_constant() self._vm_writer.write_push(Segment.CONST, len(value)) self._vm_writer.write_call('String.new', 1) for v in value: self._vm_writer.write_push(Segment.CONST, ord(v)) self._vm_writer.write_call('String.appendChar', 2) elif self._what_next_token([Keyword.NULL]): self._compile_keyword() self._vm_writer.write_push(Segment.CONST, 0) elif self._what_next_token([Keyword.THIS]): self._compile_keyword() self._vm_writer.write_push(Segment.POINTER, 0) elif self._what_next_token([Keyword.TRUE]): self._compile_keyword() self._vm_writer.write_push(Segment.CONST, 0) self._vm_writer.write_arithmetic(Command.NOT) elif self._what_next_token([Keyword.FALSE]): self._compile_keyword() self._vm_writer.write_push(Segment.CONST, 0) elif self._what_next_token_type([Type.IDENTIFIER]): if self._what_next_token([Symbol.LEFT_BOX_BRACKET], 1): self._compile_var_name() self._compile_symbol() self.compile_expression() self._vm_writer.write_arithmetic(Command.ADD) self._vm_writer.write_pop(Segment.POINTER, 1) self._vm_writer.write_push(Segment.THAT, 0) self._compile_symbol() elif self._what_next_token([Symbol.LEFT_ROUND_BRACKET, Symbol.DOT], 1): if self._what_next_token([Symbol.LEFT_ROUND_BRACKET], 1): self._write('IdentifierInfo', 'category: subroutine') subroutine_name = self._compile_identifier() self._compile_symbol() self._vm_writer.write_push(Segment.POINTER, 0) arg_num = self.compile_expression_list() self._compile_symbol() self._vm_writer.write_call( '%s.%s' % (self._compiled_class_name, subroutine_name), arg_num + 1) else: identifier_str = self._jack_tokenizer.next_token() if self._symbol_table.kind_of(identifier_str): instance_name = self._compile_var_name(call=True) self._compile_symbol() self._write('IdentifierInfo', 'category: subroutine') subroutine_name = self._compile_identifier() self._compile_symbol() kind = self._symbol_table.kind_of(instance_name) if kind == Kind.ARG: self._vm_writer.write_push( Segment.ARG, self._symbol_table.index_of(instance_name)) elif kind == Kind.VAR: self._vm_writer.write_push( Segment.LOCAL, self._symbol_table.index_of(instance_name)) elif kind == Kind.FIELD: self._vm_writer.write_push( Segment.THIS, self._symbol_table.index_of(instance_name)) elif kind == Kind.STATIC: self._vm_writer.write_push( Segment.STATIC, self._symbol_table.index_of(instance_name)) arg_num = self.compile_expression_list() self._compile_symbol() self._vm_writer.write_call( '%s.%s' % (self._symbol_table.type_of(instance_name), subroutine_name), arg_num + 1) else: self._write('IdentifierInfo', 'category: class') class_name = self._compile_identifier() self._compile_symbol() self._write('IdentifierInfo', 'category: subroutine') subroutine_name = self._compile_identifier() self._compile_symbol() arg_num = self.compile_expression_list() self._compile_symbol() self._vm_writer.write_call( '%s.%s' % (class_name, subroutine_name), arg_num) else: self._compile_var_name() elif self._what_next_token([Symbol.LEFT_ROUND_BRACKET]): self._compile_symbol() self.compile_expression() self._compile_symbol() elif self._what_next_token([Symbol.TILDE]): self._compile_symbol() self.compile_term() self._vm_writer.write_arithmetic(Command.NOT) elif self._what_next_token([Symbol.MINUS]): self._compile_symbol() self.compile_term() self._vm_writer.write_arithmetic(Command.NEG) self._write_end('term') def compile_expression_list(self): self._write_start('expressionList') arg_num = 0 if not self._what_next_token([Symbol.RIGHT_ROUND_BRACKET]): self.compile_expression() arg_num += 1 while self._what_next_token([Symbol.COMMA]): self._compile_symbol() self.compile_expression() arg_num += 1 self._write_end('expressionList') return arg_num def save(self): self._vm_writer.save() def _what_next_token(self, values, index=0): return self._jack_tokenizer.next_token(index) in values def _what_next_token_type(self, values, index=0): return self._jack_tokenizer.next_token_type(index) in values def _compile_symbol(self): self._jack_tokenizer.advance() value = self._jack_tokenizer.token() self._write('symbol', value) return value def _compile_keyword(self): self._jack_tokenizer.advance() value = self._jack_tokenizer.token() self._write('keyword', value) return value def _compile_identifier(self): self._jack_tokenizer.advance() value = self._jack_tokenizer.token() self._write('identifier', value) return value def _compile_integer_constant(self): self._jack_tokenizer.advance() value = self._jack_tokenizer.token() self._write('integerConstant', value) return value def _compile_string_constant(self): self._jack_tokenizer.advance() value = self._jack_tokenizer.token() self._write('stringConstant', value) return value def _compile_var_name(self, declaration=False, type=None, kind=None, let=False, call=False): if declaration: self._symbol_table.define(self._jack_tokenizer.next_token(), type, kind) elif let: pass elif call: pass else: kind = self._symbol_table.kind_of( self._jack_tokenizer.next_token()) if kind == Kind.ARG: self._vm_writer.write_push( Segment.ARG, self._symbol_table.index_of( self._jack_tokenizer.next_token())) elif kind == Kind.VAR: self._vm_writer.write_push( Segment.LOCAL, self._symbol_table.index_of( self._jack_tokenizer.next_token())) elif kind == Kind.FIELD: self._vm_writer.write_push( Segment.THIS, self._symbol_table.index_of( self._jack_tokenizer.next_token())) elif kind == Kind.STATIC: self._vm_writer.write_push( Segment.STATIC, self._symbol_table.index_of( self._jack_tokenizer.next_token())) self._write( 'IdentifierInfo', 'declaration: %s, kind: %s, index: %d' % (declaration, self._symbol_table.kind_of(self._jack_tokenizer.next_token()), self._symbol_table.index_of(self._jack_tokenizer.next_token()))) return self._compile_identifier() def _write(self, element, value): self._xml_text += '<{}> {} </{}>\n'.format(element, value, element) def _write_start(self, element): self._xml_text += '<%s>\n' % element def _write_end(self, element): self._xml_text += '</%s>\n' % element def _new_label(self): self._label_count += 1 return 'LABEL_%d' % self._label_count