exp2 first commit

This commit is contained in:
Downright
2025-03-19 19:06:14 +08:00
parent a6f95366c8
commit d4d7e6494b
2 changed files with 445 additions and 3 deletions

View File

@@ -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<Type *>(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<Value *> values;
for (auto constDef : ctx->constDef()) {
auto name = constDef->Ident()->getText();
// get its dimensions
vector<Value *> dims;
for (auto dim : constDef->constExp())
dims.push_back(any_cast<Value *>(dim->accept(this)));
if (dims.size() == 0) {
auto init = constDef->ASSIGN() ? any_cast<Value *>((constDef->constInitVal()->constExp()->accept(this)))
: nullptr;
if (init && isa<ConstantValue>(init)){
Type *btype = type->as<PointerType>()->getBaseType();
if (btype->isInt() && init->getType()->isFloat())
init = ConstantValue::get((int)dynamic_cast<ConstantValue *>(init)->getFloat());
else if (btype->isFloat() && init->getType()->isInt())
init = ConstantValue::get((float)dynamic_cast<ConstantValue *>(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<Value *>(dims[0])
: nullptr;
auto global_value = module->createGlobalValue(name, type, dims, init);
if (constDef->ASSIGN()) {
d = 0;
n = 0;
path.clear();
path = vector<int>(dims.size(), 0);
isalloca = false;
current_type = global_value->getType()->as<PointerType>()->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<Value *> values;
for (auto varDef : ctx->varDef()) {
auto name = varDef->Ident()->getText();
// get its dimensions
vector<Value *> dims;
for (auto dim : varDef->constExp())
dims.push_back(any_cast<Value *>(dim->accept(this)));
if (dims.size() == 0) {
auto init = varDef->ASSIGN() ? any_cast<Value *>((varDef->initVal()->exp()->accept(this)))
: nullptr;
if (init && isa<ConstantValue>(init)){
Type *btype = type->as<PointerType>()->getBaseType();
if (btype->isInt() && init->getType()->isFloat())
init = ConstantValue::get((int)dynamic_cast<ConstantValue *>(init)->getFloat());
else if (btype->isFloat() && init->getType()->isInt())
init = ConstantValue::get((float)dynamic_cast<ConstantValue *>(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<Value *>(dims[0])
: nullptr;
auto global_value = module->createGlobalValue(name, type, dims, init);
if (varDef->ASSIGN()) {
d = 0;
n = 0;
path.clear();
path = vector<int>(dims.size(), 0);
isalloca = false;
current_type = global_value->getType()->as<PointerType>()->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<Value *> values;
// handle variables
for (auto constDef : ctx->constDef()) {
auto name = constDef->Ident()->getText();
vector<Value *> dims;
for (auto dim : constDef->constExp())
dims.push_back(any_cast<Value *>(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<Value *>(constDef->constInitVal()->constExp()->accept(this));
if (isa<ConstantValue>(value)) {
if (ctx->bType()->INT() && dynamic_cast<ConstantValue *>(value)->isFloat())
value = ConstantValue::get((int)dynamic_cast<ConstantValue *>(value)->getFloat());
else if (ctx->bType()->FLOAT() && dynamic_cast<ConstantValue *>(value)->isInt())
value = ConstantValue::get((float)dynamic_cast<ConstantValue *>(value)->getInt());
}
else if (alloca->getType()->as<PointerType>()->getBaseType()->isInt() && value->getType()->isFloat())
value = builder.createFtoIInst(value);
else if (alloca->getType()->as<PointerType>()->getBaseType()->isFloat() && value->getType()->isInt())
value = builder.createIToFInst(value);
auto store = builder.createStoreInst(value, alloca);
}
else{
d = 0;
n = 0;
path.clear();
path = vector<int>(alloca->getNumDims(), 0);
isalloca = true;
current_alloca = alloca;
current_type = alloca->getType()->as<PointerType>()->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<Value *> values;
for (auto varDef : ctx->varDef()) {
auto name = varDef->Ident()->getText();
vector<Value *> dims;
for (auto dim : varDef->constExp())
dims.push_back(any_cast<Value *>(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<Value *>(varDef->initVal()->exp()->accept(this));
if (isa<ConstantValue>(value)) {
if (ctx->bType()->INT() && dynamic_cast<ConstantValue *>(value)->isFloat())
value = ConstantValue::get((int)dynamic_cast<ConstantValue *>(value)->getFloat());
else if (ctx->bType()->FLOAT() && dynamic_cast<ConstantValue *>(value)->isInt())
value = ConstantValue::get((float)dynamic_cast<ConstantValue *>(value)->getInt());
}
else if (alloca->getType()->as<PointerType>()->getBaseType()->isInt() && value->getType()->isFloat())
value = builder.createFtoIInst(value);
else if (alloca->getType()->as<PointerType>()->getBaseType()->isFloat() && value->getType()->isInt())
value = builder.createIToFInst(value);
auto store = builder.createStoreInst(value, alloca);
}
else{
d = 0;
n = 0;
path.clear();
path = vector<int>(alloca->getNumDims(), 0);
isalloca = true;
current_alloca = alloca;
current_type = alloca->getType()->as<PointerType>()->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<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) {