stage1 大量重构
This commit is contained in:
1 parent
e4347cc3ea
commit
2a84b61e3d
18 files changed
+1831
-1354
No files matched your search
+329
-145
@@ -1,52 +1,8 @@
|
||||
#include "spl_sema.h"
|
||||
#include "spl_intrin.h"
|
||||
#include "spl_lang_type.h"
|
||||
#include "spl_type.h"
|
||||
|
||||
void spl_scope_init(spl_scope_t *scope) {
|
||||
vec_init(scope->scopes);
|
||||
vec_push(scope->scopes, (spl_scope_node_t){0});
|
||||
scope->current_scope = 0;
|
||||
scope->root_scope = 0;
|
||||
}
|
||||
|
||||
void spl_scope_drop(spl_scope_t *scope) {
|
||||
for (usize i = 0; i < vec_size(scope->scopes); ++i) {
|
||||
map_free(vec_at(scope->scopes, i).symbols);
|
||||
}
|
||||
vec_free(scope->scopes);
|
||||
scope->current_scope = 0;
|
||||
scope->root_scope = 0;
|
||||
}
|
||||
|
||||
spl_scope_id_t spl_scope_alloc(spl_scope_t *scope) {
|
||||
spl_scope_node_t n = {0};
|
||||
n.parent = scope->current_scope;
|
||||
map_init(n.symbols, MAP_HASH_STR, MAP_CMP_STR);
|
||||
vec_push(scope->scopes, n);
|
||||
return vec_size(scope->scopes) - 1;
|
||||
}
|
||||
|
||||
bool spl_scope_insert(spl_scope_t *scope, spl_scope_id_t id, spl_symbol_t symbol) {
|
||||
Assert(id != 0 && id < vec_size(scope->scopes));
|
||||
spl_scope_node_t *node = &vec_at(scope->scopes, id);
|
||||
spl_symbol_t old = {0};
|
||||
if (map_get(node->symbols, symbol.name, &old))
|
||||
return false;
|
||||
map_put(node->symbols, symbol.name, symbol);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spl_scope_find(spl_scope_t *scope, const char *name, spl_symbol_t *out) {
|
||||
if (!scope || !name || !out)
|
||||
return false;
|
||||
for (spl_scope_id_t id = scope->current_scope; id != 0; id = vec_at(scope->scopes, id).parent) {
|
||||
spl_scope_node_t *s = &vec_at(scope->scopes, id);
|
||||
if (map_get(s->symbols, name, out))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static spl_ast_node_ref_vec_t *node_attr_list(spl_ast_node_t *n) {
|
||||
switch (n->kind) {
|
||||
case SPL_AST_FN_DECL:
|
||||
@@ -168,7 +124,7 @@ static void sema_type_to_str(spl_sema_t *sema, spl_lang_type_id_t tid, char *buf
|
||||
snprintf(buf, cap, "<invalid lang#%zu>", tid);
|
||||
return;
|
||||
}
|
||||
spl_type_node_t *ir = spl_type_node(sema->type, n->ir_type_id);
|
||||
spl_type_node_t *ir = spl_type_node(&sema->type->ir, n->ir_type_id);
|
||||
switch (n->kind) {
|
||||
case SPL_LANG_TYPE_INT:
|
||||
if (ir && ir->int_type.bits == 0)
|
||||
@@ -285,37 +241,10 @@ static spl_lang_type_id_t sema_infer_fn_signature(spl_sema_t *sema, spl_ast_node
|
||||
return fn_tid;
|
||||
}
|
||||
|
||||
/* 构建聚合类型:reserve IR 槽位作为身份锚点,让 *Node / []Node 自引用能拿到
|
||||
稳定 pointee;遍历成员后再 define 填内容。 */
|
||||
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);
|
||||
|
||||
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)
|
||||
continue;
|
||||
|
||||
if (mn->kind == SPL_AST_MEMBER_DECL) {
|
||||
spl_lang_type_id_t mtid = sema_infer(sema, mn->member_decl.type_expr);
|
||||
spl_type_member_t m = {.name = mn->member_decl.name,
|
||||
.type_id = spl_lang_type_get_ir_type(sema->type, mtid),
|
||||
.ast_node_ref = mref};
|
||||
vec_push(members, m);
|
||||
} else if (mn->kind == SPL_AST_FN_DECL) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
spl_type_node_kind_t tk;
|
||||
if (strcmp(te->type_aggregate.kind_name, "struct") == 0)
|
||||
tk = SPL_TYPE_STRUCT;
|
||||
@@ -326,11 +255,6 @@ static spl_lang_type_id_t sema_build_aggregate(spl_sema_t *sema, spl_ast_node_t
|
||||
else
|
||||
tk = SPL_TYPE_STRUCT;
|
||||
|
||||
spl_type_layout_t layout = {.mode = SPL_TYPE_LAYOUT_AUTO};
|
||||
spl_type_id_t agg_ir = spl_type_builder_agg(sema->type, tk, &members,
|
||||
spl_type_builder_int(sema->type, 32, 1), layout);
|
||||
vec_free(members);
|
||||
|
||||
spl_lang_type_kind_t lk;
|
||||
switch (tk) {
|
||||
case SPL_TYPE_STRUCT:
|
||||
@@ -349,11 +273,229 @@ static spl_lang_type_id_t sema_build_aggregate(spl_sema_t *sema, spl_ast_node_t
|
||||
lk = SPL_LANG_TYPE_STRUCT;
|
||||
break;
|
||||
}
|
||||
|
||||
spl_type_id_t agg_ir = spl_lang_reserve_ir(sema->type);
|
||||
|
||||
spl_lang_type_node_t ln = {0};
|
||||
ln.kind = lk;
|
||||
ln.ir_type_id = agg_ir;
|
||||
ln.methods = methods;
|
||||
return spl_lang_node_push(sema->type, &ln);
|
||||
vec_init(ln.methods);
|
||||
spl_lang_type_id_t agg_lang = spl_lang_node_push(sema->type, &ln);
|
||||
|
||||
if (owner_def_id) {
|
||||
spl_def_node_t *d = spl_def_node(sema->type, owner_def_id);
|
||||
if (d)
|
||||
d->lang_id = agg_lang;
|
||||
}
|
||||
|
||||
spl_lang_type_id_t saved_agg = sema->current_aggregate_lang;
|
||||
sema->current_aggregate_lang = agg_lang;
|
||||
|
||||
spl_type_member_vec_t members;
|
||||
vec_init(members);
|
||||
spl_lang_method_vec_t methods;
|
||||
vec_init(methods);
|
||||
|
||||
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)
|
||||
continue;
|
||||
|
||||
if (mn->kind == SPL_AST_MEMBER_DECL) {
|
||||
spl_lang_type_id_t mtid = 0;
|
||||
if (mn->member_decl.type_expr)
|
||||
mtid = sema_infer(sema, mn->member_decl.type_expr);
|
||||
spl_type_member_t m = {.name = mn->member_decl.name,
|
||||
.type_id = spl_lang_type_get_ir_type(sema->type, mtid),
|
||||
.ast_node_ref = mref};
|
||||
vec_push(members, m);
|
||||
} else if (mn->kind == SPL_AST_FN_DECL) {
|
||||
spl_def_id_t fn_def =
|
||||
spl_def_alloc(sema->type, SPL_DEF_FN, mn->fn_decl.name, mn->dbg, sema->ast, 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);
|
||||
} else if (mn->kind == SPL_AST_TYPE_DECL) {
|
||||
spl_def_id_t tdef = mn->resolved_def_id;
|
||||
if (!tdef)
|
||||
continue;
|
||||
spl_lang_method_t meth = {.name = mn->type_decl.name, .def_id = tdef};
|
||||
vec_push(methods, meth);
|
||||
}
|
||||
}
|
||||
|
||||
sema->current_aggregate_lang = saved_agg;
|
||||
|
||||
spl_type_node_t tn = {0};
|
||||
tn.kind = tk;
|
||||
tn.layout.mode = SPL_TYPE_LAYOUT_AUTO;
|
||||
if (tk == SPL_TYPE_ENUM)
|
||||
tn.agg_type.tag_type = spl_type_builder_int(&sema->type->ir, 32, 1);
|
||||
tn.agg_type.variants = members;
|
||||
vec_init(members);
|
||||
spl_lang_define_ir(sema->type, agg_ir, &tn);
|
||||
|
||||
spl_lang_type_node_t *lslot = spl_lang_type_node(sema->type, agg_lang);
|
||||
if (lslot) {
|
||||
vec_free(lslot->methods);
|
||||
lslot->methods = methods;
|
||||
vec_init(methods);
|
||||
}
|
||||
|
||||
return agg_lang;
|
||||
}
|
||||
|
||||
/* 文件 container 建成匿名 struct:FN_DECL / TYPE_DECL / VAR_DECL / CONST_DECL
|
||||
进 methods(复用为 names),MEMBER_DECL 进字段。 */
|
||||
static spl_lang_type_id_t sema_build_container_aggregate(spl_sema_t *sema, spl_ast_node_t *n,
|
||||
spl_def_id_t owner_def_id) {
|
||||
spl_type_id_t agg_ir = spl_lang_reserve_ir(sema->type);
|
||||
|
||||
spl_lang_type_node_t ln = {0};
|
||||
ln.kind = SPL_LANG_TYPE_STRUCT;
|
||||
ln.ir_type_id = agg_ir;
|
||||
vec_init(ln.methods);
|
||||
spl_lang_type_id_t agg_lang = spl_lang_node_push(sema->type, &ln);
|
||||
|
||||
if (owner_def_id) {
|
||||
spl_def_node_t *d = spl_def_node(sema->type, owner_def_id);
|
||||
if (d)
|
||||
d->lang_id = agg_lang;
|
||||
}
|
||||
|
||||
spl_lang_type_id_t saved_agg = sema->current_aggregate_lang;
|
||||
sema->current_aggregate_lang = agg_lang;
|
||||
|
||||
spl_type_member_vec_t members;
|
||||
vec_init(members);
|
||||
spl_lang_method_vec_t methods;
|
||||
vec_init(methods);
|
||||
|
||||
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)
|
||||
continue;
|
||||
|
||||
if (d->kind == SPL_AST_MEMBER_DECL) {
|
||||
spl_lang_type_id_t mtid = 0;
|
||||
if (d->member_decl.type_expr)
|
||||
mtid = sema_infer(sema, d->member_decl.type_expr);
|
||||
spl_type_member_t m = {.name = d->member_decl.name,
|
||||
.type_id = spl_lang_type_get_ir_type(sema->type, mtid),
|
||||
.ast_node_ref = dref};
|
||||
vec_push(members, m);
|
||||
} else if (d->kind == SPL_AST_FN_DECL) {
|
||||
spl_def_id_t fn_def = d->resolved_def_id;
|
||||
if (!fn_def)
|
||||
continue;
|
||||
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 = d->fn_decl.name, .def_id = fn_def};
|
||||
vec_push(methods, meth);
|
||||
} else if (d->kind == SPL_AST_TYPE_DECL) {
|
||||
spl_def_id_t tdef = d->resolved_def_id;
|
||||
if (!tdef)
|
||||
continue;
|
||||
spl_lang_method_t meth = {.name = d->type_decl.name, .def_id = tdef};
|
||||
vec_push(methods, meth);
|
||||
} else if (d->kind == SPL_AST_VAR_DECL || d->kind == SPL_AST_CONST_DECL) {
|
||||
spl_def_id_t vdef = d->resolved_def_id;
|
||||
if (!vdef)
|
||||
continue;
|
||||
spl_ast_node_t *pat = spl_ast_node(sema->ast, d->var_const_decl.pattern);
|
||||
if (!pat || pat->kind != SPL_AST_PATTERN_IDENT)
|
||||
continue;
|
||||
spl_lang_method_t meth = {.name = pat->pattern_ident.name, .def_id = vdef};
|
||||
vec_push(methods, meth);
|
||||
}
|
||||
}
|
||||
|
||||
sema->current_aggregate_lang = saved_agg;
|
||||
|
||||
spl_type_node_t tn = {0};
|
||||
tn.kind = SPL_TYPE_STRUCT;
|
||||
tn.layout.mode = SPL_TYPE_LAYOUT_AUTO;
|
||||
tn.agg_type.variants = members;
|
||||
vec_init(members);
|
||||
spl_lang_define_ir(sema->type, agg_ir, &tn);
|
||||
|
||||
spl_lang_type_node_t *lslot = spl_lang_type_node(sema->type, agg_lang);
|
||||
if (lslot) {
|
||||
vec_free(lslot->methods);
|
||||
lslot->methods = methods;
|
||||
vec_init(methods);
|
||||
}
|
||||
|
||||
return agg_lang;
|
||||
}
|
||||
|
||||
static spl_lang_type_id_t sema_import(spl_sema_t *sema, spl_ast_node_t *n,
|
||||
spl_ast_node_ref_vec_t *args) {
|
||||
if (!sema->loader || !sema->loader->load) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_INTERNAL, &n->dbg,
|
||||
"@import: no module loader configured");
|
||||
return 0;
|
||||
}
|
||||
if (vec_size(*args) != 1) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_INTRIN_ARG_COUNT, &n->dbg,
|
||||
"@import expects 1 argument");
|
||||
return 0;
|
||||
}
|
||||
spl_ast_node_t *arg = spl_ast_node(sema->ast, vec_at(*args, 0));
|
||||
if (!arg || arg->kind != SPL_AST_EXPR_STRING_LIT || !arg->string_lit.data) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_TYPE_MISMATCH, &n->dbg,
|
||||
"@import expects a string literal");
|
||||
return 0;
|
||||
}
|
||||
const char *path = arg->string_lit.data;
|
||||
|
||||
spl_ast_t *mod_ast = sema->loader->load(sema->loader->user, n->dbg.fname, path, sema->diag);
|
||||
if (!mod_ast || !mod_ast->root)
|
||||
return 0;
|
||||
|
||||
spl_ast_node_t *mod_root = spl_ast_node(mod_ast, mod_ast->root);
|
||||
if (!mod_root || mod_root->kind != SPL_AST_ROOT)
|
||||
return 0;
|
||||
spl_ast_node_ref_t cm_ref = mod_root->root.members;
|
||||
if (!cm_ref)
|
||||
return 0;
|
||||
|
||||
spl_ast_node_t *cm = spl_ast_node(mod_ast, cm_ref);
|
||||
if (cm->resolved_def_id) {
|
||||
spl_def_node_t *d = spl_def_node(sema->type, cm->resolved_def_id);
|
||||
if (d && d->lang_id)
|
||||
return d->lang_id;
|
||||
}
|
||||
|
||||
spl_ast_t *saved_ast = sema->ast;
|
||||
spl_scope_id_t saved_root = sema->scope->root_scope;
|
||||
spl_scope_id_t saved_cur = sema->scope->current_scope;
|
||||
spl_lang_type_id_t saved_agg = sema->current_aggregate_lang;
|
||||
|
||||
sema->ast = mod_ast;
|
||||
sema->scope->root_scope = 0;
|
||||
sema->scope->current_scope = 0;
|
||||
sema->current_aggregate_lang = 0;
|
||||
|
||||
spl_sema_run_module(sema, cm_ref);
|
||||
|
||||
spl_lang_type_id_t t = 0;
|
||||
spl_ast_node_t *cm_after = spl_ast_node(mod_ast, cm_ref);
|
||||
if (cm_after->resolved_def_id)
|
||||
t = sema_eval_decl(sema, cm_after->resolved_def_id);
|
||||
|
||||
sema->ast = saved_ast;
|
||||
sema->scope->root_scope = saved_root;
|
||||
sema->scope->current_scope = saved_cur;
|
||||
sema->current_aggregate_lang = saved_agg;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static spl_lang_type_id_t sema_eval_decl(spl_sema_t *sema, spl_def_id_t def_id) {
|
||||
@@ -364,7 +506,11 @@ static spl_lang_type_id_t sema_eval_decl(spl_sema_t *sema, spl_def_id_t def_id)
|
||||
if (def->state == SPL_DECL_RESOLVED || def->state == SPL_DECL_ERROR)
|
||||
return def->lang_id;
|
||||
|
||||
/* RESOLVING 中途但 lang_id 已被 reserve 阶段回填:直接返回。
|
||||
A ↔ B 相互引用时 B 引用 A 就走这条短路。 */
|
||||
if (def->lang_id != 0) {
|
||||
if (def->state == SPL_DECL_RESOLVING)
|
||||
return def->lang_id;
|
||||
def->state = SPL_DECL_RESOLVED;
|
||||
return def->lang_id;
|
||||
}
|
||||
@@ -376,9 +522,29 @@ static spl_lang_type_id_t sema_eval_decl(spl_sema_t *sema, spl_def_id_t def_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
def->state = SPL_DECL_RESOLVING;
|
||||
/* 提前取所有 def 字段:sema_infer_* / sema_build_* 会 push def_table,def 悬垂。 */
|
||||
spl_ast_t *owner_ast = def->owner_ast;
|
||||
spl_def_id_t owner_def_id = def->owner_def;
|
||||
usize ast_node_ref = def->ast_node_ref;
|
||||
spl_dbg_node_t dbg_node = def->dbg_node;
|
||||
|
||||
spl_ast_node_t *n = spl_ast_node(sema->ast, def->ast_node_ref);
|
||||
if (!owner_ast) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_INTERNAL, &dbg_node, "def#%zu has no owner_ast",
|
||||
def_id);
|
||||
spl_def_node_t *d2 = spl_def_node(sema->type, def_id);
|
||||
if (d2)
|
||||
d2->state = SPL_DECL_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
spl_ast_t *saved_ast = sema->ast;
|
||||
sema->ast = owner_ast;
|
||||
|
||||
def = spl_def_node(sema->type, def_id);
|
||||
if (def)
|
||||
def->state = SPL_DECL_RESOLVING;
|
||||
|
||||
spl_ast_node_t *n = spl_ast_node(sema->ast, ast_node_ref);
|
||||
spl_lang_type_id_t result = 0;
|
||||
|
||||
if (n) {
|
||||
@@ -396,8 +562,8 @@ static spl_lang_type_id_t sema_eval_decl(spl_sema_t *sema, spl_def_id_t def_id)
|
||||
}
|
||||
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_def_id) {
|
||||
spl_def_node_t *owner = spl_def_node(sema->type, owner_def_id);
|
||||
if (owner && owner->lang_id != 0)
|
||||
sema->current_aggregate_lang = owner->lang_id;
|
||||
}
|
||||
@@ -413,6 +579,10 @@ static spl_lang_type_id_t sema_eval_decl(spl_sema_t *sema, spl_def_id_t def_id)
|
||||
result = sema_infer(sema, n->var_const_decl.init_expr);
|
||||
break;
|
||||
}
|
||||
case SPL_AST_CONTAINER_MEMBERS:
|
||||
result = sema_build_container_aggregate(sema, n, def_id);
|
||||
n->resolved_lang_tid = result;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -420,9 +590,14 @@ static spl_lang_type_id_t sema_eval_decl(spl_sema_t *sema, spl_def_id_t def_id)
|
||||
|
||||
spl_def_node_t *final_def = spl_def_node(sema->type, def_id);
|
||||
if (final_def) {
|
||||
final_def->lang_id = result;
|
||||
/* reserve 阶段已回填 lang_id 时,即使 result==0(构建失败)也不清掉身份,
|
||||
后续引用拿到 ERROR 状态节点而非报环。 */
|
||||
if (result != 0)
|
||||
final_def->lang_id = result;
|
||||
final_def->state = result ? SPL_DECL_RESOLVED : SPL_DECL_ERROR;
|
||||
}
|
||||
|
||||
sema->ast = saved_ast;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -443,7 +618,7 @@ static void sema_collect_names(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
sema->scope->current_scope = mod_scope;
|
||||
|
||||
spl_symbol_t file_sym = {.name = "$file", .kind = SPL_SYMBOL_KIND_TYPE};
|
||||
file_sym.node = spl_def_alloc(sema->type, SPL_DEF_AGG, "$file", n->dbg, ref);
|
||||
file_sym.node = spl_def_alloc(sema->type, SPL_DEF_AGG, "$file", n->dbg, sema->ast, ref);
|
||||
n->resolved_def_id = file_sym.node;
|
||||
spl_scope_insert(sema->scope, mod_scope, file_sym);
|
||||
|
||||
@@ -461,9 +636,9 @@ static void sema_collect_names(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return;
|
||||
}
|
||||
if (te->kind == SPL_AST_TYPE_AGGREGATE)
|
||||
sym.node = spl_def_alloc(sema->type, SPL_DEF_AGG, sym.name, te->dbg, ref);
|
||||
sym.node = spl_def_alloc(sema->type, SPL_DEF_AGG, sym.name, te->dbg, sema->ast, ref);
|
||||
else
|
||||
sym.node = spl_def_alloc(sema->type, SPL_DEF_SCALAR, sym.name, te->dbg, ref);
|
||||
sym.node = spl_def_alloc(sema->type, SPL_DEF_SCALAR, sym.name, te->dbg, sema->ast, ref);
|
||||
n->resolved_def_id = sym.node;
|
||||
if (!spl_scope_insert(sema->scope, sema->scope->current_scope, sym)) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_DUPLICATE_SYMBOL, &n->dbg,
|
||||
@@ -473,7 +648,7 @@ static void sema_collect_names(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
}
|
||||
case SPL_AST_FN_DECL: {
|
||||
spl_symbol_t sym = {.name = n->fn_decl.name, .kind = SPL_SYMBOL_KIND_FN};
|
||||
sym.node = spl_def_alloc(sema->type, SPL_DEF_FN, sym.name, n->dbg, ref);
|
||||
sym.node = spl_def_alloc(sema->type, SPL_DEF_FN, sym.name, n->dbg, sema->ast, ref);
|
||||
n->resolved_def_id = sym.node;
|
||||
if (!spl_scope_insert(sema->scope, sema->scope->current_scope, sym)) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_DUPLICATE_SYMBOL, &n->dbg,
|
||||
@@ -487,7 +662,7 @@ static void sema_collect_names(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
if (pat && pat->kind == SPL_AST_PATTERN_IDENT) {
|
||||
const char *name = pat->pattern_ident.name;
|
||||
spl_symbol_t sym = {.name = name, .kind = SPL_SYMBOL_KIND_VAR};
|
||||
sym.node = spl_def_alloc(sema->type, SPL_DEF_VAR, name, n->dbg, ref);
|
||||
sym.node = spl_def_alloc(sema->type, SPL_DEF_VAR, name, n->dbg, sema->ast, ref);
|
||||
n->resolved_def_id = sym.node;
|
||||
if (!spl_scope_insert(sema->scope, sema->scope->current_scope, sym)) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_DUPLICATE_SYMBOL, &n->dbg,
|
||||
@@ -585,7 +760,7 @@ static spl_lang_type_id_t sema_intrin_call(spl_sema_t *sema, spl_ast_node_t *n,
|
||||
return 0;
|
||||
spl_type_id_t ft = spl_lang_type_get_ir_type(sema->type, src_lang);
|
||||
spl_type_id_t tt = spl_lang_type_get_ir_type(sema->type, dst_lang);
|
||||
spl_intrin_t expected = spl_intrin_lookup_cast(sema->type, ft, tt);
|
||||
spl_intrin_t expected = spl_intrin_lookup_cast(&sema->type->ir, ft, tt);
|
||||
if (expected == SPL_INTRIN_NONE) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_CAST_INVALID, &n->dbg,
|
||||
"`%s`: incompatible types", info->name);
|
||||
@@ -670,10 +845,9 @@ static spl_lang_type_id_t sema_coerce(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
||||
if (already == expected)
|
||||
return expected;
|
||||
|
||||
/* 已定型 */
|
||||
if (already != 0) {
|
||||
spl_lang_type_node_t *an = spl_lang_type_node(sema->type, already);
|
||||
spl_type_node_t *air = an ? spl_type_node(sema->type, an->ir_type_id) : NULL;
|
||||
spl_type_node_t *air = an ? spl_type_node(&sema->type->ir, an->ir_type_id) : NULL;
|
||||
bool a_rebindable =
|
||||
(an && an->kind == SPL_LANG_TYPE_INFER) ||
|
||||
(an && an->kind == SPL_LANG_TYPE_INT && air && air->int_type.bits == 0) ||
|
||||
@@ -694,9 +868,7 @@ static spl_lang_type_id_t sema_coerce(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
||||
n->resolved_lang_tid = 0;
|
||||
}
|
||||
|
||||
/* 未定型的构造性节点 */
|
||||
switch (n->kind) {
|
||||
|
||||
case SPL_AST_EXPR_UNARY: {
|
||||
if (n->unary.op == SPL_UNARY_OP_ADDRESS || n->unary.op == SPL_UNARY_OP_DEREF)
|
||||
break;
|
||||
@@ -764,7 +936,7 @@ static spl_lang_type_id_t sema_coerce(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
||||
"pointer offset must be integer");
|
||||
return 0;
|
||||
}
|
||||
spl_type_node_t *rn_ir = spl_type_node(sema->type, rn->ir_type_id);
|
||||
spl_type_node_t *rn_ir = spl_type_node(&sema->type->ir, rn->ir_type_id);
|
||||
if (rn_ir && rn_ir->int_type.bits == 0) {
|
||||
spl_lang_type_id_t it =
|
||||
spl_lang_make_int(sema->type, sizeof(void *) * 8, 1);
|
||||
@@ -842,7 +1014,7 @@ static spl_lang_type_id_t sema_coerce(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
||||
}
|
||||
|
||||
spl_type_id_t agg_ir = spl_lang_type_get_ir_type(sema->type, expected);
|
||||
spl_type_node_t *irn = spl_type_node(sema->type, agg_ir);
|
||||
spl_type_node_t *irn = spl_type_node(&sema->type->ir, agg_ir);
|
||||
if (!irn) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_TYPE_MISMATCH, &n->dbg,
|
||||
"aggregate type unresolved");
|
||||
@@ -862,7 +1034,8 @@ static spl_lang_type_id_t sema_coerce(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
||||
return 0;
|
||||
}
|
||||
usize idx = 0;
|
||||
if (!spl_type_agg_member_idx(sema->type, agg_ir, item->struct_init_item.name, &idx)) {
|
||||
if (!spl_type_agg_member_idx(&sema->type->ir, agg_ir, item->struct_init_item.name,
|
||||
&idx)) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_NO_FIELD, &item->dbg, "no variant `%s`",
|
||||
item->struct_init_item.name);
|
||||
return 0;
|
||||
@@ -882,7 +1055,8 @@ static spl_lang_type_id_t sema_coerce(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
||||
if (!item || item->kind != SPL_AST_STRUCT_INIT_ITEM)
|
||||
continue;
|
||||
usize idx = 0;
|
||||
if (!spl_type_agg_member_idx(sema->type, agg_ir, item->struct_init_item.name, &idx)) {
|
||||
if (!spl_type_agg_member_idx(&sema->type->ir, agg_ir, item->struct_init_item.name,
|
||||
&idx)) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_NO_FIELD, &item->dbg, "no field `%s`",
|
||||
item->struct_init_item.name);
|
||||
continue;
|
||||
@@ -925,7 +1099,6 @@ static spl_lang_type_id_t sema_coerce(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
||||
break;
|
||||
}
|
||||
|
||||
/* 兜底:infer 后按子类型 / comptime 判定 */
|
||||
spl_lang_type_id_t from = sema_infer(sema, ref);
|
||||
if (!from)
|
||||
return 0;
|
||||
@@ -934,8 +1107,8 @@ static spl_lang_type_id_t sema_coerce(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
||||
|
||||
spl_lang_type_node_t *from_n = spl_lang_type_node(sema->type, from);
|
||||
spl_lang_type_node_t *to_n = spl_lang_type_node(sema->type, expected);
|
||||
spl_type_node_t *from_ir = from_n ? spl_type_node(sema->type, from_n->ir_type_id) : NULL;
|
||||
spl_type_node_t *to_ir = to_n ? spl_type_node(sema->type, to_n->ir_type_id) : NULL;
|
||||
spl_type_node_t *from_ir = from_n ? spl_type_node(&sema->type->ir, from_n->ir_type_id) : NULL;
|
||||
spl_type_node_t *to_ir = to_n ? spl_type_node(&sema->type->ir, to_n->ir_type_id) : NULL;
|
||||
|
||||
bool from_comptime_int =
|
||||
from_n && from_n->kind == SPL_LANG_TYPE_INT && from_ir && from_ir->int_type.bits == 0;
|
||||
@@ -983,7 +1156,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
|
||||
switch (n->kind) {
|
||||
|
||||
/* ---------- 字面量 ---------- */
|
||||
case SPL_AST_EXPR_INT_LIT: {
|
||||
spl_lang_type_id_t t = spl_lang_make_int(sema->type, 0, 1);
|
||||
n->resolved_lang_tid = t;
|
||||
@@ -1022,7 +1194,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return t;
|
||||
}
|
||||
|
||||
/* ---------- IDENT ---------- */
|
||||
case SPL_AST_EXPR_IDENT: {
|
||||
const char *name = n->ident.name;
|
||||
spl_symbol_t sym;
|
||||
@@ -1042,7 +1213,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return t;
|
||||
}
|
||||
|
||||
/* ---------- UNARY ---------- */
|
||||
case SPL_AST_EXPR_UNARY: {
|
||||
spl_lang_type_id_t op = sema_infer(sema, n->unary.operand);
|
||||
if (op == 0)
|
||||
@@ -1094,7 +1264,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------- BINARY ---------- */
|
||||
case SPL_AST_EXPR_BINARY: {
|
||||
spl_binary_op_t op = n->binary.op;
|
||||
|
||||
@@ -1174,7 +1343,7 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
|
||||
if (ln && ln->kind == SPL_LANG_TYPE_PTR && rn && rn->kind == SPL_LANG_TYPE_INT &&
|
||||
(op == SPL_OP_ADD || op == SPL_OP_SUB)) {
|
||||
spl_type_node_t *rn_ir = spl_type_node(sema->type, rn->ir_type_id);
|
||||
spl_type_node_t *rn_ir = spl_type_node(&sema->type->ir, rn->ir_type_id);
|
||||
if (rn_ir && rn_ir->int_type.bits == 0) {
|
||||
spl_lang_type_id_t it = spl_lang_make_int(sema->type, sizeof(void *) * 8, 1);
|
||||
sema_coerce(sema, n->binary.right, it);
|
||||
@@ -1200,7 +1369,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return common;
|
||||
}
|
||||
|
||||
/* ---------- CALL ---------- */
|
||||
case SPL_AST_EXPR_CALL: {
|
||||
spl_ast_node_t *callee = spl_ast_node(sema->ast, n->call.callee);
|
||||
if (callee && callee->kind == SPL_AST_EXPR_IDENT) {
|
||||
@@ -1243,8 +1411,10 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
}
|
||||
|
||||
for (usize i = 0; i < nargs && i < fixed; ++i) {
|
||||
spl_lang_type_id_t pt =
|
||||
vec_at(spl_lang_type_node(sema->type, callee_tid)->extra.fn.params, i);
|
||||
spl_lang_type_node_t *fn2 = spl_lang_type_node(sema->type, callee_tid);
|
||||
if (!fn2)
|
||||
return 0;
|
||||
spl_lang_type_id_t pt = vec_at(fn2->extra.fn.params, i);
|
||||
if (!sema_coerce(sema, vec_at(n->call.args, i), pt))
|
||||
return 0;
|
||||
}
|
||||
@@ -1261,7 +1431,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ---------- FIELD ---------- */
|
||||
case SPL_AST_EXPR_FIELD: {
|
||||
spl_lang_type_id_t obj_tid = sema_infer(sema, n->field.obj);
|
||||
spl_lang_type_node_t *obj = spl_lang_type_node(sema->type, obj_tid);
|
||||
@@ -1287,7 +1456,8 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
|
||||
spl_type_id_t agg_ir = spl_lang_type_get_ir_type(sema->type, agg_lang);
|
||||
if (agg_ir) {
|
||||
const spl_type_member_t *m = spl_type_agg_member(sema->type, agg_ir, n->field.field);
|
||||
const spl_type_member_t *m =
|
||||
spl_type_agg_member(&sema->type->ir, agg_ir, n->field.field);
|
||||
if (m) {
|
||||
spl_lang_type_id_t ft = sema_lang_from_ir(sema, m->type_id);
|
||||
if (!ft) {
|
||||
@@ -1300,12 +1470,18 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
}
|
||||
}
|
||||
|
||||
for (usize i = 0; i < vec_size(agg->methods); ++i) {
|
||||
spl_lang_method_t *meth = &vec_at(agg->methods, i);
|
||||
if (strcmp(meth->name, n->field.field) != 0)
|
||||
const char *fname = n->field.field;
|
||||
usize nmethods = vec_size(agg->methods);
|
||||
for (usize i = 0; i < nmethods; ++i) {
|
||||
spl_lang_type_node_t *agg2 = spl_lang_type_node(sema->type, agg_lang);
|
||||
if (!agg2)
|
||||
break;
|
||||
spl_lang_method_t *meth = &vec_at(agg2->methods, i);
|
||||
if (strcmp(meth->name, fname) != 0)
|
||||
continue;
|
||||
n->resolved_def_id = meth->def_id;
|
||||
spl_lang_type_id_t t = sema_eval_decl(sema, meth->def_id);
|
||||
spl_def_id_t did = meth->def_id;
|
||||
n->resolved_def_id = did;
|
||||
spl_lang_type_id_t t = sema_eval_decl(sema, did);
|
||||
n->resolved_lang_tid = t;
|
||||
return t;
|
||||
}
|
||||
@@ -1315,7 +1491,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ---------- INDEX ---------- */
|
||||
case SPL_AST_EXPR_INDEX: {
|
||||
spl_lang_type_id_t obj_tid = sema_infer(sema, n->index.obj);
|
||||
sema_infer(sema, n->index.index);
|
||||
@@ -1355,7 +1530,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return elem;
|
||||
}
|
||||
|
||||
/* ---------- SLICE ---------- */
|
||||
case SPL_AST_EXPR_SLICE: {
|
||||
spl_lang_type_id_t obj_tid = sema_infer(sema, n->slice.obj);
|
||||
if (n->slice.begin)
|
||||
@@ -1379,7 +1553,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return s;
|
||||
}
|
||||
|
||||
/* ---------- CAST ---------- */
|
||||
case SPL_AST_EXPR_CAST: {
|
||||
spl_lang_type_id_t dst_lang = sema_infer(sema, n->cast.type);
|
||||
if (!dst_lang)
|
||||
@@ -1389,7 +1562,7 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return 0;
|
||||
|
||||
spl_lang_type_node_t *sn = spl_lang_type_node(sema->type, src_lang);
|
||||
spl_type_node_t *sir = sn ? spl_type_node(sema->type, sn->ir_type_id) : NULL;
|
||||
spl_type_node_t *sir = sn ? spl_type_node(&sema->type->ir, sn->ir_type_id) : NULL;
|
||||
bool src_is_literal_int =
|
||||
sn && sn->kind == SPL_LANG_TYPE_INT && sir && sir->int_type.bits == 0;
|
||||
bool src_is_literal_float =
|
||||
@@ -1414,7 +1587,7 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
"as: unresolved source or target type");
|
||||
return 0;
|
||||
}
|
||||
spl_intrin_t in = spl_intrin_lookup_cast(sema->type, ft, tt);
|
||||
spl_intrin_t in = spl_intrin_lookup_cast(&sema->type->ir, ft, tt);
|
||||
if (in == SPL_INTRIN_NONE) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_CAST_INVALID, &n->dbg,
|
||||
"as: invalid conversion (not supported by as)");
|
||||
@@ -1424,7 +1597,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return dst_lang;
|
||||
}
|
||||
|
||||
/* ---------- TUPLE ---------- */
|
||||
case SPL_AST_EXPR_TUPLE: {
|
||||
spl_lang_type_id_vec_t es;
|
||||
vec_init(es);
|
||||
@@ -1437,7 +1609,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return t;
|
||||
}
|
||||
|
||||
/* ---------- ARRAY_LIT ---------- */
|
||||
case SPL_AST_EXPR_ARRAY_LIT: {
|
||||
spl_lang_type_id_t elem_t = 0;
|
||||
if (n->array_literal.elem_type)
|
||||
@@ -1467,7 +1638,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
/* ---------- AGGREGATE_LIT ---------- */
|
||||
case SPL_AST_EXPR_AGGREGATE_LIT: {
|
||||
const char *type_name = n->aggregate_literal.name;
|
||||
if (!type_name) {
|
||||
@@ -1501,7 +1671,7 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return 0;
|
||||
}
|
||||
spl_type_id_t agg_ir = spl_lang_type_get_ir_type(sema->type, agg);
|
||||
spl_type_node_t *irn = spl_type_node(sema->type, agg_ir);
|
||||
spl_type_node_t *irn = spl_type_node(&sema->type->ir, agg_ir);
|
||||
if (irn) {
|
||||
for (usize i = 0; i < vec_size(n->aggregate_literal.fields); ++i) {
|
||||
spl_ast_node_t *item =
|
||||
@@ -1509,7 +1679,7 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
if (!item || item->kind != SPL_AST_STRUCT_INIT_ITEM)
|
||||
continue;
|
||||
usize idx = 0;
|
||||
if (!spl_type_agg_member_idx(sema->type, agg_ir, item->struct_init_item.name,
|
||||
if (!spl_type_agg_member_idx(&sema->type->ir, agg_ir, item->struct_init_item.name,
|
||||
&idx)) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_NO_FIELD, &item->dbg, "no field `%s`",
|
||||
item->struct_init_item.name);
|
||||
@@ -1525,8 +1695,21 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return agg;
|
||||
}
|
||||
|
||||
/* ---------- COMPTIME_CALL ---------- */
|
||||
case SPL_AST_EXPR_COMPTIME_CALL: {
|
||||
if (n->comptime_call.name && strcmp(n->comptime_call.name, "import") == 0) {
|
||||
spl_lang_type_id_t t = sema_import(sema, n, &n->comptime_call.args);
|
||||
n->resolved_lang_tid = t;
|
||||
return t;
|
||||
}
|
||||
if (n->comptime_call.name && strcmp(n->comptime_call.name, "self") == 0) {
|
||||
if (sema->current_aggregate_lang == 0) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_UNDEFINED_SYMBOL, &n->dbg,
|
||||
"`@self` outside of aggregate");
|
||||
return 0;
|
||||
}
|
||||
n->resolved_lang_tid = sema->current_aggregate_lang;
|
||||
return sema->current_aggregate_lang;
|
||||
}
|
||||
spl_intrin_t in = spl_intrin_lookup_call(n->comptime_call.name);
|
||||
if (in == SPL_INTRIN_NONE) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_UNKNOWN_INTRIN, &n->dbg,
|
||||
@@ -1538,11 +1721,9 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return t;
|
||||
}
|
||||
|
||||
/* ---------- BLOCK ---------- */
|
||||
case SPL_AST_EXPR_BLOCK:
|
||||
return sema_block_body(sema, n, 0);
|
||||
|
||||
/* ---------- IF ---------- */
|
||||
case SPL_AST_EXPR_IF: {
|
||||
spl_lang_type_id_t bt = spl_lang_make_bool(sema->type);
|
||||
sema_coerce(sema, n->if_expr.cond, bt);
|
||||
@@ -1560,7 +1741,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ---------- IFVAR / WHILE / LOOP / FOR / MATCH ---------- */
|
||||
case SPL_AST_EXPR_IFVAR: {
|
||||
sema_infer(sema, n->ifvar_expr.var_decl);
|
||||
if (n->ifvar_expr.then_block)
|
||||
@@ -1623,7 +1803,7 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
if (strcmp(var_name, "_") != 0) {
|
||||
spl_symbol_t sym = {.name = var_name, .kind = SPL_SYMBOL_KIND_VAR};
|
||||
sym.node = spl_def_alloc(sema->type, SPL_DEF_VAR, var_name, id_node->dbg,
|
||||
vec_at(n->for_expr.idents, i));
|
||||
sema->ast, vec_at(n->for_expr.idents, i));
|
||||
spl_def_resolve(sema->type, sym.node, elem_tid);
|
||||
if (!spl_scope_insert(sema->scope, sema->scope->current_scope, sym)) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_DUPLICATE_SYMBOL,
|
||||
@@ -1656,7 +1836,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ---------- FN_TYPE ---------- */
|
||||
case SPL_AST_EXPR_FN_TYPE: {
|
||||
spl_lang_type_id_vec_t ps;
|
||||
vec_init(ps);
|
||||
@@ -1670,7 +1849,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return fn;
|
||||
}
|
||||
|
||||
/* ---------- 类型表达式 ---------- */
|
||||
case SPL_AST_TYPE_PATH: {
|
||||
const char *name = n->type_path.name;
|
||||
spl_lang_type_id_t b = spl_type_lookup_builtin(sema->type, name);
|
||||
@@ -1754,10 +1932,14 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
n->resolved_lang_tid = sema->current_aggregate_lang;
|
||||
return sema->current_aggregate_lang;
|
||||
}
|
||||
if (name && strcmp(name, "import") == 0) {
|
||||
spl_lang_type_id_t t = sema_import(sema, n, &n->type_comptime_call.args);
|
||||
n->resolved_lang_tid = t;
|
||||
return t;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ---------- 顶层声明 ---------- */
|
||||
case SPL_AST_CONTAINER_MEMBERS:
|
||||
for (usize i = 0; i < vec_size(n->container_members.declarations); ++i)
|
||||
sema_infer(sema, vec_at(n->container_members.declarations, i));
|
||||
@@ -1795,7 +1977,7 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
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,
|
||||
psym.node = spl_def_alloc(sema->type, SPL_DEF_VAR, psym.name, pd->dbg, sema->ast,
|
||||
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);
|
||||
@@ -1845,7 +2027,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return lang;
|
||||
}
|
||||
|
||||
/* ---------- VAR / CONST ---------- */
|
||||
case SPL_AST_VAR_DECL:
|
||||
case SPL_AST_CONST_DECL: {
|
||||
spl_ast_node_t *pat = spl_ast_node(sema->ast, n->var_const_decl.pattern);
|
||||
@@ -1858,7 +2039,7 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
|
||||
if (n->resolved_def_id == 0) {
|
||||
spl_symbol_t sym = {.name = name, .kind = SPL_SYMBOL_KIND_VAR};
|
||||
sym.node = spl_def_alloc(sema->type, SPL_DEF_VAR, name, n->dbg, ref);
|
||||
sym.node = spl_def_alloc(sema->type, SPL_DEF_VAR, name, n->dbg, sema->ast, ref);
|
||||
n->resolved_def_id = sym.node;
|
||||
if (!spl_scope_insert(sema->scope, sema->scope->current_scope, sym)) {
|
||||
spl_diag_error(sema->diag, SPL_DIAG_KIND_DUPLICATE_SYMBOL, &n->dbg,
|
||||
@@ -1892,7 +2073,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return decl_tid;
|
||||
}
|
||||
|
||||
/* ---------- MEMBER / PARAM ---------- */
|
||||
case SPL_AST_MEMBER_DECL:
|
||||
if (n->member_decl.type_expr)
|
||||
return sema_infer(sema, n->member_decl.type_expr);
|
||||
@@ -1902,7 +2082,6 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return sema_infer(sema, n->param_decl.type_expr);
|
||||
return 0;
|
||||
|
||||
/* ---------- 语句 ---------- */
|
||||
case SPL_AST_STATEMENT_RET: {
|
||||
if (n->statement_ret.expr) {
|
||||
if (sema->current_fn_ret_tid)
|
||||
@@ -2009,7 +2188,7 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spl_sema_init(spl_sema_t *sema, spl_ast_t *ast, spl_type_t *type, spl_scope_t *scope,
|
||||
void spl_sema_init(spl_sema_t *sema, spl_ast_t *ast, spl_lang_type_t *type, spl_scope_t *scope,
|
||||
spl_attr_t *attr) {
|
||||
Assert(sema != NULL && ast != NULL && type != NULL && scope != NULL && attr != NULL);
|
||||
sema->ast = ast;
|
||||
@@ -2021,6 +2200,7 @@ void spl_sema_init(spl_sema_t *sema, spl_ast_t *ast, spl_type_t *type, spl_scope
|
||||
sema->attr = attr;
|
||||
sema->root = (spl_symbol_t){0};
|
||||
vec_init(sema->label_stack);
|
||||
sema->loader = NULL;
|
||||
|
||||
sema->diag = NULL;
|
||||
}
|
||||
@@ -2046,6 +2226,10 @@ void spl_sema_run(spl_sema_t *sema) {
|
||||
if (!root || root->kind != SPL_AST_ROOT)
|
||||
return;
|
||||
spl_sema_run_module(sema, root->root.members);
|
||||
|
||||
spl_ast_node_t *cm = spl_ast_node(sema->ast, root->root.members);
|
||||
if (cm && cm->resolved_def_id)
|
||||
sema_eval_decl(sema, cm->resolved_def_id);
|
||||
}
|
||||
|
||||
void spl_sema_dump(spl_sema_t *sema) {
|
||||
@@ -2066,9 +2250,9 @@ void spl_sema_dump(spl_sema_t *sema) {
|
||||
printf("\n");
|
||||
}
|
||||
printf("TypeTable:\n");
|
||||
for (usize i = 1; i < vec_size(sema->type->type_table); ++i) {
|
||||
for (usize i = 1; i < vec_size(sema->type->ir.type_table); ++i) {
|
||||
printf(" type_id#%zu ", i);
|
||||
spl_type_pure_dump(sema->type, i);
|
||||
spl_type_pure_dump(&sema->type->ir, i);
|
||||
printf("\n");
|
||||
}
|
||||
printf("DefTable:\n");
|
||||
|
||||
Reference in new issue
Block a user