feat(ast): 重构AST转储功能并创建AST到IR转换器

- 重构ast_dump.c中的宏定义,简化PRINT_VALUE、PRINT_NODE、
  PRINT_QUOTED_VALUE等宏的实现
- 移除冗余的PRINT_COLORED宏定义
- 统一使用SCC_TREE_DUMP_PRINT_PURE和SCC_TREE_DUMP_PRINT_AROUND
  宏进行转储输出
- 在dump_stmt_impl函数中优化节点转储逻辑,统一使用end_node_dump
  替代手动换行
- 添加对未知节点类型的警告日志输出
- 创建新的ast2ir模块,包含AST到IR的基本转换功能
- 实现ast_type_to_ir_type、ast_expr_to_ir、ast_stmt_to_ir、
  ast_decl_to_ir等核心转换函数
- 更新IR库依赖配置,添加scc_utils和tree_dump依赖
- 新增IR基础接口定义文件ir_base.h和IR构建器接口ir_builder.h
This commit is contained in:
zzy
2026-01-30 23:01:55 +08:00
parent c8bf98525d
commit 2a90e165a5
17 changed files with 2341 additions and 172 deletions

351
libs/ir/src/ir_builder.c Normal file
View File

@@ -0,0 +1,351 @@
#include <ir_builder.h>
#include <ir_builtin.h>
void scc_ir_builder_init(scc_ir_builder_t *builder) {
builder->current_bblock = SCC_IR_REF_NULL;
builder->current_func = SCC_IR_REF_NULL;
scc_ir_cprog_init(&builder->cprog);
scc_ir_ctx_init(&builder->ctx);
}
void scc_ir_builder_drop(scc_ir_builder_t *builder) {
scc_ir_cprog_drop(&builder->cprog);
scc_ir_ctx_drop(&builder->ctx);
}
scc_ir_func_ref_t scc_ir_builder_begin_func(scc_ir_builder_t *builder,
const char *name,
scc_ir_type_ref_t type,
const char **param_names) {
scc_ir_func_t func = {0};
// 初始化参数和基本块向量
func.name = name;
func.type = type;
scc_vec_init(func.params);
scc_vec_init(func.bblocks);
// 创建函数并设置为当前函数
scc_ir_func_ref_t func_ref = scc_ir_ctx_new_func(&builder->ctx, &func);
builder->current_func = func_ref;
// 如果提供了参数名称,则创建参数节点
if (param_names == null) {
return func_ref;
}
scc_ir_func_t *func_ptr = scc_ir_ctx_get_func(&builder->ctx, func_ref);
scc_ir_type_t *func_type = scc_ir_ctx_get_type(&builder->ctx, type);
if (func_type == null || func_type->tag != SCC_IR_TYPE_FUNC) {
LOG_ERROR("Invalid function type");
return func_ref;
}
scc_vec_foreach(func_type->data.function.params, i) {
scc_ir_type_ref_t param_type =
scc_vec_at(func_type->data.function.params, i);
scc_ir_node_t param_node = {0};
param_node.tag = SCC_IR_NODE_NULL; // 参数节点标记
param_node.type = param_type;
param_node.name = param_names[i];
scc_vec_init(param_node.used_by);
scc_ir_node_ref_t param_ref =
scc_ir_ctx_new_node(&builder->ctx, &param_node);
scc_vec_push(func_ptr->params, param_ref);
}
return func_ref;
}
void scc_ir_builder_end_func(scc_ir_builder_t *builder) {
scc_ir_func_t *func_ptr =
scc_ir_ctx_get_func(&builder->ctx, builder->current_func);
if (func_ptr == null) {
LOG_FATAL("Invalid function reference");
return;
}
if (scc_vec_size(func_ptr->bblocks) == 0) {
scc_vec_push(builder->cprog.func_decls, builder->current_func);
} else {
scc_vec_push(builder->cprog.func_defs, builder->current_func);
}
builder->current_func = 0;
}
scc_ir_func_ref_t scc_ir_builder_current_func(scc_ir_builder_t *builder) {
return builder->current_func;
}
scc_ir_bblock_ref_t scc_ir_builder_begin_bblock(scc_ir_builder_t *builder,
const char *label) {
scc_ir_bblock_t bblock = {0};
if (label) {
bblock.label = label;
} else {
// TODO 自动生成标签
char *auto_label = scc_malloc(sizeof(char) * 64);
if (auto_label)
LOG_FATAL("allocate memory failed");
static int auto_counter = 0;
scc_snprintf(auto_label, sizeof(auto_label), ".BB%d", auto_counter++);
bblock.label = auto_label;
}
scc_vec_init(bblock.instrs);
scc_ir_bblock_ref_t bblock_ref =
scc_ir_ctx_new_bblock(&builder->ctx, &bblock);
builder->current_bblock = bblock_ref;
// 将基本块添加到当前函数
scc_ir_func_t *current_func =
scc_ir_ctx_get_func(&builder->ctx, builder->current_func);
if (current_func) {
scc_vec_push(current_func->bblocks, bblock_ref);
}
return bblock_ref;
}
void scc_ir_builder_end_bblock(scc_ir_builder_t *builder) {
builder->current_bblock = 0;
}
void scc_ir_builder_set_current_bblock(scc_ir_builder_t *builder,
scc_ir_bblock_ref_t bblock) {
builder->current_bblock = bblock;
}
static void scc_ir_builder_add_instr(scc_ir_builder_t *builder,
scc_ir_node_ref_t node) {
scc_ir_bblock_t *current_bblock =
scc_ir_ctx_get_bblock(&builder->ctx, builder->current_bblock);
if (current_bblock) {
scc_vec_push(current_bblock->instrs, node);
} else {
LOG_ERROR("Current basic block is not set");
}
}
scc_ir_node_ref_t scc_ir_builder_alloca(scc_ir_builder_t *builder,
scc_ir_type_ref_t type,
const char *name) {
scc_ir_node_t alloc_node = {0};
alloc_node.tag = SCC_IR_NODE_ALLOC;
alloc_node.type = scc_ir_ctx_new_type(
&builder->ctx,
&(scc_ir_type_t){.tag = SCC_IR_TYPE_PTR, .data.pointer.base = type});
alloc_node.name = name;
scc_ir_node_ref_t node_ref =
scc_ir_ctx_new_node(&builder->ctx, &alloc_node);
// 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref);
return node_ref;
}
scc_ir_node_ref_t scc_ir_builder_load(scc_ir_builder_t *builder,
scc_ir_node_ref_t ptr) {
scc_ir_node_t load_node = {0};
load_node.tag = SCC_IR_NODE_LOAD;
load_node.data.load.target = ptr;
// 设置类型为指针指向的类型
scc_ir_node_t *ptr_node = scc_ir_ctx_get_node(&builder->ctx, ptr);
if (ptr_node) {
scc_ir_type_t *ptr_type =
scc_ir_ctx_get_type(&builder->ctx, ptr_node->type);
if (ptr_type && ptr_type->tag == SCC_IR_TYPE_PTR) {
load_node.type = ptr_type->data.pointer.base;
}
}
scc_ir_node_ref_t node_ref = scc_ir_ctx_new_node(&builder->ctx, &load_node);
// 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref);
return node_ref;
}
scc_ir_node_ref_t scc_ir_builder_store(scc_ir_builder_t *builder,
scc_ir_node_ref_t ptr,
scc_ir_node_ref_t value) {
scc_ir_node_t store_node = {0};
store_node.tag = SCC_IR_NODE_STORE;
store_node.data.store.target = ptr;
store_node.data.store.value = value;
scc_ir_node_ref_t node_ref =
scc_ir_ctx_new_node(&builder->ctx, &store_node);
// 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref);
return node_ref;
}
scc_ir_node_ref_t scc_ir_builder_get_ptr(scc_ir_builder_t *builder,
scc_ir_node_ref_t ptr,
scc_ir_node_ref_t index) {
scc_ir_node_t get_ptr_node = {0};
get_ptr_node.tag = SCC_IR_NODE_GET_PTR;
get_ptr_node.data.get_ptr.src_addr = ptr;
get_ptr_node.data.get_ptr.index = index;
// 类型应与源地址相同(都是指针)
scc_ir_node_t *src_node = scc_ir_ctx_get_node(&builder->ctx, ptr);
if (src_node) {
get_ptr_node.type = src_node->type;
}
scc_ir_node_ref_t node_ref =
scc_ir_ctx_new_node(&builder->ctx, &get_ptr_node);
// 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref);
return node_ref;
}
scc_ir_node_ref_t scc_ir_builder_binop(scc_ir_builder_t *builder,
scc_ir_op_type_t op,
scc_ir_node_ref_t lhs,
scc_ir_node_ref_t rhs) {
scc_ir_node_t binop_node = {0};
binop_node.tag = SCC_IR_NODE_OP;
binop_node.data.op.op = op;
binop_node.data.op.lhs = lhs;
binop_node.data.op.rhs = rhs;
// 类型通常与操作数相同(对于算术运算)
scc_ir_node_t *lhs_node = scc_ir_ctx_get_node(&builder->ctx, lhs);
if (lhs_node) {
binop_node.type = lhs_node->type;
}
scc_ir_node_ref_t node_ref =
scc_ir_ctx_new_node(&builder->ctx, &binop_node);
// 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref);
return node_ref;
}
scc_ir_node_ref_t scc_ir_builder_cmp(scc_ir_builder_t *builder,
scc_ir_op_type_t op, scc_ir_node_ref_t lhs,
scc_ir_node_ref_t rhs) {
scc_ir_node_t cmp_node = {0};
cmp_node.tag = SCC_IR_NODE_OP;
cmp_node.data.op.op = op;
cmp_node.data.op.lhs = lhs;
cmp_node.data.op.rhs = rhs;
// 比较操作的结果通常是布尔值
cmp_node.type = scc_ir_ctx_get_builtin_i32(&builder->ctx);
scc_ir_node_ref_t node_ref = scc_ir_ctx_new_node(&builder->ctx, &cmp_node);
// 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref);
return node_ref;
}
scc_ir_node_ref_t scc_ir_builder_jump(scc_ir_builder_t *builder,
scc_ir_bblock_ref_t target) {
scc_ir_node_t jump_node = {0};
jump_node.tag = SCC_IR_NODE_JUMP;
jump_node.data.jump.target_bblock = target;
scc_ir_node_ref_t node_ref = scc_ir_ctx_new_node(&builder->ctx, &jump_node);
// 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref);
return node_ref;
}
scc_ir_node_ref_t scc_ir_builder_branch(scc_ir_builder_t *builder,
scc_ir_node_ref_t cond,
scc_ir_bblock_ref_t true_target,
scc_ir_bblock_ref_t false_target) {
scc_ir_node_t branch_node = {0};
branch_node.tag = SCC_IR_NODE_BRANCH;
branch_node.data.branch.cond = cond;
branch_node.data.branch.true_bblock = true_target;
branch_node.data.branch.false_bblock = false_target;
scc_ir_node_ref_t node_ref =
scc_ir_ctx_new_node(&builder->ctx, &branch_node);
// 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref);
return node_ref;
}
scc_ir_node_ref_t scc_ir_builder_call(scc_ir_builder_t *builder,
scc_ir_func_ref_t callee,
const scc_ir_node_ref_t *args,
usize arg_count) {
scc_ir_node_t call_node = {0};
call_node.tag = SCC_IR_NODE_CALL;
call_node.data.call.callee = callee;
scc_vec_init(call_node.data.call.args);
for (usize i = 0; i < arg_count; i++) {
scc_vec_push(call_node.data.call.args, args[i]);
}
// 设置返回类型为被调用函数的返回类型
scc_ir_func_t *callee_func = scc_ir_ctx_get_func(&builder->ctx, callee);
if (callee_func) {
scc_ir_type_t *func_type =
scc_ir_ctx_get_type(&builder->ctx, callee_func->type);
if (func_type && func_type->tag == SCC_IR_TYPE_FUNC) {
call_node.type = func_type->data.function.ret_type;
}
}
scc_ir_node_ref_t node_ref = scc_ir_ctx_new_node(&builder->ctx, &call_node);
// 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref);
return node_ref;
}
scc_ir_node_ref_t scc_ir_builder_ret(scc_ir_builder_t *builder,
scc_ir_node_ref_t value) {
scc_ir_node_t ret_node = {0};
ret_node.tag = SCC_IR_NODE_RET;
ret_node.data.ret.ret_val = value;
scc_ir_node_ref_t node_ref = scc_ir_ctx_new_node(&builder->ctx, &ret_node);
// 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref);
return node_ref;
}
scc_ir_node_ref_t scc_ir_builder_ret_void(scc_ir_builder_t *builder) {
scc_ir_node_t ret_node = {0};
ret_node.tag = SCC_IR_NODE_RET;
ret_node.data.ret.ret_val = 0; // 无返回值
scc_ir_node_ref_t node_ref = scc_ir_ctx_new_node(&builder->ctx, &ret_node);
// 添加到当前基本块
scc_ir_builder_add_instr(builder, node_ref);
return node_ref;
}