refactor(ir): 将IR节点重构为值引用并添加字符串字面量支持

- 将scc_ir_node_ref_t重命名为scc_ir_value_ref_t,并更新所有相关API
- 修改IR定义中的节点标签枚举为值标签枚举(scc_ir_node_tag_t -> scc_ir_value_tag_t)
- 更新AST到IR转换器中所有节点引用的类型声明
- 添加对内置类型(VOID, CHAR, INT等)的完整映射实现
- 实现字符串字面量的常量数组创建功能
- 更新项目名称从"Simple Modual C Compiler"为"Simple C Compiler"
- 在Doxyfile中排除external目录的文档生成
- 移除未使用的strpool字段并重命名decl到IR的映射表

BREAKING CHANGE: IR节点引用类型已更改,所有使用scc_ir_node_ref_t的地方需
替换为scc_ir_value_ref_t。
This commit is contained in:
zzy
2026-03-31 11:42:14 +08:00
parent 4ddad7b456
commit 78e7c800ba
22 changed files with 992 additions and 727 deletions

View File

@@ -8,9 +8,9 @@
typedef struct {
scc_ir_builder_t builder;
scc_hashtable_t node2ir; ///< decl to ir_ref
scc_hashtable_t decl2ir_ref; ///< decl to ir_ref
scc_hashtable_t symtab; ///< symbol to ir_ref
scc_strpool_t strpool; ///< string pool
// scc_strpool_t strpool; ///< string pool
const scc_type_abi_t *abi;
} scc_ast2ir_ctx_t;
@@ -21,8 +21,8 @@ void scc_ast2ir_ctx_drop(scc_ast2ir_ctx_t *ctx);
void scc_ast2ir_translation_unit(scc_ast2ir_ctx_t *ctx,
scc_ast_translation_unit_t *tu);
void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl);
scc_ir_node_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
cbool is_lvalue);
scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
cbool is_lvalue);
void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt);
scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
scc_ast_type_t *ast_type);

View File

