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
+88 -24

No files matched your search

+33 -8
View File
@@ -544,6 +544,23 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
spl_ir_node_ref_t r = emit_expr(a, n->binary.right); spl_ir_node_ref_t r = emit_expr(a, n->binary.right);
if (!l || !r) if (!l || !r)
return 0; return 0;
spl_ast_node_t *ln = spl_ast_node(a->sema->ast, n->binary.left);
spl_lang_type_id_t lt = node_lang(a, ln);
spl_lang_type_node_t *lln = spl_lang_type_node(a->sema->type, lt);
if (lln && lln->kind == SPL_LANG_TYPE_PTR && (op == SPL_OP_ADD || op == SPL_OP_SUB)) {
spl_lang_type_id_t elem_lang = lln->extra.elem;
spl_type_id_t elem_ir = to_ir_type(a, elem_lang);
spl_type_id_t rt_ir = node_ir(a, spl_ast_node(a->sema->ast, n->binary.right));
spl_ir_node_ref_t off = r;
if (op == SPL_OP_SUB)
off = spl_ir_builder_arith_neg(a->ir, rt_ir, r);
return spl_ir_builder_mem_offset(a->ir, elem_ir, l, off);
}
spl_type_id_t t = node_ir(a, n); spl_type_id_t t = node_ir(a, n);
switch (op) { switch (op) {
case SPL_OP_ADD: case SPL_OP_ADD:
@@ -899,17 +916,20 @@ static void emit_stmt(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
switch (n->kind) { switch (n->kind) {
case SPL_AST_STATEMENT_RET: { case SPL_AST_STATEMENT_RET: {
while (vec_size(a->defer_stack) > 0) { spl_type_id_t ret_ir = to_ir_type(a, a->cur_ret_lang);
/* 先求值 ret 表达式,结果保存在 v 中 */
spl_ir_node_ref_t v = 0;
if (n->statement_ret.expr)
v = emit_expr(a, n->statement_ret.expr);
/* 再执行 defer(LIFO),只清空当前函数注册的 defer */
while (vec_size(a->defer_stack) > a->cur_defer_base) {
spl_ast_node_ref_t d = vec_pop(a->defer_stack); spl_ast_node_ref_t d = vec_pop(a->defer_stack);
emit_stmt(a, d); emit_stmt(a, d);
} }
spl_type_id_t ret_ir = to_ir_type(a, a->cur_ret_lang);
if (n->statement_ret.expr) {
spl_ir_node_ref_t v = emit_expr(a, n->statement_ret.expr);
spl_ir_builder_control_ret(a->ir, ret_ir, v); spl_ir_builder_control_ret(a->ir, ret_ir, v);
} else {
spl_ir_builder_control_ret(a->ir, ret_ir, 0);
}
return; return;
} }
case SPL_AST_STATEMENT_DEFER: case SPL_AST_STATEMENT_DEFER:
@@ -1244,7 +1264,10 @@ static void emit_fn_body(spl_ast2ir_t *a, spl_ast_node_t *n) {
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 = ret_lang; a->cur_ret_lang = ret_lang;
usize defer_base = vec_size(a->defer_stack); usize saved_defer_base = a->cur_defer_base;
a->cur_defer_base = vec_size(a->defer_stack);
usize defer_base = a->cur_defer_base;
usize loop_base = vec_size(a->loop_stack); usize loop_base = vec_size(a->loop_stack);
spl_ir_builder_block_begin(a->ir); spl_ir_builder_block_begin(a->ir);
@@ -1301,6 +1324,7 @@ static void emit_fn_body(spl_ast2ir_t *a, spl_ast_node_t *n) {
} }
a->cur_ret_lang = saved_ret; a->cur_ret_lang = saved_ret;
a->cur_defer_base = saved_defer_base;
spl_ir_builder_block_end(a->ir); spl_ir_builder_block_end(a->ir);
spl_ir_builder_fn_end(a->ir); spl_ir_builder_fn_end(a->ir);
@@ -1455,6 +1479,7 @@ void spl_ast2ir_init(spl_ast2ir_t *ast2ir, spl_ir_builder_t *ir, const spl_sema_
vec_init(ast2ir->defer_stack); vec_init(ast2ir->defer_stack);
ast2ir->err_count = 0; ast2ir->err_count = 0;
ast2ir->cur_ret_lang = 0; ast2ir->cur_ret_lang = 0;
ast2ir->cur_defer_base = 0;
} }
void spl_ast2ir_drop(spl_ast2ir_t *ast2ir) { void spl_ast2ir_drop(spl_ast2ir_t *ast2ir) {
+1
View File
@@ -23,6 +23,7 @@ typedef struct {
spl_loop_ctx_vec_t loop_stack; spl_loop_ctx_vec_t loop_stack;
spl_defer_stack_t defer_stack; spl_defer_stack_t defer_stack;
spl_lang_type_id_t cur_ret_lang; spl_lang_type_id_t cur_ret_lang;
usize cur_defer_base;
int err_count; int err_count;
} spl_ast2ir_t; } spl_ast2ir_t;
+35 -11
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 || 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) { 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 lt = sema_infer(sema, n->binary.left);
spl_lang_type_id_t rt = sema_infer(sema, n->binary.right); spl_lang_type_id_t rt = sema_infer(sema, n->binary.right);
if (!lt || !rt) 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; n->resolved_lang_tid = common;
return spl_lang_make_bool(sema->type); 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 */ /* 算术 / 位 / 移位:两侧 check 到 expected */
if (!sema_check(sema, n->binary.left, expected)) if (!sema_check(sema, n->binary.left, expected))
return 0; 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; common = lt;
} }
} }
/* ptr +/- int 特判 */
if (!common) { if (!common) {
SPL_ERROR(&n->dbg, "arithmetic operands type mismatch"); spl_lang_type_node_t *pln = spl_lang_type_node(sema->type, lt);
sema->error_count++; spl_lang_type_node_t *prn = spl_lang_type_node(sema->type, rt);
return 0; 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.left, common);
sema_check(sema, n->binary.right, common); sema_check(sema, n->binary.right, common);
@@ -1133,13 +1155,14 @@ 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) if (obj->kind == SPL_LANG_TYPE_PTR)
agg_lang = obj->extra.elem; agg_lang = obj->extra.elem;
spl_lang_type_node_t *agg = spl_lang_type_node(sema->type, agg_lang); 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 && if (!agg) {
agg->kind != SPL_LANG_TYPE_ENUM)) { SPL_ERROR(&n->dbg, "field access on invalid type");
SPL_ERROR(&n->dbg, "field access on non-aggregate type");
sema->error_count++; sema->error_count++;
return 0; return 0;
} }
spl_type_id_t agg_ir = spl_lang_type_get_ir_type(sema->type, agg_lang); 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, agg_ir, n->field.field);
if (m) { if (m) {
spl_lang_type_id_t ft = sema_lang_from_ir(sema, m->type_id); spl_lang_type_id_t ft = sema_lang_from_ir(sema, m->type_id);
@@ -1151,13 +1174,14 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
n->resolved_lang_tid = ft; n->resolved_lang_tid = ft;
return ft; return ft;
} }
}
for (usize i = 0; i < vec_size(agg->methods); ++i) { for (usize i = 0; i < vec_size(agg->methods); ++i) {
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;
n->resolved_def_id = meth.def_id; n->resolved_def_id = meth->def_id;
spl_lang_type_id_t t = sema_eval_decl(sema, meth.def_id); spl_lang_type_id_t t = sema_eval_decl(sema, meth->def_id);
n->resolved_lang_tid = t; n->resolved_lang_tid = t;
return t; return t;
} }
+19 -5
View File
@@ -389,6 +389,17 @@ bool spl_lang_type_is_subtype(const spl_type_t *type, spl_lang_type_id_t sub,
// 推断类型暂不处理子类型关系 // 推断类型暂不处理子类型关系
return false; return false;
} }
if (nsub->kind == SPL_LANG_TYPE_PTR && nsuper->kind == SPL_LANG_TYPE_PTR) {
spl_lang_type_node_t *sub_elem = spl_lang_type_node(type, nsub->extra.elem);
spl_lang_type_node_t *super_elem = spl_lang_type_node(type, nsuper->extra.elem);
if (sub_elem && sub_elem->kind == SPL_LANG_TYPE_NEVER)
return true; /* *never <: *T */
if (super_elem && super_elem->kind == SPL_LANG_TYPE_ANY)
return true; /* *T <: *any */
if (nsub->extra.elem == nsuper->extra.elem)
return true; /* *T <: *T */
return false;
}
// 对于简单类型,委托给底层类型判断 // 对于简单类型,委托给底层类型判断
// 如果语言级 kind 相同且底层类型可子类型,则成立 // 如果语言级 kind 相同且底层类型可子类型,则成立
@@ -704,19 +715,22 @@ spl_lang_type_id_t spl_lang_make_slice(spl_type_t *type, spl_lang_type_id_t elem
spl_type_id_t elem_ir = spl_lang_type_get_ir_type(type, elem_lang); spl_type_id_t elem_ir = spl_lang_type_get_ir_type(type, elem_lang);
if (!elem_ir) if (!elem_ir)
return 0; return 0;
// 获取 usize 底层类型
spl_type_id_t usize_ir = spl_type_builder_int(type, sizeof(void *) * 8, 0); spl_lang_type_id_t ptr_lang = spl_lang_make_ptr(type, elem_lang);
spl_type_id_t ptr_ir = spl_type_builder_ptr(type, elem_ir); spl_lang_type_id_t usize_lang = spl_lang_make_int(type, sizeof(void *) * 8, 0);
// 构建 struct { ptr, len } spl_type_id_t ptr_ir = spl_lang_type_get_ir_type(type, ptr_lang);
spl_type_id_t usize_ir = spl_lang_type_get_ir_type(type, usize_lang);
spl_type_member_vec_t members; spl_type_member_vec_t members;
vec_init(members); vec_init(members);
spl_type_member_t m1 = {.name = "ptr", .type_id = ptr_ir}; spl_type_member_t m1 = {.name = "ptr", .type_id = ptr_ir};
spl_type_member_t m2 = {.name = "len", .type_id = usize_ir}; spl_type_member_t m2 = {.name = "len", .type_id = usize_ir};
vec_push(members, m1); vec_push(members, m1);
vec_push(members, m2); vec_push(members, m2);
spl_type_layout_t layout = {.mode = SPL_TYPE_LAYOUT_AUTO, .fixed_align_bits = 0}; spl_type_layout_t layout = {.mode = SPL_TYPE_LAYOUT_AUTO, .fixed_align_bits = 0};
spl_type_id_t struct_ir = spl_type_builder_agg(type, SPL_TYPE_STRUCT, &members, 0, layout); spl_type_id_t struct_ir = spl_type_builder_agg(type, SPL_TYPE_STRUCT, &members, 0, layout);
// 语言级节点
spl_lang_type_node_t node = {0}; spl_lang_type_node_t node = {0};
node.kind = SPL_LANG_TYPE_SLICE; node.kind = SPL_LANG_TYPE_SLICE;
node.ir_type_id = struct_ir; node.ir_type_id = struct_ir;