stage1 支持defer 支持null 支持指针运算 支持*any指针

This commit is contained in:
zzy committed 2026-09-15 11:08:44 +08:00
1 parent 983746c797
commit be41a82d55
4 files changed
+98 -34

No files matched your search

+44 -20
View File
@@ -582,7 +582,6 @@ static spl_lang_type_id_t sema_check(spl_sema_t *sema, spl_ast_node_ref_t ref,
if (op == SPL_OP_CMP_EQ || op == SPL_OP_CMP_NE || op == SPL_OP_CMP_LT ||
op == SPL_OP_CMP_LE || op == SPL_OP_CMP_GT || op == SPL_OP_CMP_GE) {
/* 比较:结果 bool,节点存操作数类型;不依赖 expected */
spl_lang_type_id_t lt = sema_infer(sema, n->binary.left);
spl_lang_type_id_t rt = sema_infer(sema, n->binary.right);
if (!lt || !rt)
@@ -605,6 +604,23 @@ static spl_lang_type_id_t sema_check(spl_sema_t *sema, spl_ast_node_ref_t ref,
n->resolved_lang_tid = common;
return spl_lang_make_bool(sema->type);
}
/* ptr +/- int:右侧 check 到整数,节点类型仍为指针 */
if (op == SPL_OP_ADD || op == SPL_OP_SUB) {
spl_lang_type_id_t lt = sema_infer(sema, n->binary.left);
if (!lt)
return 0;
spl_lang_type_node_t *lln = spl_lang_type_node(sema->type, lt);
if (lln && lln->kind == SPL_LANG_TYPE_PTR) {
spl_lang_type_id_t it = spl_lang_make_int(sema->type, sizeof(void *) * 8, 1);
if (!sema_check(sema, n->binary.right, it))
return 0;
n->resolved_lang_tid = lt;
n->expected_lang_tid = expected;
return expected;
}
}
/* 算术 / 位 / 移位:两侧 check 到 expected */
if (!sema_check(sema, n->binary.left, expected))
return 0;
@@ -1044,10 +1060,16 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
common = lt;
}
}
/* ptr +/- int 特判 */
if (!common) {
SPL_ERROR(&n->dbg, "arithmetic operands type mismatch");
sema->error_count++;
return 0;
spl_lang_type_node_t *pln = spl_lang_type_node(sema->type, lt);
spl_lang_type_node_t *prn = spl_lang_type_node(sema->type, rt);
if (pln && pln->kind == SPL_LANG_TYPE_PTR && prn && prn->kind == SPL_LANG_TYPE_INT &&
(op == SPL_OP_ADD || op == SPL_OP_SUB)) {
n->resolved_lang_tid = lt;
n->expected_lang_tid = 0;
return lt;
}
}
sema_check(sema, n->binary.left, common);
sema_check(sema, n->binary.right, common);
@@ -1133,31 +1155,33 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
if (obj->kind == SPL_LANG_TYPE_PTR)
agg_lang = obj->extra.elem;
spl_lang_type_node_t *agg = spl_lang_type_node(sema->type, agg_lang);
if (!agg || (agg->kind != SPL_LANG_TYPE_STRUCT && agg->kind != SPL_LANG_TYPE_UNION &&
agg->kind != SPL_LANG_TYPE_ENUM)) {
SPL_ERROR(&n->dbg, "field access on non-aggregate type");
if (!agg) {
SPL_ERROR(&n->dbg, "field access on invalid type");
sema->error_count++;
return 0;
}
spl_type_id_t agg_ir = spl_lang_type_get_ir_type(sema->type, agg_lang);
const spl_type_member_t *m = spl_type_agg_member(sema->type, agg_ir, n->field.field);
if (m) {
spl_lang_type_id_t ft = sema_lang_from_ir(sema, m->type_id);
if (!ft) {
SPL_ERROR(&n->dbg, "cannot resolve field type");
sema->error_count++;
return 0;
if (agg_ir) {
const spl_type_member_t *m = spl_type_agg_member(sema->type, agg_ir, n->field.field);
if (m) {
spl_lang_type_id_t ft = sema_lang_from_ir(sema, m->type_id);
if (!ft) {
SPL_ERROR(&n->dbg, "cannot resolve field type");
sema->error_count++;
return 0;
}
n->resolved_lang_tid = ft;
return ft;
}
n->resolved_lang_tid = ft;
return ft;
}
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;
}