Compare commits

...

47 Commits

Author SHA1 Message Date
mxr e79d677644 fix(sem)解决常量数组初始化错误问题
1 week ago
potapo c8f40ea09a 浮点实现,常量存在问题以及存储
2 weeks ago
potapo d9201de428 函数调用
2 weeks ago
LuoHello 700bbb4e3b <feature/ir>全局变量及局部变量区分,支持整型常量
2 weeks ago
LuoHello 728de089ff 控制流if,break,while,continue实现,条件跳转,无条件跳转实现,函数参数,函数类型系
2 weeks ago
LuoHello bc4400c1c7 控制流if,break,while,continue实现,条件跳转,无条件跳转实现,函数参数,函数类型系统完善
2 weeks ago
mxr c945a61f90 fix(sem)解决数组变量绑定缺失问题
2 weeks ago
potapo 0826c86772 嵌套初始化实现,库函数未增加
2 weeks ago
potapo ce25b612bf 数组基本实现成功,嵌套聚合初始化暂未实现
2 weeks ago
potapo fa76f0fbfc 数组基本实现成功,嵌套聚合初始化暂未实现
2 weeks ago
mxr 6e129b3a56 fix(sem)fix merge problem
2 weeks ago
potapo 5e7e8a6ff2 数组未实现
2 weeks ago
potapo 9c7095bba7 实现赋值
2 weeks ago
potapo 97c01debbd 基本测试通过但有函数没有实现
2 weeks ago
potapo f53f7ec82c 函数返回错误类型
2 weeks ago
LuoHello affccfb27c 完善 FunctionType 支持:扩展 CreateFunction 以支持 FunctionType,更新 IR 生成和打印
2 weeks ago
mxr b93d769576 feat(sem)增添常量绑定
2 weeks ago
mxr 9efcdde353 feat(sem)修改变量绑定
2 weeks ago
mxr 74f325c6fd feat(sem)常量浮点类型隐式转换为整型
2 weeks ago
mxr 8477ab4aca fix(sem)修正常量表达式求值问题
2 weeks ago
ftt 8e42c77caf 继续修改数组下标问题
2 weeks ago
mxr bff9a5d296 fix(sem)修正标量常量当作数组处理的问题
2 weeks ago
mxr 6cc1908515 chore(sem)合并ir分支到sem
2 weeks ago
ftt e0c8898dae 继续修改数组下标问题
2 weeks ago
LuoHello 310c93feac IRGen,IR fit our antrl4,full make passed
2 weeks ago
mxr 066db23e40 chore(sem)删除错误上传的文件
2 weeks ago
mxr 40403e955d feat(sem)补充常量求值
2 weeks ago
ftt 7eed5fe6f6 [sema] 数组下标个数不匹配
2 weeks ago
mxr 4098545062 feat(sem)补充符号表对库函数stoptime的支持
2 weeks ago
mxr f6773274dd feat(sem)补充符号表对库函数starttime的支持
2 weeks ago
mxr e1a4f30488 test(test)修改测试脚本run.sh用于批量测试语义分析结果
2 weeks ago
ftt f3fe34801e feat(sem)提交语义分析B部分
2 weeks ago
mxr d175189193 fix(sem)修正上一次提交的语法错误
2 weeks ago
mxr d1f2efa4ae feat(sem)补充符号表对库函数的支持
2 weeks ago
mxr a015a4bc30 fix(sem)修正符号表部分的编译错误
3 weeks ago
mxr c4479eaa1e fix(sem)修正符号表的语法错误
3 weeks ago
mxr a0d5288351 feat(sem)补充符号表对浮点类型的支持
3 weeks ago
mxr 5d4bb511d1 feat(sem)补充符号表实现
3 weeks ago
mxr c450277c83 feat(sem)补充类型系统Label类型
3 weeks ago
mxr c21c066e4d feat(sem)补充类型系统浮点类型
3 weeks ago
mxr 2070193fcd feat(sem)补充类型系统
3 weeks ago
mxr a1ba450950 chore(git)修改.gitignore文件
3 weeks ago
LuoHello 56753bc842 feat:SysY.g4删除Number,使用进制及数据类型区分常量,本地测试通过
3 weeks ago
mxr 43e257368f fix(frontend): 修改SysY.g4语法规则,通过前端编译,不能通过全量编译
3 weeks ago
pw6fhtz7q 4f8dec86d7 Merge pull request '实验一' (#1) from feature/lab1 into master
3 weeks ago
mxr 3b3318613a test(test): 添加测试脚本run.sh
3 weeks ago
mxr a8bd6d647d feat(frontend): 添加SysY.g4语法和词法描述
3 weeks ago

6
.gitignore vendored

@ -68,3 +68,9 @@ Thumbs.db
# Project outputs
# =========================
test/test_result/
# =========================
# mxr
# =========================
result.txt
build.sh

@ -41,10 +41,16 @@
namespace ir {
class Type;
class ArrayType;
class FunctionType;
class Value;
class User;
class ConstantValue;
class ConstantInt;
class ConstantFloat;
class ConstantArray;
class ConstantZero;
class ConstantAggregateZero;
class GlobalValue;
class Instruction;
class BasicBlock;
@ -77,39 +83,134 @@ class Use {
};
// IR 上下文:集中管理类型、常量等共享资源,便于复用与扩展。
// ir/IR.h - 修改 Context 类定义
class Context {
public:
Context() = default;
~Context();
// 去重创建 i32 常量。
// 去重创建 i32 常量
ConstantInt* GetConstInt(int v);
// 去重创建浮点常量
ConstantFloat* GetConstFloat(float v);
// 创建数组常量(不去重,因为数组常量通常比较复杂且组合多样)
ConstantArray* GetConstArray(std::shared_ptr<ArrayType> ty,
std::vector<ConstantValue*> elements);
// 获取零常量(按类型缓存)
ConstantZero* GetZeroConstant(std::shared_ptr<Type> ty);
// 获取聚合类型的零常量
ConstantAggregateZero* GetAggregateZero(std::shared_ptr<Type> ty);
std::string NextTemp();
private:
std::unordered_map<int, std::unique_ptr<ConstantInt>> const_ints_;
// 浮点常量:使用整数表示浮点数位模式作为键(避免浮点精度问题)
std::unordered_map<uint32_t, std::unique_ptr<ConstantFloat>> const_floats_;
// 零常量缓存(按类型指针)
std::unordered_map<Type*, std::unique_ptr<ConstantZero>> zero_constants_;
std::unordered_map<Type*, std::unique_ptr<ConstantAggregateZero>> aggregate_zeros_;
// 数组常量简单存储,不去重(因为数组常量通常组合多样,去重成本高)
std::vector<std::unique_ptr<ConstantArray>> const_arrays_;
int temp_index_ = -1;
};
class Type {
public:
enum class Kind { Void, Int32, PtrInt32 };
explicit Type(Kind k);
enum class Kind { Void, Int32, Float, PtrInt32, PtrFloat, Label, Array, Function,
Int1, PtrInt1};
virtual ~Type() = default;
// 使用静态共享对象获取类型。
// 同一类型可直接比较返回值是否相等,例如:
// Type::GetInt32Type() == Type::GetInt32Type()
static const std::shared_ptr<Type>& GetVoidType();
static const std::shared_ptr<Type>& GetInt32Type();
static const std::shared_ptr<Type>& GetFloatType();
static const std::shared_ptr<Type>& GetPtrInt32Type();
Kind GetKind() const;
bool IsVoid() const;
bool IsInt32() const;
bool IsPtrInt32() const;
static const std::shared_ptr<Type>& GetPtrFloatType();
static const std::shared_ptr<Type>& GetLabelType();
static std::shared_ptr<ArrayType> GetArrayType(std::shared_ptr<Type> elem, std::vector<int> dims);
static std::shared_ptr<FunctionType> GetFunctionType(std::shared_ptr<Type> ret, std::vector<std::shared_ptr<Type>> params);
static const std::shared_ptr<Type>& GetInt1Type();
static const std::shared_ptr<Type>& GetPtrInt1Type();
// 类型判断
Kind GetKind() const { return kind_; }
bool IsVoid() const { return kind_ == Kind::Void; }
bool IsInt32() const { return kind_ == Kind::Int32; }
bool IsFloat() const { return kind_ == Kind::Float; }
bool IsPtrInt32() const { return kind_ == Kind::PtrInt32; }
bool IsPtrFloat() const { return kind_ == Kind::PtrFloat; }
bool IsLabel() const { return kind_ == Kind::Label; }
bool IsArray() const { return kind_ == Kind::Array; }
bool IsFunction() const { return kind_ == Kind::Function; }
bool IsInt1() const { return kind_ == Kind::Int1; }
bool IsPtrInt1() const { return kind_ == Kind::PtrInt1; }
// 类型属性
virtual size_t Size() const; // 字节大小
virtual size_t Alignment() const; // 对齐要求
virtual bool IsComplete() const; // 是否为完整类型(非 void数组维度已知等
protected:
explicit Type(Kind k); // 构造函数 protected只能由工厂和派生类调用
private:
Kind kind_;
};
// 数组类型
class ArrayType : public Type {
public:
// 获取元素类型和维度
const std::shared_ptr<Type>& GetElementType() const { return elem_type_; }
const std::vector<int>& GetDimensions() const { return dims_; }
size_t GetElementCount() const; // 总元素个数
size_t Size() const override;
size_t Alignment() const override;
bool IsComplete() const override;
protected:
ArrayType(std::shared_ptr<Type> elem, std::vector<int> dims);
friend class Type; // 允许 Type::GetArrayType 构造
private:
std::shared_ptr<Type> elem_type_;
std::vector<int> dims_;
};
// 函数类型
class FunctionType : public Type {
public:
const std::shared_ptr<Type>& GetReturnType() const { return return_type_; }
const std::vector<std::shared_ptr<Type>>& GetParamTypes() const { return param_types_; }
size_t Size() const override; // 函数类型没有大小,通常返回 0
size_t Alignment() const override; // 无对齐要求
bool IsComplete() const override; // 函数类型视为完整
protected:
FunctionType(std::shared_ptr<Type> ret, std::vector<std::shared_ptr<Type>> params);
friend class Type;
private:
std::shared_ptr<Type> return_type_;
std::vector<std::shared_ptr<Type>> param_types_;
};
class Value {
public:
Value(std::shared_ptr<Type> ty, std::string name);
@ -151,8 +252,82 @@ class ConstantInt : public ConstantValue {
int value_{};
};
// 后续还需要扩展更多指令类型。
enum class Opcode { Add, Sub, Mul, Alloca, Load, Store, Ret };
// 在 ConstantInt 类之后添加以下类
// ConstantFloat - 浮点常量
class ConstantFloat : public ConstantValue {
public:
ConstantFloat(std::shared_ptr<Type> ty, float v);
float GetValue() const { return value_; }
private:
float value_{};
};
// ConstantArray - 数组常量
class ConstantArray : public ConstantValue {
public:
// 构造函数:接收数组类型和常量元素列表
ConstantArray(std::shared_ptr<ArrayType> ty, std::vector<ConstantValue*> elements);
// 获取元素数量
size_t GetNumElements() const { return elements_.size(); }
// 获取指定索引的元素
ConstantValue* GetElement(size_t index) const { return elements_[index]; }
// 获取所有元素
const std::vector<ConstantValue*>& GetElements() const { return elements_; }
// 验证常量数组的类型是否正确
bool IsValid() const;
private:
std::vector<ConstantValue*> elements_;
};
// ConstantZero - 零常量(用于零初始化)
class ConstantZero : public ConstantValue {
public:
explicit ConstantZero(std::shared_ptr<Type> ty);
// 工厂方法:创建特定类型的零常量
static std::unique_ptr<ConstantZero> GetZero(std::shared_ptr<Type> ty);
};
// ConstantAggregateZero - 聚合类型的零常量(数组、结构体等)
class ConstantAggregateZero : public ConstantValue {
public:
explicit ConstantAggregateZero(std::shared_ptr<Type> ty);
// 获取聚合类型
std::shared_ptr<Type> GetAggregateType() const { return GetType(); }
// 工厂方法:创建聚合类型的零常量
static std::unique_ptr<ConstantAggregateZero> GetZero(std::shared_ptr<Type> ty);
};
//function 参数占位类,目前仅保存类型和名字,后续可扩展更多属性(例如是否为数组参数、数组维度等)。
class Argument : public Value {
public:
Argument(std::shared_ptr<Type> ty, std::string name);
};
// 后续还需要扩展更多指令类型。add call instruction 只是最小占位,后续可以继续补 sub/mul/div/rem、br/condbr、phi、gep 等指令。
enum class Opcode {
Add, Sub, Mul,
Alloca, Load, Store, Ret, Call,
Br, CondBr, Icmp, ZExt, Trunc,
Div, Mod,
And, Or, Not,
GEP,
FAdd, FSub, FMul, FDiv,
FCmp,
SIToFP, // 整数转浮点
FPToSI, // 浮点转整数
FPExt, // 浮点扩展
FPTrunc, // 浮点截断
};
// ZExt 和 Trunc 是零扩展和截断指令,SysY 的 int (i32) vs LLVM IR 的比较结果 (i1)。
// User 是所有“会使用其他 Value 作为输入”的 IR 对象的抽象基类。
// 当前实现中只有 Instruction 继承自 User。
@ -162,7 +337,16 @@ class User : public Value {
size_t GetNumOperands() const;
Value* GetOperand(size_t index) const;
void SetOperand(size_t index, Value* value);
// 添加模板方法,支持派生类自动转换
template<typename T>
void SetOperand(size_t index, T* value) {
SetOperand(index, static_cast<Value*>(value));
}
template<typename T>
void AddOperand(T* value) {
AddOperand(static_cast<Value*>(value));
}
protected:
// 统一的 operand 入口。
void AddOperand(Value* value);
@ -173,9 +357,42 @@ class User : public Value {
// GlobalValue 是全局值/全局变量体系的空壳占位类。
// 当前只补齐类层次,具体初始化器、打印和链接语义后续再补。
// ir/IR.h - 修正 GlobalValue 定义
// ir/IR.h - 修正 GlobalValue 定义
class GlobalValue : public User {
public:
private:
std::vector<ConstantValue*> initializer_; // 初始化值列表
bool is_constant_ = false; // 是否为常量如const变量
bool is_extern_ = false; // 是否为外部声明
public:
GlobalValue(std::shared_ptr<Type> ty, std::string name);
// 初始化器相关 - 使用 ConstantValue*
void SetInitializer(ConstantValue* init);
void SetInitializer(const std::vector<ConstantValue*>& init);
const std::vector<ConstantValue*>& GetInitializer() const { return initializer_; }
bool HasInitializer() const { return !initializer_.empty(); }
// 常量属性
void SetConstant(bool is_const) { is_constant_ = is_const; }
bool IsConstant() const { return is_constant_; }
// 外部声明
void SetExtern(bool is_extern) { is_extern_ = is_extern; }
bool IsExtern() const { return is_extern_; }
// 类型判断 - 使用 Type 的方法
bool IsArray() const { return GetType()->IsArray(); }
bool IsScalar() const { return GetType()->IsInt32() || GetType()->IsFloat(); }
// 获取数组大小(如果是数组类型)
int GetArraySize() const {
if (auto* array_ty = dynamic_cast<ArrayType*>(GetType().get())) {
return array_ty->GetElementCount();
}
return 0;
}
};
class Instruction : public User {
@ -223,6 +440,284 @@ class StoreInst : public Instruction {
Value* GetPtr() const;
};
// 在 IR.h 中修改 BranchInst 类定义
class BranchInst : public Instruction {
public:
// 无条件跳转构造函数
BranchInst(std::shared_ptr<Type> void_ty, BasicBlock* target)
: Instruction(Opcode::Br, void_ty, ""),
is_conditional_(false),
cond_(nullptr),
target_(target),
true_target_(nullptr),
false_target_(nullptr) {}
// 条件跳转构造函数
BranchInst(std::shared_ptr<Type> void_ty, Value* cond,
BasicBlock* true_target, BasicBlock* false_target)
: Instruction(Opcode::CondBr, void_ty, ""),
is_conditional_(true),
cond_(cond),
target_(nullptr),
true_target_(true_target),
false_target_(false_target) {
// 添加操作数以便维护 def-use 关系
AddOperand(cond);
// 注意BasicBlock 也是 Value也需要添加到操作数中
// 但 BasicBlock 继承自 Value所以可以添加
AddOperand(true_target);
AddOperand(false_target);
}
// 判断是否为条件跳转
bool IsConditional() const { return is_conditional_; }
// 获取无条件跳转的目标(仅适用于无条件跳转)
BasicBlock* GetTarget() const {
if (is_conditional_) {
throw std::runtime_error("GetTarget called on conditional branch");
}
return target_;
}
// 获取条件值(仅适用于条件跳转)
Value* GetCondition() const {
if (!is_conditional_) {
throw std::runtime_error("GetCondition called on unconditional branch");
}
return cond_;
}
// 获取真分支目标(仅适用于条件跳转)
BasicBlock* GetTrueTarget() const {
if (!is_conditional_) {
throw std::runtime_error("GetTrueTarget called on unconditional branch");
}
return true_target_;
}
// 获取假分支目标(仅适用于条件跳转)
BasicBlock* GetFalseTarget() const {
if (!is_conditional_) {
throw std::runtime_error("GetFalseTarget called on unconditional branch");
}
return false_target_;
}
// 设置无条件跳转目标
void SetTarget(BasicBlock* target) {
if (is_conditional_) {
throw std::runtime_error("SetTarget called on conditional branch");
}
target_ = target;
}
// 设置条件跳转的分支目标
void SetTrueTarget(BasicBlock* target) {
if (!is_conditional_) {
throw std::runtime_error("SetTrueTarget called on unconditional branch");
}
true_target_ = target;
// 更新操作数
SetOperand(1, target);
}
void SetFalseTarget(BasicBlock* target) {
if (!is_conditional_) {
throw std::runtime_error("SetFalseTarget called on unconditional branch");
}
false_target_ = target;
// 更新操作数
SetOperand(2, target);
}
void SetCondition(Value* cond) {
if (!is_conditional_) {
throw std::runtime_error("SetCondition called on unconditional branch");
}
cond_ = cond;
// 更新操作数
SetOperand(0, cond);
}
private:
bool is_conditional_;
Value* cond_; // 条件值(条件跳转使用)
BasicBlock* target_; // 无条件跳转目标
BasicBlock* true_target_; // 真分支目标(条件跳转使用)
BasicBlock* false_target_; // 假分支目标(条件跳转使用)
};
// 创建整数比较指令
class IcmpInst : public Instruction {
public:
enum class Predicate {
EQ, // equal
NE, // not equal
LT, // less than
LE, // less than or equal
GT, // greater than
GE // greater than or equal
};
IcmpInst(Predicate pred, Value* lhs, Value* rhs, std::shared_ptr<Type> i1_ty, std::string name)
: Instruction(Opcode::Icmp, i1_ty, name), pred_(pred) {
AddOperand(lhs);
AddOperand(rhs);
}
Predicate GetPredicate() const { return pred_; }
Value* GetLhs() const { return GetOperand(0); }
Value* GetRhs() const { return GetOperand(1); }
private:
Predicate pred_;
};
class FcmpInst : public Instruction {
public:
enum class Predicate {
FALSE, // Always false
OEQ, // Ordered and equal
OGT, // Ordered and greater than
OGE, // Ordered and greater than or equal
OLT, // Ordered and less than
OLE, // Ordered and less than or equal
ONE, // Ordered and not equal
ORD, // Ordered (no nans)
UNO, // Unordered (isnan(x) || isnan(y))
UEQ, // Unordered or equal
UGT, // Unordered or greater than
UGE, // Unordered or greater than or equal
ULT, // Unordered or less than
ULE, // Unordered or less than or equal
UNE, // Unordered or not equal
TRUE // Always true
};
FcmpInst(Predicate pred, Value* lhs, Value* rhs,
std::shared_ptr<Type> i1_ty, std::string name)
: Instruction(Opcode::FCmp, i1_ty, name), pred_(pred) {
AddOperand(lhs);
AddOperand(rhs);
}
Predicate GetPredicate() const { return pred_; }
Value* GetLhs() const { return GetOperand(0); }
Value* GetRhs() const { return GetOperand(1); }
private:
Predicate pred_;
};
// ZExtInst - 零扩展指令
class ZExtInst : public Instruction {
public:
ZExtInst(Value* value, std::shared_ptr<Type> target_ty, std::string name = "")
: Instruction(Opcode::ZExt, target_ty, name) {
AddOperand(value);
}
// 获取被扩展的值
Value* GetValue() const {
return GetOperand(0);
}
// 获取源类型
std::shared_ptr<Type> GetSourceType() const {
return GetValue()->GetType();
}
// 获取目标类型
std::shared_ptr<Type> GetTargetType() const {
return GetType();
}
// 设置被扩展的值
void SetValue(Value* value) {
SetOperand(0, value);
}
};
// TruncInst - 截断指令
class TruncInst : public Instruction {
public:
TruncInst(Value* value, std::shared_ptr<Type> target_ty, std::string name = "")
: Instruction(Opcode::Trunc, target_ty, name) {
AddOperand(value);
}
// 获取被截断的值
Value* GetValue() const {
return GetOperand(0);
}
// 获取源类型
std::shared_ptr<Type> GetSourceType() const {
return GetValue()->GetType();
}
// 获取目标类型
std::shared_ptr<Type> GetTargetType() const {
return GetType();
}
// 设置被截断的值
void SetValue(Value* value) {
SetOperand(0, value);
}
};
class GEPInst : public Instruction {
public:
GEPInst(std::shared_ptr<Type> ptr_ty,
Value* base,
const std::vector<Value*>& indices,
const std::string& name);
Value* GetBase() const;
const std::vector<Value*>& GetIndices() const;
};
// Function 当前也采用了最小实现。
// 需要特别注意:由于项目里还没有单独的 FunctionType
// Function 继承自 Value 后,其 type_ 目前只保存“返回类型”,
// 并不能完整表达“返回类型 + 形参列表”这一整套函数签名。
// 这对当前只支持 int main() 的最小 IR 足够,但后续若补普通函数、
// 形参和调用,通常需要引入专门的函数类型表示。
class Function : public Value {
public:
// 当前构造函数接收完整的 FunctionType。
Function(std::string name, std::shared_ptr<FunctionType> func_type);
BasicBlock* CreateBlock(const std::string& name);
BasicBlock* GetEntry();
const BasicBlock* GetEntry() const;
const std::vector<std::unique_ptr<BasicBlock>>& GetBlocks() const;
// 函数增加参数的接口,目前仅保存参数类型和名字,后续可扩展更多属性(例如是否为数组参数、数组维度等)。注意这里是直接在 Function 上管理参数列表,而不是通过一个单独的 FunctionType 来表达完整函数签名,这也是当前最小实现的一个简化点。
Argument* AddArgument(std::unique_ptr<Argument> arg);
const std::vector<std::unique_ptr<Argument>>& GetArguments() const;
private:
BasicBlock* entry_ = nullptr;
std::vector<std::unique_ptr<BasicBlock>> blocks_;
std::vector<std::unique_ptr<Argument>> arguments_;
};
class CallInst : public Instruction {
public:
CallInst(std::shared_ptr<Type> ret_ty,
Function* callee,
const std::vector<Value*>& args,
const std::string& name);
Function* GetCallee() const;
const std::vector<Value*>& GetArgs() const;
private:
Function* callee_;
std::vector<Value*> args_;
};
// BasicBlock 已纳入 Value 体系,便于后续向更完整 IR 类图靠拢。
// 当前其类型仍使用 void 作为占位,后续可替换为专门的 label type。
class BasicBlock : public Value {
@ -254,39 +749,51 @@ class BasicBlock : public Value {
std::vector<BasicBlock*> successors_;
};
// Function 当前也采用了最小实现。
// 需要特别注意:由于项目里还没有单独的 FunctionType
// Function 继承自 Value 后,其 type_ 目前只保存“返回类型”,
// 并不能完整表达“返回类型 + 形参列表”这一整套函数签名。
// 这对当前只支持 int main() 的最小 IR 足够,但后续若补普通函数、
// 形参和调用,通常需要引入专门的函数类型表示。
class Function : public Value {
public:
// 当前构造函数接收的也是返回类型,而不是完整函数类型。
Function(std::string name, std::shared_ptr<Type> ret_type);
BasicBlock* CreateBlock(const std::string& name);
BasicBlock* GetEntry();
const BasicBlock* GetEntry() const;
const std::vector<std::unique_ptr<BasicBlock>>& GetBlocks() const;
private:
BasicBlock* entry_ = nullptr;
std::vector<std::unique_ptr<BasicBlock>> blocks_;
};
class Module {
public:
Module() = default;
Context& GetContext();
const Context& GetContext() const;
// 创建函数时当前只显式入返回类型,尚未接入完整的 FunctionType。
// 创建函数时传入完整的 FunctionType。
Function* CreateFunction(const std::string& name,
std::shared_ptr<Type> ret_type);
std::shared_ptr<FunctionType> func_type);
GlobalValue* CreateGlobal(const std::string& name,
std::shared_ptr<Type> ty);
Function* FindFunction(const std::string& name) const;
const std::vector<std::unique_ptr<Function>>& GetFunctions() const;
const std::vector<std::unique_ptr<GlobalValue>>& GetGlobals() const;
private:
Context context_;
std::vector<std::unique_ptr<Function>> functions_;
std::vector<std::unique_ptr<GlobalValue>> globals_;
};
// SIToFP - 整数转浮点
class SIToFPInst : public Instruction {
public:
SIToFPInst(Value* value, std::shared_ptr<Type> target_ty, std::string name = "")
: Instruction(Opcode::SIToFP, target_ty, name) {
AddOperand(value);
}
Value* GetValue() const {
return GetOperand(0);
}
};
// FPToSI - 浮点转整数
class FPToSIInst : public Instruction {
public:
FPToSIInst(Value* value, std::shared_ptr<Type> target_ty, std::string name = "")
: Instruction(Opcode::FPToSI, target_ty, name) {
AddOperand(value);
}
Value* GetValue() const {
return GetOperand(0);
}
};
class IRBuilder {
@ -297,14 +804,80 @@ class IRBuilder {
// 构造常量、二元运算、返回指令的最小集合。
ConstantInt* CreateConstInt(int v);
ConstantFloat* CreateConstFloat(float v); // 新增
ConstantArray* CreateConstArray(std::shared_ptr<ArrayType> ty,
std::vector<ConstantValue*> elements); // 新增
ConstantZero* CreateZeroConstant(std::shared_ptr<Type> ty); // 新增
BinaryInst* CreateBinary(Opcode op, Value* lhs, Value* rhs,
const std::string& name);
BinaryInst* CreateAdd(Value* lhs, Value* rhs, const std::string& name);
AllocaInst* CreateAllocaI32(const std::string& name);
AllocaInst* CreateAllocaFloat(const std::string& name);
LoadInst* CreateLoad(Value* ptr, const std::string& name);
StoreInst* CreateStore(Value* val, Value* ptr);
ReturnInst* CreateRet(Value* v);
CallInst* CreateCall(Function* callee, const std::vector<Value*>& args,
const std::string& name);
// 创建无条件跳转
BranchInst* CreateBr(BasicBlock* target);
// 创建条件跳转
BranchInst* CreateCondBr(Value* cond, BasicBlock* true_target,
BasicBlock* false_target);
// 创建整数比较指令
IcmpInst* CreateICmpEQ(Value* lhs, Value* rhs, const std::string& name);
IcmpInst* CreateICmpNE(Value* lhs, Value* rhs, const std::string& name);
IcmpInst* CreateICmpLT(Value* lhs, Value* rhs, const std::string& name);
IcmpInst* CreateICmpLE(Value* lhs, Value* rhs, const std::string& name);
IcmpInst* CreateICmpGT(Value* lhs, Value* rhs, const std::string& name);
IcmpInst* CreateICmpGE(Value* lhs, Value* rhs, const std::string& name);
// 创建类型转换指令
ZExtInst* CreateZExt(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name = "");
TruncInst* CreateTrunc(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name = "");
// 便捷方法
ZExtInst* CreateZExtI1ToI32(Value* value, const std::string& name = "zext");
TruncInst* CreateTruncI32ToI1(Value* value, const std::string& name = "trunc");
BinaryInst* CreateDiv(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateMod(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateMul(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateSub(Value* lhs, Value* rhs, const std::string& name);
// 比较运算接口
BinaryInst* CreateAnd(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateOr(Value* lhs, Value* rhs, const std::string& name);
IcmpInst* CreateNot(Value* val, const std::string& name);
GEPInst* CreateGEP(Value* base, const std::vector<Value*>& indices, const std::string& name);
// 浮点运算
BinaryInst* CreateFAdd(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateFSub(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateFMul(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateFDiv(Value* lhs, Value* rhs, const std::string& name);
// 浮点比较
FcmpInst* CreateFCmpOEQ(Value* lhs, Value* rhs, const std::string& name);
FcmpInst* CreateFCmpONE(Value* lhs, Value* rhs, const std::string& name);
FcmpInst* CreateFCmpOLT(Value* lhs, Value* rhs, const std::string& name);
FcmpInst* CreateFCmpOLE(Value* lhs, Value* rhs, const std::string& name);
FcmpInst* CreateFCmpOGT(Value* lhs, Value* rhs, const std::string& name);
FcmpInst* CreateFCmpOGE(Value* lhs, Value* rhs, const std::string& name);
// 类型转换
SIToFPInst* CreateSIToFP(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name = "");
FPToSIInst* CreateFPToSI(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name = "");
private:
Context& ctx_;
BasicBlock* insert_block_;
@ -313,6 +886,9 @@ class IRBuilder {
class IRPrinter {
public:
void Print(const Module& module, std::ostream& os);
private:
void PrintConstant(const ConstantValue* constant, std::ostream& os);
};
} // namespace ir

@ -21,37 +21,130 @@ class Value;
}
class IRGenImpl final : public SysYBaseVisitor {
public:
public:
IRGenImpl(ir::Module& module, const SemanticContext& sema);
// 顶层
std::any visitCompUnit(SysYParser::CompUnitContext* ctx) override;
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx) override;
// 块
std::any visitBlock(SysYParser::BlockContext* ctx) override; // 注意:规则名为 Block
std::any visitBlockItem(SysYParser::BlockItemContext* ctx) override;
// 声明
std::any visitDecl(SysYParser::DeclContext* ctx) override;
std::any visitStmt(SysYParser::StmtContext* ctx) override;
std::any visitVarDef(SysYParser::VarDefContext* ctx) override;
std::any visitReturnStmt(SysYParser::ReturnStmtContext* ctx) override;
std::any visitParenExp(SysYParser::ParenExpContext* ctx) override;
std::any visitNumberExp(SysYParser::NumberExpContext* ctx) override;
std::any visitVarExp(SysYParser::VarExpContext* ctx) override;
std::any visitAdditiveExp(SysYParser::AdditiveExpContext* ctx) override;
private:
enum class BlockFlow {
std::any visitConstDecl(SysYParser::ConstDeclContext* ctx) override;
std::any visitConstDef(SysYParser::ConstDefContext* ctx) override;
std::any visitInitVal(SysYParser::InitValContext* ctx) override;
std::any visitConstInitVal(SysYParser::ConstInitValContext* ctx) override;
// 语句
std::any visitStmt(SysYParser::StmtContext* ctx) override;
// 表达式
// 基本表达式(变量、常量、括号表达式)直接翻译为 IR 中的值;函数调用和一元运算需要特殊处理。
std::any visitExp(SysYParser::ExpContext* ctx) override;
std::any visitCond(SysYParser::CondContext* ctx) override;
std::any visitLVal(SysYParser::LValContext* ctx) override;
std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override;
std::any visitUnaryExp(SysYParser::UnaryExpContext* ctx) override;
std::any visitFuncRParams(SysYParser::FuncRParamsContext* ctx) override;
std::any visitMulExp(SysYParser::MulExpContext* ctx) override;
// 加法表达式、乘法表达式、关系表达式、相等表达式、条件表达式分别对应不同的访问函数,按照优先级分层访问,最终调用 visitLVal 来处理变量访问
std::any visitAddExp(SysYParser::AddExpContext* ctx) override;
std::any visitRelExp(SysYParser::RelExpContext* ctx) override;
std::any visitEqExp(SysYParser::EqExpContext* ctx) override;
std::any visitLAndExp(SysYParser::LAndExpContext* ctx) override;
std::any visitLOrExp(SysYParser::LOrExpContext* ctx) override;
std::any visitConstExp(SysYParser::ConstExpContext* ctx) override;
// 辅助函数
ir::Value* EvalExpr(SysYParser::ExpContext& expr); // 只保留一处
ir::Value* EvalCond(SysYParser::CondContext& cond);
std::any visitCallExp(SysYParser::UnaryExpContext* ctx);
std::vector<ir::Value*> ProcessNestedInitVals(SysYParser::InitValContext* ctx);
int TryEvaluateConstInt(SysYParser::ConstExpContext* ctx);
void AddRuntimeFunctions();
ir::Function* CreateRuntimeFunctionDecl(const std::string& funcName);
private:
// 辅助函数声明
enum class BlockFlow{
Continue,
Terminated,
};
BlockFlow VisitBlockItemResult(SysYParser::BlockItemContext& item);
ir::Value* EvalExpr(SysYParser::ExpContext& expr);
BlockFlow HandleReturnStmt(SysYParser::StmtContext* ctx);
BlockFlow HandleIfStmt(SysYParser::StmtContext* ctx);
BlockFlow HandleWhileStmt(SysYParser::StmtContext* ctx);
BlockFlow HandleBreakStmt(SysYParser::StmtContext* ctx);
BlockFlow HandleContinueStmt(SysYParser::StmtContext* ctx);
BlockFlow HandleAssignStmt(SysYParser::StmtContext* ctx);
// 完全正确的左值判断函数
bool IsLValueExpression(SysYParser::ExpContext* ctx);
bool IsLValueInAddExp(SysYParser::AddExpContext* ctx);
bool IsLValueInMulExp(SysYParser::MulExpContext* ctx);
bool IsLValueInUnaryExp(SysYParser::UnaryExpContext* ctx);
bool IsLValueInPrimaryExp(SysYParser::PrimaryExpContext* ctx);
// 循环上下文结构
struct LoopContext {
ir::BasicBlock* condBlock;
ir::BasicBlock* bodyBlock;
ir::BasicBlock* exitBlock;
};
struct ArrayInfo {
std::vector<ir::Value*> elements;
std::vector<int> dimensions;
};
std::vector<LoopContext> loopStack_;
ir::Module& module_;
const SemanticContext& sema_;
ir::Function* func_;
ir::IRBuilder builder_;
// 名称绑定由 Sema 负责IRGen 只维护“声明 -> 存储槽位”的代码生成状态。
ir::Value* EvalAssign(SysYParser::StmtContext* ctx);
// 按 VarDefContext 查找存储位置(用于数组访问等场景)
std::unordered_map<SysYParser::VarDefContext*, ir::Value*> storage_map_;
// 按变量名快速查找(用于 LVal 等场景)
std::unordered_map<std::string, ir::Value*> local_var_map_; // 局部变量
std::unordered_map<std::string, ir::GlobalValue*> global_map_; // 全局变量
std::unordered_map<std::string, ir::Value*> param_map_; // 函数参数
// 常量映射:常量名 -> 常量值(标量常量)
std::unordered_map<std::string, ir::ConstantValue*> const_value_map_;
// 全局常量映射:常量名 -> 全局变量(数组常量)
std::unordered_map<std::string, ir::GlobalValue*> const_global_map_;
// 原有的常量存储映射(用于兼容)
std::unordered_map<antlr4::ParserRuleContext*, ir::Value*> const_storage_map_;
std::unordered_map<SysYParser::VarDefContext*, ArrayInfo> array_info_map_;
// 新增:处理全局和局部变量的辅助函数
std::any HandleGlobalVariable(SysYParser::VarDefContext* ctx,
const std::string& varName,
bool is_array);
std::any HandleLocalVariable(SysYParser::VarDefContext* ctx,
const std::string& varName,
bool is_array);
// 常量求值辅助函数
int EvaluateConstAddExp(SysYParser::AddExpContext* ctx);
int EvaluateConstMulExp(SysYParser::MulExpContext* ctx);
int EvaluateConstUnaryExp(SysYParser::UnaryExpContext* ctx);
int EvaluateConstPrimaryExp(SysYParser::PrimaryExpContext* ctx);
int EvaluateConstExp(SysYParser::ExpContext* ctx);
};
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,

@ -2,29 +2,93 @@
#pragma once
#include <unordered_map>
#include <vector>
#include <memory>
#include "SysYParser.h"
#include "ir/IR.h"
// 表达式信息结构
struct ExprInfo {
std::shared_ptr<ir::Type> type = nullptr;
bool is_lvalue = false;
bool is_const = false;
bool is_const_int = false; // 是否是整型常量
int const_int_value = 0;
float const_float_value = 0.0f;
antlr4::ParserRuleContext* node = nullptr; // 对应的语法树节点
};
// 语义分析上下文:存储分析过程中产生的信息
class SemanticContext {
public:
void BindVarUse(SysYParser::VarContext* use,
SysYParser::VarDefContext* decl) {
var_uses_[use] = decl;
}
SysYParser::VarDefContext* ResolveVarUse(
const SysYParser::VarContext* use) const {
auto it = var_uses_.find(use);
return it == var_uses_.end() ? nullptr : it->second;
}
private:
std::unordered_map<const SysYParser::VarContext*,
SysYParser::VarDefContext*>
var_uses_;
public:
// ----- 变量使用绑定(使用 LValContext 而不是 VarContext-----
void BindVarUse(SysYParser::LValContext* use,
SysYParser::VarDefContext* decl) {
var_uses_[use] = decl;
}
SysYParser::VarDefContext* ResolveVarUse(
const SysYParser::LValContext* use) const {
auto it = var_uses_.find(use);
return it == var_uses_.end() ? nullptr : it->second;
}
void BindConstUse(SysYParser::LValContext* use, SysYParser::ConstDefContext* decl) {
const_uses_[use] = decl;
}
SysYParser::ConstDefContext* ResolveConstUse(const SysYParser::LValContext* use) const {
auto it = const_uses_.find(use);
return it == const_uses_.end() ? nullptr : it->second;
}
// ----- 表达式类型信息存储 -----
void SetExprType(antlr4::ParserRuleContext* node, const ExprInfo& info) {
ExprInfo copy = info;
copy.node = node;
expr_types_[node] = copy;
}
ExprInfo* GetExprType(antlr4::ParserRuleContext* node) {
auto it = expr_types_.find(node);
return it == expr_types_.end() ? nullptr : &it->second;
}
const ExprInfo* GetExprType(antlr4::ParserRuleContext* node) const {
auto it = expr_types_.find(node);
return it == expr_types_.end() ? nullptr : &it->second;
}
// ----- 隐式转换标记(供 IR 生成使用)-----
struct ConversionInfo {
antlr4::ParserRuleContext* node;
std::shared_ptr<ir::Type> from_type;
std::shared_ptr<ir::Type> to_type;
};
void AddConversion(antlr4::ParserRuleContext* node,
std::shared_ptr<ir::Type> from,
std::shared_ptr<ir::Type> to) {
conversions_.push_back({node, from, to});
}
const std::vector<ConversionInfo>& GetConversions() const { return conversions_; }
private:
// 变量使用映射 - 使用 LValContext 作为键
std::unordered_map<const SysYParser::LValContext*,
SysYParser::VarDefContext*> var_uses_;
// 表达式类型映射
std::unordered_map<antlr4::ParserRuleContext*, ExprInfo> expr_types_;
// 隐式转换列表
std::vector<ConversionInfo> conversions_;
std::unordered_map<const SysYParser::LValContext*, SysYParser::ConstDefContext*> const_uses_;
};
// 目前仅检查:
// - 变量先声明后使用
// - 局部变量不允许重复定义
SemanticContext RunSema(SysYParser::CompUnitContext& comp_unit);
SemanticContext RunSema(SysYParser::CompUnitContext& comp_unit);

@ -3,15 +3,121 @@
#include <string>
#include <unordered_map>
#include <vector>
#include <memory>
#include "SysYParser.h"
#include "ir/IR.h"
// 符号种类
enum class SymbolKind {
Variable,
Function,
Parameter,
Constant
};
// 符号条目
struct Symbol {
std::string name;
SymbolKind kind;
std::shared_ptr<ir::Type> type; // 指向 Type 对象的智能指针
int scope_level = 0; // 定义时的作用域深度
int stack_offset = -1; // 局部变量/参数栈偏移(全局变量为 -1
bool is_initialized = false; // 是否已初始化
bool is_builtin = false; // 是否为库函数
// 对于数组参数,存储维度信息
std::vector<int> array_dims; // 数组各维长度参数数组的第一维可能为0表示省略
bool is_array_param = false; // 是否是数组参数
// 对于函数,额外存储参数列表(类型已包含在函数类型中,这里仅用于快速访问)
std::vector<std::shared_ptr<ir::Type>> param_types;
// 对于常量,存储常量值(这里支持 int32 和 float
union ConstantValue {
int i32;
float f32;
} const_value;
bool is_int_const = true; // 标记常量类型,用于区分 int 和 float
// 关联的语法树节点(用于报错位置或进一步分析)
SysYParser::VarDefContext* var_def_ctx = nullptr;
SysYParser::ConstDefContext* const_def_ctx = nullptr;
SysYParser::FuncFParamContext* param_def_ctx = nullptr;
SysYParser::FuncDefContext* func_def_ctx = nullptr;
};
class SymbolTable {
public:
void Add(const std::string& name, SysYParser::VarDefContext* decl);
bool Contains(const std::string& name) const;
SysYParser::VarDefContext* Lookup(const std::string& name) const;
public:
SymbolTable();
~SymbolTable() = default;
// ----- 作用域管理 -----
void enterScope(); // 进入新作用域
void exitScope(); // 退出当前作用域
int currentScopeLevel() const { return static_cast<int>(scopes_.size()) - 1; }
// ----- 符号操作(推荐使用)-----
bool addSymbol(const Symbol& sym); // 添加符号到当前作用域
Symbol* lookup(const std::string& name); // 从当前作用域向外查找
Symbol* lookupCurrent(const std::string& name); // 仅在当前作用域查找
const Symbol* lookup(const std::string& name) const;
const Symbol* lookupCurrent(const std::string& name) const;
// ----- 与原接口兼容(保留原有功能)-----
void Add(const std::string& name, SysYParser::VarDefContext* decl);
bool Contains(const std::string& name) const;
SysYParser::VarDefContext* Lookup(const std::string& name) const;
// ----- 辅助函数:从语法树节点构造 Type -----
static std::shared_ptr<ir::Type> getTypeFromFuncDef(SysYParser::FuncDefContext* ctx);
void registerBuiltinFunctions();
// 对常量表达式求值(返回整数值,用于数组维度等)
int EvaluateConstExp(SysYParser::ConstExpContext* ctx) const;
// 对常量表达式求值(返回浮点值,用于全局初始化)
float EvaluateConstExpFloat(SysYParser::ConstExpContext* ctx) const;
// 对常量初始化列表求值,返回一系列常量值(扁平化)
struct ConstValue {
enum Kind { INT, FLOAT };
Kind kind;
union {
int int_val;
float float_val;
};
};
void fillArray(
std::vector<ConstValue>& values,
size_t& index,
SysYParser::ConstInitValContext* ctx,
const std::vector<int>& dims,
size_t dim_idx,
std::shared_ptr<ir::Type> base_type) const;
void fillZero(std::vector<ConstValue>& values, size_t& index,
const std::vector<int>& dims, size_t dim_idx,
std::shared_ptr<ir::Type> base_type) const;
std::vector<ConstValue> EvaluateConstInitVal(
SysYParser::ConstInitValContext* ctx,
const std::vector<int>& dims,
std::shared_ptr<ir::Type> base_type) const;
int EvaluateConstExpression(SysYParser::ExpContext* ctx) const;
private:
// 作用域栈:每个元素是一个从名字到符号的映射
std::vector<std::unordered_map<std::string, Symbol>> scopes_;
static constexpr int GLOBAL_SCOPE = 0; // 全局作用域索引
ConstValue EvaluateAddExp(SysYParser::AddExpContext* ctx) const;
ConstValue EvaluateMulExp(SysYParser::MulExpContext* ctx) const;
ConstValue EvaluateUnaryExp(SysYParser::UnaryExpContext* ctx) const;
ConstValue EvaluatePrimaryExp(SysYParser::PrimaryExpContext* ctx) const;
private:
std::unordered_map<std::string, SysYParser::VarDefContext*> table_;
std::shared_ptr<ir::Type> getTypeFromVarDef(SysYParser::VarDefContext* ctx) const;
};

File diff suppressed because it is too large Load Diff

@ -0,0 +1,98 @@
#!/bin/bash
# 测试脚本
# 用法: ./run_tests.sh [--verbose] [<单个测试文件>]
COMPILER="./build/bin/compiler"
TEST_DIR="test/test_case"
RESULT_FILE="result.txt"
VERBOSE=0
# 解析参数
if [[ "$1" == "--verbose" ]]; then
VERBOSE=1
shift
fi
# 检查编译器是否存在
if [ ! -f "$COMPILER" ]; then
echo "错误: 编译器未找到于 $COMPILER"
echo "请先完成项目构建 (cmake 和 make)"
exit 1
fi
# 如果指定了单个文件,检查文件是否存在
if [ -n "$1" ] && [ ! -f "$1" ]; then
echo "错误: 文件 $1 不存在"
exit 1
fi
# 清空(或创建)结果文件
> "$RESULT_FILE"
# 计数器
total=0
passed=0
failed=0
echo "开始测试 ir out 解析..."
echo "输出将保存到 $RESULT_FILE"
echo "------------------------"
# 确定测试文件列表
if [ -n "$1" ]; then
# 使用提供的单个文件
TEST_FILES=("$1")
else
# 收集所有 .sy 文件
mapfile -t TEST_FILES < <(find "$TEST_DIR" -type f -name "*.sy" | sort)
fi
for file in "${TEST_FILES[@]}"; do
((total++))
if [ $VERBOSE -eq 1 ]; then
echo "测试文件: $file"
else
echo -n "测试 $file ... "
fi
echo "========== $file ==========" >> "$RESULT_FILE"
if [ $VERBOSE -eq 1 ]; then
# "$COMPILER" --emit-parse-tree "$file" 2>&1 | tee -a "$RESULT_FILE"
"$COMPILER" --emit-ir "$file" 2>&1 | tee -a "$RESULT_FILE"
result=${PIPESTATUS[0]}
else
# "$COMPILER" --emit-parse-tree "$file" >> "$RESULT_FILE" 2>&1
"$COMPILER" --emit-ir "$file" >> "$RESULT_FILE" 2>&1
result=$?
fi
echo "" >> "$RESULT_FILE"
if [ $result -eq 0 ]; then
if [ $VERBOSE -eq 0 ]; then
echo "通过"
fi
((passed++))
else
if [ $VERBOSE -eq 0 ]; then
echo "失败"
else
echo ">>> 解析失败: $file"
fi
((failed++))
fi
done
echo "------------------------"
echo "总计: $total"
echo "通过: $passed"
echo "失败: $failed"
echo "详细输出已保存至 $RESULT_FILE"
if [ $failed -gt 0 ]; then
exit 1
else
exit 0
fi

@ -0,0 +1,156 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
COMPILER="$ROOT_DIR/build/bin/compiler"
TMP_DIR="$ROOT_DIR/build/test_compiler"
TEST_DIRS=("$ROOT_DIR/test/test_case/functional" "$ROOT_DIR/test/test_case/performance")
if [[ ! -x "$COMPILER" ]]; then
echo "未找到编译器: $COMPILER"
echo "请先构建编译器,例如: mkdir -p build && cd build && cmake .. && make -j"
exit 1
fi
mkdir -p "$TMP_DIR"
ir_total=0
ir_pass=0
result_total=0
result_pass=0
ir_failures=()
result_failures=()
function normalize_file() {
sed 's/\r$//' "$1"
}
for test_dir in "${TEST_DIRS[@]}"; do
if [[ ! -d "$test_dir" ]]; then
echo "跳过不存在的测试目录: $test_dir"
continue
fi
shopt -s nullglob
for input in "$test_dir"/*.sy; do
ir_total=$((ir_total+1))
base=$(basename "$input")
stem=${base%.sy}
out_dir="$TMP_DIR/$(basename "$test_dir")"
mkdir -p "$out_dir"
ll_file="$out_dir/$stem.ll"
stdout_file="$out_dir/$stem.stdout"
expected_file="$test_dir/$stem.out"
stdin_file="$test_dir/$stem.in"
echo "[TEST] $input"
# 编译并捕获所有输出
compiler_status=0
compiler_output=""
compiler_output=$("$COMPILER" --emit-ir "$input" 2>&1) || compiler_status=$?
# 临时文件存储原始输出
raw_ll="$out_dir/$stem.raw.ll"
printf '%s\n' "$compiler_output" > "$raw_ll"
# 检查编译是否成功
if [[ $compiler_status -ne 0 ]]; then
echo " [IR] 编译失败: 返回码 $compiler_status"
ir_failures+=("$input: compiler failed ($compiler_status)")
# 失败:保留原始输出(包含所有调试信息)
cp "$raw_ll" "$ll_file"
rm -f "$raw_ll"
continue
fi
# 检查是否生成了有效的函数定义(在过滤后的内容中检查)
# 先过滤一下看看是否有define
filtered_content=$(sed -E '/^\[DEBUG\]|^SymbolTable::|^Check|^绑定|^保存|^dim_count:/d' "$raw_ll")
if ! echo "$filtered_content" | grep -qE '^define '; then
echo " [IR] 失败: 未生成有效函数定义"
ir_failures+=("$input: invalid IR output")
# 失败:保留原始输出
cp "$raw_ll" "$ll_file"
rm -f "$raw_ll"
continue
fi
# 编译成功过滤掉所有调试输出只保留IR
# 过滤规则:
# 1. 以 [DEBUG] 开头的行
# 2. SymbolTable:: 开头的行
# 3. CheckLValue: 开头的行
# 4. 绑定变量: 开头的行
# 5. dim_count: 开头的行
# 6. 空行(可选)
sed -E '/^(\[DEBUG|SymbolTable::|Check|绑定|保存|dim_)/d' "$raw_ll" > "$ll_file"
# 可选:删除多余的空行
sed -i '/^$/N;/\n$/D' "$ll_file"
rm -f "$raw_ll"
ir_pass=$((ir_pass+1))
echo " [IR] 生成成功 (IR已保存到: $ll_file)"
# 运行测试
if [[ -f "$expected_file" ]]; then
result_total=$((result_total+1))
# 运行LLVM IR
run_status=0
if [[ -f "$stdin_file" ]]; then
lli "$ll_file" < "$stdin_file" > "$stdout_file" 2>&1 || run_status=$?
else
lli "$ll_file" > "$stdout_file" 2>&1 || run_status=$?
fi
# 读取预期返回值
expected=$(normalize_file "$expected_file")
# 比较返回值
if [[ "$run_status" -eq "$expected" ]]; then
result_pass=$((result_pass+1))
echo " [RUN] 返回值匹配: $run_status"
# 成功:保留已清理的.ll文件删除输出文件
rm -f "$stdout_file"
else
echo " [RUN] 返回值不匹配: got $run_status, expected $expected"
result_failures+=("$input: exit code mismatch (got $run_status, expected $expected)")
# 失败:.ll文件已经保留输出文件也保留用于调试
fi
else
echo " [RUN] 未找到预期返回值文件 $expected_file,跳过结果验证"
fi
done
shopt -u nullglob
done
# 输出统计
cat <<EOF
测试完成。
IR 生成: $ir_pass / $ir_total
结果匹配: $result_pass / $result_total
EOF
# 输出失败列表
if [[ ${#ir_failures[@]} -gt 0 ]]; then
echo ""
echo "IR 失败列表:"
for item in "${ir_failures[@]}"; do
echo " $item"
done
fi
if [[ ${#result_failures[@]} -gt 0 ]]; then
echo ""
echo "结果失败列表:"
for item in "${result_failures[@]}"; do
echo " $item"
done
echo ""
echo "失败的测试文件已保留在: $TMP_DIR"
echo "可以查看对应的.ll文件进行调试"
fi

@ -1,68 +1,154 @@
// SysY 子集语法:支持形如
// int main() { int a = 1; int b = 2; return a + b; }
// 的最小返回表达式编译。
// 后续需要自行添加
// SysY 子集语法
grammar SysY;
/*===-------------------------------------------===*/
/* Lexer rules */
/*===-------------------------------------------===*/
//----词法规则(优先级从高到低)----//
//keywords
Void : 'void';
Int : 'int';
Float : 'float';
Const : 'const';
If : 'if';
Else : 'else';
While : 'while';
Break : 'break';
Continue: 'continue';
Return : 'return';
//Two-character operator (long preferred)
LeOp : '<=';
GeOp : '>=';
EqOp : '==';
NeOp : '!=';
AndOp : '&&';
OrOp : '||';
//single character operators
AddOp : '+';
SubOp : '-';
MulOp : '*';
DivOp : '/';
QuoOp : '%';
NotOp : '!';
LOp : '<';
GOp : '>';
Assign : '=';
//Separator
Semi : ';';
Comma : ',';
L_PAREN : '(';
R_PAREN : ')';
L_BRACK : '[';
R_BRACK : ']';
L_BRACE : '{';
R_BRACE : '}';
// 16进制float first
HEX_FLOAT
: '0' [xX](
// 形式1: 0x1.921fb6p+1 (有小数点和指数)
HEX_DIGIT* '.' HEX_DIGIT+ [pP] [+-]? DECIMAL_DIGIT+
| // 形式2: 0x1p+1 (没有小数点,只有指数)
HEX_DIGIT+ [pP] [+-]? DECIMAL_DIGIT+
| // 形式3: 0x.AP-3 (小数点开头)
'.' HEX_DIGIT+ [pP] [+-]? DECIMAL_DIGIT+
)
;
fragment HEX_DIGIT: [0-9a-fA-F];
fragment DECIMAL_DIGIT: [0-9];
// 10进制float
DEC_FLOAT
: [0-9]+ '.' [0-9]* EXP? //1.2/1./1.2e10/...
| '.' [0-9]+ EXP? //.1/.1e2
| [0-9]+ EXP //1e2/1e-2
;
fragment EXP: [eE] [+-]? [0-9]+;
HEX_INT: '0' [xX] [0-9a-fA-F]+; //16进制
OCTAL_INT: '0' [0-7]*; //8进制
DECIMAL_INT: [1-9][0-9]*; //10进制
ZERO: '0'; //单独0
// 标识符
Ident
: [a-zA-Z_][a-zA-Z_0-9]*
;
INT: 'int';
RETURN: 'return';
// 注释和空白
WS
: [ \t\r\n]+ -> skip
;
ASSIGN: '=';
ADD: '+';
COMMENT
: '//' ~[\r\n]* -> skip
;
LPAREN: '(';
RPAREN: ')';
LBRACE: '{';
RBRACE: '}';
SEMICOLON: ';';
BLOCK_COMMENT
: '/*' .*? '*/' -> skip
;
ID: [a-zA-Z_][a-zA-Z_0-9]*;
ILITERAL: [0-9]+;
//----语法规则----//
compUnit
: (funcDef|decl)+ EOF
;
WS: [ \t\r\n] -> skip;
LINECOMMENT: '//' ~[\r\n]* -> skip;
BLOCKCOMMENT: '/*' .*? '*/' -> skip;
decl
: varDecl
| constDecl
;
/*===-------------------------------------------===*/
/* Syntax rules */
/*===-------------------------------------------===*/
constDecl
: Const bType constDef (Comma constDef)* Semi
;
compUnit
: funcDef EOF
bType
: Int
| Float
;
decl
: btype varDef SEMICOLON
constDef
: Ident (L_BRACK constExp R_BRACK)* Assign constInitVal
;
constInitVal
: constExp
| L_BRACE (constInitVal (Comma constInitVal)*)? R_BRACE
;
btype
: INT
varDecl
: bType varDef (Comma varDef)* Semi
;
varDef
: lValue (ASSIGN initValue)?
: Ident (L_BRACK constExp R_BRACK)* (Assign initVal)?
;
initValue
initVal
: exp
| L_BRACE (initVal (Comma initVal)*)? R_BRACE
;
funcDef
: funcType ID LPAREN RPAREN blockStmt
: funcType Ident L_PAREN (funcFParams)? R_PAREN block
;
funcType
: INT
: Void
| Int
| Float
;
funcFParams
: funcFParam (Comma funcFParam)*
;
funcFParam
: bType Ident (L_BRACK R_BRACK (L_BRACK exp R_BRACK)*)?
;
blockStmt
: LBRACE blockItem* RBRACE
block
: L_BRACE (blockItem)* R_BRACE
;
blockItem
@ -71,28 +157,85 @@ blockItem
;
stmt
: returnStmt
: lVal Assign exp Semi
| (exp)? Semi
| block
| If L_PAREN cond R_PAREN stmt (Else stmt)?
| While L_PAREN cond R_PAREN stmt
| Break Semi
| Continue Semi
| Return (exp)? Semi
;
returnStmt
: RETURN exp SEMICOLON
exp
: addExp
;
exp
: LPAREN exp RPAREN # parenExp
| var # varExp
| number # numberExp
| exp ADD exp # additiveExp
cond
: lOrExp
;
lVal
: Ident (L_BRACK exp R_BRACK)*
;
primaryExp
: L_PAREN exp R_PAREN
| lVal
| HEX_FLOAT
| DEC_FLOAT
| HEX_INT
| OCTAL_INT
| DECIMAL_INT
| ZERO
;
unaryExp
: primaryExp
| Ident L_PAREN (funcRParams)? R_PAREN
| unaryOp unaryExp
;
unaryOp
: AddOp
| SubOp
| NotOp
;
funcRParams
: exp (Comma exp)*
;
mulExp
: unaryExp
| mulExp (MulOp|DivOp|QuoOp) unaryExp
;
addExp
: mulExp
| addExp (AddOp|SubOp) mulExp
;
relExp
: addExp
| relExp (LOp|GOp|LeOp|GeOp) addExp
;
eqExp
: relExp
| eqExp (EqOp|NeOp) relExp
;
var
: ID
lAndExp
: eqExp
| lAndExp AndOp eqExp
;
lValue
: ID
lOrExp
: lAndExp
| lOrExp OrOp lAndExp
;
number
: ILITERAL
constExp
: addExp
;

@ -1,6 +1,8 @@
// 管理基础类型、整型常量池和临时名生成。
#include "ir/IR.h"
// ir/IR.cpp
#include "ir/IR.h"
#include <cstring> // for memcpy
#include <sstream>
namespace ir {
@ -15,10 +17,64 @@ ConstantInt* Context::GetConstInt(int v) {
return inserted->second.get();
}
// 新增:获取浮点常量
ConstantFloat* Context::GetConstFloat(float v) {
// 使用浮点数的二进制表示作为键,避免精度问题
uint32_t key;
std::memcpy(&key, &v, sizeof(float));
auto it = const_floats_.find(key);
if (it != const_floats_.end()) {
return it->second.get();
}
auto float_ty = Type::GetFloatType();
auto constant = std::make_unique<ConstantFloat>(float_ty, v);
auto* ptr = constant.get();
const_floats_[key] = std::move(constant);
return ptr;
}
// 新增:创建数组常量
ConstantArray* Context::GetConstArray(std::shared_ptr<ArrayType> ty,
std::vector<ConstantValue*> elements) {
auto constant = std::make_unique<ConstantArray>(ty, std::move(elements));
auto* ptr = constant.get();
const_arrays_.push_back(std::move(constant));
return ptr;
}
// 新增:获取零常量
ConstantZero* Context::GetZeroConstant(std::shared_ptr<Type> ty) {
auto it = zero_constants_.find(ty.get());
if (it != zero_constants_.end()) {
return it->second.get();
}
auto constant = std::make_unique<ConstantZero>(ty);
auto* ptr = constant.get();
zero_constants_[ty.get()] = std::move(constant);
return ptr;
}
// 新增:获取聚合类型的零常量
ConstantAggregateZero* Context::GetAggregateZero(std::shared_ptr<Type> ty) {
auto it = aggregate_zeros_.find(ty.get());
if (it != aggregate_zeros_.end()) {
return it->second.get();
}
auto constant = std::make_unique<ConstantAggregateZero>(ty);
auto* ptr = constant.get();
aggregate_zeros_[ty.get()] = std::move(constant);
return ptr;
}
std::string Context::NextTemp() {
std::ostringstream oss;
oss << "%" << ++temp_index_;
oss << "%t" << ++temp_index_;
return oss.str();
}
} // namespace ir
} // namespace ir

@ -5,10 +5,21 @@
namespace ir {
Function::Function(std::string name, std::shared_ptr<Type> ret_type)
: Value(std::move(ret_type), std::move(name)) {
Function::Function(std::string name, std::shared_ptr<FunctionType> func_type)
: Value(std::move(func_type), std::move(name)) {
entry_ = CreateBlock("entry");
}
// 向函数添加参数的实现。
Argument* Function::AddArgument(std::unique_ptr<Argument> arg) {// 独占所有权,自动释放内存
if (!arg) return nullptr; // 1. 检查参数是否为空
auto* ptr = arg.get(); // 2. 获取原始指针(用于返回)
arguments_.push_back(std::move(arg)); // 3. 将参数所有权转移到函数的参数列表中,arg已经是空指针了不能再使用arg了
return ptr; // 4. 返回参数指针,方便调用者使用
}
// 获取函数参数列表的实现。
const std::vector<std::unique_ptr<Argument>>& Function::GetArguments() const {
return arguments_;
}
BasicBlock* Function::CreateBlock(const std::string& name) {
auto block = std::make_unique<BasicBlock>(name);

@ -1,11 +1,121 @@
// GlobalValue 占位实现:
// - 具体的全局初始化器、打印和链接语义需要自行补全
// ir/GlobalValue.cpp
#include "ir/IR.h"
#include <stdexcept>
namespace ir {
GlobalValue::GlobalValue(std::shared_ptr<Type> ty, std::string name)
: User(std::move(ty), std::move(name)) {}
} // namespace ir
void GlobalValue::SetInitializer(ConstantValue* init) {
if (!init) {
throw std::runtime_error("GlobalValue::SetInitializer: init is null");
}
// 获取实际的值类型(用于类型检查)
std::shared_ptr<Type> value_type;
// 如果当前类型是指针,获取指向的值类型
if (GetType()->IsPtrInt32()) {
value_type = Type::GetInt32Type();
} else if (GetType()->IsPtrFloat()) {
value_type = Type::GetFloatType();
} else if (GetType()->IsPtrInt1()) {
value_type = Type::GetInt1Type();
} else {
// 非指针类型:直接使用当前类型
value_type = GetType();
}
// 类型检查
bool type_match = false;
// 检查标量类型
if (value_type->IsInt32() && init->GetType()->IsInt32()) {
type_match = true;
} else if (value_type->IsFloat() && init->GetType()->IsFloat()) {
type_match = true;
} else if (value_type->IsInt1() && init->GetType()->IsInt1()) {
type_match = true;
}
// 检查数组类型:允许用单个标量初始化整个数组
else if (value_type->IsArray()) {
auto* array_ty = static_cast<ArrayType*>(value_type.get());
auto* elem_type = array_ty->GetElementType().get();
if (elem_type->IsInt32() && init->GetType()->IsInt32()) {
type_match = true;
} else if (elem_type->IsFloat() && init->GetType()->IsFloat()) {
type_match = true;
}
}
if (!type_match) {
throw std::runtime_error("GlobalValue::SetInitializer: type mismatch");
}
initializer_.clear();
initializer_.push_back(init);
}
void GlobalValue::SetInitializer(const std::vector<ConstantValue*>& init) {
if (init.empty()) {
return;
}
// 获取实际的值类型
std::shared_ptr<Type> value_type;
if (GetType()->IsPtrInt32()) {
value_type = Type::GetInt32Type();
} else if (GetType()->IsPtrFloat()) {
value_type = Type::GetFloatType();
} else if (GetType()->IsPtrInt1()) {
value_type = Type::GetInt1Type();
} else {
value_type = GetType();
}
// 检查类型
if (value_type->IsArray()) {
auto* array_ty = static_cast<ArrayType*>(value_type.get());
size_t array_size = array_ty->GetElementCount();
if (init.size() > array_size) {
throw std::runtime_error("GlobalValue::SetInitializer: too many initializers");
}
// 检查每个初始化值的类型
auto* elem_type = array_ty->GetElementType().get();
for (auto* elem : init) {
bool elem_match = false;
if (elem_type->IsInt32() && elem->GetType()->IsInt32()) {
elem_match = true;
} else if (elem_type->IsFloat() && elem->GetType()->IsFloat()) {
elem_match = true;
}
if (!elem_match) {
throw std::runtime_error("GlobalValue::SetInitializer: element type mismatch");
}
}
}
else if (value_type->IsInt32() || value_type->IsFloat() || value_type->IsInt1()) {
if (init.size() != 1) {
throw std::runtime_error("GlobalValue::SetInitializer: scalar requires exactly one initializer");
}
if ((value_type->IsInt32() && !init[0]->GetType()->IsInt32()) ||
(value_type->IsFloat() && !init[0]->GetType()->IsFloat()) ||
(value_type->IsInt1() && !init[0]->GetType()->IsInt1())) {
throw std::runtime_error("GlobalValue::SetInitializer: type mismatch");
}
}
else {
throw std::runtime_error("GlobalValue::SetInitializer: unsupported type");
}
initializer_ = init;
}
} // namespace ir

@ -5,7 +5,7 @@
#include "ir/IR.h"
#include <stdexcept>
#include <cstring>
#include "utils/Log.h"
namespace ir {
@ -21,6 +21,21 @@ ConstantInt* IRBuilder::CreateConstInt(int v) {
return ctx_.GetConstInt(v);
}
// IRBuilder 方法实现
ConstantFloat* IRBuilder::CreateConstFloat(float v) {
return ctx_.GetConstFloat(v);
}
ConstantArray* IRBuilder::CreateConstArray(std::shared_ptr<ArrayType> ty,
std::vector<ConstantValue*> elements) {
return ctx_.GetConstArray(ty, std::move(elements));
}
ConstantZero* IRBuilder::CreateZeroConstant(std::shared_ptr<Type> ty) {
return ctx_.GetZeroConstant(ty);
}
BinaryInst* IRBuilder::CreateBinary(Opcode op, Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {
@ -34,7 +49,69 @@ BinaryInst* IRBuilder::CreateBinary(Opcode op, Value* lhs, Value* rhs,
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateBinary 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(op, lhs->GetType(), lhs, rhs, name);
// 检查操作码是否为有效的二元操作符
switch (op) {
case Opcode::Add:
case Opcode::Sub:
case Opcode::Mul:
case Opcode::Div:
case Opcode::Mod:
case Opcode::And:
case Opcode::Or:
// 添加浮点操作码
case Opcode::FAdd:
case Opcode::FSub:
case Opcode::FMul:
case Opcode::FDiv:
// 有效的二元操作符
break;
case Opcode::Not:
// Not是一元操作符不应该在BinaryInst中
throw std::runtime_error(FormatError("ir", "Not是一元操作符应使用其他指令"));
default:
throw std::runtime_error(FormatError("ir", "BinaryInst 不支持的操作码"));
}
// 确定结果类型
std::shared_ptr<Type> result_type;
// 检查操作数类型是否相同
if (lhs->GetType()->GetKind() != rhs->GetType()->GetKind()) {
throw std::runtime_error(
FormatError("ir", "CreateBinary 操作数类型不匹配"));
}
// 检查是否为浮点操作
bool is_float_op = (op == Opcode::FAdd || op == Opcode::FSub ||
op == Opcode::FMul || op == Opcode::FDiv);
if (is_float_op) {
// 浮点操作要求操作数是浮点类型
if (!lhs->GetType()->IsFloat()) {
throw std::runtime_error(
FormatError("ir", "浮点运算要求操作数为浮点类型"));
}
result_type = lhs->GetType();
} else {
bool is_logical = (op == Opcode::And || op == Opcode::Or);
if (is_logical) {
// 逻辑运算的结果是 int32布尔值
result_type = Type::GetInt32Type();
} else {
// 算术运算的结果类型与操作数相同
result_type = lhs->GetType();
}
// 检查操作数类型是否支持
if (!lhs->GetType()->IsInt32() && !lhs->GetType()->IsFloat()) {
throw std::runtime_error(
FormatError("ir", "CreateBinary 只支持 int32 和 float 类型"));
}
}
return insert_block_->Append<BinaryInst>(op, result_type, lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateAdd(Value* lhs, Value* rhs,
@ -49,6 +126,13 @@ AllocaInst* IRBuilder::CreateAllocaI32(const std::string& name) {
return insert_block_->Append<AllocaInst>(Type::GetPtrInt32Type(), name);
}
AllocaInst* IRBuilder::CreateAllocaFloat(const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
return insert_block_->Append<AllocaInst>(Type::GetPtrFloatType(), name);
}
LoadInst* IRBuilder::CreateLoad(Value* ptr, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
@ -57,9 +141,32 @@ LoadInst* IRBuilder::CreateLoad(Value* ptr, const std::string& name) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateLoad 缺少 ptr"));
}
return insert_block_->Append<LoadInst>(Type::GetInt32Type(), ptr, name);
auto ptr_ty = ptr->GetType();
std::shared_ptr<Type> elem_ty;
if (ptr_ty->IsPtrInt32()) {
elem_ty = Type::GetInt32Type();
} else if (ptr_ty->IsPtrFloat()) {
elem_ty = Type::GetFloatType();
} else if (ptr_ty->IsPtrInt1()) {
elem_ty = Type::GetInt1Type();
} else if (ptr_ty->IsArray()) {
// 数组类型的指针,元素类型是数组元素类型
auto* array_ty = dynamic_cast<ArrayType*>(ptr_ty.get());
if (array_ty) {
elem_ty = array_ty->GetElementType();
} else {
throw std::runtime_error(FormatError("ir", "不支持的指针类型"));
}
} else {
// 尝试其他指针类型
throw std::runtime_error(FormatError("ir", "不支持的指针类型"));
}
return insert_block_->Append<LoadInst>(elem_ty, ptr, name);
}
StoreInst* IRBuilder::CreateStore(Value* val, Value* ptr) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
@ -72,6 +179,32 @@ StoreInst* IRBuilder::CreateStore(Value* val, Value* ptr) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateStore 缺少 ptr"));
}
// 检查类型兼容性
auto ptr_ty = ptr->GetType();
auto val_ty = val->GetType();
if (ptr_ty->IsPtrInt32()) {
if (!val_ty->IsInt32()) {
throw std::runtime_error(FormatError("ir", "存储类型不匹配:期望 int32"));
}
} else if (ptr_ty->IsPtrFloat()) {
if (!val_ty->IsFloat()) {
throw std::runtime_error(FormatError("ir", "存储类型不匹配:期望 float"));
}
} else if (ptr_ty->IsArray()) {
// 数组存储:检查元素类型
auto* array_ty = dynamic_cast<ArrayType*>(ptr_ty.get());
if (array_ty) {
auto elem_ty = array_ty->GetElementType();
if (elem_ty->IsInt32() && !val_ty->IsInt32()) {
throw std::runtime_error(FormatError("ir", "数组元素类型不匹配:期望 int32"));
} else if (elem_ty->IsFloat() && !val_ty->IsFloat()) {
throw std::runtime_error(FormatError("ir", "数组元素类型不匹配:期望 float"));
}
}
}
return insert_block_->Append<StoreInst>(Type::GetVoidType(), val, ptr);
}
@ -86,4 +219,402 @@ ReturnInst* IRBuilder::CreateRet(Value* v) {
return insert_block_->Append<ReturnInst>(Type::GetVoidType(), v);
}
BranchInst* IRBuilder::CreateBr(BasicBlock* target) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!target) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateBr 缺少 target"));
}
return insert_block_->Append<BranchInst>(Type::GetVoidType(), target);
}
BranchInst* IRBuilder::CreateCondBr(Value* cond, BasicBlock* true_target,
BasicBlock* false_target) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!cond) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateCondBr 缺少 cond"));
}
if (!true_target) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateCondBr 缺少 true_target"));
}
if (!false_target) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateCondBr 缺少 false_target"));
}
return insert_block_->Append<BranchInst>(Type::GetVoidType(), cond, true_target, false_target);
}
// 创建整数相等比较
IcmpInst* IRBuilder::CreateICmpEQ(Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs || !rhs) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateICmpEQ 缺少操作数"));
}
// 检查类型必须一致
if (lhs->GetType() != rhs->GetType()) {
throw std::runtime_error(
FormatError("ir", "比较操作数类型不匹配"));
}
return insert_block_->Append<IcmpInst>(IcmpInst::Predicate::EQ, lhs, rhs,
Type::GetInt1Type(), name);
}
// 创建整数不等比较
IcmpInst* IRBuilder::CreateICmpNE(Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs || !rhs) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateICmpNE 缺少操作数"));
}
if (lhs->GetType() != rhs->GetType()) {
throw std::runtime_error(
FormatError("ir", "比较操作数类型不匹配"));
}
return insert_block_->Append<IcmpInst>(IcmpInst::Predicate::NE, lhs, rhs,
Type::GetInt1Type(), name);
}
// 创建整数小于比较
IcmpInst* IRBuilder::CreateICmpLT(Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs || !rhs) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateICmpLT 缺少操作数"));
}
if (lhs->GetType() != rhs->GetType()) {
throw std::runtime_error(
FormatError("ir", "比较操作数类型不匹配"));
}
return insert_block_->Append<IcmpInst>(IcmpInst::Predicate::LT, lhs, rhs,
Type::GetInt1Type(), name);
}
// 创建整数小于等于比较
IcmpInst* IRBuilder::CreateICmpLE(Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs || !rhs) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateICmpLE 缺少操作数"));
}
if (lhs->GetType() != rhs->GetType()) {
throw std::runtime_error(
FormatError("ir", "比较操作数类型不匹配"));
}
return insert_block_->Append<IcmpInst>(IcmpInst::Predicate::LE, lhs, rhs,
Type::GetInt1Type(), name);
}
// 创建整数大于比较
IcmpInst* IRBuilder::CreateICmpGT(Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs || !rhs) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateICmpGT 缺少操作数"));
}
if (lhs->GetType() != rhs->GetType()) {
throw std::runtime_error(
FormatError("ir", "比较操作数类型不匹配"));
}
return insert_block_->Append<IcmpInst>(IcmpInst::Predicate::GT, lhs, rhs,
Type::GetInt1Type(), name);
}
// 创建整数大于等于比较
IcmpInst* IRBuilder::CreateICmpGE(Value* lhs, Value* rhs,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs || !rhs) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateICmpGE 缺少操作数"));
}
if (lhs->GetType() != rhs->GetType()) {
throw std::runtime_error(
FormatError("ir", "比较操作数类型不匹配"));
}
return insert_block_->Append<IcmpInst>(IcmpInst::Predicate::GE, lhs, rhs,
Type::GetInt1Type(), name);
}
// 创建零扩展指令
ZExtInst* IRBuilder::CreateZExt(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!value) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateZExt 缺少 value"));
}
if (!target_ty) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateZExt 缺少 target_ty"));
}
auto src_ty = value->GetType();
// 类型检查:源类型应该是较小的整数类型
if (!src_ty->IsInt1() && !src_ty->IsInt32()) {
throw std::runtime_error(
FormatError("ir", "ZExt 源类型必须是整数类型"));
}
// 目标类型应该是较大的整数类型
if (!target_ty->IsInt32()) {
throw std::runtime_error(
FormatError("ir", "ZExt 目标类型必须是整数类型"));
}
return insert_block_->Append<ZExtInst>(value, target_ty, name);
}
// 创建截断指令
TruncInst* IRBuilder::CreateTrunc(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!value) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateTrunc 缺少 value"));
}
if (!target_ty) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateTrunc 缺少 target_ty"));
}
auto src_ty = value->GetType();
// 类型检查:源类型应该是较大的整数类型
if (!src_ty->IsInt32()) {
throw std::runtime_error(
FormatError("ir", "Trunc 源类型必须是整数类型"));
}
// 目标类型应该是较小的整数类型
if (!target_ty->IsInt1() && !target_ty->IsInt32()) {
throw std::runtime_error(
FormatError("ir", "Trunc 目标类型必须是整数类型"));
}
return insert_block_->Append<TruncInst>(value, target_ty, name);
}
// 便捷方法i1 转 i32
ZExtInst* IRBuilder::CreateZExtI1ToI32(Value* value, const std::string& name) {
return CreateZExt(value, Type::GetInt32Type(), name);
}
// 便捷方法i32 转 i1
TruncInst* IRBuilder::CreateTruncI32ToI1(Value* value, const std::string& name) {
return CreateTrunc(value, Type::GetInt1Type(), name);
}
BinaryInst* IRBuilder::CreateDiv(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateDiv 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateDiv 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::Div, lhs->GetType(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateMod(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMod 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMod 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::Mod, lhs->GetType(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateAnd(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateAnd 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateAnd 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::And, Type::GetInt32Type(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateOr(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateOr 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateOr 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::Or, Type::GetInt32Type(), lhs, rhs, name);
}
IcmpInst* IRBuilder::CreateNot(Value* val, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!val) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateNot 缺少 operand"));
}
auto zero = CreateConstInt(0);
return CreateICmpEQ(val, zero, name);
}
GEPInst* IRBuilder::CreateGEP(Value* base,
const std::vector<Value*>& indices,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!base) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateGEP 缺少 base"));
}
// 检查所有索引
for (size_t i = 0; i < indices.size(); ++i) {
if (!indices[i]) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateGEP 索引 " + std::to_string(i) + " 为空"));
}
}
// GEP返回指针类型假设与base类型相同
return insert_block_->Append<GEPInst>(base->GetType(), base, indices, name);
}
BinaryInst* IRBuilder::CreateMul(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMul 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMul 缺少 rhs"));
}
return CreateBinary(Opcode::Mul, lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateSub(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateSub 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateSub 缺少 rhs"));
}
return CreateBinary(Opcode::Sub, lhs, rhs, name);
}
// 注意:当前 CreateCall 仅支持直接调用 Function且不支持变长参数列表等复杂特性。
// 创建函数调用指令的实现,被调用的函数,参数列表,返回值临时变量名
CallInst* IRBuilder::CreateCall(Function* callee,
const std::vector<Value*>& args,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!callee) { //被调用的函数不能为空
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateCall 缺少 callee"));
}
auto func_ty = std::static_pointer_cast<FunctionType>(callee->GetType());
auto ret_ty = func_ty->GetReturnType();
return insert_block_->Append<CallInst>(ret_ty, callee, args, name);
}
BinaryInst* IRBuilder::CreateFAdd(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<BinaryInst>(Opcode::FAdd, lhs->GetType(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateFSub(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<BinaryInst>(Opcode::FSub, lhs->GetType(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateFMul(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<BinaryInst>(Opcode::FMul, lhs->GetType(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateFDiv(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<BinaryInst>(Opcode::FDiv, lhs->GetType(), lhs, rhs, name);
}
// 浮点比较
FcmpInst* IRBuilder::CreateFCmpOEQ(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<FcmpInst>(
FcmpInst::Predicate::OEQ, lhs, rhs, Type::GetInt1Type(), name);
}
FcmpInst* IRBuilder::CreateFCmpONE(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<FcmpInst>(
FcmpInst::Predicate::ONE, lhs, rhs, Type::GetInt1Type(), name);
}
FcmpInst* IRBuilder::CreateFCmpOLT(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<FcmpInst>(
FcmpInst::Predicate::OLT, lhs, rhs, Type::GetInt1Type(), name);
}
FcmpInst* IRBuilder::CreateFCmpOLE(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<FcmpInst>(
FcmpInst::Predicate::OLE, lhs, rhs, Type::GetInt1Type(), name);
}
FcmpInst* IRBuilder::CreateFCmpOGT(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<FcmpInst>(
FcmpInst::Predicate::OGT, lhs, rhs, Type::GetInt1Type(), name);
}
FcmpInst* IRBuilder::CreateFCmpOGE(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<FcmpInst>(
FcmpInst::Predicate::OGE, lhs, rhs, Type::GetInt1Type(), name);
}
// 类型转换
SIToFPInst* IRBuilder::CreateSIToFP(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name) {
return insert_block_->Append<SIToFPInst>(value, target_ty, name);
}
FPToSIInst* IRBuilder::CreateFPToSI(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name) {
return insert_block_->Append<FPToSIInst>(value, target_ty, name);
}
} // namespace ir

@ -14,12 +14,17 @@ namespace ir {
static const char* TypeToString(const Type& ty) {
switch (ty.GetKind()) {
case Type::Kind::Void:
return "void";
case Type::Kind::Int32:
return "i32";
case Type::Kind::PtrInt32:
return "i32*";
case Type::Kind::Void: return "void";
case Type::Kind::Int32: return "i32";
case Type::Kind::Float: return "float";
case Type::Kind::PtrInt32: return "i32*";
case Type::Kind::PtrFloat: return "float*";
case Type::Kind::Label: return "label";
case Type::Kind::Array: return "array";
case Type::Kind::Function: return "function";
case Type::Kind::Int1: return "i1";
case Type::Kind::PtrInt1: return "i1*";
default: return "unknown";
}
throw std::runtime_error(FormatError("ir", "未知类型"));
}
@ -40,6 +45,39 @@ static const char* OpcodeToString(Opcode op) {
return "store";
case Opcode::Ret:
return "ret";
case Opcode::Call:
return "call";
case Opcode::Br:
return "br";
case Opcode::CondBr:
return "condbr";
case Opcode::Icmp:
return "icmp";
case Opcode::Div:
return "div";
case Opcode::Mod:
return "mod";
case Opcode::ZExt:
return "zext";
case Opcode::Trunc:
return "trunc";
case Opcode::And:
return "and";
case Opcode::Or:
return "or";
case Opcode::Not:
return "not";
case Opcode::GEP:
return "getelementptr";
case Opcode::FAdd: return "fadd";
case Opcode::FSub: return "fsub";
case Opcode::FMul: return "fmul";
case Opcode::FDiv: return "fdiv";
case Opcode::FCmp: return "fcmp";
case Opcode::SIToFP: return "sitofp";
case Opcode::FPToSI: return "fptosi";
case Opcode::FPExt: return "fpext";
case Opcode::FPTrunc: return "fptrunc";
}
return "?";
}
@ -48,13 +86,44 @@ static std::string ValueToString(const Value* v) {
if (auto* ci = dynamic_cast<const ConstantInt*>(v)) {
return std::to_string(ci->GetValue());
}
return v ? v->GetName() : "<null>";
if (!v) {
return "<null>";
}
const auto& name = v->GetName();
if (name.empty()) {
return "<unnamed>";
}
if (name[0] == '%' || name[0] == '@') {
return name;
}
if (dynamic_cast<const GlobalValue*>(v)) {
return "@" + name;
}
return "%" + name;
}
void IRPrinter::Print(const Module& module, std::ostream& os) {
for (const auto& global : module.GetGlobals()) {
if (!global) continue;
os << "@" << global->GetName() << " = global ";
if (global->GetType()->IsPtrInt32()) {
os << "i32 0\n";
} else if (global->GetType()->IsPtrFloat()) {
os << "float 0.0\n";
} else {
os << TypeToString(*global->GetType()) << " zeroinitializer\n";
}
}
for (const auto& func : module.GetFunctions()) {
os << "define " << TypeToString(*func->GetType()) << " @" << func->GetName()
<< "() {\n";
auto* func_ty = static_cast<const FunctionType*>(func->GetType().get());
os << "define " << TypeToString(*func_ty->GetReturnType()) << " @" << func->GetName() << "(";
bool first = true;
for (const auto& arg : func->GetArguments()) {
if (!first) os << ", ";
first = false;
os << TypeToString(*arg->GetType()) << " %" << arg->GetName();
}
os << ") {\n";
for (const auto& bb : func->GetBlocks()) {
if (!bb) {
continue;
@ -65,7 +134,13 @@ void IRPrinter::Print(const Module& module, std::ostream& os) {
switch (inst->GetOpcode()) {
case Opcode::Add:
case Opcode::Sub:
case Opcode::Mul: {
case Opcode::Mul:
case Opcode::Div:
case Opcode::Mod:
case Opcode::And:
case Opcode::Not:
case Opcode::Or:
{
auto* bin = static_cast<const BinaryInst*>(inst);
os << " " << bin->GetName() << " = "
<< OpcodeToString(bin->GetOpcode()) << " "
@ -76,19 +151,31 @@ void IRPrinter::Print(const Module& module, std::ostream& os) {
}
case Opcode::Alloca: {
auto* alloca = static_cast<const AllocaInst*>(inst);
os << " " << alloca->GetName() << " = alloca i32\n";
std::string elem_ty_str;
if (alloca->GetType()->IsPtrInt32()) {
elem_ty_str = "i32";
} else if (alloca->GetType()->IsPtrFloat()) {
elem_ty_str = "float";
} else {
elem_ty_str = TypeToString(*alloca->GetType());
}
os << " " << alloca->GetName() << " = alloca " << elem_ty_str << "\n";
break;
}
case Opcode::Load: {
auto* load = static_cast<const LoadInst*>(inst);
os << " " << load->GetName() << " = load i32, i32* "
os << " " << load->GetName() << " = load "
<< TypeToString(*load->GetType()) << ", "
<< TypeToString(*load->GetPtr()->GetType()) << " "
<< ValueToString(load->GetPtr()) << "\n";
break;
}
case Opcode::Store: {
auto* store = static_cast<const StoreInst*>(inst);
os << " store i32 " << ValueToString(store->GetValue())
<< ", i32* " << ValueToString(store->GetPtr()) << "\n";
os << " store " << TypeToString(*store->GetValue()->GetType()) << " "
<< ValueToString(store->GetValue())
<< ", " << TypeToString(*store->GetPtr()->GetType()) << " "
<< ValueToString(store->GetPtr()) << "\n";
break;
}
case Opcode::Ret: {
@ -97,6 +184,85 @@ void IRPrinter::Print(const Module& module, std::ostream& os) {
<< ValueToString(ret->GetValue()) << "\n";
break;
}
// CallInst类在 include/ir/IR.h 中定义
case Opcode::Call: {
auto* call = static_cast<const CallInst*>(inst);
os << " " << call->GetName() << " = call "
<< TypeToString(*call->GetType()) << " @" << call->GetCallee()->GetName() << "(";
bool first = true;
for (auto* arg : call->GetArgs()) {
if (!first) os << ", ";
first = false;
os << TypeToString(*arg->GetType()) << " " << ValueToString(arg);
}
os << ")\n";
break;
}
// 在 IRPrinter.cpp 的 switch 语句中添加
case Opcode::Br:
case Opcode::CondBr: {
auto* br = static_cast<const BranchInst*>(inst);
if (!br->IsConditional()) {
os << " br label %" << br->GetTarget()->GetName() << "\n";
} else {
os << " br i1 " << ValueToString(br->GetCondition())
<< ", label %" << br->GetTrueTarget()->GetName()
<< ", label %" << br->GetFalseTarget()->GetName() << "\n";
}
break;
}
case Opcode::Icmp: {
auto* icmp = static_cast<const IcmpInst*>(inst);
os << " " << icmp->GetName() << " = icmp ";
switch (icmp->GetPredicate()) {
case IcmpInst::Predicate::EQ: os << "eq"; break;
case IcmpInst::Predicate::NE: os << "ne"; break;
case IcmpInst::Predicate::LT: os << "slt"; break;
case IcmpInst::Predicate::LE: os << "sle"; break;
case IcmpInst::Predicate::GT: os << "sgt"; break;
case IcmpInst::Predicate::GE: os << "sge"; break;
}
os << " " << TypeToString(*icmp->GetLhs()->GetType())
<< " " << ValueToString(icmp->GetLhs())
<< ", " << ValueToString(icmp->GetRhs()) << "\n";
break;
}
case Opcode::ZExt: {
auto* zext = static_cast<const ZExtInst*>(inst);
os << " " << zext->GetName() << " = zext "
<< TypeToString(*zext->GetSourceType()) << " "
<< ValueToString(zext->GetValue()) << " to "
<< TypeToString(*zext->GetTargetType()) << "\n";
break;
}
case Opcode::Trunc: {
auto* trunc = static_cast<const TruncInst*>(inst);
os << " " << trunc->GetName() << " = trunc "
<< TypeToString(*trunc->GetSourceType()) << " "
<< ValueToString(trunc->GetValue()) << " to "
<< TypeToString(*trunc->GetTargetType()) << "\n";
break;
}
case Opcode::GEP:{
// 简化打印:只打印基本信息和操作数数量
os << " " << inst->GetName() << " = getelementptr ";
os << TypeToString(*inst->GetType()) << " (";
for (size_t i = 0; i < inst->GetNumOperands(); ++i) {
if (i > 0) os << ", ";
os << ValueToString(inst->GetOperand(i));
}
os << ")\n";
break;
}
default: {
// 处理未知操作码
os << " ; 未知指令: " << OpcodeToString(inst->GetOpcode()) << "\n";
break;
}
}
}
}
@ -104,4 +270,28 @@ void IRPrinter::Print(const Module& module, std::ostream& os) {
}
}
void IRPrinter::PrintConstant(const ConstantValue* constant, std::ostream& os) {
if (auto* const_int = dynamic_cast<const ConstantInt*>(constant)) {
os << const_int->GetValue();
}
else if (auto* const_float = dynamic_cast<const ConstantFloat*>(constant)) {
os << const_float->GetValue();
}
else if (auto* const_array = dynamic_cast<const ConstantArray*>(constant)) {
os << "[";
auto& elements = const_array->GetElements();
for (size_t i = 0; i < elements.size(); ++i) {
if (i > 0) os << ", ";
PrintConstant(elements[i], os);
}
os << "]";
}
else if (auto* zero = dynamic_cast<const ConstantZero*>(constant)) {
os << "zero";
}
else if (auto* agg_zero = dynamic_cast<const ConstantAggregateZero*>(constant)) {
os << "zeroinitializer";
}
}
} // namespace ir

@ -52,7 +52,10 @@ Instruction::Instruction(Opcode op, std::shared_ptr<Type> ty, std::string name)
Opcode Instruction::GetOpcode() const { return opcode_; }
bool Instruction::IsTerminator() const { return opcode_ == Opcode::Ret; }
bool Instruction::IsTerminator() const {
return opcode_ == Opcode::Ret || opcode_ == Opcode::Br ||
opcode_ == Opcode::CondBr;
}
BasicBlock* Instruction::GetParent() const { return parent_; }
@ -61,22 +64,62 @@ void Instruction::SetParent(BasicBlock* parent) { parent_ = parent; }
BinaryInst::BinaryInst(Opcode op, std::shared_ptr<Type> ty, Value* lhs,
Value* rhs, std::string name)
: Instruction(op, std::move(ty), std::move(name)) {
if (op != Opcode::Add) {
throw std::runtime_error(FormatError("ir", "BinaryInst 当前只支持 Add"));
}
if (!lhs || !rhs) {
throw std::runtime_error(FormatError("ir", "BinaryInst 缺少操作数"));
}
// 检查操作码是否为有效的二元操作符
switch (op) {
case Opcode::Add:
case Opcode::Sub:
case Opcode::Mul:
case Opcode::Div:
case Opcode::Mod:
case Opcode::And:
case Opcode::Or:
// 有效的二元操作符
break;
case Opcode::Not:
// Not是一元操作符不应该在BinaryInst中
throw std::runtime_error(FormatError("ir", "Not是一元操作符应使用其他指令"));
default:
throw std::runtime_error(FormatError("ir", "BinaryInst 不支持的操作码"));
}
// 当前 BinaryInst 仅支持 Add/Sub/Mul且操作数和结果必须都是 i32。
if (op != Opcode::Add && op != Opcode::Sub && op != Opcode::Mul) {
}
if (!type_ || !lhs->GetType() || !rhs->GetType()) {
throw std::runtime_error(FormatError("ir", "BinaryInst 缺少类型信息"));
}
if (lhs->GetType()->GetKind() != rhs->GetType()->GetKind() ||
type_->GetKind() != lhs->GetType()->GetKind()) {
throw std::runtime_error(FormatError("ir", "BinaryInst 类型不匹配"));
}
if (!type_->IsInt32()) {
throw std::runtime_error(FormatError("ir", "BinaryInst 当前只支持 i32"));
// 对于比较操作结果类型是i1但我们的类型系统可能还没有i1
// 暂时简化所有操作都返回i32比较操作返回0或1
// 检查操作数类型是否匹配
if (lhs->GetType()->GetKind() != rhs->GetType()->GetKind()) {
throw std::runtime_error(FormatError("ir", "BinaryInst 操作数类型不匹配"));
}
// 检查操作数类型是否支持
if (!lhs->GetType()->IsInt32() && !lhs->GetType()->IsFloat()) {
throw std::runtime_error(
FormatError("ir", "BinaryInst 只支持 int32 和 float 类型"));
}
// 对于算术运算,结果类型应与操作数类型相同
bool is_logical = (op == Opcode::And || op == Opcode::Or);
if (is_logical) {
// 比较和逻辑运算的结果应该是整数类型
if (!type_->IsInt32()) {
throw std::runtime_error(
FormatError("ir", "比较和逻辑运算的结果类型必须是 int32"));
}
} else {
// 算术运算的结果类型应与操作数类型相同
if (type_->GetKind() != lhs->GetType()->GetKind()) {
throw std::runtime_error(
FormatError("ir", "BinaryInst 结果类型与操作数类型不匹配"));
}
}
AddOperand(lhs);
AddOperand(rhs);
}
@ -148,4 +191,61 @@ Value* StoreInst::GetValue() const { return GetOperand(0); }
Value* StoreInst::GetPtr() const { return GetOperand(1); }
Function* CallInst::GetCallee() const { return callee_; }
const std::vector<Value*>& CallInst::GetArgs() const { return args_; }
GEPInst::GEPInst(std::shared_ptr<Type> ptr_ty,
Value* base,
const std::vector<Value*>& indices,
const std::string& name)
: Instruction(Opcode::GEP, ptr_ty, name) {
// 添加base作为第一个操作数
AddOperand(base);
// 添加所有索引作为后续操作数
for (auto* index : indices) {
AddOperand(index);
}
}
Value* GEPInst::GetBase() const {
// 第一个操作数是base
return GetOperand(0);
}
const std::vector<Value*>& GEPInst::GetIndices() const {
// 需要返回索引列表但Instruction只存储操作数
// 这是一个设计问题:要么修改架构,要么提供辅助方法
// 简化实现返回空vector或创建临时vector
static std::vector<Value*> indices;
indices.clear();
// 索引从操作数1开始
for (size_t i = 1; i < GetNumOperands(); ++i) {
indices.push_back(GetOperand(i));
}
return indices;
}
CallInst::CallInst(std::shared_ptr<Type> ret_ty, Function* callee,
const std::vector<Value*>& args, const std::string& name)
: Instruction(Opcode::Call, std::move(ret_ty), name), // name 是 const&,这里会复制
callee_(callee), args_(args) {
if (!callee_) {
throw std::runtime_error(FormatError("ir", "CallInst 缺少被调用函数"));
}
for (auto* arg : args_) {
if (!arg) {
throw std::runtime_error(FormatError("ir", "CallInst 参数不能为 null"));
}
AddOperand(arg);
}
}
} // namespace ir

@ -9,13 +9,46 @@ Context& Module::GetContext() { return context_; }
const Context& Module::GetContext() const { return context_; }
Function* Module::CreateFunction(const std::string& name,
std::shared_ptr<Type> ret_type) {
functions_.push_back(std::make_unique<Function>(name, std::move(ret_type)));
std::shared_ptr<FunctionType> func_type) {
functions_.push_back(std::make_unique<Function>(name, std::move(func_type)));
return functions_.back().get();
}
Function* Module::FindFunction(const std::string& name) const {
for (const auto& func : functions_) {
if (func->GetName() == name) {
return func.get();
}
}
return nullptr;
}
const std::vector<std::unique_ptr<Function>>& Module::GetFunctions() const {
return functions_;
}
GlobalValue* Module::CreateGlobal(const std::string& name,
std::shared_ptr<Type> ty) {
// 对于标量类型,自动转换为指针类型
std::shared_ptr<Type> global_ty;
if (ty->IsInt32()) {
global_ty = Type::GetPtrInt32Type(); // i32 -> i32*
} else if (ty->IsFloat()) {
global_ty = Type::GetPtrFloatType(); // float -> float*
} else if (ty->IsInt1()) {
global_ty = Type::GetPtrInt1Type(); // i1 -> i1*
} else {
// 数组等类型保持不变
global_ty = ty;
}
globals_.push_back(std::make_unique<GlobalValue>(global_ty, name));
return globals_.back().get();
}
const std::vector<std::unique_ptr<GlobalValue>>& Module::GetGlobals() const {
return globals_;
}
} // namespace ir

@ -1,31 +1,219 @@
// 当前仅支持 void、i32 和 i32*。
#include "ir/IR.h"
#include <cassert>
namespace ir {
Type::Type(Kind k) : kind_(k) {}
size_t Type::Size() const {
switch (kind_) {
case Kind::Void: return 0;
case Kind::Int32: return 4;
case Kind::Float: return 4; // 单精度浮点 4 字节
case Kind::PtrInt32: return 8; // 假设 64 位指针
case Kind::PtrFloat: return 8;
case Kind::Label: return 8; // 标签地址大小(指针大小)
default: return 0; // 派生类应重写
}
}
size_t Type::Alignment() const {
switch (kind_) {
case Kind::Int32: return 4;
case Kind::Float: return 4;
case Kind::PtrInt32: return 8;
case Kind::PtrFloat: return 8;
case Kind::Label: return 8; // 与指针相同
default: return 1;
}
}
bool Type::IsComplete() const {
return kind_ != Kind::Void;
}
const std::shared_ptr<Type>& Type::GetVoidType() {
static const std::shared_ptr<Type> type = std::make_shared<Type>(Kind::Void);
static const std::shared_ptr<Type> type = std::shared_ptr<Type>(new Type(Kind::Void));
return type;
}
const std::shared_ptr<Type>& Type::GetInt32Type() {
static const std::shared_ptr<Type> type = std::make_shared<Type>(Kind::Int32);
static const std::shared_ptr<Type> type = std::shared_ptr<Type>(new Type(Kind::Int32));
return type;
}
const std::shared_ptr<Type>& Type::GetFloatType() {
static const std::shared_ptr<Type> type(new Type(Kind::Float));
return type;
}
const std::shared_ptr<Type>& Type::GetPtrInt32Type() {
static const std::shared_ptr<Type> type = std::make_shared<Type>(Kind::PtrInt32);
static const std::shared_ptr<Type> type = std::shared_ptr<Type>(new Type(Kind::PtrInt32));
return type;
}
Type::Kind Type::GetKind() const { return kind_; }
const std::shared_ptr<Type>& Type::GetPtrFloatType() {
static const std::shared_ptr<Type> type(new Type(Kind::PtrFloat));
return type;
}
const std::shared_ptr<Type>& Type::GetLabelType() {
static const std::shared_ptr<Type> type(new Type(Kind::Label));
return type;
}
// Int1 类型表示布尔值,通常用于比较指令的结果
const std::shared_ptr<Type>& Type::GetInt1Type() {
static const std::shared_ptr<Type> type = std::shared_ptr<Type>(new Type(Kind::Int1));
return type;
}
// PtrInt1 类型表示指向 Int1 的指针,主要用于条件跳转等场景
const std::shared_ptr<Type>& Type::GetPtrInt1Type() {
static const std::shared_ptr<Type> type = std::shared_ptr<Type>(new Type(Kind::PtrInt1));
return type;
}
bool Type::IsVoid() const { return kind_ == Kind::Void; }
// ---------- 数组类型缓存 ----------
// 使用自定义键类型保证唯一性:元素类型指针 + 维度向量
struct ArrayKey {
const Type* elem_type;
std::vector<int> dims;
bool Type::IsInt32() const { return kind_ == Kind::Int32; }
bool operator==(const ArrayKey& other) const {
return elem_type == other.elem_type && dims == other.dims;
}
};
bool Type::IsPtrInt32() const { return kind_ == Kind::PtrInt32; }
struct ArrayKeyHash {
std::size_t operator()(const ArrayKey& key) const {
std::size_t h = std::hash<const Type*>{}(key.elem_type);
for (int d : key.dims) {
h ^= std::hash<int>{}(d) + 0x9e3779b9 + (h << 6) + (h >> 2);
}
return h;
}
};
static std::unordered_map<ArrayKey, std::weak_ptr<ArrayType>, ArrayKeyHash>& GetArrayCache() {
static std::unordered_map<ArrayKey, std::weak_ptr<ArrayType>, ArrayKeyHash> cache;
return cache;
}
std::shared_ptr<ArrayType> Type::GetArrayType(std::shared_ptr<Type> elem,
std::vector<int> dims) {
// 检查维度合法性
for (int d : dims) {
if (d <= 0) {
// SysY 数组维度必须为正整数常量表达式,这里假设已检查
return nullptr;
}
}
ArrayKey key{elem.get(), dims};
auto& cache = GetArrayCache();
auto it = cache.find(key);
if (it != cache.end()) {
auto ptr = it->second.lock();
if (ptr) return ptr;
}
auto arr = std::shared_ptr<ArrayType>(new ArrayType(std::move(elem), std::move(dims)));
cache[key] = arr;
return arr;
}
// ---------- 函数类型缓存 ----------
struct FunctionKey {
const Type* return_type;
std::vector<const Type*> param_types;
bool operator==(const FunctionKey& other) const {
return return_type == other.return_type && param_types == other.param_types;
}
};
struct FunctionKeyHash {
std::size_t operator()(const FunctionKey& key) const {
std::size_t h = std::hash<const Type*>{}(key.return_type);
for (const Type* t : key.param_types) {
h ^= std::hash<const Type*>{}(t) + 0x9e3779b9 + (h << 6) + (h >> 2);
}
return h;
}
};
static std::unordered_map<FunctionKey, std::weak_ptr<FunctionType>, FunctionKeyHash>& GetFunctionCache() {
static std::unordered_map<FunctionKey, std::weak_ptr<FunctionType>, FunctionKeyHash> cache;
return cache;
}
std::shared_ptr<FunctionType> Type::GetFunctionType(std::shared_ptr<Type> ret,
std::vector<std::shared_ptr<Type>> params) {
// 提取裸指针用于键(保证唯一性,因为 shared_ptr 指向同一对象)
std::vector<const Type*> param_ptrs;
param_ptrs.reserve(params.size());
for (const auto& p : params) {
param_ptrs.push_back(p.get());
}
FunctionKey key{ret.get(), std::move(param_ptrs)};
auto& cache = GetFunctionCache();
auto it = cache.find(key);
if (it != cache.end()) {
auto ptr = it->second.lock();
if (ptr) return ptr;
}
auto func = std::shared_ptr<FunctionType>(new FunctionType(std::move(ret), std::move(params)));
cache[key] = func;
return func;
}
// ---------- ArrayType 实现 ----------
ArrayType::ArrayType(std::shared_ptr<Type> elem, std::vector<int> dims)
: Type(Kind::Array), elem_type_(std::move(elem)), dims_(std::move(dims)) {
// 数组元素类型必须是完整类型
assert(elem_type_ && elem_type_->IsComplete());
}
size_t ArrayType::GetElementCount() const {
size_t count = 1;
for (int d : dims_) count *= d;
return count;
}
size_t ArrayType::Size() const {
return GetElementCount() * elem_type_->Size();
}
size_t ArrayType::Alignment() const {
// 数组对齐等于其元素对齐
return elem_type_->Alignment();
}
bool ArrayType::IsComplete() const {
// 维度已确定且元素类型完整,则数组完整
return !dims_.empty() && elem_type_->IsComplete();
}
// ---------- FunctionType 实现 ----------
FunctionType::FunctionType(std::shared_ptr<Type> ret,
std::vector<std::shared_ptr<Type>> params)
: Type(Kind::Function), return_type_(std::move(ret)), param_types_(std::move(params)) {}
size_t FunctionType::Size() const {
// 函数类型没有运行时大小,通常用于类型检查,返回 0
return 0;
}
size_t FunctionType::Alignment() const {
// 不对齐
return 1;
}
bool FunctionType::IsComplete() const {
// 函数类型总是完整的(只要返回类型完整,但 SysY 中 void 也视为完整)
return true;
}
} // namespace ir

@ -76,8 +76,65 @@ void Value::ReplaceAllUsesWith(Value* new_value) {
ConstantValue::ConstantValue(std::shared_ptr<Type> ty, std::string name)
: Value(std::move(ty), std::move(name)) {}
// 建一个 Argument 对象,用给定的类型和名称初始化它,并继承 Value 的所有属性和方法。
Argument::Argument(std::shared_ptr<Type> ty, std::string name)
: Value(std::move(ty), std::move(name)) {}
ConstantInt::ConstantInt(std::shared_ptr<Type> ty, int v)
: ConstantValue(std::move(ty), ""), value_(v) {}
// ConstantFloat 实现
ConstantFloat::ConstantFloat(std::shared_ptr<Type> ty, float v)
: ConstantValue(ty, ""), value_(v) {
if (!ty->IsFloat()) {
throw std::runtime_error("ConstantFloat requires Float type");
}
}
// ConstantArray 实现
ConstantArray::ConstantArray(std::shared_ptr<ArrayType> ty,
std::vector<ConstantValue*> elements)
: ConstantValue(ty, ""), elements_(std::move(elements)) {
if (!IsValid()) {
throw std::runtime_error("Invalid constant array initialization");
}
}
bool ConstantArray::IsValid() const {
auto* array_ty = dynamic_cast<ArrayType*>(GetType().get());
if (!array_ty) return false;
// 检查元素数量是否匹配
if (elements_.size() != array_ty->GetElementCount()) return false;
// 检查每个元素的类型是否匹配数组元素类型
auto& elem_ty = array_ty->GetElementType();
for (auto* elem : elements_) {
if (elem->GetType() != elem_ty) return false;
}
return true;
}
// ConstantZero 实现
ConstantZero::ConstantZero(std::shared_ptr<Type> ty)
: ConstantValue(ty, "zero") {
// 零常量可以用于任何类型
}
std::unique_ptr<ConstantZero> ConstantZero::GetZero(std::shared_ptr<Type> ty) {
return std::make_unique<ConstantZero>(ty);
}
// ConstantAggregateZero 实现
ConstantAggregateZero::ConstantAggregateZero(std::shared_ptr<Type> ty)
: ConstantValue(ty, "zero") {
if (!ty->IsArray()) {
throw std::runtime_error("ConstantAggregateZero requires aggregate type");
}
}
std::unique_ptr<ConstantAggregateZero> ConstantAggregateZero::GetZero(std::shared_ptr<Type> ty) {
return std::make_unique<ConstantAggregateZero>(ty);
}
} // namespace ir

@ -10,4 +10,4 @@ target_link_libraries(irgen PUBLIC
build_options
${ANTLR4_RUNTIME_TARGET}
ir
)
)

@ -8,100 +8,839 @@
namespace {
std::string GetLValueName(SysYParser::LValueContext& lvalue) {
if (!lvalue.ID()) {
// 使用 LValContext 而不是 LValueContext
std::string GetLValueName(SysYParser::LValContext& lvalue) {
if (!lvalue.Ident()) {
throw std::runtime_error(FormatError("irgen", "非法左值"));
}
return lvalue.ID()->getText();
return lvalue.Ident()->getText();
}
int TryGetConstInt(SysYParser::ConstExpContext* ctx) {
// 这里是一个简化的版本,实际上应该调用语义分析的常量求值
// 暂时假设所有常量表达式都是整数常量
// 实际实现需要更复杂的逻辑
// 简化为返回10
return 10;
}
} // namespace
std::any IRGenImpl::visitBlockStmt(SysYParser::BlockStmtContext* ctx) {
// 注意visitBlock 已经在 IRGenFunc.cpp 中实现,这里不要重复定义
std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) {
std::cerr << "[DEBUG] visitDecl: 开始处理声明" << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少语句块"));
throw std::runtime_error(FormatError("irgen", "缺少变量声明"));
}
// 处理 varDecl
if (auto* varDecl = ctx->varDecl()) {
std::cerr << "[DEBUG] visitDecl: 处理变量声明" << std::endl;
// 检查类型
if (varDecl->bType() && varDecl->bType()->Int()) {
for (auto* varDef : varDecl->varDef()) {
varDef->accept(this);
}
} else {
throw std::runtime_error(FormatError("irgen", "当前仅支持 int 类型变量"));
}
}
for (auto* item : ctx->blockItem()) {
if (item) {
if (VisitBlockItemResult(*item) == BlockFlow::Terminated) {
// 当前语法要求 return 为块内最后一条语句;命中后可停止生成。
break;
// 处理 constDecl
if (ctx->constDecl()) {
std::cerr << "[DEBUG] visitDecl: 处理常量声明" << std::endl;
auto* constDecl = ctx->constDecl();
if (constDecl->bType() && constDecl->bType()->Int()) {
for (auto* constDef : constDecl->constDef()) {
constDef->accept(this);
}
} else if (constDecl->bType() && constDecl->bType()->Float()) {
throw std::runtime_error(FormatError("irgen", "float常量暂未实现"));
} else {
throw std::runtime_error(FormatError("irgen", "未知的常量类型"));
}
}
std::cerr << "[DEBUG] visitDecl: 声明处理完成" << std::endl;
return {};
}
IRGenImpl::BlockFlow IRGenImpl::VisitBlockItemResult(
SysYParser::BlockItemContext& item) {
return std::any_cast<BlockFlow>(item.accept(this));
}
std::any IRGenImpl::visitBlockItem(SysYParser::BlockItemContext* ctx) {
// 在 IRGenDecl.cpp 中确保有这个函数
std::any IRGenImpl::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
std::cerr << "[DEBUG] visitConstDecl: 开始处理常量声明" << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少块内项"));
throw std::runtime_error(FormatError("irgen", "非法常量声明"));
}
if (ctx->decl()) {
ctx->decl()->accept(this);
return BlockFlow::Continue;
}
if (ctx->stmt()) {
return ctx->stmt()->accept(this);
std::cerr << "[DEBUG] visitConstDecl: processing constant declaration" << std::endl;
// 检查类型
if (ctx->bType()) {
if (ctx->bType()->Int()) {
// int 类型常量
for (auto* constDef : ctx->constDef()) {
if (constDef) {
constDef->accept(this);
}
}
} else if (ctx->bType()->Float()) {
// float 类型常量(暂不支持)
throw std::runtime_error(FormatError("irgen", "float常量暂未实现"));
} else {
throw std::runtime_error(FormatError("irgen", "未知的常量类型"));
}
} else {
throw std::runtime_error(FormatError("irgen", "常量声明缺少类型"));
}
throw std::runtime_error(FormatError("irgen", "暂不支持的语句或声明"));
std::cerr << "[DEBUG] visitConstDecl: 常量声明处理完成" << std::endl;
return {};
}
// 变量声明的 IR 生成目前也是最小实现:
// - 先检查声明的基础类型,当前仅支持局部 int
// - 再把 Decl 中的变量定义交给 visitVarDef 继续处理。
//
// 和更完整的版本相比,这里还没有:
// - 一个 Decl 中多个变量定义的顺序处理;
// - const、数组、全局变量等不同声明形态
// - 更丰富的类型系统。
std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少变量声明"));
std::any IRGenImpl::visitConstDef(SysYParser::ConstDefContext* ctx) {
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "非法常量定义"));
}
if (!ctx->btype() || !ctx->btype()->INT()) {
throw std::runtime_error(FormatError("irgen", "当前仅支持局部 int 变量声明"));
std::string const_name = ctx->Ident()->getText();
// 检查是否为数组
bool is_array = !ctx->constExp().empty();
// 获取常量类型int 或 float
bool is_float = false;
auto* constDecl = dynamic_cast<SysYParser::ConstDeclContext*>(ctx->parent);
if (constDecl && constDecl->bType()) {
if (constDecl->bType()->Float()) {
is_float = true;
std::cerr << "[DEBUG] visitConstDef: 常量 " << const_name << " 是 float 类型" << std::endl;
}
}
auto* var_def = ctx->varDef();
if (!var_def) {
throw std::runtime_error(FormatError("irgen", "非法变量声明"));
if (is_array) {
// 数组常量处理
std::vector<int> dimensions;
for (auto* const_exp : ctx->constExp()) {
int dim_size = TryEvaluateConstInt(const_exp);
if (dim_size <= 0) dim_size = 1;
dimensions.push_back(dim_size);
}
// 创建数组类型
std::shared_ptr<ir::Type> element_type;
if (is_float) {
element_type = ir::Type::GetFloatType();
} else {
element_type = ir::Type::GetInt32Type();
}
auto array_type = ir::Type::GetArrayType(element_type, dimensions);
ir::GlobalValue* global_array = module_.CreateGlobal(const_name, array_type);
// 处理初始化值
std::vector<ir::ConstantValue*> init_consts;
if (auto* const_init_val = ctx->constInitVal()) {
auto result = const_init_val->accept(this);
if (result.has_value()) {
try {
auto init_vec = std::any_cast<std::vector<ir::Value*>>(result);
for (auto* val : init_vec) {
if (is_float) {
if (auto* const_float = dynamic_cast<ir::ConstantFloat*>(val)) {
init_consts.push_back(const_float);
} else if (auto* const_int = dynamic_cast<ir::ConstantInt*>(val)) {
// 整数转浮点
float float_val = static_cast<float>(const_int->GetValue());
init_consts.push_back(builder_.CreateConstFloat(float_val));
} else {
init_consts.push_back(builder_.CreateConstFloat(0.0f));
}
} else {
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(val)) {
init_consts.push_back(const_int);
} else if (auto* const_float = dynamic_cast<ir::ConstantFloat*>(val)) {
// 浮点转整数
int int_val = static_cast<int>(const_float->GetValue());
init_consts.push_back(builder_.CreateConstInt(int_val));
} else {
init_consts.push_back(builder_.CreateConstInt(0));
}
}
}
} catch (const std::bad_any_cast&) {
try {
ir::Value* single_val = std::any_cast<ir::Value*>(result);
if (is_float) {
if (auto* const_float = dynamic_cast<ir::ConstantFloat*>(single_val)) {
init_consts.push_back(const_float);
} else {
init_consts.push_back(builder_.CreateConstFloat(0.0f));
}
} else {
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(single_val)) {
init_consts.push_back(const_int);
} else {
init_consts.push_back(builder_.CreateConstInt(0));
}
}
} catch (...) {}
}
}
}
// 补0
int total_size = 1;
for (int dim : dimensions) total_size *= dim;
while (init_consts.size() < static_cast<size_t>(total_size)) {
if (is_float) {
init_consts.push_back(builder_.CreateConstFloat(0.0f));
} else {
init_consts.push_back(builder_.CreateConstInt(0));
}
}
global_array->SetInitializer(init_consts);
global_array->SetConstant(true);
const_storage_map_[ctx] = global_array;
const_global_map_[const_name] = global_array;
} else {
// 标量常量处理
if (!ctx->constInitVal()) {
throw std::runtime_error(FormatError("irgen", "常量缺少初始值"));
}
ir::ConstantValue* const_value = nullptr;
auto* const_init_val = ctx->constInitVal();
if (const_init_val->constExp()) {
// 对于常量表达式,我们可以尝试直接求值
if (is_float) {
// TODO: 实现浮点常量表达式的求值
const_value = module_.GetContext().GetConstFloat(0.0f);
} else {
int value = TryEvaluateConstInt(const_init_val->constExp());
const_value = module_.GetContext().GetConstInt(value);
}
} else {
if (is_float) {
const_value = module_.GetContext().GetConstFloat(0.0f);
} else {
const_value = module_.GetContext().GetConstInt(0);
}
}
// 存储常量值到映射
const_value_map_[const_name] = const_value;
}
var_def->accept(this);
return {};
}
// 当前仍是教学用的最小版本,因此这里只支持:
// - 局部 int 变量;
// - 标量初始化;
// - 一个 VarDef 对应一个槽位。
// TO DO:visitVarDef来区分全局和局部变量并且正确处理数组变量的定义和初始化
std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
std::cerr << "[DEBUG] visitVarDef: 开始处理变量定义" << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少变量定义"));
}
if (!ctx->lValue()) {
if (!ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "变量声明缺少名称"));
}
GetLValueName(*ctx->lValue());
std::string varName = ctx->Ident()->getText();
std::cerr << "[DEBUG] visitVarDef: 变量名称: " << varName << std::endl;
// 防止同一个变量被多次分配存储空间。
if (storage_map_.find(ctx) != storage_map_.end()) {
throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位"));
throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位: " + varName));
}
bool is_array = !ctx->constExp().empty();
std::cerr << "[DEBUG] visitVarDef: 是否为数组: " << (is_array ? "" : "") << std::endl;
// 使用 func_ 来判断func_ == nullptr 表示在全局作用域
if (func_ == nullptr) {
std::cerr << "[DEBUG] visitVarDef: 处理全局变量" << std::endl;
// 全局变量处理
return HandleGlobalVariable(ctx, varName, is_array);
} else {
std::cerr << "[DEBUG] visitVarDef: 处理局部变量" << std::endl;
// 局部变量处理
return HandleLocalVariable(ctx, varName, is_array);
}
}
std::any IRGenImpl::HandleGlobalVariable(SysYParser::VarDefContext* ctx,
const std::string& varName,
bool is_array) {
std::cerr << "[DEBUG] HandleGlobalVariable: 开始处理全局变量 " << varName << std::endl;
// 获取变量类型int 或 float
bool is_float = false;
auto* varDecl = dynamic_cast<SysYParser::VarDeclContext*>(ctx->parent);
if (varDecl && varDecl->bType()) {
if (varDecl->bType()->Float()) {
is_float = true;
std::cerr << "[DEBUG] HandleGlobalVariable: 变量 " << varName << " 是 float 类型" << std::endl;
} else if (varDecl->bType()->Int()) {
std::cerr << "[DEBUG] HandleGlobalVariable: 变量 " << varName << " 是 int 类型" << std::endl;
}
}
if (is_array) {
// 全局数组变量
int total_size = 1;
std::vector<int> dimensions;
// 计算总大小
for (auto* const_exp : ctx->constExp()) {
int dim_size = TryEvaluateConstInt(const_exp);
if (dim_size <= 0) {
dim_size = 1;
std::cerr << "[WARNING] HandleGlobalVariable: 无法确定数组维度大小使用1" << std::endl;
}
dimensions.push_back(dim_size);
total_size *= dim_size;
}
std::cerr << "[DEBUG] HandleGlobalVariable: 数组总大小: " << total_size << std::endl;
// 创建数组类型
std::shared_ptr<ir::Type> element_type;
if (is_float) {
element_type = ir::Type::GetFloatType();
} else {
element_type = ir::Type::GetInt32Type();
}
auto array_type = ir::Type::GetArrayType(element_type, dimensions);
ir::GlobalValue* global_array = module_.CreateGlobal(varName, array_type);
std::cerr << "[DEBUG] HandleGlobalVariable: 创建全局数组: " << varName << std::endl;
// 处理初始化值
std::vector<ir::ConstantValue*> init_consts;
if (auto* initVal = ctx->initVal()) {
std::cerr << "[DEBUG] HandleGlobalVariable: 处理初始化值" << std::endl;
auto result = initVal->accept(this);
if (result.has_value()) {
try {
auto init_vec = std::any_cast<std::vector<ir::Value*>>(result);
std::cerr << "[DEBUG] HandleGlobalVariable: 获取到初始化值列表, 大小: " << init_vec.size() << std::endl;
for (auto* val : init_vec) {
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(val)) {
init_consts.push_back(const_int);
} else if (auto* const_float = dynamic_cast<ir::ConstantFloat*>(val)) {
init_consts.push_back(const_float);
} else {
// 非常量表达式使用0
if (is_float) {
init_consts.push_back(builder_.CreateConstFloat(0.0f));
} else {
init_consts.push_back(builder_.CreateConstInt(0));
}
}
}
} catch (const std::bad_any_cast&) {
try {
ir::Value* single_val = std::any_cast<ir::Value*>(result);
std::cerr << "[DEBUG] HandleGlobalVariable: 获取到单个初始化值" << std::endl;
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(single_val)) {
init_consts.push_back(const_int);
} else if (auto* const_float = dynamic_cast<ir::ConstantFloat*>(single_val)) {
init_consts.push_back(const_float);
} else {
if (is_float) {
init_consts.push_back(builder_.CreateConstFloat(0.0f));
} else {
init_consts.push_back(builder_.CreateConstInt(0));
}
}
} catch (const std::bad_any_cast&) {
std::cerr << "[WARNING] HandleGlobalVariable: 无法解析数组初始化值" << std::endl;
}
}
}
}
// 如果初始化值不足补0
while (init_consts.size() < static_cast<size_t>(total_size)) {
if (is_float) {
init_consts.push_back(builder_.CreateConstFloat(0.0f));
} else {
init_consts.push_back(builder_.CreateConstInt(0));
}
}
// 设置全局数组的初始化器
if (!init_consts.empty()) {
global_array->SetInitializer(init_consts);
std::cerr << "[DEBUG] HandleGlobalVariable: 设置全局数组初始化器" << std::endl;
}
// 存储全局变量引用
storage_map_[ctx] = global_array;
global_map_[varName] = global_array;
} else {
// 全局标量变量
std::shared_ptr<ir::Type> var_type;
if (is_float) {
var_type = ir::Type::GetFloatType();
} else {
var_type = ir::Type::GetInt32Type();
}
ir::GlobalValue* global_var = module_.CreateGlobal(varName, var_type);
std::cerr << "[DEBUG] HandleGlobalVariable: 创建全局标量变量: " << varName << std::endl;
// 处理初始化值
ir::ConstantValue* init_value = nullptr;
if (auto* initVal = ctx->initVal()) {
std::cerr << "[DEBUG] HandleGlobalVariable: 处理标量初始化值" << std::endl;
auto result = initVal->accept(this);
if (result.has_value()) {
try {
ir::Value* val = std::any_cast<ir::Value*>(result);
if (is_float) {
if (auto* const_float = dynamic_cast<ir::ConstantFloat*>(val)) {
init_value = const_float;
} else if (auto* const_int = dynamic_cast<ir::ConstantInt*>(val)) {
// 整数转浮点
float float_val = static_cast<float>(const_int->GetValue());
init_value = builder_.CreateConstFloat(float_val);
} else {
init_value = builder_.CreateConstFloat(0.0f);
}
} else {
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(val)) {
init_value = const_int;
} else if (auto* const_float = dynamic_cast<ir::ConstantFloat*>(val)) {
// 浮点转整数
int int_val = static_cast<int>(const_float->GetValue());
init_value = builder_.CreateConstInt(int_val);
} else {
init_value = builder_.CreateConstInt(0);
}
}
} catch (const std::bad_any_cast&) {
if (is_float) {
init_value = builder_.CreateConstFloat(0.0f);
} else {
init_value = builder_.CreateConstInt(0);
}
}
}
}
// 如果没有初始化值,默认初始化
if (!init_value) {
if (is_float) {
init_value = builder_.CreateConstFloat(0.0f);
} else {
init_value = builder_.CreateConstInt(0);
}
}
// 设置全局变量的初始化器
global_var->SetInitializer(init_value);
// 存储全局变量引用
storage_map_[ctx] = global_var;
global_map_[varName] = global_var;
}
return {};
}
// 修改 HandleLocalVariable 函数中的数组处理部分
std::any IRGenImpl::HandleLocalVariable(SysYParser::VarDefContext* ctx,
const std::string& varName,
bool is_array) {
std::cerr << "[DEBUG] HandleLocalVariable: 开始处理局部变量 " << varName << std::endl;
// 获取变量类型
bool is_float = false;
auto* varDecl = dynamic_cast<SysYParser::VarDeclContext*>(ctx->parent);
if (varDecl && varDecl->bType()) {
if (varDecl->bType()->Float()) {
is_float = true;
std::cerr << "[DEBUG] HandleLocalVariable: 变量 " << varName << " 是 float 类型" << std::endl;
}
}
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp());
storage_map_[ctx] = slot;
ir::Value* init = nullptr;
if (auto* init_value = ctx->initValue()) {
if (!init_value->exp()) {
throw std::runtime_error(FormatError("irgen", "当前不支持聚合初始化"));
if (is_array) {
// 局部数组变量
int total_size = 1;
std::vector<int> dimensions;
// 获取数组维度
for (auto* const_exp : ctx->constExp()) {
try {
int dim_size = TryEvaluateConstInt(const_exp);
if (dim_size <= 0) dim_size = 1;
dimensions.push_back(dim_size);
total_size *= dim_size;
} catch (const std::exception& e) {
std::cerr << "[WARNING] HandleLocalVariable: 无法获取数组维度使用维度1" << std::endl;
dimensions.push_back(1);
total_size *= 1;
}
}
// 创建数组类型
std::shared_ptr<ir::Type> elem_type;
if (is_float) {
elem_type = ir::Type::GetFloatType();
} else {
elem_type = ir::Type::GetInt32Type();
}
// 修正:使用完整的维度列表创建数组类型
auto array_type = ir::Type::GetArrayType(elem_type, dimensions);
// 分配数组内存 - 为每个元素创建独立的 alloca
std::vector<ir::Value*> element_slots;
for (int i = 0; i < total_size; i++) {
ir::AllocaInst* slot;
if (is_float) {
slot = builder_.CreateAllocaFloat(
module_.GetContext().NextTemp() + "_" + varName + "_" + std::to_string(i));
} else {
slot = builder_.CreateAllocaI32(
module_.GetContext().NextTemp() + "_" + varName + "_" + std::to_string(i));
}
element_slots.push_back(slot);
}
// 存储第一个元素的地址作为数组的基地址
storage_map_[ctx] = element_slots[0];
local_var_map_[varName] = element_slots[0];
// 处理初始化
if (auto* initVal = ctx->initVal()) {
auto result = initVal->accept(this);
if (result.has_value()) {
try {
std::vector<ir::Value*> init_values =
std::any_cast<std::vector<ir::Value*>>(result);
// 初始化数组元素
for (size_t i = 0; i < init_values.size() && i < static_cast<size_t>(total_size); i++) {
builder_.CreateStore(init_values[i], element_slots[i]);
}
// 剩余元素初始化为0
for (size_t i = init_values.size(); i < static_cast<size_t>(total_size); i++) {
if (is_float) {
builder_.CreateStore(builder_.CreateConstFloat(0.0f), element_slots[i]);
} else {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
} catch (const std::bad_any_cast&) {
try {
ir::Value* single_value = std::any_cast<ir::Value*>(result);
// 只初始化第一个元素
builder_.CreateStore(single_value, element_slots[0]);
// 其他元素初始化为0
for (int i = 1; i < total_size; i++) {
if (is_float) {
builder_.CreateStore(builder_.CreateConstFloat(0.0f), element_slots[i]);
} else {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
} catch (const std::bad_any_cast&) {
// 全部初始化为0
for (int i = 0; i < total_size; i++) {
if (is_float) {
builder_.CreateStore(builder_.CreateConstFloat(0.0f), element_slots[i]);
} else {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
}
}
} else {
// 没有初始化值全部初始化为0
for (int i = 0; i < total_size; i++) {
if (is_float) {
builder_.CreateStore(builder_.CreateConstFloat(0.0f), element_slots[i]);
} else {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
}
} else {
// 无初始化所有元素初始化为0
for (int i = 0; i < total_size; i++) {
if (is_float) {
builder_.CreateStore(builder_.CreateConstFloat(0.0f), element_slots[i]);
} else {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
}
init = EvalExpr(*init_value->exp());
} else {
init = builder_.CreateConstInt(0);
// 局部标量变量
ir::AllocaInst* slot;
if (is_float) {
slot = builder_.CreateAllocaFloat(module_.GetContext().NextTemp() + "_" + varName);
} else {
slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + varName);
}
storage_map_[ctx] = slot;
local_var_map_[varName] = slot;
// 处理初始化
ir::Value* init = nullptr;
if (auto* initVal = ctx->initVal()) {
auto result = initVal->accept(this);
if (result.has_value()) {
try {
init = std::any_cast<ir::Value*>(result);
} catch (const std::bad_any_cast&) {
try {
std::vector<ir::Value*> init_values =
std::any_cast<std::vector<ir::Value*>>(result);
if (!init_values.empty()) {
init = init_values[0];
} else {
if (is_float) {
init = builder_.CreateConstFloat(0.0f);
} else {
init = builder_.CreateConstInt(0);
}
}
} catch (const std::bad_any_cast&) {
if (is_float) {
init = builder_.CreateConstFloat(0.0f);
} else {
init = builder_.CreateConstInt(0);
}
}
}
} else {
if (is_float) {
init = builder_.CreateConstFloat(0.0f);
} else {
init = builder_.CreateConstInt(0);
}
}
} else {
if (is_float) {
init = builder_.CreateConstFloat(0.0f);
} else {
init = builder_.CreateConstInt(0);
}
}
builder_.CreateStore(init, slot);
}
builder_.CreateStore(init, slot);
return {};
}
std::any IRGenImpl::visitInitVal(SysYParser::InitValContext* ctx) {
std::cerr << "[DEBUG] visitInitVal: 开始处理初始化值" << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法初始化值"));
}
// 如果是单个表达式
if (ctx->exp()) {
std::cerr << "[DEBUG] visitInitVal: 处理表达式初始化" << std::endl;
return EvalExpr(*ctx->exp());
}
// 如果是聚合初始化(花括号列表)
else if (!ctx->initVal().empty()) {
std::cerr << "[DEBUG] visitInitVal: 处理聚合初始化" << std::endl;
// 处理嵌套聚合初始化
return ProcessNestedInitVals(ctx);
}
std::cerr << "[DEBUG] visitInitVal: 空初始化列表" << std::endl;
// 空初始化列表
return std::vector<ir::Value*>{};
}
// 新增:处理嵌套聚合初始化的辅助函数
std::vector<ir::Value*> IRGenImpl::ProcessNestedInitVals(SysYParser::InitValContext* ctx) {
std::cerr << "[DEBUG] ProcessNestedInitVals: 开始处理嵌套初始化值" << std::endl;
std::vector<ir::Value*> all_values;
for (auto* init_val : ctx->initVal()) {
auto result = init_val->accept(this);
if (result.has_value()) {
try {
// 尝试获取单个值
ir::Value* value = std::any_cast<ir::Value*>(result);
all_values.push_back(value);
std::cerr << "[DEBUG] ProcessNestedInitVals: 获取到单个值" << std::endl;
} catch (const std::bad_any_cast&) {
try {
// 尝试获取值列表(嵌套情况)
std::vector<ir::Value*> nested_values =
std::any_cast<std::vector<ir::Value*>>(result);
std::cerr << "[DEBUG] ProcessNestedInitVals: 获取到嵌套值列表, 大小: " << nested_values.size() << std::endl;
// 展平嵌套的值
all_values.insert(all_values.end(),
nested_values.begin(), nested_values.end());
} catch (const std::bad_any_cast&) {
// 未知类型
std::cerr << "[ERROR] ProcessNestedInitVals: 不支持的初始化值类型" << std::endl;
throw std::runtime_error(
FormatError("irgen", "不支持的初始化值类型"));
}
}
} else {
std::cerr << "[DEBUG] ProcessNestedInitVals: 无初始化值结果" << std::endl;
}
}
std::cerr << "[DEBUG] ProcessNestedInitVals: 共获取 " << all_values.size() << " 个初始化值" << std::endl;
return all_values;
}
int IRGenImpl::TryEvaluateConstInt(SysYParser::ConstExpContext* ctx) {
std::cerr << "[DEBUG] TryEvaluateConstInt: 开始求值常量表达式" << std::endl;
if (!ctx) {
std::cerr << "[DEBUG] TryEvaluateConstInt: ctx is null" << std::endl;
return 0;
}
// 直接访问常量表达式树,计算数值
// 这里需要实现真正的常量求值逻辑
// 简化版本:假设常量表达式是整数常量
if (ctx->addExp()) {
// 尝试从 addExp 求值
return EvaluateConstAddExp(ctx->addExp());
}
return 0;
}
// 添加辅助函数来求值常量表达式
int IRGenImpl::EvaluateConstAddExp(SysYParser::AddExpContext* ctx) {
if (!ctx) return 0;
// 如果没有左操作数,直接求值右操作数
if (!ctx->addExp()) {
return EvaluateConstMulExp(ctx->mulExp());
}
int left = EvaluateConstAddExp(ctx->addExp());
int right = EvaluateConstMulExp(ctx->mulExp());
if (ctx->AddOp()) {
return left + right;
} else if (ctx->SubOp()) {
return left - right;
}
return 0;
}
int IRGenImpl::EvaluateConstMulExp(SysYParser::MulExpContext* ctx) {
if (!ctx) return 0;
// 如果没有左操作数,直接求值右操作数
if (!ctx->mulExp()) {
return EvaluateConstUnaryExp(ctx->unaryExp());
}
int left = EvaluateConstMulExp(ctx->mulExp());
int right = EvaluateConstUnaryExp(ctx->unaryExp());
if (ctx->MulOp()) {
return left * right;
} else if (ctx->DivOp()) {
return left / right;
} else if (ctx->QuoOp()) {
return left % right;
}
return 0;
}
int IRGenImpl::EvaluateConstUnaryExp(SysYParser::UnaryExpContext* ctx) {
if (!ctx) return 0;
// 基本表达式(数字字面量)
if (ctx->primaryExp()) {
return EvaluateConstPrimaryExp(ctx->primaryExp());
}
// 一元运算
if (ctx->unaryOp() && ctx->unaryExp()) {
int operand = EvaluateConstUnaryExp(ctx->unaryExp());
std::string op = ctx->unaryOp()->getText();
if (op == "+") {
return operand;
} else if (op == "-") {
return -operand;
} else if (op == "!") {
return !operand;
}
}
return 0;
}
int IRGenImpl::EvaluateConstPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
if (!ctx) return 0;
// 处理数字字面量
if (ctx->DECIMAL_INT()) {
return std::stoi(ctx->DECIMAL_INT()->getText());
}
if (ctx->HEX_INT()) {
std::string hex = ctx->HEX_INT()->getText();
return std::stoi(hex, nullptr, 16);
}
if (ctx->OCTAL_INT()) {
std::string oct = ctx->OCTAL_INT()->getText();
return std::stoi(oct, nullptr, 8);
}
if (ctx->ZERO()) {
return 0;
}
// 处理括号表达式
if (ctx->L_PAREN() && ctx->exp()) {
return EvaluateConstExp(ctx->exp());
}
// 常量标识符(引用其他常量)
if (ctx->lVal()) {
std::string const_name = ctx->lVal()->Ident()->getText();
auto it = const_value_map_.find(const_name);
if (it != const_value_map_.end()) {
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(it->second)) {
return const_int->GetValue();
}
}
// 也可以从语义分析获取常量值
// ...
}
return 0;
}
int IRGenImpl::EvaluateConstExp(SysYParser::ExpContext* ctx) {
if (!ctx || !ctx->addExp()) return 0;
return EvaluateConstAddExp(ctx->addExp());
}

@ -20,61 +20,896 @@
// - 数组、指针、下标访问
// - 条件与比较表达式
// - ...
ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) {
return std::any_cast<ir::Value*>(expr.accept(this));
std::cout << "[DEBUG IRGEN] EvalExpr: " << expr.getText() << std::endl;
try {
auto result_any = expr.accept(this);
if (!result_any.has_value()) {
std::cerr << "[ERROR] EvalExpr: result_any has no value" << std::endl;
throw std::runtime_error("表达式求值结果为空");
}
try {
ir::Value* result = std::any_cast<ir::Value*>(result_any);
std::cerr << "[DEBUG] EvalExpr: success, result = " << (void*)result << std::endl;
return result;
} catch (const std::bad_any_cast& e) {
std::cerr << "[ERROR] EvalExpr: bad any_cast - " << e.what() << std::endl;
std::cerr << " Type info: " << result_any.type().name() << std::endl;
// 尝试其他可能的类型
try {
// 检查是否是无值的any可能来自visit函数返回{}
std::cerr << "[DEBUG] EvalExpr: Trying to handle empty any" << std::endl;
return nullptr;
} catch (...) {
throw std::runtime_error(FormatError("irgen", "表达式求值返回了错误的类型"));
}
}
} catch (const std::exception& e) {
std::cerr << "[ERROR] Exception in EvalExpr: " << e.what() << std::endl;
throw;
}
}
std::any IRGenImpl::visitParenExp(SysYParser::ParenExpContext* ctx) {
if (!ctx || !ctx->exp()) {
throw std::runtime_error(FormatError("irgen", "非法括号表达式"));
}
return EvalExpr(*ctx->exp());
ir::Value* IRGenImpl::EvalCond(SysYParser::CondContext& cond) {
return std::any_cast<ir::Value*>(cond.accept(this));
}
std::any IRGenImpl::visitNumberExp(SysYParser::NumberExpContext* ctx) {
if (!ctx || !ctx->number() || !ctx->number()->ILITERAL()) {
throw std::runtime_error(FormatError("irgen", "当前仅支持整数字面量"));
// 基本表达式:数字、变量、括号表达式
std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
std::cout << "[DEBUG IRGEN] visitPrimaryExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少基本表达式"));
}
return static_cast<ir::Value*>(
builder_.CreateConstInt(std::stoi(ctx->number()->getText())));
std::cerr << "[DEBUG] visitPrimaryExp" << std::endl;
// 处理数字字面量
if (ctx->DECIMAL_INT()) {
int value = std::stoi(ctx->DECIMAL_INT()->getText());
ir::Value* const_int = builder_.CreateConstInt(value);
std::cerr << "[DEBUG] visitPrimaryExp: constant int " << value
<< " created as " << (void*)const_int << std::endl;
return static_cast<ir::Value*>(const_int);
}
if (ctx->HEX_FLOAT()) {
std::string hex_float_str = ctx->HEX_FLOAT()->getText();
float value = 0.0f;
// 解析十六进制浮点数
try {
// C++11 的 std::stof 支持十六进制浮点数表示
value = std::stof(hex_float_str);
} catch (const std::exception& e) {
std::cerr << "[WARNING] 无法解析十六进制浮点数: " << hex_float_str
<< "使用0.0代替" << std::endl;
value = 0.0f;
}
ir::Value* const_float = builder_.CreateConstFloat(value);
std::cerr << "[DEBUG] visitPrimaryExp: constant hex float " << value
<< " created as " << (void*)const_float << std::endl;
return static_cast<ir::Value*>(const_float);
}
// 处理十进制浮点常量
if (ctx->DEC_FLOAT()) {
std::string dec_float_str = ctx->DEC_FLOAT()->getText();
float value = 0.0f;
try {
value = std::stof(dec_float_str);
} catch (const std::exception& e) {
std::cerr << "[WARNING] 无法解析十进制浮点数: " << dec_float_str
<< "使用0.0代替" << std::endl;
value = 0.0f;
}
ir::Value* const_float = builder_.CreateConstFloat(value);
std::cerr << "[DEBUG] visitPrimaryExp: constant dec float " << value
<< " created as " << (void*)const_float << std::endl;
return static_cast<ir::Value*>(const_float);
}
if (ctx->HEX_INT()) {
std::string hex = ctx->HEX_INT()->getText();
int value = std::stoi(hex, nullptr, 16);
ir::Value* const_int = builder_.CreateConstInt(value);
return static_cast<ir::Value*>(const_int);
}
if (ctx->OCTAL_INT()) {
std::string oct = ctx->OCTAL_INT()->getText();
int value = std::stoi(oct, nullptr, 8);
ir::Value* const_int = builder_.CreateConstInt(value);
return static_cast<ir::Value*>(const_int);
}
if (ctx->ZERO()) {
ir::Value* const_int = builder_.CreateConstInt(0);
return static_cast<ir::Value*>(const_int);
}
// 处理变量
if (ctx->lVal()) {
std::cerr << "[DEBUG] visitPrimaryExp: visiting lVal" << std::endl;
return ctx->lVal()->accept(this);
}
// 处理括号表达式
if (ctx->L_PAREN() && ctx->exp()) {
std::cerr << "[DEBUG] visitPrimaryExp: visiting parenthesized expression" << std::endl;
return EvalExpr(*ctx->exp());
}
std::cerr << "[ERROR] visitPrimaryExp: unsupported primary expression type" << std::endl;
throw std::runtime_error(FormatError("irgen", "不支持的基本表达式类型"));
}
// 变量使用的处理流程:
// 左值(变量)处理
// 1. 先通过语义分析结果把变量使用绑定回声明;
// 2. 再通过 storage_map_ 找到该声明对应的栈槽位;
// 3. 最后生成 load把内存中的值读出来。
//
// 因此当前 IRGen 自己不再做名字查找,而是直接消费 Sema 的绑定结果。
std::any IRGenImpl::visitVarExp(SysYParser::VarExpContext* ctx) {
if (!ctx || !ctx->var() || !ctx->var()->ID()) {
throw std::runtime_error(FormatError("irgen", "当前仅支持普通整型变量"));
std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "非法左值"));
}
auto* decl = sema_.ResolveVarUse(ctx->var());
if (!decl) {
throw std::runtime_error(
FormatError("irgen",
"变量使用缺少语义绑定: " + ctx->var()->ID()->getText()));
std::string varName = ctx->Ident()->getText();
std::cerr << "[DEBUG] visitLVal: " << varName << std::endl;
// 优先检查是否是常量
auto const_it = const_value_map_.find(varName);
if (const_it != const_value_map_.end()) {
// 常量直接返回值不需要load
std::cerr << "[DEBUG] visitLVal: constant " << varName << std::endl;
return static_cast<ir::Value*>(const_it->second);
}
// 检查全局常量
auto const_global_it = const_global_map_.find(varName);
if (const_global_it != const_global_map_.end()) {
// 全局常量需要load
ir::Value* ptr = const_global_it->second;
if (!ctx->exp().empty()) {
// 数组访问
std::vector<ir::Value*> indices;
indices.push_back(builder_.CreateConstInt(0));
for (auto* exp : ctx->exp()) {
ir::Value* index = EvalExpr(*exp);
indices.push_back(index);
}
ir::Value* elem_ptr = builder_.CreateGEP(
ptr, indices, module_.GetContext().NextTemp());
return static_cast<ir::Value*>(
builder_.CreateLoad(elem_ptr, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateLoad(ptr, module_.GetContext().NextTemp()));
}
}
// 不是常量,按正常变量处理
// ... 原有的变量查找代码 ...
auto* decl = sema_.ResolveVarUse(ctx);
ir::Value* ptr = nullptr;
if (decl) {
auto it = storage_map_.find(decl);
if (it != storage_map_.end()) {
ptr = it->second;
}
}
if (!ptr) {
auto it2 = param_map_.find(varName);
if (it2 != param_map_.end()) {
ptr = it2->second;
}
}
if (!ptr) {
auto it3 = global_map_.find(varName);
if (it3 != global_map_.end()) {
ptr = it3->second;
}
}
auto it = storage_map_.find(decl);
if (it == storage_map_.end()) {
if (!ptr) {
auto it4 = local_var_map_.find(varName);
if (it4 != local_var_map_.end()) {
ptr = it4->second;
}
}
if (!ptr) {
throw std::runtime_error(
FormatError("irgen",
"变量声明缺少存储槽位: " + ctx->var()->ID()->getText()));
FormatError("irgen", "变量声明缺少存储槽位: " + varName));
}
return static_cast<ir::Value*>(
builder_.CreateLoad(it->second, module_.GetContext().NextTemp()));
}
// 检查是否有数组下标
bool is_array_access = !ctx->exp().empty();
if (is_array_access) {
std::vector<ir::Value*> indices;
indices.push_back(builder_.CreateConstInt(0));
for (auto* exp : ctx->exp()) {
ir::Value* index = EvalExpr(*exp);
indices.push_back(index);
}
ir::Value* elem_ptr = builder_.CreateGEP(
ptr, indices, module_.GetContext().NextTemp());
return static_cast<ir::Value*>(
builder_.CreateLoad(elem_ptr, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateLoad(ptr, module_.GetContext().NextTemp()));
}
}
std::any IRGenImpl::visitAdditiveExp(SysYParser::AdditiveExpContext* ctx) {
if (!ctx || !ctx->exp(0) || !ctx->exp(1)) {
std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
std::cout << "[DEBUG IRGEN] visitAddExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
}
ir::Value* lhs = EvalExpr(*ctx->exp(0));
ir::Value* rhs = EvalExpr(*ctx->exp(1));
return static_cast<ir::Value*>(
builder_.CreateBinary(ir::Opcode::Add, lhs, rhs,
module_.GetContext().NextTemp()));
// 如果没有 addExp(),说明是单个 mulExp()
if (!ctx->addExp()) {
return ctx->mulExp()->accept(this);
}
// 正确提取左操作数
auto left_any = ctx->addExp()->accept(this);
if (!left_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "左操作数求值失败"));
}
ir::Value* left = std::any_cast<ir::Value*>(left_any);
// 正确提取右操作数
auto right_any = ctx->mulExp()->accept(this);
if (!right_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "右操作数求值失败"));
}
ir::Value* right = std::any_cast<ir::Value*>(right_any);
std::cerr << "[DEBUG] visitAddExp: left=" << (void*)left
<< ", type=" << (left->GetType()->IsFloat() ? "float" : "int")
<< ", right=" << (void*)right
<< ", type=" << (right->GetType()->IsFloat() ? "float" : "int") << std::endl;
// 处理类型转换:如果操作数类型不同,需要进行类型转换
if (left->GetType()->IsFloat() != right->GetType()->IsFloat()) {
if (left->GetType()->IsFloat()) {
// left是floatright是int需要将right转换为float
right = builder_.CreateSIToFP(right, ir::Type::GetFloatType());
} else {
// right是floatleft是int需要将left转换为float
left = builder_.CreateSIToFP(left, ir::Type::GetFloatType());
}
}
// 根据操作符生成相应的指令
if (ctx->AddOp()) {
if (left->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFAdd(left, right, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateAdd(left, right, module_.GetContext().NextTemp()));
}
} else if (ctx->SubOp()) {
if (left->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFSub(left, right, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateSub(left, right, module_.GetContext().NextTemp()));
}
}
throw std::runtime_error(FormatError("irgen", "未知的加法操作符"));
}
std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
std::cout << "[DEBUG IRGEN] visitMulExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
}
// 如果是基本形式 UnaryExp
if (!ctx->mulExp()) {
return ctx->unaryExp()->accept(this);
}
// 提取左操作数
auto left_any = ctx->mulExp()->accept(this);
if (!left_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "左操作数求值失败"));
}
ir::Value* left = std::any_cast<ir::Value*>(left_any);
// 提取右操作数
auto right_any = ctx->unaryExp()->accept(this);
if (!right_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "右操作数求值失败"));
}
ir::Value* right = std::any_cast<ir::Value*>(right_any);
std::cerr << "[DEBUG] visitMulExp: left=" << (void*)left
<< ", type=" << (left->GetType()->IsFloat() ? "float" : "int")
<< ", right=" << (void*)right
<< ", type=" << (right->GetType()->IsFloat() ? "float" : "int") << std::endl;
// 处理类型转换:如果操作数类型不同,需要进行类型转换
if (left->GetType()->IsFloat() != right->GetType()->IsFloat()) {
if (left->GetType()->IsFloat()) {
// left是floatright是int需要将right转换为float
right = builder_.CreateSIToFP(right, ir::Type::GetFloatType());
} else {
// right是floatleft是int需要将left转换为float
left = builder_.CreateSIToFP(left, ir::Type::GetFloatType());
}
}
// 根据操作符生成指令
if (ctx->MulOp()) {
if (left->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFMul(left, right, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateMul(left, right, module_.GetContext().NextTemp()));
}
} else if (ctx->DivOp()) {
if (left->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFDiv(left, right, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateDiv(left, right, module_.GetContext().NextTemp()));
}
} else if (ctx->QuoOp()) {
// 取模运算:浮点数不支持取模,只支持整数
if (left->GetType()->IsFloat() || right->GetType()->IsFloat()) {
throw std::runtime_error(
FormatError("irgen", "浮点数不支持取模运算"));
}
return static_cast<ir::Value*>(
builder_.CreateMod(left, right, module_.GetContext().NextTemp()));
}
throw std::runtime_error(FormatError("irgen", "未知的乘法操作符"));
}
// 逻辑与
std::any IRGenImpl::visitLAndExp(SysYParser::LAndExpContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法逻辑与表达式"));
if (!ctx->lAndExp()) {
return ctx->eqExp()->accept(this);
}
ir::Value* left = std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this));
ir::Value* right = std::any_cast<ir::Value*>(ctx->eqExp()->accept(this));
auto zero = builder_.CreateConstInt(0);
auto left_bool = builder_.CreateICmpNE(left, zero, module_.GetContext().NextTemp());
auto right_bool = builder_.CreateICmpNE(right, zero, module_.GetContext().NextTemp());
return builder_.CreateAnd(left_bool, right_bool, module_.GetContext().NextTemp());
}
// 逻辑或
std::any IRGenImpl::visitLOrExp(SysYParser::LOrExpContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法逻辑或表达式"));
if (!ctx->lOrExp()) {
return ctx->lAndExp()->accept(this);
}
ir::Value* left = std::any_cast<ir::Value*>(ctx->lOrExp()->accept(this));
ir::Value* right = std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this));
auto zero = builder_.CreateConstInt(0);
auto left_bool = builder_.CreateICmpNE(left, zero, module_.GetContext().NextTemp());
auto right_bool = builder_.CreateICmpNE(right, zero, module_.GetContext().NextTemp());
return builder_.CreateOr(left_bool, right_bool, module_.GetContext().NextTemp());
}
std::any IRGenImpl::visitExp(SysYParser::ExpContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法表达式"));
return ctx->addExp()->accept(this);
}
std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法条件表达式"));
return ctx->lOrExp()->accept(this);
}
std::any IRGenImpl::visitCallExp(SysYParser::UnaryExpContext* ctx) {
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "非法函数调用"));
}
std::string funcName = ctx->Ident()->getText();
std::cout << "[DEBUG IRGEN] visitCallExp: 调用函数 " << funcName << std::endl;
// 查找函数对象
ir::Function* callee = module_.FindFunction(funcName);
// 如果没找到,可能是运行时函数还没声明,尝试动态声明
if (!callee) {
std::cout << "[DEBUG IRGEN] 函数 " << funcName << " 未找到,尝试动态声明" << std::endl;
// 根据函数名动态创建运行时函数声明
callee = CreateRuntimeFunctionDecl(funcName);
if (!callee) {
throw std::runtime_error(FormatError("irgen", "未找到函数: " + funcName));
}
}
// 收集实参
std::vector<ir::Value*> args;
if (ctx->funcRParams()) {
auto argList = ctx->funcRParams()->accept(this);
try {
args = std::any_cast<std::vector<ir::Value*>>(argList);
std::cout << "[DEBUG IRGEN] visitCallExp: 收集到 " << args.size() << " 个参数" << std::endl;
} catch (const std::bad_any_cast& e) {
std::cerr << "[ERROR] visitCallExp: 函数调用参数类型错误: " << e.what() << std::endl;
}
}
// 生成调用指令
ir::Value* callResult = builder_.CreateCall(callee, args, module_.GetContext().NextTemp());
// 如果函数返回 void返回一个默认值用于表达式上下文
if (callResult->GetType()->IsVoid()) {
// void 函数调用不产生值,但我们返回一个 0 常量以保持类型一致性
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
}
std::cout << "[DEBUG IRGEN] visitCallExp: 函数调用完成,返回值 " << (void*)callResult << std::endl;
return static_cast<ir::Value*>(callResult);
}
// 动态创建运行时函数声明的辅助函数
ir::Function* IRGenImpl::CreateRuntimeFunctionDecl(const std::string& funcName) {
std::cout << "[DEBUG IRGEN] CreateRuntimeFunctionDecl: " << funcName << std::endl;
// 根据常见运行时函数名创建对应的函数类型
if (funcName == "getint" || funcName == "getch") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(ir::Type::GetInt32Type(), {}));
}
else if (funcName == "putint" || funcName == "putch") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type()}));
}
else if (funcName == "getarray") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetInt32Type(),
{ir::Type::GetPtrInt32Type(), ir::Type::GetInt32Type()}));
}
else if (funcName == "putarray") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type(), ir::Type::GetPtrInt32Type()}));
}
else if (funcName == "puts") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetPtrInt32Type()}));
}
else if (funcName == "starttime" || funcName == "stoptime") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(ir::Type::GetVoidType(), {}));
}
else if (funcName == "_sysy_starttime" || funcName == "_sysy_stoptime") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type()}));
}
else if (funcName == "read_map") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(ir::Type::GetInt32Type(), {}));
}
else if (funcName == "float_eq") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetInt32Type(),
{ir::Type::GetFloatType(), ir::Type::GetFloatType()}));
}
else if (funcName == "memset") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetPtrInt32Type(),
{ir::Type::GetPtrInt32Type(),
ir::Type::GetInt32Type(),
ir::Type::GetInt32Type()}));
}
// 其他函数不支持动态创建
return nullptr;
}
std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法一元表达式"));
}
// 基本表达式
if (ctx->primaryExp()) {
return ctx->primaryExp()->accept(this);
}
// 函数调用
if (ctx->Ident()) {
return visitCallExp(ctx);
}
// 一元运算
if (ctx->unaryOp() && ctx->unaryExp()) {
auto* operand = std::any_cast<ir::Value*>(ctx->unaryExp()->accept(this));
std::string op = ctx->unaryOp()->getText();
if (op == "+") {
// +x 等价于 x
return operand;
} else if (op == "-") {
// -x 根据操作数类型选择整数或浮点减法
if (operand->GetType()->IsFloat()) {
// 浮点取负0.0 - x
ir::Value* zero_float = builder_.CreateConstFloat(0.0f);
return static_cast<ir::Value*>(
builder_.CreateFSub(zero_float, operand, module_.GetContext().NextTemp()));
} else {
// 整数取负0 - x
ir::Value* zero = builder_.CreateConstInt(0);
return static_cast<ir::Value*>(
builder_.CreateSub(zero, operand, module_.GetContext().NextTemp()));
}
} else if (op == "!") {
// 逻辑非运算
// 先将值转换为bool与0比较
ir::Value* zero;
if (operand->GetType()->IsFloat()) {
zero = builder_.CreateConstFloat(0.0f);
// 浮点比较不等于0
ir::Value* cmp = builder_.CreateFCmpONE(operand, zero, module_.GetContext().NextTemp());
// 将bool转换为int
return static_cast<ir::Value*>(
builder_.CreateZExt(cmp, ir::Type::GetInt32Type()));
} else {
zero = builder_.CreateConstInt(0);
return builder_.CreateNot(operand, module_.GetContext().NextTemp());
}
}
}
throw std::runtime_error(FormatError("irgen", "暂不支持的一元表达式形式"));
}
// 实现函数调用
std::any IRGenImpl::visitFuncRParams(SysYParser::FuncRParamsContext* ctx) {
if (!ctx) return std::vector<ir::Value*>{};
std::vector<ir::Value*> args;
for (auto* exp : ctx->exp()) {
args.push_back(EvalExpr(*exp));
}
return args;
}
// 修改 visitConstExp 以支持常量表达式求值
std::any IRGenImpl::visitConstExp(SysYParser::ConstExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法常量表达式"));
}
try {
if (ctx->addExp()) {
// 尝试获取数值
auto result = ctx->addExp()->accept(this);
if (result.has_value()) {
try {
ir::Value* value = std::any_cast<ir::Value*>(result);
// 尝试判断是否是 ConstantInt
// 暂时简化:返回 IR 值
return static_cast<ir::Value*>(value);
} catch (const std::bad_any_cast&) {
// 可能是其他类型
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
}
}
}
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
} catch (const std::exception& e) {
std::cerr << "[WARNING] visitConstExp: 常量表达式求值失败: " << e.what()
<< "返回0" << std::endl;
// 如果普通表达式求值失败返回0
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
}
}
std::any IRGenImpl::visitConstInitVal(SysYParser::ConstInitValContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法常量初始化值"));
}
// 如果是单个常量表达式
if (ctx->constExp()) {
try {
auto result = ctx->constExp()->accept(this);
if (result.has_value()) {
try {
ir::Value* value = std::any_cast<ir::Value*>(result);
// 尝试提取常量值
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(value)) {
return static_cast<ir::Value*>(const_int);
} else {
// 如果不是常量,尝试计算数值
int int_val = TryEvaluateConstInt(ctx->constExp());
return static_cast<ir::Value*>(builder_.CreateConstInt(int_val));
}
} catch (const std::bad_any_cast&) {
int int_val = TryEvaluateConstInt(ctx->constExp());
return static_cast<ir::Value*>(builder_.CreateConstInt(int_val));
}
}
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
} catch (const std::exception& e) {
std::cerr << "[WARNING] visitConstInitVal: " << e.what() << std::endl;
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
}
}
// 如果是聚合初始化(花括号列表)
else if (!ctx->constInitVal().empty()) {
std::vector<ir::Value*> all_values;
for (auto* init_val : ctx->constInitVal()) {
auto result = init_val->accept(this);
if (result.has_value()) {
try {
// 尝试获取单个常量值
ir::Value* value = std::any_cast<ir::Value*>(result);
all_values.push_back(value);
} catch (const std::bad_any_cast&) {
try {
// 尝试获取值列表(嵌套情况)
std::vector<ir::Value*> nested_values =
std::any_cast<std::vector<ir::Value*>>(result);
all_values.insert(all_values.end(),
nested_values.begin(), nested_values.end());
} catch (const std::bad_any_cast&) {
throw std::runtime_error(
FormatError("irgen", "不支持的常量初始化值类型"));
}
}
}
}
return all_values;
}
// 空初始化列表
return std::vector<ir::Value*>{};
}
std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
}
if (ctx->relExp() && ctx->addExp()) {
auto left_any = ctx->relExp()->accept(this);
auto right_any = ctx->addExp()->accept(this);
auto* lhs = std::any_cast<ir::Value*>(left_any);
auto* rhs = std::any_cast<ir::Value*>(right_any);
std::cerr << "[DEBUG] visitRelExp: left=" << (void*)lhs
<< ", type=" << (lhs->GetType()->IsFloat() ? "float" : "int")
<< ", right=" << (void*)rhs
<< ", type=" << (rhs->GetType()->IsFloat() ? "float" : "int") << std::endl;
// 处理类型转换:如果操作数类型不同,需要进行类型转换
if (lhs->GetType()->IsFloat() != rhs->GetType()->IsFloat()) {
if (lhs->GetType()->IsFloat()) {
// lhs是floatrhs是int需要将rhs转换为float
rhs = builder_.CreateSIToFP(rhs, ir::Type::GetFloatType());
} else {
// rhs是floatlhs是int需要将lhs转换为float
lhs = builder_.CreateSIToFP(lhs, ir::Type::GetFloatType());
}
}
// 根据操作数和类型选择指令
if (ctx->LOp()) {
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpOLT(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpLT(lhs, rhs, module_.GetContext().NextTemp()));
}
}
if (ctx->GOp()) {
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpOGT(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpGT(lhs, rhs, module_.GetContext().NextTemp()));
}
}
if (ctx->LeOp()) {
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpOLE(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpLE(lhs, rhs, module_.GetContext().NextTemp()));
}
}
if (ctx->GeOp()) {
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpOGE(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpGE(lhs, rhs, module_.GetContext().NextTemp()));
}
}
throw std::runtime_error(FormatError("irgen", "未知关系运算符"));
}
if (ctx->addExp()) {
return ctx->addExp()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "关系表达式暂未实现"));
}
std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法相等表达式"));
}
if (ctx->eqExp() && ctx->relExp()) {
auto left_any = ctx->eqExp()->accept(this);
auto right_any = ctx->relExp()->accept(this);
auto* lhs = std::any_cast<ir::Value*>(left_any);
auto* rhs = std::any_cast<ir::Value*>(right_any);
std::cerr << "[DEBUG] visitEqExp: left=" << (void*)lhs
<< ", type=" << (lhs->GetType()->IsFloat() ? "float" : "int")
<< ", right=" << (void*)rhs
<< ", type=" << (rhs->GetType()->IsFloat() ? "float" : "int") << std::endl;
// 处理类型转换:如果操作数类型不同,需要进行类型转换
if (lhs->GetType()->IsFloat() != rhs->GetType()->IsFloat()) {
if (lhs->GetType()->IsFloat()) {
// lhs是floatrhs是int需要将rhs转换为float
rhs = builder_.CreateSIToFP(rhs, ir::Type::GetFloatType());
} else {
// rhs是floatlhs是int需要将lhs转换为float
lhs = builder_.CreateSIToFP(lhs, ir::Type::GetFloatType());
}
}
// 根据操作符和类型选择指令
if (ctx->EqOp()) {
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpOEQ(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpEQ(lhs, rhs, module_.GetContext().NextTemp()));
}
}
if (ctx->NeOp()) {
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpONE(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpNE(lhs, rhs, module_.GetContext().NextTemp()));
}
}
throw std::runtime_error(FormatError("irgen", "未知相等运算符"));
}
if (ctx->relExp()) {
return ctx->relExp()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "相等表达式暂未实现"));
}
ir::Value* IRGenImpl::EvalAssign(SysYParser::StmtContext* ctx) {
std::cout << "[DEBUG IRGEN] visitCond: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx || !ctx->lVal() || !ctx->exp()) {
throw std::runtime_error(FormatError("irgen", "非法赋值语句"));
}
// 计算右值
ir::Value* rhs = EvalExpr(*ctx->exp());
auto* lval = ctx->lVal();
std::string varName = lval->Ident()->getText();
// 首先尝试从语义分析获取变量定义
auto* var_decl = sema_.ResolveVarUse(lval);
if (var_decl) {
// 是变量赋值
// 从storage_map_获取存储位置
auto it = storage_map_.find(var_decl);
if (it == storage_map_.end()) {
throw std::runtime_error(
FormatError("irgen", "变量声明缺少存储槽位: " + varName));
}
ir::Value* base_ptr = it->second;
// 检查是否有数组下标
auto exp_list = lval->exp();
if (!exp_list.empty()) {
// 这是数组元素赋值需要生成GEP指令
std::vector<ir::Value*> indices;
// 第一个索引是0假设一维数组
indices.push_back(builder_.CreateConstInt(0));
// 添加用户提供的下标
for (auto* exp : exp_list) {
ir::Value* index = EvalExpr(*exp);
indices.push_back(index);
}
// 生成GEP指令获取元素地址
ir::Value* elem_ptr = builder_.CreateGEP(
base_ptr, indices, module_.GetContext().NextTemp());
// 生成store指令
builder_.CreateStore(rhs, elem_ptr);
} else {
// 普通标量赋值
// 调试输出指针类型
std::cerr << "[DEBUG] base_ptr type: " << base_ptr->GetType() << std::endl;
std::cerr << "[DEBUG] rhs type: " << rhs->GetType()<< std::endl;
// 如果 base_ptr 不是指针类型,可能需要特殊处理
if (!base_ptr->GetType()->IsPtrInt32()) {
std::cerr << "[ERROR] base_ptr is not a pointer type!" << std::endl;
throw std::runtime_error("尝试存储到非指针类型");
}
builder_.CreateStore(rhs, base_ptr);
}
} else {
// 尝试获取常量定义
auto* const_decl = sema_.ResolveConstUse(lval);
if (const_decl) {
// 尝试给常量赋值,这是错误的
throw std::runtime_error(
FormatError("irgen", "不能给常量赋值: " + varName));
} else {
throw std::runtime_error(
FormatError("irgen", "变量/常量使用缺少语义绑定: " + varName));
}
}
return rhs;
}