@@ -13,6 +13,23 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
// 映射内置类型
scc_ir_type_init(&ir_type, SCC_IR_TYPE_i32);
// TODO: 根据具体内置类型设置
switch (ast_type->builtin.type) {
case SCC_AST_BUILTIN_TYPE_VOID:
return scc_ir_builder_type_void(&ctx->builder);
case SCC_AST_BUILTIN_TYPE_CHAR:
case SCC_AST_BUILTIN_TYPE_UNSIGNED_CHAR:
return scc_ir_builder_type_u8(&ctx->builder);
case SCC_AST_BUILTIN_TYPE_SIGNED_CHAR:
return scc_ir_builder_type_i8(&ctx->builder);
case SCC_AST_BUILTIN_TYPE_INT:
case SCC_AST_BUILTIN_TYPE_SIGNED_INT:
return scc_ir_builder_type_i32(&ctx->builder);
case SCC_AST_BUILTIN_TYPE_UNSIGNED_INT:
return scc_ir_builder_type_u32(&ctx->builder);
default:
Panic("Unsupported AST type: %d", ast_type->builtin.type);
break;
}
break;
}
@@ -81,10 +98,10 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
*
* @param ctx
* @param expr
* @return scc_ir_node_ref_t
* @return scc_ir_value_ref_t
*/
scc_ir_node_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
cbool is_lvalue) {
scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
cbool is_lvalue) {
if (ctx == null || expr == null) {
LOG_ERROR("args is null");
return 0;
@@ -94,7 +111,7 @@ scc_ir_node_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
switch (expr->base.type) {
case SCC_AST_EXPR_BINARY: {
scc_ast_expr_t tmp_expr;
scc_ir_node_ref_t lhs, rhs;
scc_ir_value_ref_t lhs, rhs;
switch (expr->binary.op) {
case SCC_AST_OP_ASSIGN: // =
rhs = scc_ast2ir_expr(ctx, expr->binary.rhs, false);
@@ -212,7 +229,7 @@ scc_ir_node_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
}
case SCC_AST_EXPR_UNARY: {
scc_ir_node_ref_t operand =
scc_ir_value_ref_t operand =
scc_ast2ir_expr(ctx, expr->unary.operand, is_lvalue);
// /* 一元操作符 */
// SCC_AST_OP_UNARY_PLUS, // + (一元)
@@ -232,7 +249,7 @@ scc_ir_node_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
scc_ir_const_int_t value;
scc_ir_type_ref_t type_ref = scc_ir_builder_type_i32(&ctx->builder);
value.int32 = 0;
scc_ir_node_ref_t zero_ref =
scc_ir_value_ref_t zero_ref =
scc_ir_builder_const_int(&ctx->builder, type_ref, value);
return scc_ir_builder_binop(&ctx->builder, SCC_IR_OP_SUB, zero_ref,
operand);
@@ -247,7 +264,7 @@ scc_ir_node_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
scc_ir_const_int_t value;
scc_ir_type_ref_t type_ref = scc_ir_builder_type_i32(&ctx->builder);
value.int32 = 0;
scc_ir_node_ref_t zero_ref =
scc_ir_value_ref_t zero_ref =
scc_ir_builder_const_int(&ctx->builder, type_ref, value);
return scc_ir_builder_binop(&ctx->builder, SCC_IR_OP_EQ, zero_ref,
operand);
@@ -270,19 +287,19 @@ scc_ir_node_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
scc_vec_foreach(expr->call.args, i) {
scc_ast_expr_t *arg_expr = scc_vec_at(expr->call.args, i);
scc_ir_node_ref_t arg_node;
scc_ir_value_ref_t arg_node;
arg_node = scc_ast2ir_expr(ctx, arg_expr, false);
scc_vec_push(args, arg_node);
}
// 创建调用节点(需要查找函数定义)
scc_ir_func_ref_t func = (scc_ir_node_ref_t)(usize)scc_hashtable_get(
scc_ir_func_ref_t func = (scc_ir_value_ref_t)(usize)scc_hashtable_get(
&ctx->symtab, expr->call.callee->identifier._target->name);
if (!func) {
LOG_ERROR("Function %s not found",
expr->call.callee->identifier._target->name);
}
scc_ir_node_ref_t node =
scc_ir_value_ref_t node =
scc_ir_builder_call(&ctx->builder, func, args.data, args.size);
scc_vec_free(args);
return node;
@@ -310,20 +327,25 @@ scc_ir_node_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
return scc_ir_builder_const_int(&ctx->builder, type_ref, value);
}
// SCC_AST_EXPR_INT_LITERAL, // 整数字面量
// SCC_AST_EXPR_FLOAT_LITERAL, // 浮点字面量
// SCC_AST_EXPR_CHAR_LITERAL, // 字符字面量
// case SCC_AST_EXPR_STRING_LITERAL: {
// return scc_ir_builder_store();
// }
// SCC_AST_EXPR_INT_LITERAL, // 整数字面量
// SCC_AST_EXPR_FLOAT_LITERAL, // 浮点字面量
// SCC_AST_EXPR_CHAR_LITERAL, // 字符字面量
case SCC_AST_EXPR_STRING_LITERAL: {
// FIXME
scc_ir_builder_const_string(&ctx->builder, expr->literal.lexme,
scc_strlen(expr->literal.lexme));
if (is_lvalue)
TODO();
break;
}
case SCC_AST_EXPR_IDENTIFIER: {
if (expr->identifier._target == null) {
LOG_ERROR("unknown identifier %s", expr->identifier.name);
}
// FIXME hack hashtable
scc_ir_node_ref_t in = (scc_ir_node_ref_t)(usize)scc_hashtable_get(
&ctx->node2ir, expr->identifier._target);
scc_ir_value_ref_t in = (scc_ir_value_ref_t)(usize)scc_hashtable_get(
&ctx->decl2ir_ref, expr->identifier._target);
Assert(in != 0);
if (is_lvalue) {
return in;
@@ -389,7 +411,7 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
scc_ir_bblock_ref_t merge_block =
scc_ir_builder_bblock(&ctx->builder, "if_merge");
scc_ir_node_ref_t cond_node =
scc_ir_value_ref_t cond_node =
scc_ast2ir_expr(ctx, stmt->if_stmt.cond, false);
scc_ir_builder_branch(&ctx->builder, cond_node, true_block,
false_block);
@@ -421,7 +443,7 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
scc_ir_builder_jump(&ctx->builder, cond_block);
scc_ir_builder_set_current_bblock(&ctx->builder, cond_block);
scc_ir_node_ref_t cond_node =
scc_ir_value_ref_t cond_node =
scc_ast2ir_expr(ctx, stmt->while_stmt.cond, false);
scc_ir_builder_branch(&ctx->builder, cond_node, body_block, exit_block);
@@ -448,7 +470,7 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
scc_ir_builder_jump(&ctx->builder, cond_block);
scc_ir_builder_set_current_bblock(&ctx->builder, cond_block);
scc_ir_node_ref_t cond_node =
scc_ir_value_ref_t cond_node =
scc_ast2ir_expr(ctx, stmt->while_stmt.cond, false);
scc_ir_builder_branch(&ctx->builder, cond_node, body_block, exit_block);
@@ -481,7 +503,7 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
scc_ir_builder_set_current_bblock(&ctx->builder, cond_block);
if (stmt->for_stmt.cond) {
scc_ir_node_ref_t cond_node =
scc_ir_value_ref_t cond_node =
scc_ast2ir_expr(ctx, stmt->for_stmt.cond, false);
scc_ir_builder_branch(&ctx->builder, cond_node, body_block,
exit_block);
@@ -507,7 +529,7 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
// SCC_AST_STMT_CONTINUE, // continue 语句
case SCC_AST_STMT_RETURN: {
if (stmt->return_stmt.expr) {
scc_ir_node_ref_t ret_val_node =
scc_ir_value_ref_t ret_val_node =
scc_ast2ir_expr(ctx, stmt->return_stmt.expr, false);
scc_ir_builder_ret(&ctx->builder, ret_val_node);
} else {
@@ -541,16 +563,17 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
scc_ir_type_ref_t ir_type = scc_ast2ir_type(ctx, decl->var.type);
// 创建分配节点
scc_ir_node_ref_t alloc_val_node =
scc_ir_value_ref_t alloc_val_node =
scc_ir_builder_alloca(&ctx->builder, ir_type, decl->name);
scc_hashtable_set(&ctx->node2ir, decl, (void *)(usize)alloc_val_node);
scc_hashtable_set(&ctx->decl2ir_ref, decl,
(void *)(usize)alloc_val_node);
// 如果有初始化表达式
if (!decl->var.init) {
break;
}
scc_ir_node_ref_t init_val_node =
scc_ir_value_ref_t init_val_node =
scc_ast2ir_expr(ctx, decl->var.init, false);
scc_ir_builder_store(&ctx->builder, alloc_val_node, init_val_node);
break;
@@ -581,12 +604,12 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
scc_ast_decl_t *param =
scc_vec_at(decl->func.type->function.params, i);
scc_ir_node_ref_t param_node_ref = scc_vec_at(func->params, i);
scc_ir_node_t *param_node =
scc_ir_module_get_node(ctx->builder.ctx.module, param_node_ref);
scc_ir_value_ref_t param_node_ref = scc_vec_at(func->params, i);
scc_ir_value_t *param_node = scc_ir_module_get_value(
ctx->builder.ctx.module, param_node_ref);
Assert(param_node != null);
param_node->name = param->name;
scc_hashtable_set(&ctx->node2ir, param,
scc_hashtable_set(&ctx->decl2ir_ref, param,
(void *)(usize)param_node_ref);
}
scc_ast2ir_stmt(ctx, decl->func.body);
@@ -640,13 +663,13 @@ void scc_ast2ir_ctx_init(scc_ast2ir_ctx_t *ctx, const scc_type_abi_t *abi,
Assert(ctx != null);
ctx->abi = abi;
scc_ir_builder_init(&ctx->builder, cprog);
scc_hashtable_init(&ctx->node2ir, scc_hash_node, scc_cmp_node);
scc_hashtable_init(&ctx->decl2ir_ref, scc_hash_node, scc_cmp_node);
scc_hashtable_init(&ctx->symtab, (scc_hashtable_hash_func_t)scc_strhash32,
(scc_hashtable_equal_func_t)scc_strcmp);
}
void scc_ast2ir_ctx_drop(scc_ast2ir_ctx_t *ctx) {
scc_ir_builder_drop(&ctx->builder);
scc_hashtable_drop(&ctx->node2ir);
scc_hashtable_drop(&ctx->decl2ir_ref);
scc_hashtable_drop(&ctx->symtab);
}