stage1 支持defer 支持null 支持指针运算 支持*any指针
This commit is contained in:
1 parent
983746c797
commit
be41a82d55
4 files changed
+98
-34
No files matched your search
+44
-20
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user