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;