From d4d7e6494b3ec590b9f28d792e7877955963f432 Mon Sep 17 00:00:00 2001 From: Downright <12709502+downrighr@user.noreply.gitee.com> Date: Wed, 19 Mar 2025 19:06:14 +0800 Subject: [PATCH 1/9] exp2 first commit --- src/SysYIRGenerator.cpp | 334 +++++++++++++++++++++++++++++++++++++++- src/SysYIRGenerator.h | 114 ++++++++++++++ 2 files changed, 445 insertions(+), 3 deletions(-) diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp index 3eccc14..94e7640 100644 --- a/src/SysYIRGenerator.cpp +++ b/src/SysYIRGenerator.cpp @@ -6,18 +6,346 @@ using namespace std; namespace sysy { -any SysYIRGenerator::visitCompUnit(SysYParser::CompUnitContext *ctx) { +/* + * @brief: visit compUnit + * @details: + * compUnit: (decl | funcDef)+; + */ +std::any SysYIRGenerator::visitCompUnit(SysYParser::CompUnitContext *ctx) { // create the IR module auto pModule = new Module(); assert(pModule); module.reset(pModule); + + SymbolTable::ModuleScope scope(symbols_table); + + // 待添加运行时库函数getint等 // generates globals and functions + visitChildren(ctx); // return the IR module return pModule; } -std::any -SysYIRGenerator::visitFuncRParams(SysYParser::FuncRParamsContext *ctx) { + +/* + * @brief: visit decl + * @details: + * decl: constDecl | varDecl; + * constDecl: CONST bType constDef (COMMA constDef)* SEMI; + * varDecl: bType varDef (COMMA varDef)* SEMI; + * constDecl and varDecl shares similar syntax structure + * we consider them together? not sure + */ +std::any SysYIRGenerator::visitDecl(SysYParser::DeclContext *ctx) { + if(ctx->constDecl()){ + return visitConstDecl(ctx->constDecl()); + }else if(ctx->varDecl()){ + return visitVarDecl(ctx->varDecl()); + } + return nullptr; +} + +/* + * @brief: visit constdecl + * @details: + * constDecl: CONST bType constDef (COMMA constDef)* SEMI; + */ +std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext *ctx) { + auto type = Type::getPointerType(any_cast(ctx->bType()->accept(this))); + if(symbols_table.isModuleScope()) + visitConstGlobalDecl(ctx, type); + else + visitConstLocalDecl(ctx, type); + return std::any(); +} + +/* + * @brief: visit btype + * @details: + * bType: INT | FLOAT; + */ +std::any SysYIRGenerator::visitBType(SysYParser::BTypeContext *ctx) { + return ctx->INT() ? Type::getIntType() : Type::getFloatType(); +} + +// std::any visitConstDef(SysYParser::ConstDefContext *ctx); + +std::any SysYIRGenerator::visitConstGlobalDecl(SysYParser::ConstDeclContext *ctx, Type* type) { + std::vector values; + for (auto constDef : ctx->constDef()) { + + auto name = constDef->Ident()->getText(); + // get its dimensions + vector dims; + for (auto dim : constDef->constExp()) + dims.push_back(any_cast(dim->accept(this))); + + if (dims.size() == 0) { + auto init = constDef->ASSIGN() ? any_cast((constDef->constInitVal()->constExp()->accept(this))) + : nullptr; + if (init && isa(init)){ + Type *btype = type->as()->getBaseType(); + if (btype->isInt() && init->getType()->isFloat()) + init = ConstantValue::get((int)dynamic_cast(init)->getFloat()); + else if (btype->isFloat() && init->getType()->isInt()) + init = ConstantValue::get((float)dynamic_cast(init)->getInt()); + } + + auto global_value = module->createGlobalValue(name, type, dims, init); + + symbols_table.insert(name, global_value); + values.push_back(global_value); + } + else{ + auto init = constDef->ASSIGN() ? any_cast(dims[0]) + : nullptr; + auto global_value = module->createGlobalValue(name, type, dims, init); + if (constDef->ASSIGN()) { + d = 0; + n = 0; + path.clear(); + path = vector(dims.size(), 0); + isalloca = false; + current_type = global_value->getType()->as()->getBaseType(); + current_global = global_value; + numdims = global_value->getNumDims(); + for (auto init : constDef->constInitVal()->constInitVal()) + init->accept(this); + // visitConstInitValue(init); + } + symbols_table.insert(name, global_value); + values.push_back(global_value); + } + } + return values; +} + +std::any SysYIRGenerator::visitVarGlobalDecl(SysYParser::VarDeclContext *ctx, Type* type){ + std::vector values; + for (auto varDef : ctx->varDef()) { + + auto name = varDef->Ident()->getText(); + // get its dimensions + vector dims; + for (auto dim : varDef->constExp()) + dims.push_back(any_cast(dim->accept(this))); + + if (dims.size() == 0) { + auto init = varDef->ASSIGN() ? any_cast((varDef->initVal()->exp()->accept(this))) + : nullptr; + if (init && isa(init)){ + Type *btype = type->as()->getBaseType(); + if (btype->isInt() && init->getType()->isFloat()) + init = ConstantValue::get((int)dynamic_cast(init)->getFloat()); + else if (btype->isFloat() && init->getType()->isInt()) + init = ConstantValue::get((float)dynamic_cast(init)->getInt()); + } + + auto global_value = module->createGlobalValue(name, type, dims, init); + + symbols_table.insert(name, global_value); + values.push_back(global_value); + } + else{ + auto init = varDef->ASSIGN() ? any_cast(dims[0]) + : nullptr; + auto global_value = module->createGlobalValue(name, type, dims, init); + if (varDef->ASSIGN()) { + d = 0; + n = 0; + path.clear(); + path = vector(dims.size(), 0); + isalloca = false; + current_type = global_value->getType()->as()->getBaseType(); + current_global = global_value; + numdims = global_value->getNumDims(); + for (auto init : varDef->initVal()->initVal()) + init->accept(this); + // visitInitValue(init); + } + symbols_table.insert(name, global_value); + values.push_back(global_value); + } + } + return values; +} + +std::any SysYIRGenerator::visitConstLocalDecl(SysYParser::ConstDeclContext *ctx, Type* type){ + std::vector values; + // handle variables + for (auto constDef : ctx->constDef()) { + + auto name = constDef->Ident()->getText(); + vector dims; + for (auto dim : constDef->constExp()) + dims.push_back(any_cast(dim->accept(this))); + auto alloca = builder.createAllocaInst(type, dims, name); + symbols_table.insert(name, alloca); + + if (constDef->ASSIGN()) { + if (alloca->getNumDims() == 0) { + + auto value = any_cast(constDef->constInitVal()->constExp()->accept(this)); + + if (isa(value)) { + if (ctx->bType()->INT() && dynamic_cast(value)->isFloat()) + value = ConstantValue::get((int)dynamic_cast(value)->getFloat()); + else if (ctx->bType()->FLOAT() && dynamic_cast(value)->isInt()) + value = ConstantValue::get((float)dynamic_cast(value)->getInt()); + } + else if (alloca->getType()->as()->getBaseType()->isInt() && value->getType()->isFloat()) + value = builder.createFtoIInst(value); + else if (alloca->getType()->as()->getBaseType()->isFloat() && value->getType()->isInt()) + value = builder.createIToFInst(value); + + auto store = builder.createStoreInst(value, alloca); + } + else{ + d = 0; + n = 0; + path.clear(); + path = vector(alloca->getNumDims(), 0); + isalloca = true; + current_alloca = alloca; + current_type = alloca->getType()->as()->getBaseType(); + numdims = alloca->getNumDims(); + for (auto init : constDef->constInitVal()->constInitVal()) + init->accept(this); + } + } + + values.push_back(alloca); + } + return values; +} + +std::any SysYIRGenerator::visitVarLocalDecl(SysYParser::VarDeclContext *ctx, Type* type){ + std::vector values; + for (auto varDef : ctx->varDef()) { + + auto name = varDef->Ident()->getText(); + vector dims; + for (auto dim : varDef->constExp()) + dims.push_back(any_cast(dim->accept(this))); + auto alloca = builder.createAllocaInst(type, dims, name); + symbols_table.insert(name, alloca); + + if (varDef->ASSIGN()) { + if (alloca->getNumDims() == 0) { + + auto value = any_cast(varDef->initVal()->exp()->accept(this)); + + if (isa(value)) { + if (ctx->bType()->INT() && dynamic_cast(value)->isFloat()) + value = ConstantValue::get((int)dynamic_cast(value)->getFloat()); + else if (ctx->bType()->FLOAT() && dynamic_cast(value)->isInt()) + value = ConstantValue::get((float)dynamic_cast(value)->getInt()); + } + else if (alloca->getType()->as()->getBaseType()->isInt() && value->getType()->isFloat()) + value = builder.createFtoIInst(value); + else if (alloca->getType()->as()->getBaseType()->isFloat() && value->getType()->isInt()) + value = builder.createIToFInst(value); + + auto store = builder.createStoreInst(value, alloca); + } + else{ + d = 0; + n = 0; + path.clear(); + path = vector(alloca->getNumDims(), 0); + isalloca = true; + current_alloca = alloca; + current_type = alloca->getType()->as()->getBaseType(); + numdims = alloca->getNumDims(); + for (auto init : varDef->initVal()->initVal()) + init->accept(this); + } + } + + values.push_back(alloca); + } + return values; +} + + + +/* + * @brief: visit constInitVal + * @details: + * constInitVal: constExp + * | LBRACE (constInitVal (COMMA constInitVal)*)? RBRACE; + */ +std::any visitConstInitVal(SysYParser::ConstInitValContext *ctx){ + +} + + +/* + * @brief: visit function type + * @details: + * funcType: VOID | INT | FLOAT; + */ +std::any SysYIRGenerator::visitFuncType(SysYParser::FuncTypeContext* ctx){ + return ctx->INT() ? Type::getIntType() : (ctx->FLOAT() ? Type::getFloatType() : Type::getVoidType()); +} + +/* + * @brief: visit function define + * @details: + * funcDef: funcType Ident LPAREN funcFParams? RPAREN blockStmt; + * funcFParams: funcFParam (COMMA funcFParam)*; + * funcFParam: bType Ident (LBRACK RBRACK (LBRACK exp RBRACK)*)?; + * entry -> next -> others -> exit + * entry: allocas, br + * next: retval, params, br + * other: blockStmt init block + * exit: load retval, ret + */ +std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext* ctx){ + auto funcName = ctx->Ident()->getText(); + auto funcParams = ctx->funcFParams()->funcFParam(); + Type* returnType = any_cast(ctx->funcType()->accept(this)); + + vector paramTypes; + vector paramNames; + + for(auto funcParam:funcParams){ + Type* paramType = any_cast(funcParam->bType()->accept(this)); + paramTypes.push_back(paramType); + paramNames.push_back(funcParam->Ident()->getText()); + } + + auto funcType = FunctionType::get(returnType, paramTypes); + auto function = module->createFunction(funcName, funcType); + + auto entry = function->getEntryBlock(); + for(size_t i = 0; i < paramTypes.size(); i++) + entry->createArgument(paramTypes[i], paramNames[i]); + builder.setPosition(entry, entry->end()); + ctx->blockStmt()->accept(this); + + return function; +} + +/* + * @brief: visit blockStmt + * @details: + * blockStmt: LBRACE blockItem* RBRACE; + * blockItem: decl | stmt; + */ +std::any SysYIRGenerator::visitBlockStmt(SysYParser::BlockStmtContext* ctx){ + + SymbolTable::BlockScope scope(symbols_table); + + for (auto item : ctx->blockItem()) + item->accept(this); + + builder.getBasicBlock(); + return std::any(); +} + + +std::any SysYIRGenerator::visitFuncRParams(SysYParser::FuncRParamsContext *ctx) { return visitChildren(ctx); } std::any SysYIRGenerator::visitNumber(SysYParser::NumberContext *ctx) { diff --git a/src/SysYIRGenerator.h b/src/SysYIRGenerator.h index bfc1865..b0419a6 100644 --- a/src/SysYIRGenerator.h +++ b/src/SysYIRGenerator.h @@ -5,13 +5,86 @@ #include "SysYBaseVisitor.h" #include "SysYParser.h" #include +#include +#include namespace sysy { +class SymbolTable{ +private: + enum Kind + { + kModule, + kFunction, + kBlock, + }; + + std::forward_list>> Scopes; + +public: + struct ModuleScope { + SymbolTable& tables_ref; + ModuleScope(SymbolTable& tables) : tables_ref(tables) { + tables.enter(kModule); + } + ~ModuleScope() { tables_ref.exit(); } + }; + struct FunctionScope { + SymbolTable& tables_ref; + FunctionScope(SymbolTable& tables) : tables_ref(tables) { + tables.enter(kFunction); + } + ~FunctionScope() { tables_ref.exit(); } + }; + struct BlockScope { + SymbolTable& tables_ref; + BlockScope(SymbolTable& tables) : tables_ref(tables) { + tables.enter(kBlock); + } + ~BlockScope() { tables_ref.exit(); } + }; + + SymbolTable() = default; + + bool isModuleScope() const { return Scopes.front().first == kModule; } + bool isFunctionScope() const { return Scopes.front().first == kFunction; } + bool isBlockScope() const { return Scopes.front().first == kBlock; } + Value *lookup(const std::string &name) const { + for (auto &scope : Scopes) { + auto iter = scope.second.find(name); + if (iter != scope.second.end()) + return iter->second; + } + return nullptr; + } + auto insert(const std::string &name, Value *value) { + assert(not Scopes.empty()); + return Scopes.front().second.emplace(name, value); + } +private: + void enter(Kind kind) { + Scopes.emplace_front(); + Scopes.front().first = kind; + } + void exit() { + Scopes.pop_front(); + } + +}; + class SysYIRGenerator : public SysYBaseVisitor { private: std::unique_ptr module; IRBuilder builder; + SymbolTable symbols_table; + //array init use variables + int d = 0, n = 0; + vector path; + bool isalloca; + AllocaInst *current_alloca; + GlobalValue *current_global; + Type *current_type; + int numdims = 0; public: SysYIRGenerator() = default; @@ -21,9 +94,50 @@ public: public: std::any visitCompUnit(SysYParser::CompUnitContext *ctx) override; + + std::any visitDecl(SysYParser::DeclContext *ctx) override; + + std::any visitConstDecl(SysYParser::ConstDeclContext *ctx) override; + + std::any visitBType(SysYParser::BTypeContext *ctx) override; + + std::any visitConstDef(SysYParser::ConstDefContext *ctx) override; + + std::any visitConstInitVal(SysYParser::ConstInitValContext *ctx) override; + + std::any visitFuncType(SysYParser::FuncTypeContext* ctx) override; + + std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override; + + + std::any visitVarDecl(SysYParser::VarDeclContext *ctx) override; + + std::any visitVarDef(SysYParser::VarDefContext *ctx, Type* btype); + + std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override; + + std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override; + + std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx) override; + + std::any visitStmt(SysYParser::StmtContext *ctx) override; + std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override; + std::any visitNumber(SysYParser::NumberContext *ctx) override; + std::any visitString(SysYParser::StringContext *ctx) override; + +private: + std::any visitConstGlobalDecl(SysYParser::ConstDeclContext *ctx, Type* type); + std::any visitVarGlobalDecl(SysYParser::VarDeclContext *ctx, Type* type); + std::any visitConstLocalDecl(SysYParser::ConstDeclContext *ctx, Type* type); + std::any visitVarLocalDecl(SysYParser::VarDeclContext *ctx, Type* type); + Type *getArithmeticResultType(Type *lhs, Type *rhs) { + assert(lhs->isIntOrFloat() and rhs->isIntOrFloat()); + return lhs == rhs ? lhs : Type::getFloatType(); + } + }; // class SysYIRGenerator } // namespace sysy \ No newline at end of file From 3e80cb8f3f5d7b5086f9bdbf4aed1f50a31e60a7 Mon Sep 17 00:00:00 2001 From: Downright <12709502+downrighr@user.noreply.gitee.com> Date: Wed, 19 Mar 2025 20:35:37 +0800 Subject: [PATCH 2/9] add tag4stmt in .g4,format cpp modification needed --- src/ASTPrinter.h | 9 +++++++++ src/SysY.g4 | 30 +++++++++++++++--------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/ASTPrinter.h b/src/ASTPrinter.h index 6f787fa..8c55383 100644 --- a/src/ASTPrinter.h +++ b/src/ASTPrinter.h @@ -25,6 +25,15 @@ public: std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override; std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override; std::any visitBlockStmt(SysYParser::BlockStmtContext *ctx) override; + + // std::any visitAssignStmt(SysYParser::AssignStmtContext *ctx) override; + // std::any visitExpStmt(SysYParser::ExpStmtContext *ctx) override; + // std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override; + // std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override; + // std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override; + // std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override; + // std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override; + // std::any visitBlockItem(SysYParser::BlockItemContext *ctx) override; std::any visitStmt(SysYParser::StmtContext *ctx) override; // std::any visitExp(SysYParser::ExpContext *ctx) override; diff --git a/src/SysY.g4 b/src/SysY.g4 index 2a8361e..b3ed583 100644 --- a/src/SysY.g4 +++ b/src/SysY.g4 @@ -136,29 +136,29 @@ blockStmt: LBRACE blockItem* RBRACE; blockItem: decl | stmt; -stmt: lValue ASSIGN exp SEMICOLON - | exp? SEMICOLON - | blockStmt - | IF LPAREN cond RPAREN stmt (ELSE stmt)? - | WHILE LPAREN cond RPAREN stmt - | BREAK SEMICOLON - | CONTINUE SEMICOLON - | RETURN exp? SEMICOLON; +stmt: lValue ASSIGN exp SEMICOLON #assignStmt + | exp? SEMICOLON #expStmt + | blockStmt #blkStmt + | IF LPAREN cond RPAREN stmt (ELSE stmt)? #ifStmt + | WHILE LPAREN cond RPAREN stmt #whileStmt + | BREAK SEMICOLON #breakStmt + | CONTINUE SEMICOLON #continueStmt + | RETURN exp? SEMICOLON #returnStmt; exp: addExp; cond: lOrExp; lValue: Ident (LBRACK exp RBRACK)*; // 为了方便测试 primaryExp 可以是一个string -primaryExp: LPAREN exp RPAREN - | lValue - | number - | string; +primaryExp: LPAREN exp RPAREN #parenExp + | lValue #lVal + | number #num + | string #str; number: ILITERAL | FLITERAL; -unaryExp: primaryExp - | Ident LPAREN (funcRParams)? RPAREN - | unaryOp unaryExp; +unaryExp: primaryExp #primExp + | Ident LPAREN (funcRParams)? RPAREN #call + | unaryOp unaryExp #unExp; unaryOp: ADD|SUB|NOT; funcRParams: exp (COMMA exp)*; From a36f73c8a28e3cb3e6e7b888f7447a62ac93af2f Mon Sep 17 00:00:00 2001 From: Downright <12709502+downrighr@user.noreply.gitee.com> Date: Mon, 24 Mar 2025 00:44:52 +0800 Subject: [PATCH 3/9] add file --- README.md | 2 + doc/markdowns/IR.md | 169 +++++++++++++++++++++++++++++++++++++ doc/markdowns/IRbuilder.md | 156 ++++++++++++++++++++++++++++++++++ doc/markdowns/IRcpp.md | 121 ++++++++++++++++++++++++++ src/ASTPrinter.cpp | 140 +++++++++++++----------------- src/ASTPrinter.h | 24 +++--- src/SysYIRGenerator.h | 47 ++++++----- 7 files changed, 549 insertions(+), 110 deletions(-) create mode 100644 doc/markdowns/IR.md create mode 100644 doc/markdowns/IRbuilder.md create mode 100644 doc/markdowns/IRcpp.md diff --git a/README.md b/README.md index 5e63e3e..7e20007 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,8 @@ doxygen doc/Doxyfile 上述命令执行完毕后,将在doxygen/html下找到生成的代码文档。 +该版本还未实现数组初始化定义等功能 + ## 实验3:从SysY IR 生成ARMv7汇编代码 ### 后端相关源码 diff --git a/doc/markdowns/IR.md b/doc/markdowns/IR.md new file mode 100644 index 0000000..412cde3 --- /dev/null +++ b/doc/markdowns/IR.md @@ -0,0 +1,169 @@ +这个头文件定义了一个用于生成中间表示(IR)的数据结构,主要用于编译器前端将抽象语法树(AST)转换为中间代码。以下是文件中定义的主要类和功能的整理和解释: + +--- + +### **1. 类型系统(Type System)** +#### **1.1 `Type` 类** +- **作用**:表示所有基本标量类型(如 `int`、`float`、`void` 等)以及指针类型和函数类型。 +- **成员**: + - `Kind` 枚举:表示类型的种类(如 `kInt`、`kFloat`、`kPointer` 等)。 + - `kind`:当前类型的种类。 + - 构造函数:`Type(Kind kind)`,用于初始化类型。 + - 静态方法:如 `getIntType()`、`getFloatType()` 等,用于获取特定类型的单例对象。 + - 类型检查方法:如 `isInt()`、`isFloat()` 等,用于检查当前类型是否为某种类型。 + - `getSize()`:获取类型的大小。 + - `as()`:将当前类型动态转换为派生类(如 `PointerType` 或 `FunctionType`)。 + +#### **1.2 `PointerType` 类** +- **作用**:表示指针类型,派生自 `Type`。 +- **成员**: + - `baseType`:指针指向的基础类型。 + - 静态方法:`get(Type *baseType)`,用于获取指向 `baseType` 的指针类型。 + - `getBaseType()`:获取指针指向的基础类型。 + +#### **1.3 `FunctionType` 类** +- **作用**:表示函数类型,派生自 `Type`。 +- **成员**: + - `returnType`:函数的返回类型。 + - `paramTypes`:函数的参数类型列表。 + - 静态方法:`get(Type *returnType, const std::vector ¶mTypes)`,用于获取函数类型。 + - `getReturnType()`:获取函数的返回类型。 + - `getParamTypes()`:获取函数的参数类型列表。 + +--- + +### **2. 中间表示(IR)** +#### **2.1 `Value` 类** +- **作用**:表示 IR 中的所有值(如指令、常量、参数等)。 +- **成员**: + - `Kind` 枚举:表示值的种类(如 `kAdd`、`kSub`、`kConstant` 等)。 + - `kind`:当前值的种类。 + - `type`:值的类型。 + - `name`:值的名称。 + - `uses`:值的用途列表(表示哪些指令使用了该值)。 + - 构造函数:`Value(Kind kind, Type *type, const std::string &name)`。 + - 类型检查方法:如 `isInt()`、`isFloat()` 等。 + - `getUses()`:获取值的用途列表。 + - `replaceAllUsesWith(Value *value)`:将该值的所有用途替换为另一个值。 + - `print(std::ostream &os)`:打印值的表示。 + +#### **2.2 `ConstantValue` 类** +- **作用**:表示编译时常量(如整数常量、浮点数常量)。 +- **成员**: + - `iScalar` 和 `fScalar`:分别存储整数和浮点数常量的值。 + - 静态方法:`get(int value)` 和 `get(float value)`,用于获取常量值。 + - `getInt()` 和 `getFloat()`:获取常量的值。 + +#### **2.3 `Argument` 类** +- **作用**:表示函数或基本块的参数。 +- **成员**: + - `block`:参数所属的基本块。 + - `index`:参数的索引。 + - 构造函数:`Argument(Type *type, BasicBlock *block, int index, const std::string &name)`。 + - `getParent()`:获取参数所属的基本块。 + - `getIndex()`:获取参数的索引。 + +#### **2.4 `BasicBlock` 类** +- **作用**:表示基本块,包含一系列指令。 +- **成员**: + - `parent`:基本块所属的函数。 + - `instructions`:基本块中的指令列表。 + - `arguments`:基本块的参数列表。 + - `successors` 和 `predecessors`:基本块的后继和前驱列表。 + - 构造函数:`BasicBlock(Function *parent, const std::string &name)`。 + - `getParent()`:获取基本块所属的函数。 + - `getInstructions()`:获取基本块中的指令列表。 + - `createArgument()`:为基本块创建一个参数。 + +#### **2.5 `Instruction` 类** +- **作用**:表示 IR 中的指令,派生自 `User`。 +- **成员**: + - `Kind` 枚举:表示指令的种类(如 `kAdd`、`kSub`、`kLoad` 等)。 + - `kind`:当前指令的种类。 + - `parent`:指令所属的基本块。 + - 构造函数:`Instruction(Kind kind, Type *type, BasicBlock *parent, const std::string &name)`。 + - `getParent()`:获取指令所属的基本块。 + - `getFunction()`:获取指令所属的函数。 + - 指令分类方法:如 `isBinary()`、`isUnary()`、`isMemory()` 等。 + +#### **2.6 `User` 类** +- **作用**:表示使用其他值的指令或全局值,派生自 `Value`。 +- **成员**: + - `operands`:指令的操作数列表。 + - 构造函数:`User(Kind kind, Type *type, const std::string &name)`。 + - `getOperand(int index)`:获取指定索引的操作数。 + - `addOperand(Value *value)`:添加一个操作数。 + - `replaceOperand(int index, Value *value)`:替换指定索引的操作数。 + +#### **2.7 具体指令类** +- **`CallInst`**:表示函数调用指令。 +- **`UnaryInst`**:表示一元操作指令(如取反、类型转换)。 +- **`BinaryInst`**:表示二元操作指令(如加法、减法)。 +- **`ReturnInst`**:表示返回指令。 +- **`UncondBrInst`**:表示无条件跳转指令。 +- **`CondBrInst`**:表示条件跳转指令。 +- **`AllocaInst`**:表示栈内存分配指令。 +- **`LoadInst`**:表示从内存加载值的指令。 +- **`StoreInst`**:表示将值存储到内存的指令。 + +--- + +### **3. 模块和函数** +#### **3.1 `Function` 类** +- **作用**:表示函数,包含多个基本块。 +- **成员**: + - `parent`:函数所属的模块。 + - `blocks`:函数中的基本块列表。 + - 构造函数:`Function(Module *parent, Type *type, const std::string &name)`。 + - `getReturnType()`:获取函数的返回类型。 + - `getParamTypes()`:获取函数的参数类型列表。 + - `addBasicBlock()`:为函数添加一个基本块。 + +#### **3.2 `GlobalValue` 类** +- **作用**:表示全局变量或常量。 +- **成员**: + - `parent`:全局值所属的模块。 + - `hasInit`:是否有初始化值。 + - `isConst`:是否是常量。 + - 构造函数:`GlobalValue(Module *parent, Type *type, const std::string &name, const std::vector &dims, Value *init)`。 + - `init()`:获取全局值的初始化值。 + +#### **3.3 `Module` 类** +- **作用**:表示整个编译单元(如一个源文件)。 +- **成员**: + - `children`:模块中的所有值(如函数、全局变量)。 + - `functions`:模块中的函数列表。 + - `globals`:模块中的全局变量列表。 + - `createFunction()`:创建一个函数。 + - `createGlobalValue()`:创建一个全局变量。 + - `getFunction()`:获取指定名称的函数。 + - `getGlobalValue()`:获取指定名称的全局变量。 + +--- + +### **4. 工具类** +#### **4.1 `Use` 类** +- **作用**:表示值与其使用者之间的关系。 +- **成员**: + - `index`:值在使用者操作数列表中的索引。 + - `user`:使用者。 + - `value`:被使用的值。 + - 构造函数:`Use(int index, User *user, Value *value)`。 + - `getValue()`:获取被使用的值。 + +#### **4.2 `range` 类** +- **作用**:封装迭代器对 `[begin, end)`,用于遍历容器。 +- **成员**: + - `begin()` 和 `end()`:返回范围的起始和结束迭代器。 + - `size()`:返回范围的大小。 + - `empty()`:判断范围是否为空。 + +--- + +### **5. 总结** +- **类型系统**:`Type`、`PointerType`、`FunctionType` 用于表示 IR 中的类型。 +- **中间表示**:`Value`、`ConstantValue`、`Instruction` 等用于表示 IR 中的值和指令。 +- **模块和函数**:`Module`、`Function`、`GlobalValue` 用于组织 IR 的结构。 +- **工具类**:`Use` 和 `range` 用于辅助实现 IR 的数据结构和遍历。 + +这个头文件定义了一个完整的 IR 数据结构,适用于编译器前端将 AST 转换为中间代码,并支持后续的优化和目标代码生成。 \ No newline at end of file diff --git a/doc/markdowns/IRbuilder.md b/doc/markdowns/IRbuilder.md new file mode 100644 index 0000000..40b5e4b --- /dev/null +++ b/doc/markdowns/IRbuilder.md @@ -0,0 +1,156 @@ +`IRBuilder.h` 文件定义了一个 `IRBuilder` 类,用于简化中间表示(IR)的构建过程。`IRBuilder` 提供了创建各种 IR 指令的便捷方法,并将这些指令插入到指定的基本块中。以下是对文件中主要内容的整理和解释: + +--- + +### **1. `IRBuilder` 类的作用** +`IRBuilder` 是一个工具类,用于在生成中间表示(IR)时简化指令的创建和插入操作。它的主要功能包括: +- 提供创建各种 IR 指令的工厂方法。 +- 将创建的指令插入到指定的基本块中。 +- 支持在基本块的任意位置插入指令。 + +--- + +### **2. 主要成员** + +#### **2.1 成员变量** +- **`block`**:当前操作的基本块。 +- **`position`**:当前操作的插入位置(基本块中的迭代器)。 + +#### **2.2 构造函数** +- **默认构造函数**:`IRBuilder()`。 +- **带参数的构造函数**: + - `IRBuilder(BasicBlock *block)`:初始化 `IRBuilder`,并设置当前基本块和插入位置(默认在基本块末尾)。 + - `IRBuilder(BasicBlock *block, BasicBlock::iterator position)`:初始化 `IRBuilder`,并设置当前基本块和插入位置。 + +#### **2.3 设置方法** +- **`setPosition(BasicBlock *block, BasicBlock::iterator position)`**:设置当前基本块和插入位置。 +- **`setPosition(BasicBlock::iterator position)`**:设置当前插入位置。 + +#### **2.4 获取方法** +- **`getBasicBlock()`**:获取当前基本块。 +- **`getPosition()`**:获取当前插入位置。 + +--- + +### **3. 指令创建方法** +`IRBuilder` 提供了多种工厂方法,用于创建不同类型的 IR 指令。这些方法会将创建的指令插入到当前基本块的指定位置。 + +#### **3.1 函数调用指令** +- **`createCallInst(Function *callee, const std::vector &args, const std::string &name)`**: + - 创建一个函数调用指令。 + - 参数: + - `callee`:被调用的函数。 + - `args`:函数参数列表。 + - `name`:指令的名称(可选)。 + - 返回:`CallInst*`。 + +#### **3.2 一元操作指令** +- **`createUnaryInst(Instruction::Kind kind, Type *type, Value *operand, const std::string &name)`**: + - 创建一个一元操作指令(如取反、类型转换)。 + - 参数: + - `kind`:指令的类型(如 `kNeg`、`kFtoI` 等)。 + - `type`:指令的结果类型。 + - `operand`:操作数。 + - `name`:指令的名称(可选)。 + - 返回:`UnaryInst*`。 + +- **具体一元操作指令**: + - `createNegInst(Value *operand, const std::string &name)`:创建整数取反指令。 + - `createNotInst(Value *operand, const std::string &name)`:创建逻辑取反指令。 + - `createFtoIInst(Value *operand, const std::string &name)`:创建浮点数转整数指令。 + - `createFNegInst(Value *operand, const std::string &name)`:创建浮点数取反指令。 + - `createIToFInst(Value *operand, const std::string &name)`:创建整数转浮点数指令。 + +#### **3.3 二元操作指令** +- **`createBinaryInst(Instruction::Kind kind, Type *type, Value *lhs, Value *rhs, const std::string &name)`**: + - 创建一个二元操作指令(如加法、减法)。 + - 参数: + - `kind`:指令的类型(如 `kAdd`、`kSub` 等)。 + - `type`:指令的结果类型。 + - `lhs` 和 `rhs`:左操作数和右操作数。 + - `name`:指令的名称(可选)。 + - 返回:`BinaryInst*`。 + +- **具体二元操作指令**: + - 整数运算: + - `createAddInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数加法指令。 + - `createSubInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数减法指令。 + - `createMulInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数乘法指令。 + - `createDivInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数除法指令。 + - `createRemInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数取余指令。 + - 整数比较: + - `createICmpEQInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数相等比较指令。 + - `createICmpNEInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数不等比较指令。 + - `createICmpLTInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数小于比较指令。 + - `createICmpLEInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数小于等于比较指令。 + - `createICmpGTInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数大于比较指令。 + - `createICmpGEInst(Value *lhs, Value *rhs, const std::string &name)`:创建整数大于等于比较指令。 + - 浮点数运算: + - `createFAddInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数加法指令。 + - `createFSubInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数减法指令。 + - `createFMulInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数乘法指令。 + - `createFDivInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数除法指令。 + - `createFRemInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数取余指令。 + - 浮点数比较: + - `createFCmpEQInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数相等比较指令。 + - `createFCmpNEInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数不等比较指令。 + - `createFCmpLTInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数小于比较指令。 + - `createFCmpLEInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数小于等于比较指令。 + - `createFCmpGTInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数大于比较指令。 + - `createFCmpGEInst(Value *lhs, Value *rhs, const std::string &name)`:创建浮点数大于等于比较指令。 + +#### **3.4 控制流指令** +- **`createReturnInst(Value *value)`**: + - 创建返回指令。 + - 参数: + - `value`:返回值(可选)。 + - 返回:`ReturnInst*`。 + +- **`createUncondBrInst(BasicBlock *block, std::vector args)`**: + - 创建无条件跳转指令。 + - 参数: + - `block`:目标基本块。 + - `args`:跳转参数(可选)。 + - 返回:`UncondBrInst*`。 + +- **`createCondBrInst(Value *condition, BasicBlock *thenBlock, BasicBlock *elseBlock, const std::vector &thenArgs, const std::vector &elseArgs)`**: + - 创建条件跳转指令。 + - 参数: + - `condition`:跳转条件。 + - `thenBlock`:条件为真时的目标基本块。 + - `elseBlock`:条件为假时的目标基本块。 + - `thenArgs` 和 `elseArgs`:跳转参数(可选)。 + - 返回:`CondBrInst*`。 + +#### **3.5 内存操作指令** +- **`createAllocaInst(Type *type, const std::vector &dims, const std::string &name)`**: + - 创建栈内存分配指令。 + - 参数: + - `type`:分配的类型。 + - `dims`:数组维度(可选)。 + - `name`:指令的名称(可选)。 + - 返回:`AllocaInst*`。 + +- **`createLoadInst(Value *pointer, const std::vector &indices, const std::string &name)`**: + - 创建加载指令。 + - 参数: + - `pointer`:指针值。 + - `indices`:数组索引(可选)。 + - `name`:指令的名称(可选)。 + - 返回:`LoadInst*`。 + +- **`createStoreInst(Value *value, Value *pointer, const std::vector &indices, const std::string &name)`**: + - 创建存储指令。 + - 参数: + - `value`:要存储的值。 + - `pointer`:指针值。 + - `indices`:数组索引(可选)。 + - `name`:指令的名称(可选)。 + - 返回:`StoreInst*`。 + +--- + +### **4. 总结** +- `IRBuilder` 是一个用于简化 IR 构建的工具类,提供了创建各种 IR 指令的工厂方法。 +- 通过 `IRBuilder`,可以方便地在指定基本块的任意位置插入指令。 +- 该类的设计使得 IR 的生成更加模块化和易于维护。 \ No newline at end of file diff --git a/doc/markdowns/IRcpp.md b/doc/markdowns/IRcpp.md new file mode 100644 index 0000000..91cd1bb --- /dev/null +++ b/doc/markdowns/IRcpp.md @@ -0,0 +1,121 @@ +这个 `IR.cpp` 文件实现了 `IR.h` 中定义的中间表示(IR)数据结构的功能。它包含了类型系统、值、指令、基本块、函数和模块的具体实现,以及一些辅助函数用于打印 IR 的内容。以下是对文件中主要内容的整理和解释: + +--- + +### **1. 辅助函数** +#### **1.1 `interleave` 函数** +- **作用**:用于在输出流中插入分隔符(如逗号)来打印容器中的元素。 +- **示例**: + ```cpp + interleave(os, container, ", "); + ``` + +#### **1.2 打印函数** +- **`printVarName`**:打印变量名,全局变量以 `@` 开头,局部变量以 `%` 开头。 +- **`printBlockName`**:打印基本块名,以 `^` 开头。 +- **`printFunctionName`**:打印函数名,以 `@` 开头。 +- **`printOperand`**:打印操作数,如果是常量则直接打印值,否则打印变量名。 + +--- + +### **2. 类型系统** +#### **2.1 `Type` 类的实现** +- **静态方法**: + - `getIntType()`、`getFloatType()`、`getVoidType()`、`getLabelType()`:返回对应类型的单例对象。 + - `getPointerType(Type *baseType)`:返回指向 `baseType` 的指针类型。 + - `getFunctionType(Type *returnType, const vector ¶mTypes)`:返回函数类型。 +- **`getSize()`**:返回类型的大小(如 `int` 和 `float` 为 4 字节,指针为 8 字节)。 +- **`print()`**:打印类型的表示。 + +#### **2.2 `PointerType` 类的实现** +- **静态方法**: + - `get(Type *baseType)`:返回指向 `baseType` 的指针类型,使用 `std::map` 缓存已创建的指针类型。 +- **`getBaseType()`**:返回指针指向的基础类型。 + +#### **2.3 `FunctionType` 类的实现** +- **静态方法**: + - `get(Type *returnType, const vector ¶mTypes)`:返回函数类型,使用 `std::set` 缓存已创建的函数类型。 +- **`getReturnType()`** 和 `getParamTypes()`:分别返回函数的返回类型和参数类型列表。 + +--- + +### **3. 值(Value)** +#### **3.1 `Value` 类的实现** +- **`replaceAllUsesWith(Value *value)`**:将该值的所有用途替换为另一个值。 +- **`isConstant()`**:判断值是否为常量(包括常量值、全局值和函数)。 + +#### **3.2 `ConstantValue` 类的实现** +- **静态方法**: + - `get(int value)` 和 `get(float value)`:返回整数或浮点数常量,使用 `std::map` 缓存已创建的常量。 +- **`getInt()` 和 `getFloat()`**:返回常量的值。 +- **`print()`**:打印常量的值。 + +#### **3.3 `Argument` 类的实现** +- **构造函数**:初始化参数的类型、所属基本块和索引。 +- **`print()`**:打印参数的表示。 + +--- + +### **4. 基本块(BasicBlock)** +#### **4.1 `BasicBlock` 类的实现** +- **构造函数**:初始化基本块的名称和所属函数。 +- **`print()`**:打印基本块的表示,包括参数和指令。 + +--- + +### **5. 指令(Instruction)** +#### **5.1 `Instruction` 类的实现** +- **构造函数**:初始化指令的类型、所属基本块和名称。 +- **`print()`**:由具体指令类实现。 + +#### **5.2 具体指令类的实现** +- **`CallInst`**:表示函数调用指令。 + - **`print()`**:打印函数调用的表示。 +- **`UnaryInst`**:表示一元操作指令(如取反、类型转换)。 + - **`print()`**:打印一元操作的表示。 +- **`BinaryInst`**:表示二元操作指令(如加法、减法)。 + - **`print()`**:打印二元操作的表示。 +- **`ReturnInst`**:表示返回指令。 + - **`print()`**:打印返回指令的表示。 +- **`UncondBrInst`**:表示无条件跳转指令。 + - **`print()`**:打印无条件跳转的表示。 +- **`CondBrInst`**:表示条件跳转指令。 + - **`print()`**:打印条件跳转的表示。 +- **`AllocaInst`**:表示栈内存分配指令。 + - **`print()`**:打印内存分配的表示。 +- **`LoadInst`**:表示从内存加载值的指令。 + - **`print()`**:打印加载指令的表示。 +- **`StoreInst`**:表示将值存储到内存的指令。 + - **`print()`**:打印存储指令的表示。 + +--- + +### **6. 函数(Function)** +#### **6.1 `Function` 类的实现** +- **构造函数**:初始化函数的名称、返回类型和参数类型。 +- **`print()`**:打印函数的表示,包括基本块和指令。 + +--- + +### **7. 模块(Module)** +#### **7.1 `Module` 类的实现** +- **`print()`**:打印模块的表示,包括所有函数和全局变量。 + +--- + +### **8. 用户(User)** +#### **8.1 `User` 类的实现** +- **`setOperand(int index, Value *value)`**:设置指定索引的操作数。 +- **`replaceOperand(int index, Value *value)`**:替换指定索引的操作数,并更新用途列表。 + +--- + +### **9. 总结** +- **类型系统**:实现了 `Type`、`PointerType` 和 `FunctionType`,用于表示 IR 中的类型。 +- **值**:实现了 `Value`、`ConstantValue` 和 `Argument`,用于表示 IR 中的值和参数。 +- **基本块**:实现了 `BasicBlock`,用于组织指令。 +- **指令**:实现了多种具体指令类(如 `CallInst`、`BinaryInst` 等),用于表示 IR 中的操作。 +- **函数和模块**:实现了 `Function` 和 `Module`,用于组织 IR 的结构。 +- **打印功能**:通过 `print()` 方法,可以将 IR 的内容输出为可读的文本格式。 + +这个文件是编译器中间表示的核心实现,能够将抽象语法树(AST)转换为中间代码,并支持后续的优化和目标代码生成。 \ No newline at end of file diff --git a/src/ASTPrinter.cpp b/src/ASTPrinter.cpp index 1b05d6c..d283c7c 100644 --- a/src/ASTPrinter.cpp +++ b/src/ASTPrinter.cpp @@ -133,69 +133,58 @@ std::any ASTPrinter::visitBlockStmt(SysYParser::BlockStmtContext *ctx){ } // std::any ASTPrinter::visitBlockItem(SysYParser::BlockItemContext *ctx); -std::any ASTPrinter::visitStmt(SysYParser::StmtContext *ctx){ - if(ctx->lValue()&& ctx->exp()) { - cout << getIndent(); - ctx->lValue()->accept(this); - cout << ' ' << ctx->ASSIGN()->getText() <<' '; +std::any ASTPrinter::visitAssignStmt(SysYParser::AssignStmtContext *ctx){ + ctx->lValue()->accept(this); + cout << ' ' << ctx->ASSIGN()->getText() << ' '; + ctx->exp()->accept(this); + cout << ctx->SEMICOLON()->getText() << '\n'; + return nullptr; +} + +std::any ASTPrinter::visitExpStmt(SysYParser::ExpStmtContext *ctx){ + if (ctx->exp()) { ctx->exp()->accept(this); - cout << ctx->SEMICOLON()->getText() << endl; } - else if(ctx->blockStmt()){ - ctx->blockStmt()->accept(this); + cout << ctx->SEMICOLON()->getText() << '\n'; + return nullptr; +} + +std::any ASTPrinter::visitIfStmt(SysYParser::IfStmtContext *ctx){ + cout << getIndent() << ctx->IF()->getText() << ' ' << ctx->LPAREN()->getText(); + ctx->cond()->accept(this); + cout << ctx->RPAREN()->getText() << ' '; + ctx->stmt(0)->accept(this); + if (ctx->ELSE()) { + cout << getIndent() << ctx->ELSE()->getText() << ' '; + ctx->stmt(1)->accept(this); } - else if(ctx->IF()){ - cout << getIndent() << "if ("; - ctx->cond()->accept(this); - cout << ")"; - // visit ctx->stmt(0) to judge if it is a blockStmt or a Lvale=exp - if(ctx->stmt(0)->blockStmt())ctx->stmt(0)->accept(this); - else{ - cout << " {"<< endl; - indentLevel++; - ctx->stmt(0)->accept(this); - indentLevel--; - cout << getIndent() << "}" << endl; - } - if (ctx->stmt().size() > 1) { - cout << getIndent() << "else"; - if(ctx->stmt(1)->blockStmt())ctx->stmt(1)->accept(this); - else{ - cout << " {"<< endl; - indentLevel++; - ctx->stmt(1)->accept(this); - indentLevel--; - cout << getIndent() << "}" << endl; - } - } - } - else if(ctx->WHILE()){ - cout << getIndent() << "while ("; - ctx->cond()->accept(this); - cout << ")"; - if(ctx->stmt(0)->blockStmt())ctx->stmt(0)->accept(this); - else{ - cout << " {"<< endl; - indentLevel++; - ctx->stmt(0)->accept(this); - indentLevel--; - cout << getIndent() << "}" << endl; - } - } - else if(ctx->BREAK()){ - cout << getIndent() << "break;" << endl; - } - else if(ctx->CONTINUE()){ - cout << getIndent() << "continue;" << endl; - } - else if(ctx->RETURN()){ - cout << getIndent() << "return"; - if(ctx->exp()){ - cout << ' '; - ctx->exp()->accept(this); - } - cout << ctx->SEMICOLON()->getText() << endl; + return nullptr; +} + +std::any ASTPrinter::visitWhileStmt(SysYParser::WhileStmtContext *ctx){ + cout << getIndent() << ctx->WHILE()->getText() << ' ' << ctx->LPAREN()->getText(); + ctx->cond()->accept(this); + cout << ctx->RPAREN()->getText() << ' '; + ctx->stmt()->accept(this); + return nullptr; +} + +std::any ASTPrinter::visitBreakStmt(SysYParser::BreakStmtContext *ctx){ + cout << getIndent() << ctx->BREAK()->getText() << ctx->SEMICOLON()->getText() << '\n'; + return nullptr; +} + +std::any ASTPrinter::visitContinueStmt(SysYParser::ContinueStmtContext *ctx){ + cout << getIndent() << ctx->CONTINUE()->getText() << ctx->SEMICOLON()->getText() << '\n'; + return nullptr; +} + +std::any ASTPrinter::visitReturnStmt(SysYParser::ReturnStmtContext *ctx){ + cout << getIndent() << ctx->RETURN()->getText() << ' '; + if (ctx->exp()) { + ctx->exp()->accept(this); } + cout << ctx->SEMICOLON()->getText() << '\n'; return nullptr; } @@ -211,6 +200,12 @@ std::any ASTPrinter::visitLValue(SysYParser::LValueContext *ctx){ return nullptr; } // std::any ASTPrinter::visitPrimaryExp(SysYParser::PrimaryExpContext *ctx); +std::any ASTPrinter::visitParenExp(SysYParser::ParenExpContext *ctx){ + cout << ctx->LPAREN()->getText(); + ctx->exp()->accept(this); + cout << ctx->RPAREN()->getText(); + return nullptr; +} std::any ASTPrinter::visitNumber(SysYParser::NumberContext *ctx) { if(ctx->ILITERAL())cout << ctx->ILITERAL()->getText(); @@ -222,28 +217,15 @@ std::any ASTPrinter::visitString(SysYParser::StringContext *ctx) { cout << ctx->STRING()->getText(); return nullptr; } - -std::any ASTPrinter::visitUnaryExp(SysYParser::UnaryExpContext *ctx){ - if(ctx->primaryExp()) - ctx->primaryExp()->accept(this); - else if(ctx->Ident()){ - cout << ctx->Ident()->getText() << ctx->LPAREN()->getText(); - if(ctx->funcRParams()) - ctx->funcRParams()->accept(this); - if (ctx->RPAREN()) - cout << ctx->RPAREN()->getText(); - else - cout << ""; - } - else if(ctx->unaryExp()){ - cout << ctx->unaryOp()->getText(); - ctx->unaryExp()->accept(this); - } - else - ctx->accept(this); +// std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx); +// std::any ASTPrinter::visitUnaryOp(SysYParser::UnaryOpContext *ctx); +std::any ASTPrinter::visitCall(SysYParser::CallContext *ctx){ + cout << ctx->Ident()->getText() << ctx->LPAREN()->getText(); + if(ctx->funcRParams()) + ctx->funcRParams()->accept(this); + cout << ctx->RPAREN()->getText(); return nullptr; } -// std::any ASTPrinter::visitUnaryOp(SysYParser::UnaryOpContext *ctx); any ASTPrinter::visitFuncRParams(SysYParser::FuncRParamsContext *ctx) { if (ctx->exp().empty()) diff --git a/src/ASTPrinter.h b/src/ASTPrinter.h index 8c55383..31b4863 100644 --- a/src/ASTPrinter.h +++ b/src/ASTPrinter.h @@ -26,23 +26,27 @@ public: std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override; std::any visitBlockStmt(SysYParser::BlockStmtContext *ctx) override; - // std::any visitAssignStmt(SysYParser::AssignStmtContext *ctx) override; - // std::any visitExpStmt(SysYParser::ExpStmtContext *ctx) override; - // std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override; - // std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override; - // std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override; - // std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override; - // std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override; - // std::any visitBlockItem(SysYParser::BlockItemContext *ctx) override; - std::any visitStmt(SysYParser::StmtContext *ctx) override; + // std::any visitStmt(SysYParser::StmtContext *ctx) override; + + std::any visitAssignStmt(SysYParser::AssignStmtContext *ctx) override; + std::any visitExpStmt(SysYParser::ExpStmtContext *ctx) override; + std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override; + std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override; + std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override; + std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override; + std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override; + // std::any visitExp(SysYParser::ExpContext *ctx) override; // std::any visitCond(SysYParser::CondContext *ctx) override; std::any visitLValue(SysYParser::LValueContext *ctx) override; // std::any visitPrimaryExp(SysYParser::PrimaryExpContext *ctx) override; + std::any visitParenExp(SysYParser::ParenExpContext *ctx) override; std::any visitNumber(SysYParser::NumberContext *ctx) override; std::any visitString(SysYParser::StringContext *ctx) override; - std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override; + // std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override; + std::any visitCall(SysYParser::CallContext *ctx) override; + // std::any visitUnExpOp(SysYParser::UnExpContext *ctx) override; // std::any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override; std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override; std::any visitMulExp(SysYParser::MulExpContext *ctx) override; diff --git a/src/SysYIRGenerator.h b/src/SysYIRGenerator.h index b0419a6..fb1ef33 100644 --- a/src/SysYIRGenerator.h +++ b/src/SysYIRGenerator.h @@ -77,7 +77,9 @@ private: std::unique_ptr module; IRBuilder builder; SymbolTable symbols_table; - //array init use variables + + static Type current_type; + int d = 0, n = 0; vector path; bool isalloca; @@ -94,39 +96,42 @@ public: public: std::any visitCompUnit(SysYParser::CompUnitContext *ctx) override; - std::any visitDecl(SysYParser::DeclContext *ctx) override; - std::any visitConstDecl(SysYParser::ConstDeclContext *ctx) override; - std::any visitBType(SysYParser::BTypeContext *ctx) override; - std::any visitConstDef(SysYParser::ConstDefContext *ctx) override; - std::any visitConstInitVal(SysYParser::ConstInitValContext *ctx) override; - std::any visitFuncType(SysYParser::FuncTypeContext* ctx) override; - std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override; - - std::any visitVarDecl(SysYParser::VarDeclContext *ctx) override; - - std::any visitVarDef(SysYParser::VarDefContext *ctx, Type* btype); - + // std::any visitVarDef(SysYParser::VarDefContext *ctx) override; + std::any visitInitVal(SysYParser::InitValContext *ctx) override; std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override; - std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override; - std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx) override; - - std::any visitStmt(SysYParser::StmtContext *ctx) override; - - std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override; - + // std::any visitStmt(SysYParser::StmtContext *ctx) override; + std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override; + std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override; + std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override; + std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override; + std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override; + std::any visitExp(SysYParser::ExpContext *ctx) override; + std::any visitLValue(SysYParser::LValueContext *ctx) override; + // std::any visitPrimaryExp(SysYParser::PrimaryExpContext *ctx) override; + std::any visitParenExp(SysYParser::ParenExpContext *ctx) override; std::any visitNumber(SysYParser::NumberContext *ctx) override; - std::any visitString(SysYParser::StringContext *ctx) override; + std::any visitCall(SysYParser::CallContext *ctx) override; + // std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override; + std::any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override; + std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override; + std::any visitMulExp(SysYParser::MulExpContext *ctx) override; + std::any visitAddExp(SysYParser::AddExpContext *ctx) override; + std::any visitRelExp(SysYParser::RelExpContext *ctx) override; + std::any visitEqExp(SysYParser::EqExpContext *ctx) override; + std::any visitLAndExp(SysYParser::LAndExpContext *ctx) override; + std::any visitLOrExp(SysYParser::LOrExpContext *ctx) override; + std::any visitConstExp(SysYParser::ConstExpContext *ctx) override; private: std::any visitConstGlobalDecl(SysYParser::ConstDeclContext *ctx, Type* type); From 7f364abffbc3f0f617ad6c6e6a272dadd0e2a49a Mon Sep 17 00:00:00 2001 From: Downright <12709502+downrighr@user.noreply.gitee.com> Date: Mon, 24 Mar 2025 19:06:49 +0800 Subject: [PATCH 4/9] frame finished but bad_any_cast --- README.md | 7 +- src/ASTPrinter.cpp | 16 +- src/SysYIRGenerator.cpp | 831 +++++++++++++++++++++++++++++++++++----- src/SysYIRGenerator.h | 22 +- 4 files changed, 759 insertions(+), 117 deletions(-) diff --git a/README.md b/README.md index 7e20007..244e029 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,8 @@ sudo apt install -y uuid-dev libutfcpp-dev pkg-config make git cmake openjdk-11- git clone https://gitee.com/xsu1989/sysy.git cd sysy cmake -S . -B build -cmake --build build +cmake --build build --target all -- -j $(nproc) +cmake --build build --target all -- -j $(nproc) -DCMAKE_BUILD_TYPE=Debug ``` 构建完成后,可以运行一个小的测试用例。该测试将逗号分隔的整数或字符串列表进行格式化后重新输出,即将相邻参数之间的分隔统一调整为逗号外加一个空格。 @@ -81,7 +82,7 @@ cmake_install.cmake SysYBaseVisitor.h SysYLexer.cpp SysYLexer.interp SysYP 完成格式化器进阶内容后,可以通过执行`sysyc`观察格式化器的执行效果。 ```bash -./build/sysyc -f test/format-test.sy +./build/bin/sysyc -f test/format-test.sy ``` ## 实验2:从AST生成中间表示 @@ -100,7 +101,7 @@ cmake_install.cmake SysYBaseVisitor.h SysYLexer.cpp SysYLexer.interp SysYP 完成实验2后,可以通过执行`sysyc`观察生成的IR。 ```bash -./build/sysyc -s ir 01_add.sy +./build/bin/sysyc -s ir test/01_add.sy ``` 请同学们仔细阅读代码学习IR的定义。可以使用doxygen工具自动生成HTML文档 diff --git a/src/ASTPrinter.cpp b/src/ASTPrinter.cpp index d283c7c..a29383e 100644 --- a/src/ASTPrinter.cpp +++ b/src/ASTPrinter.cpp @@ -124,7 +124,7 @@ std::any ASTPrinter::visitFuncFParam(SysYParser::FuncFParamContext *ctx){ } std::any ASTPrinter::visitBlockStmt(SysYParser::BlockStmtContext *ctx){ - cout << ' ' << ctx->LBRACE()->getText() << endl; + cout << ctx->LBRACE()->getText() << endl; indentLevel++; for (auto item : ctx->blockItem()) item->accept(this); indentLevel--; @@ -134,6 +134,7 @@ std::any ASTPrinter::visitBlockStmt(SysYParser::BlockStmtContext *ctx){ // std::any ASTPrinter::visitBlockItem(SysYParser::BlockItemContext *ctx); std::any ASTPrinter::visitAssignStmt(SysYParser::AssignStmtContext *ctx){ + cout << getIndent(); ctx->lValue()->accept(this); cout << ' ' << ctx->ASSIGN()->getText() << ' '; ctx->exp()->accept(this); @@ -142,6 +143,7 @@ std::any ASTPrinter::visitAssignStmt(SysYParser::AssignStmtContext *ctx){ } std::any ASTPrinter::visitExpStmt(SysYParser::ExpStmtContext *ctx){ + cout << getIndent(); if (ctx->exp()) { ctx->exp()->accept(this); } @@ -153,7 +155,17 @@ std::any ASTPrinter::visitIfStmt(SysYParser::IfStmtContext *ctx){ cout << getIndent() << ctx->IF()->getText() << ' ' << ctx->LPAREN()->getText(); ctx->cond()->accept(this); cout << ctx->RPAREN()->getText() << ' '; - ctx->stmt(0)->accept(this); + //格式化有问题 + if(ctx->stmt(0)) { + ctx->stmt(0)->accept(this); + } + else { + cout << '{' << endl; + indentLevel++; + ctx->stmt(0)->accept(this); + indentLevel--; + cout << getIndent() << '}' << endl; + } if (ctx->ELSE()) { cout << getIndent() << ctx->ELSE()->getText() << ' '; ctx->stmt(1)->accept(this); diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp index 94e7640..0f6bc2e 100644 --- a/src/SysYIRGenerator.cpp +++ b/src/SysYIRGenerator.cpp @@ -21,9 +21,55 @@ std::any SysYIRGenerator::visitCompUnit(SysYParser::CompUnitContext *ctx) { // 待添加运行时库函数getint等 // generates globals and functions + auto type_i32 = Type::getIntType(); + auto type_f32 = Type::getFloatType(); + auto type_void = Type::getVoidType(); + auto type_i32p = Type::getPointerType(type_i32); + auto type_f32p = Type::getPointerType(type_f32); - visitChildren(ctx); - // return the IR module + //runtime library + module->createFunction("getint", Type::getFunctionType(type_i32, {})); + module->createFunction("getch", Type::getFunctionType(type_i32, {})); + module->createFunction("getfloat", Type::getFunctionType(type_f32, {})); + symbols_table.insert("getint", module->getFunction("getint")); + symbols_table.insert("getch", module->getFunction("getch")); + symbols_table.insert("getfloat", module->getFunction("getfloat")); + + module->createFunction("getarray", Type::getFunctionType(type_i32, {type_i32p})); + module->createFunction("getfarray", Type::getFunctionType(type_i32, {type_f32p})); + symbols_table.insert("getarray", module->getFunction("getarray")); + symbols_table.insert("getfarray", module->getFunction("getfarray")); + + module->createFunction("putint", Type::getFunctionType(type_void, {type_i32})); + module->createFunction("putch", Type::getFunctionType(type_void, {type_i32})); + module->createFunction("putfloat", Type::getFunctionType(type_void, {type_f32})); + symbols_table.insert("putint", module->getFunction("putint")); + symbols_table.insert("putch", module->getFunction("putch")); + symbols_table.insert("putfloat", module->getFunction("putfloat")); + + module->createFunction("putarray", Type::getFunctionType(type_void, {type_i32, type_i32p})); + module->createFunction("putfarray", Type::getFunctionType(type_void, {type_i32, type_f32p})); + symbols_table.insert("putarray", module->getFunction("putarray")); + symbols_table.insert("putfarray", module->getFunction("putfarray")); + + module->createFunction("putf", Type::getFunctionType(type_void, {})); + symbols_table.insert("putf", module->getFunction("putf")); + + module->createFunction("starttime", Type::getFunctionType(type_void, {type_i32})); + module->createFunction("stoptime", Type::getFunctionType(type_void, {type_i32})); + symbols_table.insert("starttime", module->getFunction("starttime")); + symbols_table.insert("stoptime", module->getFunction("stoptime")); + + // visit all decls and funcDefs + for(auto decl:ctx->decl()){ + decl->accept(this); + } + for(auto funcDef:ctx->funcDef()){ + builder = IRBuilder(); + printf("entry funcDef\n"); + funcDef->accept(this); + } + // return the IR module ? return pModule; } @@ -37,39 +83,706 @@ std::any SysYIRGenerator::visitCompUnit(SysYParser::CompUnitContext *ctx) { * we consider them together? not sure */ std::any SysYIRGenerator::visitDecl(SysYParser::DeclContext *ctx) { - if(ctx->constDecl()){ + if(ctx->constDecl()) return visitConstDecl(ctx->constDecl()); - }else if(ctx->varDecl()){ + else if(ctx->varDecl()) return visitVarDecl(ctx->varDecl()); - } - return nullptr; + std::cerr << "error unkown decl" << ctx->getText() << std::endl; + return std::any(); } /* * @brief: visit constdecl * @details: * constDecl: CONST bType constDef (COMMA constDef)* SEMI; + * constDef: Ident (LBRACK constExp RBRACK)* (ASSIGN constInitVal)?; */ std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext *ctx) { - auto type = Type::getPointerType(any_cast(ctx->bType()->accept(this))); - if(symbols_table.isModuleScope()) - visitConstGlobalDecl(ctx, type); - else - visitConstLocalDecl(ctx, type); + cout << "visitconstDecl" << endl; + current_type = any_cast(ctx->bType()->accept(this)); + for(auto constDef:ctx->constDef()){ + constDef->accept(this); + } return std::any(); } - /* * @brief: visit btype * @details: * bType: INT | FLOAT; */ std::any SysYIRGenerator::visitBType(SysYParser::BTypeContext *ctx) { - return ctx->INT() ? Type::getIntType() : Type::getFloatType(); + if(ctx->INT()) + return Type::getIntType(); + else if(ctx->FLOAT()) + return Type::getFloatType(); + std::cerr << "error: unknown type" << ctx->getText() << std::endl; + return std::any(); } -// std::any visitConstDef(SysYParser::ConstDefContext *ctx); +/* + * @brief: visit constDef + * @details: + * constDef: Ident (LBRACK constExp RBRACK)* (ASSIGN constInitVal)?; + * constInitVal: constExp | LBRACE (constInitVal (COMMA constInitVal)*)? RBRACE; + */ +std::any SysYIRGenerator::visitConstDef(SysYParser::ConstDefContext *ctx){ + auto name = ctx->Ident()->getText(); + auto type = current_type; + auto init = ctx->constInitVal() ? any_cast(ctx->constInitVal()->accept(this)) : (Value *)nullptr; + if (ctx->constExp().empty()){ + //scalar + if(init){ + if(symbols_table.isModuleScope()){ + assert(init->isConstant() && "global must be initialized by constant"); + auto global = module->createGlobalValue(name, type, {}, init); + symbols_table.insert(name, global); + } + else{ + auto alloca = builder.createAllocaInst(type, {}, name); + auto store = builder.createStoreInst(init, alloca); + symbols_table.insert(name, alloca); + } + } + else{ + assert(false && "const without initialization"); + } + } + else{ + //array + std::cerr << "array constDef not implemented yet" << std::endl; + } + printf("visitConstDef %s\n",name.c_str()); + return std::any(); +} + + +/* + * @brief: visit constInitVal + * @details: + * constInitVal: constExp + * | LBRACE (constInitVal (COMMA constInitVal)*)? RBRACE; + */ +std::any SysYIRGenerator::visitConstInitVal(SysYParser::ConstInitValContext *ctx){ + Value* initvalue; + if(ctx->constExp()) + initvalue = any_cast(ctx->constExp()->accept(this)); + else{ + //还未实现数组初始化等功能待验证 + std::cerr << "array initvalue not implemented yet" << std::endl; + // auto numConstInitVals = ctx->constInitVal().size(); + // vector initvalues; + // for(int i = 0; i < numConstInitVals; i++) + // initvalues.push_back(any_cast(ctx->constInitVal(i)->accept(this))); + // initvalue = ConstantValue::getArray(initvalues); + } + return initvalue; +} + +/* + * @brief: visit function type + * @details: + * funcType: VOID | INT | FLOAT; + */ +std::any SysYIRGenerator::visitFuncType(SysYParser::FuncTypeContext* ctx){ + if(ctx->INT()) + return Type::getIntType(); + else if(ctx->FLOAT()) + return Type::getFloatType(); + else if(ctx->VOID()) + return Type::getVoidType(); + std::cerr << "invalid function type: " << ctx->getText() << std::endl; + return std::any(); +} + +/* + * @brief: visit function define + * @details: + * funcDef: funcType Ident LPAREN funcFParams? RPAREN blockStmt; + * funcFParams: funcFParam (COMMA funcFParam)*; + * funcFParam: bType Ident (LBRACK RBRACK (LBRACK exp RBRACK)*)?; + * entry -> next -> others -> exit + * entry: allocas, br + * next: retval, params, br + * other: blockStmt init block + * exit: load retval, ret + */ +std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext* ctx){ + + auto funcName = ctx->Ident()->getText(); + auto returnType = any_cast(ctx->funcType()->accept(this)); + auto func = module->getFunction(funcName); + + cout << "func: "; + returnType->print(cout); + cout << ' '<< funcName.c_str() << endl; + + vector paramTypes; + vector paramNames; + + if(ctx->funcFParams()){ + for(auto funcParam:ctx->funcFParams()->funcFParam()){ + Type* paramType = any_cast(funcParam->bType()->accept(this)); + paramTypes.push_back(paramType); + paramNames.push_back(funcParam->Ident()->getText()); + } + } + + + auto funcType = FunctionType::get(returnType, paramTypes); + auto function = module->createFunction(funcName, funcType); + + SymbolTable::FunctionScope scope(symbols_table); + BasicBlock* entryblock = function->getEntryBlock(); + for(size_t i = 0; i < paramTypes.size(); i++) + entryblock->createArgument(paramTypes[i], paramNames[i]); + + for(auto& arg: entryblock->getArguments()) + symbols_table.insert(arg->getName(), arg.get()); + builder.setPosition(entryblock, entryblock->end()); + + ctx->blockStmt()->accept(this); + + return std::any(); +} + +/* + * @brief: visit varDecl + * @details: + * varDecl: bType varDef (COMMA varDef)* SEMI; + */ +std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx){ + cout << "visitVarDecl" << endl; + current_type = any_cast(ctx->bType()->accept(this)); + for(auto varDef:ctx->varDef()){ + varDef->accept(this); + } + return std::any(); +} + +/* + * @brief: visit varDef + * @details: + * varDef: Ident (LBRACK constExp RBRACK)* (ASSIGN initVal)?; + */ +std::any SysYIRGenerator::visitVarDef(SysYParser::VarDefContext *ctx){ + auto name = ctx->Ident()->getText(); + auto type = current_type; + auto init = ctx->initVal() ? any_cast(ctx->initVal()->accept(this)) : (Value *)nullptr; + + cout << "vardef: "; + current_type->print(cout); + cout << ' ' << name << endl; + + if(ctx->constExp().empty()){ + //scalar + if(symbols_table.isModuleScope()){ + + if(init) + assert(init->isConstant() && "global must be initialized by constant"); + auto global = module->createGlobalValue(name, type, {}, init); + symbols_table.insert(name, global); + cout << "add module var " << name << "inited by " ; + init->print(cout); + cout << '\n'; + } + else{ + auto alloca = builder.createAllocaInst(type, {}, name); + auto store = (StoreInst *)nullptr; + if(init) + store = builder.createStoreInst(init, alloca); + symbols_table.insert(name, alloca); + cout << "add local var " << name ; + if(init){ + cout << "inited by " ; + init->print(cout); + } + cout << '\n'; + } + } + else{ + //array + std::cerr << "array varDef not implemented yet" << std::endl; + } + return std::any(); +} + +/* + * @brief: visit initVal + * @details: + * initVal: exp | LBRACE (initVal (COMMA initVal)*)? RBRACE; + */ +std::any SysYIRGenerator::visitInitVal(SysYParser::InitValContext *ctx) { + Value* initvalue; + if(ctx->exp()) + initvalue = any_cast(ctx->exp()->accept(this)); + else{ + //还未实现数组初始化等功能待验证 + std::cerr << "array initvalue not implemented yet" << std::endl; + // auto numConstInitVals = ctx->constInitVal().size(); + // vector initvalues; + // for(int i = 0; i < numConstInitVals; i++) + // initvalues.push_back(any_cast(ctx->constInitVal(i)->accept(this))); + // initvalue = ConstantValue::getArray(initvalues); + } + return initvalue; +} + +// std::any SysYIRGenerator::visitFuncFParams(SysYParser::FuncFParamsContext* ctx){ +// return visitChildren(ctx); +// } +// std::any SysYIRGenerator::visitFuncFParam(SysYParser::FuncFParamContext *ctx) { +// return visitChildren(ctx); +// } + +/* + * @brief: visit blockStmt + * @details: + * blockStmt: LBRACE blockItem* RBRACE; + * blockItem: decl | stmt; + */ +std::any SysYIRGenerator::visitBlockStmt(SysYParser::BlockStmtContext* ctx){ + SymbolTable::BlockScope scope(symbols_table); + for (auto item : ctx->blockItem()){ + item->accept(this); + // if(builder.getBasicBlock()->isTerminal()){ + // break; + // } + } + return std::any(); +} + +/* + * @brief: visit ifstmt + * @details: + * ifStmt: IF LPAREN cond RPAREN stmt (ELSE stmt)?; + */ +std::any SysYIRGenerator::visitIfStmt(SysYParser::IfStmtContext *ctx) { + auto condition = any_cast(ctx->cond()->accept(this)); + + auto thenBlock = builder.getBasicBlock()->getParent()->addBasicBlock("then"); + auto elseBlock = builder.getBasicBlock()->getParent()->addBasicBlock("else"); + + auto condbr = builder.createCondBrInst(condition,thenBlock,elseBlock,{},{}); + + builder.setPosition(thenBlock, thenBlock->end()); + ctx->stmt(0)->accept(this); + + if(ctx->ELSE()){ + builder.setPosition(elseBlock, elseBlock->end()); + ctx->stmt(1)->accept(this); + } + //无条件跳转到下一个基本块 + // builder.createUncondBrInst(builder.getBasicBlock()->getParent()->addBasicBlock("next"),{}); + return std::any(); +} + +/* + * @brief: visit whilestmt + * @details: + * whileStmt: WHILE LPAREN cond RPAREN stmt; + */ + + std::any SysYIRGenerator::visitWhileStmt(SysYParser::WhileStmtContext* ctx) { + //需要解决一个函数多个循环的命名问题 + auto header = builder.getBasicBlock()->getParent()->addBasicBlock("header"); + auto body = builder.getBasicBlock()->getParent()->addBasicBlock("body"); + auto exit = builder.getBasicBlock()->getParent()->addBasicBlock("exit"); + + SymbolTable::BlockScope scope(symbols_table); + + { // visit header block + builder.setPosition(header, header->end()); + auto cond = any_cast(ctx->cond()->accept(this)); + auto condbr = builder.createCondBrInst(cond, body, exit, {}, {}); + } + + { // visit body block + builder.setPosition(body, body->end()); + ctx->stmt()->accept(this); + auto uncondbr = builder.createUncondBrInst(header, {}); + } + + // visit exit block + builder.setPosition(exit, exit->end()); + //无条件跳转到下一个基本块以及一些参数传递 + + return std::any(); +} + +/* + * @brief: visit breakstmt + * @details: + * breakStmt: BREAK SEMICOLON; + */ +std::any SysYIRGenerator::visitBreakStmt(SysYParser::BreakStmtContext* ctx) { + //如何获取break所在body对应的header块 + return std::any(); +} +/* + * @brief Visit ReturnStmt + * returnStmt: RETURN exp? SEMICOLON; + */ +std::any SysYIRGenerator::visitReturnStmt(SysYParser::ReturnStmtContext* ctx) { + // auto value = ctx->exp() ? any_cast_Value(visit(ctx->exp())) : nullptr; + auto value = ctx->exp() ? any_cast(ctx->exp()->accept(this)) : nullptr; + + const auto func = builder.getBasicBlock()->getParent(); + + assert(func && "ret stmt block parent err!"); + + // 匹配 返回值类型 与 函数定义类型 + if (func->getReturnType()->isVoid()) { + if (ctx->exp()) + assert(false && "the returned value is not matching the function"); + + auto ret = builder.createReturnInst(); + return std::any(); + } + + assert(ctx->exp() && "the returned value is not matching the function"); + + auto ret = builder.createReturnInst(value); + + //需要增加无条件跳转吗 + return std::any(); +} + +/* + * @brief: visit continuestmt + * @details: + * continueStmt: CONTINUE SEMICOLON; + */ +std::any SysYIRGenerator::visitContinueStmt(SysYParser::ContinueStmtContext* ctx) { + //如何获取continue所在body对应的header块 + return std::any(); +} + + +/* + * @brief visit assign stmt + * @details: + * assignStmt: lValue ASSIGN exp SEMICOLON + */ +std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext* ctx) { + cout << "visitassignstme :\n"; + auto lvalue = any_cast(ctx->lValue()->accept(this)); + cout << 'lval: (' << lvalue->getName() ; + auto rvalue = any_cast(ctx->exp()->accept(this)); + //可能要考虑类型转换例如int a = 1.0 + builder.createStoreInst(rvalue, lvalue); + + cout << ') = rval(' << rvalue->getName(); + + + return std::any(); +} + +/* + * @brief: visit lValue + * @details: + * lValue: Ident (LBRACK exp RBRACK)*; + */ +std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext* ctx) { + auto name = ctx->Ident()->getText(); + Value* value = symbols_table.lookup(name); + + assert(value && "lvalue not found"); + + if(ctx->exp().size() == 0){ + //scalar + cout << "lvalue: " << name << endl; + return value; + } + else{ + //array + std::cerr << "array lvalue not implemented yet" << std::endl; + } + std::cerr << "error lvalue" << ctx->getText() << std::endl; + return std::any(); +} + + + +std::any SysYIRGenerator::visitNumber(SysYParser::NumberContext *ctx) { + ConstantValue* res = nullptr; + if (auto iLiteral = ctx->ILITERAL()) { + /* 基数 (8, 10, 16) */ + const auto text = iLiteral->getText(); + int base = 10; + if (text.find("0x") == 0 || text.find("0X") == 0) { + base = 16; + } else if (text.find("0b") == 0 || text.find("0B") == 0) { + base = 2; + } else if (text.find("0") == 0) { + base = 8; + } + res = ConstantValue::get((int)std::stol(text, 0, base)); + } else if (auto fLiteral = ctx->FLITERAL()) { + const auto text = fLiteral->getText(); + res = ConstantValue::get((float)std::stof(text)); + } + return res; +} + +/* + * @brief: visit call + * @details: + * call: Ident LPAREN funcRParams? RPAREN; + */ +std::any SysYIRGenerator::visitCall(SysYParser::CallContext* ctx) { + auto funcName = ctx->Ident()->getText(); + auto func = module->getFunction(funcName); + assert(func && "function not found"); + + //需要做类型检查和转换 + std::vector args; + if(ctx->funcRParams()){ + for(auto exp:ctx->funcRParams()->exp()){ + args.push_back(any_cast(exp->accept(this))); + } + } + auto call = builder.createCallInst(func, args); + return call; +} + +/* + * @brief: visit unexp + * @details: + * unExp: unaryOp unaryExp + */ +std::any SysYIRGenerator::visitUnExp(SysYParser::UnExpContext *ctx) { + Value* res = nullptr; + auto op = ctx->unaryOp()->getText(); + auto exp = any_cast(ctx->unaryExp()->accept(this)); + if(ctx->unaryOp()->ADD()){ + res = exp; + } + else if(ctx->unaryOp()->SUB()){ + res = builder.createNegInst(exp, exp->getName()); + } + else if(ctx->unaryOp()->NOT()){ + //not将非零值转换为0,零值转换为1 + res = builder.createNotInst(exp, exp->getName()); + } + return res; +} + +/* + * @brief: visit mulexp + * @details: + * mulExp: unaryExp ((MUL | DIV | MOD) unaryExp)* + */ +std::any SysYIRGenerator::visitMulExp(SysYParser::MulExpContext *ctx) { + Value* res = nullptr; + auto lhs = any_cast(ctx->unaryExp(0)->accept(this)); + if(ctx->unaryExp().size() == 1){ + res = lhs; + } + else{ + for(size_t i = 1; i < ctx->unaryExp().size(); i++){ + auto unaryexp = ctx->unaryExp(i); + auto rhs = any_cast(unaryexp->accept(this)); + auto opNode = dynamic_cast(ctx->children[2 * i + 1]); + + if(opNode->getText() == "*"){ + res = builder.createMulInst(lhs, rhs, lhs->getName() + "*" + rhs->getName()); + } + else if(opNode->getText() == "/"){ + res = builder.createDivInst(lhs, rhs, lhs->getName() + "/" + rhs->getName()); + } + else if(opNode->getText() == "%"){ + std::cerr << "mod not implemented yet" << std::endl; + // res = builder.createModInst(lhs, rhs, lhs->getName() + "%" + rhs->getName()); + } + } + } + return res; +} + +/* + * @brief: visit addexp + * @details: + * addExp: mulExp ((ADD | SUB) mulExp)* + */ +std::any SysYIRGenerator::visitAddExp(SysYParser::AddExpContext *ctx) { + Value* res = nullptr; + auto lhs = any_cast(ctx->mulExp(0)->accept(this)); + if(ctx->mulExp().size() == 1){ + res = lhs; + } + else{ + for(size_t i = 1; i < ctx->mulExp().size(); i++){ + auto mulexp = ctx->mulExp(i); + auto rhs = any_cast(mulexp->accept(this)); + auto opNode = dynamic_cast(ctx->children[2 * i + 1]); + + if(opNode->getText() == "+"){ + res = builder.createAddInst(lhs, rhs, lhs->getName() + "+" + rhs->getName()); + } + else if(opNode->getText() == "-"){ + res = builder.createSubInst(lhs, rhs, lhs->getName() + "-" + rhs->getName()); + } + } + } + return res; +} + +/* + * @brief: visit relexp + * @details: + * relExp: addExp ((LT | GT | LE | GE) addExp)* + */ +std::any SysYIRGenerator::visitRelExp(SysYParser::RelExpContext *ctx) { + Value* res = nullptr; + auto lhs = any_cast(ctx->addExp(0)->accept(this)); + if(ctx->addExp().size() == 1){ + res = lhs; + } + else{ + for(size_t i = 1; i < ctx->addExp().size(); i++){ + auto addexp = ctx->addExp(i); + auto rhs = any_cast(addexp->accept(this)); + auto opNode = dynamic_cast(ctx->children[2 * i + 1]); + if(lhs->getType() != rhs->getType()){ + std::cerr << "type mismatch:type check not implemented" << std::endl; + } + Type* type = lhs->getType(); + if(opNode->getText() == "<"){ + if(type->isInt()) + res = builder.createICmpLTInst(lhs, rhs, lhs->getName() + "<" + rhs->getName()); + else if(type->isFloat()) + res = builder.createFCmpLTInst(lhs, rhs, lhs->getName() + "<" + rhs->getName()); + } + else if(opNode->getText() == ">"){ + if(type->isInt()) + res = builder.createICmpGTInst(lhs, rhs, lhs->getName() + ">" + rhs->getName()); + else if(type->isFloat()) + res = builder.createFCmpGTInst(lhs, rhs, lhs->getName() + ">" + rhs->getName()); + } + else if(opNode->getText() == "<="){ + if(type->isInt()) + res = builder.createICmpLEInst(lhs, rhs, lhs->getName() + "<=" + rhs->getName()); + else if(type->isFloat()) + res = builder.createFCmpLEInst(lhs, rhs, lhs->getName() + "<=" + rhs->getName()); + } + else if(opNode->getText() == ">="){ + if(type->isInt()) + res = builder.createICmpGEInst(lhs, rhs, lhs->getName() + ">=" + rhs->getName()); + else if(type->isFloat()) + res = builder.createFCmpGEInst(lhs, rhs, lhs->getName() + ">=" + rhs->getName()); + } + } + } + return res; +} + +/* + * @brief: visit eqexp + * @details: + * eqExp: relExp ((EQ | NEQ) relExp)* + */ +std::any SysYIRGenerator::visitEqExp(SysYParser::EqExpContext* ctx) { + Value* res = nullptr; + auto lhs = any_cast(ctx->relExp(0)->accept(this)); + if(ctx->relExp().size() == 1){ + res = lhs; + } + else{ + for(size_t i = 1; i < ctx->relExp().size(); i++){ + auto relexp = ctx->relExp(i); + auto rhs = any_cast(relexp->accept(this)); + auto opNode = dynamic_cast(ctx->children[2 * i + 1]); + if(lhs->getType() != rhs->getType()){ + std::cerr << "type mismatch:type check not implemented" << std::endl; + } + Type* type = lhs->getType(); + if(opNode->getText() == "=="){ + if(type->isInt()) + res = builder.createICmpEQInst(lhs, rhs, lhs->getName() + "==" + rhs->getName()); + else if(type->isFloat()) + res = builder.createFCmpEQInst(lhs, rhs, lhs->getName() + "==" + rhs->getName()); + } + else if(opNode->getText() == "!="){ + if(type->isInt()) + res = builder.createICmpNEInst(lhs, rhs, lhs->getName() + "!=" + rhs->getName()); + else if(type->isFloat()) + res = builder.createFCmpNEInst(lhs, rhs, lhs->getName() + "!=" + rhs->getName()); + } + } + } + return res; +} + +/* + * @brief: visit lAndexp + * @details: + * lAndExp: eqExp (AND eqExp)* + */ +std::any SysYIRGenerator::visitLAndExp(SysYParser::LAndExpContext* ctx) { + auto currentBlock = builder.getBasicBlock(); + // auto trueBlock = currentBlock->getParent()->addBasicBlock("trueland" + std::to_string(++trueBlockNum)); + auto falseBlock = currentBlock->getParent()->addBasicBlock("falseland" + std::to_string(++falseBlockNum)); + auto value = any_cast(ctx->eqExp(0)->accept(this)); + auto trueBlock = currentBlock; + for(size_t i = 1; i < ctx->eqExp().size(); i++){ + trueBlock = trueBlock->getParent()->addBasicBlock("trueland" + std::to_string(++trueBlockNum)); + builder.createCondBrInst(value, currentBlock, falseBlock, {}, {}); + builder.setPosition(trueBlock, trueBlock->end()); + value = any_cast(ctx->eqExp(i)->accept(this)); + } + //结构trueblk条件跳转到falseblk + // - trueBlock1->trueBlock2->trueBlock3->...->trueBlockn->nextblk + //entry-| + // -falseBlock->nextblk + //需要在最后一个trueblock的末尾加上无条件跳转到下一个基本块的指令 + // builder.createCondBrInst(value, trueBlock, falseBlock, {}, {}); + return std::any(); +} + +/* + * @brief: visit lOrexp + * @details: + * lOrExp: lAndExp (OR lAndExp)* + */ +std::any SysYIRGenerator::visitLOrExp(SysYParser::LOrExpContext* ctx) { + auto currentBlock = builder.getBasicBlock(); + auto trueBlock = currentBlock->getParent()->addBasicBlock("trueland" + std::to_string(++trueBlockNum)); + auto value = any_cast(ctx->lAndExp(0)->accept(this)); + auto falseBlock = currentBlock; + for(size_t i = 1; i < ctx->lAndExp().size(); i++){ + falseBlock = currentBlock->getParent()->addBasicBlock("falseland" + std::to_string(++falseBlockNum)); + builder.createCondBrInst(value, trueBlock, falseBlock, {}, {}); + builder.setPosition(falseBlock, falseBlock->end()); + value = any_cast(ctx->lAndExp(i)->accept(this)); + } + //结构trueblk条件跳转到falseblk + // - falseBlock1->falseBlock2->falseBlock3->...->falseBlockn->nextblk + //entry-| + // -trueBlock->nextblk + //需要在最后一个falseblock的末尾加上无条件跳转到下一个基本块的指令 + // builder.createCondBrInst(value, trueBlock, falseBlock, {}, {}); + return std::any(); +} + +/* + * @brief: visit constexp + * @details: + * constExp: addExp; + */ +std::any SysYIRGenerator::visitConstExp(SysYParser::ConstExpContext* ctx) { + ConstantValue* res = nullptr; + auto value = any_cast(ctx->addExp()->accept(this)); + if(isa(value)){ + res = dynamic_cast(value); + } + else{ + std::cerr << "error constexp" << ctx->getText() << std::endl; + } + return res; +} + +/* begin std::any SysYIRGenerator::visitConstGlobalDecl(SysYParser::ConstDeclContext *ctx, Type* type) { std::vector values; for (auto constDef : ctx->constDef()) { @@ -266,93 +979,7 @@ std::any SysYIRGenerator::visitVarLocalDecl(SysYParser::VarDeclContext *ctx, Typ } return values; } - - - -/* - * @brief: visit constInitVal - * @details: - * constInitVal: constExp - * | LBRACE (constInitVal (COMMA constInitVal)*)? RBRACE; - */ -std::any visitConstInitVal(SysYParser::ConstInitValContext *ctx){ - -} - - -/* - * @brief: visit function type - * @details: - * funcType: VOID | INT | FLOAT; - */ -std::any SysYIRGenerator::visitFuncType(SysYParser::FuncTypeContext* ctx){ - return ctx->INT() ? Type::getIntType() : (ctx->FLOAT() ? Type::getFloatType() : Type::getVoidType()); -} - -/* - * @brief: visit function define - * @details: - * funcDef: funcType Ident LPAREN funcFParams? RPAREN blockStmt; - * funcFParams: funcFParam (COMMA funcFParam)*; - * funcFParam: bType Ident (LBRACK RBRACK (LBRACK exp RBRACK)*)?; - * entry -> next -> others -> exit - * entry: allocas, br - * next: retval, params, br - * other: blockStmt init block - * exit: load retval, ret - */ -std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext* ctx){ - auto funcName = ctx->Ident()->getText(); - auto funcParams = ctx->funcFParams()->funcFParam(); - Type* returnType = any_cast(ctx->funcType()->accept(this)); - - vector paramTypes; - vector paramNames; - - for(auto funcParam:funcParams){ - Type* paramType = any_cast(funcParam->bType()->accept(this)); - paramTypes.push_back(paramType); - paramNames.push_back(funcParam->Ident()->getText()); - } - - auto funcType = FunctionType::get(returnType, paramTypes); - auto function = module->createFunction(funcName, funcType); - - auto entry = function->getEntryBlock(); - for(size_t i = 0; i < paramTypes.size(); i++) - entry->createArgument(paramTypes[i], paramNames[i]); - builder.setPosition(entry, entry->end()); - ctx->blockStmt()->accept(this); - - return function; -} - -/* - * @brief: visit blockStmt - * @details: - * blockStmt: LBRACE blockItem* RBRACE; - * blockItem: decl | stmt; - */ -std::any SysYIRGenerator::visitBlockStmt(SysYParser::BlockStmtContext* ctx){ - - SymbolTable::BlockScope scope(symbols_table); - - for (auto item : ctx->blockItem()) - item->accept(this); - - builder.getBasicBlock(); - return std::any(); -} - - -std::any SysYIRGenerator::visitFuncRParams(SysYParser::FuncRParamsContext *ctx) { - return visitChildren(ctx); -} -std::any SysYIRGenerator::visitNumber(SysYParser::NumberContext *ctx) { - return visitChildren(ctx); -} -std::any SysYIRGenerator::visitString(SysYParser::StringContext *ctx) { - return visitChildren(ctx); -} + end +*/ } // namespace sysy \ No newline at end of file diff --git a/src/SysYIRGenerator.h b/src/SysYIRGenerator.h index fb1ef33..2752f08 100644 --- a/src/SysYIRGenerator.h +++ b/src/SysYIRGenerator.h @@ -77,8 +77,8 @@ private: std::unique_ptr module; IRBuilder builder; SymbolTable symbols_table; - - static Type current_type; + + int trueBlockNum = 0, falseBlockNum = 0; int d = 0, n = 0; vector path; @@ -104,27 +104,29 @@ public: std::any visitFuncType(SysYParser::FuncTypeContext* ctx) override; std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override; std::any visitVarDecl(SysYParser::VarDeclContext *ctx) override; - // std::any visitVarDef(SysYParser::VarDefContext *ctx) override; + std::any visitVarDef(SysYParser::VarDefContext *ctx) override; std::any visitInitVal(SysYParser::InitValContext *ctx) override; - std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override; - std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override; + // std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override; + // std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override; std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx) override; // std::any visitStmt(SysYParser::StmtContext *ctx) override; + std::any visitAssignStmt(SysYParser::AssignStmtContext *ctx) override; std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override; std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override; std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override; std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override; std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override; - std::any visitExp(SysYParser::ExpContext *ctx) override; + // std::any visitExp(SysYParser::ExpContext *ctx) override; std::any visitLValue(SysYParser::LValueContext *ctx) override; // std::any visitPrimaryExp(SysYParser::PrimaryExpContext *ctx) override; - std::any visitParenExp(SysYParser::ParenExpContext *ctx) override; + // std::any visitParenExp(SysYParser::ParenExpContext *ctx) override; std::any visitNumber(SysYParser::NumberContext *ctx) override; - std::any visitString(SysYParser::StringContext *ctx) override; + // std::any visitString(SysYParser::StringContext *ctx) override; std::any visitCall(SysYParser::CallContext *ctx) override; // std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override; - std::any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override; - std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override; + // std::any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override; + std::any visitUnExp(SysYParser::UnExpContext *ctx) override; + // std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override; std::any visitMulExp(SysYParser::MulExpContext *ctx) override; std::any visitAddExp(SysYParser::AddExpContext *ctx) override; std::any visitRelExp(SysYParser::RelExpContext *ctx) override; From 9bea0879e050ba4e18e86197b4edc1ccd45bdd59 Mon Sep 17 00:00:00 2001 From: Downright <12709502+downrighr@user.noreply.gitee.com> Date: Wed, 26 Mar 2025 11:39:22 +0800 Subject: [PATCH 5/9] pass test1,but test2 segmentation fault --- CMakeLists.txt | 17 +++-- src/SysYIRGenerator.cpp | 157 ++++++++++++++++++++++++++-------------- src/SysYIRGenerator.h | 4 +- 3 files changed, 116 insertions(+), 62 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 29f8da6..d7ebf33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.19) +cmake_minimum_required(VERSION 3.19) # cmake_policy(SET CMP0135 OLD) @@ -15,11 +15,18 @@ set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to") set(CMAKE_CXX_STANDARD_REQUIRED YES) set(CMAKE_CXX_EXTENSIONS OFF) +# ========== 修改点 1:强制 Debug 模式(调试时使用) ========== if(NOT CMAKE_BUILD_TYPE) - message(STATUS "Build type not set, falling back to Debug mode.") - set(CMAKE_BUILD_TYPE "Release" CACHE STRING - "Choose the type of build, options are: Debug Release." FORCE) -endif(NOT CMAKE_BUILD_TYPE) + message(STATUS "Build type not set, defaulting to Debug mode for GDB support.") + set(CMAKE_BUILD_TYPE "Debug" CACHE STRING + "Choose the type of build, options are: Debug Release RelWithDebInfo." FORCE) +endif() + +# ========== 修改点 2:确保 Debug 模式生成调试信息 ========== +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + message(STATUS "Debug mode enabled: Adding -g flag for GDB debugging.") + add_compile_options(-g -O0) # -O0 禁用优化,避免干扰调试 +endif() # Set output directories set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp index 0f6bc2e..fd689ca 100644 --- a/src/SysYIRGenerator.cpp +++ b/src/SysYIRGenerator.cpp @@ -112,9 +112,9 @@ std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext *ctx) { */ std::any SysYIRGenerator::visitBType(SysYParser::BTypeContext *ctx) { if(ctx->INT()) - return Type::getIntType(); - else if(ctx->FLOAT()) - return Type::getFloatType(); + return Type::getPointerType(Type::getIntType()); + else if(ctx->FLOAT()) + return Type::getPointerType(Type::getFloatType()); std::cerr << "error: unknown type" << ctx->getText() << std::endl; return std::any(); } @@ -127,21 +127,33 @@ std::any SysYIRGenerator::visitBType(SysYParser::BTypeContext *ctx) { */ std::any SysYIRGenerator::visitConstDef(SysYParser::ConstDefContext *ctx){ auto name = ctx->Ident()->getText(); - auto type = current_type; - auto init = ctx->constInitVal() ? any_cast(ctx->constInitVal()->accept(this)) : (Value *)nullptr; + Type* type = current_type; + Value* init = ctx->constInitVal() ? any_cast(ctx->constInitVal()->accept(this)) : (Value *)nullptr; if (ctx->constExp().empty()){ //scalar if(init){ if(symbols_table.isModuleScope()){ assert(init->isConstant() && "global must be initialized by constant"); - auto global = module->createGlobalValue(name, type, {}, init); + Value* global = module->createGlobalValue(name, type, {}, init); symbols_table.insert(name, global); + cout << "add module const " << name ; + if(init){ + cout << " inited by " ; + init->print(cout); + } + cout << '\n'; } else{ - auto alloca = builder.createAllocaInst(type, {}, name); - auto store = builder.createStoreInst(init, alloca); + Value* alloca = builder.createAllocaInst(type, {}, name); + Value* store = builder.createStoreInst(init, alloca); symbols_table.insert(name, alloca); + cout << "add local const " << name ; + if(init){ + cout << " inited by " ; + init->print(cout); + } + cout << '\n'; } } else{ @@ -238,7 +250,9 @@ std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext* ctx){ entryblock->createArgument(paramTypes[i], paramNames[i]); for(auto& arg: entryblock->getArguments()) - symbols_table.insert(arg->getName(), arg.get()); + symbols_table.insert(arg->getName(), (Value *)arg.get()); + + cout << "setposition entryblock" << endl; builder.setPosition(entryblock, entryblock->end()); ctx->blockStmt()->accept(this); @@ -253,7 +267,7 @@ std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext* ctx){ */ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx){ cout << "visitVarDecl" << endl; - current_type = any_cast(ctx->bType()->accept(this)); + current_type = any_cast(ctx->bType()->accept(this)); for(auto varDef:ctx->varDef()){ varDef->accept(this); } @@ -266,9 +280,10 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx){ * varDef: Ident (LBRACK constExp RBRACK)* (ASSIGN initVal)?; */ std::any SysYIRGenerator::visitVarDef(SysYParser::VarDefContext *ctx){ - auto name = ctx->Ident()->getText(); - auto type = current_type; - auto init = ctx->initVal() ? any_cast(ctx->initVal()->accept(this)) : (Value *)nullptr; + const std::string name = ctx->Ident()->getText(); + Type* type = current_type; + Value* init = ctx->initVal() ? any_cast(ctx->initVal()->accept(this)) : nullptr; + // const std::vector dims = {}; cout << "vardef: "; current_type->print(cout); @@ -280,23 +295,31 @@ std::any SysYIRGenerator::visitVarDef(SysYParser::VarDefContext *ctx){ if(init) assert(init->isConstant() && "global must be initialized by constant"); - auto global = module->createGlobalValue(name, type, {}, init); + Value* global = module->createGlobalValue(name, type, {}, init); symbols_table.insert(name, global); - cout << "add module var " << name << "inited by " ; - init->print(cout); + cout << "add module var " << name ; + // if(init){ + // cout << " inited by " ; + // init->print(cout); + // } cout << '\n'; } else{ - auto alloca = builder.createAllocaInst(type, {}, name); - auto store = (StoreInst *)nullptr; - if(init) - store = builder.createStoreInst(init, alloca); + + Value* alloca = builder.createAllocaInst(type, {}, name); + cout << "creatalloca" << endl; + alloca->print(cout); + Value* store = (StoreInst *)nullptr; + if(init != nullptr) + store = builder.createStoreInst(alloca, init, {}, name); symbols_table.insert(name, alloca); - cout << "add local var " << name ; - if(init){ - cout << "inited by " ; - init->print(cout); - } + // alloca->setName(name); + cout << "add local var " ; + alloca->print(cout); + // if(init){ + // cout << " inited by " ; + // init->print(cout); + // } cout << '\n'; } } @@ -313,7 +336,7 @@ std::any SysYIRGenerator::visitVarDef(SysYParser::VarDefContext *ctx){ * initVal: exp | LBRACE (initVal (COMMA initVal)*)? RBRACE; */ std::any SysYIRGenerator::visitInitVal(SysYParser::InitValContext *ctx) { - Value* initvalue; + Value* initvalue = nullptr; if(ctx->exp()) initvalue = any_cast(ctx->exp()->accept(this)); else{ @@ -424,8 +447,9 @@ std::any SysYIRGenerator::visitBreakStmt(SysYParser::BreakStmtContext* ctx) { * returnStmt: RETURN exp? SEMICOLON; */ std::any SysYIRGenerator::visitReturnStmt(SysYParser::ReturnStmtContext* ctx) { + cout << "visitReturnStmt" << endl; // auto value = ctx->exp() ? any_cast_Value(visit(ctx->exp())) : nullptr; - auto value = ctx->exp() ? any_cast(ctx->exp()->accept(this)) : nullptr; + Value* value = ctx->exp() ? any_cast(ctx->exp()->accept(this)) : nullptr; const auto func = builder.getBasicBlock()->getParent(); @@ -467,14 +491,11 @@ std::any SysYIRGenerator::visitContinueStmt(SysYParser::ContinueStmtContext* ctx std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext* ctx) { cout << "visitassignstme :\n"; auto lvalue = any_cast(ctx->lValue()->accept(this)); - cout << 'lval: (' << lvalue->getName() ; + cout << "getlval" << endl;//lvalue->print(cout);cout << ')'; auto rvalue = any_cast(ctx->exp()->accept(this)); //可能要考虑类型转换例如int a = 1.0 - builder.createStoreInst(rvalue, lvalue); - - cout << ') = rval(' << rvalue->getName(); - - + cout << "getrval" << endl;//rvalue->print(cout);cout << ")\n"; + builder.createStoreInst(rvalue, lvalue, {}, {}); return std::any(); } @@ -484,6 +505,7 @@ std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext* ctx) { * lValue: Ident (LBRACK exp RBRACK)*; */ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext* ctx) { + cout << "visitLValue" << endl; auto name = ctx->Ident()->getText(); Value* value = symbols_table.lookup(name); @@ -502,10 +524,18 @@ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext* ctx) { return std::any(); } - +std::any SysYIRGenerator::visitPrimExp(SysYParser::PrimExpContext *ctx){ + cout << "visitPrimExp" << endl; + return visitChildren(ctx); +} +// std::any SysYIRGenerator::visitExp(SysYParser::ExpContext* ctx) { +// cout << "visitExp" << endl; +// return ctx->addExp()->accept(this); +// } std::any SysYIRGenerator::visitNumber(SysYParser::NumberContext *ctx) { - ConstantValue* res = nullptr; + cout << "visitNumber" << endl; + Value* res = nullptr; if (auto iLiteral = ctx->ILITERAL()) { /* 基数 (8, 10, 16) */ const auto text = iLiteral->getText(); @@ -522,6 +552,10 @@ std::any SysYIRGenerator::visitNumber(SysYParser::NumberContext *ctx) { const auto text = fLiteral->getText(); res = ConstantValue::get((float)std::stof(text)); } + cout << "number: "; + res->print(cout); + cout << endl; + return res; } @@ -531,6 +565,7 @@ std::any SysYIRGenerator::visitNumber(SysYParser::NumberContext *ctx) { * call: Ident LPAREN funcRParams? RPAREN; */ std::any SysYIRGenerator::visitCall(SysYParser::CallContext* ctx) { + cout << "visitCall" << endl; auto funcName = ctx->Ident()->getText(); auto func = module->getFunction(funcName); assert(func && "function not found"); @@ -542,7 +577,7 @@ std::any SysYIRGenerator::visitCall(SysYParser::CallContext* ctx) { args.push_back(any_cast(exp->accept(this))); } } - auto call = builder.createCallInst(func, args); + Value* call = builder.createCallInst(func, args); return call; } @@ -552,6 +587,7 @@ std::any SysYIRGenerator::visitCall(SysYParser::CallContext* ctx) { * unExp: unaryOp unaryExp */ std::any SysYIRGenerator::visitUnExp(SysYParser::UnExpContext *ctx) { + cout << "visitUnExp" << endl; Value* res = nullptr; auto op = ctx->unaryOp()->getText(); auto exp = any_cast(ctx->unaryExp()->accept(this)); @@ -574,15 +610,19 @@ std::any SysYIRGenerator::visitUnExp(SysYParser::UnExpContext *ctx) { * mulExp: unaryExp ((MUL | DIV | MOD) unaryExp)* */ std::any SysYIRGenerator::visitMulExp(SysYParser::MulExpContext *ctx) { + cout << "visitMulExp" << endl; Value* res = nullptr; - auto lhs = any_cast(ctx->unaryExp(0)->accept(this)); + cout << "mulExplhsin\n"; + Value* lhs = any_cast(ctx->unaryExp(0)->accept(this)); + cout << "mulExplhsout\n"; if(ctx->unaryExp().size() == 1){ + cout << "unaryExp().size() = 1\n"; res = lhs; } else{ + cout << "unaryExp().size() > 1\n"; for(size_t i = 1; i < ctx->unaryExp().size(); i++){ - auto unaryexp = ctx->unaryExp(i); - auto rhs = any_cast(unaryexp->accept(this)); + Value* rhs = any_cast(ctx->unaryExp(i)->accept(this)); auto opNode = dynamic_cast(ctx->children[2 * i + 1]); if(opNode->getText() == "*"){ @@ -606,16 +646,18 @@ std::any SysYIRGenerator::visitMulExp(SysYParser::MulExpContext *ctx) { * addExp: mulExp ((ADD | SUB) mulExp)* */ std::any SysYIRGenerator::visitAddExp(SysYParser::AddExpContext *ctx) { + cout << "visitAddExp" << endl; Value* res = nullptr; - auto lhs = any_cast(ctx->mulExp(0)->accept(this)); + Value* lhs = any_cast(ctx->mulExp(0)->accept(this)); if(ctx->mulExp().size() == 1){ + cout << "ctx->mulExp().size() = 1\n"; res = lhs; } else{ for(size_t i = 1; i < ctx->mulExp().size(); i++){ - auto mulexp = ctx->mulExp(i); - auto rhs = any_cast(mulexp->accept(this)); - auto opNode = dynamic_cast(ctx->children[2 * i + 1]); + cout << "i = " << i << "\n"; + Value* rhs = any_cast(ctx->mulExp(i)->accept(this)); + auto opNode = dynamic_cast(ctx->children[2 * i - 1]); if(opNode->getText() == "+"){ res = builder.createAddInst(lhs, rhs, lhs->getName() + "+" + rhs->getName()); @@ -624,7 +666,9 @@ std::any SysYIRGenerator::visitAddExp(SysYParser::AddExpContext *ctx) { res = builder.createSubInst(lhs, rhs, lhs->getName() + "-" + rhs->getName()); } } + lhs = res; } + return res; } @@ -634,16 +678,16 @@ std::any SysYIRGenerator::visitAddExp(SysYParser::AddExpContext *ctx) { * relExp: addExp ((LT | GT | LE | GE) addExp)* */ std::any SysYIRGenerator::visitRelExp(SysYParser::RelExpContext *ctx) { + cout << "visitRelExp" << endl; Value* res = nullptr; - auto lhs = any_cast(ctx->addExp(0)->accept(this)); + Value* lhs = any_cast(ctx->addExp(0)->accept(this)); if(ctx->addExp().size() == 1){ res = lhs; } else{ for(size_t i = 1; i < ctx->addExp().size(); i++){ - auto addexp = ctx->addExp(i); - auto rhs = any_cast(addexp->accept(this)); - auto opNode = dynamic_cast(ctx->children[2 * i + 1]); + Value* rhs = any_cast(ctx->addExp(i)->accept(this)); + auto opNode = dynamic_cast(ctx->children[2 * i - 1]); if(lhs->getType() != rhs->getType()){ std::cerr << "type mismatch:type check not implemented" << std::endl; } @@ -683,16 +727,16 @@ std::any SysYIRGenerator::visitRelExp(SysYParser::RelExpContext *ctx) { * eqExp: relExp ((EQ | NEQ) relExp)* */ std::any SysYIRGenerator::visitEqExp(SysYParser::EqExpContext* ctx) { + cout << "visitEqExp" << endl; Value* res = nullptr; - auto lhs = any_cast(ctx->relExp(0)->accept(this)); + Value* lhs = any_cast(ctx->relExp(0)->accept(this)); if(ctx->relExp().size() == 1){ res = lhs; } else{ for(size_t i = 1; i < ctx->relExp().size(); i++){ - auto relexp = ctx->relExp(i); - auto rhs = any_cast(relexp->accept(this)); - auto opNode = dynamic_cast(ctx->children[2 * i + 1]); + Value* rhs = any_cast(ctx->relExp(i)->accept(this)); + auto opNode = dynamic_cast(ctx->children[2 * i - 1]); if(lhs->getType() != rhs->getType()){ std::cerr << "type mismatch:type check not implemented" << std::endl; } @@ -720,10 +764,11 @@ std::any SysYIRGenerator::visitEqExp(SysYParser::EqExpContext* ctx) { * lAndExp: eqExp (AND eqExp)* */ std::any SysYIRGenerator::visitLAndExp(SysYParser::LAndExpContext* ctx) { + cout << "visitLAndExp" << endl; auto currentBlock = builder.getBasicBlock(); // auto trueBlock = currentBlock->getParent()->addBasicBlock("trueland" + std::to_string(++trueBlockNum)); auto falseBlock = currentBlock->getParent()->addBasicBlock("falseland" + std::to_string(++falseBlockNum)); - auto value = any_cast(ctx->eqExp(0)->accept(this)); + Value* value = any_cast(ctx->eqExp(0)->accept(this)); auto trueBlock = currentBlock; for(size_t i = 1; i < ctx->eqExp().size(); i++){ trueBlock = trueBlock->getParent()->addBasicBlock("trueland" + std::to_string(++trueBlockNum)); @@ -746,9 +791,10 @@ std::any SysYIRGenerator::visitLAndExp(SysYParser::LAndExpContext* ctx) { * lOrExp: lAndExp (OR lAndExp)* */ std::any SysYIRGenerator::visitLOrExp(SysYParser::LOrExpContext* ctx) { + cout << "visitLOrExp" << endl; auto currentBlock = builder.getBasicBlock(); auto trueBlock = currentBlock->getParent()->addBasicBlock("trueland" + std::to_string(++trueBlockNum)); - auto value = any_cast(ctx->lAndExp(0)->accept(this)); + Value* value = any_cast(ctx->lAndExp(0)->accept(this)); auto falseBlock = currentBlock; for(size_t i = 1; i < ctx->lAndExp().size(); i++){ falseBlock = currentBlock->getParent()->addBasicBlock("falseland" + std::to_string(++falseBlockNum)); @@ -771,10 +817,11 @@ std::any SysYIRGenerator::visitLOrExp(SysYParser::LOrExpContext* ctx) { * constExp: addExp; */ std::any SysYIRGenerator::visitConstExp(SysYParser::ConstExpContext* ctx) { + cout << "visitConstExp" << endl; ConstantValue* res = nullptr; - auto value = any_cast(ctx->addExp()->accept(this)); + Value* value = any_cast(ctx->addExp()->accept(this)); if(isa(value)){ - res = dynamic_cast(value); + res = dyncast(value); } else{ std::cerr << "error constexp" << ctx->getText() << std::endl; diff --git a/src/SysYIRGenerator.h b/src/SysYIRGenerator.h index 2752f08..26969a3 100644 --- a/src/SysYIRGenerator.h +++ b/src/SysYIRGenerator.h @@ -85,7 +85,7 @@ private: bool isalloca; AllocaInst *current_alloca; GlobalValue *current_global; - Type *current_type; + Type* current_type; int numdims = 0; public: @@ -118,7 +118,7 @@ public: std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override; // std::any visitExp(SysYParser::ExpContext *ctx) override; std::any visitLValue(SysYParser::LValueContext *ctx) override; - // std::any visitPrimaryExp(SysYParser::PrimaryExpContext *ctx) override; + std::any visitPrimExp(SysYParser::PrimExpContext *ctx) override; // std::any visitParenExp(SysYParser::ParenExpContext *ctx) override; std::any visitNumber(SysYParser::NumberContext *ctx) override; // std::any visitString(SysYParser::StringContext *ctx) override; From 1322ed8e088e9dac59ecda4a8d321fc408a37880 Mon Sep 17 00:00:00 2001 From: Downright <12709502+downrighr@user.noreply.gitee.com> Date: Wed, 26 Mar 2025 11:39:29 +0800 Subject: [PATCH 6/9] gdb json --- .vscode/launch.json | 25 +++++++++++++ .vscode/settings.json | 85 +++++++++++++++++++++++++++++++++++++++++++ .vscode/tasks.json | 15 ++++++++ 3 files changed, 125 insertions(+) create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 .vscode/tasks.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..b39ee3a --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug sysyc with GDB", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/bin/sysyc", // 可执行文件路径 + "args": ["-s", "ir", "test/01_add.sy"], // 默认参数(可替换) + "stopAtEntry": false, + "cwd": "${workspaceFolder}", // 工作目录 + "environment": [], + "externalConsole": false, + "MIMode": "gdb", // 使用 GDB + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "miDebuggerPath": "/usr/bin/gdb" // GDB 路径(默认通常正确) + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..5c92943 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,85 @@ +{ + "files.associations": { + "any": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "codecvt": "cpp", + "compare": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "forward_list": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "semaphore": "cpp", + "shared_mutex": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp", + "__nullptr": "cpp", + "__config": "cpp", + "__hash_table": "cpp", + "__split_buffer": "cpp", + "__tree": "cpp", + "queue": "cpp", + "stack": "cpp", + "__bit_reference": "cpp", + "__functional_base": "cpp", + "__node_handle": "cpp", + "__memory": "cpp", + "filesystem": "cpp", + "locale": "cpp", + "__locale": "cpp" + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..84ac2fb --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,15 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "java (buildArtifact)", + "targetPath": "${workspaceFolder}/${workspaceFolderBasename}.jar", + "elements": [ + "${compileOutput}", + "${dependencies}" + ], + "problemMatcher": [], + "label": "java (buildArtifact): mysysy" + } + ] +} \ No newline at end of file From f74d31939981b21762fe9b69872f3af10e0c4f80 Mon Sep 17 00:00:00 2001 From: Downright <12709502+downrighr@user.noreply.gitee.com> Date: Wed, 26 Mar 2025 11:44:34 +0800 Subject: [PATCH 7/9] pass test 11_add2 --- src/SysYIRGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp index fd689ca..7ddee8e 100644 --- a/src/SysYIRGenerator.cpp +++ b/src/SysYIRGenerator.cpp @@ -623,7 +623,7 @@ std::any SysYIRGenerator::visitMulExp(SysYParser::MulExpContext *ctx) { cout << "unaryExp().size() > 1\n"; for(size_t i = 1; i < ctx->unaryExp().size(); i++){ Value* rhs = any_cast(ctx->unaryExp(i)->accept(this)); - auto opNode = dynamic_cast(ctx->children[2 * i + 1]); + auto opNode = dynamic_cast(ctx->children[2 * i - 1]); if(opNode->getText() == "*"){ res = builder.createMulInst(lhs, rhs, lhs->getName() + "*" + rhs->getName()); From f01c38d3e8f905632818a2f921d39ccdd28d77f2 Mon Sep 17 00:00:00 2001 From: Downright <12709502+downrighr@user.noreply.gitee.com> Date: Wed, 26 Mar 2025 18:29:17 +0800 Subject: [PATCH 8/9] commit 4 cmakelist and .gitignore --- .gitignore | 3 ++- CMakeLists.txt | 17 +++++------------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index ae0af5b..87cacae 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,5 @@ doxygen !/testdata/functional/*.out !/testdata/performance/*.out build -.antlr \ No newline at end of file +.antlr +.vscode \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index d7ebf33..29f8da6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.19) +cmake_minimum_required (VERSION 3.19) # cmake_policy(SET CMP0135 OLD) @@ -15,18 +15,11 @@ set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to conform to") set(CMAKE_CXX_STANDARD_REQUIRED YES) set(CMAKE_CXX_EXTENSIONS OFF) -# ========== 修改点 1:强制 Debug 模式(调试时使用) ========== if(NOT CMAKE_BUILD_TYPE) - message(STATUS "Build type not set, defaulting to Debug mode for GDB support.") - set(CMAKE_BUILD_TYPE "Debug" CACHE STRING - "Choose the type of build, options are: Debug Release RelWithDebInfo." FORCE) -endif() - -# ========== 修改点 2:确保 Debug 模式生成调试信息 ========== -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - message(STATUS "Debug mode enabled: Adding -g flag for GDB debugging.") - add_compile_options(-g -O0) # -O0 禁用优化,避免干扰调试 -endif() + message(STATUS "Build type not set, falling back to Debug mode.") + set(CMAKE_BUILD_TYPE "Release" CACHE STRING + "Choose the type of build, options are: Debug Release." FORCE) +endif(NOT CMAKE_BUILD_TYPE) # Set output directories set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) From a35c63245e01eef56180987da385f4fdcdd40013 Mon Sep 17 00:00:00 2001 From: Downright <12709502+downrighr@user.noreply.gitee.com> Date: Wed, 26 Mar 2025 18:34:36 +0800 Subject: [PATCH 9/9] Remove .vscode dir --- .gitignore | 4 +- .vscode/launch.json | 25 ------------- .vscode/settings.json | 85 ------------------------------------------- .vscode/tasks.json | 15 -------- 4 files changed, 2 insertions(+), 127 deletions(-) delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 .vscode/tasks.json diff --git a/.gitignore b/.gitignore index 87cacae..2e16250 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,6 @@ doxygen !/testdata/functional/*.out !/testdata/performance/*.out -build +build/ .antlr -.vscode \ No newline at end of file +.vscode/ \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index b39ee3a..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": "Debug sysyc with GDB", - "type": "cppdbg", - "request": "launch", - "program": "${workspaceFolder}/build/bin/sysyc", // 可执行文件路径 - "args": ["-s", "ir", "test/01_add.sy"], // 默认参数(可替换) - "stopAtEntry": false, - "cwd": "${workspaceFolder}", // 工作目录 - "environment": [], - "externalConsole": false, - "MIMode": "gdb", // 使用 GDB - "setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - } - ], - "miDebuggerPath": "/usr/bin/gdb" // GDB 路径(默认通常正确) - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 5c92943..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "files.associations": { - "any": "cpp", - "array": "cpp", - "atomic": "cpp", - "bit": "cpp", - "*.tcc": "cpp", - "bitset": "cpp", - "cctype": "cpp", - "chrono": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "codecvt": "cpp", - "compare": "cpp", - "concepts": "cpp", - "condition_variable": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "forward_list": "cpp", - "list": "cpp", - "map": "cpp", - "set": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "unordered_set": "cpp", - "vector": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "optional": "cpp", - "random": "cpp", - "ratio": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "fstream": "cpp", - "initializer_list": "cpp", - "iomanip": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "istream": "cpp", - "limits": "cpp", - "mutex": "cpp", - "new": "cpp", - "numbers": "cpp", - "ostream": "cpp", - "semaphore": "cpp", - "shared_mutex": "cpp", - "sstream": "cpp", - "stdexcept": "cpp", - "stop_token": "cpp", - "streambuf": "cpp", - "thread": "cpp", - "cinttypes": "cpp", - "typeinfo": "cpp", - "__nullptr": "cpp", - "__config": "cpp", - "__hash_table": "cpp", - "__split_buffer": "cpp", - "__tree": "cpp", - "queue": "cpp", - "stack": "cpp", - "__bit_reference": "cpp", - "__functional_base": "cpp", - "__node_handle": "cpp", - "__memory": "cpp", - "filesystem": "cpp", - "locale": "cpp", - "__locale": "cpp" - } -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 84ac2fb..0000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "type": "java (buildArtifact)", - "targetPath": "${workspaceFolder}/${workspaceFolderBasename}.jar", - "elements": [ - "${compileOutput}", - "${dependencies}" - ], - "problemMatcher": [], - "label": "java (buildArtifact): mysysy" - } - ] -} \ No newline at end of file