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")
Leave a comment