#pragma once #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "cps/AST.h" #include "cps/RuntimeCheck.h" #include "cps/FunctionGen.h" #include "cps/IntegerHandler.h" #include "cps/RealHandler.h" #include "cps/BooleanHandler.h" #include "cps/ArithmeticHandler.h" #include "cps/StringHandler.h" #include "cps/CharHandler.h" #include "cps/StringConversionHandler.h" #include #include namespace cps { class ArrayHandler; class CodeGen { std::unique_ptr TheContext; std::unique_ptr TheModule; std::unique_ptr> Builder; std::map NamedValues; std::unique_ptr Arrays; std::unique_ptr RuntimeChecker; std::unique_ptr FuncGen; std::unique_ptr IntHandler; std::unique_ptr RealHelper; std::unique_ptr BoolHandler; std::unique_ptr ArithHandler; std::unique_ptr StrHandler; std::unique_ptr ChrHandler; std::unique_ptr StrConvHandler; llvm::FunctionCallee PrintfFunc; llvm::FunctionCallee ScanfFunc; llvm::Value *PrintfFormatStr; // %lld\n llvm::Value *PrintfFloatFormatStr; // %f\n llvm::Value *PrintfStringFormatStr; // %s\n llvm::Value *ScanfFormatStr; // %lld llvm::Value *ScanfFloatFormatStr; // %lf llvm::Value *ScanfStringFormatStr; // %s llvm::Value *TrueStr; // "TRUE" llvm::Value *FalseStr; // "FALSE" void SetupExternalFunctions(); llvm::AllocaInst *CreateEntryBlockAlloca(llvm::Function *TheFunction, const std::string &VarName); void emitIfStmt(IfStmtAST *Stmt); void emitWhileStmt(WhileStmtAST *Stmt); void emitRepeatStmt(RepeatStmtAST *Stmt); void emitForStmt(ForStmtAST *Stmt); public: CodeGen(); ~CodeGen(); void compile(const std::vector> &Statements); void print(); llvm::Value *emitExpr(ExprAST *Expr); void emitStmt(StmtAST *Stmt); friend class ArrayHandler; }; }