IRGen,IR fit our antrl4,full make passed

LuoHello 3 weeks ago
parent 56753bc842
commit 310c93feac

@ -41,6 +41,8 @@
namespace ir {
class Type;
class ArrayType;
class FunctionType;
class Value;
class User;
class ConstantValue;
@ -93,23 +95,85 @@ class Context {
class Type {
public:
enum class Kind { Void, Int32, PtrInt32 };
explicit Type(Kind k);
enum class Kind { Void, Int32, Float, PtrInt32, PtrFloat, Label, Array, Function };
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);
// 类型判断
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; }
// 类型属性
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);

@ -24,18 +24,29 @@ class IRGenImpl final : public SysYBaseVisitor {
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;
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;
// 语句
std::any visitStmt(SysYParser::StmtContext* ctx) override;
// 表达式
std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override;
std::any visitLVal(SysYParser::LValContext* ctx) override;
std::any visitAddExp(SysYParser::AddExpContext* ctx) override;
std::any visitMulExp(SysYParser::MulExpContext* ctx) override;
std::any visitRelExp(SysYParser::RelExpContext* ctx) override;
std::any visitEqExp(SysYParser::EqExpContext* ctx) override;
std::any visitCond(SysYParser::CondContext* ctx) override;
private:
enum class BlockFlow {
@ -45,6 +56,15 @@ class IRGenImpl final : public SysYBaseVisitor {
BlockFlow VisitBlockItemResult(SysYParser::BlockItemContext& item);
ir::Value* EvalExpr(SysYParser::ExpContext& expr);
ir::Value* EvalCond(SysYParser::CondContext& cond);
// 辅助函数
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);
ir::Module& module_;
const SemanticContext& sema_;
@ -52,6 +72,14 @@ class IRGenImpl final : public SysYBaseVisitor {
ir::IRBuilder builder_;
// 名称绑定由 Sema 负责IRGen 只维护“声明 -> 存储槽位”的代码生成状态。
std::unordered_map<SysYParser::VarDefContext*, ir::Value*> storage_map_;
// 循环栈,用于 break/continue
struct LoopContext {
ir::BasicBlock* condBlock;
ir::BasicBlock* bodyBlock;
ir::BasicBlock* exitBlock;
};
std::vector<LoopContext> loopStack_;
};
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,

@ -2,29 +2,83 @@
#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 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_;
};
// 目前仅检查:
// - 变量先声明后使用
// - 局部变量不允许重复定义
SemanticContext RunSema(SysYParser::CompUnitContext& comp_unit);
SemanticContext RunSema(SysYParser::CompUnitContext& comp_unit);

@ -3,15 +3,74 @@
#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<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::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); // 仅在当前作用域查找
// ----- 与原接口兼容(保留原有功能)-----
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> getTypeFromVarDef(SysYParser::VarDefContext* ctx);
static std::shared_ptr<ir::Type> getTypeFromFuncDef(SysYParser::FuncDefContext* ctx);
void registerBuiltinFunctions();
private:
// 作用域栈:每个元素是一个从名字到符号的映射
std::vector<std::unordered_map<std::string, Symbol>> scopes_;
private:
std::unordered_map<std::string, SysYParser::VarDefContext*> table_;
static constexpr int GLOBAL_SCOPE = 0; // 全局作用域索引
};

@ -14,12 +14,15 @@ 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";
default: return "unknown";
}
throw std::runtime_error(FormatError("ir", "未知类型"));
}

@ -1,31 +1,208 @@
// 当前仅支持 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;
}
// ---------- 数组类型缓存 ----------
// 使用自定义键类型保证唯一性:元素类型指针 + 维度向量
struct ArrayKey {
const Type* elem_type;
std::vector<int> dims;
bool operator==(const ArrayKey& other) const {
return elem_type == other.elem_type && dims == other.dims;
}
};
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;
}
bool Type::IsVoid() const { return kind_ == Kind::Void; }
auto func = std::shared_ptr<FunctionType>(new FunctionType(std::move(ret), std::move(params)));
cache[key] = func;
return func;
}
bool Type::IsInt32() const { return kind_ == Kind::Int32; }
// ---------- 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();
}
bool Type::IsPtrInt32() const { return kind_ == Kind::PtrInt32; }
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

