stage1 支持defer 支持null 支持指针运算 支持*any指针
This commit is contained in:
1 parent
983746c797
commit
be41a82d55
4 files changed
+98
-34
No files matched your search
+34
-9
@@ -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_builder_control_ret(a->ir, ret_ir, v);
|
||||||
spl_ir_node_ref_t v = emit_expr(a, n->statement_ret.expr);
|
|
||||||
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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
+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 ||
|
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,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)
|
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);
|
||||||
const spl_type_member_t *m = spl_type_agg_member(sema->type, agg_ir, n->field.field);
|
if (agg_ir) {
|
||||||
if (m) {
|
const spl_type_member_t *m = spl_type_agg_member(sema->type, agg_ir, n->field.field);
|
||||||
spl_lang_type_id_t ft = sema_lang_from_ir(sema, m->type_id);
|
if (m) {
|
||||||
if (!ft) {
|
spl_lang_type_id_t ft = sema_lang_from_ir(sema, m->type_id);
|
||||||
SPL_ERROR(&n->dbg, "cannot resolve field type");
|
if (!ft) {
|
||||||
sema->error_count++;
|
SPL_ERROR(&n->dbg, "cannot resolve field type");
|
||||||
return 0;
|
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) {
|
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
@@ -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;
|
||||||
|
|||||||
Reference in new issue
Block a user