@ -1,6 +1,8 @@
#include "irgen/IRGen.h"
#include <memory>
#include <stdexcept>
#include <vector>
#include "SysYParser.h"
#include "ir/IR.h"
@ -9,7 +11,6 @@
namespace {
void VerifyFunctionStructure(const ir::Function& func) {
// 当前 IRGen 仍是单入口、顺序生成;这里在生成结束后补一层块终结校验。
for (const auto& bb : func.GetBlocks()) {
if (!bb || !bb->HasTerminator()) {
throw std::runtime_error(
@ -25,63 +26,343 @@ IRGenImpl::IRGenImpl(ir::Module& module, const SemanticContext& sema)
: module_(module),
sema_(sema),
func_(nullptr),
builder_(module.GetContext(), nullptr) {}
// 编译单元的 IR 生成当前只实现了最小功能:
// - Module 已在 GenerateIR 中创建,这里只负责继续生成其中的内容;
// - 当前会读取编译单元中的函数定义,并交给 visitFuncDef 生成函数 IR
//
// 当前还没有实现:
// - 多个函数定义的遍历与生成;
// - 全局变量、全局常量的 IR 生成。
builder_(module.GetContext(), nullptr) {
AddRuntimeFunctions();
}
void IRGenImpl::AddRuntimeFunctions() {
std::cout << "[DEBUG IRGEN] 添加运行时库函数声明" << std::endl;
// 输入函数(返回 int
module_.CreateFunction("getint",
ir::Type::GetFunctionType(ir::Type::GetInt32Type(), {}));
module_.CreateFunction("getch",
ir::Type::GetFunctionType(ir::Type::GetInt32Type(), {}));
// getarray(int* a, int n): int
module_.CreateFunction("getarray",
ir::Type::GetFunctionType(
ir::Type::GetInt32Type(),
{ir::Type::GetPtrInt32Type(), ir::Type::GetInt32Type()}));
// 输出函数(返回 void
module_.CreateFunction("putint",
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type()}));
module_.CreateFunction("putch",
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type()}));
// putarray(int n, int* a): void
module_.CreateFunction("putarray",
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type(), ir::Type::GetPtrInt32Type()}));
// 字符串输出(暂时用 int* 替代 char*
module_.CreateFunction("puts",
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetPtrInt32Type()}));
// 时间测量函数SysY 标准库)
module_.CreateFunction("_sysy_starttime",
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type()}));
module_.CreateFunction("_sysy_stoptime",
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type()}));
// 简化版本
module_.CreateFunction("starttime",
ir::Type::GetFunctionType(ir::Type::GetVoidType(), {}));
module_.CreateFunction("stoptime",
ir::Type::GetFunctionType(ir::Type::GetVoidType(), {}));
// 其他可能需要的函数
module_.CreateFunction("read_map",
ir::Type::GetFunctionType(ir::Type::GetInt32Type(), {}));
// 浮点数
module_.CreateFunction("float_eq",
ir::Type::GetFunctionType(
ir::Type::GetInt32Type(),
{ir::Type::GetFloatType(), ir::Type::GetFloatType()}));
// 内存操作函数
module_.CreateFunction("memset",
ir::Type::GetFunctionType(
ir::Type::GetPtrInt32Type(),
{ir::Type::GetPtrInt32Type(),
ir::Type::GetInt32Type(),
ir::Type::GetInt32Type()}));
std::cout << "[DEBUG IRGEN] 运行时库函数声明完成" << std::endl;
}
// 修正:没有 mainFuncDef通过函数名找到 main
std::any IRGenImpl::visitCompUnit(SysYParser::CompUnitContext* ctx) {
std::cout << "[DEBUG IRGEN] visitCompUnit" << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少编译单元"));
}
auto* func = ctx->funcDef();
if (!func) {
throw std::runtime_error(FormatError("irgen", "缺少函数定义"));
// 处理全局变量声明
for (auto* decl : ctx->decl()) {
if (decl) {
decl->accept(this);
}
}
func->accept(this);
// 处理所有函数定义
for (auto* funcDef : ctx->funcDef()) {
if (funcDef) {
funcDef->accept(this);
}
}
return {};
}
// 函数 IR 生成当前实现了:
// 1. 获取函数名;
// 2. 检查函数返回类型;
// 3. 在 Module 中创建 Function
// 4. 将 builder 插入点设置到入口基本块;
// 5. 继续生成函数体。
//
// 当前还没有实现:
// - 通用函数返回类型处理;
// - 形参列表遍历与参数类型收集;
// - FunctionType 这样的函数类型对象;
// - Argument/形式参数 IR 对象;
// - 入口块中的参数初始化逻辑。
// ...
// 因此这里目前只支持最小的“无参 int 函数”生成。
std::any IRGenImpl::visitFuncDef(SysYParser::FuncDefContext* ctx) {
std::cout << "[DEBUG IRGEN] visitFuncDef: " << (ctx && ctx->Ident() ? ctx->Ident()->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少函数定义"));
}
if (!ctx->blockStmt()) {
if (!ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "缺少函数名"));
}
std::string funcName = ctx->Ident()->getText();
if (!ctx->block()) {
throw std::runtime_error(FormatError("irgen", "函数体为空"));
}
if (!ctx->ID()) {
throw std::runtime_error(FormatError("irgen", "缺少函数名"));
std::shared_ptr<ir::Type> ret_type = ir::Type::GetInt32Type();
if (ctx->funcType()) {
if (ctx->funcType()->Void()) {
ret_type = ir::Type::GetVoidType();
} else if (ctx->funcType()->Int()) {
ret_type = ir::Type::GetInt32Type();
} else if (ctx->funcType()->Float()) {
ret_type = ir::Type::GetFloatType();
}
}
if (!ctx->funcType() || !ctx->funcType()->INT()) {
throw std::runtime_error(FormatError("irgen", "当前仅支持无参 int 函数"));
std::vector<std::shared_ptr<ir::Type>> param_types;
if (ctx->funcFParams()) {
for (auto* param : ctx->funcFParams()->funcFParam()) {
if (!param || !param->Ident()) continue;
std::string name = param->Ident()->getText();
std::shared_ptr<ir::Type> param_ty;
// 检查 bType 是否存在
if (!param->bType()) {
throw std::runtime_error(FormatError("irgen", "函数参数缺少类型: " + name));
}
if (param->bType()->Int()) {
param_ty = ir::Type::GetInt32Type();
} else if (param->bType()->Float()) {
param_ty = ir::Type::GetFloatType();
} else {
param_ty = ir::Type::GetInt32Type(); // 默认值
}
if (!param->L_BRACK().empty()) {
if (param_ty->IsInt32()) {
param_ty = ir::Type::GetPtrInt32Type();
} else if (param_ty->IsFloat()) {
param_ty = ir::Type::GetPtrFloatType();
}
}
param_types.push_back(param_ty);
}
}
func_ = module_.CreateFunction(ctx->ID()->getText(), ir::Type::GetInt32Type());
builder_.SetInsertPoint(func_->GetEntry());
// 创建函数类型
auto func_type = ir::Type::GetFunctionType(ret_type, param_types);
// 调试输出
std::cerr << "[DEBUG] visitFuncDef: 创建函数 " << funcName
<< ",返回类型: " << (ret_type->IsVoid() ? "void" : ret_type->IsFloat() ? "float" : "int")
<< ",参数数量: " << param_types.size() << std::endl;
// 创建函数对象
func_ = module_.CreateFunction(funcName, func_type);
// 检查函数是否成功创建
if (!func_) {
std::cerr << "[ERROR] visitFuncDef: 创建函数失败func_ 为 nullptr!" << std::endl;
throw std::runtime_error(FormatError("irgen", "创建函数失败: " + funcName));
}
std::cerr << "[DEBUG] visitFuncDef: 函数对象地址: " << (void*)func_ << std::endl;
// 设置插入点
auto* entry_block = func_->GetEntry();
if (!entry_block) {
std::cerr << "[ERROR] visitFuncDef: 函数入口基本块为空!" << std::endl;
throw std::runtime_error(FormatError("irgen", "函数入口基本块为空: " + funcName));
}
builder_.SetInsertPoint(entry_block);
storage_map_.clear();
param_map_.clear();
// 函数参数处理
if (ctx->funcFParams()) {
for (auto* param : ctx->funcFParams()->funcFParam()) {
if (!param || !param->Ident()) continue;
std::string name = param->Ident()->getText();
std::shared_ptr<ir::Type> param_ty;
// 再次检查 bType
if (!param->bType()) {
throw std::runtime_error(FormatError("irgen", "函数参数缺少类型: " + name));
}
if (param->bType()->Int()) {
param_ty = ir::Type::GetInt32Type();
} else if (param->bType()->Float()) {
param_ty = ir::Type::GetFloatType();
} else {
param_ty = ir::Type::GetInt32Type();
}
if (!param->L_BRACK().empty()) {
if (param_ty->IsInt32()) {
param_ty = ir::Type::GetPtrInt32Type();
} else if (param_ty->IsFloat()) {
param_ty = ir::Type::GetPtrFloatType();
}
}
// 检查函数对象是否有效
if (!func_) {
std::cerr << "[ERROR] visitFuncDef: func_ 在添加参数时变为 nullptr!" << std::endl;
throw std::runtime_error(FormatError("irgen", "函数对象无效"));
}
std::cerr << "[DEBUG] visitFuncDef: 为函数 " << funcName
<< " 添加参数 " << name << ",类型: "
<< (param_ty->IsInt32() ? "int32" : param_ty->IsFloat() ? "float" :
param_ty->IsPtrInt32() ? "ptr_int32" : param_ty->IsPtrFloat() ? "ptr_float" : "other")
<< std::endl;
// 创建参数并添加到函数
auto arg = std::make_unique<ir::Argument>(param_ty, name);
if (!arg) {
throw std::runtime_error(FormatError("irgen", "创建参数失败: " + name));
}
auto* arg_ptr = arg.get();
auto* added_arg = func_->AddArgument(std::move(arg));
if (!added_arg) {
std::cerr << "[ERROR] visitFuncDef: AddArgument 返回 nullptr!" << std::endl;
throw std::runtime_error(FormatError("irgen", "添加参数失败: " + name));
}
// 为参数创建存储槽位
ir::AllocaInst* slot = nullptr;
if (param_ty->IsInt32() || param_ty->IsPtrInt32()) {
slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp());
} else if (param_ty->IsFloat() || param_ty->IsPtrFloat()) {
slot = builder_.CreateAllocaFloat(module_.GetContext().NextTemp());
} else {
throw std::runtime_error(FormatError("irgen", "不支持的参数类型"));
}
if (!slot) {
throw std::runtime_error(FormatError("irgen", "创建参数存储槽位失败: " + name));
}
builder_.CreateStore(added_arg, slot);
param_map_[name] = slot;
std::cerr << "[DEBUG] visitFuncDef: 参数 " << name << " 处理完成" << std::endl;
}
}
// 生成函数体
std::cerr << "[DEBUG] visitFuncDef: 开始生成函数体" << std::endl;
ctx->block()->accept(this);
// 如果函数没有终止指令,添加默认返回
if (!func_->GetEntry()->HasTerminator()) {
std::cerr << "[DEBUG] visitFuncDef: 函数体没有终止指令,添加默认返回" << std::endl;
auto retVal = builder_.CreateConstInt(0);
builder_.CreateRet(retVal);
}
ctx->blockStmt()->accept(this);
// 语义正确性主要由 sema 保证,这里只兜底检查 IR 结构是否合法。
VerifyFunctionStructure(*func_);
// 验证函数结构
try {
VerifyFunctionStructure(*func_);
} catch (const std::exception& e) {
std::cerr << "[ERROR] visitFuncDef: 验证函数结构失败: " << e.what() << std::endl;
throw;
}
std::cerr << "[DEBUG] visitFuncDef: 函数 " << funcName << " 生成完成" << std::endl;
func_ = nullptr;
return {};
}
std::any IRGenImpl::visitBlock(SysYParser::BlockContext* ctx) {
std::cout << "[DEBUG IRGEN] visitBlock: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少语句块"));
}
BlockFlow flow = BlockFlow::Continue;
for (auto* item : ctx->blockItem()) {
if (!item) continue;
flow = VisitBlockItemResult(*item);
if (flow == BlockFlow::Terminated) {
break;
}
auto* cur = builder_.GetInsertBlock();
std::cout << "[DEBUG] current insert block: "
<< (cur ? cur->GetName() : "<null>") << std::endl;
if (cur && cur->HasTerminator()) {
break;
}
}
return flow;
}
// 类型安全的包装器
IRGenImpl::BlockFlow IRGenImpl::VisitBlockItemResult(
SysYParser::BlockItemContext& item) {
auto result = item.accept(this);// 调用 visitBlockItem返回 std::any 包装的 BlockFlow
return std::any_cast<BlockFlow>(result); // 解包为 BlockFlow
}
// 用于遍历块内项,返回是否继续访问后续项(如遇到 return/break/continue 则终止访问)
std::any IRGenImpl::visitBlockItem(SysYParser::BlockItemContext* ctx) {
std::cout << "[DEBUG IRGEN] visitBlockItem: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少块内项"));
}
// 块内项可以是语句或声明,优先处理语句(如 return/break/continue 可能终止块内执行)
if (ctx->stmt()) {
return ctx->stmt()->accept(this); // 语句访问返回 BlockFlow指示是否继续访问后续项
}
// 处理声明(如变量定义),继续访问后续项
if (ctx->decl()) {
ctx->decl()->accept(this);
return BlockFlow::Continue; // 声明不会终止块内执行,继续访问后续项
}
throw std::runtime_error(FormatError("irgen", "暂不支持的块内项"));
}

