CSCI 439: Lab 5 Code Generation (Fall 2022)

Correction: Whoops, in the originally posted lab 5 code (and the posted lab 4 sample solution) I believe the parse tree builder is adding extra terminators in parsagn when dealing with the chains of = var = var = value. The terminator is already being added in the parsestmt, it shouldn't be included in the parseasgn. To fix the parseasgn function, drop numChildren to 3 instead of 4 and remove the line assigning a leaf to children[3].

In this lab we'll produce a code generator, used to read code written in our language from labs 3/4 and producing equivalent code in a simple subset of C++.

In the repository for this lab you are provided with a sample solution for lab 4: a scanner/parser that builds a parse tree from valid source code. If you wish, you can instead use your own lab 4 solution as your starting point, just be sure to add the "genCode" function appropriately (see below).

A skeletal "genCode" function has been added as a final call from the main routine, taking the constructed parse tree as a parameter.
Whoops, no it hasn't!
What I envisioned was something like
bool genCode(node* root);
which would take a pointer to the root of the generated tree, after (or replacing) the call to printParseTree in main.
The simplest approach might be to add the new function to parser.h/.cpp.

The genCode function is then meant to traverse the parse tree, producing a C program that achieves the functionality of the original source.

Your task for lab 5 is to implement the genCode function.

The produced code can assume the original source is meant to represent an entire program, with the C++ equivalent consisting of a single main routine and using the iostream libary for output, and longs/doubles for ints and reals.

The table below shows a sample source program and the resulting C++ equivalent, but the whitespace shown for the output has been arbitrarily chosen (i.e. yours doesn't have to exactly match).

int foo ;
real rubberducky ;
int i ;
real r ;
int x ;
i = 10 ;
r = 3.456 ;
print r ;
foo = x = i ;
rubberducky = r ;
print x ;
#include <iostream>
int main()
{
   long foo ;
   double rubberducky ;
   long i ;
   double r ;
   long x ;
   i = 10 ;
   r = 3.456 ;
   std::cout << r << std::endl;
   foo = x = i ;
   rubberducky = r;
   std::cout << x << std::endl;
}
Corrections added: the std:: and the endl were missing originally, and it should probably have been assigning foo = x = i (rather than r) for the sake of matching types.

Recommended approach:

Have codeGen traverse the parse tree from the top down, and base its actions on the current type of node, e.g. Similar logic can be worked out for each of the possible node types in the generated parse tree.