Homework: Program Code Generator
This homework is necessary preparation for the lab. Make sure you type your code and you bring the file to the lab so that you will not have to waste time entering your code during the lab.
The contract for generateCodeForStatement is informal and vague.
The details of the code to generate for each kind of statement are
provided in the Code Generation
slides
(39-47, in particular). The code generated by your implementation
must match the code-generation patterns described in the slides.
-
First, assume you are given an implementation for the following static method. (In lab you will be given an implementation.)
/** * Converts {@code Condition} into corresponding conditional jump * instruction byte code. * * @param c * the {@code Condition} to be converted * @return the conditional jump instruction byte code corresponding to {@code c} * @ensures <pre> * conditionalJump = * [conditional jump instruction byte code corresponding to c] * </pre> */ private static Instruction conditionalJump(Condition c) {...}Using recursion and the
conditionalJumpmethod above, complete the body of thegenerateCodeForStatementstatic method below. Use the code for thecase IFas a guide for the other cases./** * Generates the sequence of virtual machine instructions ("byte codes") * corresponding to {@code s} and appends it at the end of {@code cp}. * * @param s * the {@code Statement} for which to generate code * @param context * the {@code Context} in which to find user defined instructions * @param cp * the {@code Sequence} containing the generated code * @updates cp * @ensures <pre> * if [all instructions called in s are either primitive or * defined in context] and * [context does not include any calling cycles, i.e., recursion] then * cp = #cp * [sequence of virtual machine "byte codes" corresponding to s] * else * [reports an appropriate error message to the console and terminates client] * </pre> */ private static void generateCodeForStatement(Statement s, Map<String, Statement> context, Sequence<Integer> cp) { final int dummy = 0; switch (s.kind()) { case BLOCK: { // TODO - fill in case break; } case IF: { Statement b = s.newInstance(); Condition c = s.disassembleIf(b); cp.add(cp.length(), conditionalJump(c).byteCode()); int jump = cp.length(); cp.add(cp.length(), dummy); generateCodeForStatement(b, context, cp); cp.replaceEntry(jump, cp.length()); s.assembleIf(c, b); break; } case IF_ELSE: { // TODO - fill in case break; } case WHILE: { // TODO - fill in case break; } // case CALL will go here default: { // nothing to do here: this will never happen... break; } } }
Additional Questions
-
Complete the
case CALLingenerateCodeForStatement. -
Complete the body of the
generatedCodeinstance method for theProgramcomponent. To generate code for a givenProgram(this) you need to generate code for the body of the program and append aHALTinstruction at the end of that.thismust be restored./** * Generates and returns the sequence of virtual machine instructions * ("byte codes") corresponding to {@code this}. * * @return the compiled program * @ensures <pre> * if [all instructions called in this are either primitive or * defined in this.context] and * [this does not include any calling cycles, i.e., recursion] then * generatedCode = * [the sequence of virtual machine "byte codes" corresponding to this] * else * [reports an appropriate error message to the console and terminates client] * </pre> */ public Sequence<Integer> generatedCode();