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:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -36,3 +36,6 @@ external/
|
|||||||
# dot file and svg file
|
# dot file and svg file
|
||||||
*.dot
|
*.dot
|
||||||
*.svg
|
*.svg
|
||||||
|
|
||||||
|
# dll def or other definition file
|
||||||
|
*.def
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ dependencies = [
|
|||||||
{ name = "pproc", path = "./libs/pproc" },
|
{ name = "pproc", path = "./libs/pproc" },
|
||||||
{ name = "parser", path = "./libs/parser" },
|
{ name = "parser", path = "./libs/parser" },
|
||||||
{ name = "ast", path = "./libs/ast" },
|
{ name = "ast", path = "./libs/ast" },
|
||||||
# { name = "ast2ir", path = "./libs/ast2ir" },
|
{ name = "ast2ir", path = "./libs/ast2ir" },
|
||||||
# { name = "ir", path = "./libs/ir" },
|
{ name = "ir", path = "./libs/ir" },
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ version = "0.1.0"
|
|||||||
authors = []
|
authors = []
|
||||||
description = ""
|
description = ""
|
||||||
|
|
||||||
# dependencies = []
|
dependencies = [
|
||||||
|
{ name = "scc_ast", path = "../ast" },
|
||||||
|
{ name = "scc_ir", path = "../ir" },
|
||||||
|
]
|
||||||
# features = {}
|
# features = {}
|
||||||
# default_features = []
|
# default_features = []
|
||||||
|
|||||||
141
libs/ast2ir/include/abi/win_x64_type_abi.h
Normal file
141
libs/ast2ir/include/abi/win_x64_type_abi.h
Normal 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__ */
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
#ifndef __SCC_AST2IR_H__
|
#ifndef __SCC_AST2IR_H__
|
||||||
#define __SCC_AST2IR_H__
|
#define __SCC_AST2IR_H__
|
||||||
|
|
||||||
#include <lexer_token.h>
|
#include "scc_type_abi.h"
|
||||||
#include <scc_ast.h>
|
#include <scc_ast.h>
|
||||||
#include <scc_ir.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__ */
|
#endif /* __SCC_AST2IR_H__ */
|
||||||
|
|||||||
14
libs/ast2ir/include/scc_type_abi.h
Normal file
14
libs/ast2ir/include/scc_type_abi.h
Normal 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__ */
|
||||||
@@ -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_ir_type_ref_vec_t params;
|
||||||
scc_vec_init(params);
|
scc_vec_init(params);
|
||||||
scc_vec_foreach(ast_type->function.param_types, i) {
|
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_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);
|
scc_vec_push(params, tmp_type);
|
||||||
}
|
}
|
||||||
ir_type.data.function.params = params;
|
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: {
|
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: {
|
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;
|
scc_ir_op_type_t op;
|
||||||
switch (expr->binary.op) {
|
switch (expr->binary.op) {
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
case SCC_AST_OP_ADD: op = IR_OP_ADD; break;
|
case SCC_AST_OP_ADD: op = SCC_IR_OP_ADD; break;
|
||||||
case SCC_AST_OP_SUB: op = IR_OP_SUB; break;
|
case SCC_AST_OP_SUB: op = SCC_IR_OP_SUB; break;
|
||||||
case SCC_AST_OP_MUL: op = IR_OP_MUL; break;
|
case SCC_AST_OP_MUL: op = SCC_IR_OP_MUL; break;
|
||||||
case SCC_AST_OP_DIV: op = IR_OP_DIV; break;
|
case SCC_AST_OP_DIV: op = SCC_IR_OP_DIV; break;
|
||||||
case SCC_AST_OP_MOD: op = IR_OP_MOD; break;
|
case SCC_AST_OP_MOD: op = SCC_IR_OP_MOD; break;
|
||||||
case SCC_AST_OP_LOGICAL_AND: op = IR_OP_AND; break;
|
case SCC_AST_OP_LOGICAL_AND: op = SCC_IR_OP_AND; break;
|
||||||
case SCC_AST_OP_LOGICAL_OR: op = IR_OP_OR; break;
|
case SCC_AST_OP_LOGICAL_OR: op = SCC_IR_OP_OR; break;
|
||||||
case SCC_AST_OP_BITWISE_XOR: op = IR_OP_XOR; break;
|
case SCC_AST_OP_BITWISE_XOR: op = SCC_IR_OP_XOR; break;
|
||||||
case SCC_AST_OP_LEFT_SHIFT: op = IR_OP_SHL; break;
|
case SCC_AST_OP_LEFT_SHIFT: op = SCC_IR_OP_SHL; break;
|
||||||
case SCC_AST_OP_RIGHT_SHIFT: op = IR_OP_SHR; break;
|
case SCC_AST_OP_RIGHT_SHIFT: op = SCC_IR_OP_SHR; break;
|
||||||
case SCC_AST_OP_EQUAL: op = IR_OP_EQ; break;
|
case SCC_AST_OP_EQUAL: op = SCC_IR_OP_EQ; break;
|
||||||
case SCC_AST_OP_NOT_EQUAL: op = IR_OP_NEQ; break;
|
case SCC_AST_OP_NOT_EQUAL: op = SCC_IR_OP_NEQ; break;
|
||||||
case SCC_AST_OP_LESS: op = IR_OP_LT; break;
|
case SCC_AST_OP_LESS: op = SCC_IR_OP_LT; break;
|
||||||
case SCC_AST_OP_LESS_EQUAL: op = IR_OP_LE; break;
|
case SCC_AST_OP_LESS_EQUAL: op = SCC_IR_OP_LE; break;
|
||||||
case SCC_AST_OP_GREATER: op = IR_OP_GT; break;
|
case SCC_AST_OP_GREATER: op = SCC_IR_OP_GT; break;
|
||||||
case SCC_AST_OP_GREATER_EQUAL: op = IR_OP_GE; break;
|
case SCC_AST_OP_GREATER_EQUAL: op = SCC_IR_OP_GE; break;
|
||||||
case SCC_AST_OP_ASSIGN: {
|
case SCC_AST_OP_ASSIGN: {
|
||||||
// 赋值表达式:存储右值到左值位置
|
// 赋值表达式:存储右值到左值位置
|
||||||
return scc_ir_builder_store(ctx, lhs, rhs);
|
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 */
|
/* clang-format on */
|
||||||
default:
|
default:
|
||||||
LOG_WARN("Unsupported binary operator: %d", expr->binary.op);
|
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) {
|
switch (expr->unary.op) {
|
||||||
case SCC_TOK_SUB:
|
case SCC_AST_OP_SUB:
|
||||||
// 负号
|
// 负号
|
||||||
// 实现为0 - operand
|
// 实现为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),
|
scc_ir_ctx_get_builtin_zero(&ctx->ctx),
|
||||||
operand);
|
operand);
|
||||||
case SCC_TOK_BIT_NOT:
|
case SCC_AST_OP_BITWISE_NOT:
|
||||||
// 按位取反
|
// 按位取反
|
||||||
return scc_ir_builder_binop(ctx, IR_OP_NOT, operand, 0);
|
return scc_ir_builder_binop(ctx, SCC_IR_OP_NOT, operand, 0);
|
||||||
case SCC_TOK_NOT:
|
case SCC_AST_OP_LOGICAL_NOT:
|
||||||
// 逻辑非
|
// 逻辑非
|
||||||
// 实现为与0比较
|
// 实现为与0比较
|
||||||
return scc_ir_builder_binop(
|
return scc_ir_builder_binop(ctx, SCC_IR_OP_EQ,
|
||||||
ctx, IR_OP_EQ, scc_ir_ctx_get_builtin_zero(&ctx->ctx), operand);
|
scc_ir_ctx_get_builtin_zero(&ctx->ctx),
|
||||||
|
operand);
|
||||||
default:
|
default:
|
||||||
LOG_WARN("Unsupported unary operator: %d", expr->unary.op);
|
LOG_WARN("Unsupported unary operator: %d", expr->unary.op);
|
||||||
return 0;
|
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);
|
// 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;
|
// 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_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) {
|
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: {
|
case SCC_AST_DECL_FUNC: {
|
||||||
// TODO params name
|
// TODO params name
|
||||||
scc_ir_type_ref_t func_type = ast_type_to_ir_type(ctx, decl->func.type);
|
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) {
|
if (decl->func.body) {
|
||||||
scc_ir_builder_begin_bblock(ctx, "entry");
|
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) {
|
if (tu == null || builder == null) {
|
||||||
LOG_ERROR("Invalid argument");
|
LOG_ERROR("Invalid argument");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化上下文
|
|
||||||
scc_ir_builder_init(builder);
|
|
||||||
|
|
||||||
// 转换所有声明
|
|
||||||
scc_vec_foreach(tu->declarations, i) {
|
scc_vec_foreach(tu->declarations, i) {
|
||||||
scc_ast_decl_t *decl = scc_vec_at(tu->declarations, i);
|
scc_ast_decl_t *decl = scc_vec_at(tu->declarations, i);
|
||||||
ast_decl_to_ir(builder, decl);
|
ast_decl_to_ir(builder, decl);
|
||||||
|
|||||||
0
libs/ast2ir/tests/test_ast2ir_unit.c
Normal file
0
libs/ast2ir/tests/test_ast2ir_unit.c
Normal file
@@ -23,17 +23,26 @@ typedef ir_handle_t scc_ir_func_ref_t;
|
|||||||
typedef SCC_VEC(scc_ir_func_ref_t) scc_ir_func_ref_vec_t;
|
typedef SCC_VEC(scc_ir_func_ref_t) scc_ir_func_ref_vec_t;
|
||||||
|
|
||||||
typedef enum scc_ir_type_tag {
|
typedef enum scc_ir_type_tag {
|
||||||
|
SCC_IR_TYPE_UNKNOWN,
|
||||||
SCC_IR_TYPE_VOID,
|
SCC_IR_TYPE_VOID,
|
||||||
SCC_IR_TYPE_I1,
|
|
||||||
SCC_IR_TYPE_I8,
|
SCC_IR_TYPE_I8,
|
||||||
SCC_IR_TYPE_I16,
|
SCC_IR_TYPE_I16,
|
||||||
SCC_IR_TYPE_I32,
|
SCC_IR_TYPE_I32,
|
||||||
SCC_IR_TYPE_I64,
|
SCC_IR_TYPE_I64,
|
||||||
SCC_IR_TYPE_I128,
|
SCC_IR_TYPE_I128,
|
||||||
|
|
||||||
|
SCC_IR_TYPE_U8,
|
||||||
|
SCC_IR_TYPE_U16,
|
||||||
|
SCC_IR_TYPE_U32,
|
||||||
|
SCC_IR_TYPE_U64,
|
||||||
|
SCC_IR_TYPE_U128,
|
||||||
|
|
||||||
SCC_IR_TYPE_F16,
|
SCC_IR_TYPE_F16,
|
||||||
SCC_IR_TYPE_F32,
|
SCC_IR_TYPE_F32,
|
||||||
SCC_IR_TYPE_F64,
|
SCC_IR_TYPE_F64,
|
||||||
SCC_IR_TYPE_F128,
|
SCC_IR_TYPE_F128,
|
||||||
|
|
||||||
SCC_IR_TYPE_PTR,
|
SCC_IR_TYPE_PTR,
|
||||||
SCC_IR_TYPE_ARRAY,
|
SCC_IR_TYPE_ARRAY,
|
||||||
SCC_IR_TYPE_FUNC,
|
SCC_IR_TYPE_FUNC,
|
||||||
@@ -76,56 +85,61 @@ struct scc_ir_func {
|
|||||||
typedef enum scc_ir_node_tag {
|
typedef enum scc_ir_node_tag {
|
||||||
SCC_IR_NODE_NULL,
|
SCC_IR_NODE_NULL,
|
||||||
SCC_IR_NODE_CONST_INT,
|
SCC_IR_NODE_CONST_INT,
|
||||||
SCC_IR_NODE_ALLOC,
|
SCC_IR_NODE_CONV, ///< 类型转换
|
||||||
SCC_IR_NODE_LOAD,
|
SCC_IR_NODE_FUNC_ARG_REF, ///< 函数参数引用
|
||||||
SCC_IR_NODE_STORE,
|
SCC_IR_NODE_BLOCK_ARG_REF, ///< 基本块参数引用
|
||||||
SCC_IR_NODE_GET_PTR,
|
SCC_IR_NODE_ALLOC, ///< 分配内存(stack)
|
||||||
SCC_IR_NODE_OP,
|
SCC_IR_NODE_GLOBAL_ALLOC, ///< 全局分配(bss)
|
||||||
SCC_IR_NODE_BRANCH,
|
SCC_IR_NODE_LOAD, ///< 加载数据
|
||||||
SCC_IR_NODE_JUMP,
|
SCC_IR_NODE_STORE, ///< 存储数据
|
||||||
SCC_IR_NODE_CALL,
|
SCC_IR_NODE_GET_PTR, ///< 获取指针
|
||||||
SCC_IR_NODE_RET,
|
SCC_IR_NODE_GET_ELEM_PTR, ///< 获取元素指针(used by array)
|
||||||
|
SCC_IR_NODE_OP, ///< 二元运算
|
||||||
|
SCC_IR_NODE_BRANCH, ///< 有条件分支
|
||||||
|
SCC_IR_NODE_JUMP, ///< 无条件跳转
|
||||||
|
SCC_IR_NODE_CALL, ///< 调用函数
|
||||||
|
SCC_IR_NODE_RET, ///< 函数返回
|
||||||
} scc_ir_node_tag_t;
|
} scc_ir_node_tag_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/// Empty op for init or nop
|
/// Empty op for init or nop
|
||||||
IR_OP_EMPTY,
|
SCC_IR_OP_EMPTY,
|
||||||
/// Not equal to.
|
/// Not equal to.
|
||||||
IR_OP_NEQ,
|
SCC_IR_OP_NEQ,
|
||||||
/// Equal to.
|
/// Equal to.
|
||||||
IR_OP_EQ,
|
SCC_IR_OP_EQ,
|
||||||
/// Greater than.
|
/// Greater than.
|
||||||
IR_OP_GT,
|
SCC_IR_OP_GT,
|
||||||
/// Less than.
|
/// Less than.
|
||||||
IR_OP_LT,
|
SCC_IR_OP_LT,
|
||||||
/// Greater than or equal to.
|
/// Greater than or equal to.
|
||||||
IR_OP_GE,
|
SCC_IR_OP_GE,
|
||||||
/// Less than or equal to.
|
/// Less than or equal to.
|
||||||
IR_OP_LE,
|
SCC_IR_OP_LE,
|
||||||
/// Addition.
|
/// Addition.
|
||||||
IR_OP_ADD,
|
SCC_IR_OP_ADD,
|
||||||
/// Subtraction.
|
/// Subtraction.
|
||||||
IR_OP_SUB,
|
SCC_IR_OP_SUB,
|
||||||
/// Multiplication.
|
/// Multiplication.
|
||||||
IR_OP_MUL,
|
SCC_IR_OP_MUL,
|
||||||
/// Division.
|
/// Division.
|
||||||
IR_OP_DIV,
|
SCC_IR_OP_DIV,
|
||||||
/// Modulo.
|
/// Modulo.
|
||||||
IR_OP_MOD,
|
SCC_IR_OP_MOD,
|
||||||
/// Bitwise AND.
|
/// Bitwise AND.
|
||||||
IR_OP_AND,
|
SCC_IR_OP_AND,
|
||||||
/// Bitwise OR.
|
/// Bitwise OR.
|
||||||
IR_OP_OR,
|
SCC_IR_OP_OR,
|
||||||
/// Bitwise XOR.
|
/// Bitwise XOR.
|
||||||
IR_OP_XOR,
|
SCC_IR_OP_XOR,
|
||||||
/// Bitwise NOT.
|
/// Bitwise NOT.
|
||||||
IR_OP_NOT,
|
SCC_IR_OP_NOT,
|
||||||
/// Shift left logical.
|
/// Shift left logical.
|
||||||
IR_OP_SHL,
|
SCC_IR_OP_SHL,
|
||||||
/// Shift right logical.
|
/// Shift right logical.
|
||||||
IR_OP_SHR,
|
SCC_IR_OP_SHR,
|
||||||
/// Shift right arithmetic.
|
/// Shift right arithmetic.
|
||||||
IR_OP_SAR,
|
SCC_IR_OP_SAR,
|
||||||
} scc_ir_op_type_t;
|
} scc_ir_op_type_t;
|
||||||
|
|
||||||
struct scc_ir_node {
|
struct scc_ir_node {
|
||||||
@@ -151,9 +165,17 @@ struct scc_ir_node {
|
|||||||
u8 uint_any[16];
|
u8 uint_any[16];
|
||||||
} const_uint;
|
} const_uint;
|
||||||
// aggregate;
|
// aggregate;
|
||||||
// func_arg_ref;
|
struct {
|
||||||
// block_arg_ref;
|
usize idx;
|
||||||
// global_alloc;
|
} arg_ref;
|
||||||
|
struct {
|
||||||
|
scc_ir_node_ref_vec_t elements;
|
||||||
|
} global_alloc;
|
||||||
|
struct {
|
||||||
|
scc_ir_node_ref_t operand;
|
||||||
|
scc_ir_type_ref_t target_type; // 目标类型
|
||||||
|
enum { CONV_SEXT, CONV_ZEXT, CONV_TRUNC } conv_type;
|
||||||
|
} conv;
|
||||||
struct {
|
struct {
|
||||||
scc_ir_node_ref_t target;
|
scc_ir_node_ref_t target;
|
||||||
} load;
|
} load;
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ void scc_ir_node_init(scc_ir_node_t *in, const char *name,
|
|||||||
in->data.get_ptr.index = 0;
|
in->data.get_ptr.index = 0;
|
||||||
break;
|
break;
|
||||||
case SCC_IR_NODE_OP:
|
case SCC_IR_NODE_OP:
|
||||||
in->data.op.op = IR_OP_EMPTY;
|
in->data.op.op = SCC_IR_OP_EMPTY;
|
||||||
in->data.op.lhs = 0;
|
in->data.op.lhs = 0;
|
||||||
in->data.op.rhs = 0;
|
in->data.op.rhs = 0;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -22,7 +22,11 @@ static u32 hash_type(const scc_ir_type_t *key) {
|
|||||||
|
|
||||||
switch (key->tag) {
|
switch (key->tag) {
|
||||||
case SCC_IR_TYPE_VOID:
|
case SCC_IR_TYPE_VOID:
|
||||||
case SCC_IR_TYPE_I1:
|
case SCC_IR_TYPE_U8:
|
||||||
|
case SCC_IR_TYPE_U16:
|
||||||
|
case SCC_IR_TYPE_U32:
|
||||||
|
case SCC_IR_TYPE_U64:
|
||||||
|
case SCC_IR_TYPE_U128:
|
||||||
case SCC_IR_TYPE_I8:
|
case SCC_IR_TYPE_I8:
|
||||||
case SCC_IR_TYPE_I16:
|
case SCC_IR_TYPE_I16:
|
||||||
case SCC_IR_TYPE_I32:
|
case SCC_IR_TYPE_I32:
|
||||||
@@ -70,7 +74,11 @@ static int cmp_type(const scc_ir_type_t *key1, const scc_ir_type_t *key2) {
|
|||||||
|
|
||||||
switch (key1->tag) {
|
switch (key1->tag) {
|
||||||
case SCC_IR_TYPE_VOID:
|
case SCC_IR_TYPE_VOID:
|
||||||
case SCC_IR_TYPE_I1:
|
case SCC_IR_TYPE_U8:
|
||||||
|
case SCC_IR_TYPE_U16:
|
||||||
|
case SCC_IR_TYPE_U32:
|
||||||
|
case SCC_IR_TYPE_U64:
|
||||||
|
case SCC_IR_TYPE_U128:
|
||||||
case SCC_IR_TYPE_I8:
|
case SCC_IR_TYPE_I8:
|
||||||
case SCC_IR_TYPE_I16:
|
case SCC_IR_TYPE_I16:
|
||||||
case SCC_IR_TYPE_I32:
|
case SCC_IR_TYPE_I32:
|
||||||
|
|||||||
@@ -31,13 +31,16 @@ static const char *get_node_type_str(scc_ir_node_tag_t tag) {
|
|||||||
// 获取操作符字符串
|
// 获取操作符字符串
|
||||||
static const char *get_op_str(scc_ir_op_type_t op) {
|
static const char *get_op_str(scc_ir_op_type_t op) {
|
||||||
static const char *ops[] = {
|
static const char *ops[] = {
|
||||||
[IR_OP_EMPTY] = "empty", [IR_OP_NEQ] = "!=", [IR_OP_EQ] = "==",
|
[SCC_IR_OP_EMPTY] = "empty", [SCC_IR_OP_NEQ] = "!=",
|
||||||
[IR_OP_GT] = ">", [IR_OP_LT] = "<", [IR_OP_GE] = ">=",
|
[SCC_IR_OP_EQ] = "==", [SCC_IR_OP_GT] = ">",
|
||||||
[IR_OP_LE] = "<=", [IR_OP_ADD] = "+", [IR_OP_SUB] = "-",
|
[SCC_IR_OP_LT] = "<", [SCC_IR_OP_GE] = ">=",
|
||||||
[IR_OP_MUL] = "*", [IR_OP_DIV] = "/", [IR_OP_MOD] = "%",
|
[SCC_IR_OP_LE] = "<=", [SCC_IR_OP_ADD] = "+",
|
||||||
[IR_OP_AND] = "&", [IR_OP_OR] = "|", [IR_OP_XOR] = "^",
|
[SCC_IR_OP_SUB] = "-", [SCC_IR_OP_MUL] = "*",
|
||||||
[IR_OP_NOT] = "~", [IR_OP_SHL] = "<<", [IR_OP_SHR] = ">>",
|
[SCC_IR_OP_DIV] = "/", [SCC_IR_OP_MOD] = "%",
|
||||||
[IR_OP_SAR] = ">>a", // Arithmetic shift right
|
[SCC_IR_OP_AND] = "&", [SCC_IR_OP_OR] = "|",
|
||||||
|
[SCC_IR_OP_XOR] = "^", [SCC_IR_OP_NOT] = "~",
|
||||||
|
[SCC_IR_OP_SHL] = "<<", [SCC_IR_OP_SHR] = ">>",
|
||||||
|
[SCC_IR_OP_SAR] = ">>a", // Arithmetic shift right
|
||||||
};
|
};
|
||||||
|
|
||||||
if (op >= 0 && op < sizeof(ops) / sizeof(ops[0]) && ops[op] != NULL) {
|
if (op >= 0 && op < sizeof(ops) / sizeof(ops[0]) && ops[op] != NULL) {
|
||||||
@@ -49,7 +52,9 @@ static const char *get_op_str(scc_ir_op_type_t op) {
|
|||||||
// 获取类型标签字符串
|
// 获取类型标签字符串
|
||||||
static const char *get_type_tag_str(scc_ir_type_tag_t tag) {
|
static const char *get_type_tag_str(scc_ir_type_tag_t tag) {
|
||||||
static const char *type_tags[] = {
|
static const char *type_tags[] = {
|
||||||
[SCC_IR_TYPE_VOID] = "void", [SCC_IR_TYPE_I1] = "i1",
|
[SCC_IR_TYPE_VOID] = "void", [SCC_IR_TYPE_U8] = "u8",
|
||||||
|
[SCC_IR_TYPE_U16] = "u16", [SCC_IR_TYPE_U32] = "u32",
|
||||||
|
[SCC_IR_TYPE_U64] = "u64", [SCC_IR_TYPE_U128] = "u128",
|
||||||
[SCC_IR_TYPE_I8] = "i8", [SCC_IR_TYPE_I16] = "i16",
|
[SCC_IR_TYPE_I8] = "i8", [SCC_IR_TYPE_I16] = "i16",
|
||||||
[SCC_IR_TYPE_I32] = "i32", [SCC_IR_TYPE_I64] = "i64",
|
[SCC_IR_TYPE_I32] = "i32", [SCC_IR_TYPE_I64] = "i64",
|
||||||
[SCC_IR_TYPE_I128] = "i128", [SCC_IR_TYPE_F16] = "f16",
|
[SCC_IR_TYPE_I128] = "i128", [SCC_IR_TYPE_F16] = "f16",
|
||||||
@@ -82,7 +87,7 @@ static void dump_const_int_node(scc_ir_dump_ctx_t *ctx,
|
|||||||
const scc_ir_node_t *node) {
|
const scc_ir_node_t *node) {
|
||||||
scc_tree_dump_push_level(ctx->dump_ctx, true);
|
scc_tree_dump_push_level(ctx->dump_ctx, true);
|
||||||
scc_tree_print_indent(ctx->dump_ctx);
|
scc_tree_print_indent(ctx->dump_ctx);
|
||||||
scc_printf("%d\n", node->data.const_int.int32);
|
scc_tree_dump_printf(ctx->dump_ctx, "%d\n", node->data.const_int.int32);
|
||||||
scc_tree_dump_pop_level(ctx->dump_ctx);
|
scc_tree_dump_pop_level(ctx->dump_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,13 +194,14 @@ static void dump_jump_node(scc_ir_dump_ctx_t *ctx, const scc_ir_node_t *node) {
|
|||||||
scc_ir_bblock_t *target_bblock =
|
scc_ir_bblock_t *target_bblock =
|
||||||
scc_ir_ctx_get_bblock(ctx->ir_ctx, node->data.jump.target_bblock);
|
scc_ir_ctx_get_bblock(ctx->ir_ctx, node->data.jump.target_bblock);
|
||||||
if (target_bblock) {
|
if (target_bblock) {
|
||||||
scc_printf("to '%s'", target_bblock->label ? target_bblock->label
|
scc_tree_dump_printf(ctx->dump_ctx, "to '%s'",
|
||||||
|
target_bblock->label ? target_bblock->label
|
||||||
: "<unnamed>");
|
: "<unnamed>");
|
||||||
} else {
|
} else {
|
||||||
scc_printf("to invalid block");
|
scc_tree_dump_printf(ctx->dump_ctx, "to invalid block");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
scc_printf("to NULL");
|
scc_tree_dump_printf(ctx->dump_ctx, "to NULL");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,16 +212,17 @@ static void dump_call_node(scc_ir_dump_ctx_t *ctx, const scc_ir_node_t *node) {
|
|||||||
scc_ir_func_t *callee =
|
scc_ir_func_t *callee =
|
||||||
scc_ir_ctx_get_func(ctx->ir_ctx, node->data.call.callee);
|
scc_ir_ctx_get_func(ctx->ir_ctx, node->data.call.callee);
|
||||||
if (callee) {
|
if (callee) {
|
||||||
scc_printf("func='%s'", callee->name ? callee->name : "<unnamed>");
|
scc_tree_dump_printf(ctx->dump_ctx, "func='%s'",
|
||||||
|
callee->name ? callee->name : "<unnamed>");
|
||||||
} else {
|
} else {
|
||||||
scc_printf("func=<invalid>");
|
scc_tree_dump_printf(ctx->dump_ctx, "func=<invalid>");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
scc_printf("func=NULL");
|
scc_tree_dump_printf(ctx->dump_ctx, "func=NULL");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scc_vec_size(node->data.call.args) > 0) {
|
if (scc_vec_size(node->data.call.args) > 0) {
|
||||||
scc_printf("\n");
|
scc_tree_dump_printf(ctx->dump_ctx, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 输出参数
|
// 输出参数
|
||||||
@@ -261,14 +268,14 @@ void scc_ir_dump_node(scc_ir_dump_ctx_t *ctx, scc_ir_node_ref_t node_ref) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node->type) {
|
if (node->type) {
|
||||||
scc_printf(" : ");
|
scc_tree_dump_printf(ctx->dump_ctx, " : ");
|
||||||
scc_ir_type_t *type = scc_ir_ctx_get_type(ctx->ir_ctx, node->type);
|
scc_ir_type_t *type = scc_ir_ctx_get_type(ctx->ir_ctx, node->type);
|
||||||
if (type) {
|
if (type) {
|
||||||
PRINT_VALUE(ctx->dump_ctx, "%s", get_type_tag_str(type->tag));
|
PRINT_VALUE(ctx->dump_ctx, "%s", get_type_tag_str(type->tag));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scc_printf("\n");
|
scc_tree_dump_printf(ctx->dump_ctx, "\n");
|
||||||
|
|
||||||
// 根据节点类型输出特定信息
|
// 根据节点类型输出特定信息
|
||||||
switch (node->tag) {
|
switch (node->tag) {
|
||||||
@@ -305,7 +312,7 @@ void scc_ir_dump_node(scc_ir_dump_ctx_t *ctx, scc_ir_node_ref_t node_ref) {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PRINT_QUOTED_VALUE(ctx->dump_ctx, "unknown");
|
PRINT_QUOTED_VALUE(ctx->dump_ctx, "unknown");
|
||||||
scc_printf("tag(%d)", node->tag);
|
scc_tree_dump_printf(ctx->dump_ctx, "tag(%d)", node->tag);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -325,7 +332,7 @@ void scc_ir_dump_type(scc_ir_dump_ctx_t *ctx, scc_ir_type_ref_t type_ref) {
|
|||||||
scc_tree_print_indent(ctx->dump_ctx);
|
scc_tree_print_indent(ctx->dump_ctx);
|
||||||
PRINT_NODE(ctx->dump_ctx, "Type: ");
|
PRINT_NODE(ctx->dump_ctx, "Type: ");
|
||||||
PRINT_QUOTED_VALUE(ctx->dump_ctx, get_type_tag_str(type->tag));
|
PRINT_QUOTED_VALUE(ctx->dump_ctx, get_type_tag_str(type->tag));
|
||||||
scc_printf("\n");
|
scc_tree_dump_printf(ctx->dump_ctx, "\n");
|
||||||
|
|
||||||
// 递归转储子类型
|
// 递归转储子类型
|
||||||
switch (type->tag) {
|
switch (type->tag) {
|
||||||
@@ -398,7 +405,7 @@ void scc_ir_dump_bblock(scc_ir_dump_ctx_t *ctx,
|
|||||||
PRINT_NODE(ctx->dump_ctx, "BasicBlock: ");
|
PRINT_NODE(ctx->dump_ctx, "BasicBlock: ");
|
||||||
PRINT_QUOTED_VALUE(ctx->dump_ctx,
|
PRINT_QUOTED_VALUE(ctx->dump_ctx,
|
||||||
bblock->label ? bblock->label : "<unnamed>");
|
bblock->label ? bblock->label : "<unnamed>");
|
||||||
scc_printf("\n");
|
scc_tree_dump_printf(ctx->dump_ctx, "\n");
|
||||||
|
|
||||||
// 转储基本块中的指令
|
// 转储基本块中的指令
|
||||||
for (usize i = 0; i < scc_vec_size(bblock->instrs); i++) {
|
for (usize i = 0; i < scc_vec_size(bblock->instrs); i++) {
|
||||||
@@ -422,7 +429,7 @@ void scc_ir_dump_func(scc_ir_dump_ctx_t *ctx, scc_ir_func_ref_t func_ref) {
|
|||||||
scc_tree_print_indent(ctx->dump_ctx);
|
scc_tree_print_indent(ctx->dump_ctx);
|
||||||
PRINT_NODE(ctx->dump_ctx, "Function: ");
|
PRINT_NODE(ctx->dump_ctx, "Function: ");
|
||||||
PRINT_QUOTED_VALUE(ctx->dump_ctx, func->name ? func->name : "<unnamed>");
|
PRINT_QUOTED_VALUE(ctx->dump_ctx, func->name ? func->name : "<unnamed>");
|
||||||
scc_printf("\n");
|
scc_tree_dump_printf(ctx->dump_ctx, "\n");
|
||||||
|
|
||||||
// 输出函数类型
|
// 输出函数类型
|
||||||
if (func->type) {
|
if (func->type) {
|
||||||
@@ -546,6 +553,7 @@ void scc_ir_dump_type_linear(scc_ir_dump_ctx_t *ctx,
|
|||||||
} else {
|
} else {
|
||||||
PRINT_TYPE(ctx->dump_ctx, ")");
|
PRINT_TYPE(ctx->dump_ctx, ")");
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("invalid type tag");
|
LOG_ERROR("invalid type tag");
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
void test_example() {
|
|
||||||
printf("Test passed!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
test_example();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -47,7 +47,7 @@ int main() {
|
|||||||
u32 idata_size = scc_pe_reserve_idata(&idata_builder);
|
u32 idata_size = scc_pe_reserve_idata(&idata_builder);
|
||||||
scc_pe_section_range idata_range = scc_pe_reserve_section_header(
|
scc_pe_section_range idata_range = scc_pe_reserve_section_header(
|
||||||
&builder, (BYTE *)".idata\0",
|
&builder, (BYTE *)".idata\0",
|
||||||
IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ |
|
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
|
||||||
IMAGE_SCN_MEM_WRITE,
|
IMAGE_SCN_MEM_WRITE,
|
||||||
idata_size, idata_size);
|
idata_size, idata_size);
|
||||||
scc_vec_at(builder.image_data_directory_vec, IMAGE_DIRECTORY_ENTRY_IMPORT) =
|
scc_vec_at(builder.image_data_directory_vec, IMAGE_DIRECTORY_ENTRY_IMPORT) =
|
||||||
@@ -97,6 +97,5 @@ int main() {
|
|||||||
scc_pe_write_section(&builder, &idata_range,
|
scc_pe_write_section(&builder, &idata_range,
|
||||||
scc_vec_unsafe_get_data(idata_buffer),
|
scc_vec_unsafe_get_data(idata_buffer),
|
||||||
scc_vec_size(idata_buffer));
|
scc_vec_size(idata_buffer));
|
||||||
|
|
||||||
scc_pe_dump_to_file(&builder, "hello_world.exe");
|
scc_pe_dump_to_file(&builder, "hello_world.exe");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ static void scc_winpe_hnt_builder_push(scc_winpe_hnt_builder_t *builder,
|
|||||||
scc_hashtable_set(&builder->str_map, name, (void *)(u64)builder->data.size);
|
scc_hashtable_set(&builder->str_map, name, (void *)(u64)builder->data.size);
|
||||||
|
|
||||||
/// FIXME WARNING需要转换为little endian
|
/// FIXME WARNING需要转换为little endian
|
||||||
scc_vec_push(builder->data, hint >> 8);
|
|
||||||
scc_vec_push(builder->data, hint & 0xff);
|
scc_vec_push(builder->data, hint & 0xff);
|
||||||
|
scc_vec_push(builder->data, hint >> 8);
|
||||||
|
|
||||||
while (*name) {
|
while (*name) {
|
||||||
scc_vec_push(builder->data, *name);
|
scc_vec_push(builder->data, *name);
|
||||||
|
|||||||
@@ -9,9 +9,10 @@
|
|||||||
#define __SCC_CORE_VEC_H__
|
#define __SCC_CORE_VEC_H__
|
||||||
|
|
||||||
#ifndef __SCC_CORE_VEC_USE_STD__
|
#ifndef __SCC_CORE_VEC_USE_STD__
|
||||||
|
#include "scc_core_log.h"
|
||||||
|
|
||||||
#include "scc_core_impl.h"
|
#include "scc_core_impl.h"
|
||||||
#include "scc_core_type.h"
|
#include "scc_core_type.h"
|
||||||
|
|
||||||
#define __scc_vec_realloc scc_realloc
|
#define __scc_vec_realloc scc_realloc
|
||||||
#define __scc_vec_free scc_free
|
#define __scc_vec_free scc_free
|
||||||
#else
|
#else
|
||||||
@@ -27,7 +28,7 @@ typedef size_t usize;
|
|||||||
#define LOG_FATAL(...) \
|
#define LOG_FATAL(...) \
|
||||||
do { \
|
do { \
|
||||||
printf(__VA_ARGS__); \
|
printf(__VA_ARGS__); \
|
||||||
exit(1); \
|
abort(); \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
39
src/main.c
39
src/main.c
@@ -3,9 +3,9 @@
|
|||||||
#include <scc_pproc.h>
|
#include <scc_pproc.h>
|
||||||
|
|
||||||
#include <ast_dump.h>
|
#include <ast_dump.h>
|
||||||
|
#include <ir_dump.h>
|
||||||
|
#include <scc_ast2ir.h>
|
||||||
#include <scc_parser.h>
|
#include <scc_parser.h>
|
||||||
// #include <ir_dump.h>
|
|
||||||
// #include <scc_ast2ir.h>
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *input_file;
|
const char *input_file;
|
||||||
@@ -332,20 +332,29 @@ sstream_drop:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scc_ir_builder_t ir_builder;
|
scc_ir_builder_t ir_builder;
|
||||||
// scc_ast2ir(translation_unit, &ir_builder);
|
scc_ir_builder_init(&ir_builder);
|
||||||
|
#include <abi/win_x64_type_abi.h>
|
||||||
|
scc_ast2ir_translation_unit(&ir_builder, translation_unit,
|
||||||
|
scc_win_x64_type_abi);
|
||||||
|
|
||||||
// if (config.emit_ir) {
|
if (config.emit_ir) {
|
||||||
// scc_ir_dump_ctx_t ir_dump_ctx;
|
scc_ir_dump_ctx_t ir_dump_ctx;
|
||||||
// scc_tree_dump_ctx_t tree_dump; // 仅为 ir dump 辅助
|
scc_tree_dump_ctx_t tree_dump;
|
||||||
// scc_tree_dump_ctx_init(&tree_dump, true);
|
if (fp == null) {
|
||||||
// scc_ir_dump_ctx_init(&ir_dump_ctx, &tree_dump, &ir_builder.cprog,
|
scc_tree_dump_ctx_init(&tree_dump, true, (void *)scc_fprintf,
|
||||||
// &ir_builder.ctx);
|
(void *)scc_stdout);
|
||||||
// // scc_ir_dump_cprog(&ir_dump_ctx);
|
} else {
|
||||||
// scc_ir_dump_cprog_linear(&ir_dump_ctx);
|
scc_tree_dump_ctx_init(&tree_dump, false, (void *)scc_fprintf,
|
||||||
// scc_tree_dump_ctx_drop(&tree_dump);
|
(void *)fp);
|
||||||
// return 0;
|
}
|
||||||
// }
|
scc_ir_dump_ctx_init(&ir_dump_ctx, &tree_dump, &ir_builder.cprog,
|
||||||
|
&ir_builder.ctx);
|
||||||
|
// scc_ir_dump_cprog(&ir_dump_ctx);
|
||||||
|
scc_ir_dump_cprog_linear(&ir_dump_ctx);
|
||||||
|
scc_tree_dump_ctx_drop(&tree_dump);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
scc_printf("output exe at %s\n", config.output_file);
|
scc_printf("output exe at %s\n", config.output_file);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user