[lab2]修复了标签冗余错误,以及一些其他bug
This commit is contained in:
@ -8,7 +8,9 @@ std::string SysYIRGenerator::generateIR(SysYParser::CompUnitContext* unit) {
|
||||
}
|
||||
|
||||
std::string SysYIRGenerator::getNextTemp() {
|
||||
return "%" + std::to_string(tempCounter++);
|
||||
std::string ret = "%" + std::to_string(tempCounter++);
|
||||
tmpTable[ret] = "void";
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string SysYIRGenerator::getLLVMType(const std::string& type) {
|
||||
@ -44,12 +46,14 @@ std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
|
||||
<< "* " << allocaName << ", align 4\n";
|
||||
}
|
||||
symbolTable[varName] = {allocaName, llvmType};
|
||||
tmpTable[allocaName] = llvmType;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext* ctx) {
|
||||
std::string type = ctx->bType()->getText();
|
||||
currentVarType = getLLVMType(type);
|
||||
for (auto varDef : ctx->varDef()) {
|
||||
varDef->accept(this);
|
||||
}
|
||||
@ -58,7 +62,7 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext* ctx) {
|
||||
|
||||
std::any SysYIRGenerator::visitVarDef(SysYParser::VarDefContext* ctx) {
|
||||
std::string varName = ctx->Ident()->getText();
|
||||
std::string type = symbolTable[varName].second;
|
||||
std::string type = currentVarType;
|
||||
std::string llvmType = getLLVMType(type);
|
||||
std::string allocaName = getNextTemp();
|
||||
|
||||
@ -66,10 +70,23 @@ std::any SysYIRGenerator::visitVarDef(SysYParser::VarDefContext* ctx) {
|
||||
|
||||
if (ctx->ASSIGN()) {
|
||||
std::string value = std::any_cast<std::string>(ctx->initVal()->accept(this));
|
||||
|
||||
if (llvmType == "float") {
|
||||
try {
|
||||
double floatValue = std::stod(value);
|
||||
uint64_t hexValue = reinterpret_cast<uint64_t&>(floatValue);
|
||||
std::stringstream ss;
|
||||
ss << "0x" << std::hex << std::uppercase << hexValue;
|
||||
value = ss.str();
|
||||
} catch (...) {
|
||||
throw std::runtime_error("Invalid float literal: " + value);
|
||||
}
|
||||
}
|
||||
irStream << " store " << llvmType << " " << value << ", " << llvmType
|
||||
<< "* " << allocaName << ", align 4\n";
|
||||
}
|
||||
symbolTable[varName] = {allocaName, llvmType};
|
||||
tmpTable[allocaName] = llvmType;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -78,18 +95,20 @@ std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext* ctx) {
|
||||
currentReturnType = getLLVMType(ctx->funcType()->getText());
|
||||
symbolTable.clear();
|
||||
hasReturn = false;
|
||||
tempCounter = 0;
|
||||
|
||||
irStream << "define dso_local " << currentReturnType << " @" << currentFunction << "(";
|
||||
if (ctx->funcFParams()) {
|
||||
auto params = ctx->funcFParams()->funcFParam();
|
||||
tempCounter += params.size();
|
||||
for (size_t i = 0; i < params.size(); ++i) {
|
||||
if (i > 0) irStream << ", ";
|
||||
std::string paramType = getLLVMType(params[i]->bType()->getText());
|
||||
irStream << paramType << " noundef %" << i;
|
||||
symbolTable[params[i]->Ident()->getText()] = {"%" + std::to_string(i), paramType};
|
||||
tmpTable["%" + std::to_string(i)] = paramType;
|
||||
}
|
||||
}
|
||||
tempCounter++;
|
||||
irStream << ") #0 {\n";
|
||||
|
||||
ctx->blockStmt()->accept(this);
|
||||
@ -117,6 +136,17 @@ std::any SysYIRGenerator::visitStmt(SysYParser::StmtContext* ctx) {
|
||||
std::string lhsAlloca = std::any_cast<std::string>(ctx->lValue()->accept(this));
|
||||
std::string lhsType = symbolTable[ctx->lValue()->Ident()->getText()].second;
|
||||
std::string rhs = std::any_cast<std::string>(ctx->exp()->accept(this));
|
||||
if (lhsType == "float") {
|
||||
try {
|
||||
double floatValue = std::stod(rhs);
|
||||
uint64_t hexValue = reinterpret_cast<uint64_t&>(floatValue);
|
||||
std::stringstream ss;
|
||||
ss << "0x" << std::hex << std::uppercase << hexValue;
|
||||
rhs = ss.str();
|
||||
} catch (...) {
|
||||
throw std::runtime_error("Invalid float literal: " + rhs);
|
||||
}
|
||||
}
|
||||
irStream << " store " << lhsType << " " << rhs << ", " << lhsType
|
||||
<< "* " << lhsAlloca << ", align 4\n";
|
||||
} else if (ctx->RETURN()) {
|
||||
@ -162,6 +192,7 @@ std::any SysYIRGenerator::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
|
||||
std::string type = symbolTable[varName].second;
|
||||
std::string temp = getNextTemp();
|
||||
irStream << " " << temp << " = load " << type << ", " << type << "* " << allocaPtr << ", align 4\n";
|
||||
tmpTable[temp] = type;
|
||||
return temp;
|
||||
} else if (ctx->exp()) {
|
||||
return ctx->exp()->accept(this);
|
||||
@ -172,9 +203,9 @@ std::any SysYIRGenerator::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
|
||||
|
||||
std::any SysYIRGenerator::visitNumber(SysYParser::NumberContext* ctx) {
|
||||
if (ctx->ILITERAL()) {
|
||||
return "i32 " + ctx->ILITERAL()->getText();
|
||||
return ctx->ILITERAL()->getText();
|
||||
} else if (ctx->FLITERAL()) {
|
||||
return "float " + ctx->FLITERAL()->getText();
|
||||
return ctx->FLITERAL()->getText();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@ -185,6 +216,7 @@ std::any SysYIRGenerator::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
|
||||
std::string op = ctx->unaryOp()->getText();
|
||||
std::string temp = getNextTemp();
|
||||
std::string type = operand.substr(0, operand.find(' '));
|
||||
tmpTable[temp] = type;
|
||||
if (op == "-") {
|
||||
irStream << " " << temp << " = sub " << type << " 0, " << operand << "\n";
|
||||
} else if (op == "!") {
|
||||
@ -206,6 +238,7 @@ std::any SysYIRGenerator::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
|
||||
argList += args[i];
|
||||
}
|
||||
irStream << " " << temp << " = call " << currentReturnType << " @" << funcName << "(" << argList << ")\n";
|
||||
tmpTable[temp] = currentReturnType;
|
||||
return temp;
|
||||
}
|
||||
return ctx->primaryExp()->accept(this);
|
||||
@ -218,7 +251,7 @@ std::any SysYIRGenerator::visitMulExp(SysYParser::MulExpContext* ctx) {
|
||||
std::string right = std::any_cast<std::string>(unaryExps[i]->accept(this));
|
||||
std::string op = ctx->children[2*i-1]->getText();
|
||||
std::string temp = getNextTemp();
|
||||
std::string type = left.substr(0, left.find(' '));
|
||||
std::string type = tmpTable[left];
|
||||
if (op == "*") {
|
||||
irStream << " " << temp << " = mul nsw " << type << " " << left << ", " << right << "\n";
|
||||
} else if (op == "/") {
|
||||
@ -238,7 +271,7 @@ std::any SysYIRGenerator::visitAddExp(SysYParser::AddExpContext* ctx) {
|
||||
std::string right = std::any_cast<std::string>(mulExps[i]->accept(this));
|
||||
std::string op = ctx->children[2*i-1]->getText();
|
||||
std::string temp = getNextTemp();
|
||||
std::string type = left.substr(0, left.find(' '));
|
||||
std::string type = tmpTable[left];
|
||||
if (op == "+") {
|
||||
irStream << " " << temp << " = add nsw " << type << " " << left << ", " << right << "\n";
|
||||
} else if (op == "-") {
|
||||
|
||||
@ -14,7 +14,9 @@ public:
|
||||
private:
|
||||
std::stringstream irStream;
|
||||
int tempCounter = 0;
|
||||
std::string currentVarType;
|
||||
std::map<std::string, std::pair<std::string, std::string>> symbolTable;
|
||||
std::map<std::string, std::string> tmpTable;
|
||||
std::vector<std::string> globalVars;
|
||||
std::string currentFunction;
|
||||
std::string currentReturnType;
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
//test add
|
||||
|
||||
|
||||
int main(){
|
||||
int main(int e){
|
||||
int a, b;
|
||||
float d;
|
||||
float c;
|
||||
a = 10;
|
||||
b = 2;
|
||||
int c = a;
|
||||
d = 1.1 ;
|
||||
return a + b + c;
|
||||
a = 11;
|
||||
c = 1.3 ;
|
||||
return a+b;
|
||||
}
|
||||
|
||||
int add(int a, int b){
|
||||
return a+b;
|
||||
}
|
||||
Reference in New Issue
Block a user