stage1 初步实现

This commit is contained in:
zzy
2026-08-06 19:26:30 +08:00
parent a56b4cbb70
commit 314100afbc
35 changed files with 556 additions and 2236 deletions

View File

@@ -3,11 +3,12 @@
* 设计要点 * - 名称解析自包含局部变类型用自身环境栈顶层类函数sema root scope 与聚合成员表 * -
* 变量落在内存槽(@mem.alloca写走 @mem.load/store表达式临时值为 SSA * - 控制流用"块表 +
* fixup 补丁"分跳转目标在函数末尾回填为块首指令node ref * -
* 聚合字段访问:读@agg.extract写字节地址直写"@mem.offset + @mem.store<EFBFBD>?* - 枚举=
* 聚合字段访问:读@agg.extract写字节地址直写"@mem.offset + @mem.store* - 枚举=
* agg.construct(enum)([tag, payload?])match tag 分发 * - defer 按作用域逆序执行(正常退/ ret /
* break / continue 全覆盖) */
#include "spl_ast2ir.h"
#include "spl_builtin.h"
#include <stdio.h>
#include <stdlib.h>
@@ -133,7 +134,7 @@ static spl_def_id_t def_for_type(spl_ast2ir_t *a, spl_type_id_t tid) {
return fallback;
}
/* 判断 agg_def 条目是否为结构字段SPL_DEF_MEMBER<EFBFBD>?*/
/* 判断 agg_def 条目是否为结构字段SPL_DEF_MEMBER*/
static int agg_entry_is_field(spl_ast2ir_t *a, const spl_var_def_t *e) {
if (!e->def_id)
return 0;
@@ -141,7 +142,7 @@ static int agg_entry_is_field(spl_ast2ir_t *a, const spl_var_def_t *e) {
return ed && ed->kind == SPL_DEF_MEMBER;
}
/* 命名空间成员类型(方<EFBFBD>?嵌套类型/static var按名任意 kind */
/* 命名空间成员类型(方嵌套类型/static var按名任意 kind */
static spl_type_id_t agg_member_type(spl_ast2ir_t *a, spl_type_id_t agg_tid, const char *name) {
agg_tid = underlying(a->sema, agg_tid);
spl_def_id_t d = def_for_type(a, agg_tid);
@@ -155,7 +156,7 @@ static spl_type_id_t agg_member_type(spl_ast2ir_t *a, spl_type_id_t agg_tid, con
return 0;
}
/* 结构字段序号 = 相对 SPL_DEF_MEMBER 的位置(<EFBFBD>?type.agg_field_types 按序对齐<EFBFBD>?*/
/* 结构字段序号 = 相对 SPL_DEF_MEMBER 的位置type.agg_field_types 按序对齐*/
static isize agg_member_index(spl_ast2ir_t *a, spl_type_id_t agg_tid, const char *name) {
agg_tid = underlying(a->sema, agg_tid);
spl_def_id_t d = def_for_type(a, agg_tid);
@@ -188,7 +189,7 @@ static spl_type_id_t agg_field_tid_at(spl_ast2ir_t *a, spl_type_id_t agg_tid, is
return 0;
}
/* 按字段序号查成员名agg_def 中第 idx <EFBFBD>?SPL_DEF_MEMBER 条目<EFBFBD>?*/
/* 按字段序号查成员名agg_def 中第 idx SPL_DEF_MEMBER 条目*/
static const char *agg_field_name_at(spl_ast2ir_t *a, spl_type_id_t agg_tid, isize idx) {
agg_tid = underlying(a->sema, agg_tid);
spl_def_id_t d = def_for_type(a, agg_tid);
@@ -289,6 +290,7 @@ typedef struct {
VEC(spl_type_id_t) types; /* nodes 平行的结果类型表 */
int terminated;
spl_type_id_t hint;
usize cur_src; /* 当前语句AST 节点 ref调试行号 */
int err;
} fnctx_t;
@@ -342,6 +344,7 @@ static spl_ir_node_ref_t emit_node(spl_ast2ir_t *a, fnctx_t *fc) {
fc->terminated = 0;
}
spl_ir_node_ref_t r = spl_ir_alloc_node(&a->ir, fc->fn);
spl_ir_node(&a->ir, fc->fn, r)->src_ref = fc->cur_src; /* 调试行号 */
if (fc->cur_block < fc->blocks.size && !fc->blocks.data[fc->cur_block].first)
fc->blocks.data[fc->cur_block].first = r;
if (fc->types.size == 0) {
@@ -533,7 +536,7 @@ static spl_ir_node_ref_t emit_offset(spl_ast2ir_t *a, fnctx_t *fc, spl_type_id_t
return n;
}
/* 字段地址mem.field_ptr(agg_tid, agg, idx) *field_type。布局偏移ir2vm 算ast2ir 不算*/
/* 字段地址mem.field_ptr(agg_tid, agg, idx) *field_type。布局偏移ir2vm 算ast2ir 不算*/
static spl_ir_node_ref_t emit_field(spl_ast2ir_t *a, fnctx_t *fc, spl_type_id_t agg_tid,
spl_ir_node_ref_t ptr, isize fidx) {
spl_type_id_t fty = agg_field_tid_or_builtin(a, agg_tid, fidx);
@@ -548,7 +551,7 @@ static spl_ir_node_ref_t emit_field(spl_ast2ir_t *a, fnctx_t *fc, spl_type_id_t
return n;
}
/* 全局静态数据地址mem.global_alloc(tid, gdata_idx) <EFBFBD>?*tid */
/* 全局静态数据地址mem.global_alloc(tid, gdata_idx) *tid */
static spl_ir_node_ref_t emit_global_alloc(spl_ast2ir_t *a, fnctx_t *fc, spl_type_id_t tid,
usize gdata_idx) {
spl_ir_node_ref_t n = emit_node(a, fc);
@@ -665,7 +668,7 @@ static ir_env_t *env_find(fnctx_t *fc, const char *name) {
return NULL;
}
/* def_id 优先定位sema 已作用域解析,绕开同名遮蔽歧义);<EFBFBD>?def_id 时兜底名<EFBFBD>?*/
/* def_id 优先定位sema 已作用域解析绕开同名遮蔽歧义def_id 时兜底名*/
static ir_env_t *env_find_def(fnctx_t *fc, spl_def_id_t def_id, const char *name) {
if (def_id) {
for (usize i = fc->env.size; i > 0; i--) {
@@ -740,7 +743,7 @@ static spl_ir_node_ref_t enum_tag_of(spl_ast2ir_t *a, fnctx_t *fc, spl_type_id_t
return emit_agg_extract(a, fc, enum_tid, enum_tag_tid(a), 0, val);
}
/* tid 是否<EFBFBD>?enum */
/* tid 是否enum */
static int is_enum_expand(spl_ast2ir_t *a, spl_type_id_t tid, spl_type_id_t *out_enum) {
spl_type_node_t *t = tn(a->sema, underlying(a->sema, tid));
if (t && t->kind == SPL_TYPE_ENUM) {
@@ -865,13 +868,13 @@ static spl_type_id_t resolve_type_expr(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_nod
spl_ast_node_t *n = node_at(a->sema, ref);
if (!n)
return 0;
/* 首<EFBFBD>?sema 注解resolved_def_id <EFBFBD>?def <EFBFBD>?类型(聚<EFBFBD>?别名/命名类型<EFBFBD>?*/
/* 首sema 注解resolved_def_id def 类型(聚别名/命名类型*/
if (n->resolved_def_id) {
spl_def_node_t *d = def_at(a->sema, n->resolved_def_id);
if (d && d->type_id)
return d->type_id;
}
/* 兜底:组<EFBFBD>?内置类型sema 不为其建 def <EFBFBD>?*T、[]T、fn(...)、关键字、别名到组合<EFBFBD>?*/
/* 兜底组内置类型sema 不为其建 def *T、[]T、fn(...)、关键字、别名到组合*/
spl_type_id_t base = 0;
switch (n->type_expr.kind) {
case SPL_AST_BASE_TYPE_PATH:
@@ -898,7 +901,7 @@ static spl_type_id_t resolve_type_expr(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_nod
case SPL_AST_TYPE_STRUCT:
case SPL_AST_TYPE_UNION:
case SPL_AST_TYPE_ENUM:
/* 内联聚合不应走到这里sema 已注解其 def防御性报<EFBFBD>?*/
/* 内联聚合不应走到这里sema 已注解其 def防御性报*/
diag(a, fc, ref, "inline aggregate not annotated by sema");
return 0;
default:
@@ -1019,7 +1022,7 @@ static spl_ast_node_ref_t field_chain_base(spl_ast2ir_t *a, spl_ast_node_t *pf,
return bref;
}
/* 字段链的存储地址root.a.b 地址 + 字段类型<EFBFBD>?*/
/* 字段链的存储地址root.a.b 地址 + 字段类型*/
static spl_ir_node_ref_t lower_field_address(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node_ref_t bref,
spl_type_id_t *out_tid) {
spl_ast_node_t *n = node_at(a->sema, bref);
@@ -1031,7 +1034,7 @@ static spl_ir_node_ref_t lower_field_address(spl_ast2ir_t *a, fnctx_t *fc, spl_a
const char *names[MAX_FIELD_CHAIN];
int nf = 0;
spl_ast_node_ref_t root_ref = field_chain_base(a, pf, names, &nf);
/* 类型命名空间基址Foo.counter全局 var/const <EFBFBD>?lvalue = <EFBFBD>?gdata 地址<EFBFBD>?*/
/* 类型命名空间基址Foo.counter全局 var/const lvalue = gdata 地址*/
spl_type_id_t ns = type_of_type_ref(a, fc, root_ref);
if (ns && nf == 1) {
spl_def_id_t gdef = def_for_type(a, ns);
@@ -1134,10 +1137,13 @@ static spl_ir_node_ref_t index_addr(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node_t
base_addr = base_lv ? emit_load(a, fc, base_t, base_lv) : base_addr;
elem_t = underlying(a->sema, bt->ptr_pointee);
} else if (bt && bt->kind == SPL_TYPE_SLICE) {
spl_ir_node_ref_t slv = base_lv ? emit_load(a, fc, base_t, base_lv) : base_addr;
elem_t = bt->slice_element;
spl_type_id_t ep = spl_type_ptr((spl_type_t *)&a->sema->type, elem_t);
base_addr = emit_agg_extract(a, fc, base_t, ep, 0, slv);
if (base_lv) {
spl_ir_node_ref_t slv = emit_load(a, fc, base_t, base_lv);
spl_type_id_t ep = spl_type_ptr((spl_type_t *)&a->sema->type, elem_t);
base_addr = emit_agg_extract(a, fc, base_t, ep, 0, slv);
}
/* base_lv==0 时 base_addr 已是切片表达式中提取出的 ptr 标量,直接复用 */
} else {
diag(a, fc, 0, "index requires array/slice/pointer");
return 0;
@@ -1442,7 +1448,7 @@ static spl_ir_node_ref_t lower_primary(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_nod
}
spl_type_id_t ft = agg_field_tid_or_builtin(a, hint_t, fidx);
spl_ir_node_ref_t v = lower_expr(a, fc, item->aggregate_init_item.expr);
/* 字段是指针、值是聚合 lvalue自动取地址<EFBFBD>?left = expr 语义<EFBFBD>?*/
/* 字段是指针、值是聚合 lvalue自动取地址left = expr 语义*/
spl_type_node_t *fld_t = ft ? tn(a->sema, ft) : NULL;
spl_type_node_t *v_t = tn(a->sema, underlying(a->sema, node_type(fc, v)));
if (fld_t && fld_t->kind == SPL_TYPE_PTR && v_t &&
@@ -1525,7 +1531,7 @@ static spl_ir_node_ref_t lower_primary(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_nod
fc->hint = tt->agg_field_types.data[i];
spl_ir_node_ref_t v = lower_expr(a, fc, item->aggregate_init_item.expr);
fc->hint = 0;
/* 字段是指针、值是聚合 lvalue自动取地址<EFBFBD>?left = expr 语义<EFBFBD>?*/
/* 字段是指针、值是聚合 lvalue自动取地址left = expr 语义*/
spl_type_node_t *fld_t = tn(a->sema, tt->agg_field_types.data[i]);
spl_type_node_t *v_t = tn(a->sema, underlying(a->sema, node_type(fc, v)));
if (fld_t && fld_t->kind == SPL_TYPE_PTR && v_t &&
@@ -1547,22 +1553,80 @@ static spl_ir_node_ref_t lower_primary(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_nod
}
case SPL_AST_BUILTIN_EXPR: {
const char *id = pn->primary_expr.builtin_expr.ident;
if (strcmp(id, "sizeof") == 0 && pn->primary_expr.builtin_expr.expr_list.size) {
const spl_builtin_t *bi = spl_builtin_lookup(id);
if (!bi) {
diag(a, fc, 0, "unsupported builtin call");
return 0;
}
usize nargs = pn->primary_expr.builtin_expr.expr_list.size;
if (nargs < (usize)bi->min_args || (bi->max_args >= 0 && nargs > (usize)bi->max_args)) {
diag(a, fc, 0, "builtin @arg count mismatch");
return 0;
}
/* @sizeof / @bitsizeof / @alignof / @field_count: 单类型参数 → 对应 IR 类型查询节点 */
if (bi->kind == SPL_BUILTIN_SIZE_OF || bi->kind == SPL_BUILTIN_BITSIZE_OF ||
bi->kind == SPL_BUILTIN_ALIGN_OF || bi->kind == SPL_BUILTIN_FIELD_COUNT) {
spl_type_id_t t =
type_from_type_like(a, fc, pn->primary_expr.builtin_expr.expr_list.data[0]);
if (!t) {
diag(a, fc, 0, "sizeof: cannot resolve type");
diag(a, fc, 0, "builtin @type query: cannot resolve type");
return 0;
}
spl_ir_node_ref_t n = emit_node(a, fc);
spl_ir_node_t *e = enode(a, fc, n);
e->kind = SPL_IR_TYPE_SIZEOF;
e->ir_sizeof.tid = t;
switch (bi->kind) {
case SPL_BUILTIN_SIZE_OF:
e->kind = SPL_IR_TYPE_SIZEOF;
e->ir_sizeof.tid = t;
break;
case SPL_BUILTIN_BITSIZE_OF:
e->kind = SPL_IR_TYPE_BITSIZEOF;
e->bitsizeof.tid = t;
break;
case SPL_BUILTIN_ALIGN_OF:
e->kind = SPL_IR_TYPE_ALIGNOF;
e->ir_alignof.tid = t;
break;
default:
e->kind = SPL_IR_TYPE_FIELD_COUNT;
e->field_count.tid = t;
break;
}
set_ntype(fc, n, kw_type(a, "usize"));
return n;
}
if (strcmp(id, "dbg") == 0) {
for (usize i = 0; i < pn->primary_expr.builtin_expr.expr_list.size; i++)
/* @offsetof(T, field): 字段名 → 索引常量节点 */
if (bi->kind == SPL_BUILTIN_OFFSET_OF) {
spl_type_id_t t =
type_from_type_like(a, fc, pn->primary_expr.builtin_expr.expr_list.data[0]);
spl_ast_node_t *farg =
node_at(a->sema, pn->primary_expr.builtin_expr.expr_list.data[1]);
if (!t || !farg || farg->kind != SPL_AST_EXPR) {
diag(a, fc, 0, "@offsetof: invalid arguments");
return 0;
}
spl_ast_node_t *fn_ = farg->expr.op == SPL_AST_PRIMARY_EXPR
? node_at(a->sema, farg->expr.op_expr.left)
: NULL;
const char *fname =
(fn_ && fn_->primary_expr.kind == SPL_AST_IDENT) ? fn_->primary_expr.ident : NULL;
isize fidx = fname ? agg_index_or_builtin(a, t, fname) : -1;
if (fidx < 0) {
diag(a, fc, 0, "@offsetof: unknown field");
return 0;
}
spl_ir_node_ref_t idx = const_int(a, fc, kw_type(a, "usize"), (usize)fidx);
spl_ir_node_ref_t n = emit_node(a, fc);
spl_ir_node_t *e = enode(a, fc, n);
e->kind = SPL_IR_TYPE_OFFSETOF;
e->ir_offsetof.tid = t;
e->ir_offsetof.field_idx = idx;
set_ntype(fc, n, kw_type(a, "usize"));
return n;
}
/* @dbg(args...): 逐参数求值(副作用),发射断点 */
if (bi->kind == SPL_BUILTIN_DBG) {
for (usize i = 0; i < nargs; i++)
lower_expr(a, fc, pn->primary_expr.builtin_expr.expr_list.data[i]);
spl_ir_node_ref_t n = emit_node(a, fc);
spl_ir_node_t *e = enode(a, fc, n);
@@ -1570,7 +1634,31 @@ static spl_ir_node_ref_t lower_primary(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_nod
set_ntype(fc, n, kw_type(a, "void"));
return n;
}
diag(a, fc, 0, "unsupported builtin call");
/* @assert(cond): 若 cond 为假 → trapHALT */
if (bi->kind == SPL_BUILTIN_ASSERT) {
spl_ir_node_ref_t c =
lower_expr(a, fc, pn->primary_expr.builtin_expr.expr_list.data[0]);
usize trap_b = new_block(fc);
usize exit_b = new_block(fc);
emit_br(a, fc, c, exit_b, trap_b);
begin_block(fc, trap_b);
{
spl_ir_node_ref_t n = emit_node(a, fc);
spl_ir_node_t *e = enode(a, fc, n);
e->kind = SPL_IR_CONTROL_TRAP;
set_ntype(fc, n, kw_type(a, "void"));
fc->terminated = 1;
}
begin_block(fc, exit_b);
spl_ir_node_ref_t r = emit_node(a, fc);
spl_ir_node_t *e = enode(a, fc, r);
e->kind = SPL_IR_TYPE_CONST;
e->type_const.tid = kw_type(a, "void");
set_ntype(fc, r, kw_type(a, "void"));
return r;
}
/* @import: 预留未实现 */
diag(a, fc, 0, "builtin @import not implemented");
return 0;
}
default:
@@ -1719,7 +1807,7 @@ static int resolve_callee(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node_ref_t base,
vt = underlying(a->sema, vtt->ptr_pointee);
vtt = tn(a->sema, vt);
}
/* enum 方法:在enum def 上查*/
/* enum 方法在enum def 上查*/
spl_type_id_t lookup = vt;
spl_type_id_t e0 = 0;
if (vtt && is_enum_expand(a, vt, &e0))
@@ -1759,7 +1847,7 @@ static spl_ir_node_ref_t lower_field(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node_
if (vidx >= 0)
return enum_variant_value(a, fc, ttr, vidx);
}
/* 聚合命名空间成员static var/const <EFBFBD>?全局数据 */
/* 聚合命名空间成员static var/const 全局数据 */
spl_def_id_t gdef = def_for_type(a, ttr);
spl_def_node_t *gd = gdef ? def_at(a->sema, gdef) : NULL;
for (usize i = 0; gd && i < gd->agg_def.size; i++) {
@@ -1868,6 +1956,12 @@ static spl_ir_node_ref_t lower_postfix(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_nod
case SPL_AST_SLICE_EXPR: {
spl_type_id_t bt = 0;
spl_ir_node_ref_t base_lv = lower_lvalue(a, fc, pf->postfix_expr.primary_expr, &bt);
spl_ir_node_ref_t base_val = 0;
if (!base_lv) {
/* base 是切片/数组表达式(如 arr[1..4][1..2]):取值后提取字段 */
base_val = lower_expr(a, fc, pf->postfix_expr.primary_expr);
bt = node_type(fc, base_val);
}
spl_type_node_t *tt = tn(a->sema, underlying(a->sema, bt));
if (!tt || (tt->kind != SPL_TYPE_ARRAY && tt->kind != SPL_TYPE_SLICE)) {
diag(a, fc, 0, "slice requires array/slice");
@@ -1882,7 +1976,7 @@ static spl_ir_node_ref_t lower_postfix(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_nod
base_ptr = base_lv;
total_len = const_int(a, fc, kw_type(a, "usize"), tt->array_type.len);
} else {
spl_ir_node_ref_t slv = emit_load(a, fc, bt, base_lv);
spl_ir_node_ref_t slv = base_lv ? emit_load(a, fc, bt, base_lv) : base_val;
spl_type_id_t ep = spl_type_ptr((spl_type_t *)&a->sema->type, elem);
base_ptr = emit_agg_extract(a, fc, bt, ep, 0, slv);
total_len = emit_agg_extract(a, fc, bt, kw_type(a, "usize"), 1, slv);
@@ -2167,7 +2261,7 @@ static spl_ir_node_ref_t lower_assign(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node
lt = it->tid;
target = it->slot;
} else {
/* 全局 var<EFBFBD>?/ 命名空间裸名<EFBFBD>?*/
/* 全局 var顶/ 命名空间裸名*/
spl_def_id_t def = pn->resolved_def_id;
if (!def)
def = root_lookup(a, pn->primary_expr.ident);
@@ -2276,6 +2370,8 @@ static spl_ir_node_ref_t lower_expr(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node_r
spl_ast_node_t *n = node_at(a->sema, ref);
if (!n || n->kind != SPL_AST_EXPR)
return 0;
if (ref)
fc->cur_src = ref; /* 调试行号:当前语*/
switch (n->expr.op) {
case SPL_AST_PRIMARY_EXPR:
return lower_primary(a, fc, node_at(a->sema, n->expr.op_expr.left));
@@ -2369,6 +2465,9 @@ static void lower_var_decl(spl_ast2ir_t *a, fnctx_t *fc, const char *name, spl_d
emit_store(a, fc, tid, slot, v);
}
env_add(fc, name, def_id, tid, slot, 0, 0, 1);
/* 调试:登记变量名 alloca 节点 */
spl_ir_dbg_var_t dv = {name, slot, tid, 0, 0};
vec_push(a->ir.funcs.data[fc->fn].dbg_vars, dv);
}
static void lower_if(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node_t *b) {
@@ -2468,6 +2567,18 @@ static void for_seq_setup(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node_ref_t eref,
spl_ir_node_ref_t v = lower_expr(a, fc, eref);
spl_type_id_t vt = underlying(a->sema, node_type(fc, v));
spl_type_node_t *vtt = vt ? tn(a->sema, vt) : NULL;
if (vtt && vtt->kind == SPL_TYPE_RANGE) {
/* Range 值:内部 { begin, end },迭代 begin..end-1 */
s->kind = FOR_RANGE;
s->elem_tid = vtt->range_element;
s->begin_slot = emit_alloca(a, fc, s->elem_tid);
emit_store(a, fc, s->elem_tid, s->begin_slot,
emit_agg_extract(a, fc, vt, s->elem_tid, 0, v));
spl_ir_node_ref_t end = emit_agg_extract(a, fc, vt, s->elem_tid, 1, v);
spl_ir_node_ref_t b = emit_load(a, fc, s->elem_tid, s->begin_slot);
s->len = emit_arith(a, fc, SPL_IR_ARITH_SUB, s->elem_tid, end, b);
return;
}
if (vtt && vtt->kind == SPL_TYPE_SLICE) {
s->kind = FOR_SLICE;
s->elem_tid = vtt->slice_element;
@@ -2640,13 +2751,26 @@ static void lower_match(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node_t *b) {
emit_jmp(a, fc, body_b);
} else {
spl_ir_node_ref_t cond = 0;
if (is_enum && pk->packed_expr.ident) {
isize vidx = enum_variant_index(a, st, pk->packed_expr.ident);
if (vidx < 0)
vidx = 0;
spl_ir_node_ref_t tv = emit_load(a, fc, tag_t, tag_slot);
spl_ir_node_ref_t idxc = const_int(a, fc, tag_t, (usize)vidx);
cond = emit_cmp(a, fc, SPL_IR_CMP_EQ, tag_t, tv, idxc);
const char *vname = NULL;
if (is_enum) {
/* 变体名:`.Red`ident或 `Tag.ident`expr 字段路径)两种形式 */
vname = pk->packed_expr.ident;
if (!vname && pk->packed_expr.expr) {
spl_ast_node_t *en = node_at(a->sema, pk->packed_expr.expr);
if (en && en->kind == SPL_AST_EXPR && en->expr.op == SPL_AST_POSTFIX_EXPR) {
spl_ast_node_t *epf = node_at(a->sema, en->expr.op_expr.left);
if (epf && epf->postfix_expr.kind == SPL_AST_FIELD_EXPR)
vname = epf->postfix_expr.field_expr;
}
}
if (vname) {
isize vidx = enum_variant_index(a, st, vname);
if (vidx < 0)
vidx = 0;
spl_ir_node_ref_t tv = emit_load(a, fc, tag_t, tag_slot);
spl_ir_node_ref_t idxc = const_int(a, fc, tag_t, (usize)vidx);
cond = emit_cmp(a, fc, SPL_IR_CMP_EQ, tag_t, tv, idxc);
}
} else if (is_int && pk->packed_expr.expr) {
spl_ir_node_ref_t sv = emit_load(a, fc, st, subj_slot);
spl_ir_node_ref_t pv = lower_expr(a, fc, pk->packed_expr.expr);
@@ -2665,7 +2789,7 @@ static void lower_match(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node_t *b) {
spl_type_id_t pt = enum_payload_tid(a, st, vidx);
if (pt) {
spl_ir_node_ref_t sv = emit_load(a, fc, st, subj_slot);
/* enum 布局 = tag(0) + payload(8):直接提<EFBFBD>?payloadfield_tid = 变体具体类型 */
/* enum 布局 = tag(0) + payload(8)直接提payloadfield_tid = 变体具体类型 */
spl_ir_node_ref_t pv = emit_agg_extract(a, fc, st, pt, 1, sv);
spl_ir_node_ref_t bslot = emit_alloca(a, fc, pt);
emit_store(a, fc, pt, bslot, pv);
@@ -2729,9 +2853,23 @@ static void lower_stmt(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node_ref_t ref) {
case SPL_AST_IF_STATEMENT:
lower_if(a, fc, b);
break;
case SPL_AST_IFVAR_STATEMENT:
diag(a, fc, ref, "if-var not supported");
case SPL_AST_IFVAR_STATEMENT: {
/* if var .x[y] = e { }:绑定新变量 y = e进入 if 块sema 语义)
* 若 bind_ident 为空if var .x = e则不绑定仅进入 if 块 */
spl_ast_node_t *pk = node_at(a->sema, b->block_item.ifvar_statement.packed_expr);
if (pk && pk->packed_expr.bind_ident && pk->packed_expr.expr) {
spl_ir_node_ref_t ev = lower_expr(a, fc, pk->packed_expr.expr);
spl_type_id_t vt = underlying(a->sema, node_type(fc, ev));
spl_ir_node_ref_t bslot = emit_alloca(a, fc, vt);
emit_store(a, fc, vt, bslot, ev);
env_add(fc, pk->packed_expr.bind_ident, 0, vt, bslot, 0, 0, 0);
}
env_push(fc);
lower_block(a, fc, &b->block_item.ifvar_statement.if_block);
env_pop(fc);
/* else 分支:无失败语义,不发射 */
break;
}
case SPL_AST_WHILE_STATEMENT:
lower_while(a, fc, b);
break;
@@ -2784,7 +2922,7 @@ static void lower_stmt(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node_ref_t ref) {
* ================================================================ */
static spl_ir_func_ref_t a2ir_fn_of(spl_ast2ir_t *a, spl_type_id_t fn_tid) {
/* 懒扫描IR func 已记<EFBFBD>?fn_tidspl_type_fn 不去重fn_tid 唯一<EFBFBD>?*/
/* 懒扫描IR func 已记fn_tidspl_type_fn 不去重fn_tid 唯一*/
for (usize i = 1; i < a->ir.funcs.size; i++) {
if (a->ir.funcs.data[i].fn_tid == fn_tid)
return i;
@@ -2818,6 +2956,9 @@ static void lower_func_body(spl_ast2ir_t *a, spl_ir_func_ref_t fid, spl_type_id_
spl_ir_node_ref_t slot = emit_alloca(a, &fc, pt);
emit_store(a, &fc, pt, slot, pr);
env_add(&fc, pd->param_decl.name, pd->resolved_def_id, pt, slot, 0, 0, 0);
/* 调试参数登记值在参数区fp 偏移ir2vm param_off 填) */
spl_ir_dbg_var_t dv = {pd->param_decl.name, slot, pt, 1, (usize)i};
vec_push(a->ir.funcs.data[fid].dbg_vars, dv);
}
begin_block(&fc, new_block(&fc));
lower_block(a, &fc, &fn->fn_decl.block);
@@ -2870,10 +3011,10 @@ void spl_ast2ir_drop(spl_ast2ir_t *ast2ir) {
}
/* ================================================================
* 全局数据(聚合类型下 / 顶层<EFBFBD>?var、const<EFBFBD>?
* 全局数据(聚合类型下 / 顶层var、const
* ================================================================ */
/* 常量折叠仅支持字面量int/char/float/string/null与一元负<EFBFBD>?*/
/* 常量折叠仅支持字面量int/char/float/string/null与一元负*/
typedef struct {
int const_init;
isize int_v;
@@ -2937,6 +3078,13 @@ static void collect_gdata_list(spl_ast2ir_t *a, spl_ast_node_ref_vec_t *members)
} else if (m->kind == SPL_AST_CONST_DECL) {
mname = m->const_decl.name;
iexpr = m->const_decl.expr;
} else if (m->kind == SPL_AST_MEMBER_DECL) {
/* 顶层裸成员(文件级 IDENT: T视为全局 var聚合体内 MEMBER_DECL 是字段不收集 */
spl_def_node_t *md = m->resolved_def_id ? def_at(a->sema, m->resolved_def_id) : NULL;
if (!md || md->kind != SPL_DEF_VAR)
continue;
mname = m->member_decl.name;
iexpr = 0;
} else {
continue;
}
@@ -2950,7 +3098,7 @@ static void collect_gdata_list(spl_ast2ir_t *a, spl_ast_node_ref_vec_t *members)
spl_type_id_t g_tid = d->type_id;
if (iexpr)
fold_const_init(a, iexpr, &g);
/* 全局 value = type.const 节点(标量折叠值;聚合/init 零) */
/* 全局 value = type.const 节点(标量折叠值;聚合/init 零) */
spl_ir_node_t v;
memset(&v, 0, sizeof v);
v.kind = SPL_IR_TYPE_CONST;
@@ -2987,7 +3135,7 @@ static void collect_gdata(spl_ast2ir_t *a) {
}
}
/* def_id <EFBFBD>?gdata value 节点索引;未命中返回 -1 */
/* def_id gdata value 节点索引;未命中返回 -1 */
static isize gdata_index_by_def(spl_ast2ir_t *a, spl_def_id_t def_id) {
for (usize i = 0; i < a->gdata_ref.size; i++)
if (a->gdata_ref.data[i].def_id == def_id)