feat(ast2ir): 添加AST到IR转换功能并完善类型ABI支持

- 添加了ast2ir库用于将AST转换为IR中间表示
- 实现了Windows x64 ABI类型定义文件
- 完善了IR库中的类型定义,添加了无符号整数类型和操作符枚举
- 更新了IR转储功能以支持新的节点类型
- 在主程序中集成了AST到IR的转换流程
- 修改了PE目标文件生成功能以修正节区标志
- 更新了向量实现的日志和错误处理机制

fix(ir): 修复IR库中的操作符枚举和类型处理问题

- 修复了IR操作符枚举的命名空间问题,统一使用SCC_IR前缀
- 添加了无符号整数类型的哈希和比较支持
- 修正了常量整数节点的打印函数调用
- 更新了各种IR节点的转储输出格式
- 删除了测试文件中的冗余代码

refactor: 重构项目依赖配置和构建设置

- 启用了ast2ir和ir库的依赖配置
- 添加了def文件到.gitignore中
- 重命名了部分测试文件
This commit is contained in:
zzy
2026-03-15 15:44:50 +08:00
parent 6ebf0c48e3
commit 45c59e0b65
19 changed files with 339 additions and 131 deletions

View File

@@ -4,6 +4,9 @@ version = "0.1.0"
authors = []
description = ""
# dependencies = []
dependencies = [
{ name = "scc_ast", path = "../ast" },
{ name = "scc_ir", path = "../ir" },
]
# features = {}
# default_features = []

View File

@@ -0,0 +1,141 @@
#ifndef __SCC_WIN_X64_TYPE_ABI_H__
#define __SCC_WIN_X64_TYPE_ABI_H__
#include "../scc_type_abi.h"
/**
* @brief Windows x64 ABI Type
* @details
* https://learn.microsoft.com/zh-cn/cpp/build/x64-software-conventions?view=msvc-180
*/
static const scc_type_abi_t scc_win_x64_type_abi[] = {
{
.ast_type = SCC_AST_BUILTIN_TYPE_UNKNOWN,
.ir_type = SCC_IR_TYPE_UNKNOWN,
.size = 0,
.alignment = 0,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_VOID,
.ir_type = SCC_IR_TYPE_VOID,
.size = 0,
.alignment = 0,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_BOOL,
.ir_type = SCC_IR_TYPE_U8,
.size = 1,
.alignment = 1,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_CHAR,
.ir_type = SCC_IR_TYPE_I8,
.size = 1,
.alignment = 1,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_CHAR,
.ir_type = SCC_IR_TYPE_I8,
.size = 1,
.alignment = 1,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_CHAR,
.ir_type = SCC_IR_TYPE_U8,
.size = 1,
.alignment = 1,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_SHORT,
.ir_type = SCC_IR_TYPE_I16,
.size = 2,
.alignment = 2,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_SHORT,
.ir_type = SCC_IR_TYPE_I16,
.size = 2,
.alignment = 2,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_SHORT,
.ir_type = SCC_IR_TYPE_U16,
.size = 2,
.alignment = 2,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_INT,
.ir_type = SCC_IR_TYPE_I32,
.size = 4,
.alignment = 4,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_INT,
.ir_type = SCC_IR_TYPE_I32,
.size = 4,
.alignment = 4,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_INT,
.ir_type = SCC_IR_TYPE_U32,
.size = 4,
.alignment = 4,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_LONG,
.ir_type = SCC_IR_TYPE_I32,
.size = 4,
.alignment = 4,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_LONG,
.ir_type = SCC_IR_TYPE_I32,
.size = 4,
.alignment = 4,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG,
.ir_type = SCC_IR_TYPE_U32,
.size = 4,
.alignment = 4,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_LONG_LONG,
.ir_type = SCC_IR_TYPE_I64,
.size = 8,
.alignment = 8,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_SIGNED_LONG_LONG,
.ir_type = SCC_IR_TYPE_I64,
.size = 8,
.alignment = 8,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_UNSIGNED_LONG_LONG,
.ir_type = SCC_IR_TYPE_I64,
.size = 8,
.alignment = 8,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_FLOAT,
.ir_type = SCC_IR_TYPE_F32,
.size = 4,
.alignment = 4,
},
{
.ast_type = SCC_AST_BUILTIN_TYPE_DOUBLE,
.ir_type = SCC_IR_TYPE_F64,
.size = 8,
.alignment = 8,
},
{
// NULL
.ast_type = SCC_AST_BUILTIN_TYPE_UNKNOWN,
.ir_type = SCC_IR_TYPE_UNKNOWN,
.size = 0,
.alignment = 0,
},
};
#endif /* __SCC_WIN_X64_TYPE_ABI_H__ */

