stage1 支持任意顺序声明 使用eval求值的机制

This commit is contained in:
zzy committed 2026-09-14 18:11:58 +08:00
1 parent a1e684f6d4
commit a621e34d51
6 files changed
+320 -107

No files matched your search

+84 -23
View File
@@ -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 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_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_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_fn_reserve(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_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_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_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; return;
} }
case SPL_AST_FN_DECL:
emit_fn(a, n);
return;
default: default:
return; return;
} }
} }
static void emit_fn(spl_ast2ir_t *a, spl_ast_node_t *n) { static void emit_fn_reserve(spl_ast2ir_t *a, spl_ast_node_t *n) {
if (!n->resolved_def_id) if (!n || !n->resolved_def_id)
return; return;
spl_lang_type_id_t fn_lang = spl_def_get_lang_id(a->sema->type, n->resolved_def_id); 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) if (!fn_ir)
return; 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); 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); 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; spl_lang_type_id_t saved_ret = a->cur_ret_lang;
a->cur_ret_lang = fn_ln->extra.fn.ret; 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) { while (vec_size(a->defer_stack) > defer_base) {
spl_ast_node_ref_t d = vec_pop(a->defer_stack); spl_ast_node_ref_t d = vec_pop(a->defer_stack);
(void)d; (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); 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) { 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)); spl_ast_node_t *mn = spl_ast_node(a->sema->ast, vec_at(te->type_aggregate.members, i));
if (!mn) if (!mn)
continue; continue;
if (mn->kind == SPL_AST_FN_DECL) { 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) { } 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); spl_ast_node_t *mt = spl_ast_node(a->sema->ast, mn->member_decl.type_expr);
if (mt && mt->kind == SPL_AST_TYPE_AGGREGATE) 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); spl_ast_node_t *n = spl_ast_node(a->sema->ast, ref);
if (!n) if (!n)
return; return;
if (n->kind == SPL_AST_TOP_LEVEL_BLOCK) { if (n->kind == SPL_AST_TOP_LEVEL_BLOCK) {
if (n->top_level_block.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; return;
} }
if (n->kind != SPL_AST_CONTAINER_MEMBERS) 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; continue;
switch (d->kind) { switch (d->kind) {
case SPL_AST_FN_DECL: case SPL_AST_FN_DECL:
emit_fn(a, d); emit_fn_reserve(a, d);
break; break;
case SPL_AST_TYPE_DECL: { case SPL_AST_TYPE_DECL: {
spl_ast_node_t *te = spl_ast_node(a->sema->ast, d->type_decl.type_expr); spl_ast_node_t *te = spl_ast_node(a->sema->ast, d->type_decl.type_expr);
if (te && te->kind == SPL_AST_TYPE_AGGREGATE) if (te && te->kind == SPL_AST_TYPE_AGGREGATE)
emit_aggregate_fns(a, te); emit_aggregate_fns_reserve(a, te);
break; break;
} }
case SPL_AST_TOP_LEVEL_BLOCK: 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; break;
default: default:
break; break;
@@ -1295,5 +1355,6 @@ void spl_ast2ir_run(spl_ast2ir_t *ast2ir) {
spl_ast_node_t *root = spl_ast_node(ast, ast->root); spl_ast_node_t *root = spl_ast_node(ast, ast->root);
if (!root || root->kind != SPL_AST_ROOT) if (!root || root->kind != SPL_AST_ROOT)
return; return;
emit_container(ast2ir, root->root.members); emit_container_reserve(ast2ir, root->root.members);
emit_container_body(ast2ir, root->root.members);
} }
+21
View File
@@ -387,6 +387,27 @@ spl_ir_func_ref_t spl_ir_builder_fn_begin(spl_ir_builder_t *b, const char *name,
return fid; 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) { void spl_ir_builder_fn_end(spl_ir_builder_t *b) {
spl_ir_func_t *f = spl_ir_func(&b->ir, b->current_fn); spl_ir_func_t *f = spl_ir_func(&b->ir, b->current_fn);
if (!f) { if (!f) {
+3
View File
@@ -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_ir_func_ref_t spl_ir_builder_fn_begin(spl_ir_builder_t *b, const char *name,
spl_type_id_t fn_tid); 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); void spl_ir_builder_fn_end(spl_ir_builder_t *b);
usize spl_ir_builder_block_begin(spl_ir_builder_t *b); usize spl_ir_builder_block_begin(spl_ir_builder_t *b);
+201 -69
View File
@@ -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, 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); 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_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) { 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); 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; spl_type_member_vec_t members;
vec_init(members); vec_init(members);
spl_lang_method_vec_t methods; spl_lang_method_vec_t methods;
vec_init(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) { 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_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_id_t fn_def =
spl_def_alloc(sema->type, SPL_DEF_FN, mn->fn_decl.name, mn->dbg, mref); spl_def_alloc(sema->type, SPL_DEF_FN, mn->fn_decl.name, mn->dbg, mref);
mn->resolved_def_id = fn_def; 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}; spl_lang_method_t meth = {.name = mn->fn_decl.name, .def_id = fn_def};
vec_push(methods, meth); 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.kind = lk;
ln.ir_type_id = agg_ir; ln.ir_type_id = agg_ir;
ln.methods = methods; ln.methods = methods;
spl_lang_type_id_t agg_lang = spl_lang_node_push(sema->type, &ln); return 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;
} }
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); spl_ast_node_t *n = spl_ast_node(sema->ast, ref);
if (!n) if (!n)
return; 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); spl_scope_insert(sema->scope, mod_scope, file_sym);
for (usize i = 0; i < vec_size(n->container_members.declarations); ++i) { 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 /* 故意不恢复 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: case SPL_AST_TOP_LEVEL_BLOCK:
if (n->top_level_block.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; break;
default: 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, 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) { spl_ast_node_ref_vec_t *args) {
const spl_intrin_info_t *info = spl_intrin_info(in); 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; return 0;
} }
n->resolved_def_id = sym.node; n->resolved_def_id = sym.node;
spl_def_node_t *def = spl_def_node(sema->type, sym.node); spl_lang_type_id_t t = sema_eval_decl(sema, sym.node);
if (!def) { n->resolved_lang_tid = t;
SPL_ERROR(&n->dbg, "definition for `%s` not found", name); return t;
sema->error_count++;
return 0;
}
n->resolved_lang_tid = def->lang_id;
return def->lang_id;
} }
/* ---------- UNARY ---------- */ /* ---------- 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); spl_lang_method_t *meth = &vec_at(agg->methods, i);
if (strcmp(meth->name, n->field.field) != 0) if (strcmp(meth->name, n->field.field) != 0)
continue; 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_def_id = meth->def_id;
n->resolved_lang_tid = fd->lang_id; spl_lang_type_id_t t = sema_eval_decl(sema, meth->def_id);
return fd->lang_id; n->resolved_lang_tid = t;
return t;
} }
SPL_ERROR(&n->dbg, "no field `%s`", n->field.field); 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++; sema->error_count++;
return 0; return 0;
} }
spl_def_node_t *def = spl_def_node(sema->type, sym.node); spl_lang_type_id_t t = sema_eval_decl(sema, sym.node);
if (!def || !def->lang_id) n->resolved_lang_tid = t;
return 0; return t;
n->resolved_lang_tid = def->lang_id;
return def->lang_id;
} }
case SPL_AST_TYPE_POINTER: { case SPL_AST_TYPE_POINTER: {
spl_lang_type_id_t p = sema_infer(sema, n->type_pointer.pointee); 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; return t;
} }
case SPL_AST_TYPE_AGGREGATE: case SPL_AST_TYPE_AGGREGATE:
return sema_build_aggregate(sema, n); return sema_build_aggregate(sema, n, 0);
case SPL_AST_TYPE_COMPTIME_CALL: { case SPL_AST_TYPE_COMPTIME_CALL: {
const char *name = n->type_comptime_call.name; const char *name = n->type_comptime_call.name;
if (name && strcmp(name, "self") == 0) { if (name && strcmp(name, "self") == 0) {
@@ -1411,24 +1530,28 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
if (n->resolved_def_id == 0) if (n->resolved_def_id == 0)
Panic("fn `%s` not collected", n->fn_decl.name); Panic("fn `%s` not collected", n->fn_decl.name);
spl_lang_type_id_vec_t param_types; spl_def_node_t *def = spl_def_node(sema->type, n->resolved_def_id);
vec_init(param_types); if (!def)
for (usize i = 0; i < vec_size(n->fn_decl.params); ++i) { return 0;
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) spl_lang_type_id_t fn_tid = def->lang_id;
vec_push(param_types, sema_infer(sema, pd->param_decl.type_expr)); if (fn_tid == 0)
else fn_tid = sema_eval_decl(sema, n->resolved_def_id);
vec_push(param_types, spl_lang_make_varargs(sema->type)); 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;
} }
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); sema_push_scope(sema);
for (usize i = 0; i < vec_size(n->fn_decl.params); ++i) { 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)); spl_ast_node_t *pd = spl_ast_node(sema->ast, vec_at(n->fn_decl.params, i));
@@ -1437,7 +1560,11 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
psym.node = spl_def_alloc(sema->type, SPL_DEF_VAR, psym.name, pd->dbg, psym.node = spl_def_alloc(sema->type, SPL_DEF_VAR, psym.name, pd->dbg,
vec_at(n->fn_decl.params, i)); vec_at(n->fn_decl.params, i));
spl_lang_type_id_t p_tid = sema_infer(sema, pd->param_decl.type_expr); spl_lang_type_id_t p_tid = sema_infer(sema, pd->param_decl.type_expr);
spl_def_resolve(sema->type, psym.node, p_tid); 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; pd->resolved_def_id = psym.node;
spl_scope_insert(sema->scope, sema->scope->current_scope, psym); spl_scope_insert(sema->scope, sema->scope->current_scope, psym);
} }
@@ -1447,26 +1574,34 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
sema_infer(sema, n->fn_decl.body); sema_infer(sema, n->fn_decl.body);
sema->current_fn_ret_tid = old_ret; sema->current_fn_ret_tid = old_ret;
sema_pop_scope(sema); sema_pop_scope(sema);
}
sema->current_aggregate_lang = saved_agg;
return fn_tid; return fn_tid;
} }
case SPL_AST_TYPE_DECL: { case SPL_AST_TYPE_DECL: {
if (!n->type_decl.type_expr) if (!n->type_decl.type_expr)
break; break;
spl_def_node_t *def =
n->resolved_def_id ? spl_def_node(sema->type, n->resolved_def_id) : NULL;
if (!def)
break;
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); spl_ast_node_t *te = spl_ast_node(sema->ast, n->type_decl.type_expr);
if (!te) if (te && te->kind == SPL_AST_TYPE_AGGREGATE) {
break; for (usize i = 0; i < vec_size(te->type_aggregate.members); ++i) {
if (te->kind == SPL_AST_TYPE_AGGREGATE) { spl_ast_node_ref_t mref = vec_at(te->type_aggregate.members, i);
spl_lang_type_id_t agg_lang = sema_build_aggregate(sema, te); spl_ast_node_t *mn = spl_ast_node(sema->ast, mref);
spl_def_resolve(sema->type, n->resolved_def_id, agg_lang); if (mn && mn->kind == SPL_AST_FN_DECL)
n->resolved_lang_tid = agg_lang; sema_infer(sema, mref);
} 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;
} }
break; }
return lang;
} }
/* ---------- VAR / CONST ---------- */ /* ---------- 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->scope = scope;
sema->error_count = 0; sema->error_count = 0;
sema->current_fn_ret_tid = 0; sema->current_fn_ret_tid = 0;
sema->current_aggregate_lang = 0;
sema->attr = attr; sema->attr = attr;
sema->root = (spl_symbol_t){0}; sema->root = (spl_symbol_t){0};
sema->store_scope = 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; return;
spl_scope_id_t saved = sema->scope->current_scope; spl_scope_id_t saved = sema->scope->current_scope;
sema_collect(sema, module_ref); 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_infer(sema, module_ref);
sema->scope->current_scope = saved; 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) { void spl_sema_run(spl_sema_t *sema) {
if (!sema->ast || !sema->ast->root) if (!sema->ast || !sema->ast->root)
return; return;
spl_ast_node_t *root = spl_ast_node(sema->ast, sema->ast->root); spl_ast_node_t *root = spl_ast_node(sema->ast, sema->ast->root);
if (!root || root->kind != SPL_AST_ROOT) if (!root || root->kind != SPL_AST_ROOT)
return; return;
spl_sema_run_module(sema, root->root.members); spl_sema_run_module(sema, root->root.members);
} }
+2 -10
View File
@@ -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.dbg_node = dbg;
n.lang_id = 0; n.lang_id = 0;
n.ast_node_ref = ast_node_ref; n.ast_node_ref = ast_node_ref;
n.state = SPL_DECL_UNRESOLVED;
n.owner_def = 0;
vec_push(type->def_table, n); vec_push(type->def_table, n);
return vec_size(type->def_table) - 1; return vec_size(type->def_table) - 1;
} }
@@ -1091,18 +1093,8 @@ void spl_type_def_dump(spl_type_t *type, spl_def_id_t id) {
def_kind_name = "agg"; def_kind_name = "agg";
break; break;
case SPL_DEF_BUILTIN: 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"; def_kind_name = "builtin";
break; break;
}
break;
case SPL_DEF_DISTINCT: case SPL_DEF_DISTINCT:
def_kind_name = "distinct"; def_kind_name = "distinct";
break; break;
+9 -5
View File
@@ -138,17 +138,21 @@ typedef enum {
SPL_DEF_BUILTIN, SPL_DEF_BUILTIN,
} spl_def_node_kind_t; } 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 { typedef struct {
spl_def_node_kind_t kind; spl_def_node_kind_t kind;
enum {
SPL_BUILTIN_NONE,
SPL_BUILTIN_SLICE,
SPL_BUILTIN_RANGE,
} builtin_kind;
const char *name; const char *name;
spl_dbg_node_t dbg_node; spl_dbg_node_t dbg_node;
spl_lang_type_id_t lang_id; spl_lang_type_id_t lang_id;
usize ast_node_ref; usize ast_node_ref;
spl_decl_state_t state;
spl_def_id_t owner_def;
} spl_def_node_t; } spl_def_node_t;
typedef VEC(spl_def_node_t) spl_def_node_vec_t; typedef VEC(spl_def_node_t) spl_def_node_vec_t;