From 3d57260f3fb2cf39a0522fe889d54e618315204e Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Wed, 26 Aug 2026 14:55:47 +0800 Subject: [PATCH] =?UTF-8?q?stage1=20=E5=AE=9E=E7=8E=B0=E9=83=A8=E5=88=86as?= =?UTF-8?q?t2ir=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stage1/spl_ast2ir.c | 89 +++++++++++++---- stage1/spl_ir.c | 233 ++++++++++++++++++++++++++++---------------- stage1/spl_ir.h | 56 ++++++++--- stage1/spl_sema.c | 42 ++++---- stage1/spl_type.c | 16 +-- stage1/spl_type.h | 10 +- 6 files changed, 298 insertions(+), 148 deletions(-) diff --git a/stage1/spl_ast2ir.c b/stage1/spl_ast2ir.c index 2f0aa54..b338f10 100644 --- a/stage1/spl_ast2ir.c +++ b/stage1/spl_ast2ir.c @@ -1,7 +1,12 @@ #include "spl_ast2ir.h" +static spl_ir_node_ref_t spl_ir_const_comptime_int(spl_ir_builder_t *ir, const spl_sema_t *sema, + usize i) { + return spl_ir_builder_type_const_int(ir, spl_type_builder_int(sema->type, 0, 0), i); +} + static spl_type_id_t tid_from_def(const spl_sema_t *sema, spl_def_id_t def) { - spl_def_node_t *d = spl_type_def(sema->type, def); + spl_def_node_t *d = spl_def_node(sema->type, def); return d ? d->type_id : 0; } @@ -25,18 +30,35 @@ static spl_ir_node_ref_t transit(spl_ir_builder_t *ir, const spl_sema_t *sema, TODO(); break; case SPL_AST_FN_DEFINE: { - spl_def_node_t *def = spl_type_def(sema->type, n->resolved_def_id); - Assert(def != NULL); - spl_ir_builder_fn_new(ir, n->fn_decl.name, def->type_id); + spl_type_id_t tid = tid_from_def(sema, n->resolved_def_id); + spl_type_node_t *fn_type = spl_type_node(sema->type, tid); + Assert(fn_type && fn_type->kind == SPL_TYPE_FN); + // n->fn_decl.attr_list; TODO @extern(vm) using extern attribute + spl_ir_builder_fn_begin(ir, n->fn_decl.name, tid, (spl_ir_attr_t){0} /*TODO*/); + + spl_ir_builder_block_begin(ir); vec_for(n->fn_decl.block, i) { transit(ir, sema, vec_at(n->fn_decl.block, i)); } + if (!ir->terminated) { + spl_ir_builder_control_ret(ir, n->fn_decl.type_expr, 0); + } + spl_ir_builder_block_end(ir); + spl_ir_builder_fn_end(ir); + } break; case SPL_AST_TYPE_DECL: TODO(); break; case SPL_AST_VAR_DECL: { + spl_type_id_t tid = tid_from_def(sema, n->resolved_def_id); + spl_ir_node_ref_t var_ref = + spl_ir_builder_mem_alloca(ir, tid, spl_ir_const_comptime_int(ir, sema, 1)); + if (n->var_const_decl.expr) { + spl_ir_builder_mem_store(ir, tid, var_ref, transit(ir, sema, n->var_const_decl.expr)); + } + } break; + case SPL_AST_CONST_DECL: { TODO(); } break; - case SPL_AST_CONST_DECL: case SPL_AST_MEMBER_DECL: TODO(); break; @@ -45,8 +67,18 @@ static spl_ir_node_ref_t transit(spl_ir_builder_t *ir, const spl_sema_t *sema, case SPL_AST_PARAM_DECL: break; case SPL_AST_ATTR_ITEM: - case SPL_AST_ARGG_INIT_ITEM: - case SPL_AST_IF_STATEMENT: + case SPL_AST_ARGG_INIT_ITEM: { + TODO(); + } break; + case SPL_AST_IF_STATEMENT: { + spl_ir_node_ref_t ref = transit(ir, sema, n->if_statement.expr); + ref = spl_ir_builder_control_br(ir, ref); + spl_ir_builder_block_end(ir); + usize true_block = spl_ir_builder_block_begin(ir); + + usize false_block = spl_ir_builder_block_begin(ir); + spl_ir_builder_control_br_fixup(ir, ref, true_block, false_block); + } break; case SPL_AST_IFVAR_STATEMENT: case SPL_AST_WHILE_STATEMENT: case SPL_AST_LOOP_STATEMENT: @@ -116,19 +148,43 @@ static spl_ir_node_ref_t transit(spl_ir_builder_t *ir, const spl_sema_t *sema, } case SPL_AST_EXPR_FLOAT_LIT: case SPL_AST_EXPR_CHAR_LIT: - case SPL_AST_EXPR_STRING_LIT: - case SPL_AST_EXPR_TRUE: - case SPL_AST_EXPR_FALSE: - case SPL_AST_EXPR_NULL: + case SPL_AST_EXPR_STRING_LIT: { + TODO(); + } break; + case SPL_AST_EXPR_TRUE: { + return spl_ir_builder_type_const_bool( + ir, spl_type_builder_simple(sema->type, SPL_TYPE_BOOL), true); + } break; + case SPL_AST_EXPR_FALSE: { + return spl_ir_builder_type_const_bool( + ir, spl_type_builder_simple(sema->type, SPL_TYPE_BOOL), false); + } + case SPL_AST_EXPR_NULL: { + return spl_ir_builder_type_const_bool(ir, n->resolved_type_id, 0); + } break; case SPL_AST_EXPR_UNDEFINED: break; case SPL_AST_EXPR_IDENT: { } break; - case SPL_AST_ARGGREGATE_INIT: - case SPL_AST_EXPR_EXPR: - case SPL_AST_ARRAY_LIT: - case SPL_AST_BUILTIN_EXPR: - case SPL_AST_BLOCK_EXPR: + case SPL_AST_ARGGREGATE_INIT: { + vec_for(n->primary_expr.aggregate_init.expr, i) { + transit(ir, sema, vec_at(n->primary_expr.aggregate_init.expr, i)); + } + } break; + case SPL_AST_EXPR_EXPR: { + transit(ir, sema, n->primary_expr.expr); + } break; + case SPL_AST_ARRAY_LIT: { + TODO(); + } break; + case SPL_AST_BUILTIN_EXPR: { + TODO(); + } break; + case SPL_AST_BLOCK_EXPR: { + vec_for(n->primary_expr.block_expr, i) { + transit(ir, sema, vec_at(n->primary_expr.block_expr, i)); + } + } break; case SPL_AST_BASE_TYPE_FN: case SPL_AST_BASE_TYPE_PATH: TODO(); @@ -157,7 +213,6 @@ static spl_ir_node_ref_t transit(spl_ir_builder_t *ir, const spl_sema_t *sema, case SPL_AST_TYPE__F64: case SPL_AST_TYPE_ANY: case SPL_AST_TYPE_IDENT: - TODO(); break; case SPL_AST_COUNT: UNREACHABLE(); diff --git a/stage1/spl_ir.c b/stage1/spl_ir.c index 79d7705..3683292 100644 --- a/stage1/spl_ir.c +++ b/stage1/spl_ir.c @@ -14,8 +14,8 @@ const char *spl_ir_kind_name(spl_ir_kind_t kind) { void spl_ir_init(spl_ir_t *ir) { vec_init(ir->funcs); vec_push(ir->funcs, (spl_ir_func_t){0}); - vec_init(ir->gdata); - vec_push(ir->gdata, (spl_ir_node_t){0}); + // vec_init(ir->gdata); + // vec_push(ir->gdata, (spl_ir_node_t){0}); } static void node_drop_vecs(spl_ir_node_t *n) { @@ -38,43 +38,52 @@ void spl_ir_drop(spl_ir_t *ir) { spl_ir_func_t *f = &vec_at(ir->funcs, i); vec_for(f->nodes, j) { node_drop_vecs(&vec_at(f->nodes, j)); } vec_free(f->nodes); - vec_free(f->labels); } vec_free(ir->funcs); - vec_for(ir->gdata, i) { node_drop_vecs(&vec_at(ir->gdata, i)); } - vec_free(ir->gdata); + // vec_for(ir->gdata, i) { node_drop_vecs(&vec_at(ir->gdata, i)); } + // vec_free(ir->gdata); } +// 申请空的 ir_func 返回 id spl_ir_func_ref_t spl_ir_alloc_fn(spl_ir_t *ir) { + if (ir == NULL) { + return 0; + } spl_ir_func_t f = {0}; vec_init(f.nodes); - vec_init(f.labels); - vec_push(f.nodes, (spl_ir_node_t){0}); /* 0 = error 哨兵 */ + vec_push(f.nodes, (spl_ir_node_t){0}); vec_push(ir->funcs, f); return vec_size(ir->funcs) - 1; } +// 从 fn_id 申请空的 ir_node 返回 id spl_ir_node_ref_t spl_ir_alloc_node(spl_ir_t *ir, spl_ir_func_ref_t fn_id) { - if (!fn_id || fn_id >= vec_size(ir->funcs)) + if (!fn_id || fn_id >= vec_size(ir->funcs)) { return 0; + } spl_ir_func_t *f = &vec_at(ir->funcs, fn_id); spl_ir_node_t n = {0}; vec_push(f->nodes, n); return vec_size(f->nodes) - 1; } +// 从 fn_id 里通过 node_id 获取 ir_node spl_ir_node_t *spl_ir_node(spl_ir_t *ir, spl_ir_func_ref_t fn_id, spl_ir_node_ref_t node_id) { - if (!fn_id || fn_id >= vec_size(ir->funcs)) + if (!fn_id || fn_id >= vec_size(ir->funcs)) { return NULL; + } spl_ir_func_t *f = &vec_at(ir->funcs, fn_id); - if (!node_id || node_id >= vec_size(f->nodes)) + if (!node_id || node_id >= vec_size(f->nodes)) { return NULL; + } return &vec_at(f->nodes, node_id); } +// 从 fn_id 获取 ir_func spl_ir_func_t *spl_ir_func(spl_ir_t *ir, spl_ir_func_ref_t fn_id) { - if (!fn_id || fn_id >= vec_size(ir->funcs)) + if (!fn_id || fn_id >= vec_size(ir->funcs)) { return NULL; + } return &vec_at(ir->funcs, fn_id); } @@ -279,102 +288,126 @@ void spl_ir_dump(spl_ir_t *ir, const spl_type_t *ty) { if (vec_size(func->nodes) == 0) printf(" (extern)\n"); } - if (vec_size(ir->gdata) > 1) { - printf("gdata:\n"); - vec_for(ir->gdata, i) { - if (i == 0) - continue; - spl_ir_node_t *node = &vec_at(ir->gdata, i); - printf(" #%zu ", i); - printf("%s", spl_ir_kind_name(node->kind)); - ir_dump_node(ty, node); - printf("\n"); - } - } + // if (vec_size(ir->gdata) > 1) { + // printf("gdata:\n"); + // vec_for(ir->gdata, i) { + // if (i == 0) + // continue; + // spl_ir_node_t *node = &vec_at(ir->gdata, i); + // printf(" #%zu ", i); + // printf("%s", spl_ir_kind_name(node->kind)); + // ir_dump_node(ty, node); + // printf("\n"); + // } + // } } // IR Builder +// 从当前 fn 申请新的 node 并注入到当前基本块 static spl_ir_node_ref_t builder_alloc_node(spl_ir_builder_t *b, spl_ir_kind_t kind) { + Assert(!b->terminated && "emit into a terminated block"); spl_ir_node_ref_t ref = spl_ir_alloc_node(&b->ir, b->current_fn); Assert(ref != 0); spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, ref); n->kind = kind; n->dbg = b->dbg; - b->current_node = ref; + if (b->current_block < vec_size(b->blocks)) { + vec_at(b->blocks, b->current_block) = ref; + } else { + Panic("unknown bblock"); + return 0; + } return ref; } -static spl_ir_func_t *builder_cur_func(spl_ir_builder_t *b) { - return spl_ir_func(&b->ir, b->current_fn); -} - -static void builder_reloc_add(spl_ir_builder_t *b, spl_ir_node_ref_t label) { - if (label == 0) { - LOG_WARN("reloc null lable"); - return; - } - spl_ir_func_t *f = builder_cur_func(b); - if (f && label < vec_size(f->nodes)) { - // resolved - return; - } - vec_for(b->reloc_label, i) { - if (vec_at(b->reloc_label, i) == label) { - return; - } - } - vec_push(b->reloc_label, label); -} - -static void builder_reloc_check(spl_ir_builder_t *b) { - spl_ir_func_t *f = builder_cur_func(b); - if (!f) - return; - vec_for(b->reloc_label, i) { - spl_ir_node_ref_t label = vec_at(b->reloc_label, i); - if (label >= vec_size(f->nodes)) { - LOG_ERROR("fn `%s`: forward label %%%zu unresolved", f->name ? f->name : "?", label); - } - } - b->reloc_label.size = 0; -} - void spl_ir_builder_init(spl_ir_builder_t *b) { spl_ir_init(&b->ir); b->current_fn = 0; - b->current_node = 0; b->dbg = (spl_dbg_node_t){0}; - vec_init(b->reloc_label); + vec_init(b->blocks); + b->current_block = 0; + vec_init(b->fixups); + b->terminated = false; } void spl_ir_builder_drop(spl_ir_builder_t *b) { spl_ir_drop(&b->ir); - vec_free(b->reloc_label); + vec_free(b->blocks); + vec_free(b->fixups); } -spl_ir_func_ref_t spl_ir_builder_fn_new(spl_ir_builder_t *b, const char *name, - spl_type_id_t fn_tid) { +spl_ir_func_ref_t spl_ir_builder_fn_begin(spl_ir_builder_t *b, const char *name, + spl_type_id_t fn_tid, spl_ir_attr_t attr) { if (b->current_fn) { - builder_reloc_check(b); + spl_ir_builder_fn_end(b); } spl_ir_func_ref_t fid = spl_ir_alloc_fn(&b->ir); spl_ir_func_t *f = spl_ir_func(&b->ir, fid); f->name = name; + f->attr = attr; f->fn_tid = fn_tid; + b->current_fn = fid; - b->current_node = 0; + b->current_block = 0; + b->blocks.size = 0; + b->fixups.size = 0; + b->terminated = false; return fid; } -spl_ir_func_ref_t spl_ir_builder_cur_fn(const spl_ir_builder_t *b) { return b->current_fn; } +void spl_ir_builder_fn_end(spl_ir_builder_t *b) { + spl_ir_func_t *f = spl_ir_func(&b->ir, b->current_fn); + if (!f) { + Panic("ir func not found"); + return; + } -void spl_ir_builder_set_dbg(spl_ir_builder_t *b, spl_dbg_node_t dbg) { b->dbg = dbg; } + vec_for(b->fixups, i) { + spl_ir_fix_t *fx = &vec_at(b->fixups, i); + spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, fx->node); + if (!n) { + SPL_ERROR(&n->dbg, "unknown node in func"); + continue; + } + spl_ir_node_ref_t target = 0; + if (fx->block < vec_size(b->blocks)) { + target = vec_at(b->blocks, fx->block); + } + if (target == 0) { + Panic("unknown reloc target bblock"); + } + switch (fx->slot) { + case SPL_IR_FIX_BR_TRUE: + n->control_br.true_label = target; + break; + case SPL_IR_FIX_BR_FALSE: + n->control_br.false_label = target; + break; + case SPL_IR_FIX_JMP: + n->control_jmp.label = target; + break; + } + } -spl_ir_node_ref_t spl_ir_builder_block_new(spl_ir_builder_t *b) { - spl_ir_func_t *f = builder_cur_func(b); - Assert(f != NULL); - return vec_size(f->nodes); + b->current_block = 0; + b->blocks.size = 0; + b->fixups.size = 0; + b->terminated = false; +} + +usize spl_ir_builder_block_begin(spl_ir_builder_t *b) { + vec_push(b->blocks, (spl_ir_block_t){0}); + usize block = vec_size(b->blocks) - 1; + b->current_block = block; + b->terminated = false; + return block; +} + +void spl_ir_builder_block_end(spl_ir_builder_t *b) { + if (!b->terminated) { + Panic("bblock must be end of terminated"); + } } #define X(name, kind) \ @@ -510,6 +543,22 @@ spl_ir_node_ref_t spl_ir_builder_mem_set(spl_ir_builder_t *b, spl_type_id_t tid, return ref; } +spl_ir_node_ref_t spl_ir_builder_type_const_bool(spl_ir_builder_t *b, spl_type_id_t tid, bool val) { + spl_ir_node_ref_t ref = builder_alloc_node(b, SPL_IR_TYPE_CONST); + spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, ref); + n->type_const.tid = tid; + n->type_const.bool_lit = val; + return ref; +} + +spl_ir_node_ref_t spl_ir_builder_type_const_ptr(spl_ir_builder_t *b, spl_type_id_t tid, void *val) { + spl_ir_node_ref_t ref = builder_alloc_node(b, SPL_IR_TYPE_CONST); + spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, ref); + n->type_const.tid = tid; + n->type_const.ptr_lit = val; + return ref; +} + spl_ir_node_ref_t spl_ir_builder_type_const_int(spl_ir_builder_t *b, spl_type_id_t tid, usize val) { spl_ir_node_ref_t ref = builder_alloc_node(b, SPL_IR_TYPE_CONST); spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, ref); @@ -640,27 +689,46 @@ spl_ir_node_ref_t spl_ir_builder_control_select(spl_ir_builder_t *b, spl_type_id return ref; } -spl_ir_node_ref_t spl_ir_builder_control_br(spl_ir_builder_t *b, spl_ir_node_ref_t cond, - spl_ir_node_ref_t true_label, - spl_ir_node_ref_t false_label) { - builder_reloc_add(b, true_label); - builder_reloc_add(b, false_label); +spl_ir_node_ref_t spl_ir_builder_control_br(spl_ir_builder_t *b, spl_ir_node_ref_t cond) { spl_ir_node_ref_t ref = builder_alloc_node(b, SPL_IR_CONTROL_BR); spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, ref); n->control_br.cond = cond; - n->control_br.true_label = true_label; - n->control_br.false_label = false_label; + n->control_br.true_label = 0; + n->control_br.false_label = 0; + b->terminated = true; return ref; } -spl_ir_node_ref_t spl_ir_builder_control_jmp(spl_ir_builder_t *b, spl_ir_node_ref_t label) { - builder_reloc_add(b, label); +void spl_ir_builder_control_br_fixup(spl_ir_builder_t *b, spl_ir_node_ref_t ref, usize true_block, + usize false_block) { + spl_ir_node_t *node = spl_ir_node(&b->ir, b->current_fn, ref); + if (!(node && node->kind == SPL_IR_CONTROL_BR)) { + Panic("fixup must be valid jmp ir node"); + } + spl_ir_fix_t f1 = {.node = ref, .slot = SPL_IR_FIX_BR_TRUE, .block = true_block}; + vec_push(b->fixups, f1); + spl_ir_fix_t f2 = {.node = ref, .slot = SPL_IR_FIX_BR_FALSE, .block = false_block}; + vec_push(b->fixups, f2); +} + +spl_ir_node_ref_t spl_ir_builder_control_jmp(spl_ir_builder_t *b) { spl_ir_node_ref_t ref = builder_alloc_node(b, SPL_IR_CONTROL_JMP); spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, ref); - n->control_jmp.label = label; + n->control_jmp.label = 0; + b->terminated = true; return ref; } +void spl_ir_builder_control_jmp_fixup(spl_ir_builder_t *b, spl_ir_node_ref_t ref, + usize target_block) { + spl_ir_node_t *node = spl_ir_node(&b->ir, b->current_fn, ref); + if (!(node && node->kind == SPL_IR_CONTROL_JMP)) { + Panic("fixup must be valid jmp ir node"); + } + spl_ir_fix_t fx = {.node = ref, .slot = SPL_IR_FIX_JMP, .block = target_block}; + vec_push(b->fixups, fx); +} + spl_ir_node_ref_t spl_ir_builder_control_call(spl_ir_builder_t *b, spl_type_id_t tid, spl_ir_node_ref_t func) { spl_ir_node_ref_t ref = builder_alloc_node(b, SPL_IR_CONTROL_CALL); @@ -693,6 +761,7 @@ spl_ir_node_ref_t spl_ir_builder_control_ret(spl_ir_builder_t *b, spl_type_id_t spl_ir_node_t *n = spl_ir_node(&b->ir, b->current_fn, ref); n->control_ret.tid = tid; n->control_ret.val = val; + b->terminated = true; return ref; } diff --git a/stage1/spl_ir.h b/stage1/spl_ir.h index 661f265..073dfc4 100644 --- a/stage1/spl_ir.h +++ b/stage1/spl_ir.h @@ -141,6 +141,8 @@ typedef struct { struct { spl_type_id_t tid; union { + bool bool_lit; + void *ptr_lit; usize int_lit; double float_lit; const char *cstr_lit; @@ -231,14 +233,21 @@ typedef struct { spl_ir_attr_t attr; spl_type_id_t fn_tid; spl_ir_node_vec_t nodes; - spl_ir_node_ref_vec_t labels; } spl_ir_func_t; - typedef VEC(spl_ir_func_t) spl_ir_func_vec_t; +typedef spl_ir_node_ref_t spl_ir_block_t; +typedef VEC(spl_ir_block_t) spl_ir_block_vec_t; + +typedef struct { + spl_ir_node_ref_t node; + enum { SPL_IR_FIX_BR_TRUE, SPL_IR_FIX_BR_FALSE, SPL_IR_FIX_JMP } slot; + spl_ir_node_ref_t block; +} spl_ir_fix_t; +typedef VEC(spl_ir_fix_t) spl_ir_fix_vec_t; + typedef struct { spl_ir_func_vec_t funcs; - spl_ir_node_vec_t gdata; } spl_ir_t; void spl_ir_init(spl_ir_t *ir); @@ -255,10 +264,12 @@ const char *spl_ir_kind_name(spl_ir_kind_t kind); typedef struct { spl_ir_t ir; - spl_ir_func_ref_t current_fn; - spl_ir_node_ref_t current_node; - spl_ir_node_ref_vec_t reloc_label; spl_dbg_node_t dbg; + spl_ir_func_ref_t current_fn; /* 当前函数 */ + spl_ir_node_ref_t current_block; /* 当前发射块(0 = 未设) */ + spl_ir_block_vec_t blocks; /* 当前函数的基本块表 */ + spl_ir_fix_vec_t fixups; /* 跳转回填表 */ + bool terminated; /* 当前块已以 br/jmp/ret 终止 */ } spl_ir_builder_t; /* clang-format off */ @@ -300,12 +311,12 @@ typedef struct { void spl_ir_builder_init(spl_ir_builder_t *b); void spl_ir_builder_drop(spl_ir_builder_t *b); -spl_ir_func_ref_t spl_ir_builder_fn_new(spl_ir_builder_t *b, const char *name, - spl_type_id_t fn_tid); -spl_ir_func_ref_t spl_ir_builder_cur_fn(const spl_ir_builder_t *b); -void spl_ir_builder_set_dbg(spl_ir_builder_t *b, spl_dbg_node_t dbg); +spl_ir_func_ref_t spl_ir_builder_fn_begin(spl_ir_builder_t *b, const char *name, + spl_type_id_t fn_tid, spl_ir_attr_t attr); +void spl_ir_builder_fn_end(spl_ir_builder_t *b); -spl_ir_node_ref_t spl_ir_builder_block_new(spl_ir_builder_t *b); +usize spl_ir_builder_block_begin(spl_ir_builder_t *b); +void spl_ir_builder_block_end(spl_ir_builder_t *b); #define X(name, kind) \ spl_ir_node_ref_t spl_ir_builder_##name(spl_ir_builder_t *b, spl_type_id_t tid, \ @@ -331,6 +342,8 @@ SPL_IR_CMP_TABLE SPL_IR_CAST_TABLE #undef X +/* memory */ + spl_ir_node_ref_t spl_ir_builder_mem_alloca(spl_ir_builder_t *b, spl_type_id_t tid, spl_ir_node_ref_t count); spl_ir_node_ref_t spl_ir_builder_mem_global_alloc(spl_ir_builder_t *b, spl_type_id_t tid, @@ -350,6 +363,10 @@ spl_ir_node_ref_t spl_ir_builder_mem_set(spl_ir_builder_t *b, spl_type_id_t tid, spl_ir_node_ref_t dst, spl_ir_node_ref_t val, spl_ir_node_ref_t size); +/* type const */ + +spl_ir_node_ref_t spl_ir_builder_type_const_ptr(spl_ir_builder_t *b, spl_type_id_t tid, void *val); +spl_ir_node_ref_t spl_ir_builder_type_const_bool(spl_ir_builder_t *b, spl_type_id_t tid, bool val); spl_ir_node_ref_t spl_ir_builder_type_const_int(spl_ir_builder_t *b, spl_type_id_t tid, usize val); spl_ir_node_ref_t spl_ir_builder_type_const_float(spl_ir_builder_t *b, spl_type_id_t tid, double val); @@ -358,6 +375,9 @@ spl_ir_node_ref_t spl_ir_builder_type_const_cstr(spl_ir_builder_t *b, spl_type_i spl_ir_node_ref_t spl_ir_builder_type_const_char(spl_ir_builder_t *b, spl_type_id_t tid, char val); spl_ir_node_ref_t spl_ir_builder_type_const_fn(spl_ir_builder_t *b, spl_type_id_t tid, spl_ir_func_ref_t val); + +/* type */ + spl_ir_node_ref_t spl_ir_builder_type_bitsizeof(spl_ir_builder_t *b, spl_type_id_t tid); spl_ir_node_ref_t spl_ir_builder_type_sizeof(spl_ir_builder_t *b, spl_type_id_t tid); spl_ir_node_ref_t spl_ir_builder_type_alignof(spl_ir_builder_t *b, spl_type_id_t tid); @@ -365,6 +385,8 @@ spl_ir_node_ref_t spl_ir_builder_type_offsetof(spl_ir_builder_t *b, spl_type_id_ spl_ir_node_ref_t field_idx); spl_ir_node_ref_t spl_ir_builder_type_field_count(spl_ir_builder_t *b, spl_type_id_t tid); +/* agg */ + spl_ir_node_ref_t spl_ir_builder_agg_construct(spl_ir_builder_t *b, spl_type_id_t tid); void spl_ir_builder_agg_construct_field(spl_ir_builder_t *b, spl_ir_node_ref_t node, spl_ir_node_ref_t field); @@ -374,13 +396,17 @@ spl_ir_node_ref_t spl_ir_builder_agg_extract(spl_ir_builder_t *b, spl_type_id_t spl_ir_node_ref_t spl_ir_builder_agg_insert(spl_ir_builder_t *b, spl_type_id_t tid, usize field_idx, spl_ir_node_ref_t agg, spl_ir_node_ref_t field); +/* control */ + spl_ir_node_ref_t spl_ir_builder_control_select(spl_ir_builder_t *b, spl_type_id_t tid, spl_ir_node_ref_t cond, spl_ir_node_ref_t true_val, spl_ir_node_ref_t false_val); -spl_ir_node_ref_t spl_ir_builder_control_br(spl_ir_builder_t *b, spl_ir_node_ref_t cond, - spl_ir_node_ref_t true_label, - spl_ir_node_ref_t false_label); -spl_ir_node_ref_t spl_ir_builder_control_jmp(spl_ir_builder_t *b, spl_ir_node_ref_t label); +spl_ir_node_ref_t spl_ir_builder_control_br(spl_ir_builder_t *b, spl_ir_node_ref_t cond); +void spl_ir_builder_control_br_fixup(spl_ir_builder_t *b, spl_ir_node_ref_t ref, usize true_block, + usize false_block); +spl_ir_node_ref_t spl_ir_builder_control_jmp(spl_ir_builder_t *b); +void spl_ir_builder_control_jmp_fixup(spl_ir_builder_t *b, spl_ir_node_ref_t ref, + usize target_block); spl_ir_node_ref_t spl_ir_builder_control_call(spl_ir_builder_t *b, spl_type_id_t tid, spl_ir_node_ref_t func); void spl_ir_builder_control_call_param(spl_ir_builder_t *b, spl_ir_node_ref_t node, diff --git a/stage1/spl_sema.c b/stage1/spl_sema.c index 87a2c64..b39fb56 100644 --- a/stage1/spl_sema.c +++ b/stage1/spl_sema.c @@ -29,7 +29,7 @@ bool spl_scope_insert(spl_scope_t *scope, spl_scope_id_t id, spl_symbol_t symbol spl_symbol_t old = {0}; spl_scope_node_t *node = &vec_at(scope->scopes, id); if (map_get(node->symbols, symbol.name, &old)) { - // spl_type_def(sema->type, old); TODO debug node + // spl_def_node(sema->type, old); TODO debug node SPL_ERROR(&(spl_dbg_node_t){0}, "find same symbol %s", symbol.name); return false; } @@ -61,7 +61,7 @@ static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) { case SPL_AST_CONTAINER_MEMBERS: { symbol.name = "$file"; symbol.kind = SPL_SYMBOL_KIND_TYPE; - symbol.node = spl_type_def_alloc(sema->type, SPL_DEF_AGG, "$file", n->dbg, ref); + symbol.node = spl_def_alloc(sema->type, SPL_DEF_AGG, "$file", n->dbg, ref); n->resolved_def_id = symbol.node; spl_scope_id_t scope_id = spl_scope_alloc(sema->scope); @@ -86,7 +86,7 @@ static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) { case SPL_AST_TYPE_UNION: case SPL_AST_TYPE_ENUM: case SPL_AST_TYPE_SHAPE: /* TODO for shape */ - symbol.node = spl_type_def_alloc(sema->type, SPL_DEF_AGG, symbol.name, te->dbg, ref); + symbol.node = spl_def_alloc(sema->type, SPL_DEF_AGG, symbol.name, te->dbg, ref); n->resolved_def_id = symbol.node; spl_scope_id_t scope_id = spl_scope_alloc(sema->scope); spl_scope_id_t old_id = sema->scope->current_scope; @@ -99,7 +99,7 @@ static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) { sema->scope->current_scope = old_id; break; default: - symbol.node = spl_type_def_alloc(sema->type, SPL_DEF_SCALAR, symbol.name, te->dbg, ref); + symbol.node = spl_def_alloc(sema->type, SPL_DEF_SCALAR, symbol.name, te->dbg, ref); n->resolved_def_id = symbol.node; spl_scope_insert(sema->scope, sema->scope->current_scope, symbol); break; @@ -109,7 +109,7 @@ static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) { case SPL_AST_FN_DEFINE: { symbol.name = n->fn_decl.name; symbol.kind = SPL_SYMBOL_KIND_FN; - symbol.node = spl_type_def_alloc(sema->type, SPL_DEF_FN_PARAMS, symbol.name, n->dbg, ref); + symbol.node = spl_def_alloc(sema->type, SPL_DEF_FN, symbol.name, n->dbg, ref); n->resolved_def_id = symbol.node; // TODO same type avaliable insert twice for decl and define but define must only once spl_scope_insert(sema->scope, sema->scope->current_scope, symbol); @@ -118,7 +118,7 @@ static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) { case SPL_AST_CONST_DECL: { symbol.name = n->var_const_decl.name; symbol.kind = SPL_SYMBOL_KIND_VAR; - symbol.node = spl_type_def_alloc(sema->type, SPL_DEF_VAR, symbol.name, n->dbg, ref); + symbol.node = spl_def_alloc(sema->type, SPL_DEF_VAR, symbol.name, n->dbg, ref); n->resolved_def_id = symbol.node; spl_scope_insert(sema->scope, sema->scope->current_scope, symbol); } break; @@ -304,7 +304,7 @@ static spl_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { spl_type_id_t fntid = spl_type_builder_fn( sema->type, ret_id, vec_unsafe_get_data(params_type), vec_size(params_type)); // Move params_type don't need free - spl_type_def_resolve(sema->type, n->resolved_def_id, fntid); + spl_def_resolve(sema->type, n->resolved_def_id, fntid); break; } case SPL_AST_FN_DEFINE: { @@ -329,7 +329,7 @@ static spl_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { vec_push(params_type, tid); if (node->resolved_def_id) { - spl_type_def_resolve(sema->type, node->resolved_def_id, tid); + spl_def_resolve(sema->type, node->resolved_def_id, tid); } } spl_type_id_t ret_id = sema_parse(sema, n->fn_decl.type_expr); @@ -337,7 +337,7 @@ static spl_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { spl_type_id_t fntid = spl_type_builder_fn( sema->type, ret_id, vec_unsafe_get_data(params_type), vec_size(params_type)); // Move params_type don't need free - spl_type_def_resolve(sema->type, n->resolved_def_id, fntid); + spl_def_resolve(sema->type, n->resolved_def_id, fntid); spl_type_id_t old_ret = sema->current_fn_ret_tid; sema->current_fn_ret_tid = ret_id; @@ -384,7 +384,7 @@ static spl_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { spl_type_builder_int(sema->type, 32, 1), layout); // Move members don't need free - spl_type_def_resolve(sema->type, n->resolved_def_id, tid); + spl_def_resolve(sema->type, n->resolved_def_id, tid); /* 第二遍:方法 body(struct 类型已 resolve,可引用自身类型) */ vec_for(te->type_expr.aggregate_list, i) { spl_ast_node_ref_t mref = vec_at(te->type_expr.aggregate_list, i); @@ -401,7 +401,7 @@ static spl_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { break; default: { spl_type_id_t tid = sema_parse(sema, n->type_decl.type_expr); - spl_type_def_resolve(sema->type, n->resolved_def_id, tid); + spl_def_resolve(sema->type, n->resolved_def_id, tid); break; } } @@ -412,7 +412,7 @@ static spl_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { spl_symbol_t symbol = {0}; symbol.name = n->var_const_decl.name; symbol.kind = SPL_SYMBOL_KIND_VAR; - symbol.node = spl_type_def_alloc(sema->type, SPL_DEF_VAR, symbol.name, n->dbg, ref); + symbol.node = spl_def_alloc(sema->type, SPL_DEF_VAR, symbol.name, n->dbg, ref); n->resolved_def_id = symbol.node; spl_scope_insert(sema->scope, sema->scope->current_scope, symbol); } @@ -431,7 +431,7 @@ static spl_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { SPL_ERROR(&n->dbg, "decl type must not none %d"); sema->error_count += 1; } - spl_type_def_resolve(sema->type, n->resolved_def_id, decl_tid); + spl_def_resolve(sema->type, n->resolved_def_id, decl_tid); } break; case SPL_AST_MEMBER_DECL: { /* 字段/变体不建 def, 类型由 TYPE_DECL 组装成员时统一构造 */ @@ -449,7 +449,7 @@ static spl_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { spl_symbol_t symbol = {0}; symbol.name = n->param_decl.name; symbol.kind = SPL_SYMBOL_KIND_VAR; - symbol.node = spl_type_def_alloc(sema->type, SPL_DEF_VAR, symbol.name, n->dbg, ref); + symbol.node = spl_def_alloc(sema->type, SPL_DEF_VAR, symbol.name, n->dbg, ref); n->resolved_def_id = symbol.node; spl_scope_insert(sema->scope, sema->scope->current_scope, symbol); } @@ -457,7 +457,7 @@ static spl_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { if (n->param_decl.type_expr) { ptid = sema_parse(sema, n->param_decl.type_expr); } - spl_type_def_resolve(sema->type, n->resolved_def_id, ptid); + spl_def_resolve(sema->type, n->resolved_def_id, ptid); return ptid; } break; case SPL_AST_ATTR_ITEM: @@ -526,8 +526,8 @@ static spl_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { spl_symbol_t symbol = {0}; symbol.name = vname; symbol.kind = SPL_SYMBOL_KIND_VAR; - symbol.node = spl_type_def_alloc(sema->type, SPL_DEF_VAR, vname, n->dbg, eref); - spl_type_def_resolve(sema->type, symbol.node, etid); + symbol.node = spl_def_alloc(sema->type, SPL_DEF_VAR, vname, n->dbg, eref); + spl_def_resolve(sema->type, symbol.node, etid); spl_scope_insert(sema->scope, sema->scope->current_scope, symbol); } } @@ -894,7 +894,7 @@ static spl_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { } Assert(symbol.node != 0); n->resolved_def_id = symbol.node; - spl_def_node_t *d = spl_type_def(sema->type, symbol.node); + spl_def_node_t *d = spl_def_node(sema->type, symbol.node); Assert(d != 0); return d->type_id; } @@ -911,7 +911,7 @@ static spl_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { sema->error_count++; break; } - spl_def_node_t *d = spl_type_def(sema->type, sym.node); + spl_def_node_t *d = spl_def_node(sema->type, sym.node); spl_type_id_t tid = d ? d->type_id : 0; spl_type_node_t *tn = spl_type_node(sema->type, tid); if (!tn || (tn->kind != SPL_TYPE_STRUCT && tn->kind != SPL_TYPE_UNION)) { @@ -987,7 +987,7 @@ static spl_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref) { if (vec_size(n->type_expr.type_path.ident_vec) == 1) { spl_symbol_t sym = {0}; if (spl_scope_find(sema->scope, tname, &sym)) { - spl_def_node_t *d = spl_type_def(sema->type, sym.node); + spl_def_node_t *d = spl_def_node(sema->type, sym.node); if (d && d->type_id) { n->resolved_type_id = d->type_id; return d->type_id; @@ -1136,7 +1136,7 @@ void spl_sema_dump(spl_sema_t *sema) { vec_for(sema->type->def_table, i) { printf(" def#%zu ", i); spl_type_def_dump(sema->type, i); - spl_def_node_t *d = spl_type_def(sema->type, i); + spl_def_node_t *d = spl_def_node(sema->type, i); printf("\n"); } } diff --git a/stage1/spl_type.c b/stage1/spl_type.c index 5bea977..0e7a2bb 100644 --- a/stage1/spl_type.c +++ b/stage1/spl_type.c @@ -304,8 +304,8 @@ spl_type_id_t spl_type_builder_agg(spl_type_t *type, spl_type_node_kind_t tk, return spl_type_node_push(type, &tn); } -spl_def_id_t spl_type_def_alloc(spl_type_t *type, spl_def_node_kind_t kind, const char *name, - spl_dbg_node_t dbg, usize ast_node_ref) { +spl_def_id_t spl_def_alloc(spl_type_t *type, spl_def_node_kind_t kind, const char *name, + spl_dbg_node_t dbg, usize ast_node_ref) { spl_def_node_t n = {0}; n.kind = kind; n.name = name; @@ -315,8 +315,8 @@ spl_def_id_t spl_type_def_alloc(spl_type_t *type, spl_def_node_kind_t kind, cons return vec_size(type->def_table) - 1; } -void spl_type_def_resolve(spl_type_t *type, spl_def_id_t id, spl_type_id_t tid) { - spl_def_node_t *d = spl_type_def(type, id); +void spl_def_resolve(spl_type_t *type, spl_def_id_t id, spl_type_id_t tid) { + spl_def_node_t *d = spl_def_node(type, id); if (!d) { return; } @@ -383,7 +383,7 @@ spl_type_node_t *spl_type_node(spl_type_t *type, spl_type_id_t id) { return &vec_at(type->type_table, id); } -spl_def_node_t *spl_type_def(spl_type_t *type, spl_def_id_t id) { +spl_def_node_t *spl_def_node(spl_type_t *type, spl_def_id_t id) { if (!id || id >= vec_size(type->def_table)) return NULL; return &vec_at(type->def_table, id); @@ -497,7 +497,7 @@ void spl_type_pure_dump(spl_type_t *type, spl_type_id_t id) { } void spl_type_def_dump(spl_type_t *type, spl_def_id_t id) { - spl_def_node_t *node = spl_type_def(type, id); + spl_def_node_t *node = spl_def_node(type, id); if (!node) { printf("none"); return; @@ -517,8 +517,8 @@ void spl_type_def_dump(spl_type_t *type, spl_def_id_t id) { case SPL_DEF_VAR: def_kind_name = "var"; break; - case SPL_DEF_FN_PARAMS: - def_kind_name = "fn_params"; + case SPL_DEF_FN: + def_kind_name = "fn"; break; case SPL_DEF_AGG: def_kind_name = "agg"; diff --git a/stage1/spl_type.h b/stage1/spl_type.h index 654f293..04f0f1d 100644 --- a/stage1/spl_type.h +++ b/stage1/spl_type.h @@ -83,7 +83,7 @@ typedef enum { SPL_DEF_SCALAR, SPL_DEF_MEMBER, SPL_DEF_VAR, - SPL_DEF_FN_PARAMS, + SPL_DEF_FN, SPL_DEF_AGG, // include enum variants SPL_DEF_DISTINCT, // newtype SPL_DEF_ALIAS, // sametypes @@ -112,11 +112,11 @@ void spl_type_def_dump(spl_type_t *type, spl_def_id_t id); void spl_type_pure_dump(spl_type_t *type, spl_type_id_t id); spl_type_node_t *spl_type_node(spl_type_t *type, spl_type_id_t id); -spl_def_node_t *spl_type_def(spl_type_t *type, spl_def_id_t id); +spl_def_node_t *spl_def_node(spl_type_t *type, spl_def_id_t id); -spl_type_id_t spl_type_def_alloc(spl_type_t *type, spl_def_node_kind_t kind, const char *name, - spl_dbg_node_t dbg, usize ast_node_ref); -void spl_type_def_resolve(spl_type_t *type, spl_def_id_t id, spl_type_id_t tid); +spl_type_id_t spl_def_alloc(spl_type_t *type, spl_def_node_kind_t kind, const char *name, + spl_dbg_node_t dbg, usize ast_node_ref); +void spl_def_resolve(spl_type_t *type, spl_def_id_t id, spl_type_id_t tid); spl_type_id_t spl_type_fn_param_tid(spl_type_t *type, spl_type_id_t fn_tid, usize idx); const spl_type_member_t *spl_type_agg_member(spl_type_t *type, spl_type_id_t tid, const char *name);