stage1 支持任意顺序声明 使用eval求值的机制
This commit is contained in:
1 parent
a1e684f6d4
commit
a621e34d51
6 files changed
+336
-123
No files matched your search
+84
-23
@@ -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);
|
||||
}
|
||||
Reference in new issue
Block a user