You must complete the implementation of the codegen program in the file codegen.cpp. The codegen.cpp program reads an XML representation of an abstract syntax tree of a Jack class from standard input and writes a Hack Virtual Machine (VM) code implementation of the class to standard output. All output must be written using the write_to_output() function described in iobuffer.h.
The main function in the codegen.cpp file reads an abstract syntax tree of a Jack class from standard input using the function ast_parse_xml(). It then passes the tree to the function visit_class() that uses the functions described in abstract-syntax-tree.h to walk over the abstract syntax tree of the class.
You must modify the visit_*() functions to add code that will output a VM implementation of the class. Any code that walks the abstract syntax tree of a class will be very similar in structure so the startup files should save you a lot of typing. However, you do not need to follow this structure if you do not want to. You must not modify the main() function but you can modify the remainder of the code as much as you like.
Compiling and Running
When the Makefile attempts to compile the program codegen, it will use the file codegen.cpp.
The program can be compiled and run against the provided tests using the command:
% make 1codegen
make will only compile the program if it has not yet been compiled or the source files have changed since it was last compiled.
Note: Do not modify the provided Makefile or the sub-directories bin, includes or lib. These will be replaced during testing by the web submission system.
The final stage of writing a compiler is to generate a new representation of the program in the target language using the information discovered during parsing. In this case we are taking an abstract syntax tree produced by a parser, which may or may not have been subsequently transformed by one or more optimisers, and translating the tree into equivalent VM language. You should review Workshop 11 to see an example of how this can be done. Further details of what code should be generated for different elements of Jack can be found in lectures and in the text book.
We strongly suggest that you test your program with small examples first so that you can independently test the functionality you are implementing. In the tests sub-directory you can find files with examples of the VM code your program must produce for given inputs.
You can also construct small example Jack programs and see what VM code the JackCompiler produces. The assignment description includes some specific requirements, such as how to handle expressions, that may mean that the JackCompiler produces slightly different VM code. However, it is still a valuable tool and is a good way of working out the VM code solutions to some of the questions in the lecture worksheets.
There is one part of the code generation which is not well defined by the Jack language, namely expression evaluation. There is no operator precedence defined which means that expressions such as A * B + C / D could be interpreted as any of:
- ((A * B) + C) / D
- (A * (B + C)) / D
- (A * B) + (C / D)
- A * (B + (C / D))
- A * ((B + C) / D)
Even in the simple case of A + B, the code generated could evaluate A before B or B before A. In order to avoid ambiguity this assignment will require all expression terms to be evaluated as follows:
- all operators are assumed to be left associative, ie A * B + C / D is equivalent to ((A * B) + C) / D, and
- when evaluating an infix operation, the right operand is evaluated before the left operand.
As a result the code to evaluate the expression A * B + C / D is generated in this order:
- code to evaluate A
- code to evaluate B
- code to evaluate C
- code to evaluate D
- Do not modify the main() function in codegen.cpp.
- All output must be written using the write_to_output() function in includes/iobuffer.h.
- All output must be written with one VM command per line.
- VM labels are local to their function, you can reuse the same name in more than one function.
- Use the label names WHILE_EXP and WHILE_END for while loops. Append a unique number for each while loop in a function starting from 0. Restart the count in each new VM function.
- Use the label names IF_TRUE, IF_FALSE and IF_END for if statements. Append a unique number for each if statement in a function starting from 0. Restart the count in each new VM function.
- String literals must be created using the String.new() constructor and then adding each character using the String.appendChar() method one at a time.
- Integer constant values should all be in the range 0 to +32,767. However, the ast_int node will accept any value in the range -32,768 to +32,767. Where a negative value is found, the absolute integer value must be pushed onto the stack and followed by a neg command. In the special case of, -32,768, the integer constant 32767 must be pushed onto the stack, then the integer constant 1 must be pushed onto the stack followed by an add command.
- If the infix operator in a parse tree is == or =, the VM command to output is eq.
- If the infix operator in a parse tree is <=. , the VM commands to output are gt followed by not.
- If the infix operator in a parse tree is >=. , the VM commands to output are lt followed by not.
- If the infix operator in a parse tree is ~=. , the VM commands to output are eq followed by not.
- Assignment status: Already Solved By Our Experts
- (USA, AUS, UK & CA PhD. Writers)
- CLICK HERE TO GET A PROFESSIONAL WRITER TO WORK ON THIS PAPER AND OTHER SIMILAR PAPERS, GET A NON PLAGIARIZED PAPER FROM OUR EXPERTS