feat(ast): 重构AST节点类型定义并实现数组下标访问
- 将scc_ast_node_type_t重命名为scc_ast_node_kind_t以提高语义清晰度 - 为scc_ast_node结构体添加名称定义 - 更新所有相关头文件中的类型引用 - 实现数组下标表达式的IR转换逻辑 - 添加对sizeof和alignof表达式的基本支持 fix(ast2ir): 修复表达式求值和类型处理问题 - 修复数组类型退化为指针的逻辑 - 修复变量声明初始化值检查条件 - 添加结构体和枚举类型的IR生成支持 - 移除未使用的代码段 refactor(ir): 完善IR上下文错误处理 - 为未处理的类型标签添加恐慌处理 - 修复联合类型的哈希计算 chore(build): 更新依赖项配置 - 修正lexer模块中的依赖项名称 style(parser): 清理解析器代码 - 移除未使用的类型哈希表 - 更新语义分析回调函数签名 - 添加属性语法的占位符实现 - 完善内存清理逻辑 test: 添加数组下标和枚举测试用例 - 新增15_array_subscript.c测试数组下标访问 - 新增16_enum.c测试枚举类型功能 - 更新期望结果配置文件
This commit is contained in:
@@ -108,8 +108,8 @@ scc_ir_value_ref_t scc_ast2ir_logical_expr(scc_ast2ir_ctx_t *ctx,
|
||||
scc_ast_expr_t *expr,
|
||||
scc_ir_value_ref_t lhs,
|
||||
scc_ir_value_ref_t rhs) {
|
||||
scc_ir_bblock_ref_t start_block =
|
||||
scc_ir_builder_current_bblock(&ctx->builder);
|
||||
// scc_ir_bblock_ref_t start_block =
|
||||
// scc_ir_builder_current_bblock(&ctx->builder);
|
||||
|
||||
scc_ir_bblock_ref_t right_block =
|
||||
scc_ir_builder_bblock(&ctx->builder, "logic_right");
|
||||
@@ -421,12 +421,39 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
|
||||
scc_vec_free(args);
|
||||
return node;
|
||||
}
|
||||
// SCC_AST_EXPR_ARRAY_SUBSCRIPT, // 数组下标
|
||||
case SCC_AST_EXPR_ARRAY_SUBSCRIPT: {
|
||||
// 1. 计算数组/指针基址(右值,得到地址)
|
||||
scc_ir_value_ref_t base_ptr =
|
||||
scc_ast2ir_expr(ctx, expr->subscript.array, true);
|
||||
// 2. 计算下标值
|
||||
scc_ir_value_ref_t index =
|
||||
scc_ast2ir_expr(ctx, expr->subscript.index, false);
|
||||
// 3. 生成 getptr(GEP)
|
||||
scc_ir_value_ref_t elem_ptr =
|
||||
scc_ir_builder_get_ptr(&ctx->builder, base_ptr, index);
|
||||
// 4. 根据左值/右值返回
|
||||
if (is_lvalue) {
|
||||
return elem_ptr; // 作为左值:返回地址
|
||||
} else {
|
||||
return scc_ir_builder_load(&ctx->builder,
|
||||
elem_ptr); // 作为右值:加载值
|
||||
}
|
||||
}
|
||||
// SCC_AST_EXPR_MEMBER, // 成员访问 .
|
||||
// SCC_AST_EXPR_PTR_MEMBER, // 指针成员访问 ->
|
||||
// SCC_AST_EXPR_CAST, // 类型转换
|
||||
// SCC_AST_EXPR_SIZE_OF, // sizeof
|
||||
// SCC_AST_EXPR_ALIGN_OF, // _Alignof
|
||||
case SCC_AST_EXPR_SIZE_OF: {
|
||||
scc_ir_const_int_t val;
|
||||
val.int64 = 1;
|
||||
return scc_ir_builder_const_int(
|
||||
&ctx->builder, scc_ir_builder_type_u64(&ctx->builder), val);
|
||||
}
|
||||
case SCC_AST_EXPR_ALIGN_OF: {
|
||||
scc_ir_const_int_t val;
|
||||
val.int64 = 1;
|
||||
return scc_ir_builder_const_int(
|
||||
&ctx->builder, scc_ir_builder_type_u64(&ctx->builder), val);
|
||||
}
|
||||
// SCC_AST_EXPR_COMPOUND, // 复合字面量
|
||||
// SCC_AST_EXPR_LVALUE, // 右值
|
||||
// SCC_AST_EXPR_BUILTIN,// 内置表达式 ... directive map to ir builtin
|
||||
@@ -491,16 +518,19 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
|
||||
// 右值:如果是数组类型,退化为指针(返回地址)
|
||||
scc_ir_type_t *ir_type =
|
||||
scc_ir_module_get_type_by_value(ctx->builder.ctx.module, in);
|
||||
Assert(ir_type->tag == SCC_IR_TYPE_PTR);
|
||||
scc_ir_type_t *target_type = scc_ir_module_get_type(
|
||||
ctx->builder.ctx.module, ir_type->data.pointer.base);
|
||||
if (target_type->tag == SCC_IR_TYPE_ARRAY) {
|
||||
// 生成 getptr 获取数组首地址
|
||||
return scc_ir_builder_get_ptr(&ctx->builder, in,
|
||||
SCC_IR_REF_nullptr);
|
||||
if (ir_type->tag == SCC_IR_TYPE_PTR) {
|
||||
scc_ir_type_t *target_type = scc_ir_module_get_type(
|
||||
ctx->builder.ctx.module, ir_type->data.pointer.base);
|
||||
if (target_type->tag == SCC_IR_TYPE_ARRAY) {
|
||||
// 生成 getptr 获取数组首地址
|
||||
return scc_ir_builder_get_ptr(&ctx->builder, in,
|
||||
SCC_IR_REF_nullptr);
|
||||
} else {
|
||||
// 标量类型:加载值
|
||||
return scc_ir_builder_load(&ctx->builder, in);
|
||||
}
|
||||
} else {
|
||||
// 标量类型:加载值
|
||||
return scc_ir_builder_load(&ctx->builder, in);
|
||||
return in;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -719,7 +749,7 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
|
||||
}
|
||||
scc_ir_value_ref_t init_val_node =
|
||||
scc_ast2ir_expr(ctx, decl->var.init, false);
|
||||
Assert(init_val_node != nullptr);
|
||||
Assert(init_val_node != SCC_IR_REF_nullptr);
|
||||
|
||||
// FIXME array auto calucate size
|
||||
scc_ir_type_t *ir_type =
|
||||
@@ -802,10 +832,29 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
|
||||
break;
|
||||
}
|
||||
case SCC_AST_DECL_STRUCT:
|
||||
break;
|
||||
case SCC_AST_DECL_UNION:
|
||||
scc_vec_foreach(decl->record.fields, i) {
|
||||
scc_ast_decl_t *item = scc_vec_at(decl->record.fields, i);
|
||||
scc_ast2ir_decl(ctx, item);
|
||||
}
|
||||
break;
|
||||
case SCC_AST_DECL_ENUM:
|
||||
scc_ir_const_int_t val;
|
||||
val.int32 = 0;
|
||||
scc_vec_foreach(decl->record.fields, i) {
|
||||
scc_ast_decl_t *item = scc_vec_at(decl->record.fields, i);
|
||||
Assert(item->base.type == SCC_AST_DECL_VAR);
|
||||
if (item->var.init) {
|
||||
Assert(item->var.init->base.type == SCC_AST_EXPR_INT_LITERAL);
|
||||
parse_lexme2const_int(item->var.init->literal.lexme, &val);
|
||||
}
|
||||
scc_ir_value_ref_t item_val_ref = scc_ir_builder_const_int(
|
||||
&ctx->builder, scc_ir_builder_type_i32(&ctx->builder), val);
|
||||
scc_hashtable_set(&ctx->decl2ir_ref, item,
|
||||
(void *)(usize)item_val_ref);
|
||||
val.int32 += 1;
|
||||
}
|
||||
break;
|
||||
case SCC_AST_DECL_TYPEDEF:
|
||||
break;
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user