stage1 实现ir2vm 修复nob test命令的构建问题
This commit is contained in:
1 parent
87d9b7ea34
commit
a64a96f9a4
11 files changed
+1565
-195
No files matched your search
+81
-45
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user