Joos1W Compiler Framework
All Classes Functions Typedefs Pages
CodeGen.h
1 #pragma once
2 
3 #include "ast/AST.h"
4 #include "ast/DeclContext.h"
5 #include "ast/Stmt.h"
6 #include "semantic/NameResolver.h"
7 #include "tir/Constant.h"
8 #include "tir/IRBuilder.h"
9 #include "tir/Instructions.h"
10 #include "tir/TIR.h"
11 
12 namespace codegen {
13 
14 class CGExprEvaluator;
15 
16 /**
17  * @brief Returns if the AST type will be mapped to a pointer in IR or not.
18  *
19  * @param ty The AST type
20  * @return true True for strings, null and references.
21  * @return false False for arrays and primitive types.
22  */
23 static bool isAstTypeReference(ast::Type const* ty) {
24  return ty->isString() || ty->isNull() || ty->isReference();
25 }
26 
28  friend class CGExprEvaluator;
29 
30 public:
31  CodeGenerator(tir::Context& ctx, tir::CompilationUnit& cu,
32  semantic::NameResolver& nr);
33  CodeGenerator(CodeGenerator const&) = delete;
34  CodeGenerator(CodeGenerator&&) = delete;
35  CodeGenerator& operator=(CodeGenerator const&) = delete;
36  CodeGenerator& operator=(CodeGenerator&&) = delete;
37  void run(ast::LinkingUnit const* lu);
38  tir::Type* emitType(ast::Type const* type);
39 
40 private:
41  void emitStmt(ast::Stmt const* stmt);
42  tir::Value* emitExpr(ast::Expr const* expr);
43  // Emit the function body, assuming the declaration is there
44  void emitFunction(ast::MethodDecl const* decl);
45  // Emit just the declaration, no body
46  void emitFunctionDecl(ast::MethodDecl const* decl);
47  // Emit the class type and static fields, no body
48  void emitClassDecl(ast::ClassDecl const* decl);
49  // Emit the class body (methods and field initializers)
50  void emitClass(ast::ClassDecl const* decl);
51 
52 private:
53  // Given a pointer to the array struct, read out the size
54  tir::Value* emitGetArraySz(tir::Value* ptr);
55  // Given a pointer to the array struct, read out the pointer
56  tir::Value* emitGetArrayPtr(tir::Value* ptr);
57  // Given a pointer to the array struct, set the size
58  void emitSetArraySz(tir::Value* ptr, tir::Value* sz);
59  // Given a pointer to the array struct, set the pointer
60  void emitSetArrayPtr(tir::Value* ptr, tir::Value* arr);
61 
62 private:
63  void emitReturnStmt(ast::ReturnStmt const* stmt);
64  void emitForStmt(ast::ForStmt const* stmt);
65  void emitBlockStmt(ast::BlockStatement const* stmt);
66  void emitDeclStmt(ast::DeclStmt const* stmt);
67  void emitExprStmt(ast::ExprStmt const* stmt);
68  void emitIfStmt(ast::IfStmt const* stmt);
69  void emitWhileStmt(ast::WhileStmt const* stmt);
70 
71 private:
72  tir::Context& ctx;
73  tir::CompilationUnit& cu;
74  tir::Function* curFn{nullptr};
75  // Local AST local decl -> IR Alloca
76  std::unordered_map<ast::Decl const*, tir::AllocaInst*> valueMap{};
77  // Global static AST func/field -> IR Global
78  std::unordered_map<ast::Decl const*, tir::Value*> gvMap{};
79  // Global AST Class -> IR Type
80  std::unordered_map<ast::Decl const*, tir::Type*> typeMap{};
81  // Array type (cache)
82  tir::StructType* arrayType{nullptr};
83  tir::IRBuilder builder{ctx};
84  semantic::NameResolver& nr;
85 };
86 
87 } // namespace codegen