From 80cc6c8982b575fd2b94011c4fb9d420c17b351f Mon Sep 17 00:00:00 2001 From: Su Xing Date: Mon, 27 Mar 2023 01:12:36 +0800 Subject: [PATCH] Add skeleton for SysY IR generator. --- src/CMakeLists.txt | 1 + src/IR.h | 6 +- src/SysYIRGenerator.cpp | 68 ++++++++++++++++ src/SysYIRGenerator.h | 173 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 src/SysYIRGenerator.cpp create mode 100644 src/SysYIRGenerator.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d5c1b45..8028acb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,7 @@ add_executable(sysyc sysyc.cpp SysYFormatter.cpp IR.cpp + SysYIRGenerator.cpp ) target_include_directories(sysyc PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(sysyc PRIVATE SysYParser) diff --git a/src/IR.h b/src/IR.h index abb84bc..4476e8e 100644 --- a/src/IR.h +++ b/src/IR.h @@ -252,7 +252,7 @@ protected: BasicBlock *block; int index; -protected: +public: Argument(Type *type, BasicBlock *block, int index, const std::string &name = "") : Value(type, name), block(block), index(index) {} @@ -301,6 +301,10 @@ public: iterator begin() { return instructions.begin(); } iterator end() { return instructions.end(); } iterator terminator() { return std::prev(end()); } + Argument *createArgument(Type *type, const std::string &name = "") { + arguments.emplace_back(type, this, arguments.size(), name); + return &arguments.back(); + }; }; // class BasicBlock //! User is the abstract base type of `Value` types which use other `Value` as diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp new file mode 100644 index 0000000..976c95f --- /dev/null +++ b/src/SysYIRGenerator.cpp @@ -0,0 +1,68 @@ +#include +#include +#include +using namespace std; +#include "SysYIRGenerator.h" + +namespace sysy { + +any SysYIRGenerator::visitModule(SysYParser::ModuleContext *ctx) { + auto pModule = new Module(); + assert(pModule); + module.reset(pModule); + for (auto decl : ctx->decl()) + visitDecl(decl); + for (auto func : ctx->func()) + visitFunc(func); + return pModule; +} + +any SysYIRGenerator::visitFunc(SysYParser::FuncContext *ctx) { + auto name = ctx->ID()->getText(); + auto params = ctx->funcFParams()->funcFParam(); + vector paramTypes; + vector paramNames; + for (auto param : params) { + paramTypes.push_back(any_cast(visitBtype(param->btype()))); + paramNames.push_back(param->ID()->getText()); + } + Type *returnType = any_cast(visitFuncType(ctx->funcType())); + auto funcType = Type::getFunctionType(returnType, paramTypes); + auto function = module->createFunction(name, funcType); + auto entry = function->getEntryBlock(); + for (auto i = 0; i < paramTypes.size(); ++i) + entry->createArgument(paramTypes[i], paramNames[i]); + builder.setPosition(entry, entry->end()); + visitBlockStmt(ctx->blockStmt()); + return function; +} +any SysYIRGenerator::visitBtype(SysYParser::BtypeContext *ctx) { + return ctx->INT() ? Type::getIntType() : Type::getFloatType(); +} + +any SysYIRGenerator::visitBlockStmt(SysYParser::BlockStmtContext *ctx) { + for (auto item : ctx->blockItem()) + visitBlockItem(item); + return builder.getBasicBlock(); +} + +any SysYIRGenerator::visitBlockItem(SysYParser::BlockItemContext *ctx) { + return ctx->decl() ? visitDecl(ctx->decl()) : visitStmt(ctx->stmt()); +} + +any SysYIRGenerator::visitDecl(SysYParser::DeclContext *ctx) { + std::vector values; + auto type = any_cast(visitBtype(ctx->btype())); + for (auto varDef : ctx->varDef()) { + auto name = varDef->lValue()->ID()->getText(); + auto alloca = builder.createAllocaInst(type, {}, name); + if (varDef->ASSIGN()) { + auto value = any_cast(varDef->initValue()->accept(this)); + auto store = builder.createStoreInst(value, alloca); + } + values.push_back(alloca); + } + return values; +} + +} // namespace sysy \ No newline at end of file diff --git a/src/SysYIRGenerator.h b/src/SysYIRGenerator.h new file mode 100644 index 0000000..ba65fe4 --- /dev/null +++ b/src/SysYIRGenerator.h @@ -0,0 +1,173 @@ +#pragma once + +#include "IR.h" +#include "IRBuilder.h" +#include "SysYBaseVisitor.h" +#include "SysYParser.h" +#include + +namespace sysy { + +class SysYIRGenerator : public SysYBaseVisitor { +private: + std::unique_ptr module; + IRBuilder builder; + +public: + SysYIRGenerator() = default; + +public: + virtual std::any visitModule(SysYParser::ModuleContext *ctx) override; + + virtual std::any visitDecl(SysYParser::DeclContext *ctx) override; + + virtual std::any visitBtype(SysYParser::BtypeContext *ctx) override; + + virtual std::any visitVarDef(SysYParser::VarDefContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any + visitScalarInitValue(SysYParser::ScalarInitValueContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any + visitArrayInitValue(SysYParser::ArrayInitValueContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitFunc(SysYParser::FuncContext *ctx) override; + + virtual std::any visitFuncType(SysYParser::FuncTypeContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any + visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any + visitFuncFParam(SysYParser::FuncFParamContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitBlockStmt(SysYParser::BlockStmtContext *ctx) override; + + virtual std::any visitBlockItem(SysYParser::BlockItemContext *ctx) override; + + virtual std::any visitStmt(SysYParser::StmtContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any + visitAssignStmt(SysYParser::AssignStmtContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitExpStmt(SysYParser::ExpStmtContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any + visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any + visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitEmptyStmt(SysYParser::EmptyStmtContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any + visitRelationExp(SysYParser::RelationExpContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any + visitMultiplicativeExp(SysYParser::MultiplicativeExpContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitLValueExp(SysYParser::LValueExpContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitNumberExp(SysYParser::NumberExpContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitAndExp(SysYParser::AndExpContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitParenExp(SysYParser::ParenExpContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitStringExp(SysYParser::StringExpContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitOrExp(SysYParser::OrExpContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitCallExp(SysYParser::CallExpContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any + visitAdditiveExp(SysYParser::AdditiveExpContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitEqualExp(SysYParser::EqualExpContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitCall(SysYParser::CallContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitLValue(SysYParser::LValueContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitNumber(SysYParser::NumberContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any visitString(SysYParser::StringContext *ctx) override { + return visitChildren(ctx); + } + + virtual std::any + visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override { + return visitChildren(ctx); + } + +}; // class SysYIRGenerator + +} // namespace sysy \ No newline at end of file