[lab2]add a TODO table
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
// SysYIRGenerator.cpp
|
// SysYIRGenerator.cpp
|
||||||
#include "SysYIRGenerator.h"
|
#include "SysYIRGenerator.h"
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
// #TODO浮点数精度还是有问题
|
||||||
std::string SysYIRGenerator::generateIR(SysYParser::CompUnitContext* unit) {
|
std::string SysYIRGenerator::generateIR(SysYParser::CompUnitContext* unit) {
|
||||||
visitCompUnit(unit);
|
visitCompUnit(unit);
|
||||||
return irStream.str();
|
return irStream.str();
|
||||||
@@ -42,6 +42,17 @@ std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
|
|||||||
|
|
||||||
if (constDef->constInitVal()) {
|
if (constDef->constInitVal()) {
|
||||||
std::string value = std::any_cast<std::string>(constDef->constInitVal()->accept(this));
|
std::string value = std::any_cast<std::string>(constDef->constInitVal()->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
|
irStream << " store " << llvmType << " " << value << ", " << llvmType
|
||||||
<< "* " << allocaName << ", align 4\n";
|
<< "* " << allocaName << ", align 4\n";
|
||||||
}
|
}
|
||||||
@@ -76,7 +87,7 @@ std::any SysYIRGenerator::visitVarDef(SysYParser::VarDefContext* ctx) {
|
|||||||
double floatValue = std::stod(value);
|
double floatValue = std::stod(value);
|
||||||
uint64_t hexValue = reinterpret_cast<uint64_t&>(floatValue);
|
uint64_t hexValue = reinterpret_cast<uint64_t&>(floatValue);
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "0x" << std::hex << std::uppercase << hexValue;
|
ss << "0x" << std::hex << std::uppercase << (hexValue & (0xffffffffUL << 32));
|
||||||
value = ss.str();
|
value = ss.str();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
throw std::runtime_error("Invalid float literal: " + value);
|
throw std::runtime_error("Invalid float literal: " + value);
|
||||||
@@ -94,6 +105,8 @@ std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext* ctx) {
|
|||||||
currentFunction = ctx->Ident()->getText();
|
currentFunction = ctx->Ident()->getText();
|
||||||
currentReturnType = getLLVMType(ctx->funcType()->getText());
|
currentReturnType = getLLVMType(ctx->funcType()->getText());
|
||||||
symbolTable.clear();
|
symbolTable.clear();
|
||||||
|
tmpTable.clear();
|
||||||
|
tempCounter = 0;
|
||||||
hasReturn = false;
|
hasReturn = false;
|
||||||
|
|
||||||
irStream << "define dso_local " << currentReturnType << " @" << currentFunction << "(";
|
irStream << "define dso_local " << currentReturnType << " @" << currentFunction << "(";
|
||||||
@@ -110,7 +123,22 @@ std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext* ctx) {
|
|||||||
}
|
}
|
||||||
tempCounter++;
|
tempCounter++;
|
||||||
irStream << ") #0 {\n";
|
irStream << ") #0 {\n";
|
||||||
|
|
||||||
|
if (ctx->funcFParams()) {
|
||||||
|
auto params = ctx->funcFParams()->funcFParam();
|
||||||
|
for (size_t i = 0; i < params.size(); ++i) {
|
||||||
|
std::string varName = params[i]->Ident()->getText();
|
||||||
|
std::string type = params[i]->bType()->getText();
|
||||||
|
std::string llvmType = getLLVMType(type);
|
||||||
|
std::string allocaName = getNextTemp();
|
||||||
|
tmpTable[allocaName] = llvmType;
|
||||||
|
|
||||||
|
irStream << " " << allocaName << " = alloca " << llvmType << ", align 4\n";
|
||||||
|
irStream << " store " << llvmType << " " << symbolTable[varName].first << ", " << llvmType
|
||||||
|
<< "* " << allocaName << ", align 4\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
ctx->blockStmt()->accept(this);
|
ctx->blockStmt()->accept(this);
|
||||||
|
|
||||||
if (!hasReturn) {
|
if (!hasReturn) {
|
||||||
@@ -141,13 +169,13 @@ std::any SysYIRGenerator::visitStmt(SysYParser::StmtContext* ctx) {
|
|||||||
double floatValue = std::stod(rhs);
|
double floatValue = std::stod(rhs);
|
||||||
uint64_t hexValue = reinterpret_cast<uint64_t&>(floatValue);
|
uint64_t hexValue = reinterpret_cast<uint64_t&>(floatValue);
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "0x" << std::hex << std::uppercase << hexValue;
|
ss << "0x" << std::hex << std::uppercase << (hexValue & (0xffffffffUL << 32));
|
||||||
rhs = ss.str();
|
rhs = ss.str();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
throw std::runtime_error("Invalid float literal: " + rhs);
|
throw std::runtime_error("Invalid float literal: " + rhs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
irStream << " store " << lhsType << " " << rhs << ", " << lhsType
|
irStream << " store1 " << lhsType << " " << rhs << ", " << lhsType
|
||||||
<< "* " << lhsAlloca << ", align 4\n";
|
<< "* " << lhsAlloca << ", align 4\n";
|
||||||
} else if (ctx->RETURN()) {
|
} else if (ctx->RETURN()) {
|
||||||
hasReturn = true;
|
hasReturn = true;
|
||||||
@@ -289,7 +317,7 @@ std::any SysYIRGenerator::visitRelExp(SysYParser::RelExpContext* ctx) {
|
|||||||
std::string right = std::any_cast<std::string>(addExps[i]->accept(this));
|
std::string right = std::any_cast<std::string>(addExps[i]->accept(this));
|
||||||
std::string op = ctx->children[2*i-1]->getText();
|
std::string op = ctx->children[2*i-1]->getText();
|
||||||
std::string temp = getNextTemp();
|
std::string temp = getNextTemp();
|
||||||
std::string type = left.substr(0, left.find(' '));
|
std::string type = tmpTable[left];
|
||||||
if (op == "<") {
|
if (op == "<") {
|
||||||
irStream << " " << temp << " = icmp slt " << type << " " << left << ", " << right << "\n";
|
irStream << " " << temp << " = icmp slt " << type << " " << left << ", " << right << "\n";
|
||||||
} else if (op == ">") {
|
} else if (op == ">") {
|
||||||
@@ -311,7 +339,7 @@ std::any SysYIRGenerator::visitEqExp(SysYParser::EqExpContext* ctx) {
|
|||||||
std::string right = std::any_cast<std::string>(relExps[i]->accept(this));
|
std::string right = std::any_cast<std::string>(relExps[i]->accept(this));
|
||||||
std::string op = ctx->children[2*i-1]->getText();
|
std::string op = ctx->children[2*i-1]->getText();
|
||||||
std::string temp = getNextTemp();
|
std::string temp = getNextTemp();
|
||||||
std::string type = left.substr(0, left.find(' '));
|
std::string type = tmpTable[left];
|
||||||
if (op == "==") {
|
if (op == "==") {
|
||||||
irStream << " " << temp << " = icmp eq " << type << " " << left << ", " << right << "\n";
|
irStream << " " << temp << " = icmp eq " << type << " " << left << ", " << right << "\n";
|
||||||
} else if (op == "!=") {
|
} else if (op == "!=") {
|
||||||
|
|||||||
Reference in New Issue
Block a user