#ifndef _SYSYF_IR_BUILDER_H_ #define _SYSYF_IR_BUILDER_H_ #include "BasicBlock.h" #include "Constant.h" #include "Function.h" #include "IRStmtBuilder.h" #include "Module.h" #include "Type.h" #include #include "SyntaxTree.h" namespace SysYF { namespace IR { class Scope { public: // enter a new scope void enter() { name2var.push_back({}); name2func.push_back({}); } // exit a scope void exit() { name2var.pop_back(); name2func.pop_back(); } bool in_global() { return name2var.size() == 1; } // push a name to scope // return true if successful // return false if this name already exits // but func name could be same with variable name bool push(std::string name, Ptr val) { bool result; if (dynamic_pointer_cast(val)){ result = (name2func[name2func.size() - 1].insert({name, val})).second; } else{ result = (name2var[name2var.size() - 1].insert({name, val})).second; } return result; } Ptr find(std::string name, bool isfunc) { if (isfunc){ for (auto s = name2func.rbegin(); s!= name2func.rend();s++) { auto iter = s->find(name); if (iter != s->end()) { return iter->second; } } } else{ for (auto s = name2var.rbegin(); s!= name2var.rend();s++) { auto iter = s->find(name); if (iter != s->end()) { return iter->second; } } } return nullptr; } private: std::vector >> name2var; std::vector >> name2func; }; class IRBuilder: public SyntaxTree::Visitor { private: void ArrayInitTraverser(Ptr initVal, int depth, int index, Ptr varType, std::vector arrayDim); void GetArrayInit(Ptr initVal, std::vector arrayDim, Ptr varType, bool global); void TypeConvert(Ptr origin, Ptr expected); void BinaryExprGen(Ptr lhs, Ptr rhs, SyntaxTree::BinOp op); void BinaryCondExprGen(Ptr lhs, Ptr rhs, SyntaxTree::BinaryCondOp op); virtual void visit(SyntaxTree::InitVal &) override final; virtual void visit(SyntaxTree::Assembly &) override final; virtual void visit(SyntaxTree::FuncDef &) override final; virtual void visit(SyntaxTree::VarDef &) override final; virtual void visit(SyntaxTree::AssignStmt &) override final; virtual void visit(SyntaxTree::ReturnStmt &) override final; virtual void visit(SyntaxTree::BlockStmt &) override final; virtual void visit(SyntaxTree::EmptyStmt &) override final; virtual void visit(SyntaxTree::ExprStmt &) override final; virtual void visit(SyntaxTree::UnaryCondExpr &) override final; virtual void visit(SyntaxTree::BinaryCondExpr &) override final; virtual void visit(SyntaxTree::BinaryExpr &) override final; virtual void visit(SyntaxTree::UnaryExpr &) override final; virtual void visit(SyntaxTree::LVal &) override final; virtual void visit(SyntaxTree::Literal &) override final; virtual void visit(SyntaxTree::FuncCallStmt &) override final; virtual void visit(SyntaxTree::FuncParam &) override final; virtual void visit(SyntaxTree::FuncFParamList &) override final; virtual void visit(SyntaxTree::IfStmt &) override final; virtual void visit(SyntaxTree::WhileStmt &) override final; virtual void visit(SyntaxTree::BreakStmt &) override final; virtual void visit(SyntaxTree::ContinueStmt &) override final; Ptr builder; Scope scope; Ptr module; IRBuilder() { module = Module::create("SysYF code"); builder = IRStmtBuilder::create(nullptr, module); auto TyVoid = Type::get_void_type(module); auto TyInt32 = Type::get_int32_type(module); auto TyInt32Ptr = Type::get_int32_ptr_type(module); auto TyFloat = Type::get_float_type(module); auto TyFloatPtr = Type::get_float_ptr_type(module); auto input_type = FunctionType::create(TyInt32, {}); auto get_int = Function::create( input_type, "get_int", module); input_type = FunctionType::create(TyFloat, {}); auto get_float = Function::create( input_type, "get_float", module); input_type = FunctionType::create(TyInt32, {}); auto get_char = Function::create( input_type, "get_char", module); PtrVec input_params; PtrVec ().swap(input_params); input_params.push_back(TyInt32Ptr); input_type = FunctionType::create(TyInt32, input_params); auto get_int_array = Function::create( input_type, "get_int_array", module); PtrVec ().swap(input_params); input_params.push_back(TyFloatPtr); input_type = FunctionType::create(TyInt32, input_params); auto get_float_array = Function::create( input_type, "get_float_array", module); PtrVec output_params; PtrVec ().swap(output_params); output_params.push_back(TyInt32); auto output_type = FunctionType::create(TyVoid, output_params); auto put_int = Function::create( output_type, "put_int", module); PtrVec ().swap(output_params); output_params.push_back(TyFloat); output_type = FunctionType::create(TyVoid, output_params); auto put_float = Function::create( output_type, "put_float", module); PtrVec ().swap(output_params); output_params.push_back(TyInt32); output_type = FunctionType::create(TyVoid, output_params); auto put_char = Function::create( output_type, "put_char", module); PtrVec ().swap(output_params); output_params.push_back(TyInt32); output_params.push_back(TyInt32Ptr); output_type = FunctionType::create(TyVoid, output_params); auto put_int_array = Function::create( output_type, "put_int_array", module); PtrVec ().swap(output_params); output_params.push_back(TyInt32); output_params.push_back(TyFloatPtr); output_type = FunctionType::create(TyVoid, output_params); auto put_float_array = Function::create( output_type, "put_float_array", module); scope.enter(); scope.push("getint", get_int); scope.push("getfloat", get_float); scope.push("getch", get_char); scope.push("getarray", get_int_array); scope.push("get_float_array", get_float_array); scope.push("putint", put_int); scope.push("putfloat", put_float); scope.push("putch", put_char); scope.push("putarray", put_int_array); scope.push("putfloatarray", put_float_array); } public: static Ptr create() { return Ptr(new IRBuilder()); } Ptr getModule() { return module; } }; } } #endif // _SYSYF_IR_BUILDER_H_