Working through ‘WACC’ – Chapter 2, Unary operators

There is a big change in this chapter. A new intermediate form called tacky is introduced

Structure of the compiler

The compiler now looks like this.

One very important point here is that there are now two distinct phases

  • Generate Tacky. Tacky is Nora’s target platform neutral representation of the c code. This phase doesnt care about the CPU
  • Generate assembler from Tacky.

This division makes it theoretically easy to implement a compiler that targets different instruction sets (which is why I came here in the first place). Tacky is completely self-contained, it could be simply converted to ascii and written to a file, the phase 2 of compilation could be a separate program.

I christened my backend intermediate form (Assembler AST in the diagram) Moira , Machine Oriented Instruction Representation. You will see many uses of this name in my code.

I also made a big decision to diverge from Nora’s design. I could not see the use of the C AST internal representation. So my parser directly reads the lexer token stream and generates the tacky code. (This decision comes back to haunt me later)

In the back end though I do generate the intermediate form (moira) because I could see the use: a post generation pass needs to be made before generating the final assembler code.

A TACKY sample

FYI here is what TACKY looks like. This program (which we can now handle after completing this chapter).

int main(void) {
  return ~(-2);
}

generates (this is debug output from mycc, not a file)

Dumping TackyProgram
Function: main
      Unary Negate Int(2) Variable("temp.0")
      Unary Complement Variable("temp.0") Variable("temp.1")
      Return Variable("temp.1")

Comments

Leave a comment