@ -16,24 +16,409 @@
// - 空语句、块语句嵌套分发之外的更多语句形态
std::any IRGenImpl::visitStmt(SysYParser::StmtContext* ctx) {
std::cout << "[DEBUG IRGEN] visitStmt: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少语句"));
}
if (ctx->returnStmt()) {
return ctx->returnStmt()->accept(this);
// return 语句 - 通过 Return() 关键字判断
if (ctx->Return()) {
return HandleReturnStmt(ctx);
}
// 赋值语句
if (ctx->lVal() && ctx->Assign() && ctx->exp()) {
return HandleAssignStmt(ctx);
}
// if 语句
if (ctx->If()) {
return HandleIfStmt(ctx);
}
// while 语句
if (ctx->While()) {
return HandleWhileStmt(ctx);
}
// break 语句
if (ctx->Break()) {
return HandleBreakStmt(ctx);
}
// continue 语句
if (ctx->Continue()) {
return HandleContinueStmt(ctx);
}
// 块语句
if (ctx->block()) {
return ctx->block()->accept(this);
}
// 空语句或表达式语句(先计算表达式)
if (ctx->exp()) {
EvalExpr(*ctx->exp());
return BlockFlow::Continue;
}
throw std::runtime_error(FormatError("irgen", "暂不支持的语句类型"));
}
// 修改 HandleReturnStmt 函数
std::any IRGenImpl::visitReturnStmt(SysYParser::ReturnStmtContext* ctx) {
IRGenImpl::BlockFlow IRGenImpl::HandleReturnStmt(SysYParser::StmtContext* ctx) {
std::cout << "[DEBUG IRGEN] HandleReturnStmt: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少 return 语句"));
}
if (!ctx->exp()) {
throw std::runtime_error(FormatError("irgen", "return 缺少表达式"));
// 检查函数是否存在
if (!func_) {
throw std::runtime_error(FormatError("irgen", "Return语句不在函数中"));
}
// 获取函数类型中的返回类型
auto func_type = std::dynamic_pointer_cast<ir::FunctionType>(func_->GetType());
if (!func_type) {
throw std::runtime_error(FormatError("irgen", "函数类型无效"));
}
auto ret_type = func_type->GetReturnType();
if (ret_type->IsVoid()) {
if (ctx->exp()) {
// 表达式被忽略(可计算但不使用)
EvalExpr(*ctx->exp());
}
// 对于void函数创建返回指令不传参数
builder_.CreateRet(nullptr);
} else {
ir::Value* retValue = nullptr;
if (ctx->exp()) {
retValue = EvalExpr(*ctx->exp());
if (!retValue) {
throw std::runtime_error(FormatError("irgen", "返回值表达式求值失败"));
}
// 类型转换
if (retValue->GetType() != ret_type) {
if (ret_type->IsInt32() && retValue->GetType()->IsFloat()) {
retValue = builder_.CreateFPToSI(retValue, ir::Type::GetInt32Type());
} else if (ret_type->IsFloat() && retValue->GetType()->IsInt32()) {
retValue = builder_.CreateSIToFP(retValue, ir::Type::GetFloatType());
}
}
} else {
// 无表达式,返回默认值
if (ret_type->IsInt32()) {
retValue = builder_.CreateConstInt(0);
} else if (ret_type->IsFloat()) {
retValue = builder_.CreateConstFloat(0.0f);
} else {
retValue = builder_.CreateConstInt(0); // fallback
}
}
builder_.CreateRet(retValue);
}
ir::Value* v = EvalExpr(*ctx->exp());
builder_.CreateRet(v);
return BlockFlow::Terminated;
}
// if语句待实现
IRGenImpl::BlockFlow IRGenImpl::HandleIfStmt(SysYParser::StmtContext* ctx) {
std::cout << "[DEBUG IRGEN] HandleIfStmt: " << (ctx ? ctx->getText() : "<null>") << std::endl;
auto* cond = ctx->cond();
auto* thenStmt = ctx->stmt(0);
auto* elseStmt = ctx->stmt(1);
// 创建基本块
auto* thenBlock = func_->CreateBlock("then");
auto* elseBlock = (ctx->Else() && elseStmt) ? func_->CreateBlock("else") : nullptr;
auto* mergeBlock = func_->CreateBlock("merge");
std::cout << "[DEBUG IF] thenBlock: " << thenBlock->GetName() << std::endl;
if (elseBlock) std::cout << "[DEBUG IF] elseBlock: " << elseBlock->GetName() << std::endl;
std::cout << "[DEBUG IF] mergeBlock: " << mergeBlock->GetName() << std::endl;
std::cout << "[DEBUG IF] current insert block before cond: "
<< builder_.GetInsertBlock()->GetName() << std::endl;
// 生成条件
auto* condValue = EvalCond(*cond);
// 创建条件跳转
if (elseBlock) {
std::cout << "[DEBUG IF] Creating condbr: " << condValue->GetName()
<< " -> " << thenBlock->GetName() << ", " << elseBlock->GetName() << std::endl;
builder_.CreateCondBr(condValue, thenBlock, elseBlock);
} else {
std::cout << "[DEBUG IF] Creating condbr: " << condValue->GetName()
<< " -> " << thenBlock->GetName() << ", " << mergeBlock->GetName() << std::endl;
builder_.CreateCondBr(condValue, thenBlock, mergeBlock);
}
// 生成 then 分支
std::cout << "[DEBUG IF] Generating then branch in block: " << thenBlock->GetName() << std::endl;
builder_.SetInsertPoint(thenBlock);
auto thenResult = thenStmt->accept(this);
bool thenTerminated = (std::any_cast<BlockFlow>(thenResult) == BlockFlow::Terminated);
std::cout << "[DEBUG IF] then branch terminated: " << thenTerminated << std::endl;
if (!thenTerminated) {
std::cout << "[DEBUG IF] Adding br to merge block from then" << std::endl;
builder_.CreateBr(mergeBlock);
}
std::cout << "[DEBUG IF] then block has terminator: " << thenBlock->HasTerminator() << std::endl;
// 生成 else 分支
bool elseTerminated = false;
if (elseBlock) {
std::cout << "[DEBUG IF] Generating else branch in block: " << elseBlock->GetName() << std::endl;
builder_.SetInsertPoint(elseBlock);
auto elseResult = elseStmt->accept(this);
elseTerminated = (std::any_cast<BlockFlow>(elseResult) == BlockFlow::Terminated);
std::cout << "[DEBUG IF] else branch terminated: " << elseTerminated << std::endl;
if (!elseTerminated) {
std::cout << "[DEBUG IF] Adding br to merge block from else" << std::endl;
builder_.CreateBr(mergeBlock);
}
std::cout << "[DEBUG IF] else block has terminator: " << elseBlock->HasTerminator() << std::endl;
}
// 决定后续插入点
std::cout << "[DEBUG IF] thenTerminated=" << thenTerminated
<< ", elseTerminated=" << elseTerminated << std::endl;
if (elseBlock) {
if (thenTerminated && elseTerminated) {
auto* afterIfBlock = func_->CreateBlock("after.if");
std::cout << "[DEBUG IF] Both branches terminated, creating new block: "
<< afterIfBlock->GetName() << std::endl;
builder_.SetInsertPoint(afterIfBlock);
} else {
std::cout << "[DEBUG IF] Setting insert point to merge block: "
<< mergeBlock->GetName() << std::endl;
builder_.SetInsertPoint(mergeBlock);
}
} else {
std::cout << "[DEBUG IF] No else, setting insert point to merge block: "
<< mergeBlock->GetName() << std::endl;
builder_.SetInsertPoint(mergeBlock);
}
std::cout << "[DEBUG IF] Final insert block: "
<< builder_.GetInsertBlock()->GetName() << std::endl;
return BlockFlow::Continue;
}
// while语句待实现IRGenImpl::BlockFlow IRGenImpl::HandleWhileStmt(SysYParser::StmtContext* ctx) {
IRGenImpl::BlockFlow IRGenImpl::HandleWhileStmt(SysYParser::StmtContext* ctx) {
std::cout << "[DEBUG IRGEN] HandleWhileStmt: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx || !ctx->cond() || !ctx->stmt(0)) {
throw std::runtime_error(FormatError("irgen", "非法 while 语句"));
}
std::cout << "[DEBUG WHILE] Current insert block before while: "
<< builder_.GetInsertBlock()->GetName() << std::endl;
auto* condBlock = func_->CreateBlock("while.cond");
auto* bodyBlock = func_->CreateBlock("while.body");
auto* exitBlock = func_->CreateBlock("while.exit");
std::cout << "[DEBUG WHILE] condBlock: " << condBlock->GetName() << std::endl;
std::cout << "[DEBUG WHILE] bodyBlock: " << bodyBlock->GetName() << std::endl;
std::cout << "[DEBUG WHILE] exitBlock: " << exitBlock->GetName() << std::endl;
std::cout << "[DEBUG WHILE] Adding br to condBlock from current block" << std::endl;
builder_.CreateBr(condBlock);
loopStack_.push_back({condBlock, bodyBlock, exitBlock});
std::cout << "[DEBUG WHILE] loopStack size: " << loopStack_.size() << std::endl;
// 条件块
std::cout << "[DEBUG WHILE] Generating condition in block: " << condBlock->GetName() << std::endl;
builder_.SetInsertPoint(condBlock);
auto* condValue = EvalCond(*ctx->cond());
builder_.CreateCondBr(condValue, bodyBlock, exitBlock);
std::cout << "[DEBUG WHILE] condBlock has terminator: " << condBlock->HasTerminator() << std::endl;
// 循环体
std::cout << "[DEBUG WHILE] Generating body in block: " << bodyBlock->GetName() << std::endl;
builder_.SetInsertPoint(bodyBlock);
auto bodyResult = ctx->stmt(0)->accept(this);
bool bodyTerminated = (std::any_cast<BlockFlow>(bodyResult) == BlockFlow::Terminated);
std::cout << "[DEBUG WHILE] body terminated: " << bodyTerminated << std::endl;
if (!bodyTerminated) {
std::cout << "[DEBUG WHILE] Adding br to condBlock from body" << std::endl;
builder_.CreateBr(condBlock);
}
std::cout << "[DEBUG WHILE] bodyBlock has terminator: " << bodyBlock->HasTerminator() << std::endl;
loopStack_.pop_back();
std::cout << "[DEBUG WHILE] loopStack size after pop: " << loopStack_.size() << std::endl;
// 设置插入点为 exitBlock
std::cout << "[DEBUG WHILE] Setting insert point to exitBlock: " << exitBlock->GetName() << std::endl;
builder_.SetInsertPoint(exitBlock);
std::cout << "[DEBUG WHILE] exitBlock has terminator before return: "
<< exitBlock->HasTerminator() << std::endl;
return BlockFlow::Continue;
}
// break语句待实现
IRGenImpl::BlockFlow IRGenImpl::HandleBreakStmt(SysYParser::StmtContext* ctx) {
std::cout << "[DEBUG IRGEN] HandleBreakStmt: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (loopStack_.empty()) {
throw std::runtime_error(FormatError("irgen", "break 语句不在循环中"));
}
std::cout << "[DEBUG BREAK] Current insert block before break: "
<< builder_.GetInsertBlock()->GetName() << std::endl;
std::cout << "[DEBUG BREAK] Breaking to exitBlock: "
<< loopStack_.back().exitBlock->GetName() << std::endl;
// 跳转到循环退出块
builder_.CreateBr(loopStack_.back().exitBlock);
// break 本身就是终止当前路径,后续 unreachable 代码不需要继续生成。
return BlockFlow::Terminated;
}
IRGenImpl::BlockFlow IRGenImpl::HandleContinueStmt(SysYParser::StmtContext* ctx) {
std::cout << "[DEBUG IRGEN] HandleContinueStmt: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (loopStack_.empty()) {
throw std::runtime_error(FormatError("irgen", "continue 语句不在循环中"));
}
std::cout << "[DEBUG CONTINUE] Current insert block before continue: "
<< builder_.GetInsertBlock()->GetName() << std::endl;
std::cout << "[DEBUG CONTINUE] Continuing to condBlock: "
<< loopStack_.back().condBlock->GetName() << std::endl;
// 跳转到循环条件块
builder_.CreateBr(loopStack_.back().condBlock);
// continue 本身就是终止当前路径,后续 unreachable 代码不需要继续生成。
return BlockFlow::Terminated;
}
// 赋值语句(待实现)
// 赋值语句
// 赋值语句
IRGenImpl::BlockFlow IRGenImpl::HandleAssignStmt(SysYParser::StmtContext* ctx) {
std::cout << "[DEBUG IRGEN] HandleAssignStmt: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx || !ctx->lVal() || !ctx->exp()) {
throw std::runtime_error(FormatError("irgen", "非法赋值语句"));
}
// 计算右值
ir::Value* rhs = EvalExpr(*ctx->exp());
if (!rhs) {
throw std::runtime_error(FormatError("irgen", "赋值 RHS 计算失败"));
}
auto* lval = ctx->lVal();
std::string varName = lval->Ident()->getText();
std::cerr << "[DEBUG] HandleAssignStmt: assigning to " << varName << std::endl;
// 1. 检查是否为常量(不能给常量赋值)
auto* const_decl = sema_.ResolveConstUse(lval);
if (const_decl) {
throw std::runtime_error(
FormatError("irgen", "不能给常量赋值: " + varName));
}
// 2. 查找存储位置
ir::Value* base_ptr = nullptr;
// 2.1 尝试通过语义分析获取变量定义,并从 storage_map_ 查找
auto* var_decl = sema_.ResolveVarUse(lval);
if (var_decl) {
auto it = storage_map_.find(var_decl);
if (it != storage_map_.end()) {
base_ptr = it->second;
std::cerr << "[DEBUG] HandleAssignStmt: found in storage_map_ for " << varName
<< ", ptr = " << (void*)base_ptr << std::endl;
}
}
// 2.2 从参数映射查找(关键!)
if (!base_ptr) {
auto it2 = param_map_.find(varName);
if (it2 != param_map_.end()) {
base_ptr = it2->second;
std::cerr << "[DEBUG] HandleAssignStmt: found in param_map_ for " << varName
<< ", ptr = " << (void*)base_ptr << std::endl;
}
}
// 2.3 从全局变量映射查找
if (!base_ptr) {
auto it3 = global_map_.find(varName);
if (it3 != global_map_.end()) {
base_ptr = it3->second;
std::cerr << "[DEBUG] HandleAssignStmt: found in global_map_ for " << varName
<< ", ptr = " << (void*)base_ptr << std::endl;
}
}
// 2.4 从局部变量映射查找fallback
if (!base_ptr) {
auto it4 = local_var_map_.find(varName);
if (it4 != local_var_map_.end()) {
base_ptr = it4->second;
std::cerr << "[DEBUG] HandleAssignStmt: found in local_var_map_ for " << varName
<< ", ptr = " << (void*)base_ptr << std::endl;
}
}
// 如果还是找不到,才报错
if (!base_ptr) {
throw std::runtime_error(
FormatError("irgen", "变量声明缺少存储槽位: " + varName));
}
// 3. 检查是否有数组下标
auto exp_list = lval->exp();
if (!exp_list.empty()) {
// 数组元素赋值
std::vector<ir::Value*> indices;
indices.push_back(builder_.CreateConstInt(0));
for (auto* exp : exp_list) {
ir::Value* index = EvalExpr(*exp);
indices.push_back(index);
}
ir::Value* elem_ptr = builder_.CreateGEP(
base_ptr, indices, module_.GetContext().NextTemp());
builder_.CreateStore(rhs, elem_ptr);
} else {
// 普通标量赋值
std::cerr << "[DEBUG] HandleAssignStmt: scalar assignment to " << varName
<< ", ptr = " << (void*)base_ptr
<< ", rhs = " << (void*)rhs << std::endl;
// 在 HandleAssignStmt 中,存储前添加类型调试
if (base_ptr && base_ptr->GetType()) {
std::cerr << "[DEBUG] Is int32: " << base_ptr->GetType()->IsInt32() << std::endl;
std::cerr << "[DEBUG] Is float: " << base_ptr->GetType()->IsFloat() << std::endl;
std::cerr << "[DEBUG] Is ptr int32: " << base_ptr->GetType()->IsPtrInt32() << std::endl;
std::cerr << "[DEBUG] Is ptr float: " << base_ptr->GetType()->IsPtrFloat() << std::endl;
std::cerr << "[DEBUG] Is array: " << base_ptr->GetType()->IsArray() << std::endl;
}
if (rhs && rhs->GetType()) {
std::cerr << "[DEBUG] Value is int32: " << rhs->GetType()->IsInt32() << std::endl;
}
builder_.CreateStore(rhs, base_ptr);
}
return BlockFlow::Continue;
}