@ -8,100 +8,76 @@
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();
}
} // namespace
std::any IRGenImpl::visitBlockStmt(SysYParser::BlockStmtContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少语句块"));
}
for (auto* item : ctx->blockItem()) {
if (item) {
if (VisitBlockItemResult(*item) == BlockFlow::Terminated) {
// 当前语法要求 return 为块内最后一条语句;命中后可停止生成。
break;
}
}
}
return {};
}
// 注意visitBlock 已经在 IRGenFunc.cpp 中实现,这里不要重复定义
IRGenImpl::BlockFlow IRGenImpl::VisitBlockItemResult(
SysYParser::BlockItemContext& item) {
return std::any_cast<BlockFlow>(item.accept(this));
}
std::any IRGenImpl::visitBlockItem(SysYParser::BlockItemContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少块内项"));
}
if (ctx->decl()) {
ctx->decl()->accept(this);
return BlockFlow::Continue;
}
if (ctx->stmt()) {
return ctx->stmt()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "暂不支持的语句或声明"));
}
// 变量声明的 IR 生成目前也是最小实现:
// - 先检查声明的基础类型,当前仅支持局部 int
// - 再把 Decl 中的变量定义交给 visitVarDef 继续处理。
//
// 和更完整的版本相比,这里还没有:
// - 一个 Decl 中多个变量定义的顺序处理;
// - const、数组、全局变量等不同声明形态
// - 更丰富的类型系统。
std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少变量声明"));
}
if (!ctx->btype() || !ctx->btype()->INT()) {
throw std::runtime_error(FormatError("irgen", "当前仅支持局部 int 变量声明"));
// 处理 varDecl
if (auto* varDecl = ctx->varDecl()) {
// 检查类型
if (varDecl->bType() && varDecl->bType()->Int()) {
for (auto* varDef : varDecl->varDef()) {
varDef->accept(this);
}
} else {
throw std::runtime_error(FormatError("irgen", "当前仅支持 int 类型变量"));
}
}
auto* var_def = ctx->varDef();
if (!var_def) {
throw std::runtime_error(FormatError("irgen", "非法变量声明"));
// 处理 constDecl暂不支持
if (ctx->constDecl()) {
throw std::runtime_error(FormatError("irgen", "常量声明暂未实现"));
}
var_def->accept(this);
return {};
}
// 当前仍是教学用的最小版本,因此这里只支持:
// - 局部 int 变量;
// - 标量初始化;
// - 一个 VarDef 对应一个槽位。
std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少变量定义"));
}
if (!ctx->lValue()) {
// 使用 Ident() 而不是 lValue()
if (!ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "变量声明缺少名称"));
}
GetLValueName(*ctx->lValue());
std::string varName = ctx->Ident()->getText();
if (storage_map_.find(ctx) != storage_map_.end()) {
throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位"));
throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位: " + varName));
}
// 分配存储
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", "当前不支持聚合初始化"));
// 使用 initVal() 而不是 initValue()
if (auto* initVal = ctx->initVal()) {
if (initVal->exp()) {
init = EvalExpr(*initVal->exp());
} else {
// 数组初始化暂不支持
init = builder_.CreateConstInt(0);
}
init = EvalExpr(*init_value->exp());
} else {
init = builder_.CreateConstInt(0);
}
builder_.CreateStore(init, slot);
return {};
}

