feat(ast2ir): 添加指针运算支持并修复整数字面量解析

- 实现了指针解引用(*)和取地址(&)操作符的IR转换
- 添加parse_lexme2const_int函数统一处理整数字面量解析
- 支持数组大小表达式的常量解析
- 修复函数缺少返回语句的问题,在函数末尾添加默认ret指令

refactor(ir_builder): 调整函数参数类型处理逻辑

- 修改函数参数以指针形式传递,更新参数类型处理方式
- 优化参数节点创建过程,将参数类型包装为指针类型

fix(ir_dump): 修正IR输出格式问题

- 调整基本块和函数的输出格式,确保正确的换行和缩进
- 统一输出格式,提升可读性

feat(ir2mcode): 添加帧管理器头文件定义

- 定义frame_manager.h接口,包含栈帧分配相关函数声明
- 提供栈槽分配、寄存器保存、偏移计算等功能接口

refactor(reg_alloc): 添加初始栈大小配置

- 在寄存器分配器中增加init_stack_size字段
- 支持初始化栈大小设置,为后续帧管理功能做准备

test: 添加指针操作测试用例

- 新增14_pointer.c测试文件,验证指针取地址和解引用功能
- 在expect.toml中添加对应的期望返回值
This commit is contained in:
zzy
2026-04-04 13:22:19 +08:00
parent ca187c78f1
commit 27d86d5685
11 changed files with 109 additions and 41 deletions

View File

@@ -1,5 +1,15 @@
#include <scc_ast2ir.h>
static inline void parse_lexme2const_int(const char *lexme,
scc_ir_const_int_t *value) {
// FIXME
usize int_lit = 0;
for (usize i = 0; i < scc_strlen(lexme); i++) {
int_lit = int_lit * 10 + (lexme[i] - '0');
}
value->int64 = int_lit;
}
scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
scc_ast_type_t *ast_type) {
if (ctx == null || ast_type == null) {
@@ -51,7 +61,16 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
ir_type.data.array.base = element_type;
// TODO: 处理数组大小表达式
ir_type.data.array.len = 0; // 暂时设为0
ir_type.data.array.len = 0;
if (ast_type->array.size) {
// TODO constant expression
if (ast_type->array.size->base.type != SCC_AST_EXPR_INT_LITERAL) {
Panic("TODO: array size expression");
}
scc_ir_const_int_t value;
parse_lexme2const_int(ast_type->array.size->literal.lexme, &value);
ir_type.data.array.len = value.int32;
}
break;
}
@@ -315,6 +334,20 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
}
case SCC_AST_EXPR_UNARY: {
if (expr->unary.op == SCC_AST_OP_ADDRESS_OF) {
return scc_ast2ir_expr(ctx, expr->unary.operand, true);
} else if (expr->unary.op == SCC_AST_OP_INDIRECTION) {
// 从地址取值
scc_ir_value_ref_t ptr =
scc_ast2ir_expr(ctx, expr->unary.operand, false);
if (is_lvalue) {
// 作为左值使用(如 *ptr = ...),直接返回指针值(地址)
return ptr;
} else {
// 作为右值使用(如 x = *ptr加载指针指向的值
return scc_ir_builder_load(&ctx->builder, ptr);
}
}
scc_ir_value_ref_t operand =
scc_ast2ir_expr(ctx, expr->unary.operand, is_lvalue);
// /* 一元操作符 */
@@ -344,27 +377,9 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
operand);
}
case SCC_AST_OP_ADDRESS_OF:
// 取地址
operand =
scc_ir_builder_get_ptr(&ctx->builder, operand, SCC_IR_REF_NULL);
Assert(operand != SCC_IR_REF_NULL);
return operand;
case SCC_AST_OP_INDIRECTION:
// 从地址取值
// FIXME
scc_ir_value_t *value =
scc_ir_module_get_value(ctx->builder.ctx.module, operand);
Assert(value != null);
scc_ir_type_t *type =
scc_ir_module_get_type(ctx->builder.ctx.module, value->type);
Assert(type != null);
if (type->tag != SCC_IR_TYPE_PTR) {
LOG_FATAL("Invalid type: %d", type->tag);
}
operand = scc_ir_builder_load(&ctx->builder, operand);
Assert(operand != SCC_IR_REF_NULL);
return operand;
UNREACHABLE();
break;
case SCC_AST_OP_BITWISE_NOT:
// 按位取反
return scc_ir_builder_binop(&ctx->builder, SCC_IR_OP_NOT, operand,
@@ -428,16 +443,11 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
case SCC_AST_EXPR_INT_LITERAL: {
// FIXME maybe using some array to int;
usize int_lit = 0;
for (usize i = 0; i < scc_strlen(expr->literal.lexme); i++) {
int_lit = int_lit * 10 + (expr->literal.lexme[i] - '0');
}
scc_ir_type_ref_t type_ref = scc_ir_builder_type_i32(&ctx->builder);
scc_ir_const_int_t value;
value.int32 = int_lit;
parse_lexme2const_int(expr->literal.lexme, &value);
return scc_ir_builder_const_int(&ctx->builder, type_ref, value);
}
// SCC_AST_EXPR_FLOAT_LITERAL, // 浮点字面量
case SCC_AST_EXPR_CHAR_LITERAL: {
// FIXME just 'a' '\n'
@@ -752,6 +762,9 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
(void *)(usize)param_node_ref);
}
scc_ast2ir_stmt(ctx, decl->func.body);
// FIXME need ret for none return or other default ret
scc_ir_builder_ret_void(&ctx->builder);
scc_ir_builder_end_bblock(&ctx->builder);
scc_ir_builder_end_func(&ctx->builder);
break;