refactor(ast): 统一记录类型结构并移除成员访问操作符

- 移除了枚举类型的独立结构定义,统一使用record结构
- 移除了成员访问操作符SCC_AST_OP_MEMBER_ACCESS和SCC_AST_OP_PTR_MEMBER_ACCESS
- 更新了for循环语句中init字段的类型从scc_ast_type_t*到scc_ast_node_t*
- 修改了声明初始化函数以支持统一的记录类型处理

fix(ast2ir): 完善二元表达式处理和for循环代码生成

- 重构了赋值操作符的处理逻辑,通过临时表达式实现复合赋值
- 添加了对for循环语句的完整IR代码生成功能
- 修复了if-else语句中错误的基本块跳转问题
- 改进了标识符未找到时的错误提示信息

chore: 清理代码和修复潜在问题

- 移除了未使用的自动标签生成功能
- 统一了IR基本块标签格式化输出
- 修复了机器码生成中的寄存器存储控制流问题
- 改进了词法分析器中十六进制数字的处理逻辑
This commit is contained in:
zzy
2026-03-21 10:33:17 +08:00
parent a64e1f8330
commit 35a704a1cb
25 changed files with 1335 additions and 2095 deletions

View File

@@ -99,105 +99,123 @@ scc_ir_node_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
return 0;
}
cbool is_assign = true;
switch (expr->base.type) {
case SCC_AST_EXPR_BINARY: {
scc_ast_expr_t tmp_expr;
scc_ir_node_ref_t lhs, rhs;
cbool is_assign = false;
switch (expr->binary.op) {
case SCC_AST_OP_ASSIGN: // =
case SCC_AST_OP_ASSIGN_ADD: // +=
case SCC_AST_OP_ASSIGN_SUB: // -=
case SCC_AST_OP_ASSIGN_MUL: // *=
case SCC_AST_OP_ASSIGN_DIV: // /=
case SCC_AST_OP_ASSIGN_MOD: // %=
case SCC_AST_OP_ASSIGN_AND: // &=
case SCC_AST_OP_ASSIGN_XOR: // ^=
case SCC_AST_OP_ASSIGN_OR: // |=
case SCC_AST_OP_ASSIGN: // =
rhs = scc_ast2ir_expr(ctx, expr->binary.rhs, false);
break;
case SCC_AST_OP_ASSIGN_ADD: // +=
scc_ast_expr_binary_init(&tmp_expr, SCC_AST_OP_ADD,
expr->binary.lhs, expr->binary.rhs,
expr->base.loc);
rhs = scc_ast2ir_expr(ctx, &tmp_expr, false);
break;
case SCC_AST_OP_ASSIGN_SUB: // -=
scc_ast_expr_binary_init(&tmp_expr, SCC_AST_OP_SUB,
expr->binary.lhs, expr->binary.rhs,
expr->base.loc);
rhs = scc_ast2ir_expr(ctx, &tmp_expr, false);
break;
case SCC_AST_OP_ASSIGN_MUL: // *=
scc_ast_expr_binary_init(&tmp_expr, SCC_AST_OP_MUL,
expr->binary.lhs, expr->binary.rhs,
expr->base.loc);
rhs = scc_ast2ir_expr(ctx, &tmp_expr, false);
break;
case SCC_AST_OP_ASSIGN_DIV: // /=
scc_ast_expr_binary_init(&tmp_expr, SCC_AST_OP_DIV,
expr->binary.lhs, expr->binary.rhs,
expr->base.loc);
rhs = scc_ast2ir_expr(ctx, &tmp_expr, false);
break;
case SCC_AST_OP_ASSIGN_MOD: // %=
scc_ast_expr_binary_init(&tmp_expr, SCC_AST_OP_MOD,
expr->binary.lhs, expr->binary.rhs,
expr->base.loc);
rhs = scc_ast2ir_expr(ctx, &tmp_expr, false);
break;
case SCC_AST_OP_ASSIGN_AND: // &=
scc_ast_expr_binary_init(&tmp_expr, SCC_AST_OP_BITWISE_AND,
expr->binary.lhs, expr->binary.rhs,
expr->base.loc);
rhs = scc_ast2ir_expr(ctx, &tmp_expr, false);
break;
case SCC_AST_OP_ASSIGN_XOR: // ^=
scc_ast_expr_binary_init(&tmp_expr, SCC_AST_OP_BITWISE_XOR,
expr->binary.lhs, expr->binary.rhs,
expr->base.loc);
rhs = scc_ast2ir_expr(ctx, &tmp_expr, false);
break;
case SCC_AST_OP_ASSIGN_OR: // |=
scc_ast_expr_binary_init(&tmp_expr, SCC_AST_OP_BITWISE_OR,
expr->binary.lhs, expr->binary.rhs,
expr->base.loc);
rhs = scc_ast2ir_expr(ctx, &tmp_expr, false);
break;
case SCC_AST_OP_ASSIGN_LSHIFT: // <<=
scc_ast_expr_binary_init(&tmp_expr, SCC_AST_OP_LEFT_SHIFT,
expr->binary.lhs, expr->binary.rhs,
expr->base.loc);
rhs = scc_ast2ir_expr(ctx, &tmp_expr, false);
break;
case SCC_AST_OP_ASSIGN_RSHIFT: // >>=
is_assign = true;
scc_ast_expr_binary_init(&tmp_expr, SCC_AST_OP_RIGHT_SHIFT,
expr->binary.lhs, expr->binary.rhs,
expr->base.loc);
rhs = scc_ast2ir_expr(ctx, &tmp_expr, false);
break;
default:
is_assign = false;
break;
}
lhs = scc_ast2ir_expr(ctx, expr->binary.lhs, is_assign);
rhs = scc_ast2ir_expr(ctx, expr->binary.rhs, false);
if (is_assign) {
lhs = scc_ast2ir_expr(ctx, expr->binary.lhs, true);
return scc_ir_builder_store(&ctx->builder, lhs, rhs);
}
rhs = scc_ast2ir_expr(ctx, expr->binary.rhs, false);
lhs = scc_ast2ir_expr(ctx, expr->binary.lhs, false);
// 映射操作符
scc_ir_op_type_t op;
switch (expr->binary.op) {
/* clang-format off */
case SCC_AST_OP_ADD: op = SCC_IR_OP_ADD; break;
case SCC_AST_OP_SUB: op = SCC_IR_OP_SUB; break;
case SCC_AST_OP_MUL: op = SCC_IR_OP_MUL; break;
case SCC_AST_OP_DIV: op = SCC_IR_OP_DIV; break;
case SCC_AST_OP_MOD: op = SCC_IR_OP_MOD; break;
case SCC_AST_OP_LOGICAL_AND: op = SCC_IR_OP_AND; break;
case SCC_AST_OP_LOGICAL_OR: op = SCC_IR_OP_OR; break;
case SCC_AST_OP_BITWISE_XOR: op = SCC_IR_OP_XOR; break;
case SCC_AST_OP_LEFT_SHIFT: op = SCC_IR_OP_SHL; break;
case SCC_AST_OP_RIGHT_SHIFT: op = SCC_IR_OP_SHR; break;
case SCC_AST_OP_EQUAL: op = SCC_IR_OP_EQ; break;
case SCC_AST_OP_NOT_EQUAL: op = SCC_IR_OP_NEQ; break;
case SCC_AST_OP_LESS: op = SCC_IR_OP_LT; break;
case SCC_AST_OP_LESS_EQUAL: op = SCC_IR_OP_LE; break;
case SCC_AST_OP_GREATER: op = SCC_IR_OP_GT; break;
case SCC_AST_OP_GREATER_EQUAL: op = SCC_IR_OP_GE; break;
case SCC_AST_OP_ASSIGN: {
return scc_ir_builder_store(&ctx->builder, lhs, rhs);
case SCC_AST_OP_ADD: op = SCC_IR_OP_ADD; break;
case SCC_AST_OP_SUB: op = SCC_IR_OP_SUB; break;
case SCC_AST_OP_MUL: op = SCC_IR_OP_MUL; break;
case SCC_AST_OP_DIV: op = SCC_IR_OP_DIV; break;
case SCC_AST_OP_MOD: op = SCC_IR_OP_MOD; break;
case SCC_AST_OP_BITWISE_AND: op = SCC_IR_OP_AND; break;
case SCC_AST_OP_BITWISE_OR: op = SCC_IR_OP_OR; break;
case SCC_AST_OP_BITWISE_XOR: op = SCC_IR_OP_XOR; break;
case SCC_AST_OP_LEFT_SHIFT: op = SCC_IR_OP_SHL; break;
case SCC_AST_OP_RIGHT_SHIFT: {
op = SCC_IR_OP_SHR;
// FIXME op = SCC_IR_OP_SAR;
break;
}
case SCC_AST_OP_ASSIGN_ADD:
case SCC_AST_OP_EQUAL: op = SCC_IR_OP_EQ; break;
case SCC_AST_OP_NOT_EQUAL: op = SCC_IR_OP_NEQ; break;
case SCC_AST_OP_LESS: op = SCC_IR_OP_LT; break;
case SCC_AST_OP_LESS_EQUAL: op = SCC_IR_OP_LE; break;
case SCC_AST_OP_GREATER: op = SCC_IR_OP_GT; break;
case SCC_AST_OP_GREATER_EQUAL: op = SCC_IR_OP_GE; break;
case SCC_AST_OP_COMMA: {
// 逗号运算符:计算左表达式,丢弃结果,返回右表达式
return rhs;
}
/* 逻辑操作符 */
case SCC_AST_OP_LOGICAL_OR: // ||
case SCC_AST_OP_LOGICAL_AND: // &&
TODO();
// /* 赋值操作符 */
// /* 条件操作符 */
// SCC_AST_OP_CONDITIONAL, // ?:
// /* 逗号操作符 */
// SCC_AST_OP_COMMA, // ,
// /* 逻辑操作符 */
// SCC_AST_OP_LOGICAL_OR, // ||
// SCC_AST_OP_LOGICAL_AND, // &&
// /* 位操作符 */
// SCC_AST_OP_BITWISE_OR, // |
// SCC_AST_OP_BITWISE_XOR, // ^
// SCC_AST_OP_BITWISE_AND, // &
// /* 相等性操作符 */
// SCC_AST_OP_EQUAL, // ==
// SCC_AST_OP_NOT_EQUAL, // !=
// /* 关系操作符 */
// SCC_AST_OP_LESS, // <
// SCC_AST_OP_GREATER, // >
// SCC_AST_OP_LESS_EQUAL, // <=
// SCC_AST_OP_GREATER_EQUAL, // >=
// /* 移位操作符 */
// SCC_AST_OP_LEFT_SHIFT, // <<
// SCC_AST_OP_RIGHT_SHIFT, // >>
// /* 算术操作符 */
// SCC_AST_OP_ADD, // +
// SCC_AST_OP_SUB, // -
// SCC_AST_OP_MUL, // *
// SCC_AST_OP_DIV, // /
// SCC_AST_OP_MOD, // %
// /* 一元操作符 */
// SCC_AST_OP_UNARY_PLUS, // + (一元)
// SCC_AST_OP_UNARY_MINUS, // - (一元)
// SCC_AST_OP_ADDRESS_OF, // &
// SCC_AST_OP_INDIRECTION, // *
// SCC_AST_OP_BITWISE_NOT, // ~
// SCC_AST_OP_LOGICAL_NOT, // !
// SCC_AST_OP_PREFIX_INCREMENT, // ++ (前缀)
// SCC_AST_OP_PREFIX_DECREMENT, // -- (前缀)
// SCC_AST_OP_POSTFIX_INCREMENT, // ++ (后缀)
// SCC_AST_OP_POSTFIX_DECREMENT, // -- (后缀)
// /* 成员访问 */
// SCC_AST_OP_MEMBER_ACCESS, // .
// SCC_AST_OP_PTR_MEMBER_ACCESS, // ->
/* clang-format on */
/* clang-format on */
default:
LOG_FATAL("Unsupported binary operator: %d", expr->binary.op);
return 0;
}
// 创建操作节点
return scc_ir_builder_binop(&ctx->builder, op, lhs, rhs);
}
@@ -205,10 +223,20 @@ 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_ast2ir_expr(ctx, expr->unary.operand, is_lvalue);
// /* 一元操作符 */
// SCC_AST_OP_UNARY_PLUS, // + (一元)
// SCC_AST_OP_UNARY_MINUS, // - (一元)
// SCC_AST_OP_ADDRESS_OF, // &
// SCC_AST_OP_INDIRECTION, // *
// SCC_AST_OP_BITWISE_NOT, // ~
// SCC_AST_OP_LOGICAL_NOT, // !
// SCC_AST_OP_PREFIX_INCREMENT, // ++ (前缀)
// SCC_AST_OP_PREFIX_DECREMENT, // -- (前缀)
// SCC_AST_OP_POSTFIX_INCREMENT, // ++ (后缀)
// SCC_AST_OP_POSTFIX_DECREMENT, // -- (后缀)
// 映射一元操作符
switch (expr->unary.op) {
case SCC_AST_OP_SUB:
case SCC_AST_OP_UNARY_MINUS:
// 负号
// 实现为0 - operand
return scc_ir_builder_binop(
@@ -266,7 +294,7 @@ scc_ir_node_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
// SCC_AST_EXPR_ALIGN_OF, // _Alignof
// SCC_AST_EXPR_COMPOUND, // 复合字面量
// SCC_AST_EXPR_LVALUE, // 右值
// SCC_AST_EXPR_BUILTIN, // 内置表达式
// SCC_AST_EXPR_BUILTIN,// 内置表达式 ... directive map to ir builtin
case SCC_AST_EXPR_INT_LITERAL: {
// FIXME maybe using some array to int;
@@ -284,7 +312,7 @@ scc_ir_node_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
case SCC_AST_EXPR_IDENTIFIER: {
if (expr->identifier._target == null) {
LOG_ERROR("unknown identifier");
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(
@@ -365,7 +393,7 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
// 生成false分支
if (stmt->if_stmt.opt_else_stmt) {
scc_ir_builder_set_current_bblock(&ctx->builder, true_block);
scc_ir_builder_set_current_bblock(&ctx->builder, false_block);
scc_ast2ir_stmt(ctx, stmt->if_stmt.opt_else_stmt);
scc_ir_builder_jump(&ctx->builder, merge_block);
}
@@ -421,13 +449,46 @@ void scc_ast2ir_stmt(scc_ast2ir_ctx_t *ctx, scc_ast_stmt_t *stmt) {
}
case SCC_AST_STMT_FOR: {
TODO();
scc_ir_bblock_ref_t cond_block =
scc_ir_builder_bblock(&ctx->builder, "for_while_cond");
scc_ir_bblock_ref_t body_block =
scc_ir_builder_bblock(&ctx->builder, "for_while_body");
scc_ir_bblock_ref_t exit_block =
scc_ir_builder_bblock(&ctx->builder, "for_while_exit");
if (stmt->for_stmt.init) {
if (SCC_AST_IS_A(scc_ast_decl_t, stmt->for_stmt.init)) {
scc_ast2ir_decl(
ctx, SCC_AST_CAST_TO(scc_ast_decl_t, stmt->for_stmt.init));
} else if (SCC_AST_IS_A(scc_ast_expr_t, stmt->for_stmt.init)) {
scc_ast2ir_expr(
ctx, SCC_AST_CAST_TO(scc_ast_expr_t, stmt->for_stmt.init),
false);
} else {
LOG_FATAL("invalid for init statement");
}
}
scc_ir_builder_jump(&ctx->builder, cond_block);
scc_ir_builder_set_current_bblock(&ctx->builder, cond_block);
if (stmt->for_stmt.cond) {
scc_ir_node_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);
} else {
scc_ir_builder_jump(&ctx->builder, body_block);
}
scc_ir_builder_set_current_bblock(&ctx->builder, body_block);
scc_ast2ir_stmt(ctx, stmt->for_stmt.body);
if (stmt->for_stmt.incr) {
scc_ast2ir_expr(ctx, stmt->for_stmt.incr, false);
}
scc_ir_builder_jump(&ctx->builder, cond_block);
scc_ir_builder_set_current_bblock(&ctx->builder, exit_block);
break;
}
@@ -488,12 +549,12 @@ void scc_ast2ir_decl(scc_ast2ir_ctx_t *ctx, scc_ast_decl_t *decl) {
}
case SCC_AST_DECL_FUNC: {
// TODO params name
scc_ir_type_ref_t func_type = scc_ast2ir_type(ctx, decl->func.type);
if (decl->func.body == null) {
// function decl
break;
}
// TODO params name
scc_ir_builder_begin_func(&ctx->builder, decl->name, func_type, null);
scc_ir_builder_begin_bblock(&ctx->builder, "entry");
scc_ast2ir_stmt(ctx, decl->func.body);
@@ -546,6 +607,5 @@ 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);
scc_hashtable_init(&ctx->node2ir, scc_hash_node, scc_cmp_node);
}