@ -20,61 +20,183 @@
// - 数组、指针、下标访问
// - 条件与比较表达式
// - ...
ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) {
return std::any_cast<ir::Value*>(expr.accept(this));
}
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) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少基本表达式"));
}
return static_cast<ir::Value*>(
builder_.CreateConstInt(std::stoi(ctx->number()->getText())));
// 处理数字字面量
if (ctx->DECIMAL_INT()) {
int value = std::stoi(ctx->DECIMAL_INT()->getText());
return static_cast<ir::Value*>(builder_.CreateConstInt(value));
}
if (ctx->HEX_INT()) {
std::string hex = ctx->HEX_INT()->getText();
int value = std::stoi(hex, nullptr, 16);
return static_cast<ir::Value*>(builder_.CreateConstInt(value));
}
if (ctx->OCTAL_INT()) {
std::string oct = ctx->OCTAL_INT()->getText();
int value = std::stoi(oct, nullptr, 8);
return static_cast<ir::Value*>(builder_.CreateConstInt(value));
}
if (ctx->ZERO()) {
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
}
// 处理变量
if (ctx->lVal()) {
return ctx->lVal()->accept(this);
}
// 处理括号表达式
if (ctx->L_PAREN() && ctx->exp()) {
return EvalExpr(*ctx->exp());
}
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());
std::string varName = ctx->Ident()->getText();
// 从语义分析获取变量定义
auto* decl = sema_.ResolveVarUse(ctx);
if (!decl) {
throw std::runtime_error(
FormatError("irgen",
"变量使用缺少语义绑定: " + ctx->var()->ID()->getText()));
"变量使用缺少语义绑定: " + varName));
}
auto it = storage_map_.find(decl);
if (it == storage_map_.end()) {
throw std::runtime_error(
FormatError("irgen",
"变量声明缺少存储槽位: " + ctx->var()->ID()->getText()));
"变量声明缺少存储槽位: " + varName));
}
return static_cast<ir::Value*>(
builder_.CreateLoad(it->second, 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) {
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()));
// 注意mulExp() 返回的是 MulExpContext*,不是 vector
// 需要递归处理 AddExp 的左结合性
// AddExp : MulExp | AddExp ('+' | '-') MulExp
// 先处理左操作数
ir::Value* result = nullptr;
// 如果有左子节点AddExp递归处理
if (ctx->addExp()) {
result = std::any_cast<ir::Value*>(ctx->addExp()->accept(this));
} else {
// 否则是 MulExp
result = std::any_cast<ir::Value*>(ctx->mulExp()->accept(this));
}
// 如果有运算符和右操作数
if (ctx->AddOp() || ctx->SubOp()) {
ir::Value* rhs = std::any_cast<ir::Value*>(ctx->mulExp()->accept(this));
if (ctx->AddOp()) {
result = builder_.CreateAdd(result, rhs, module_.GetContext().NextTemp());
} else if (ctx->SubOp()) {
// 减法a - b = a + (-b)
// 暂时用加法,后续需要实现真正的减法
result = builder_.CreateAdd(result, rhs, module_.GetContext().NextTemp());
}
}
return static_cast<ir::Value*>(result);
}
// 在 IRGenExp.cpp 中添加
// 简化版 visitMulExp
std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
}
// 暂时只返回 unaryExp 的值
if (ctx->unaryExp()) {
return ctx->unaryExp()->accept(this);
}
// 如果有 mulExp 子节点,递归处理
if (ctx->mulExp()) {
return ctx->mulExp()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "乘法表达式暂未实现"));
}
// 关系表达式(暂未完整实现)
std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
}
// 简化:返回 addExp 的值
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", "非法相等表达式"));
}
// 简化:返回 relExp 的值
if (ctx->relExp()) {
return ctx->relExp()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "相等表达式暂未实现"));
}
// 条件表达式
std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法条件表达式"));
}
// 简化:返回 lOrExp 的值
if (ctx->lOrExp()) {
return ctx->lOrExp()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "条件表达式暂未实现"));
}

