stage1 支持更多语法 修复更多问题 暂时stage1功能结束
This commit is contained in:
1 parent
54425a50c7
commit
acfbbeee8b
11 files changed
+802
-183
No files matched your search
+319
-37
@@ -29,6 +29,12 @@ static spl_ir_node_ref_t emit_expr(spl_ast2ir_t *a, spl_ast_node_ref_t ref);
|
||||
static spl_ir_node_ref_t emit_lvalue(spl_ast2ir_t *a, spl_ast_node_ref_t ref);
|
||||
static void emit_stmt(spl_ast2ir_t *a, spl_ast_node_ref_t ref);
|
||||
static void emit_decl(spl_ast2ir_t *a, spl_ast_node_ref_t ref);
|
||||
static spl_ir_node_ref_t emit_var_decl(spl_ast2ir_t *a, spl_ast_node_t *n);
|
||||
static void emit_pattern_bind(spl_ast2ir_t *a, spl_ast_node_ref_t pat_ref,
|
||||
spl_ir_node_ref_t src_ptr, spl_type_id_t tid);
|
||||
static spl_ir_node_ref_t emit_match_check(spl_ast2ir_t *a, spl_ast_node_ref_t pat_ref,
|
||||
spl_type_id_t scrut_ir, spl_ir_node_ref_t scrut_slot);
|
||||
|
||||
static void emit_fn_reserve(spl_ast2ir_t *a, spl_ast_node_t *n);
|
||||
static void emit_fn_body(spl_ast2ir_t *a, spl_ast_node_t *n);
|
||||
static void emit_container_reserve(spl_ast2ir_t *a, spl_ast_node_ref_t ref);
|
||||
@@ -111,6 +117,181 @@ static spl_ir_node_ref_t emit_zero_value(spl_ast2ir_t *a, spl_type_id_t tid) {
|
||||
}
|
||||
}
|
||||
|
||||
/* 把 pattern 里的 ident 绑到 src_ptr 指向内存的对应位置。
|
||||
- PATTERN_IDENT: def2ir_map[def_id] = src_ptr
|
||||
- PATTERN_DOT: src_ptr 指向 enum,payload 在 mem_field(tid, src_ptr, vidx+1)
|
||||
- PATTERN_TUPLE / PATTERN_AGGREGATE: 递归 mem_field
|
||||
UB 语义:不做 tag 检查,调用者保证变体正确。
|
||||
*/
|
||||
static void emit_pattern_bind(spl_ast2ir_t *a, spl_ast_node_ref_t pat_ref,
|
||||
spl_ir_node_ref_t src_ptr, spl_type_id_t tid) {
|
||||
if (!pat_ref || !src_ptr)
|
||||
return;
|
||||
spl_ast_node_t *pat = spl_ast_node(a->ast, pat_ref);
|
||||
if (!pat)
|
||||
return;
|
||||
|
||||
switch (pat->kind) {
|
||||
case SPL_AST_PATTERN_IDENT: {
|
||||
if (pat->resolved_def_id)
|
||||
map_put(a->def2ir_map, pat->resolved_def_id, src_ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
case SPL_AST_EXPR_INT_LIT:
|
||||
case SPL_AST_EXPR_FLOAT_LIT:
|
||||
case SPL_AST_EXPR_CHAR_LIT:
|
||||
case SPL_AST_EXPR_STRING_LIT:
|
||||
case SPL_AST_EXPR_BOOL_LIT:
|
||||
case SPL_AST_EXPR_NULL_LIT:
|
||||
return; /* 字面量不绑定 */
|
||||
|
||||
case SPL_AST_PATTERN_UNDERSCORE:
|
||||
return;
|
||||
|
||||
case SPL_AST_PATTERN_LIST:
|
||||
for (usize i = 0; i < vec_size(pat->pattern_list.patterns); ++i)
|
||||
emit_pattern_bind(a, vec_at(pat->pattern_list.patterns, i), src_ptr, tid);
|
||||
return;
|
||||
|
||||
case SPL_AST_PATTERN_TUPLE: {
|
||||
spl_type_node_t *tn = spl_type_node(&a->sema->type->ir, tid);
|
||||
if (!tn || tn->kind != SPL_TYPE_STRUCT)
|
||||
return;
|
||||
usize n = vec_size(pat->pattern_tuple.patterns);
|
||||
usize nf = vec_size(tn->agg_type.variants);
|
||||
if (n > nf)
|
||||
return;
|
||||
for (usize i = 0; i < n; ++i) {
|
||||
spl_type_id_t ft = vec_at(tn->agg_type.variants, i).type_id;
|
||||
spl_ir_node_ref_t fp = spl_ir_builder_mem_field(a->ir, tid, src_ptr, i);
|
||||
emit_pattern_bind(a, vec_at(pat->pattern_tuple.patterns, i), fp, ft);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case SPL_AST_PATTERN_DOT: {
|
||||
spl_type_node_t *tn = spl_type_node(&a->sema->type->ir, tid);
|
||||
if (!tn || tn->kind != SPL_TYPE_ENUM)
|
||||
return;
|
||||
usize vidx = pat->resolved_def_id;
|
||||
if (vidx == 0)
|
||||
return;
|
||||
vidx -= 1;
|
||||
if (vidx >= vec_size(tn->agg_type.variants))
|
||||
return;
|
||||
spl_type_id_t payload_ir = vec_at(tn->agg_type.variants, vidx).type_id;
|
||||
spl_ir_node_ref_t pptr = spl_ir_builder_mem_field(a->ir, tid, src_ptr, vidx + 1);
|
||||
if (pat->pattern_dot.sub_pattern)
|
||||
emit_pattern_bind(a, pat->pattern_dot.sub_pattern, pptr, payload_ir);
|
||||
return;
|
||||
}
|
||||
|
||||
case SPL_AST_PATTERN_AGGREGATE: {
|
||||
spl_type_node_t *tn = spl_type_node(&a->sema->type->ir, tid);
|
||||
if (!tn || (tn->kind != SPL_TYPE_STRUCT && tn->kind != SPL_TYPE_UNION))
|
||||
return;
|
||||
for (usize i = 0; i < vec_size(pat->pattern_aggregate.fields); ++i) {
|
||||
spl_ast_node_t *f = spl_ast_node(a->ast, vec_at(pat->pattern_aggregate.fields, i));
|
||||
if (!f || f->kind != SPL_AST_PATTERN_FIELD)
|
||||
continue;
|
||||
usize idx = f->resolved_def_id;
|
||||
if (idx >= vec_size(tn->agg_type.variants))
|
||||
continue;
|
||||
spl_type_id_t ft = vec_at(tn->agg_type.variants, idx).type_id;
|
||||
spl_ir_node_ref_t fp = spl_ir_builder_mem_field(a->ir, tid, src_ptr, idx);
|
||||
if (f->pattern_field.pattern)
|
||||
emit_pattern_bind(a, f->pattern_field.pattern, fp, ft);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* 计算 pattern 对 scrutinee 的匹配条件。
|
||||
返回 0 表示无条件命中(IDENT / UNDERSCORE),否则返回 bool 节点。 */
|
||||
static spl_ir_node_ref_t emit_match_check(spl_ast2ir_t *a, spl_ast_node_ref_t pat_ref,
|
||||
spl_type_id_t scrut_ir, spl_ir_node_ref_t scrut_slot) {
|
||||
spl_ast_node_t *pat = spl_ast_node(a->ast, pat_ref);
|
||||
if (!pat)
|
||||
return 0;
|
||||
|
||||
switch (pat->kind) {
|
||||
case SPL_AST_PATTERN_UNDERSCORE:
|
||||
case SPL_AST_PATTERN_IDENT:
|
||||
return 0;
|
||||
|
||||
case SPL_AST_PATTERN_LIST: {
|
||||
spl_lang_type_id_t bt = spl_lang_make_bool(a->sema->type);
|
||||
spl_type_id_t bt_ir = to_ir_type(a, bt);
|
||||
spl_ir_node_ref_t combined = 0;
|
||||
for (usize i = 0; i < vec_size(pat->pattern_list.patterns); ++i) {
|
||||
spl_ir_node_ref_t c =
|
||||
emit_match_check(a, vec_at(pat->pattern_list.patterns, i), scrut_ir, scrut_slot);
|
||||
if (!c)
|
||||
return 0;
|
||||
combined = combined ? spl_ir_builder_arith_or(a->ir, bt_ir, combined, c) : c;
|
||||
}
|
||||
return combined;
|
||||
}
|
||||
|
||||
case SPL_AST_PATTERN_DOT: {
|
||||
spl_type_node_t *tn = spl_type_node(&a->sema->type->ir, scrut_ir);
|
||||
if (!tn || tn->kind != SPL_TYPE_ENUM)
|
||||
return 0;
|
||||
usize vidx = pat->resolved_def_id;
|
||||
if (vidx == 0)
|
||||
return 0;
|
||||
vidx -= 1;
|
||||
spl_type_id_t tag_ir = tn->agg_type.tag_type;
|
||||
spl_ir_node_ref_t tag_ptr =
|
||||
spl_ir_builder_mem_field(a->ir, scrut_ir, scrut_slot, SPL_ENUM_TAG_FIELD_IDX);
|
||||
spl_ir_node_ref_t tag_val = spl_ir_builder_mem_load(a->ir, tag_ir, tag_ptr);
|
||||
spl_ir_node_ref_t vidx_const = spl_ir_builder_type_const_int(a->ir, tag_ir, vidx);
|
||||
return spl_ir_builder_cmp_eq(a->ir, tag_ir, tag_val, vidx_const);
|
||||
}
|
||||
|
||||
case SPL_AST_EXPR_INT_LIT:
|
||||
case SPL_AST_EXPR_FLOAT_LIT:
|
||||
case SPL_AST_EXPR_CHAR_LIT:
|
||||
case SPL_AST_EXPR_STRING_LIT:
|
||||
case SPL_AST_EXPR_BOOL_LIT:
|
||||
case SPL_AST_EXPR_NULL_LIT: {
|
||||
spl_ir_node_ref_t val = emit_expr(a, pat_ref);
|
||||
if (!val)
|
||||
return 0;
|
||||
spl_ir_node_ref_t loaded = spl_ir_builder_mem_load(a->ir, scrut_ir, scrut_slot);
|
||||
return spl_ir_builder_cmp_eq(a->ir, scrut_ir, loaded, val);
|
||||
}
|
||||
|
||||
default:
|
||||
/* tuple / aggregate pattern 暂不作为 match 条件 */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 分配 slot → store init 值 → bind pattern。
|
||||
返回指向变量内存的指针(*tid),调用者可用于读取初值。 */
|
||||
static spl_ir_node_ref_t emit_var_decl(spl_ast2ir_t *a, spl_ast_node_t *n) {
|
||||
spl_type_id_t var_ir = node_ir(a, n);
|
||||
if (!var_ir)
|
||||
return 0;
|
||||
|
||||
spl_ir_node_ref_t slot = spl_ir_builder_mem_alloca(a->ir, var_ir, const_usize(a, 1));
|
||||
|
||||
if (n->var_const_decl.init_expr) {
|
||||
spl_ir_node_ref_t v = emit_expr(a, n->var_const_decl.init_expr);
|
||||
if (v)
|
||||
spl_ir_builder_mem_store(a->ir, var_ir, slot, v);
|
||||
}
|
||||
|
||||
emit_pattern_bind(a, n->var_const_decl.pattern, slot, var_ir);
|
||||
return slot;
|
||||
}
|
||||
|
||||
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)
|
||||
return;
|
||||
@@ -843,7 +1024,6 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
||||
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));
|
||||
|
||||
@@ -852,11 +1032,14 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
||||
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_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);
|
||||
if (!payload)
|
||||
Panic("enum payload emit failed");
|
||||
spl_ir_builder_mem_store(a->ir, payload_ir, pptr, payload);
|
||||
if (item->struct_init_item.expr) {
|
||||
spl_type_id_t payload_ir = 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 payload = emit_expr(a, item->struct_init_item.expr);
|
||||
if (!payload)
|
||||
Panic("enum payload emit failed");
|
||||
spl_ir_builder_mem_store(a->ir, payload_ir, pptr, payload);
|
||||
}
|
||||
|
||||
return eptr;
|
||||
}
|
||||
@@ -931,9 +1114,117 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
||||
case SPL_AST_EXPR_IF:
|
||||
case SPL_AST_EXPR_IFVAR:
|
||||
return emit_if_like(a, ref);
|
||||
case SPL_AST_EXPR_MATCH: {
|
||||
spl_ast_node_ref_t matched_ref = n->match_expr.matched_expr;
|
||||
spl_ast_node_t *matched_node = spl_ast_node(a->ast, matched_ref);
|
||||
spl_lang_type_id_t matched_lang = node_lang(a, matched_node);
|
||||
spl_type_id_t matched_ir = to_ir_type(a, matched_lang);
|
||||
if (!matched_ir)
|
||||
return 0;
|
||||
|
||||
spl_ir_node_ref_t scrut_slot =
|
||||
spl_ir_builder_mem_alloca(a->ir, matched_ir, const_usize(a, 1));
|
||||
spl_ir_node_ref_t scrut_val = emit_expr(a, matched_ref);
|
||||
if (!scrut_val)
|
||||
return 0;
|
||||
spl_ir_builder_mem_store(a->ir, matched_ir, scrut_slot, scrut_val);
|
||||
|
||||
usize narms = vec_size(n->match_expr.arms);
|
||||
spl_ir_node_ref_vec_t arm_branches;
|
||||
spl_ir_block_vec_t cond_blks;
|
||||
vec_init(arm_branches);
|
||||
vec_init(cond_blks);
|
||||
|
||||
for (usize i = 0; i < narms; ++i) {
|
||||
vec_push(cond_blks, a->ir->current_block);
|
||||
|
||||
spl_ast_node_t *arm = spl_ast_node(a->ast, vec_at(n->match_expr.arms, i));
|
||||
if (arm && arm->kind == SPL_AST_MATCH_ARM) {
|
||||
spl_ir_node_ref_t cond =
|
||||
emit_match_check(a, arm->match_arm.pattern, matched_ir, scrut_slot);
|
||||
if (cond) {
|
||||
spl_ir_node_ref_t br = spl_ir_builder_control_br(a->ir, cond);
|
||||
vec_push(arm_branches, br);
|
||||
} else {
|
||||
spl_ir_node_ref_t j = spl_ir_builder_control_jmp(a->ir);
|
||||
vec_push(arm_branches, j);
|
||||
}
|
||||
} else {
|
||||
spl_ir_node_ref_t j = spl_ir_builder_control_jmp(a->ir);
|
||||
vec_push(arm_branches, j);
|
||||
}
|
||||
|
||||
spl_ir_builder_block_end(a->ir);
|
||||
if (i + 1 < narms)
|
||||
spl_ir_builder_block_begin(a->ir);
|
||||
}
|
||||
|
||||
usize no_match_blk = spl_ir_builder_block_begin(a->ir);
|
||||
spl_ir_node_ref_t no_match_jmp = spl_ir_builder_control_jmp(a->ir);
|
||||
spl_ir_builder_block_end(a->ir);
|
||||
|
||||
spl_ir_node_ref_vec_t body_jmps;
|
||||
spl_ir_block_vec_t body_blks;
|
||||
vec_init(body_jmps);
|
||||
vec_init(body_blks);
|
||||
|
||||
for (usize i = 0; i < narms; ++i) {
|
||||
usize blk = spl_ir_builder_block_begin(a->ir);
|
||||
vec_push(body_blks, blk);
|
||||
|
||||
spl_ast_node_t *arm = spl_ast_node(a->ast, vec_at(n->match_expr.arms, i));
|
||||
if (arm && arm->kind == SPL_AST_MATCH_ARM) {
|
||||
emit_pattern_bind(a, arm->match_arm.pattern, scrut_slot, matched_ir);
|
||||
if (arm->match_arm.body)
|
||||
emit_expr(a, arm->match_arm.body);
|
||||
}
|
||||
|
||||
spl_ir_node_ref_t j = 0;
|
||||
if (!a->ir->terminated)
|
||||
j = spl_ir_builder_control_jmp(a->ir);
|
||||
vec_push(body_jmps, j);
|
||||
spl_ir_builder_block_end(a->ir);
|
||||
}
|
||||
|
||||
usize end_blk = spl_ir_builder_block_begin(a->ir);
|
||||
|
||||
for (usize i = 0; i < narms; ++i) {
|
||||
spl_ir_node_ref_t branch = vec_at(arm_branches, i);
|
||||
if (!branch)
|
||||
continue;
|
||||
spl_ir_node_t *bn = spl_ir_node(&a->ir->ir, a->ir->current_fn, branch);
|
||||
if (!bn)
|
||||
continue;
|
||||
usize body_blk = vec_at(body_blks, i);
|
||||
if (bn->kind == SPL_IR_CONTROL_BR) {
|
||||
usize next_blk = (i + 1 < narms) ? vec_at(cond_blks, i + 1) : no_match_blk;
|
||||
spl_ir_builder_control_br_fixup(a->ir, branch, body_blk, next_blk);
|
||||
} else if (bn->kind == SPL_IR_CONTROL_JMP) {
|
||||
spl_ir_builder_control_jmp_fixup(a->ir, branch, body_blk);
|
||||
}
|
||||
}
|
||||
|
||||
for (usize i = 0; i < narms; ++i) {
|
||||
spl_ir_node_ref_t j = vec_at(body_jmps, i);
|
||||
if (j)
|
||||
spl_ir_builder_control_jmp_fixup(a->ir, j, end_blk);
|
||||
}
|
||||
spl_ir_builder_control_jmp_fixup(a->ir, no_match_jmp, end_blk);
|
||||
|
||||
vec_free(arm_branches);
|
||||
vec_free(cond_blks);
|
||||
vec_free(body_jmps);
|
||||
vec_free(body_blks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
case SPL_AST_EXPR_WHILE:
|
||||
case SPL_AST_EXPR_LOOP:
|
||||
return emit_loop_like(a, ref);
|
||||
case SPL_AST_EXPR_FOR:
|
||||
spl_diag_fatal(a->diag, SPL_DIAG_KIND_UNHANDLED_NODE, &n->dbg,
|
||||
"for is not implemented yet");
|
||||
return 0;
|
||||
case SPL_AST_EXPR_SLICE: {
|
||||
spl_ast_node_t *obj = spl_ast_node(a->ast, n->slice.obj);
|
||||
spl_lang_type_id_t obj_lang = node_lang(a, obj);
|
||||
@@ -1041,13 +1332,12 @@ static spl_ir_node_ref_t emit_if_like(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
|
||||
spl_ast_node_ref_t else_ref = 0;
|
||||
|
||||
if (is_ifvar) {
|
||||
emit_decl(a, n->ifvar_expr.var_decl);
|
||||
spl_ast_node_t *vd = spl_ast_node(a->ast, n->ifvar_expr.var_decl);
|
||||
if (!vd || !vd->var_const_decl.init_expr)
|
||||
Panic("ifvar requires initializer");
|
||||
spl_ir_node_ref_t slot = 0;
|
||||
if (!map_get(a->def2ir_map, vd->resolved_def_id, &slot))
|
||||
Panic("ifvar var slot not found");
|
||||
if (!vd)
|
||||
Panic("ifvar missing var_decl");
|
||||
spl_ir_node_ref_t slot = emit_var_decl(a, vd);
|
||||
if (!slot)
|
||||
Panic("ifvar var_decl emit failed");
|
||||
cond = spl_ir_builder_mem_load(a->ir, node_ir(a, vd), slot);
|
||||
then_ref = n->ifvar_expr.then_block;
|
||||
else_ref = n->ifvar_expr.else_branch;
|
||||
@@ -1172,7 +1462,7 @@ static spl_ir_node_ref_t emit_loop_like(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
||||
for (usize i = 0; i < vec_size(top->breaks); ++i)
|
||||
spl_ir_builder_control_jmp_fixup(a->ir, vec_at(top->breaks, i), after_blk);
|
||||
vec_free(top->breaks);
|
||||
vec_pop(a->loop_stack);
|
||||
(void)vec_pop(a->loop_stack);
|
||||
|
||||
if (!result_slot)
|
||||
return 0;
|
||||
@@ -1309,32 +1599,11 @@ static void emit_decl(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
|
||||
|
||||
switch (n->kind) {
|
||||
case SPL_AST_VAR_DECL:
|
||||
case SPL_AST_CONST_DECL: {
|
||||
case SPL_AST_CONST_DECL:
|
||||
if (!a->ir->current_fn)
|
||||
return;
|
||||
if (!n->resolved_def_id)
|
||||
return;
|
||||
|
||||
spl_ast_node_t *pat = spl_ast_node(a->ast, n->var_const_decl.pattern);
|
||||
if (!pat || pat->kind != SPL_AST_PATTERN_IDENT)
|
||||
return;
|
||||
|
||||
spl_lang_type_id_t var_lang = spl_def_get_lang_id(a->sema->type, n->resolved_def_id);
|
||||
spl_type_id_t var_ir = to_ir_type(a, var_lang);
|
||||
if (!var_ir)
|
||||
return;
|
||||
|
||||
spl_ir_node_ref_t one = const_usize(a, 1);
|
||||
spl_ir_node_ref_t slot = spl_ir_builder_mem_alloca(a->ir, var_ir, one);
|
||||
map_put(a->def2ir_map, n->resolved_def_id, slot);
|
||||
|
||||
if (n->var_const_decl.init_expr) {
|
||||
spl_ir_node_ref_t v = emit_expr(a, n->var_const_decl.init_expr);
|
||||
if (v)
|
||||
spl_ir_builder_mem_store(a->ir, var_ir, slot, v);
|
||||
}
|
||||
emit_var_decl(a, n);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@@ -1344,6 +1613,13 @@ static void emit_fn_reserve(spl_ast2ir_t *a, spl_ast_node_t *n) {
|
||||
if (!n || !n->resolved_def_id)
|
||||
return;
|
||||
|
||||
spl_ir_node_ref_t existing = 0;
|
||||
if (map_get(a->def2ir_map, n->resolved_def_id, &existing)) {
|
||||
spl_diag_error(a->diag, SPL_DIAG_KIND_INTERNAL, &n->dbg,
|
||||
"fn `%s` reserved twice (def#%zu);", n->fn_decl.name, n->resolved_def_id);
|
||||
return;
|
||||
}
|
||||
|
||||
spl_lang_type_id_t fn_lang = spl_def_get_lang_id(a->sema->type, n->resolved_def_id);
|
||||
spl_lang_type_node_t *fn_ln = spl_lang_type_node(a->sema->type, fn_lang);
|
||||
if (!fn_ln || fn_ln->kind != SPL_LANG_TYPE_FN)
|
||||
@@ -1438,7 +1714,7 @@ static void emit_fn_body(spl_ast2ir_t *a, spl_ast_node_t *n) {
|
||||
while (vec_size(a->loop_stack) > loop_base) {
|
||||
spl_loop_ctx_t *top = &vec_at(a->loop_stack, vec_size(a->loop_stack) - 1);
|
||||
vec_free(top->breaks);
|
||||
vec_pop(a->loop_stack);
|
||||
(void)vec_pop(a->loop_stack);
|
||||
}
|
||||
|
||||
a->cur_ret_lang = saved_ret;
|
||||
@@ -1500,6 +1776,9 @@ static void emit_container_reserve(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
|
||||
emit_fn_reserve(a, d);
|
||||
break;
|
||||
case SPL_AST_TYPE_DECL: {
|
||||
spl_ast_node_t *tpat = spl_ast_node(a->ast, d->type_decl.pattern);
|
||||
if (!tpat || tpat->kind != SPL_AST_PATTERN_IDENT)
|
||||
break;
|
||||
spl_ast_node_t *te = spl_ast_node(a->ast, d->type_decl.type_expr);
|
||||
if (te && te->kind == SPL_AST_TYPE_AGGREGATE)
|
||||
emit_aggregate_fns_reserve(a, te);
|
||||
@@ -1536,6 +1815,9 @@ static void emit_container_body(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
|
||||
emit_fn_body(a, d);
|
||||
break;
|
||||
case SPL_AST_TYPE_DECL: {
|
||||
spl_ast_node_t *tpat = spl_ast_node(a->ast, d->type_decl.pattern);
|
||||
if (!tpat || tpat->kind != SPL_AST_PATTERN_IDENT)
|
||||
break;
|
||||
spl_ast_node_t *te = spl_ast_node(a->ast, d->type_decl.type_expr);
|
||||
if (te && te->kind == SPL_AST_TYPE_AGGREGATE)
|
||||
emit_aggregate_fns_body(a, te);
|
||||
|
||||
Reference in new issue
Block a user