frame finished but bad_any_cast
This commit is contained in:
@ -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
|
git clone https://gitee.com/xsu1989/sysy.git
|
||||||
cd sysy
|
cd sysy
|
||||||
cmake -S . -B build
|
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`观察格式化器的执行效果。
|
完成格式化器进阶内容后,可以通过执行`sysyc`观察格式化器的执行效果。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./build/sysyc -f test/format-test.sy
|
./build/bin/sysyc -f test/format-test.sy
|
||||||
```
|
```
|
||||||
|
|
||||||
## 实验2:从AST生成中间表示
|
## 实验2:从AST生成中间表示
|
||||||
@ -100,7 +101,7 @@ cmake_install.cmake SysYBaseVisitor.h SysYLexer.cpp SysYLexer.interp SysYP
|
|||||||
完成实验2后,可以通过执行`sysyc`观察生成的IR。
|
完成实验2后,可以通过执行`sysyc`观察生成的IR。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./build/sysyc -s ir 01_add.sy
|
./build/bin/sysyc -s ir test/01_add.sy
|
||||||
```
|
```
|
||||||
|
|
||||||
请同学们仔细阅读代码学习IR的定义。可以使用doxygen工具自动生成HTML文档
|
请同学们仔细阅读代码学习IR的定义。可以使用doxygen工具自动生成HTML文档
|
||||||
|
|||||||
@ -124,7 +124,7 @@ std::any ASTPrinter::visitFuncFParam(SysYParser::FuncFParamContext *ctx){
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::any ASTPrinter::visitBlockStmt(SysYParser::BlockStmtContext *ctx){
|
std::any ASTPrinter::visitBlockStmt(SysYParser::BlockStmtContext *ctx){
|
||||||
cout << ' ' << ctx->LBRACE()->getText() << endl;
|
cout << ctx->LBRACE()->getText() << endl;
|
||||||
indentLevel++;
|
indentLevel++;
|
||||||
for (auto item : ctx->blockItem()) item->accept(this);
|
for (auto item : ctx->blockItem()) item->accept(this);
|
||||||
indentLevel--;
|
indentLevel--;
|
||||||
@ -134,6 +134,7 @@ std::any ASTPrinter::visitBlockStmt(SysYParser::BlockStmtContext *ctx){
|
|||||||
// std::any ASTPrinter::visitBlockItem(SysYParser::BlockItemContext *ctx);
|
// std::any ASTPrinter::visitBlockItem(SysYParser::BlockItemContext *ctx);
|
||||||
|
|
||||||
std::any ASTPrinter::visitAssignStmt(SysYParser::AssignStmtContext *ctx){
|
std::any ASTPrinter::visitAssignStmt(SysYParser::AssignStmtContext *ctx){
|
||||||
|
cout << getIndent();
|
||||||
ctx->lValue()->accept(this);
|
ctx->lValue()->accept(this);
|
||||||
cout << ' ' << ctx->ASSIGN()->getText() << ' ';
|
cout << ' ' << ctx->ASSIGN()->getText() << ' ';
|
||||||
ctx->exp()->accept(this);
|
ctx->exp()->accept(this);
|
||||||
@ -142,6 +143,7 @@ std::any ASTPrinter::visitAssignStmt(SysYParser::AssignStmtContext *ctx){
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::any ASTPrinter::visitExpStmt(SysYParser::ExpStmtContext *ctx){
|
std::any ASTPrinter::visitExpStmt(SysYParser::ExpStmtContext *ctx){
|
||||||
|
cout << getIndent();
|
||||||
if (ctx->exp()) {
|
if (ctx->exp()) {
|
||||||
ctx->exp()->accept(this);
|
ctx->exp()->accept(this);
|
||||||
}
|
}
|
||||||
@ -153,7 +155,17 @@ std::any ASTPrinter::visitIfStmt(SysYParser::IfStmtContext *ctx){
|
|||||||
cout << getIndent() << ctx->IF()->getText() << ' ' << ctx->LPAREN()->getText();
|
cout << getIndent() << ctx->IF()->getText() << ' ' << ctx->LPAREN()->getText();
|
||||||
ctx->cond()->accept(this);
|
ctx->cond()->accept(this);
|
||||||
cout << ctx->RPAREN()->getText() << ' ';
|
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()) {
|
if (ctx->ELSE()) {
|
||||||
cout << getIndent() << ctx->ELSE()->getText() << ' ';
|
cout << getIndent() << ctx->ELSE()->getText() << ' ';
|
||||||
ctx->stmt(1)->accept(this);
|
ctx->stmt(1)->accept(this);
|
||||||
|
|||||||
@ -21,9 +21,55 @@ std::any SysYIRGenerator::visitCompUnit(SysYParser::CompUnitContext *ctx) {
|
|||||||
|
|
||||||
// 待添加运行时库函数getint等
|
// 待添加运行时库函数getint等
|
||||||
// generates globals and functions
|
// 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);
|
//runtime library
|
||||||
// return the IR module
|
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;
|
return pModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,39 +83,706 @@ std::any SysYIRGenerator::visitCompUnit(SysYParser::CompUnitContext *ctx) {
|
|||||||
* we consider them together? not sure
|
* we consider them together? not sure
|
||||||
*/
|
*/
|
||||||
std::any SysYIRGenerator::visitDecl(SysYParser::DeclContext *ctx) {
|
std::any SysYIRGenerator::visitDecl(SysYParser::DeclContext *ctx) {
|
||||||
if(ctx->constDecl()){
|
if(ctx->constDecl())
|
||||||
return visitConstDecl(ctx->constDecl());
|
return visitConstDecl(ctx->constDecl());
|
||||||
}else if(ctx->varDecl()){
|
else if(ctx->varDecl())
|
||||||
return visitVarDecl(ctx->varDecl());
|
return visitVarDecl(ctx->varDecl());
|
||||||
}
|
std::cerr << "error unkown decl" << ctx->getText() << std::endl;
|
||||||
return nullptr;
|
return std::any();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief: visit constdecl
|
* @brief: visit constdecl
|
||||||
* @details:
|
* @details:
|
||||||
* constDecl: CONST bType constDef (COMMA constDef)* SEMI;
|
* constDecl: CONST bType constDef (COMMA constDef)* SEMI;
|
||||||
|
* constDef: Ident (LBRACK constExp RBRACK)* (ASSIGN constInitVal)?;
|
||||||
*/
|
*/
|
||||||
std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext *ctx) {
|
std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext *ctx) {
|
||||||
auto type = Type::getPointerType(any_cast<Type *>(ctx->bType()->accept(this)));
|
cout << "visitconstDecl" << endl;
|
||||||
if(symbols_table.isModuleScope())
|
current_type = any_cast<Type*>(ctx->bType()->accept(this));
|
||||||
visitConstGlobalDecl(ctx, type);
|
for(auto constDef:ctx->constDef()){
|
||||||
else
|
constDef->accept(this);
|
||||||
visitConstLocalDecl(ctx, type);
|
}
|
||||||
return std::any();
|
return std::any();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief: visit btype
|
* @brief: visit btype
|
||||||
* @details:
|
* @details:
|
||||||
* bType: INT | FLOAT;
|
* bType: INT | FLOAT;
|
||||||
*/
|
*/
|
||||||
std::any SysYIRGenerator::visitBType(SysYParser::BTypeContext *ctx) {
|
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<Value*>(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<Value*>(ctx->constExp()->accept(this));
|
||||||
|
else{
|
||||||
|
//还未实现数组初始化等功能待验证
|
||||||
|
std::cerr << "array initvalue not implemented yet" << std::endl;
|
||||||
|
// auto numConstInitVals = ctx->constInitVal().size();
|
||||||
|
// vector<Value*> initvalues;
|
||||||
|
// for(int i = 0; i < numConstInitVals; i++)
|
||||||
|
// initvalues.push_back(any_cast<Value*>(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<Type*>(ctx->funcType()->accept(this));
|
||||||
|
auto func = module->getFunction(funcName);
|
||||||
|
|
||||||
|
cout << "func: ";
|
||||||
|
returnType->print(cout);
|
||||||
|
cout << ' '<< funcName.c_str() << endl;
|
||||||
|
|
||||||
|
vector<Type*> paramTypes;
|
||||||
|
vector<string> paramNames;
|
||||||
|
|
||||||
|
if(ctx->funcFParams()){
|
||||||
|
for(auto funcParam:ctx->funcFParams()->funcFParam()){
|
||||||
|
Type* paramType = any_cast<Type*>(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<Type*>(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<Value*>(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<Value*>(ctx->exp()->accept(this));
|
||||||
|
else{
|
||||||
|
//还未实现数组初始化等功能待验证
|
||||||
|
std::cerr << "array initvalue not implemented yet" << std::endl;
|
||||||
|
// auto numConstInitVals = ctx->constInitVal().size();
|
||||||
|
// vector<Value*> initvalues;
|
||||||
|
// for(int i = 0; i < numConstInitVals; i++)
|
||||||
|
// initvalues.push_back(any_cast<Value*>(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<Value *>(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<Value*>(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<Value*>(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<Value *>(ctx->lValue()->accept(this));
|
||||||
|
cout << 'lval: (' << lvalue->getName() ;
|
||||||
|
auto rvalue = any_cast<Value *>(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<Value*> args;
|
||||||
|
if(ctx->funcRParams()){
|
||||||
|
for(auto exp:ctx->funcRParams()->exp()){
|
||||||
|
args.push_back(any_cast<Value*>(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<Value*>(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<Value*>(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<Value*>(unaryexp->accept(this));
|
||||||
|
auto opNode = dynamic_cast<antlr4::tree::TerminalNode *>(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<Value*>(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<Value*>(mulexp->accept(this));
|
||||||
|
auto opNode = dynamic_cast<antlr4::tree::TerminalNode *>(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<Value*>(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<Value*>(addexp->accept(this));
|
||||||
|
auto opNode = dynamic_cast<antlr4::tree::TerminalNode *>(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<Value*>(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<Value*>(relexp->accept(this));
|
||||||
|
auto opNode = dynamic_cast<antlr4::tree::TerminalNode *>(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<Value*>(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<Value*>(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<Value*>(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<Value*>(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<Value*>(ctx->addExp()->accept(this));
|
||||||
|
if(isa<ConstantValue>(value)){
|
||||||
|
res = dynamic_cast<ConstantValue*>(value);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
std::cerr << "error constexp" << ctx->getText() << std::endl;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* begin
|
||||||
std::any SysYIRGenerator::visitConstGlobalDecl(SysYParser::ConstDeclContext *ctx, Type* type) {
|
std::any SysYIRGenerator::visitConstGlobalDecl(SysYParser::ConstDeclContext *ctx, Type* type) {
|
||||||
std::vector<Value *> values;
|
std::vector<Value *> values;
|
||||||
for (auto constDef : ctx->constDef()) {
|
for (auto constDef : ctx->constDef()) {
|
||||||
@ -266,93 +979,7 @@ std::any SysYIRGenerator::visitVarLocalDecl(SysYParser::VarDeclContext *ctx, Typ
|
|||||||
}
|
}
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
end
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* @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<Type*>(ctx->funcType()->accept(this));
|
|
||||||
|
|
||||||
vector<Type*> paramTypes;
|
|
||||||
vector<string> paramNames;
|
|
||||||
|
|
||||||
for(auto funcParam:funcParams){
|
|
||||||
Type* paramType = any_cast<Type*>(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sysy
|
} // namespace sysy
|
||||||
@ -77,8 +77,8 @@ private:
|
|||||||
std::unique_ptr<Module> module;
|
std::unique_ptr<Module> module;
|
||||||
IRBuilder builder;
|
IRBuilder builder;
|
||||||
SymbolTable symbols_table;
|
SymbolTable symbols_table;
|
||||||
|
|
||||||
static Type current_type;
|
int trueBlockNum = 0, falseBlockNum = 0;
|
||||||
|
|
||||||
int d = 0, n = 0;
|
int d = 0, n = 0;
|
||||||
vector<int> path;
|
vector<int> path;
|
||||||
@ -104,27 +104,29 @@ public:
|
|||||||
std::any visitFuncType(SysYParser::FuncTypeContext* ctx) override;
|
std::any visitFuncType(SysYParser::FuncTypeContext* ctx) override;
|
||||||
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
|
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
|
||||||
std::any visitVarDecl(SysYParser::VarDeclContext *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 visitInitVal(SysYParser::InitValContext *ctx) override;
|
||||||
std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override;
|
// std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override;
|
||||||
std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override;
|
// std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override;
|
||||||
std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx) override;
|
std::any visitBlockStmt(SysYParser::BlockStmtContext* 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 visitIfStmt(SysYParser::IfStmtContext *ctx) override;
|
std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override;
|
||||||
std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override;
|
std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override;
|
||||||
std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override;
|
std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override;
|
||||||
std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override;
|
std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override;
|
||||||
std::any visitReturnStmt(SysYParser::ReturnStmtContext *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 visitLValue(SysYParser::LValueContext *ctx) override;
|
||||||
// std::any visitPrimaryExp(SysYParser::PrimaryExpContext *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 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 visitCall(SysYParser::CallContext *ctx) override;
|
||||||
// std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override;
|
// std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override;
|
||||||
std::any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override;
|
// std::any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override;
|
||||||
std::any visitFuncRParams(SysYParser::FuncRParamsContext *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 visitMulExp(SysYParser::MulExpContext *ctx) override;
|
||||||
std::any visitAddExp(SysYParser::AddExpContext *ctx) override;
|
std::any visitAddExp(SysYParser::AddExpContext *ctx) override;
|
||||||
std::any visitRelExp(SysYParser::RelExpContext *ctx) override;
|
std::any visitRelExp(SysYParser::RelExpContext *ctx) override;
|
||||||
|
|||||||
Reference in New Issue
Block a user