stage1 支持tuple 修复悬垂指针问题
This commit is contained in:
1 parent
a621e34d51
commit
3175e04e6e
2 files changed
+158
-58
No files matched your search
+108
-43
@@ -44,7 +44,8 @@ static spl_ir_node_ref_t emit_zero_value(spl_ast2ir_t *a, spl_type_id_t tid) {
|
|||||||
spl_type_node_t *tn = spl_type_node(a->sema->type, tid);
|
spl_type_node_t *tn = spl_type_node(a->sema->type, tid);
|
||||||
if (!tn)
|
if (!tn)
|
||||||
return 0;
|
return 0;
|
||||||
switch (tn->kind) {
|
spl_type_node_kind_t tk = tn->kind;
|
||||||
|
switch (tk) {
|
||||||
case SPL_TYPE_BOOL:
|
case SPL_TYPE_BOOL:
|
||||||
return spl_ir_builder_type_const_bool(a->ir, tid, false);
|
return spl_ir_builder_type_const_bool(a->ir, tid, false);
|
||||||
case SPL_TYPE_INT:
|
case SPL_TYPE_INT:
|
||||||
@@ -55,9 +56,11 @@ static spl_ir_node_ref_t emit_zero_value(spl_ast2ir_t *a, spl_type_id_t tid) {
|
|||||||
case SPL_TYPE_FN:
|
case SPL_TYPE_FN:
|
||||||
return spl_ir_builder_type_const_ptr(a->ir, tid, NULL);
|
return spl_ir_builder_type_const_ptr(a->ir, tid, NULL);
|
||||||
case SPL_TYPE_ARRAY: {
|
case SPL_TYPE_ARRAY: {
|
||||||
|
usize arr_len = tn->array_type.len;
|
||||||
|
spl_type_id_t arr_elem = tn->array_type.element;
|
||||||
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, tid);
|
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, tid);
|
||||||
for (usize i = 0; i < tn->array_type.len; ++i) {
|
for (usize i = 0; i < arr_len; ++i) {
|
||||||
spl_ir_node_ref_t f = emit_zero_value(a, tn->array_type.element);
|
spl_ir_node_ref_t f = emit_zero_value(a, arr_elem);
|
||||||
if (!f)
|
if (!f)
|
||||||
return 0;
|
return 0;
|
||||||
spl_ir_builder_agg_construct_field(a->ir, node, f);
|
spl_ir_builder_agg_construct_field(a->ir, node, f);
|
||||||
@@ -66,20 +69,31 @@ static spl_ir_node_ref_t emit_zero_value(spl_ast2ir_t *a, spl_type_id_t tid) {
|
|||||||
}
|
}
|
||||||
case SPL_TYPE_STRUCT:
|
case SPL_TYPE_STRUCT:
|
||||||
case SPL_TYPE_SHAPE: {
|
case SPL_TYPE_SHAPE: {
|
||||||
|
usize nfield = vec_size(tn->agg_type.variants);
|
||||||
|
spl_type_id_vec_t field_tids;
|
||||||
|
vec_init(field_tids);
|
||||||
|
for (usize i = 0; i < nfield; ++i)
|
||||||
|
vec_push(field_tids, vec_at(tn->agg_type.variants, i).type_id);
|
||||||
|
|
||||||
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, tid);
|
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, tid);
|
||||||
for (usize i = 0; i < vec_size(tn->agg_type.variants); ++i) {
|
for (usize i = 0; i < nfield; ++i) {
|
||||||
spl_ir_node_ref_t f = emit_zero_value(a, vec_at(tn->agg_type.variants, i).type_id);
|
spl_ir_node_ref_t f = emit_zero_value(a, vec_at(field_tids, i));
|
||||||
if (!f)
|
if (!f) {
|
||||||
|
vec_free(field_tids);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
spl_ir_builder_agg_construct_field(a->ir, node, f);
|
spl_ir_builder_agg_construct_field(a->ir, node, f);
|
||||||
}
|
}
|
||||||
|
vec_free(field_tids);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
case SPL_TYPE_UNION: {
|
case SPL_TYPE_UNION: {
|
||||||
|
usize nfield = vec_size(tn->agg_type.variants);
|
||||||
|
if (nfield == 0)
|
||||||
|
return spl_ir_builder_agg_construct(a->ir, tid);
|
||||||
|
spl_type_id_t first_tid = vec_at(tn->agg_type.variants, 0).type_id;
|
||||||
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, tid);
|
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, tid);
|
||||||
if (vec_size(tn->agg_type.variants) == 0)
|
spl_ir_node_ref_t f = emit_zero_value(a, first_tid);
|
||||||
return node;
|
|
||||||
spl_ir_node_ref_t f = emit_zero_value(a, vec_at(tn->agg_type.variants, 0).type_id);
|
|
||||||
if (!f)
|
if (!f)
|
||||||
return 0;
|
return 0;
|
||||||
spl_ir_builder_agg_construct_field(a->ir, node, f);
|
spl_ir_builder_agg_construct_field(a->ir, node, f);
|
||||||
@@ -89,7 +103,6 @@ static spl_ir_node_ref_t emit_zero_value(spl_ast2ir_t *a, spl_type_id_t tid) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void copy_attrs_to_ir_node(spl_ast2ir_t *a, spl_ast_node_t *n, spl_ir_node_ref_t ir_ref) {
|
static void copy_attrs_to_ir_node(spl_ast2ir_t *a, spl_ast_node_t *n, spl_ir_node_ref_t ir_ref) {
|
||||||
if (!ir_ref || !n || vec_size(n->attrs) == 0)
|
if (!ir_ref || !n || vec_size(n->attrs) == 0)
|
||||||
return;
|
return;
|
||||||
@@ -234,14 +247,17 @@ static spl_ir_node_ref_t emit_lvalue(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
|
|||||||
spl_lang_type_node_t *obj_ln = spl_lang_type_node(a->sema->type, obj_lang);
|
spl_lang_type_node_t *obj_ln = spl_lang_type_node(a->sema->type, obj_lang);
|
||||||
if (!obj_ln)
|
if (!obj_ln)
|
||||||
return 0;
|
return 0;
|
||||||
if (spl_intrin_lookup_field(obj_ln->kind, n->field.field) != SPL_INTRIN_NONE)
|
spl_lang_type_kind_t obj_kind = obj_ln->kind;
|
||||||
|
spl_lang_type_id_t obj_elem = (obj_kind == SPL_LANG_TYPE_PTR) ? obj_ln->extra.elem : 0;
|
||||||
|
|
||||||
|
if (spl_intrin_lookup_field(obj_kind, n->field.field) != SPL_INTRIN_NONE)
|
||||||
return 0; /* 内建字段不是左值 */
|
return 0; /* 内建字段不是左值 */
|
||||||
|
|
||||||
spl_ir_node_ref_t base = 0;
|
spl_ir_node_ref_t base = 0;
|
||||||
spl_lang_type_id_t agg_lang = 0;
|
spl_lang_type_id_t agg_lang = 0;
|
||||||
if (obj_ln->kind == SPL_LANG_TYPE_PTR) {
|
if (obj_kind == SPL_LANG_TYPE_PTR) {
|
||||||
base = emit_expr(a, n->field.obj);
|
base = emit_expr(a, n->field.obj);
|
||||||
agg_lang = obj_ln->extra.elem;
|
agg_lang = obj_elem;
|
||||||
} else {
|
} else {
|
||||||
base = emit_lvalue(a, n->field.obj);
|
base = emit_lvalue(a, n->field.obj);
|
||||||
agg_lang = obj_lang;
|
agg_lang = obj_lang;
|
||||||
@@ -272,25 +288,43 @@ static spl_ir_node_ref_t emit_lvalue(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
|
|||||||
if (!obj_ln)
|
if (!obj_ln)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
spl_lang_type_kind_t obj_kind = obj_ln->kind;
|
||||||
|
spl_lang_type_id_t obj_elem = 0;
|
||||||
|
if (obj_kind == SPL_LANG_TYPE_PTR || obj_kind == SPL_LANG_TYPE_ARRAY ||
|
||||||
|
obj_kind == SPL_LANG_TYPE_SLICE)
|
||||||
|
obj_elem = obj_ln->extra.elem;
|
||||||
|
|
||||||
|
if (obj_kind == SPL_LANG_TYPE_TUPLE) {
|
||||||
|
spl_ast_node_t *idx_node = spl_ast_node(a->sema->ast, n->index.index);
|
||||||
|
if (!idx_node || idx_node->kind != SPL_AST_EXPR_INT_LIT)
|
||||||
|
return 0;
|
||||||
|
usize i = (usize)idx_node->int_lit.val;
|
||||||
|
spl_ir_node_ref_t base = emit_lvalue(a, n->index.obj);
|
||||||
|
if (!base)
|
||||||
|
return 0;
|
||||||
|
spl_type_id_t tuple_ir = to_ir_type(a, obj_lang);
|
||||||
|
if (!tuple_ir)
|
||||||
|
return 0;
|
||||||
|
return spl_ir_builder_mem_field(a->ir, tuple_ir, base, i);
|
||||||
|
}
|
||||||
|
|
||||||
spl_ir_node_ref_t base = 0;
|
spl_ir_node_ref_t base = 0;
|
||||||
spl_lang_type_id_t elem_lang = 0;
|
spl_lang_type_id_t elem_lang = 0;
|
||||||
if (obj_ln->kind == SPL_LANG_TYPE_PTR) {
|
if (obj_kind == SPL_LANG_TYPE_PTR) {
|
||||||
base = emit_expr(a, n->index.obj);
|
base = emit_expr(a, n->index.obj);
|
||||||
elem_lang = obj_ln->extra.elem;
|
elem_lang = obj_elem;
|
||||||
} else if (obj_ln->kind == SPL_LANG_TYPE_ARRAY) {
|
} else if (obj_kind == SPL_LANG_TYPE_ARRAY) {
|
||||||
base = emit_lvalue(a, n->index.obj);
|
base = emit_lvalue(a, n->index.obj);
|
||||||
elem_lang = obj_ln->extra.elem;
|
elem_lang = obj_elem;
|
||||||
} else if (obj_ln->kind == SPL_LANG_TYPE_SLICE) {
|
} else if (obj_kind == SPL_LANG_TYPE_SLICE) {
|
||||||
/* 切片:取出切片值,再 agg_extract 出 ptr 字段 */
|
|
||||||
spl_ir_node_ref_t slice_val = emit_expr(a, n->index.obj);
|
spl_ir_node_ref_t slice_val = emit_expr(a, n->index.obj);
|
||||||
if (!slice_val)
|
if (!slice_val)
|
||||||
return 0;
|
return 0;
|
||||||
spl_lang_type_id_t elem = obj_ln->extra.elem;
|
spl_type_id_t ptr_ir = spl_type_builder_ptr(a->sema->type, to_ir_type(a, obj_elem));
|
||||||
spl_type_id_t ptr_ir = spl_type_builder_ptr(a->sema->type, to_ir_type(a, elem));
|
|
||||||
spl_ir_node_ref_t ptr = spl_ir_builder_agg_extract(a->ir, ptr_ir, ptr_ir,
|
spl_ir_node_ref_t ptr = spl_ir_builder_agg_extract(a->ir, ptr_ir, ptr_ir,
|
||||||
SPL_SLICE_PTR_FIELD_IDX, slice_val);
|
SPL_SLICE_PTR_FIELD_IDX, slice_val);
|
||||||
base = ptr;
|
base = ptr;
|
||||||
elem_lang = elem;
|
elem_lang = obj_elem;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -673,7 +707,9 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
|||||||
if (!tn)
|
if (!tn)
|
||||||
Panic("aggregate type node missing");
|
Panic("aggregate type node missing");
|
||||||
|
|
||||||
if (tn->kind == SPL_TYPE_ENUM) {
|
spl_type_node_kind_t tn_kind = tn->kind;
|
||||||
|
|
||||||
|
if (tn_kind == SPL_TYPE_ENUM) {
|
||||||
if (vec_size(n->aggregate_literal.fields) != 1)
|
if (vec_size(n->aggregate_literal.fields) != 1)
|
||||||
Panic("enum literal must have exactly one variant");
|
Panic("enum literal must have exactly one variant");
|
||||||
spl_ast_node_t *item =
|
spl_ast_node_t *item =
|
||||||
@@ -686,25 +722,30 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
|||||||
Panic("enum variant `%s` not found (sema should have caught this)",
|
Panic("enum variant `%s` not found (sema should have caught this)",
|
||||||
item->struct_init_item.name);
|
item->struct_init_item.name);
|
||||||
|
|
||||||
|
spl_type_id_t tag_ir = tn->agg_type.tag_type;
|
||||||
|
spl_type_id_t payload_ir = vec_at(tn->agg_type.variants, vidx).type_id;
|
||||||
|
|
||||||
spl_ir_node_ref_t eptr = spl_ir_builder_mem_alloca(a->ir, t, const_usize(a, 1));
|
spl_ir_node_ref_t eptr = spl_ir_builder_mem_alloca(a->ir, t, const_usize(a, 1));
|
||||||
|
|
||||||
spl_type_id_t tag_ir = tn->agg_type.tag_type;
|
|
||||||
spl_ir_node_ref_t tptr =
|
spl_ir_node_ref_t tptr =
|
||||||
spl_ir_builder_mem_field(a->ir, t, eptr, SPL_ENUM_TAG_FIELD_IDX);
|
spl_ir_builder_mem_field(a->ir, t, eptr, SPL_ENUM_TAG_FIELD_IDX);
|
||||||
spl_ir_node_ref_t tag_val = spl_ir_builder_type_const_int(a->ir, tag_ir, vidx);
|
spl_ir_node_ref_t tag_val = spl_ir_builder_type_const_int(a->ir, tag_ir, vidx);
|
||||||
spl_ir_builder_mem_store(a->ir, tag_ir, tptr, tag_val);
|
spl_ir_builder_mem_store(a->ir, tag_ir, tptr, tag_val);
|
||||||
|
|
||||||
spl_type_id_t ftid = vec_at(tn->agg_type.variants, vidx).type_id;
|
|
||||||
spl_ir_node_ref_t pptr = spl_ir_builder_mem_field(a->ir, t, eptr, vidx + 1);
|
spl_ir_node_ref_t pptr = spl_ir_builder_mem_field(a->ir, t, eptr, vidx + 1);
|
||||||
spl_ir_node_ref_t payload = emit_expr(a, item->struct_init_item.expr);
|
spl_ir_node_ref_t payload = emit_expr(a, item->struct_init_item.expr);
|
||||||
if (!payload)
|
if (!payload)
|
||||||
Panic("enum payload emit failed");
|
Panic("enum payload emit failed");
|
||||||
spl_ir_builder_mem_store(a->ir, ftid, pptr, payload);
|
spl_ir_builder_mem_store(a->ir, payload_ir, pptr, payload);
|
||||||
|
|
||||||
return eptr;
|
return eptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
usize nfields = vec_size(tn->agg_type.variants);
|
usize nfields = vec_size(tn->agg_type.variants);
|
||||||
|
spl_type_id_vec_t field_tids;
|
||||||
|
vec_init(field_tids);
|
||||||
|
for (usize i = 0; i < nfields; ++i)
|
||||||
|
vec_push(field_tids, vec_at(tn->agg_type.variants, i).type_id);
|
||||||
|
|
||||||
spl_ir_node_ref_vec_t fields;
|
spl_ir_node_ref_vec_t fields;
|
||||||
vec_init(fields);
|
vec_init(fields);
|
||||||
@@ -730,24 +771,34 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
|||||||
|
|
||||||
for (usize i = 0; i < nfields; ++i) {
|
for (usize i = 0; i < nfields; ++i) {
|
||||||
if (!vec_at(fields, i)) {
|
if (!vec_at(fields, i)) {
|
||||||
spl_type_id_t ftid = vec_at(tn->agg_type.variants, i).type_id;
|
spl_ir_node_ref_t f = emit_zero_value(a, vec_at(field_tids, i));
|
||||||
spl_ir_node_ref_t f = emit_zero_value(a, ftid);
|
if (!f) {
|
||||||
if (!f)
|
vec_free(field_tids);
|
||||||
|
vec_free(fields);
|
||||||
Panic("cannot zero-init aggregate field #%zu", i);
|
Panic("cannot zero-init aggregate field #%zu", i);
|
||||||
|
}
|
||||||
vec_at(fields, i) = f;
|
vec_at(fields, i) = f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, t);
|
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, t);
|
||||||
if (!node)
|
if (!node) {
|
||||||
|
vec_free(field_tids);
|
||||||
|
vec_free(fields);
|
||||||
Panic("agg_construct failed for aggregate literal");
|
Panic("agg_construct failed for aggregate literal");
|
||||||
|
}
|
||||||
|
|
||||||
for (usize i = 0; i < nfields; ++i) {
|
for (usize i = 0; i < nfields; ++i) {
|
||||||
spl_ir_node_ref_t f = vec_at(fields, i);
|
spl_ir_node_ref_t f = vec_at(fields, i);
|
||||||
if (!f)
|
if (!f) {
|
||||||
|
vec_free(field_tids);
|
||||||
|
vec_free(fields);
|
||||||
Panic("aggregate field #%zu missing (sema should have caught this)", i);
|
Panic("aggregate field #%zu missing (sema should have caught this)", i);
|
||||||
|
}
|
||||||
spl_ir_builder_agg_construct_field(a->ir, node, f);
|
spl_ir_builder_agg_construct_field(a->ir, node, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec_free(field_tids);
|
||||||
vec_free(fields);
|
vec_free(fields);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@@ -772,11 +823,15 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
|||||||
if (!obj_ln)
|
if (!obj_ln)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
spl_lang_type_kind_t obj_kind = obj_ln->kind;
|
||||||
|
spl_lang_type_id_t obj_elem = obj_ln->extra.elem;
|
||||||
|
spl_type_id_t obj_ir = obj_ln->ir_type_id;
|
||||||
|
|
||||||
spl_type_id_t slice_ir = node_ir(a, n);
|
spl_type_id_t slice_ir = node_ir(a, n);
|
||||||
if (!slice_ir)
|
if (!slice_ir)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
spl_lang_type_id_t elem_lang = obj_ln->extra.elem;
|
spl_lang_type_id_t elem_lang = obj_elem;
|
||||||
spl_type_id_t elem_ir = to_ir_type(a, elem_lang);
|
spl_type_id_t elem_ir = to_ir_type(a, elem_lang);
|
||||||
spl_lang_type_id_t usize_lang = spl_lang_make_int(a->sema->type, sizeof(void *) * 8, 0);
|
spl_lang_type_id_t usize_lang = spl_lang_make_int(a->sema->type, sizeof(void *) * 8, 0);
|
||||||
spl_type_id_t usize_ir = to_ir_type(a, usize_lang);
|
spl_type_id_t usize_ir = to_ir_type(a, usize_lang);
|
||||||
@@ -800,13 +855,16 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
|||||||
spl_ir_node_ref_t end_v = 0;
|
spl_ir_node_ref_t end_v = 0;
|
||||||
if (n->slice.end) {
|
if (n->slice.end) {
|
||||||
end_v = emit_expr(a, n->slice.end);
|
end_v = emit_expr(a, n->slice.end);
|
||||||
} else if (obj_ln->kind == SPL_LANG_TYPE_ARRAY) {
|
} else if (obj_kind == SPL_LANG_TYPE_ARRAY) {
|
||||||
spl_type_node_t *arr = spl_type_node(a->sema->type, obj_ln->ir_type_id);
|
spl_type_node_t *arr = spl_type_node(a->sema->type, obj_ir);
|
||||||
end_v = spl_ir_builder_type_const_int(a->ir, usize_ir, arr->array_type.len);
|
if (!arr)
|
||||||
} else if (obj_ln->kind == SPL_LANG_TYPE_SLICE) {
|
return 0;
|
||||||
|
usize arr_len = arr->array_type.len;
|
||||||
|
end_v = spl_ir_builder_type_const_int(a->ir, usize_ir, arr_len);
|
||||||
|
} else if (obj_kind == SPL_LANG_TYPE_SLICE) {
|
||||||
spl_ir_node_ref_t slice_val = emit_expr(a, n->slice.obj);
|
spl_ir_node_ref_t slice_val = emit_expr(a, n->slice.obj);
|
||||||
end_v = spl_ir_builder_agg_extract(a->ir, obj_ln->ir_type_id, usize_ir,
|
end_v = spl_ir_builder_agg_extract(a->ir, obj_ir, usize_ir, SPL_SLICE_LEN_FIELD_IDX,
|
||||||
SPL_SLICE_LEN_FIELD_IDX, slice_val);
|
slice_val);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1124,10 +1182,15 @@ static void emit_fn_body(spl_ast2ir_t *a, spl_ast_node_t *n) {
|
|||||||
if (!fn_ln || fn_ln->kind != SPL_LANG_TYPE_FN)
|
if (!fn_ln || fn_ln->kind != SPL_LANG_TYPE_FN)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
spl_lang_type_id_t ret_lang = fn_ln->extra.fn.ret;
|
||||||
|
spl_type_id_t ret_ir = to_ir_type(a, ret_lang);
|
||||||
|
spl_lang_type_node_t *ret_ln = spl_lang_type_node(a->sema->type, ret_lang);
|
||||||
|
int ret_is_unit = (ret_ln && ret_ln->kind == SPL_LANG_TYPE_UNIT) ? 1 : 0;
|
||||||
|
|
||||||
spl_ir_builder_fn_begin_at(a->ir, fn_ref);
|
spl_ir_builder_fn_begin_at(a->ir, fn_ref);
|
||||||
|
|
||||||
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 = fn_ln->extra.fn.ret;
|
a->cur_ret_lang = ret_lang;
|
||||||
|
|
||||||
usize defer_base = vec_size(a->defer_stack);
|
usize defer_base = vec_size(a->defer_stack);
|
||||||
usize loop_base = vec_size(a->loop_stack);
|
usize loop_base = vec_size(a->loop_stack);
|
||||||
@@ -1164,10 +1227,12 @@ static void emit_fn_body(spl_ast2ir_t *a, spl_ast_node_t *n) {
|
|||||||
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_lang_type_id_t ret_lang = fn_ln->extra.fn.ret;
|
|
||||||
spl_lang_type_node_t *ret_ln = spl_lang_type_node(a->sema->type, ret_lang);
|
if (ret_is_unit) {
|
||||||
if (ret_ln && ret_ln->kind == SPL_LANG_TYPE_UNIT) {
|
spl_ir_builder_control_ret(a->ir, ret_ir, 0);
|
||||||
spl_ir_builder_control_ret(a->ir, to_ir_type(a, ret_lang), 0);
|
} else if (ret_ir) {
|
||||||
|
spl_ir_node_ref_t zero = emit_zero_value(a, ret_ir);
|
||||||
|
spl_ir_builder_control_ret(a->ir, ret_ir, zero);
|
||||||
} else {
|
} else {
|
||||||
spl_ir_builder_control_unreachable(a->ir);
|
spl_ir_builder_control_unreachable(a->ir);
|
||||||
}
|
}
|
||||||
|
|||||||
+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);
|
spl_def_node_t *final_def = spl_def_node(sema->type, def_id);
|
||||||
if (final_def) {
|
if (final_def) {
|
||||||
final_def->lang_id = result;
|
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:退回通用逻辑 */
|
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: {
|
case SPL_AST_EXPR_AGGREGATE_LIT: {
|
||||||
spl_lang_type_node_t *en = spl_lang_type_node(sema->type, expected);
|
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 &&
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
seen[idx] = true;
|
seen[idx] = true;
|
||||||
spl_type_member_t *m = &vec_at(irn->agg_type.variants, idx);
|
usize field_tid_ir = vec_at(irn->agg_type.variants, idx).type_id;
|
||||||
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, field_tid_ir);
|
||||||
if (!ft)
|
if (!ft)
|
||||||
continue;
|
continue;
|
||||||
if (!item->struct_init_item.expr) {
|
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 到形参类型 */
|
/* 固定参数:check 到形参类型 */
|
||||||
for (usize i = 0; i < nargs && i < fixed; ++i) {
|
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);
|
sema_check(sema, vec_at(n->call.args, i), pt);
|
||||||
}
|
}
|
||||||
/* varargs:默认提升到 isize */
|
/* 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) {
|
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;
|
||||||
}
|
}
|
||||||
@@ -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:
|
case SPL_LANG_TYPE_PTR:
|
||||||
elem = obj->extra.elem;
|
elem = obj->extra.elem;
|
||||||
break;
|
break;
|
||||||
case SPL_LANG_TYPE_TUPLE:
|
case SPL_LANG_TYPE_TUPLE: {
|
||||||
if (vec_size(obj->extra.elems) > 0)
|
spl_ast_node_t *idx_node = spl_ast_node(sema->ast, n->index.index);
|
||||||
elem = vec_at(obj->extra.elems, 0);
|
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;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
SPL_ERROR(&n->dbg, "index base must be array/slice/ptr/range/tuple");
|
SPL_ERROR(&n->dbg, "index base must be array/slice/ptr/range/tuple");
|
||||||
sema->error_count++;
|
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++;
|
sema->error_count++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
spl_type_member_t *m = &vec_at(irn->agg_type.variants, idx);
|
usize field_tid_ir = vec_at(irn->agg_type.variants, idx).type_id;
|
||||||
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, field_tid_ir);
|
||||||
if (ft && item->struct_init_item.expr)
|
if (ft && item->struct_init_item.expr)
|
||||||
sema_check(sema, item->struct_init_item.expr, ft);
|
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)
|
if (!def)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
spl_def_id_t owner_def_id = def->owner_def;
|
||||||
spl_lang_type_id_t fn_tid = def->lang_id;
|
spl_lang_type_id_t fn_tid = def->lang_id;
|
||||||
if (fn_tid == 0)
|
if (fn_tid == 0)
|
||||||
fn_tid = sema_eval_decl(sema, n->resolved_def_id);
|
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;
|
return fn_tid;
|
||||||
|
|
||||||
spl_lang_type_id_t saved_agg = sema->current_aggregate_lang;
|
spl_lang_type_id_t saved_agg = sema->current_aggregate_lang;
|
||||||
if (def->owner_def) {
|
if (owner_def_id) {
|
||||||
spl_def_node_t *owner = spl_def_node(sema->type, def->owner_def);
|
spl_def_node_t *owner = spl_def_node(sema->type, owner_def_id);
|
||||||
if (owner && owner->lang_id != 0)
|
if (owner && owner->lang_id != 0)
|
||||||
sema->current_aggregate_lang = owner->lang_id;
|
sema->current_aggregate_lang = owner->lang_id;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user