@ -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(
@ -27,61 +28,105 @@ IRGenImpl::IRGenImpl(ir::Module& module, const SemanticContext& sema)
func_(nullptr),
builder_(module.GetContext(), nullptr) {}
// 编译单元的 IR 生成当前只实现了最小功能:
// - Module 已在 GenerateIR 中创建,这里只负责继续生成其中的内容;
// - 当前会读取编译单元中的函数定义,并交给 visitFuncDef 生成函数 IR
//
// 当前还没有实现:
// - 多个函数定义的遍历与生成;
// - 全局变量、全局常量的 IR 生成。
// 修正:没有 mainFuncDef通过函数名找到 main
std::any IRGenImpl::visitCompUnit(SysYParser::CompUnitContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少编译单元"));
}
auto* func = ctx->funcDef();
if (!func) {
throw std::runtime_error(FormatError("irgen", "缺少函数定义"));
// 获取所有函数定义
auto funcDefs = ctx->funcDef();
// 找到 main 函数
SysYParser::FuncDefContext* mainFunc = nullptr;
for (auto* funcDef : funcDefs) {
if (funcDef->Ident() && funcDef->Ident()->getText() == "main") {
mainFunc = funcDef;
break;
}
}
func->accept(this);
if (!mainFunc) {
throw std::runtime_error(FormatError("irgen", "缺少main函数"));
}
// 生成 main 函数
mainFunc->accept(this);
return {};
}
// 函数 IR 生成当前实现了:
// 1. 获取函数名;
// 2. 检查函数返回类型;
// 3. 在 Module 中创建 Function
// 4. 将 builder 插入点设置到入口基本块;
// 5. 继续生成函数体。
//
// 当前还没有实现:
// - 通用函数返回类型处理;
// - 形参列表遍历与参数类型收集;
// - FunctionType 这样的函数类型对象;
// - Argument/形式参数 IR 对象;
// - 入口块中的参数初始化逻辑。
// ...
// 因此这里目前只支持最小的“无参 int 函数”生成。
std::any IRGenImpl::visitFuncDef(SysYParser::FuncDefContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少函数定义"));
}
if (!ctx->blockStmt()) {
throw std::runtime_error(FormatError("irgen", "函数体为空"));
}
if (!ctx->ID()) {
// 使用 Ident() 而不是 ID()
if (!ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "缺少函数名"));
}
if (!ctx->funcType() || !ctx->funcType()->INT()) {
throw std::runtime_error(FormatError("irgen", "当前仅支持无参 int 函数"));
std::string funcName = ctx->Ident()->getText();
// 检查函数体 - 使用 block() 而不是 blockStmt()
if (!ctx->block()) {
throw std::runtime_error(FormatError("irgen", "函数体为空"));
}
func_ = module_.CreateFunction(ctx->ID()->getText(), ir::Type::GetInt32Type());
// 检查返回类型 - 使用 Int() 而不是 INT()
if (!ctx->funcType() || !ctx->funcType()->Int()) {
throw std::runtime_error(FormatError("irgen", "当前仅支持int函数"));
}
// 创建函数
func_ = module_.CreateFunction(funcName, ir::Type::GetInt32Type());
builder_.SetInsertPoint(func_->GetEntry());
storage_map_.clear();
ctx->blockStmt()->accept(this);
// 语义正确性主要由 sema 保证,这里只兜底检查 IR 结构是否合法。
// 生成函数体 - 使用 block() 而不是 blockStmt()
ctx->block()->accept(this);
// 确保函数有返回值
if (!func_->GetEntry()->HasTerminator()) {
auto retVal = builder_.CreateConstInt(0);
builder_.CreateRet(retVal);
}
VerifyFunctionStructure(*func_);
return {};
}
std::any IRGenImpl::visitBlock(SysYParser::BlockContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少语句块"));
}
for (auto* item : ctx->blockItem()) {
if (item) {
if (VisitBlockItemResult(*item) == BlockFlow::Terminated) {
break;
}
}
}
return {};
}
IRGenImpl::BlockFlow IRGenImpl::VisitBlockItemResult(
SysYParser::BlockItemContext& item) {
return std::any_cast<BlockFlow>(item.accept(this));
}
std::any IRGenImpl::visitBlockItem(SysYParser::BlockItemContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少块内项"));
}
if (ctx->stmt()) {
return ctx->stmt()->accept(this);
}
if (ctx->decl()) {
ctx->decl()->accept(this);
return BlockFlow::Continue;
}
throw std::runtime_error(FormatError("irgen", "暂不支持的块内项"));
}

