feat(ast): 更新AST dump功能以使用新的树转储接口
- 将头文件中的tree_dump.h替换为scc_tree_dump.h - 修改函数签名将scc_tree_dump_ctx_t改为scc_tree_dump_t - 移除过时的宏定义和内联函数实现 - 使用新的scc_tree_dump_* API替代旧的PRINT_*宏 - 简化类型、表达式、语句和声明的转储逻辑 - 统一使用新的树转储接口进行节点和值的输出 feat(ast2ir): 实现逻辑运算符和一元运算符的IR转换 - 添加scc_ast2ir_logical_expr函数处理&&和||运算符 - 实现短路求值逻辑,包含分支控制流 - 添加对一元正号运算符的支持 - 实现取地址和间接寻址运算符 - 添加字符字面量解析支持转义序列 fix(ir): 修复字符串常量构建中的长度计算错误 - 修正数组长度计算从len+1改为len-1 - 调整字符串内容复制逻辑跳过引号边界 - 修正内存分配大小与实际数据长度匹配 refactor(ir): 更新IR转储模块使用统一的树转储接口 - 将IR转储上下文中的tree_dump_ctx_t替换为scc_tree_dump_t - 更新初始化函数签名以使用新的转储接口类型
This commit is contained in:
@@ -93,6 +93,92 @@ scc_ir_type_ref_t scc_ast2ir_type(scc_ast2ir_ctx_t *ctx,
|
||||
return scc_ir_builder_type(&ctx->builder, &ir_type);
|
||||
}
|
||||
|
||||
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 right_block =
|
||||
scc_ir_builder_bblock(&ctx->builder, "logic_right");
|
||||
scc_ir_bblock_ref_t end_block =
|
||||
scc_ir_builder_bblock(&ctx->builder, "logic_end");
|
||||
|
||||
// 为结果创建临时存储空间
|
||||
scc_ir_type_ref_t int32_type = scc_ir_builder_type_i32(&ctx->builder);
|
||||
scc_ir_value_ref_t result_var =
|
||||
scc_ir_builder_alloca(&ctx->builder, int32_type, "logic_result");
|
||||
|
||||
// 计算左操作数
|
||||
scc_ir_value_ref_t left_val = scc_ast2ir_expr(ctx, expr->binary.lhs, false);
|
||||
scc_ir_value_ref_t zero_val = scc_ir_builder_const_int(
|
||||
&ctx->builder, int32_type, (scc_ir_const_int_t){.int32 = 0});
|
||||
scc_ir_value_ref_t one_val = scc_ir_builder_const_int(
|
||||
&ctx->builder, int32_type, (scc_ir_const_int_t){.int32 = 1});
|
||||
|
||||
if (expr->binary.op == SCC_AST_OP_LOGICAL_AND) {
|
||||
// a && b
|
||||
scc_ir_bblock_ref_t false_block =
|
||||
scc_ir_builder_bblock(&ctx->builder, "and_false");
|
||||
|
||||
// 如果左操作数为0,结果为0(短路)
|
||||
scc_ir_value_ref_t is_left_zero = scc_ir_builder_binop(
|
||||
&ctx->builder, SCC_IR_OP_EQ, left_val, zero_val);
|
||||
scc_ir_builder_branch(&ctx->builder, is_left_zero, false_block,
|
||||
right_block);
|
||||
|
||||
// false_block: 左边为0,结果为0
|
||||
scc_ir_builder_set_current_bblock(&ctx->builder, false_block);
|
||||
scc_ir_builder_store(&ctx->builder, result_var, zero_val);
|
||||
scc_ir_builder_jump(&ctx->builder, end_block);
|
||||
|
||||
// right_block: 左边非0,计算右边
|
||||
scc_ir_builder_set_current_bblock(&ctx->builder, right_block);
|
||||
scc_ir_value_ref_t right_val =
|
||||
scc_ast2ir_expr(ctx, expr->binary.rhs, false);
|
||||
scc_ir_value_ref_t is_right_zero = scc_ir_builder_binop(
|
||||
&ctx->builder, SCC_IR_OP_EQ, right_val, zero_val);
|
||||
scc_ir_value_ref_t result =
|
||||
scc_ir_builder_binop(&ctx->builder, SCC_IR_OP_XOR, is_right_zero,
|
||||
one_val); // !right == 0 ? 1 : 0
|
||||
scc_ir_builder_store(&ctx->builder, result_var, result);
|
||||
scc_ir_builder_jump(&ctx->builder, end_block);
|
||||
|
||||
} else { // SCC_AST_OP_LOGICAL_OR
|
||||
// a || b
|
||||
scc_ir_bblock_ref_t true_block =
|
||||
scc_ir_builder_bblock(&ctx->builder, "or_true");
|
||||
|
||||
// 如果左操作数非0,结果为1(短路)
|
||||
scc_ir_value_ref_t is_left_nonzero = scc_ir_builder_binop(
|
||||
&ctx->builder, SCC_IR_OP_NEQ, left_val, zero_val);
|
||||
scc_ir_builder_branch(&ctx->builder, is_left_nonzero, true_block,
|
||||
right_block);
|
||||
|
||||
// true_block: 左边非0,结果为1
|
||||
scc_ir_builder_set_current_bblock(&ctx->builder, true_block);
|
||||
scc_ir_builder_store(&ctx->builder, result_var, one_val);
|
||||
scc_ir_builder_jump(&ctx->builder, end_block);
|
||||
|
||||
// right_block: 左边为0,计算右边
|
||||
scc_ir_builder_set_current_bblock(&ctx->builder, right_block);
|
||||
scc_ir_value_ref_t right_val =
|
||||
scc_ast2ir_expr(ctx, expr->binary.rhs, false);
|
||||
scc_ir_value_ref_t is_right_zero = scc_ir_builder_binop(
|
||||
&ctx->builder, SCC_IR_OP_EQ, right_val, zero_val);
|
||||
scc_ir_value_ref_t result =
|
||||
scc_ir_builder_binop(&ctx->builder, SCC_IR_OP_XOR, is_right_zero,
|
||||
one_val); // !right == 0 ? 1 : 0
|
||||
scc_ir_builder_store(&ctx->builder, result_var, result);
|
||||
scc_ir_builder_jump(&ctx->builder, end_block);
|
||||
}
|
||||
|
||||
// 设置结束块为当前块,并返回结果
|
||||
scc_ir_builder_set_current_bblock(&ctx->builder, end_block);
|
||||
return scc_ir_builder_load(&ctx->builder, result_var);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
@@ -218,7 +304,7 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
|
||||
/* 逻辑操作符 */
|
||||
case SCC_AST_OP_LOGICAL_OR: // ||
|
||||
case SCC_AST_OP_LOGICAL_AND: // &&
|
||||
TODO();
|
||||
return scc_ast2ir_logical_expr(ctx, expr, lhs, rhs);
|
||||
/* clang-format on */
|
||||
default:
|
||||
LOG_FATAL("Unsupported binary operator: %d", expr->binary.op);
|
||||
@@ -243,6 +329,9 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
|
||||
// SCC_AST_OP_POSTFIX_INCREMENT, // ++ (后缀)
|
||||
// SCC_AST_OP_POSTFIX_DECREMENT, // -- (后缀)
|
||||
switch (expr->unary.op) {
|
||||
case SCC_AST_OP_UNARY_PLUS:
|
||||
/* just pass */
|
||||
return operand;
|
||||
case SCC_AST_OP_UNARY_MINUS: {
|
||||
// 负号
|
||||
// 实现为0 - operand
|
||||
@@ -254,6 +343,28 @@ scc_ir_value_ref_t scc_ast2ir_expr(scc_ast2ir_ctx_t *ctx, scc_ast_expr_t *expr,
|
||||
return scc_ir_builder_binop(&ctx->builder, SCC_IR_OP_SUB, zero_ref,
|
||||
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;
|
||||
case SCC_AST_OP_BITWISE_NOT:
|
||||
// 按位取反
|
||||
return scc_ir_builder_binop(&ctx->builder, SCC_IR_OP_NOT, operand,
|
||||
@@ -327,9 +438,37 @@ scc_ir_value_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_CHAR_LITERAL: {
|
||||
// FIXME just 'a' '\n'
|
||||
scc_ir_type_ref_t type_ref = scc_ir_builder_type_i32(&ctx->builder);
|
||||
const char *lexme = expr->literal.lexme;
|
||||
Assert(lexme[0] == '\'');
|
||||
u8 int_lit = 0;
|
||||
if (lexme[1] == '\\') {
|
||||
switch (lexme[2]) {
|
||||
case 'a':
|
||||
int_lit = '\a';
|
||||
break;
|
||||
case 'b':
|
||||
int_lit = '\b';
|
||||
break;
|
||||
case 'f':
|
||||
int_lit = '\f';
|
||||
break;
|
||||
case 'n':
|
||||
int_lit = '\n';
|
||||
break;
|
||||
case 'r':
|
||||
int_lit = '\r';
|
||||
}
|
||||
} else {
|
||||
int_lit = lexme[1];
|
||||
}
|
||||
scc_ir_const_int_t value;
|
||||
value.int32 = int_lit;
|
||||
return scc_ir_builder_const_int(&ctx->builder, type_ref, value);
|
||||
}
|
||||
case SCC_AST_EXPR_STRING_LITERAL: {
|
||||
// FIXME
|
||||
scc_ir_builder_const_string(&ctx->builder, expr->literal.lexme,
|
||||
|
||||
Reference in New Issue
Block a user