stage1 实现并修复ast2ir的核心功能的正确性

This commit is contained in:
zzy committed 2026-09-12 09:46:56 +08:00
1 parent 49ccdec3dd
commit 87d9b7ea34
7 files changed
+1408 -110

No files matched your search

+96 -17
View File
@@ -8,11 +8,8 @@ static spl_type_id_t to_ir_type(spl_ast2ir_t *a, spl_lang_type_id_t lang) {
}
static spl_lang_type_id_t node_lang(spl_ast2ir_t *a, spl_ast_node_t *n) {
if (!n)
return 0;
if (n->kind == SPL_AST_EXPR_IDENT)
return spl_def_get_lang_id(a->sema->type, n->resolved_def_id);
return n->resolved_type_id;
(void)a;
return n ? n->resolved_lang_tid : 0;
}
static spl_type_id_t node_ir(spl_ast2ir_t *a, spl_ast_node_t *n) {
@@ -30,27 +27,48 @@ static void emit_stmt(spl_ast2ir_t *a, spl_ast_node_ref_t ref);
static void emit_decl(spl_ast2ir_t *a, spl_ast_node_ref_t ref);
static void emit_fn(spl_ast2ir_t *a, spl_ast_node_t *n);
static void emit_container(spl_ast2ir_t *a, spl_ast_node_ref_t ref);
static spl_ir_node_ref_t emit_cast(spl_ast2ir_t *a, spl_ast_node_t *n);
static spl_ir_node_ref_t ast2ir_intrin_call(spl_ast2ir_t *a, spl_ast_node_t *n, spl_intrin_t in);
static spl_ir_node_ref_t emit_cast(spl_ast2ir_t *a, spl_ast_node_t *n);
static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref);
static spl_ir_node_ref_t emit_implicit_cast(spl_ast2ir_t *a, spl_type_id_t ft, spl_type_id_t tt,
spl_ir_node_ref_t v);
static spl_ir_node_ref_t ast2ir_intrin_call(spl_ast2ir_t *a, spl_ast_node_t *n, spl_intrin_t in,
spl_ast_node_ref_vec_t *args);
static spl_ir_node_ref_t ast2ir_intrin_field(spl_ast2ir_t *a, spl_ast_node_t *n, spl_intrin_t in);
static spl_ir_node_ref_t ast2ir_intrin_len(spl_ast2ir_t *a, spl_ast_node_t *n);
static spl_ir_node_ref_t ast2ir_intrin_call(spl_ast2ir_t *a, spl_ast_node_t *n, spl_intrin_t in) {
static spl_ir_node_ref_t ast2ir_intrin_call(spl_ast2ir_t *a, spl_ast_node_t *n, spl_intrin_t in,
spl_ast_node_ref_vec_t *args) {
switch (in) {
case SPL_INTRIN_SIZEOF: {
spl_ast_node_t *arg = spl_ast_node(a->sema->ast, vec_at(n->call.args, 0));
spl_ast_node_t *arg = spl_ast_node(a->sema->ast, vec_at(*args, 0));
return spl_ir_builder_type_sizeof(a->ir, node_ir(a, arg));
}
case SPL_INTRIN_ALIGNOF: {
spl_ast_node_t *arg = spl_ast_node(a->sema->ast, vec_at(n->call.args, 0));
spl_ast_node_t *arg = spl_ast_node(a->sema->ast, vec_at(*args, 0));
return spl_ir_builder_type_alignof(a->ir, node_ir(a, arg));
}
case SPL_INTRIN_ASSERT: {
/* 目前 SEMA 只做类型检查,emit 阶段留空,
@assert 展开需待 control.trap 语义明确后再实现 */
spl_ir_node_ref_t cond = emit_expr(a, vec_at(*args, 0));
if (!cond)
return 0;
spl_lang_type_id_t b = spl_lang_make_bool(a->sema->type);
spl_ir_node_ref_t notc = spl_ir_builder_arith_not(a->ir, to_ir_type(a, b), cond);
spl_ir_node_ref_t br = spl_ir_builder_control_br(a->ir, notc);
spl_ir_builder_block_end(a->ir);
usize trap_blk = spl_ir_builder_block_begin(a->ir);
spl_ir_builder_control_trap(a->ir);
spl_ir_builder_block_end(a->ir);
usize cont_blk = spl_ir_builder_block_begin(a->ir);
spl_ir_builder_control_br_fixup(a->ir, br, trap_blk, cont_blk);
return 0;
}
case SPL_INTRIN_BREAKPOINT:
return spl_ir_builder_dbg_breakpoint(a->ir);
default:
UNREACHABLE();
}
@@ -198,7 +216,7 @@ static spl_ir_node_ref_t emit_lvalue(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
}
static spl_ir_node_ref_t emit_cast(spl_ast2ir_t *a, spl_ast_node_t *n) {
spl_ir_node_ref_t v = emit_expr(a, n->cast.expr);
spl_ir_node_ref_t v = emit_expr_raw(a, n->cast.expr);
if (!v)
return 0;
spl_ast_node_t *src = spl_ast_node(a->sema->ast, n->cast.expr);
@@ -238,6 +256,28 @@ static spl_ir_node_ref_t emit_cast(spl_ast2ir_t *a, spl_ast_node_t *n) {
}
static spl_ir_node_ref_t emit_expr(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
spl_ir_node_ref_t val = emit_expr_raw(a, ref);
if (!val)
return 0;
spl_ast_node_t *n = spl_ast_node(a->sema->ast, ref);
if (!n || n->expected_lang_tid == 0)
return val;
spl_lang_type_id_t from = n->resolved_lang_tid;
spl_lang_type_id_t to = n->expected_lang_tid;
if (!from || from == to)
return val;
spl_type_id_t from_ir = to_ir_type(a, from);
spl_type_id_t to_ir = to_ir_type(a, to);
if (!from_ir || !to_ir || from_ir == to_ir)
return val;
return emit_implicit_cast(a, from_ir, to_ir, val);
}
static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
spl_ast_node_t *n = spl_ast_node(a->sema->ast, ref);
if (!n)
return 0;
@@ -396,7 +436,7 @@ static spl_ir_node_ref_t emit_expr(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
if (callee && callee->kind == SPL_AST_EXPR_IDENT) {
spl_intrin_t in = spl_intrin_lookup_call(callee->ident.name);
if (in != SPL_INTRIN_NONE)
return ast2ir_intrin_call(a, n, in);
return ast2ir_intrin_call(a, n, in, &n->call.args);
}
spl_ir_node_ref_t fn = emit_expr(a, n->call.callee);
@@ -573,9 +613,12 @@ static spl_ir_node_ref_t emit_expr(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
spl_ir_builder_agg_construct_field(a->ir, node, len);
return node;
}
case SPL_AST_EXPR_COMPTIME_CALL:
// TODO
return 0;
case SPL_AST_EXPR_COMPTIME_CALL: {
spl_intrin_t in = spl_intrin_lookup_call(n->comptime_call.name);
if (in == SPL_INTRIN_NONE)
return 0;
return ast2ir_intrin_call(a, n, in, &n->comptime_call.args);
}
default:
TODO();
return 0;
@@ -959,6 +1002,42 @@ static void emit_container(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
}
}
static spl_ir_node_ref_t emit_implicit_cast(spl_ast2ir_t *a, spl_type_id_t ft, spl_type_id_t tt,
spl_ir_node_ref_t v) {
if (!ft || !tt || ft == tt)
return v;
spl_type_node_t *fs = spl_type_node(a->sema->type, ft);
spl_type_node_t *ts = spl_type_node(a->sema->type, tt);
if (!fs || !ts)
return v;
if (fs->kind == SPL_TYPE_INT && ts->kind == SPL_TYPE_INT) {
if (fs->int_type.bits == ts->int_type.bits)
return spl_ir_builder_cast_bitcast(a->ir, ft, tt, v);
if (fs->int_type.bits > ts->int_type.bits)
return spl_ir_builder_cast_trunc(a->ir, ft, tt, v);
if (fs->int_type.is_signed)
return spl_ir_builder_cast_sext(a->ir, ft, tt, v);
return spl_ir_builder_cast_zext(a->ir, ft, tt, v);
}
if (fs->kind == SPL_TYPE_INT && ts->kind == SPL_TYPE_FLOAT)
return spl_ir_builder_case_int2float(a->ir, ft, tt, v);
if (fs->kind == SPL_TYPE_FLOAT && ts->kind == SPL_TYPE_INT)
return spl_ir_builder_case_float2int(a->ir, ft, tt, v);
if (fs->kind == SPL_TYPE_FLOAT && ts->kind == SPL_TYPE_FLOAT) {
if (fs->float_type.bits > ts->float_type.bits)
return spl_ir_builder_cast_ftrunc(a->ir, ft, tt, v);
return spl_ir_builder_cast_fext(a->ir, ft, tt, v);
}
if (fs->kind == SPL_TYPE_BOOL && ts->kind == SPL_TYPE_INT)
return spl_ir_builder_cast_bool2int(a->ir, ft, tt, v);
if (fs->kind == SPL_TYPE_PTR && ts->kind == SPL_TYPE_INT)
return spl_ir_builder_cast_ptr2int(a->ir, ft, tt, v);
if (fs->kind == SPL_TYPE_INT && ts->kind == SPL_TYPE_PTR)
return spl_ir_builder_cast_int2ptr(a->ir, ft, tt, v);
return spl_ir_builder_cast_bitcast(a->ir, ft, tt, v);
}
static usize spl_int_map_hash(usize k) { return MAP_HASH_INT(k); }
static int spl_int_map_cmp(usize a, usize b) { return MAP_CMP_INT(a, b); }