@ -19,21 +19,70 @@ std::any IRGenImpl::visitStmt(SysYParser::StmtContext* ctx) {
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->block()) {
return ctx->block()->accept(this);
}
// 空语句或表达式语句(先计算表达式)
if (ctx->exp()) {
EvalExpr(*ctx->exp());
return BlockFlow::Continue;
}
throw std::runtime_error(FormatError("irgen", "暂不支持的语句类型"));
}
std::any IRGenImpl::visitReturnStmt(SysYParser::ReturnStmtContext* ctx) {
IRGenImpl::BlockFlow IRGenImpl::HandleReturnStmt(SysYParser::StmtContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少 return 语句"));
}
if (!ctx->exp()) {
throw std::runtime_error(FormatError("irgen", "return 缺少表达式"));
ir::Value* retValue = nullptr;
if (ctx->exp()) {
retValue = EvalExpr(*ctx->exp());
}
// 如果没有表达式返回0对于int main
if (!retValue) {
retValue = builder_.CreateConstInt(0);
}
ir::Value* v = EvalExpr(*ctx->exp());
builder_.CreateRet(v);
builder_.CreateRet(retValue);
return BlockFlow::Terminated;
}
// if语句待实现
IRGenImpl::BlockFlow IRGenImpl::HandleIfStmt(SysYParser::StmtContext* ctx) {
// TODO: 实现if语句
throw std::runtime_error(FormatError("irgen", "if语句暂未实现"));
}
// while语句待实现
IRGenImpl::BlockFlow IRGenImpl::HandleWhileStmt(SysYParser::StmtContext* ctx) {
// TODO: 实现while语句
throw std::runtime_error(FormatError("irgen", "while语句暂未实现"));
}
// break语句待实现
IRGenImpl::BlockFlow IRGenImpl::HandleBreakStmt(SysYParser::StmtContext* ctx) {
// TODO: 实现break
throw std::runtime_error(FormatError("irgen", "break语句暂未实现"));
}
// continue语句待实现
IRGenImpl::BlockFlow IRGenImpl::HandleContinueStmt(SysYParser::StmtContext* ctx) {
// TODO: 实现continue
throw std::runtime_error(FormatError("irgen", "continue语句暂未实现"));
}
// 赋值语句(待实现)
IRGenImpl::BlockFlow IRGenImpl::HandleAssignStmt(SysYParser::StmtContext* ctx) {
// TODO: 实现赋值
throw std::runtime_error(FormatError("irgen", "赋值语句暂未实现"));
}

File diff suppressed because it is too large Load Diff

@ -1,17 +1,338 @@
// 维护局部变量声明的注册与查找。
#include "sem/SymbolTable.h"
#include <antlr4-runtime.h> // 用于访问父节点
// ---------- 构造函数 ----------
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;
return true;
}
Symbol* SymbolTable::lookup(const std::string& name) {
// 从当前作用域向外层查找
for (auto it = scopes_.rbegin(); it != scopes_.rend(); ++it) {
auto& scope = *it;
auto found = scope.find(name);
if (found != scope.end()) {
return &found->second;
}
}
return nullptr;
}
void SymbolTable::Add(const std::string& name,
SysYParser::VarDefContext* decl) {
table_[name] = decl;
Symbol* SymbolTable::lookupCurrent(const std::string& name) {
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) {
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;
}
// 常量表达式求值(占位,需实现真正的常量折叠)
static int evaluateConstExp(SysYParser::ConstExpContext* ctx) {
// TODO: 实现常量折叠目前返回0
return 0;
}
// 从 VarDefContext 构造类型
std::shared_ptr<ir::Type> SymbolTable::getTypeFromVarDef(SysYParser::VarDefContext* ctx) {
// 1. 获取基本类型int/float
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(); // 默认 int
}
// 2. 解析数组维度(从 varDef 的 constExp 列表获取)
std::vector<int> dims;
for (auto constExp : ctx->constExp()) {
int dimVal = evaluateConstExp(constExp);
dims.push_back(dimVal);
}
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);
}
Loading…
Cancel
Save