View File

@@ -1,10 +1,12 @@
#ifndef __SCC_AST2IR_H__
#define __SCC_AST2IR_H__
#include <lexer_token.h>
#include "scc_type_abi.h"
#include <scc_ast.h>
#include <scc_ir.h>
void scc_ast2ir(scc_ast_translation_unit_t *tu, scc_ir_builder_t *builder);
void scc_ast2ir_translation_unit(scc_ir_builder_t *builder,
scc_ast_translation_unit_t *tu,
const scc_type_abi_t *abi);
#endif /* __SCC_AST2IR_H__ */

View File

@@ -0,0 +1,14 @@
#ifndef __SCC_TYPE_ABI_H__
#define __SCC_TYPE_ABI_H__
#include <ast_def.h>
#include <ir_def.h>
typedef struct {
scc_ast_builtin_type_t ast_type;
scc_ir_type_tag_t ir_type;
usize size;
usize alignment;
} scc_type_abi_t;
#endif /* __SCC_TYPE_ABI_H__ */

View File

@@ -66,9 +66,11 @@ static scc_ir_type_ref_t ast_type_to_ir_type(scc_ir_builder_t *ctx,
scc_ir_type_ref_vec_t params;
scc_vec_init(params);
scc_vec_foreach(ast_type->function.param_types, i) {
scc_ast_type_t *param_type =
scc_ast_decl_t *decl_param =
scc_vec_at(ast_type->function.param_types, i);
scc_ir_type_ref_t tmp_type = ast_type_to_ir_type(ctx, param_type);
Assert(decl_param->base.type == SCC_AST_DECL_PARAM);
scc_ir_type_ref_t tmp_type =
ast_type_to_ir_type(ctx, decl_param->param.type);
scc_vec_push(params, tmp_type);
}
ir_type.data.function.params = params;
@@ -99,7 +101,8 @@ static scc_ir_node_ref_t ast_expr_to_ir(scc_ir_builder_t *ctx,
}
case SCC_AST_EXPR_INT_LITERAL: {
return scc_ir_ctx_get_i32_const(&ctx->ctx, expr->literal.value.i);
// TODO parse i32 value
return scc_ir_ctx_get_i32_const(&ctx->ctx, 0);
}
case SCC_AST_EXPR_BINARY: {
@@ -112,22 +115,22 @@ static scc_ir_node_ref_t ast_expr_to_ir(scc_ir_builder_t *ctx,
scc_ir_op_type_t op;
switch (expr->binary.op) {
/* clang-format off */
case SCC_AST_OP_ADD: op = IR_OP_ADD; break;
case SCC_AST_OP_SUB: op = IR_OP_SUB; break;
case SCC_AST_OP_MUL: op = IR_OP_MUL; break;
case SCC_AST_OP_DIV: op = IR_OP_DIV; break;
case SCC_AST_OP_MOD: op = IR_OP_MOD; break;
case SCC_AST_OP_LOGICAL_AND: op = IR_OP_AND; break;
case SCC_AST_OP_LOGICAL_OR: op = IR_OP_OR; break;
case SCC_AST_OP_BITWISE_XOR: op = IR_OP_XOR; break;
case SCC_AST_OP_LEFT_SHIFT: op = IR_OP_SHL; break;
case SCC_AST_OP_RIGHT_SHIFT: op = IR_OP_SHR; break;
case SCC_AST_OP_EQUAL: op = IR_OP_EQ; break;
case SCC_AST_OP_NOT_EQUAL: op = IR_OP_NEQ; break;
case SCC_AST_OP_LESS: op = IR_OP_LT; break;
case SCC_AST_OP_LESS_EQUAL: op = IR_OP_LE; break;
case SCC_AST_OP_GREATER: op = IR_OP_GT; break;
case SCC_AST_OP_GREATER_EQUAL: op = IR_OP_GE; break;
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, lhs, rhs);
@@ -138,7 +141,7 @@ static scc_ir_node_ref_t ast_expr_to_ir(scc_ir_builder_t *ctx,
/* clang-format on */
default:
LOG_WARN("Unsupported binary operator: %d", expr->binary.op);
op = IR_OP_ADD; // 默认
op = SCC_IR_OP_ADD; // 默认
}
// 创建操作节点
@@ -151,20 +154,21 @@ static scc_ir_node_ref_t ast_expr_to_ir(scc_ir_builder_t *ctx,
// 映射一元操作符
switch (expr->unary.op) {
case SCC_TOK_SUB:
case SCC_AST_OP_SUB:
// 负号
// 实现为0 - operand
return scc_ir_builder_binop(ctx, IR_OP_SUB,
return scc_ir_builder_binop(ctx, SCC_IR_OP_SUB,
scc_ir_ctx_get_builtin_zero(&ctx->ctx),
operand);
case SCC_TOK_BIT_NOT:
case SCC_AST_OP_BITWISE_NOT:
// 按位取反
return scc_ir_builder_binop(ctx, IR_OP_NOT, operand, 0);
case SCC_TOK_NOT:
return scc_ir_builder_binop(ctx, SCC_IR_OP_NOT, operand, 0);
case SCC_AST_OP_LOGICAL_NOT:
// 逻辑非
// 实现为与0比较
return scc_ir_builder_binop(
ctx, IR_OP_EQ, scc_ir_ctx_get_builtin_zero(&ctx->ctx), operand);
return scc_ir_builder_binop(ctx, SCC_IR_OP_EQ,
scc_ir_ctx_get_builtin_zero(&ctx->ctx),
operand);
default:
LOG_WARN("Unsupported unary operator: %d", expr->unary.op);
return 0;
@@ -450,9 +454,9 @@ static void ast_stmt_to_ir(scc_ir_builder_t *ctx, scc_ast_stmt_t *stmt) {
// ast_stmt_to_ir(ctx, stmt->for_stmt.body);
// // 执行迭代表达式(如果存在)
// if (stmt->for_stmt.iter) {
// if (stmt->for_stmt.incr) {
// scc_ir_node_t dummy_node;
// ast_expr_to_ir(ctx, stmt->for_stmt.iter, &dummy_node);
// ast_expr_to_ir(ctx, stmt->for_stmt.incr, &dummy_node);
// }
// // 跳转回条件块
@@ -497,7 +501,7 @@ static void ast_decl_to_ir(scc_ir_builder_t *ctx, scc_ast_decl_t *decl) {
// 创建分配节点
scc_ir_node_ref_t alloc_val_node =
scc_ir_builder_alloca(ctx, ir_type, decl->var.name);
scc_ir_builder_alloca(ctx, ir_type, decl->name);
// 如果有初始化表达式
if (!decl->var.init) {
@@ -518,7 +522,7 @@ static void ast_decl_to_ir(scc_ir_builder_t *ctx, scc_ast_decl_t *decl) {
case SCC_AST_DECL_FUNC: {
// TODO params name
scc_ir_type_ref_t func_type = ast_type_to_ir_type(ctx, decl->func.type);
scc_ir_builder_begin_func(ctx, decl->func.name, func_type, null);
scc_ir_builder_begin_func(ctx, decl->name, func_type, null);
// 处理函数体(如果有)
if (decl->func.body) {
scc_ir_builder_begin_bblock(ctx, "entry");
@@ -535,17 +539,21 @@ static void ast_decl_to_ir(scc_ir_builder_t *ctx, scc_ast_decl_t *decl) {
}
}
// 主转换函数将AST翻译单元转换为IR程序
void scc_ast2ir(scc_ast_translation_unit_t *tu, scc_ir_builder_t *builder) {
/**
* @brief 将AST的翻译单元转换为IR
* @warning 需要初始化builder且保证tu合法
*
* @param builder
* @param tu
*/
void scc_ast2ir_translation_unit(scc_ir_builder_t *builder,
scc_ast_translation_unit_t *tu,
const scc_type_abi_t *abi) {
if (tu == null || builder == null) {
LOG_ERROR("Invalid argument");
return;
}
// 初始化上下文
scc_ir_builder_init(builder);
// 转换所有声明
scc_vec_foreach(tu->declarations, i) {
scc_ast_decl_t *decl = scc_vec_at(tu->declarations, i);
ast_decl_to_ir(builder, decl);

View File

@@ -1,10 +0,0 @@
#include <stdio.h>
void test_example() {
printf("Test passed!\n");
}
int main() {
test_example();
return 0;
}

View File