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