stage1 支持tuple 修复悬垂指针问题
This commit is contained in:
1 parent
a621e34d51
commit
3175e04e6e
2 files changed
+158
-58
No files matched your search
+50
-15
@@ -361,7 +361,6 @@ static spl_lang_type_id_t sema_eval_decl(spl_sema_t *sema, spl_def_id_t def_id)
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -630,6 +629,28 @@ static spl_lang_type_id_t sema_check(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
||||
break; /* 非数组 expected:退回通用逻辑 */
|
||||
}
|
||||
|
||||
case SPL_AST_EXPR_TUPLE: {
|
||||
spl_lang_type_node_t *en = spl_lang_type_node(sema->type, expected);
|
||||
if (en && en->kind == SPL_LANG_TYPE_TUPLE) {
|
||||
usize nelems = vec_size(n->tuple.elems);
|
||||
usize ntypes = vec_size(en->extra.elems);
|
||||
if (nelems != ntypes) {
|
||||
SPL_ERROR(&n->dbg, "tuple arity mismatch (expected %zu, got %zu)", ntypes, nelems);
|
||||
sema->error_count++;
|
||||
return 0;
|
||||
}
|
||||
for (usize i = 0; i < nelems; ++i) {
|
||||
spl_lang_type_id_t et = vec_at(en->extra.elems, i);
|
||||
if (!sema_check(sema, vec_at(n->tuple.elems, i), et))
|
||||
return 0;
|
||||
}
|
||||
n->resolved_lang_tid = expected;
|
||||
n->expected_lang_tid = 0;
|
||||
return expected;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SPL_AST_EXPR_AGGREGATE_LIT: {
|
||||
spl_lang_type_node_t *en = spl_lang_type_node(sema->type, expected);
|
||||
if (!en || (en->kind != SPL_LANG_TYPE_STRUCT && en->kind != SPL_LANG_TYPE_UNION &&
|
||||
@@ -710,8 +731,8 @@ static spl_lang_type_id_t sema_check(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
||||
continue;
|
||||
}
|
||||
seen[idx] = true;
|
||||
spl_type_member_t *m = &vec_at(irn->agg_type.variants, idx);
|
||||
spl_lang_type_id_t ft = sema_lang_from_ir(sema, m->type_id);
|
||||
usize field_tid_ir = vec_at(irn->agg_type.variants, idx).type_id;
|
||||
spl_lang_type_id_t ft = sema_lang_from_ir(sema, field_tid_ir);
|
||||
if (!ft)
|
||||
continue;
|
||||
if (!item->struct_init_item.expr) {
|
||||
@@ -1078,7 +1099,8 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
|
||||
/* 固定参数:check 到形参类型 */
|
||||
for (usize i = 0; i < nargs && i < fixed; ++i) {
|
||||
spl_lang_type_id_t pt = vec_at(fn->extra.fn.params, i);
|
||||
spl_lang_type_id_t pt =
|
||||
vec_at(spl_lang_type_node(sema->type, callee_tid)->extra.fn.params, i);
|
||||
sema_check(sema, vec_at(n->call.args, i), pt);
|
||||
}
|
||||
/* varargs:默认提升到 isize */
|
||||
@@ -1131,11 +1153,11 @@ 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)
|
||||
spl_lang_method_t meth = vec_at(agg->methods, i);
|
||||
if (strcmp(meth.name, n->field.field) != 0)
|
||||
continue;
|
||||
n->resolved_def_id = meth->def_id;
|
||||
spl_lang_type_id_t t = sema_eval_decl(sema, meth->def_id);
|
||||
n->resolved_def_id = meth.def_id;
|
||||
spl_lang_type_id_t t = sema_eval_decl(sema, meth.def_id);
|
||||
n->resolved_lang_tid = t;
|
||||
return t;
|
||||
}
|
||||
@@ -1160,10 +1182,22 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
case SPL_LANG_TYPE_PTR:
|
||||
elem = obj->extra.elem;
|
||||
break;
|
||||
case SPL_LANG_TYPE_TUPLE:
|
||||
if (vec_size(obj->extra.elems) > 0)
|
||||
elem = vec_at(obj->extra.elems, 0);
|
||||
case SPL_LANG_TYPE_TUPLE: {
|
||||
spl_ast_node_t *idx_node = spl_ast_node(sema->ast, n->index.index);
|
||||
if (!idx_node || idx_node->kind != SPL_AST_EXPR_INT_LIT) {
|
||||
SPL_ERROR(&n->dbg, "tuple index must be an integer literal");
|
||||
sema->error_count++;
|
||||
return 0;
|
||||
}
|
||||
isize i = idx_node->int_lit.val;
|
||||
if (i < 0 || (usize)i >= vec_size(obj->extra.elems)) {
|
||||
SPL_ERROR(&n->dbg, "tuple index out of range");
|
||||
sema->error_count++;
|
||||
return 0;
|
||||
}
|
||||
elem = vec_at(obj->extra.elems, (usize)i);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
SPL_ERROR(&n->dbg, "index base must be array/slice/ptr/range/tuple");
|
||||
sema->error_count++;
|
||||
@@ -1304,8 +1338,8 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
sema->error_count++;
|
||||
continue;
|
||||
}
|
||||
spl_type_member_t *m = &vec_at(irn->agg_type.variants, idx);
|
||||
spl_lang_type_id_t ft = sema_lang_from_ir(sema, m->type_id);
|
||||
usize field_tid_ir = vec_at(irn->agg_type.variants, idx).type_id;
|
||||
spl_lang_type_id_t ft = sema_lang_from_ir(sema, field_tid_ir);
|
||||
if (ft && item->struct_init_item.expr)
|
||||
sema_check(sema, item->struct_init_item.expr, ft);
|
||||
}
|
||||
@@ -1534,6 +1568,7 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
if (!def)
|
||||
return 0;
|
||||
|
||||
spl_def_id_t owner_def_id = def->owner_def;
|
||||
spl_lang_type_id_t fn_tid = def->lang_id;
|
||||
if (fn_tid == 0)
|
||||
fn_tid = sema_eval_decl(sema, n->resolved_def_id);
|
||||
@@ -1546,8 +1581,8 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
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_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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user