def compile(src_jack_file, output): print(src_jack_file) tokenizer = JackTokenizer(src_jack_file) symbol_table = SymbolTable() vm_writer = VMWriter(output) compilation_engine = CompilationEngine(tokenizer, symbol_table, vm_writer) compilation_engine.compile()
def compile(input_file_path): input_file = open(input_file_path) output_file_path = f"{input_file_path.strip('.jack')}_.xml" output_file = open(output_file_path, 'w') comp_engine = CompilationEngine() comp_engine.compile(input_file, output_file)
def compile_file(self, file_path): print("Compiling", file_path, "...") file_name = os.path.splitext(os.path.basename(file_path))[0] dir_name = os.path.split(file_path)[0] output_file_name = os.path.join(dir_name, file_name + "__.xml") with open(output_file_name, "w") as output_file: tokenizer = Tokenizer(file_path) try: compiler = CompilationEngine(tokenizer, output_file) compiler.compile() print("Compilation successful!", file_path, "=>", output_file_name) except CompilationError as err: tokenizer.close() raise CompilationError("ERROR: " + err.message)
def main(): if len(sys.argv) != 2: print( "Expected 1 argument (either the .jack file or a directory containing .jack files). Exiting!" ) return is_file_arg = sys.argv[1].endswith(".jack") if is_file_arg: jack_files = [sys.argv[1]] else: jack_files = [ join(sys.argv[1], f) for f in listdir(sys.argv[1]) if f.endswith(".jack") ] for jack_file in jack_files: ce = CompilationEngine(JackTokenizer(jack_file), jack_file.split(".jack")[0] + "Nisarg.xml") ce.compile()
class CompilationEngineTest(unittest.TestCase): def setUp(self): self.compiler = CompilationEngine() self.maxDiff = None def reformat_xml_to_standardize_whitespace(self, xml): tree = ET.fromstring(''.join(xml.split())) self.compiler.prettify_elements(tree) return ET.tostring(tree, encoding='unicode', short_empty_elements=False) def assert_xml_equal(self, actual_xml, expected_xml, debug_output=False): if debug_output: print('expected_xml:') print(self.reformat_xml_to_standardize_whitespace(expected_xml)) print('actual_xml:') print(self.reformat_xml_to_standardize_whitespace(actual_xml)) self.assertEqual( self.reformat_xml_to_standardize_whitespace(expected_xml), self.reformat_xml_to_standardize_whitespace(actual_xml)) def test_empty_class(self): output = self.compiler.compile(""" class Main { } """) self.assert_xml_equal( output, """<class> <keyword> class </keyword> <identifier> Main </identifier> <symbol> { </symbol> <symbol> } </symbol> </class>""") def test_class_with_class_variables(self): output = self.compiler.compile(""" class Main { field int x, y; field int size; static boolean test; field Square square; } """) self.assert_xml_equal( output, """<class> <keyword> class </keyword> <identifier> Main </identifier> <symbol> { </symbol> <classVarDec> <keyword> field </keyword> <keyword> int </keyword> <identifier> x </identifier> <symbol> , </symbol> <identifier> y </identifier> <symbol> ; </symbol> </classVarDec> <classVarDec> <keyword> field </keyword> <keyword> int </keyword> <identifier> size </identifier> <symbol> ; </symbol> </classVarDec> <classVarDec> <keyword> static </keyword> <keyword> boolean </keyword> <identifier> test </identifier> <symbol> ; </symbol> </classVarDec> <classVarDec> <keyword> field </keyword> <identifier> Square </identifier> <identifier> square </identifier> <symbol> ; </symbol> </classVarDec> <symbol> } </symbol> </class>""") def test_class_with_variables_and_empty_subroutine(self): output = self.compiler.compile(""" class Main { field int size; function void main() { } } """) self.assert_xml_equal( output, """<class> <keyword> class </keyword> <identifier> Main </identifier> <symbol> { </symbol> <classVarDec> <keyword> field </keyword> <keyword> int </keyword> <identifier> size </identifier> <symbol> ; </symbol> </classVarDec> <subroutineDec> <keyword> function </keyword> <keyword> void </keyword> <identifier> main </identifier> <symbol> ( </symbol> <parameterList> </parameterList> <symbol> ) </symbol> <subroutineBody> <symbol> { </symbol> <statements/> <symbol> } </symbol> </subroutineBody> </subroutineDec> <symbol> } </symbol> </class>""") def test_subroutine_with_variables_and_no_statements(self): output = self.compiler.compile(""" class Main { function void main() { var Array a; var int length; var int i, sum; } } """) self.assert_xml_equal( output, """<class> <keyword> class </keyword> <identifier> Main </identifier> <symbol> { </symbol> <subroutineDec> <keyword> function </keyword> <keyword> void </keyword> <identifier> main </identifier> <symbol> ( </symbol> <parameterList> </parameterList> <symbol> ) </symbol> <subroutineBody> <symbol> { </symbol> <varDec> <keyword> var </keyword> <identifier> Array </identifier> <identifier> a </identifier> <symbol> ; </symbol> </varDec> <varDec> <keyword> var </keyword> <keyword> int </keyword> <identifier> length </identifier> <symbol> ; </symbol> </varDec> <varDec> <keyword> var </keyword> <keyword> int </keyword> <identifier> i </identifier> <symbol> , </symbol> <identifier> sum </identifier> <symbol> ; </symbol> </varDec> <statements></statements> <symbol> } </symbol> </subroutineBody> </subroutineDec> <symbol> } </symbol> </class>""") def test_let_statement(self): output = self.compiler.compile(""" class Main { function void main() { let i = 0; } } """) self.assert_xml_equal( output, """<class> <keyword> class </keyword> <identifier> Main </identifier> <symbol> { </symbol> <subroutineDec> <keyword> function </keyword> <keyword> void </keyword> <identifier> main </identifier> <symbol> ( </symbol> <parameterList> </parameterList> <symbol> ) </symbol> <subroutineBody> <symbol> { </symbol> <statements> <letStatement> <keyword> let </keyword> <identifier> i </identifier> <symbol> = </symbol> <expression> <term> <integerConstant> 0 </integerConstant> </term> </expression> <symbol> ; </symbol> </letStatement> </statements> <symbol> } </symbol> </subroutineBody> </subroutineDec> <symbol> } </symbol> </class>""") def test_method_call(self): output = self.compiler.compile(""" class Main { function void dispose () { do square.dispose(); do Memory.deAlloc(square); return; } }""") self.assert_xml_equal( output, """<class> <keyword> class </keyword> <identifier> Main </identifier> <symbol> { </symbol> <subroutineDec> <keyword> function </keyword> <keyword> void </keyword> <identifier> dispose </identifier> <symbol> ( </symbol> <parameterList> </parameterList> <symbol> ) </symbol> <subroutineBody> <symbol> { </symbol> <statements> <doStatement> <keyword> do </keyword> <identifier> square </identifier> <symbol> . </symbol> <identifier> dispose </identifier> <symbol> ( </symbol> <expressionList> </expressionList> <symbol> ) </symbol> <symbol> ; </symbol> </doStatement> <doStatement> <keyword> do </keyword> <identifier> Memory </identifier> <symbol> . </symbol> <identifier> deAlloc </identifier> <symbol> ( </symbol> <expressionList> <expression> <term> <identifier> square </identifier> </term> </expression> </expressionList> <symbol> ) </symbol> <symbol> ; </symbol> </doStatement> <returnStatement> <keyword> return </keyword> <symbol> ; </symbol> </returnStatement> </statements> <symbol> } </symbol> </subroutineBody> </subroutineDec> <symbol> } </symbol> </class>""", True) def test_if_no_else(self): output = self.compiler.compile(""" class Main { method void moveSquare() { if (direction) { do square.moveUp(); } if (direction) { do square.moveDown(); } return; } }""") self.assert_xml_equal( output, """<class> <keyword> class </keyword> <identifier> Main </identifier> <symbol> { </symbol> <subroutineDec> <keyword> method </keyword> <keyword> void </keyword> <identifier> moveSquare </identifier> <symbol> ( </symbol> <parameterList> </parameterList> <symbol> ) </symbol> <subroutineBody> <symbol> { </symbol> <statements> <ifStatement> <keyword> if </keyword> <symbol> ( </symbol> <expression> <term> <identifier> direction </identifier> </term> </expression> <symbol> ) </symbol> <symbol> { </symbol> <statements> <doStatement> <keyword> do </keyword> <identifier> square </identifier> <symbol> . </symbol> <identifier> moveUp </identifier> <symbol> ( </symbol> <expressionList> </expressionList> <symbol> ) </symbol> <symbol> ; </symbol> </doStatement> </statements> <symbol> } </symbol> </ifStatement> <ifStatement> <keyword> if </keyword> <symbol> ( </symbol> <expression> <term> <identifier> direction </identifier> </term> </expression> <symbol> ) </symbol> <symbol> { </symbol> <statements> <doStatement> <keyword> do </keyword> <identifier> square </identifier> <symbol> . </symbol> <identifier> moveDown </identifier> <symbol> ( </symbol> <expressionList> </expressionList> <symbol> ) </symbol> <symbol> ; </symbol> </doStatement> </statements> <symbol> } </symbol> </ifStatement> <returnStatement> <keyword>return</keyword> <symbol>;</symbol> </returnStatement> </statements> <symbol> } </symbol> </subroutineBody> </subroutineDec> <symbol> } </symbol> </class>""") def test_compound_let_statement(self): output = self.compiler.compile(""" class Main { function void main() { let i = i | j; return; } }""") self.assert_xml_equal( output, """<class> <keyword>class</keyword> <identifier>Main</identifier> <symbol>{</symbol> <subroutineDec> <keyword>function</keyword> <keyword>void</keyword> <identifier>main</identifier> <symbol>(</symbol> <parameterList></parameterList> <symbol>)</symbol> <subroutineBody> <symbol>{</symbol> <statements> <letStatement> <keyword>let</keyword> <identifier>i</identifier> <symbol>=</symbol> <expression> <term> <identifier>i</identifier> </term> <symbol>|</symbol> <term> <identifier>j</identifier> </term> </expression> <symbol>;</symbol> </letStatement> <returnStatement> <keyword>return</keyword> <symbol>;</symbol> </returnStatement> </statements> <symbol>}</symbol> </subroutineBody> </subroutineDec> <symbol>}</symbol> </class> """, True)