stage1 支持任意顺序声明 使用eval求值的机制

This commit is contained in:
zzy committed 2026-09-14 18:11:58 +08:00
1 parent a1e684f6d4
commit a621e34d51
6 files changed
+336 -123

No files matched your search

+84 -23
View File
@@ -25,8 +25,10 @@ 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 void emit_fn(spl_ast2ir_t *a, spl_ast_node_t *n);
static void emit_container(spl_ast2ir_t *a, spl_ast_node_ref_t ref);
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);
static void emit_container_body(spl_ast2ir_t *a, spl_ast_node_ref_t ref);
static spl_ir_node_ref_t emit_cast(spl_ast2ir_t *a, spl_ast_node_t *n);
static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref);
@@ -1085,16 +1087,13 @@ static void emit_decl(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
}
return;
}
case SPL_AST_FN_DECL:
emit_fn(a, n);
return;
default:
return;
}
}
static void emit_fn(spl_ast2ir_t *a, spl_ast_node_t *n) {
if (!n->resolved_def_id)
static void emit_fn_reserve(spl_ast2ir_t *a, spl_ast_node_t *n) {
if (!n || !n->resolved_def_id)
return;
spl_lang_type_id_t fn_lang = spl_def_get_lang_id(a->sema->type, n->resolved_def_id);
@@ -1106,10 +1105,26 @@ static void emit_fn(spl_ast2ir_t *a, spl_ast_node_t *n) {
if (!fn_ir)
return;
spl_ir_func_ref_t fn_ref = spl_ir_builder_fn_begin(a->ir, n->fn_decl.name, fn_ir);
spl_ir_func_ref_t fn_ref = spl_ir_builder_fn_reserve(a->ir, n->fn_decl.name, fn_ir);
map_put(a->def2ir_map, n->resolved_def_id, (spl_ir_node_ref_t)fn_ref);
copy_attrs_to_ir_func(a, n, fn_ref);
}
static void emit_fn_body(spl_ast2ir_t *a, spl_ast_node_t *n) {
if (!n || !n->resolved_def_id)
return;
spl_ir_func_ref_t fn_ref = 0;
if (!map_get(a->def2ir_map, n->resolved_def_id, &fn_ref))
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)
return;
spl_ir_builder_fn_begin_at(a->ir, fn_ref);
spl_lang_type_id_t saved_ret = a->cur_ret_lang;
a->cur_ret_lang = fn_ln->extra.fn.ret;
@@ -1158,12 +1173,6 @@ static void emit_fn(spl_ast2ir_t *a, spl_ast_node_t *n) {
}
}
/* 兜底清理:
* - 若 body 已显式 return,defer 栈可能已被清空到 defer_base 之下
* (被 return 逻辑弹过),此时 vec_size <= defer_base,无需处理。
* - 若 body 里开了 loop 却没关(理论上不会,sema 已保证),
* 这里的 while 只是防止异常路径残留。
*/
while (vec_size(a->defer_stack) > defer_base) {
spl_ast_node_ref_t d = vec_pop(a->defer_stack);
(void)d;
@@ -1180,28 +1189,43 @@ static void emit_fn(spl_ast2ir_t *a, spl_ast_node_t *n) {
spl_ir_builder_fn_end(a->ir);
}
static void emit_aggregate_fns(spl_ast2ir_t *a, spl_ast_node_t *te) {
static void emit_aggregate_fns_reserve(spl_ast2ir_t *a, spl_ast_node_t *te) {
for (usize i = 0; i < vec_size(te->type_aggregate.members); ++i) {
spl_ast_node_t *mn = spl_ast_node(a->sema->ast, vec_at(te->type_aggregate.members, i));
if (!mn)
continue;
if (mn->kind == SPL_AST_FN_DECL) {
emit_fn(a, mn);
emit_fn_reserve(a, mn);
} else if (mn->kind == SPL_AST_MEMBER_DECL && mn->member_decl.type_expr) {
spl_ast_node_t *mt = spl_ast_node(a->sema->ast, mn->member_decl.type_expr);
if (mt && mt->kind == SPL_AST_TYPE_AGGREGATE)
emit_aggregate_fns(a, mt);
emit_aggregate_fns_reserve(a, mt);
}
}
}
static void emit_container(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
static void emit_aggregate_fns_body(spl_ast2ir_t *a, spl_ast_node_t *te) {
for (usize i = 0; i < vec_size(te->type_aggregate.members); ++i) {
spl_ast_node_t *mn = spl_ast_node(a->sema->ast, vec_at(te->type_aggregate.members, i));
if (!mn)
continue;
if (mn->kind == SPL_AST_FN_DECL) {
emit_fn_body(a, mn);
} else if (mn->kind == SPL_AST_MEMBER_DECL && mn->member_decl.type_expr) {
spl_ast_node_t *mt = spl_ast_node(a->sema->ast, mn->member_decl.type_expr);
if (mt && mt->kind == SPL_AST_TYPE_AGGREGATE)
emit_aggregate_fns_body(a, mt);
}
}
}
static void emit_container_reserve(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
spl_ast_node_t *n = spl_ast_node(a->sema->ast, ref);
if (!n)
return;
if (n->kind == SPL_AST_TOP_LEVEL_BLOCK) {
if (n->top_level_block.block)
emit_container(a, n->top_level_block.block);
emit_container_reserve(a, n->top_level_block.block);
return;
}
if (n->kind != SPL_AST_CONTAINER_MEMBERS)
@@ -1214,16 +1238,52 @@ static void emit_container(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
continue;
switch (d->kind) {
case SPL_AST_FN_DECL:
emit_fn(a, d);
emit_fn_reserve(a, d);
break;
case SPL_AST_TYPE_DECL: {
spl_ast_node_t *te = spl_ast_node(a->sema->ast, d->type_decl.type_expr);
if (te && te->kind == SPL_AST_TYPE_AGGREGATE)
emit_aggregate_fns(a, te);
emit_aggregate_fns_reserve(a, te);
break;
}
case SPL_AST_TOP_LEVEL_BLOCK:
emit_container(a, dref);
emit_container_reserve(a, dref);
break;
default:
break;
}
}
}
static void emit_container_body(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
spl_ast_node_t *n = spl_ast_node(a->sema->ast, ref);
if (!n)
return;
if (n->kind == SPL_AST_TOP_LEVEL_BLOCK) {
if (n->top_level_block.block)
emit_container_body(a, n->top_level_block.block);
return;
}
if (n->kind != SPL_AST_CONTAINER_MEMBERS)
return;
for (usize i = 0; i < vec_size(n->container_members.declarations); ++i) {
spl_ast_node_ref_t dref = vec_at(n->container_members.declarations, i);
spl_ast_node_t *d = spl_ast_node(a->sema->ast, dref);
if (!d)
continue;
switch (d->kind) {
case SPL_AST_FN_DECL:
emit_fn_body(a, d);
break;
case SPL_AST_TYPE_DECL: {
spl_ast_node_t *te = spl_ast_node(a->sema->ast, d->type_decl.type_expr);
if (te && te->kind == SPL_AST_TYPE_AGGREGATE)
emit_aggregate_fns_body(a, te);
break;
}
case SPL_AST_TOP_LEVEL_BLOCK:
emit_container_body(a, dref);
break;
default:
break;
@@ -1295,5 +1355,6 @@ void spl_ast2ir_run(spl_ast2ir_t *ast2ir) {
spl_ast_node_t *root = spl_ast_node(ast, ast->root);
if (!root || root->kind != SPL_AST_ROOT)
return;
emit_container(ast2ir, root->root.members);
emit_container_reserve(ast2ir, root->root.members);
emit_container_body(ast2ir, root->root.members);
}