The code generator, located in malang/codegen/codegen.go
, is the final phase of the compiler (in this simple design). It takes the AST and translates it into executable code. In this case, the target language is Go.
Theoretical Background:
- Intermediate Representation (IR): Many compilers use an intermediate representation (IR) between the AST and the final target code. The AST itself can be considered a high-level IR. More sophisticated compilers might use multiple IRs, gradually lowering the level of abstraction.
- Tree Traversal: Code generation typically involves a tree traversal of the AST. The Malang compiler uses a recursive, depth-first traversal.
- Target Code: The code generator's goal is to produce code that is semantically equivalent to the original Malang program.
Key Components:
-
GenerateCode(program ast.Program) string
: The main function. -
generateStatementCode(...)
: Generates code for statements. -
generateExpressionCode(...)
: Generates code for expressions, handling:- Operator Precedence: Uses
operatorPrecedence()
to determine the order of operations. - Associativity: Uses
isLeftAssociative()
to handle operators with the same precedence. - String Conversion: Uses
generateExpressionCodeForParayu
and theisParayu
flag to conditionally convert integers to strings withinparayu
statements. - Type inference: Uses
inferType
to infer the type based on the operator and operands.
- Operator Precedence: Uses
-
declaredVars map[string]string
: Tracks declared variables and their inferred types.
Design Choices:
- Target Language: The code generator produces Go code. This simplifies the compilation process, as we can leverage the Go compiler to produce native executables.
- Tree Traversal: The code generator uses a recursive, depth-first traversal of the AST to generate code.
- Dynamic Typing: Malang does not have explicit types, the compiler uses type inference based on how variables are used.