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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user