stage1 实现ir2vm 修复nob test命令的构建问题

This commit is contained in:
zzy committed 2026-09-12 18:51:10 +08:00
1 parent 87d9b7ea34
commit a64a96f9a4
11 files changed
+1565 -195

No files matched your search

+81 -45
View File
@@ -106,8 +106,8 @@ static spl_ir_node_ref_t ast2ir_intrin_len(spl_ast2ir_t *a, spl_ast_node_t *n) {
spl_ir_node_ref_t slice_val = emit_expr(a, n->field.obj);
if (!slice_val)
return 0;
return spl_ir_builder_agg_extract(a->ir, usize_ir, usize_ir, SPL_SLICE_LEN_FIELD_IDX,
slice_val);
return spl_ir_builder_agg_extract(a->ir, recv->ir_type_id, usize_ir,
SPL_SLICE_LEN_FIELD_IDX, slice_val);
}
default:
return 0;
@@ -160,12 +160,7 @@ static spl_ir_node_ref_t emit_lvalue(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
if (!spl_type_agg_member_idx(a->sema->type, agg_ir, n->field.field, &idx))
return 0;
spl_type_node_t *agg_n = spl_type_node(a->sema->type, agg_ir);
if (!agg_n)
return 0;
spl_type_id_t field_ir = vec_at(agg_n->agg_type.variants, idx).type_id;
return spl_ir_builder_mem_field(a->ir, field_ir, base, idx);
return spl_ir_builder_mem_field(a->ir, agg_ir, base, idx);
}
case SPL_AST_EXPR_INDEX: {
spl_ast_node_t *obj = spl_ast_node(a->sema->ast, n->index.obj);
@@ -442,16 +437,26 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
spl_ir_node_ref_t fn = emit_expr(a, n->call.callee);
if (!fn)
return 0;
/* 先求所有参数 */
usize nargs = vec_size(n->call.args);
spl_ir_node_ref_vec_t arg_refs;
vec_init(arg_refs);
for (usize i = 0; i < nargs; ++i)
vec_push(arg_refs, emit_expr(a, vec_at(n->call.args, i)));
/* 再创建 call 节点 */
spl_type_id_t ret_t = node_ir(a, n);
spl_ir_node_ref_t call = spl_ir_builder_control_call(a->ir, ret_t, fn);
if (!call)
if (!call) {
vec_free(arg_refs);
return 0;
for (usize i = 0; i < vec_size(n->call.args); ++i) {
spl_ir_node_ref_t arg = emit_expr(a, vec_at(n->call.args, i));
if (!arg)
return 0;
spl_ir_builder_control_call_param(a->ir, call, arg);
}
for (usize i = 0; i < vec_size(arg_refs); ++i)
spl_ir_builder_control_call_param(a->ir, call, vec_at(arg_refs, i));
vec_free(arg_refs);
return call;
}
case SPL_AST_EXPR_FIELD: {
@@ -478,15 +483,25 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
return emit_cast(a, n);
case SPL_AST_EXPR_TUPLE: {
spl_type_id_t t = node_ir(a, n);
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, t);
if (!node)
return 0;
for (usize i = 0; i < vec_size(n->tuple.elems); ++i) {
usize nelems = vec_size(n->tuple.elems);
spl_ir_node_ref_vec_t field_refs;
vec_init(field_refs);
for (usize i = 0; i < nelems; ++i) {
spl_ir_node_ref_t f = emit_expr(a, vec_at(n->tuple.elems, i));
if (!f)
return 0;
spl_ir_builder_agg_construct_field(a->ir, node, f);
Panic("tuple element emit failed");
vec_push(field_refs, f);
}
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, t);
if (!node)
Panic("agg_construct failed for tuple");
for (usize i = 0; i < nelems; ++i)
spl_ir_builder_agg_construct_field(a->ir, node, vec_at(field_refs, i));
vec_free(field_refs);
return node;
}
case SPL_AST_EXPR_ARRAY_LIT: {
@@ -494,16 +509,25 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
if (!t)
Panic("array literal has no type after sema");
usize nelems = vec_size(n->array_literal.elems);
spl_ir_node_ref_vec_t field_refs;
vec_init(field_refs);
for (usize i = 0; i < nelems; ++i) {
spl_ir_node_ref_t f = emit_expr(a, vec_at(n->array_literal.elems, i));
if (!f)
Panic("array element emit failed");
vec_push(field_refs, f);
}
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, t);
if (!node)
Panic("agg_construct failed for array literal");
for (usize i = 0; i < vec_size(n->array_literal.elems); ++i) {
spl_ir_node_ref_t f = emit_expr(a, vec_at(n->array_literal.elems, i));
if (!f)
Panic("array element emit failed");
spl_ir_builder_agg_construct_field(a->ir, node, f);
}
for (usize i = 0; i < nelems; ++i)
spl_ir_builder_agg_construct_field(a->ir, node, vec_at(field_refs, i));
vec_free(field_refs);
return node;
}
case SPL_AST_EXPR_AGGREGATE_LIT: {
@@ -575,41 +599,53 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
if (!obj_ln)
return 0;
/* 目前只处理数组->切片的完整形式 arr[..](无 begin / end)
或 arr[begin..end] 的通用形式。简化实现只做完整切片。 */
spl_type_id_t slice_ir = node_ir(a, n); /* struct{ptr, len} */
spl_type_id_t slice_ir = node_ir(a, n);
if (!slice_ir)
return 0;
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, slice_ir);
if (!node)
return 0;
spl_lang_type_id_t elem_lang = obj_ln->extra.elem;
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_type_id_t usize_ir = to_ir_type(a, usize_lang);
/* 取数组元素指针 */
spl_ir_node_ref_t base = emit_lvalue(a, n->slice.obj);
if (!base)
return 0;
spl_type_id_t ptr_ir =
spl_type_builder_ptr(a->sema->type, to_ir_type(a, obj_ln->extra.elem));
spl_ir_node_ref_t begin_v = 0;
if (n->slice.begin)
begin_v = emit_expr(a, n->slice.begin);
else
begin_v = spl_ir_builder_type_const_int(a->ir, usize_ir, 0);
if (!begin_v)
return 0;
/* 字段 0:ptr */
spl_ir_builder_agg_construct_field(a->ir, node, base);
spl_ir_node_ref_t ptr = spl_ir_builder_mem_offset(a->ir, elem_ir, base, begin_v);
if (!ptr)
return 0;
/* 字段 1:len —— 数组取 len,切片取原切片 len */
spl_ir_node_ref_t len = 0;
if (obj_ln->kind == SPL_LANG_TYPE_ARRAY) {
spl_ir_node_ref_t end_v = 0;
if (n->slice.end) {
end_v = emit_expr(a, n->slice.end);
} else if (obj_ln->kind == SPL_LANG_TYPE_ARRAY) {
spl_type_node_t *arr = spl_type_node(a->sema->type, obj_ln->ir_type_id);
spl_lang_type_id_t usize = spl_lang_make_int(a->sema->type, sizeof(void *) * 8, 0);
len = spl_ir_builder_type_const_int(a->ir, to_ir_type(a, usize), arr->array_type.len);
end_v = spl_ir_builder_type_const_int(a->ir, usize_ir, arr->array_type.len);
} else if (obj_ln->kind == SPL_LANG_TYPE_SLICE) {
spl_ir_node_ref_t slice_val = emit_expr(a, n->slice.obj);
spl_lang_type_id_t usize = spl_lang_make_int(a->sema->type, sizeof(void *) * 8, 0);
len = spl_ir_builder_agg_extract(a->ir, to_ir_type(a, usize), to_ir_type(a, usize),
SPL_SLICE_LEN_FIELD_IDX, slice_val);
end_v = spl_ir_builder_agg_extract(a->ir, obj_ln->ir_type_id, usize_ir,
SPL_SLICE_LEN_FIELD_IDX, slice_val);
} else {
return 0;
}
if (!end_v)
return 0;
spl_ir_node_ref_t len = spl_ir_builder_arith_sub(a->ir, usize_ir, end_v, begin_v);
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, slice_ir);
if (!node)
return 0;
spl_ir_builder_agg_construct_field(a->ir, node, ptr);
spl_ir_builder_agg_construct_field(a->ir, node, len);
return node;
}