From a621e34d51d53d8ca185419677546d1c7f3e0fde Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Mon, 14 Sep 2026 18:11:58 +0800 Subject: [PATCH] =?UTF-8?q?stage1=20=E6=94=AF=E6=8C=81=E4=BB=BB=E6=84=8F?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F=E5=A3=B0=E6=98=8E=20=E4=BD=BF=E7=94=A8eval?= =?UTF-8?q?=E6=B1=82=E5=80=BC=E7=9A=84=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stage1/spl_ast2ir.c | 107 ++++++++++++---- stage1/spl_ir.c | 21 ++++ stage1/spl_ir.h | 3 + stage1/spl_sema.c | 298 ++++++++++++++++++++++++++++++++------------ stage1/spl_type.c | 16 +-- stage1/spl_type.h | 14 ++- 6 files changed, 336 insertions(+), 123 deletions(-) diff --git a/stage1/spl_ast2ir.c b/stage1/spl_ast2ir.c index f04984b..ef3231f 100644 --- a/stage1/spl_ast2ir.c +++ b/stage1/spl_ast2ir.c @@ -25,8 +25,10 @@ static spl_ir_node_ref_t emit_expr(spl_ast2ir_t *a, spl_ast_node_ref_t ref); static spl_ir_node_ref_t emit_lvalue(spl_ast2ir_t *a, spl_ast_node_ref_t ref); 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 void emit_fn_reserve(spl_ast2ir_t *a, spl_ast_node_t *n); +static void emit_fn_body(spl_ast2ir_t *a, spl_ast_node_t *n); +static void emit_container_reserve(spl_ast2ir_t *a, spl_ast_node_ref_t ref); +static void emit_container_body(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 emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref); @@ -1085,16 +1087,13 @@ static void emit_decl(spl_ast2ir_t *a, spl_ast_node_ref_t ref) { } return; } - case SPL_AST_FN_DECL: - emit_fn(a, n); - return; default: return; } } -static void emit_fn(spl_ast2ir_t *a, spl_ast_node_t *n) { - if (!n->resolved_def_id) +static void emit_fn_reserve(spl_ast2ir_t *a, spl_ast_node_t *n) { + if (!n || !n->resolved_def_id) return; spl_lang_type_id_t fn_lang = spl_def_get_lang_id(a->sema->type, n->resolved_def_id); @@ -1106,10 +1105,26 @@ static void emit_fn(spl_ast2ir_t *a, spl_ast_node_t *n) { if (!fn_ir) return; - spl_ir_func_ref_t fn_ref = spl_ir_builder_fn_begin(a->ir, n->fn_decl.name, fn_ir); + spl_ir_func_ref_t fn_ref = spl_ir_builder_fn_reserve(a->ir, n->fn_decl.name, fn_ir); map_put(a->def2ir_map, n->resolved_def_id, (spl_ir_node_ref_t)fn_ref); copy_attrs_to_ir_func(a, n, fn_ref); +} + +static void emit_fn_body(spl_ast2ir_t *a, spl_ast_node_t *n) { + if (!n || !n->resolved_def_id) + return; + + spl_ir_func_ref_t fn_ref = 0; + if (!map_get(a->def2ir_map, n->resolved_def_id, &fn_ref)) + return; + + spl_lang_type_id_t fn_lang = spl_def_get_lang_id(a->sema->type, n->resolved_def_id); + spl_lang_type_node_t *fn_ln = spl_lang_type_node(a->sema->type, fn_lang); + if (!fn_ln || fn_ln->kind != SPL_LANG_TYPE_FN) + return; + + spl_ir_builder_fn_begin_at(a->ir, fn_ref); spl_lang_type_id_t saved_ret = a->cur_ret_lang; a->cur_ret_lang = fn_ln->extra.fn.ret; @@ -1158,12 +1173,6 @@ static void emit_fn(spl_ast2ir_t *a, spl_ast_node_t *n) { } } - /* 兜底清理: - * - 若 body 已显式 return,defer 栈可能已被清空到 defer_base 之下 - * (被 return 逻辑弹过),此时 vec_size <= defer_base,无需处理。 - * - 若 body 里开了 loop 却没关(理论上不会,sema 已保证), - * 这里的 while 只是防止异常路径残留。 - */ while (vec_size(a->defer_stack) > defer_base) { spl_ast_node_ref_t d = vec_pop(a->defer_stack); (void)d; @@ -1180,28 +1189,43 @@ static void emit_fn(spl_ast2ir_t *a, spl_ast_node_t *n) { spl_ir_builder_fn_end(a->ir); } -static void emit_aggregate_fns(spl_ast2ir_t *a, spl_ast_node_t *te) { +static void emit_aggregate_fns_reserve(spl_ast2ir_t *a, spl_ast_node_t *te) { for (usize i = 0; i < vec_size(te->type_aggregate.members); ++i) { spl_ast_node_t *mn = spl_ast_node(a->sema->ast, vec_at(te->type_aggregate.members, i)); if (!mn) continue; if (mn->kind == SPL_AST_FN_DECL) { - emit_fn(a, mn); + emit_fn_reserve(a, mn); } else if (mn->kind == SPL_AST_MEMBER_DECL && mn->member_decl.type_expr) { spl_ast_node_t *mt = spl_ast_node(a->sema->ast, mn->member_decl.type_expr); if (mt && mt->kind == SPL_AST_TYPE_AGGREGATE) - emit_aggregate_fns(a, mt); + emit_aggregate_fns_reserve(a, mt); } } } -static void emit_container(spl_ast2ir_t *a, spl_ast_node_ref_t ref) { +static void emit_aggregate_fns_body(spl_ast2ir_t *a, spl_ast_node_t *te) { + for (usize i = 0; i < vec_size(te->type_aggregate.members); ++i) { + spl_ast_node_t *mn = spl_ast_node(a->sema->ast, vec_at(te->type_aggregate.members, i)); + if (!mn) + continue; + if (mn->kind == SPL_AST_FN_DECL) { + emit_fn_body(a, mn); + } else if (mn->kind == SPL_AST_MEMBER_DECL && mn->member_decl.type_expr) { + spl_ast_node_t *mt = spl_ast_node(a->sema->ast, mn->member_decl.type_expr); + if (mt && mt->kind == SPL_AST_TYPE_AGGREGATE) + emit_aggregate_fns_body(a, mt); + } + } +} + +static void emit_container_reserve(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; if (n->kind == SPL_AST_TOP_LEVEL_BLOCK) { if (n->top_level_block.block) - emit_container(a, n->top_level_block.block); + emit_container_reserve(a, n->top_level_block.block); return; } if (n->kind != SPL_AST_CONTAINER_MEMBERS) @@ -1214,16 +1238,52 @@ static void emit_container(spl_ast2ir_t *a, spl_ast_node_ref_t ref) { continue; switch (d->kind) { case SPL_AST_FN_DECL: - emit_fn(a, d); + emit_fn_reserve(a, d); break; case SPL_AST_TYPE_DECL: { spl_ast_node_t *te = spl_ast_node(a->sema->ast, d->type_decl.type_expr); if (te && te->kind == SPL_AST_TYPE_AGGREGATE) - emit_aggregate_fns(a, te); + emit_aggregate_fns_reserve(a, te); break; } case SPL_AST_TOP_LEVEL_BLOCK: - emit_container(a, dref); + emit_container_reserve(a, dref); + break; + default: + break; + } + } +} + +static void emit_container_body(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; + if (n->kind == SPL_AST_TOP_LEVEL_BLOCK) { + if (n->top_level_block.block) + emit_container_body(a, n->top_level_block.block); + return; + } + if (n->kind != SPL_AST_CONTAINER_MEMBERS) + return; + + for (usize i = 0; i < vec_size(n->container_members.declarations); ++i) { + spl_ast_node_ref_t dref = vec_at(n->container_members.declarations, i); + spl_ast_node_t *d = spl_ast_node(a->sema->ast, dref); + if (!d) + continue; + switch (d->kind) { + case SPL_AST_FN_DECL: + emit_fn_body(a, d); + break; + case SPL_AST_TYPE_DECL: { + spl_ast_node_t *te = spl_ast_node(a->sema->ast, d->type_decl.type_expr); + if (te && te->kind == SPL_AST_TYPE_AGGREGATE) + emit_aggregate_fns_body(a, te); + break; + } + case SPL_AST_TOP_LEVEL_BLOCK: + emit_container_body(a, dref); break; default: break; @@ -1295,5 +1355,6 @@ void spl_ast2ir_run(spl_ast2ir_t *ast2ir) { spl_ast_node_t *root = spl_ast_node(ast, ast->root); if (!root || root->kind != SPL_AST_ROOT) return; - emit_container(ast2ir, root->root.members); + emit_container_reserve(ast2ir, root->root.members); + emit_container_body(ast2ir, root->root.members); } diff --git a/stage1/spl_ir.c b/stage1/spl_ir.c index 95f95f7..55e69c5 100644 --- a/stage1/spl_ir.c +++ b/stage1/spl_ir.c @@ -387,6 +387,27 @@ spl_ir_func_ref_t spl_ir_builder_fn_begin(spl_ir_builder_t *b, const char *name, return fid; } +spl_ir_func_ref_t spl_ir_builder_fn_reserve(spl_ir_builder_t *b, const char *name, + spl_type_id_t fn_tid) { + 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; + vec_init(f->attrs); + f->fn_tid = fn_tid; + return fid; +} + +void spl_ir_builder_fn_begin_at(spl_ir_builder_t *b, spl_ir_func_ref_t fid) { + if (b->current_fn && b->current_fn != fid) { + spl_ir_builder_fn_end(b); + } + b->current_fn = fid; + b->current_block = 0; + b->blocks.size = 0; + b->fixups.size = 0; + b->terminated = false; +} + 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) { diff --git a/stage1/spl_ir.h b/stage1/spl_ir.h index 0203a11..c111378 100644 --- a/stage1/spl_ir.h +++ b/stage1/spl_ir.h @@ -311,6 +311,9 @@ void spl_ir_builder_drop(spl_ir_builder_t *b); 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_func_ref_t spl_ir_builder_fn_reserve(spl_ir_builder_t *b, const char *name, + spl_type_id_t fn_tid); +void spl_ir_builder_fn_begin_at(spl_ir_builder_t *b, spl_ir_func_ref_t fid); void spl_ir_builder_fn_end(spl_ir_builder_t *b); usize spl_ir_builder_block_begin(spl_ir_builder_t *b); diff --git a/stage1/spl_sema.c b/stage1/spl_sema.c index 49fbf82..4577f8d 100644 --- a/stage1/spl_sema.c +++ b/stage1/spl_sema.c @@ -145,6 +145,8 @@ static spl_lang_type_id_t sema_check(spl_sema_t *sema, spl_ast_node_ref_t ref, static spl_lang_type_id_t sema_intrin_call(spl_sema_t *sema, spl_ast_node_t *n, spl_intrin_t in, spl_ast_node_ref_vec_t *args); static spl_lang_type_id_t sema_intrin_field(spl_sema_t *sema, spl_ast_node_t *n, spl_intrin_t in); +static spl_lang_type_id_t sema_eval_decl(spl_sema_t *sema, spl_def_id_t def_id); +static spl_lang_type_id_t sema_infer_fn_signature(spl_sema_t *sema, spl_ast_node_t *n); static bool sema_is_infer(spl_sema_t *sema, spl_lang_type_id_t tid) { spl_lang_type_node_t *n = spl_lang_type_node(sema->type, tid); @@ -200,13 +202,38 @@ static spl_lang_type_id_t sema_for_elem_type(spl_sema_t *sema, spl_lang_type_id_ } } -static spl_lang_type_id_t sema_build_aggregate(spl_sema_t *sema, spl_ast_node_t *te) { +static spl_lang_type_id_t sema_infer_fn_signature(spl_sema_t *sema, spl_ast_node_t *n) { + if (!n || n->resolved_def_id == 0) + return 0; + spl_def_node_t *def = spl_def_node(sema->type, n->resolved_def_id); + if (def && def->lang_id != 0) + return def->lang_id; + + spl_lang_type_id_vec_t param_types; + vec_init(param_types); + for (usize i = 0; i < vec_size(n->fn_decl.params); ++i) { + spl_ast_node_t *pd = spl_ast_node(sema->ast, vec_at(n->fn_decl.params, i)); + if (pd && pd->kind == SPL_AST_PARAM_DECL && pd->param_decl.type_expr) + vec_push(param_types, sema_infer(sema, pd->param_decl.type_expr)); + else + vec_push(param_types, spl_lang_make_varargs(sema->type)); + } + spl_lang_type_id_t ret_tid = sema_infer(sema, n->fn_decl.ret_type); + if (ret_tid == 0) + ret_tid = spl_lang_make_unit(sema->type); + spl_lang_type_id_t fn_tid = spl_lang_make_fn( + sema->type, ret_tid, vec_unsafe_get_data(param_types), vec_size(param_types)); + vec_free(param_types); + spl_def_resolve(sema->type, n->resolved_def_id, fn_tid); + return fn_tid; +} + +static spl_lang_type_id_t sema_build_aggregate(spl_sema_t *sema, spl_ast_node_t *te, + spl_def_id_t owner_def_id) { spl_type_member_vec_t members; vec_init(members); spl_lang_method_vec_t methods; vec_init(methods); - spl_ast_node_ref_vec_t fn_nodes; - vec_init(fn_nodes); for (usize i = 0; i < vec_size(te->type_aggregate.members); ++i) { spl_ast_node_ref_t mref = vec_at(te->type_aggregate.members, i); @@ -224,9 +251,11 @@ static spl_lang_type_id_t sema_build_aggregate(spl_sema_t *sema, spl_ast_node_t spl_def_id_t fn_def = spl_def_alloc(sema->type, SPL_DEF_FN, mn->fn_decl.name, mn->dbg, mref); mn->resolved_def_id = fn_def; + spl_def_node_t *fn_d = spl_def_node(sema->type, fn_def); + if (fn_d) + fn_d->owner_def = owner_def_id; spl_lang_method_t meth = {.name = mn->fn_decl.name, .def_id = fn_def}; vec_push(methods, meth); - vec_push(fn_nodes, mref); } } @@ -267,19 +296,81 @@ static spl_lang_type_id_t sema_build_aggregate(spl_sema_t *sema, spl_ast_node_t ln.kind = lk; ln.ir_type_id = agg_ir; ln.methods = methods; - spl_lang_type_id_t agg_lang = spl_lang_node_push(sema->type, &ln); - - spl_lang_type_id_t saved_agg = sema->current_aggregate_lang; - sema->current_aggregate_lang = agg_lang; - for (usize i = 0; i < vec_size(fn_nodes); ++i) - sema_infer(sema, vec_at(fn_nodes, i)); - sema->current_aggregate_lang = saved_agg; - - vec_free(fn_nodes); - return agg_lang; + return spl_lang_node_push(sema->type, &ln); } -static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) { +static spl_lang_type_id_t sema_eval_decl(spl_sema_t *sema, spl_def_id_t def_id) { + spl_def_node_t *def = spl_def_node(sema->type, def_id); + if (!def) + return 0; + + if (def->state == SPL_DECL_RESOLVED || def->state == SPL_DECL_ERROR) + return def->lang_id; + + if (def->lang_id != 0) { + def->state = SPL_DECL_RESOLVED; + return def->lang_id; + } + + if (def->state == SPL_DECL_RESOLVING) { + SPL_ERROR(&def->dbg_node, "circular dependency on `%s`", def->name ? def->name : "?"); + sema->error_count++; + def->state = SPL_DECL_ERROR; + return 0; + } + + def->state = SPL_DECL_RESOLVING; + + spl_ast_node_t *n = spl_ast_node(sema->ast, def->ast_node_ref); + spl_lang_type_id_t result = 0; + + if (n) { + switch (n->kind) { + case SPL_AST_TYPE_DECL: { + if (n->type_decl.type_expr) { + spl_ast_node_t *te = spl_ast_node(sema->ast, n->type_decl.type_expr); + if (te && te->kind == SPL_AST_TYPE_AGGREGATE) + result = sema_build_aggregate(sema, te, def_id); + else + result = sema_infer(sema, n->type_decl.type_expr); + } + n->resolved_lang_tid = result; + break; + } + case SPL_AST_FN_DECL: { + spl_lang_type_id_t saved_agg = sema->current_aggregate_lang; + if (def->owner_def) { + spl_def_node_t *owner = spl_def_node(sema->type, def->owner_def); + if (owner && owner->lang_id != 0) + sema->current_aggregate_lang = owner->lang_id; + } + result = sema_infer_fn_signature(sema, n); + sema->current_aggregate_lang = saved_agg; + break; + } + case SPL_AST_VAR_DECL: + case SPL_AST_CONST_DECL: { + if (n->var_const_decl.type) + result = sema_infer(sema, n->var_const_decl.type); + else if (n->var_const_decl.init_expr) + result = sema_infer(sema, n->var_const_decl.init_expr); + break; + } + default: + break; + } + } + + def->lang_id = result; + spl_def_node_t *final_def = spl_def_node(sema->type, def_id); + if (final_def) { + final_def->lang_id = result; + final_def->state = result ? SPL_DECL_RESOLVED : SPL_DECL_ERROR; + } + return result; +} + +static void sema_collect_names(spl_sema_t *sema, spl_ast_node_ref_t ref) { spl_ast_node_t *n = spl_ast_node(sema->ast, ref); if (!n) return; @@ -303,7 +394,7 @@ static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) { spl_scope_insert(sema->scope, mod_scope, file_sym); for (usize i = 0; i < vec_size(n->container_members.declarations); ++i) { - sema_collect(sema, vec_at(n->container_members.declarations, i)); + sema_collect_names(sema, vec_at(n->container_members.declarations, i)); } /* 故意不恢复 current_scope @@ -351,7 +442,7 @@ static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) { } case SPL_AST_TOP_LEVEL_BLOCK: if (n->top_level_block.block) { - sema_collect(sema, n->top_level_block.block); + sema_collect_names(sema, n->top_level_block.block); } break; default: @@ -359,6 +450,43 @@ static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) { } } +static void sema_collect_types(spl_sema_t *sema, spl_ast_node_ref_t ref) { + spl_ast_node_t *n = spl_ast_node(sema->ast, ref); + if (!n) + return; + switch (n->kind) { + case SPL_AST_CONTAINER_MEMBERS: + for (usize i = 0; i < vec_size(n->container_members.declarations); ++i) { + spl_ast_node_ref_t dref = vec_at(n->container_members.declarations, i); + spl_ast_node_t *d = spl_ast_node(sema->ast, dref); + if (d && d->kind == SPL_AST_TYPE_DECL && d->resolved_def_id) + sema_eval_decl(sema, d->resolved_def_id); + } + break; + case SPL_AST_TOP_LEVEL_BLOCK: + if (n->top_level_block.block) + sema_collect_types(sema, n->top_level_block.block); + break; + default: + break; + } +} + +static void sema_collect_signatures(spl_sema_t *sema) { + usize n = vec_size(sema->type->def_table); + for (usize i = 1; i < n; ++i) { + spl_def_node_t *d = &vec_at(sema->type->def_table, i); + if (d->kind == SPL_DEF_FN && d->state == SPL_DECL_UNRESOLVED) + sema_eval_decl(sema, i); + } +} + +static void sema_collect(spl_sema_t *sema, spl_ast_node_ref_t ref) { + sema_collect_names(sema, ref); + sema_collect_types(sema, ref); + sema_collect_signatures(sema); +} + static spl_lang_type_id_t sema_intrin_call(spl_sema_t *sema, spl_ast_node_t *n, spl_intrin_t in, spl_ast_node_ref_vec_t *args) { const spl_intrin_info_t *info = spl_intrin_info(in); @@ -741,14 +869,9 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) { return 0; } n->resolved_def_id = sym.node; - spl_def_node_t *def = spl_def_node(sema->type, sym.node); - if (!def) { - SPL_ERROR(&n->dbg, "definition for `%s` not found", name); - sema->error_count++; - return 0; - } - n->resolved_lang_tid = def->lang_id; - return def->lang_id; + spl_lang_type_id_t t = sema_eval_decl(sema, sym.node); + n->resolved_lang_tid = t; + return t; } /* ---------- UNARY ---------- */ @@ -1011,12 +1134,10 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) { spl_lang_method_t *meth = &vec_at(agg->methods, i); if (strcmp(meth->name, n->field.field) != 0) continue; - spl_def_node_t *fd = spl_def_node(sema->type, meth->def_id); - if (!fd) - return 0; n->resolved_def_id = meth->def_id; - n->resolved_lang_tid = fd->lang_id; - return fd->lang_id; + spl_lang_type_id_t t = sema_eval_decl(sema, meth->def_id); + n->resolved_lang_tid = t; + return t; } SPL_ERROR(&n->dbg, "no field `%s`", n->field.field); @@ -1326,11 +1447,9 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) { sema->error_count++; return 0; } - spl_def_node_t *def = spl_def_node(sema->type, sym.node); - if (!def || !def->lang_id) - return 0; - n->resolved_lang_tid = def->lang_id; - return def->lang_id; + spl_lang_type_id_t t = sema_eval_decl(sema, sym.node); + n->resolved_lang_tid = t; + return t; } case SPL_AST_TYPE_POINTER: { spl_lang_type_id_t p = sema_infer(sema, n->type_pointer.pointee); @@ -1386,7 +1505,7 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) { return t; } case SPL_AST_TYPE_AGGREGATE: - return sema_build_aggregate(sema, n); + return sema_build_aggregate(sema, n, 0); case SPL_AST_TYPE_COMPTIME_CALL: { const char *name = n->type_comptime_call.name; if (name && strcmp(name, "self") == 0) { @@ -1411,62 +1530,78 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) { if (n->resolved_def_id == 0) Panic("fn `%s` not collected", n->fn_decl.name); - spl_lang_type_id_vec_t param_types; - vec_init(param_types); + spl_def_node_t *def = spl_def_node(sema->type, n->resolved_def_id); + if (!def) + return 0; + + spl_lang_type_id_t fn_tid = def->lang_id; + if (fn_tid == 0) + fn_tid = sema_eval_decl(sema, n->resolved_def_id); + spl_lang_type_node_t *fn_ln = spl_lang_type_node(sema->type, fn_tid); + if (!fn_ln || fn_ln->kind != SPL_LANG_TYPE_FN) + return 0; + spl_lang_type_id_t ret_tid = fn_ln->extra.fn.ret; + + if (!n->fn_decl.body) + return fn_tid; + + spl_lang_type_id_t saved_agg = sema->current_aggregate_lang; + if (def->owner_def) { + spl_def_node_t *owner = spl_def_node(sema->type, def->owner_def); + if (owner && owner->lang_id != 0) + sema->current_aggregate_lang = owner->lang_id; + } + + sema_push_scope(sema); for (usize i = 0; i < vec_size(n->fn_decl.params); ++i) { spl_ast_node_t *pd = spl_ast_node(sema->ast, vec_at(n->fn_decl.params, i)); - if (pd && pd->kind == SPL_AST_PARAM_DECL && pd->param_decl.type_expr) - vec_push(param_types, sema_infer(sema, pd->param_decl.type_expr)); - else - vec_push(param_types, spl_lang_make_varargs(sema->type)); - } - spl_lang_type_id_t ret_tid = sema_infer(sema, n->fn_decl.ret_type); - if (ret_tid == 0) - ret_tid = spl_lang_make_unit(sema->type); - spl_lang_type_id_t fn_tid = spl_lang_make_fn( - sema->type, ret_tid, vec_unsafe_get_data(param_types), vec_size(param_types)); - vec_free(param_types); - spl_def_resolve(sema->type, n->resolved_def_id, fn_tid); - - if (n->fn_decl.body) { - sema_push_scope(sema); - for (usize i = 0; i < vec_size(n->fn_decl.params); ++i) { - spl_ast_node_t *pd = spl_ast_node(sema->ast, vec_at(n->fn_decl.params, i)); - if (pd && pd->kind == SPL_AST_PARAM_DECL) { - spl_symbol_t psym = {.name = pd->param_decl.name, .kind = SPL_SYMBOL_KIND_VAR}; - psym.node = spl_def_alloc(sema->type, SPL_DEF_VAR, psym.name, pd->dbg, - vec_at(n->fn_decl.params, i)); - spl_lang_type_id_t p_tid = sema_infer(sema, pd->param_decl.type_expr); - spl_def_resolve(sema->type, psym.node, p_tid); - pd->resolved_def_id = psym.node; - spl_scope_insert(sema->scope, sema->scope->current_scope, psym); + if (pd && pd->kind == SPL_AST_PARAM_DECL) { + spl_symbol_t psym = {.name = pd->param_decl.name, .kind = SPL_SYMBOL_KIND_VAR}; + psym.node = spl_def_alloc(sema->type, SPL_DEF_VAR, psym.name, pd->dbg, + vec_at(n->fn_decl.params, i)); + spl_lang_type_id_t p_tid = sema_infer(sema, pd->param_decl.type_expr); + spl_def_node_t *pdef = spl_def_node(sema->type, psym.node); + if (pdef) { + pdef->lang_id = p_tid; + pdef->state = p_tid ? SPL_DECL_RESOLVED : SPL_DECL_ERROR; } + pd->resolved_def_id = psym.node; + spl_scope_insert(sema->scope, sema->scope->current_scope, psym); } - spl_lang_type_id_t old_ret = sema->current_fn_ret_tid; - sema->current_fn_ret_tid = ret_tid; - sema_infer(sema, n->fn_decl.body); - sema->current_fn_ret_tid = old_ret; - sema_pop_scope(sema); } + spl_lang_type_id_t old_ret = sema->current_fn_ret_tid; + sema->current_fn_ret_tid = ret_tid; + sema_infer(sema, n->fn_decl.body); + sema->current_fn_ret_tid = old_ret; + sema_pop_scope(sema); + + sema->current_aggregate_lang = saved_agg; return fn_tid; } case SPL_AST_TYPE_DECL: { if (!n->type_decl.type_expr) break; - spl_ast_node_t *te = spl_ast_node(sema->ast, n->type_decl.type_expr); - if (!te) + spl_def_node_t *def = + n->resolved_def_id ? spl_def_node(sema->type, n->resolved_def_id) : NULL; + if (!def) break; - if (te->kind == SPL_AST_TYPE_AGGREGATE) { - spl_lang_type_id_t agg_lang = sema_build_aggregate(sema, te); - spl_def_resolve(sema->type, n->resolved_def_id, agg_lang); - n->resolved_lang_tid = agg_lang; - } else { - spl_lang_type_id_t tid = sema_infer(sema, n->type_decl.type_expr); - spl_def_resolve(sema->type, n->resolved_def_id, tid); - n->resolved_lang_tid = tid; + spl_lang_type_id_t lang = def->lang_id; + if (lang == 0) + lang = sema_eval_decl(sema, n->resolved_def_id); + if (lang == 0) + break; + + spl_ast_node_t *te = spl_ast_node(sema->ast, n->type_decl.type_expr); + if (te && te->kind == SPL_AST_TYPE_AGGREGATE) { + for (usize i = 0; i < vec_size(te->type_aggregate.members); ++i) { + spl_ast_node_ref_t mref = vec_at(te->type_aggregate.members, i); + spl_ast_node_t *mn = spl_ast_node(sema->ast, mref); + if (mn && mn->kind == SPL_AST_FN_DECL) + sema_infer(sema, mref); + } } - break; + return lang; } /* ---------- VAR / CONST ---------- */ @@ -1580,6 +1715,7 @@ void spl_sema_init(spl_sema_t *sema, spl_ast_t *ast, spl_type_t *type, spl_scope sema->scope = scope; sema->error_count = 0; sema->current_fn_ret_tid = 0; + sema->current_aggregate_lang = 0; sema->attr = attr; sema->root = (spl_symbol_t){0}; sema->store_scope = 0; @@ -1595,8 +1731,6 @@ void spl_sema_run_module(spl_sema_t *sema, spl_ast_node_ref_t module_ref) { return; spl_scope_id_t saved = sema->scope->current_scope; sema_collect(sema, module_ref); - fprintf(stderr, "after collect: current=%zu root=%zu\n", sema->scope->current_scope, - sema->scope->root_scope); sema_infer(sema, module_ref); sema->scope->current_scope = saved; } @@ -1604,11 +1738,9 @@ void spl_sema_run_module(spl_sema_t *sema, spl_ast_node_ref_t module_ref) { void spl_sema_run(spl_sema_t *sema) { if (!sema->ast || !sema->ast->root) return; - spl_ast_node_t *root = spl_ast_node(sema->ast, sema->ast->root); if (!root || root->kind != SPL_AST_ROOT) return; - spl_sema_run_module(sema, root->root.members); } diff --git a/stage1/spl_type.c b/stage1/spl_type.c index 1ca2e56..e67593e 100644 --- a/stage1/spl_type.c +++ b/stage1/spl_type.c @@ -495,6 +495,8 @@ spl_def_id_t spl_def_alloc(spl_type_t *type, spl_def_node_kind_t kind, const cha n.dbg_node = dbg; n.lang_id = 0; n.ast_node_ref = ast_node_ref; + n.state = SPL_DECL_UNRESOLVED; + n.owner_def = 0; vec_push(type->def_table, n); return vec_size(type->def_table) - 1; } @@ -1091,17 +1093,7 @@ void spl_type_def_dump(spl_type_t *type, spl_def_id_t id) { def_kind_name = "agg"; break; case SPL_DEF_BUILTIN: - switch (node->builtin_kind) { - case SPL_BUILTIN_RANGE: - def_kind_name = "builtin.range"; - break; - case SPL_BUILTIN_SLICE: - def_kind_name = "builtin.slice"; - break; - default: - def_kind_name = "builtin"; - break; - } + def_kind_name = "builtin"; break; case SPL_DEF_DISTINCT: def_kind_name = "distinct"; @@ -1112,4 +1104,4 @@ void spl_type_def_dump(spl_type_t *type, spl_def_id_t id) { } printf("kind=%s lang_id=%zu name=%s", def_kind_name, node->lang_id, node->name ? node->name : "?"); -} +} \ No newline at end of file diff --git a/stage1/spl_type.h b/stage1/spl_type.h index aa16049..6306bfc 100644 --- a/stage1/spl_type.h +++ b/stage1/spl_type.h @@ -138,17 +138,21 @@ typedef enum { SPL_DEF_BUILTIN, } spl_def_node_kind_t; +typedef enum { + SPL_DECL_UNRESOLVED, + SPL_DECL_RESOLVING, + SPL_DECL_RESOLVED, + SPL_DECL_ERROR, +} spl_decl_state_t; + typedef struct { spl_def_node_kind_t kind; - enum { - SPL_BUILTIN_NONE, - SPL_BUILTIN_SLICE, - SPL_BUILTIN_RANGE, - } builtin_kind; const char *name; spl_dbg_node_t dbg_node; spl_lang_type_id_t lang_id; usize ast_node_ref; + spl_decl_state_t state; + spl_def_id_t owner_def; } spl_def_node_t; typedef VEC(spl_def_node_t) spl_def_node_vec_t;