[lab2][night release]temporary stable version 0.1
This commit is contained in:
@ -1,7 +1,11 @@
|
|||||||
// SysYIRGenerator.cpp
|
// SysYIRGenerator.cpp
|
||||||
|
// TODO:类型转换及其检查
|
||||||
|
// TODO:sysy库函数处理
|
||||||
|
// TODO:数组处理
|
||||||
|
// TODO:对while、continue、break的测试
|
||||||
#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();
|
||||||
@ -26,22 +30,83 @@ std::any SysYIRGenerator::visitCompUnit(SysYParser::CompUnitContext* ctx) {
|
|||||||
decl->accept(this);
|
decl->accept(this);
|
||||||
}
|
}
|
||||||
for (auto funcDef : ctx->funcDef()) {
|
for (auto funcDef : ctx->funcDef()) {
|
||||||
|
inFunction = true; // 进入函数定义
|
||||||
funcDef->accept(this);
|
funcDef->accept(this);
|
||||||
|
inFunction = false; // 离开函数定义
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext* ctx) {
|
||||||
|
// TODO:数组初始化
|
||||||
|
std::string type = ctx->bType()->getText();
|
||||||
|
currentVarType = getLLVMType(type);
|
||||||
|
|
||||||
|
for (auto varDef : ctx->varDef()) {
|
||||||
|
if (!inFunction) {
|
||||||
|
// 全局变量声明
|
||||||
|
std::string varName = varDef->Ident()->getText();
|
||||||
|
std::string llvmType = getLLVMType(type);
|
||||||
|
std::string value = "0"; // 默认值为 0
|
||||||
|
|
||||||
|
if (varDef->ASSIGN()) {
|
||||||
|
value = std::any_cast<std::string>(varDef->initVal()->accept(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
irStream << "@" << varName << " = dso_local global " << llvmType << " " << value << ", align 4\n";
|
||||||
|
globalVars.push_back(varName); // 记录全局变量
|
||||||
|
} else {
|
||||||
|
// 局部变量声明
|
||||||
|
varDef->accept(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
|
std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
|
||||||
|
// TODO:数组初始化
|
||||||
std::string type = ctx->bType()->getText();
|
std::string type = ctx->bType()->getText();
|
||||||
for (auto constDef : ctx->constDef()) {
|
for (auto constDef : ctx->constDef()) {
|
||||||
|
if (!inFunction) {
|
||||||
|
// 全局常量声明
|
||||||
|
std::string varName = constDef->Ident()->getText();
|
||||||
|
std::string llvmType = getLLVMType(type);
|
||||||
|
std::string value = "0"; // 默认值为 0
|
||||||
|
|
||||||
|
try {
|
||||||
|
value = std::any_cast<std::string>(constDef->constInitVal()->accept(this));
|
||||||
|
} catch (...) {
|
||||||
|
throw std::runtime_error("Const value must be initialized upon definition.");
|
||||||
|
}
|
||||||
|
|
||||||
|
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 << "@" << varName << " = dso_local constant " << llvmType << " " << value << ", align 4\n";
|
||||||
|
globalVars.push_back(varName); // 记录全局变量
|
||||||
|
} else {
|
||||||
|
// 局部常量声明
|
||||||
std::string varName = constDef->Ident()->getText();
|
std::string varName = constDef->Ident()->getText();
|
||||||
std::string llvmType = getLLVMType(type);
|
std::string llvmType = getLLVMType(type);
|
||||||
std::string allocaName = getNextTemp();
|
std::string allocaName = getNextTemp();
|
||||||
|
std::string value = "0"; // 默认值为 0
|
||||||
|
|
||||||
|
try {
|
||||||
|
value = std::any_cast<std::string>(constDef->constInitVal()->accept(this));
|
||||||
|
} catch (...) {
|
||||||
|
throw std::runtime_error("Const value must be initialized upon definition.");
|
||||||
|
}
|
||||||
|
|
||||||
irStream << " " << allocaName << " = alloca " << llvmType << ", align 4\n";
|
irStream << " " << allocaName << " = alloca " << llvmType << ", align 4\n";
|
||||||
|
|
||||||
if (constDef->constInitVal()) {
|
|
||||||
std::string value = std::any_cast<std::string>(constDef->constInitVal()->accept(this));
|
|
||||||
if (llvmType == "float") {
|
if (llvmType == "float") {
|
||||||
try {
|
try {
|
||||||
double floatValue = std::stod(value);
|
double floatValue = std::stod(value);
|
||||||
@ -55,23 +120,16 @@ std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
|
|||||||
}
|
}
|
||||||
irStream << " store " << llvmType << " " << value << ", " << llvmType
|
irStream << " store " << llvmType << " " << value << ", " << llvmType
|
||||||
<< "* " << allocaName << ", align 4\n";
|
<< "* " << allocaName << ", align 4\n";
|
||||||
}
|
|
||||||
symbolTable[varName] = {allocaName, llvmType};
|
symbolTable[varName] = {allocaName, llvmType};
|
||||||
tmpTable[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);
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::any SysYIRGenerator::visitVarDef(SysYParser::VarDefContext* ctx) {
|
std::any SysYIRGenerator::visitVarDef(SysYParser::VarDefContext* ctx) {
|
||||||
|
// TODO:数组初始化
|
||||||
std::string varName = ctx->Ident()->getText();
|
std::string varName = ctx->Ident()->getText();
|
||||||
std::string type = currentVarType;
|
std::string type = currentVarType;
|
||||||
std::string llvmType = getLLVMType(type);
|
std::string llvmType = getLLVMType(type);
|
||||||
@ -331,7 +389,6 @@ std::any SysYIRGenerator::visitAddExp(SysYParser::AddExpContext* ctx) {
|
|||||||
std::string left = std::any_cast<std::string>(mulExps[0]->accept(this));
|
std::string left = std::any_cast<std::string>(mulExps[0]->accept(this));
|
||||||
for (size_t i = 1; i < mulExps.size(); ++i) {
|
for (size_t i = 1; i < mulExps.size(); ++i) {
|
||||||
std::string right = std::any_cast<std::string>(mulExps[i]->accept(this));
|
std::string right = std::any_cast<std::string>(mulExps[i]->accept(this));
|
||||||
irStream << "right is " << right << "\n";
|
|
||||||
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 = tmpTable[left];
|
std::string type = tmpTable[left];
|
||||||
|
|||||||
@ -32,6 +32,8 @@ private:
|
|||||||
std::string getNextTemp();
|
std::string getNextTemp();
|
||||||
std::string getLLVMType(const std::string& type);
|
std::string getLLVMType(const std::string& type);
|
||||||
|
|
||||||
|
bool inFunction = false; // 标识当前是否处于函数内部
|
||||||
|
|
||||||
// 访问方法
|
// 访问方法
|
||||||
std::any visitCompUnit(SysYParser::CompUnitContext* ctx) override;
|
std::any visitCompUnit(SysYParser::CompUnitContext* ctx) override;
|
||||||
std::any visitConstDecl(SysYParser::ConstDeclContext* ctx) override;
|
std::any visitConstDecl(SysYParser::ConstDeclContext* ctx) override;
|
||||||
|
|||||||
@ -1,40 +1,10 @@
|
|||||||
//test add
|
//test add
|
||||||
|
//const int a33[2] = {66,88};
|
||||||
|
|
||||||
int a1 = 1;
|
int main(){
|
||||||
int a2 = 2;
|
|
||||||
int a3 = 3;
|
|
||||||
int a4 = 4;
|
|
||||||
int a5 = 5;
|
|
||||||
int a6 = 6;
|
|
||||||
int a7 = 7;
|
|
||||||
int a8 = 8;
|
|
||||||
int a9 = 9;
|
|
||||||
int a10 = 10;
|
|
||||||
int a11 = 11;
|
|
||||||
int a12 = 12;
|
|
||||||
int a13 = 13;
|
|
||||||
int a14 = 14;
|
|
||||||
int a15 = 15;
|
|
||||||
int a16 = 16;
|
|
||||||
int a17 = 1;
|
|
||||||
int a18 = 2;
|
|
||||||
int a19 = 3;
|
|
||||||
int a20 = 4;
|
|
||||||
int a21 = 5;
|
|
||||||
int a22 = 6;
|
|
||||||
int a23 = 7;
|
|
||||||
int a24 = 8;
|
|
||||||
int a25 = 9;
|
|
||||||
int a26 = 10;
|
|
||||||
int a27 = 11;
|
|
||||||
int a28 = 12;
|
|
||||||
int a29 = 13;
|
|
||||||
int a30 = 14;
|
|
||||||
int a31 = 15;
|
|
||||||
int a32 = 16;
|
|
||||||
|
|
||||||
int main(int e){
|
|
||||||
int a, b;
|
int a, b;
|
||||||
|
// int g[2][3][4] = {0,1,2,3,4,5,6,7,8,};
|
||||||
|
// const int f[2] = {33,44};
|
||||||
float c;
|
float c;
|
||||||
a = 10;
|
a = 10;
|
||||||
b = 2;
|
b = 2;
|
||||||
|
|||||||
Reference in New Issue
Block a user