File diff suppressed because it is too large Load Diff

@ -1,17 +1,752 @@
// 维护局部变量声明的注册与查找。
#include "sem/SymbolTable.h"
#include <antlr4-runtime.h> // 用于访问父节点
#include <cctype>
#include <stdexcept>
#include <string>
#include <cmath>
#define DEBUG_SYMBOL_TABLE
#ifdef DEBUG_SYMBOL_TABLE
#include <iostream>
#define DEBUG_MSG(msg) std::cerr << "[SymbolTable Debug] " << msg << std::endl
#else
#define DEBUG_MSG(msg)
#endif
// ---------- 构造函数 ----------
SymbolTable::SymbolTable() {
scopes_.emplace_back(); // 初始化全局作用域
registerBuiltinFunctions(); // 注册内置库函数
}
// ---------- 作用域管理 ----------
void SymbolTable::enterScope() {
scopes_.emplace_back();
}
void SymbolTable::exitScope() {
if (scopes_.size() > 1) {
scopes_.pop_back();
}
// 不能退出全局作用域
}
// ---------- 符号添加与查找 ----------
bool SymbolTable::addSymbol(const Symbol& sym) {
auto& current_scope = scopes_.back();
if (current_scope.find(sym.name) != current_scope.end()) {
return false; // 重复定义
}
current_scope[sym.name] = sym;
// 立即验证存储的符号
const auto& stored = current_scope[sym.name];
std::cout << "SymbolTable::addSymbol: stored " << sym.name
<< " with kind=" << (int)stored.kind
<< ", const_def_ctx=" << stored.const_def_ctx
<< std::endl;
return true;
}
Symbol* SymbolTable::lookup(const std::string& name) {
return const_cast<Symbol*>(static_cast<const SymbolTable*>(this)->lookup(name));
}
Symbol* SymbolTable::lookupCurrent(const std::string& name) {
return const_cast<Symbol*>(static_cast<const SymbolTable*>(this)->lookupCurrent(name));
}
const Symbol* SymbolTable::lookup(const std::string& name) const {
for (auto it = scopes_.rbegin(); it != scopes_.rend(); ++it) {
const auto& scope = *it;
auto found = scope.find(name);
if (found != scope.end()) {
std::cout << "SymbolTable::lookup: found " << name
<< " in scope level " << (scopes_.rend() - it - 1)
<< ", kind=" << (int)found->second.kind
<< ", const_def_ctx=" << found->second.const_def_ctx
<< std::endl;
return &found->second;
}
}
return nullptr;
}
const Symbol* SymbolTable::lookupCurrent(const std::string& name) const {
const auto& current_scope = scopes_.back();
auto it = current_scope.find(name);
if (it != current_scope.end()) {
return &it->second;
}
return nullptr;
}
void SymbolTable::Add(const std::string& name,
SysYParser::VarDefContext* decl) {
table_[name] = decl;
// ---------- 兼容原接口 ----------
void SymbolTable::Add(const std::string& name, SysYParser::VarDefContext* decl) {
Symbol sym;
sym.name = name;
sym.kind = SymbolKind::Variable;
sym.type = getTypeFromVarDef(decl);
sym.var_def_ctx = decl;
sym.scope_level = currentScopeLevel();
addSymbol(sym);
}
bool SymbolTable::Contains(const std::string& name) const {
return table_.find(name) != table_.end();
// const 方法不能修改 scopes_我们模拟查找
for (auto it = scopes_.rbegin(); it != scopes_.rend(); ++it) {
if (it->find(name) != it->end()) {
return true;
}
}
return false;
}
SysYParser::VarDefContext* SymbolTable::Lookup(const std::string& name) const {
auto it = table_.find(name);
return it == table_.end() ? nullptr : it->second;
for (auto it = scopes_.rbegin(); it != scopes_.rend(); ++it) {
auto found = it->find(name);
if (found != it->end()) {
// 只返回变量定义的上下文(函数等其他符号返回 nullptr
if (found->second.kind == SymbolKind::Variable) {
return found->second.var_def_ctx;
}
return nullptr;
}
}
return nullptr;
}
// ---------- 辅助函数:从 VarDefContext 获取外层 VarDeclContext ----------
static SysYParser::VarDeclContext* getOuterVarDecl(SysYParser::VarDefContext* varDef) {
auto parent = varDef->parent;
while (parent) {
if (auto varDecl = dynamic_cast<SysYParser::VarDeclContext*>(parent)) {
return varDecl;
}
parent = parent->parent;
}
return nullptr;
}
// ---------- 辅助函数:从 VarDefContext 获取外层 ConstDeclContext常量定义----------
static SysYParser::ConstDeclContext* getOuterConstDecl(SysYParser::VarDefContext* varDef) {
auto parent = varDef->parent;
while (parent) {
if (auto constDecl = dynamic_cast<SysYParser::ConstDeclContext*>(parent)) {
return constDecl;
}
parent = parent->parent;
}
return nullptr;
}
// 从 VarDefContext 构造类型
// 原静态函数改为成员函数,并调用成员 EvaluateConstExp
std::shared_ptr<ir::Type> SymbolTable::getTypeFromVarDef(SysYParser::VarDefContext* ctx) const {
// 获取基本类型(同原代码,但通过外层 Decl 确定)
std::shared_ptr<ir::Type> base_type = nullptr;
auto varDecl = getOuterVarDecl(ctx);
if (varDecl) {
auto bType = varDecl->bType();
if (bType->Int()) base_type = ir::Type::GetInt32Type();
else if (bType->Float()) base_type = ir::Type::GetFloatType();
} else {
auto constDecl = getOuterConstDecl(ctx);
if (constDecl) {
auto bType = constDecl->bType();
if (bType->Int()) base_type = ir::Type::GetInt32Type();
else if (bType->Float()) base_type = ir::Type::GetFloatType();
}
}
if (!base_type) base_type = ir::Type::GetInt32Type();
// 解析维度
std::vector<int> dims;
for (auto* dimExp : ctx->constExp()) {
int dim = EvaluateConstExp(dimExp); // 调用成员函数
if (dim <= 0) {
throw std::runtime_error("数组维度必须为正整数");
}
dims.push_back(dim);
}
if (!dims.empty()) {
return ir::Type::GetArrayType(base_type, dims);
}
return base_type;
}
// 从 FuncDefContext 构造函数类型
std::shared_ptr<ir::Type> SymbolTable::getTypeFromFuncDef(SysYParser::FuncDefContext* ctx) {
// 1. 返回类型
std::shared_ptr<ir::Type> ret_type;
auto funcType = ctx->funcType();
if (funcType->Void()) {
ret_type = ir::Type::GetVoidType();
} else if (funcType->Int()) {
ret_type = ir::Type::GetInt32Type();
} else if (funcType->Float()) {
ret_type = ir::Type::GetFloatType();
} else {
ret_type = ir::Type::GetInt32Type(); // fallback
}
// 2. 参数类型
std::vector<std::shared_ptr<ir::Type>> param_types;
auto fParams = ctx->funcFParams();
if (fParams) {
for (auto param : fParams->funcFParam()) {
std::shared_ptr<ir::Type> param_type;
auto bType = param->bType();
if (bType->Int()) {
param_type = ir::Type::GetInt32Type();
} else if (bType->Float()) {
param_type = ir::Type::GetFloatType();
} else {
param_type = ir::Type::GetInt32Type();
}
// 处理数组参数:如果存在 [ ] 或 [ exp ],退化为指针
if (param->L_BRACK().size() > 0) {
if (param_type->IsInt32()) {
param_type = ir::Type::GetPtrInt32Type();
} else if (param_type->IsFloat()) {
param_type = ir::Type::GetPtrFloatType();
}
}
param_types.push_back(param_type);
}
}
return ir::Type::GetFunctionType(ret_type, param_types);
}
// ----- 注册内置库函数-----
void SymbolTable::registerBuiltinFunctions() {
// 确保当前处于全局作用域scopes_ 只有一层)
// 1. getint: int getint()
Symbol getint;
getint.name = "getint";
getint.kind = SymbolKind::Function;
getint.type = ir::Type::GetFunctionType(ir::Type::GetInt32Type(), {}); // 无参数
getint.param_types = {};
getint.scope_level = 0;
getint.is_builtin = true;
addSymbol(getint);
// 2. getfloat: float getfloat()
Symbol getfloat;
getfloat.name = "getfloat";
getfloat.kind = SymbolKind::Function;
getfloat.type = ir::Type::GetFunctionType(ir::Type::GetFloatType(), {});
getfloat.param_types = {};
getfloat.scope_level = 0;
getfloat.is_builtin = true;
addSymbol(getfloat);
// 3. getch: int getch()
Symbol getch;
getch.name = "getch";
getch.kind = SymbolKind::Function;
getch.type = ir::Type::GetFunctionType(ir::Type::GetInt32Type(), {});
getch.param_types = {};
getch.scope_level = 0;
getch.is_builtin = true;
addSymbol(getch);
// 4. putint: void putint(int)
std::vector<std::shared_ptr<ir::Type>> putint_params = { ir::Type::GetInt32Type() };
Symbol putint;
putint.name = "putint";
putint.kind = SymbolKind::Function;
putint.type = ir::Type::GetFunctionType(ir::Type::GetVoidType(), putint_params);
putint.param_types = putint_params;
putint.scope_level = 0;
putint.is_builtin = true;
addSymbol(putint);
// 5. putfloat: void putfloat(float)
std::vector<std::shared_ptr<ir::Type>> putfloat_params = { ir::Type::GetFloatType() };
Symbol putfloat;
putfloat.name = "putfloat";
putfloat.kind = SymbolKind::Function;
putfloat.type = ir::Type::GetFunctionType(ir::Type::GetVoidType(), putfloat_params);
putfloat.param_types = putfloat_params;
putfloat.scope_level = 0;
putfloat.is_builtin = true;
addSymbol(putfloat);
// 6. putch: void putch(int)
std::vector<std::shared_ptr<ir::Type>> putch_params = { ir::Type::GetInt32Type() };
Symbol putch;
putch.name = "putch";
putch.kind = SymbolKind::Function;
putch.type = ir::Type::GetFunctionType(ir::Type::GetVoidType(), putch_params);
putch.param_types = putch_params;
putch.scope_level = 0;
putch.is_builtin = true;
addSymbol(putch);
// 7. getarray: int getarray(int a[])
// 参数类型: int a[] 退化为 int* 即 PtrInt32
std::vector<std::shared_ptr<ir::Type>> getarray_params = { ir::Type::GetPtrInt32Type() };
Symbol getarray;
getarray.name = "getarray";
getarray.kind = SymbolKind::Function;
getarray.type = ir::Type::GetFunctionType(ir::Type::GetInt32Type(), getarray_params);
getarray.param_types = getarray_params;
getarray.scope_level = 0;
getarray.is_builtin = true;
addSymbol(getarray);
// 8. putarray: void putarray(int n, int a[])
// 参数: int n, int a[] -> 实际类型: int, int*
std::vector<std::shared_ptr<ir::Type>> putarray_params = { ir::Type::GetInt32Type(), ir::Type::GetPtrInt32Type() };
Symbol putarray;
putarray.name = "putarray";
putarray.kind = SymbolKind::Function;
putarray.type = ir::Type::GetFunctionType(ir::Type::GetVoidType(), putarray_params);
putarray.param_types = putarray_params;
putarray.scope_level = 0;
putarray.is_builtin = true;
addSymbol(putarray);
// starttime: void starttime()
Symbol starttime;
starttime.name = "starttime";
starttime.kind = SymbolKind::Function;
starttime.type = ir::Type::GetFunctionType(ir::Type::GetVoidType(), {}); // 无参数,返回 void
starttime.param_types = {};
starttime.scope_level = 0;
starttime.is_builtin = true;
addSymbol(starttime);
// stoptime: void stoptime()
Symbol stoptime;
stoptime.name = "stoptime";
stoptime.kind = SymbolKind::Function;
stoptime.type = ir::Type::GetFunctionType(ir::Type::GetVoidType(), {}); // 无参数,返回 void
stoptime.param_types = {};
stoptime.scope_level = 0;
stoptime.is_builtin = true;
addSymbol(stoptime);
// getfarray: int getfarray(float arr[])
std::vector<std::shared_ptr<ir::Type>> getfarray_params = { ir::Type::GetPtrFloatType() };
Symbol getfarray;
getfarray.name = "getfarray";
getfarray.kind = SymbolKind::Function;
getfarray.type = ir::Type::GetFunctionType(ir::Type::GetInt32Type(), getfarray_params);
getfarray.param_types = getfarray_params;
getfarray.scope_level = 0;
getfarray.is_builtin = true;
addSymbol(getfarray);
// putfarray: void putfarray(int len, float arr[])
std::vector<std::shared_ptr<ir::Type>> putfarray_params = {
ir::Type::GetInt32Type(),
ir::Type::GetPtrFloatType()
};
Symbol putfarray;
putfarray.name = "putfarray";
putfarray.kind = SymbolKind::Function;
putfarray.type = ir::Type::GetFunctionType(ir::Type::GetVoidType(), putfarray_params);
putfarray.param_types = putfarray_params;
putfarray.scope_level = 0;
putfarray.is_builtin = true;
addSymbol(putfarray);
}
// ==================== 常量表达式求值实现 ====================
static long long ParseIntegerLiteral(const std::string& text) {
// 处理前缀0x/0X 十六进制0 八进制,否则十进制
if (text.size() > 2 && (text[0] == '0' && (text[1] == 'x' || text[1] == 'X'))) {
return std::stoll(text.substr(2), nullptr, 16);
} else if (text.size() > 1 && text[0] == '0') {
return std::stoll(text, nullptr, 8);
} else {
return std::stoll(text, nullptr, 10);
}
}
static float ParseFloatLiteral(const std::string& text) {
return std::stof(text);
}
SymbolTable::ConstValue SymbolTable::EvaluatePrimaryExp(SysYParser::PrimaryExpContext* ctx) const {
if (!ctx) throw std::runtime_error("常量表达式求值:无效 PrimaryExp");
if (ctx->lVal()) {
auto lval = ctx->lVal();
if (!lval->Ident()) throw std::runtime_error("常量表达式求值:无效左值");
std::string name = lval->Ident()->getText();
DEBUG_MSG(" 左值标识符: " << name);
const Symbol* sym = lookup(name);
DEBUG_MSG(" 找到符号: kind=" << (int)sym->kind << ", value="
<< (sym->is_int_const ? std::to_string(sym->const_value.i32) : std::to_string(sym->const_value.f32)));
if (!sym) throw std::runtime_error("常量表达式求值:未定义的标识符 " + name);
if (sym->kind != SymbolKind::Constant)
throw std::runtime_error("常量表达式求值:标识符 " + name + " 不是常量");
ConstValue val;
if (sym->is_int_const) {
val.kind = ConstValue::INT;
val.int_val = sym->const_value.i32;
} else {
val.kind = ConstValue::FLOAT;
val.float_val = sym->const_value.f32;
}
return val;
}
else if (ctx->HEX_FLOAT() || ctx->DEC_FLOAT()) {
std::string text;
if (ctx->HEX_FLOAT()) text = ctx->HEX_FLOAT()->getText();
else text = ctx->DEC_FLOAT()->getText();
ConstValue val;
val.kind = ConstValue::FLOAT;
val.float_val = ParseFloatLiteral(text);
DEBUG_MSG(" 浮点字面量: " << text << " -> " << val.float_val);
return val;
}
else if (ctx->HEX_INT() || ctx->OCTAL_INT() || ctx->DECIMAL_INT() || ctx->ZERO()) {
std::string text;
if (ctx->HEX_INT()) text = ctx->HEX_INT()->getText();
else if (ctx->OCTAL_INT()) text = ctx->OCTAL_INT()->getText();
else if (ctx->DECIMAL_INT()) text = ctx->DECIMAL_INT()->getText();
else text = ctx->ZERO()->getText();
ConstValue val;
val.kind = ConstValue::INT;
val.int_val = static_cast<int>(ParseIntegerLiteral(text));
DEBUG_MSG(" 整数字面量: " << text << " -> " << val.int_val);
return val;
}
else if (ctx->exp()) {
return EvaluateAddExp(ctx->exp()->addExp());
}
else {
throw std::runtime_error("常量表达式求值:不支持的 PrimaryExp 类型");
}
}
SymbolTable::ConstValue SymbolTable::EvaluateUnaryExp(SysYParser::UnaryExpContext* ctx) const {
if (!ctx) throw std::runtime_error("常量表达式求值:无效 UnaryExp");
if (ctx->primaryExp()) {
return EvaluatePrimaryExp(ctx->primaryExp());
}
else if (ctx->unaryOp()) {
ConstValue operand = EvaluateUnaryExp(ctx->unaryExp());
std::string op = ctx->unaryOp()->getText();
DEBUG_MSG("EvaluateUnaryExp: 操作符=" << op);
DEBUG_MSG(" 操作数=" << (operand.kind==ConstValue::INT ? std::to_string(operand.int_val) : std::to_string(operand.float_val)));
if (op == "+") {
return operand;
}
else if (op == "-") {
if (operand.kind == ConstValue::INT) {
operand.int_val = -operand.int_val;
} else {
operand.float_val = -operand.float_val;
}
return operand;
}
else if (op == "!") {
if (operand.kind != ConstValue::INT) {
throw std::runtime_error("常量表达式求值:逻辑非操作数必须是整数");
}
ConstValue res;
res.kind = ConstValue::INT;
res.int_val = (operand.int_val == 0) ? 1 : 0;
return res;
}
else {
throw std::runtime_error("常量表达式求值:未知一元运算符 " + op);
}
}
else {
// 函数调用在常量表达式中不允许
throw std::runtime_error("常量表达式求值:不允许函数调用");
}
}
SymbolTable::ConstValue SymbolTable::EvaluateMulExp(SysYParser::MulExpContext* ctx) const {
if (!ctx) throw std::runtime_error("常量表达式求值:无效 MulExp");
if (ctx->mulExp()) {
DEBUG_MSG("EvaluateMulExp: 左子表达式");
ConstValue left = EvaluateMulExp(ctx->mulExp());
DEBUG_MSG(" 左值=" << (left.kind==ConstValue::INT ? std::to_string(left.int_val) : std::to_string(left.float_val)));
ConstValue right = EvaluateUnaryExp(ctx->unaryExp());
std::string op;
DEBUG_MSG(" 运算符=" << op);
DEBUG_MSG(" 右值=" << (right.kind==ConstValue::INT ? std::to_string(right.int_val) : std::to_string(right.float_val)));
if (ctx->MulOp()) op = "*";
else if (ctx->DivOp()) op = "/";
else if (ctx->QuoOp()) op = "%";
else throw std::runtime_error("常量表达式求值:未知乘法运算符");
bool is_float = (left.kind == ConstValue::FLOAT || right.kind == ConstValue::FLOAT);
if (is_float) {
float l = (left.kind == ConstValue::INT) ? static_cast<float>(left.int_val) : left.float_val;
float r = (right.kind == ConstValue::INT) ? static_cast<float>(right.int_val) : right.float_val;
ConstValue res;
res.kind = ConstValue::FLOAT;
if (op == "*") res.float_val = l * r;
else if (op == "/") res.float_val = l / r;
else if (op == "%") throw std::runtime_error("常量表达式求值:浮点数不支持取模运算");
return res;
} else {
int l = left.int_val;
int r = right.int_val;
ConstValue res;
res.kind = ConstValue::INT;
if (op == "*") res.int_val = l * r;
else if (op == "/") {
if (r == 0) throw std::runtime_error("常量表达式求值:除零错误");
res.int_val = l / r;
}
else if (op == "%") {
if (r == 0) throw std::runtime_error("常量表达式求值:模零错误");
res.int_val = l % r;
}
return res;
}
}
else {
return EvaluateUnaryExp(ctx->unaryExp());
}
}
SymbolTable::ConstValue SymbolTable::EvaluateAddExp(SysYParser::AddExpContext* ctx) const {
if (!ctx) throw std::runtime_error("常量表达式求值:无效 AddExp");
if (ctx->addExp()) {
ConstValue left = EvaluateAddExp(ctx->addExp());
ConstValue right = EvaluateMulExp(ctx->mulExp());
std::string op;
if (ctx->AddOp()) op = "+";
else if (ctx->SubOp()) op = "-";
else throw std::runtime_error("常量表达式求值:未知加法运算符");
bool is_float = (left.kind == ConstValue::FLOAT || right.kind == ConstValue::FLOAT);
if (is_float) {
float l = (left.kind == ConstValue::INT) ? static_cast<float>(left.int_val) : left.float_val;
float r = (right.kind == ConstValue::INT) ? static_cast<float>(right.int_val) : right.float_val;
ConstValue res;
res.kind = ConstValue::FLOAT;
if (op == "+") res.float_val = l + r;
else res.float_val = l - r;
return res;
} else {
int l = left.int_val;
int r = right.int_val;
ConstValue res;
res.kind = ConstValue::INT;
if (op == "+") res.int_val = l + r;
else res.int_val = l - r;
return res;
}
}
else {
return EvaluateMulExp(ctx->mulExp());
}
}
int SymbolTable::EvaluateConstExp(SysYParser::ConstExpContext* ctx) const {
if (!ctx || !ctx->addExp())
throw std::runtime_error("常量表达式求值:无效 ConstExp");
DEBUG_MSG("EvaluateConstExp: 表达式文本=" << ctx->getText());
ConstValue val = EvaluateAddExp(ctx->addExp());
DEBUG_MSG(" 求值结果: " << (val.kind==ConstValue::INT ? std::to_string(val.int_val) : std::to_string(val.float_val)));
if (val.kind == ConstValue::INT) {
return val.int_val;
} else {
float f = val.float_val;
int i = static_cast<int>(f);
if (std::abs(f - i) > 1e-6) {
throw std::runtime_error("常量表达式求值:浮点常量不能隐式转换为整数");
}
return i;
}
}
float SymbolTable::EvaluateConstExpFloat(SysYParser::ConstExpContext* ctx) const {
if (!ctx || !ctx->addExp())
throw std::runtime_error("常量表达式求值:无效 ConstExp");
DEBUG_MSG("EvaluateConstExpFloat: 表达式文本=" << ctx->getText());
ConstValue val = EvaluateAddExp(ctx->addExp());
DEBUG_MSG(" 求值结果: " << (val.kind==ConstValue::INT ? std::to_string(val.int_val) : std::to_string(val.float_val)));
if (val.kind == ConstValue::INT) {
return static_cast<float>(val.int_val);
} else {
return val.float_val;
}
}
// 递归填充函数,按维度填充值
void SymbolTable::fillArray(
std::vector<ConstValue>& values, // 存储最终所有元素(行优先)
size_t& index, // 当前填充到的位置
SysYParser::ConstInitValContext* ctx, // 当前初始化列表节点
const std::vector<int>& dims, // 剩余维度
size_t dim_idx, // 当前维度索引
std::shared_ptr<ir::Type> base_type) const // 元素基本类型
{
DEBUG_MSG("fillArray: 进入dim_idx=" << dim_idx
<< ", 剩余维度=" << (dims.size() - dim_idx)
<< ", 当前index=" << index);
// 如果已经是最内层(单个元素)
if (dim_idx == dims.size()) {
// 必须是单个表达式
if (!ctx || !ctx->constExp()) {
throw std::runtime_error("初始化值不是标量");
}
ConstValue val = EvaluateAddExp(ctx->constExp()->addExp());
// 类型检查和转换...
DEBUG_MSG(" 填充标量值: index=" << index
<< ", 值=" << (val.kind == ConstValue::INT ? std::to_string(val.int_val) : std::to_string(val.float_val)));
values[index++] = val;
return;
}
// 当前维度的元素个数
size_t cur_dim_size = dims[dim_idx];
DEBUG_MSG(" 当前维度大小=" << cur_dim_size << ", 是否是花括号列表=" << (ctx && !ctx->constExp()));
// 如果是花括号列表,则按子项填充
if (ctx && !ctx->constExp()) { // 花括号
auto sub_vals = ctx->constInitVal();
DEBUG_MSG(" 花括号列表,子项数量=" << sub_vals.size());
// 对于每个子项,填充一个子数组
for (size_t i = 0; i < cur_dim_size; ++i) {
DEBUG_MSG(" 处理子项 " << i << " / " << cur_dim_size);
if (i < sub_vals.size()) {
fillArray(values, index, sub_vals[i], dims, dim_idx + 1, base_type);
} else {
// 子项不足,填充零
DEBUG_MSG(" 子项不足,填充零");
fillZero(values, index, dims, dim_idx + 1, base_type);
}
}
} else {
// 不是花括号,即单个值,应视为对当前维度第一个元素的初始化,其余补零
// 第一个子数组
DEBUG_MSG(" 单个值(非花括号),将填充第一个子数组,其余补零");
if (ctx && ctx->constExp()) {
fillArray(values, index, ctx, dims, dim_idx + 1, base_type);
} else {
DEBUG_MSG(" 无初始化值,第一个子数组也补零");
fillZero(values, index, dims, dim_idx + 1, base_type);
}
// 剩余子数组补零
for (size_t i = 1; i < cur_dim_size; ++i) {
DEBUG_MSG(" 填充第" << i << "个子数组为零");
fillZero(values, index, dims, dim_idx + 1, base_type);
}
}
DEBUG_MSG("fillArray: 退出index=" << index);
}
// 填充指定数量的零
void SymbolTable::fillZero(std::vector<ConstValue>& values, size_t& index,
const std::vector<int>& dims, size_t dim_idx,
std::shared_ptr<ir::Type> base_type) const
{
DEBUG_MSG("fillZero: 进入dim_idx=" << dim_idx << ", 当前index=" << index);
if (dim_idx == dims.size()) {
ConstValue zero;
if (base_type->IsInt32()) {
zero.kind = ConstValue::INT;
zero.int_val = 0;
} else {
zero.kind = ConstValue::FLOAT;
zero.float_val = 0.0f;
}
DEBUG_MSG(" 填充零值: index=" << index);
values[index++] = zero;
return;
}
size_t cur_dim_size = dims[dim_idx];
DEBUG_MSG(" fillZero 当前维度大小=" << cur_dim_size);
for (size_t i = 0; i < cur_dim_size; ++i) {
DEBUG_MSG(" fillZero 子项 " << i);
fillZero(values, index, dims, dim_idx + 1, base_type);
}
DEBUG_MSG("fillZero: 退出");
}
std::vector<SymbolTable::ConstValue> SymbolTable::EvaluateConstInitVal(
SysYParser::ConstInitValContext* ctx,
const std::vector<int>& dims,
std::shared_ptr<ir::Type> base_type) const {
// ========== 1. 标量常量dims 为空)==========
if (dims.empty()) {
DEBUG_MSG(" 标量常量初始化,表达式=" << ctx->getText());
if (!ctx || !ctx->constExp()) {
throw std::runtime_error("标量常量初始化必须使用单个表达式");
}
ConstValue val = EvaluateAddExp(ctx->constExp()->addExp());
// 类型兼容性检查
/*
if (base_type->IsInt32() && val.kind == ConstValue::FLOAT) {
throw std::runtime_error("整型常量不能使用浮点常量初始化");
}
*/
// 隐式类型转换
if (base_type->IsInt32() && val.kind == ConstValue::FLOAT) {
val.kind = ConstValue::INT;
val.float_val = static_cast<int>(val.int_val);
}
if (base_type->IsFloat() && val.kind == ConstValue::INT) {
val.kind = ConstValue::FLOAT;
val.float_val = static_cast<float>(val.int_val);
}
return {val}; // 返回包含单个值的向量
}
// ========== 2. 数组常量dims 非空)==========
// 计算数组总元素个数
DEBUG_MSG("EvaluateConstInitVal: 开始,维度=" << dims.size());
size_t total = 1;
for (int d : dims) total *= d;
DEBUG_MSG(" 数组常量初始化,总元素数=" << total);
std::vector<ConstValue> values(total);
size_t index = 0;
fillArray(values, index, ctx, dims, 0, base_type);
DEBUG_MSG("EvaluateConstInitVal: 填充完成最终index=" << index);
// 可选:打印所有填充的值
for (size_t i = 0; i < values.size(); ++i) {
DEBUG_MSG(" values[" << i << "] = " << (values[i].kind == ConstValue::INT ? std::to_string(values[i].int_val) : std::to_string(values[i].float_val)));
}
return values;
}
int SymbolTable::EvaluateConstExpression(SysYParser::ExpContext* ctx) const {
if (!ctx || !ctx->addExp()) {
throw std::runtime_error("常量表达式求值:无效 ExpContext");
}
ConstValue val = EvaluateAddExp(ctx->addExp());
if (val.kind == ConstValue::INT) {
return val.int_val;
} else {
float f = val.float_val;
int i = static_cast<int>(f);
if (std::abs(f - i) > 1e-6) {
throw std::runtime_error("常量表达式求值:浮点常量不能隐式转换为整数");
}
return i;
}
}

@ -0,0 +1 @@
int main() { return 0; }

@ -0,0 +1 @@
int main() { return 0; }

@ -0,0 +1 @@
int add(int a, int b) { return a + b; } int main() { return add(1, 2); }
Loading…
Cancel
Save