stage1 修复设计问题 实现ir2vm
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
* 设计要点 * - 名称解析自包含:局部变类型用自身环境栈;顶层类函数sema root scope 与聚合成员表 * -
|
||||
* 变量落在内存槽(@mem.alloca),写走 @mem.load/store;表达式临时值为 SSA * - 控制流用"块表 +
|
||||
* fixup 补丁":分跳转目标在函数末尾回填为块首指令node ref * -
|
||||
* 聚合字段访问:读@agg.extract,写字节地址直写"(@mem.offset + @mem.store) * - 枚举=
|
||||
* 聚合字段访问:读@agg.extract,写字节地址直写"(@mem.offset + @mem.store<EFBFBD>?* - 枚举=
|
||||
* agg.construct(enum)([tag, payload?]);match tag 分发 * - defer 按作用域逆序执行(正常退/ ret /
|
||||
* break / continue 全覆盖) */
|
||||
|
||||
@@ -95,6 +95,7 @@ static int is_ptr_type(const spl_sema_t *sema, spl_type_id_t tid) {
|
||||
/* ---- 符号解析 ---- */
|
||||
|
||||
static spl_type_id_t agg_field_tid_at(spl_ast2ir_t *a, spl_type_id_t agg_tid, isize idx);
|
||||
static isize gdata_index_by_def(spl_ast2ir_t *a, spl_def_id_t def_id);
|
||||
|
||||
static spl_type_id_t kw_type(spl_ast2ir_t *a, const char *name) {
|
||||
spl_def_id_t def = 0;
|
||||
@@ -132,7 +133,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) */
|
||||
/* 判断 agg_def 条目是否为结构字段(SPL_DEF_MEMBER<EFBFBD>?*/
|
||||
static int agg_entry_is_field(spl_ast2ir_t *a, const spl_var_def_t *e) {
|
||||
if (!e->def_id)
|
||||
return 0;
|
||||
@@ -140,7 +141,7 @@ static int agg_entry_is_field(spl_ast2ir_t *a, const spl_var_def_t *e) {
|
||||
return ed && ed->kind == SPL_DEF_MEMBER;
|
||||
}
|
||||
|
||||
/* 命名空间成员类型(方法/嵌套类型/static var):按名任意 kind */
|
||||
/* 命名空间成员类型(方<EFBFBD>?嵌套类型/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);
|
||||
@@ -154,7 +155,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 的位置(与 type.agg_field_types 按序对齐) */
|
||||
/* 结构字段序号 = 相对 SPL_DEF_MEMBER 的位置(<EFBFBD>?type.agg_field_types 按序对齐<EFBFBD>?*/
|
||||
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);
|
||||
@@ -187,7 +188,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 个 SPL_DEF_MEMBER 条目) */
|
||||
/* 按字段序号查成员名(agg_def 中第 idx <EFBFBD>?SPL_DEF_MEMBER 条目<EFBFBD>?*/
|
||||
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);
|
||||
@@ -237,141 +238,6 @@ static spl_type_id_t agg_field_tid_or_builtin(spl_ast2ir_t *a, spl_type_id_t agg
|
||||
return agg_field_tid_at(a, agg_tid, idx);
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* 类型布局(sizeof / alignof / offsetof *
|
||||
* ================================================================ */
|
||||
|
||||
static usize align_up(usize v, usize a) { return (v + a - 1) & ~(a - 1); }
|
||||
|
||||
static usize type_align(const spl_sema_t *sema, spl_type_id_t tid) {
|
||||
spl_type_node_t *t = tn(sema, underlying(sema, tid));
|
||||
if (!t)
|
||||
return 1;
|
||||
switch (t->kind) {
|
||||
case SPL_TYPE_VOID:
|
||||
return 1;
|
||||
case SPL_TYPE_BOOL:
|
||||
return 1;
|
||||
case SPL_TYPE_INT:
|
||||
return t->int_type.bits / 8;
|
||||
case SPL_TYPE_FLOAT:
|
||||
return t->float_type.bits / 8;
|
||||
case SPL_TYPE_PTR:
|
||||
case SPL_TYPE_FN:
|
||||
return sizeof(usize);
|
||||
case SPL_TYPE_SLICE:
|
||||
case SPL_TYPE_RANGE:
|
||||
return sizeof(usize);
|
||||
case SPL_TYPE_ARRAY:
|
||||
return type_align(sema, t->array_type.element);
|
||||
case SPL_TYPE_STRUCT: {
|
||||
usize a = 1;
|
||||
for (usize i = 0; i < t->agg_field_types.size; i++) {
|
||||
usize fa = type_align(sema, t->agg_field_types.data[i]);
|
||||
if (fa > a)
|
||||
a = fa;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
case SPL_TYPE_UNION: {
|
||||
usize a = 1;
|
||||
for (usize i = 0; i < t->agg_field_types.size; i++) {
|
||||
usize fa = type_align(sema, t->agg_field_types.data[i]);
|
||||
if (fa > a)
|
||||
a = fa;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
case SPL_TYPE_ENUM:
|
||||
return sizeof(usize);
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static usize type_size(const spl_sema_t *sema, spl_type_id_t tid) {
|
||||
spl_type_node_t *t = tn(sema, underlying(sema, tid));
|
||||
if (!t)
|
||||
return 0;
|
||||
switch (t->kind) {
|
||||
case SPL_TYPE_VOID:
|
||||
return 0;
|
||||
case SPL_TYPE_BOOL:
|
||||
return 1;
|
||||
case SPL_TYPE_INT:
|
||||
return t->int_type.bits / 8;
|
||||
case SPL_TYPE_FLOAT:
|
||||
return t->float_type.bits / 8;
|
||||
case SPL_TYPE_PTR:
|
||||
case SPL_TYPE_FN:
|
||||
return sizeof(usize);
|
||||
case SPL_TYPE_SLICE:
|
||||
return sizeof(usize) * 2;
|
||||
case SPL_TYPE_RANGE:
|
||||
return sizeof(usize) * 2;
|
||||
case SPL_TYPE_ARRAY:
|
||||
return t->array_type.len * type_size(sema, t->array_type.element);
|
||||
case SPL_TYPE_STRUCT: {
|
||||
usize sz = 0;
|
||||
for (usize i = 0; i < t->agg_field_types.size; i++) {
|
||||
usize fa = type_align(sema, t->agg_field_types.data[i]);
|
||||
sz = align_up(sz, fa);
|
||||
sz += type_size(sema, t->agg_field_types.data[i]);
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
case SPL_TYPE_UNION: {
|
||||
usize sz = 0;
|
||||
for (usize i = 0; i < t->agg_field_types.size; i++) {
|
||||
usize fs = type_size(sema, t->agg_field_types.data[i]);
|
||||
if (fs > sz)
|
||||
sz = fs;
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
case SPL_TYPE_ENUM: {
|
||||
usize payload = 0;
|
||||
for (usize i = 0; i < t->enum_type.variants.size; i++) {
|
||||
spl_type_id_t v = underlying(sema, t->enum_type.variants.data[i]);
|
||||
if (v == underlying(sema, tid))
|
||||
continue;
|
||||
usize vs = type_size(sema, v);
|
||||
if (vs > payload)
|
||||
payload = vs;
|
||||
}
|
||||
return sizeof(usize) + payload;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 聚合字段字节偏移(struct 顺序对齐;union/enum 偏移 0;slice/range 内置字段*/
|
||||
static usize type_field_offset(const spl_sema_t *sema, spl_type_id_t agg_tid, isize idx) {
|
||||
spl_type_node_t *t = tn(sema, underlying(sema, agg_tid));
|
||||
if (!t)
|
||||
return 0;
|
||||
if (t->kind == SPL_TYPE_SLICE || t->kind == SPL_TYPE_RANGE)
|
||||
return (usize)idx * sizeof(usize);
|
||||
if ((usize)idx >= t->agg_field_types.size)
|
||||
return 0;
|
||||
switch (t->kind) {
|
||||
case SPL_TYPE_STRUCT: {
|
||||
usize off = 0;
|
||||
for (isize i = 0; i < idx; i++) {
|
||||
usize fa = type_align(sema, t->agg_field_types.data[i]);
|
||||
off = align_up(off, fa);
|
||||
off += type_size(sema, t->agg_field_types.data[i]);
|
||||
}
|
||||
return align_up(off, type_align(sema, t->agg_field_types.data[idx]));
|
||||
}
|
||||
case SPL_TYPE_UNION:
|
||||
case SPL_TYPE_ENUM:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* IR 发射(per-function 上下文)
|
||||
* ================================================================ */
|
||||
@@ -412,6 +278,7 @@ typedef VEC(ir_loop_t) ir_loop_vec_t;
|
||||
|
||||
typedef struct {
|
||||
spl_ir_func_ref_t fn;
|
||||
spl_ast2ir_t *a;
|
||||
spl_type_id_t ret_tid;
|
||||
spl_type_id_t ns_tid; /* 所在聚合类型(方法命名空间);顶层0 */
|
||||
ir_env_stack_t env;
|
||||
@@ -425,8 +292,9 @@ typedef struct {
|
||||
int err;
|
||||
} fnctx_t;
|
||||
|
||||
static void fc_init(fnctx_t *fc, spl_ir_func_ref_t fn, spl_type_id_t ret) {
|
||||
static void fc_init(fnctx_t *fc, spl_ast2ir_t *a, spl_ir_func_ref_t fn, spl_type_id_t ret) {
|
||||
memset(fc, 0, sizeof *fc);
|
||||
fc->a = a;
|
||||
fc->fn = fn;
|
||||
fc->ret_tid = ret;
|
||||
vec_init(fc->env);
|
||||
@@ -436,8 +304,9 @@ static void fc_init(fnctx_t *fc, spl_ir_func_ref_t fn, spl_type_id_t ret) {
|
||||
vec_init(fc->types);
|
||||
}
|
||||
|
||||
static void fc_init_ns(fnctx_t *fc, spl_ir_func_ref_t fn, spl_type_id_t ret, spl_type_id_t ns) {
|
||||
fc_init(fc, fn, ret);
|
||||
static void fc_init_ns(fnctx_t *fc, spl_ast2ir_t *a, spl_ir_func_ref_t fn, spl_type_id_t ret,
|
||||
spl_type_id_t ns) {
|
||||
fc_init(fc, a, fn, ret);
|
||||
fc->ns_tid = ns;
|
||||
}
|
||||
|
||||
@@ -664,6 +533,34 @@ 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 不算。 */
|
||||
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);
|
||||
spl_ir_node_ref_t n = emit_node(a, fc);
|
||||
spl_ir_node_t *e = enode(a, fc, n);
|
||||
e->kind = SPL_IR_MEM_FIELD_PTR;
|
||||
e->mem_field_ptr.tid = underlying(a->sema, agg_tid);
|
||||
e->mem_field_ptr.agg = ptr;
|
||||
e->mem_field_ptr.field_idx = (usize)fidx;
|
||||
spl_type_id_t pt = spl_type_ptr((spl_type_t *)&a->sema->type, fty);
|
||||
set_ntype(fc, n, pt);
|
||||
return n;
|
||||
}
|
||||
|
||||
/* 全局静态数据地址:mem.global_alloc(tid, gdata_idx) <20>?*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);
|
||||
spl_ir_node_t *e = enode(a, fc, n);
|
||||
e->kind = SPL_IR_MEM_GLOBAL_ALLOC;
|
||||
e->mem_global_alloc.tid = tid;
|
||||
e->mem_global_alloc.const_node = gdata_idx;
|
||||
spl_type_id_t pt = spl_type_ptr((spl_type_t *)&a->sema->type, tid);
|
||||
set_ntype(fc, n, pt);
|
||||
return n;
|
||||
}
|
||||
|
||||
static spl_ir_node_ref_t emit_agg_construct(spl_ast2ir_t *a, fnctx_t *fc, spl_type_id_t tid) {
|
||||
spl_ir_node_ref_t n = emit_node(a, fc);
|
||||
spl_ir_node_t *e = enode(a, fc, n);
|
||||
@@ -687,6 +584,7 @@ static spl_ir_node_ref_t emit_agg_extract(spl_ast2ir_t *a, fnctx_t *fc, spl_type
|
||||
spl_ir_node_t *e = enode(a, fc, n);
|
||||
e->kind = SPL_IR_AGG_EXTRACT;
|
||||
e->agg_extract.tid = tid;
|
||||
e->agg_extract.field_tid = field_tid;
|
||||
e->agg_extract.field_idx = fidx;
|
||||
e->agg_extract.val = val;
|
||||
set_ntype(fc, n, field_tid);
|
||||
@@ -767,7 +665,7 @@ static ir_env_t *env_find(fnctx_t *fc, const char *name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* def_id 优先定位(sema 已作用域解析,绕开同名遮蔽歧义);无 def_id 时兜底名字 */
|
||||
/* def_id 优先定位(sema 已作用域解析,绕开同名遮蔽歧义);<EFBFBD>?def_id 时兜底名<EFBFBD>?*/
|
||||
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--) {
|
||||
@@ -842,6 +740,17 @@ 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 是否<E698AF>?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) {
|
||||
if (out_enum)
|
||||
*out_enum = underlying(a->sema, tid);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 表达式当作类型引用解析(a / a.b.c,用于枚举变嵌套类型路径*/
|
||||
static spl_type_id_t type_of_type_ref(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node_ref_t bref) {
|
||||
spl_ast_node_t *n = node_at(a->sema, bref);
|
||||
@@ -956,13 +865,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;
|
||||
/* 首选 sema 注解:resolved_def_id → def → 类型(聚合/别名/命名类型) */
|
||||
/* 首<EFBFBD>?sema 注解:resolved_def_id <EFBFBD>?def <EFBFBD>?类型(聚<EFBFBD>?别名/命名类型<EFBFBD>?*/
|
||||
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;
|
||||
}
|
||||
/* 兜底:组合/内置类型(sema 不为其建 def 的 *T、[]T、fn(...)、关键字、别名到组合) */
|
||||
/* 兜底:组<EFBFBD>?内置类型(sema 不为其建 def <EFBFBD>?*T、[]T、fn(...)、关键字、别名到组合<EFBFBD>?*/
|
||||
spl_type_id_t base = 0;
|
||||
switch (n->type_expr.kind) {
|
||||
case SPL_AST_BASE_TYPE_PATH:
|
||||
@@ -989,7 +898,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);防御性报错 */
|
||||
/* 内联聚合不应走到这里(sema 已注解其 def);防御性报<EFBFBD>?*/
|
||||
diag(a, fc, ref, "inline aggregate not annotated by sema");
|
||||
return 0;
|
||||
default:
|
||||
@@ -1110,16 +1019,7 @@ static spl_ast_node_ref_t field_chain_base(spl_ast2ir_t *a, spl_ast_node_t *pf,
|
||||
return bref;
|
||||
}
|
||||
|
||||
/* 指针按字节偏移(mem.offset u8 为单位即字节*/
|
||||
static spl_ir_node_ref_t ptr_add_bytes(spl_ast2ir_t *a, fnctx_t *fc, spl_ir_node_ref_t addr,
|
||||
usize bytes) {
|
||||
if (!bytes || !addr)
|
||||
return addr;
|
||||
spl_ir_node_ref_t c = const_int(a, fc, kw_type(a, "usize"), bytes);
|
||||
return emit_offset(a, fc, kw_type(a, "u8"), addr, c);
|
||||
}
|
||||
|
||||
/* 字段链的存储地址(root.a.b 地址 + 字段类型*/
|
||||
/* 字段链的存储地址(root.a.b 地址 + 字段类型<E7B1BB>?*/
|
||||
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);
|
||||
@@ -1131,12 +1031,34 @@ 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 <20>?lvalue = <20>?gdata 地址<E59CB0>?*/
|
||||
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);
|
||||
spl_def_node_t *gd = gdef ? def_at(a->sema, gdef) : NULL;
|
||||
for (usize i = 0; gd && i < gd->agg_def.size; i++) {
|
||||
spl_var_def_t *e = &gd->agg_def.data[i];
|
||||
if (e->name && strcmp(e->name, names[0]) == 0 && e->def_id) {
|
||||
spl_def_node_t *ed = def_at(a->sema, e->def_id);
|
||||
if (ed && ed->kind == SPL_DEF_VAR) {
|
||||
isize gi = gdata_index_by_def(a, e->def_id);
|
||||
if (gi >= 0) {
|
||||
*out_tid = e->type_id;
|
||||
return emit_global_alloc(a, fc, e->type_id, (usize)gi);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
spl_type_id_t cur_tid = 0;
|
||||
spl_ir_node_ref_t addr = lower_lvalue(a, fc, root_ref, &cur_tid);
|
||||
spl_type_node_t *curt = tn(a->sema, underlying(a->sema, cur_tid));
|
||||
if (curt && curt->kind == SPL_TYPE_PTR) {
|
||||
cur_tid = underlying(a->sema, curt->ptr_pointee);
|
||||
addr = emit_load(a, fc, cur_tid, addr);
|
||||
spl_type_id_t pty = spl_type_ptr((spl_type_t *)&a->sema->type, cur_tid);
|
||||
addr = emit_load(a, fc, pty, addr);
|
||||
}
|
||||
if (!addr || !cur_tid)
|
||||
return 0;
|
||||
@@ -1148,16 +1070,15 @@ static spl_ir_node_ref_t lower_field_address(spl_ast2ir_t *a, fnctx_t *fc, spl_a
|
||||
isize idx = agg_index_or_builtin(a, cur_tid, names[i]);
|
||||
if (idx < 0)
|
||||
return 0;
|
||||
usize off = type_field_offset(a->sema, cur_tid, idx);
|
||||
spl_type_id_t ft = agg_field_tid_or_builtin(a, cur_tid, idx);
|
||||
if (off)
|
||||
addr = ptr_add_bytes(a, fc, addr, off);
|
||||
addr = emit_field(a, fc, cur_tid, addr, idx);
|
||||
cur_tid = ft;
|
||||
if (i > 0) {
|
||||
spl_type_node_t *ftt = tn(a->sema, underlying(a->sema, cur_tid));
|
||||
if (ftt && ftt->kind == SPL_TYPE_PTR) {
|
||||
cur_tid = underlying(a->sema, ftt->ptr_pointee);
|
||||
addr = emit_load(a, fc, cur_tid, addr);
|
||||
spl_type_id_t pty = spl_type_ptr((spl_type_t *)&a->sema->type, cur_tid);
|
||||
addr = emit_load(a, fc, pty, addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1244,8 +1165,42 @@ static spl_ir_node_ref_t lower_lvalue(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node
|
||||
*out_tid = it->tid;
|
||||
return it->slot;
|
||||
}
|
||||
if (it)
|
||||
if (it) {
|
||||
diag(a, fc, ref, "not an addressable variable");
|
||||
return 0;
|
||||
}
|
||||
/* 顶层 / 命名空间全局 var:lvalue = 全局分配地址 */
|
||||
spl_def_id_t def = pn->resolved_def_id;
|
||||
if (!def)
|
||||
def = root_lookup(a, pn->primary_expr.ident);
|
||||
if (def) {
|
||||
spl_def_node_t *d = def_at(a->sema, def);
|
||||
if (d && d->kind == SPL_DEF_VAR) {
|
||||
isize gi = gdata_index_by_def(a, def);
|
||||
if (gi >= 0) {
|
||||
*out_tid = d->type_id;
|
||||
return emit_global_alloc(a, fc, *out_tid, (usize)gi);
|
||||
}
|
||||
}
|
||||
if (fc->ns_tid) {
|
||||
spl_def_id_t gdef = def_for_type(a, fc->ns_tid);
|
||||
spl_def_node_t *gd = gdef ? def_at(a->sema, gdef) : NULL;
|
||||
for (usize i = 0; gd && i < gd->agg_def.size; i++) {
|
||||
spl_var_def_t *e = &gd->agg_def.data[i];
|
||||
if (e->name && strcmp(e->name, pn->primary_expr.ident) == 0 && e->def_id) {
|
||||
spl_def_node_t *ed = def_at(a->sema, e->def_id);
|
||||
if (ed && ed->kind == SPL_DEF_VAR) {
|
||||
isize gi = gdata_index_by_def(a, e->def_id);
|
||||
if (gi >= 0) {
|
||||
*out_tid = e->type_id;
|
||||
return emit_global_alloc(a, fc, e->type_id, (usize)gi);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (pn && pn->primary_expr.kind == SPL_AST_EXPR_EXPR)
|
||||
@@ -1307,11 +1262,36 @@ static spl_ir_node_ref_t lower_ident(spl_ast2ir_t *a, fnctx_t *fc, const char *n
|
||||
if (def) {
|
||||
spl_def_node_t *d = def_at(a->sema, def);
|
||||
if (d &&
|
||||
(d->kind == SPL_DEF_AGG || d->kind == SPL_DEF_ALIAS || d->kind == SPL_DEF_DISTINCT))
|
||||
diag(a, fc, ref, "type name used as value (aggregate member not supported)");
|
||||
else
|
||||
diag(a, fc, ref, "undefined identifier");
|
||||
(d->kind == SPL_DEF_AGG || d->kind == SPL_DEF_ALIAS || d->kind == SPL_DEF_DISTINCT)) {
|
||||
diag(a, fc, ref, "type name used as value");
|
||||
return 0;
|
||||
}
|
||||
if (d && d->kind == SPL_DEF_VAR) {
|
||||
isize gi = gdata_index_by_def(a, def);
|
||||
if (gi >= 0)
|
||||
return emit_load(a, fc, d->type_id,
|
||||
emit_global_alloc(a, fc, d->type_id, (usize)gi));
|
||||
}
|
||||
diag(a, fc, ref, "undefined identifier");
|
||||
} else {
|
||||
/* 命名空间内裸名:fc->ns_tid 聚合成员 static var/const */
|
||||
if (fc->ns_tid) {
|
||||
spl_def_id_t gdef = def_for_type(a, fc->ns_tid);
|
||||
spl_def_node_t *gd = gdef ? def_at(a->sema, gdef) : NULL;
|
||||
for (usize i = 0; gd && i < gd->agg_def.size; i++) {
|
||||
spl_var_def_t *e = &gd->agg_def.data[i];
|
||||
if (e->name && strcmp(e->name, name) == 0 && e->def_id) {
|
||||
spl_def_node_t *ed = def_at(a->sema, e->def_id);
|
||||
if (ed && ed->kind == SPL_DEF_VAR) {
|
||||
isize gi = gdata_index_by_def(a, e->def_id);
|
||||
if (gi >= 0)
|
||||
return emit_load(a, fc, e->type_id,
|
||||
emit_global_alloc(a, fc, e->type_id, (usize)gi));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
diag(a, fc, ref, "undefined identifier");
|
||||
}
|
||||
return 0;
|
||||
@@ -1413,15 +1393,20 @@ static spl_ir_node_ref_t lower_primary(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_nod
|
||||
elem = kw_type(a, "i32");
|
||||
spl_type_id_t arr = spl_type_array((spl_type_t *)&a->sema->type, elem,
|
||||
(usize)pn->primary_expr.array_lit_expr.integer);
|
||||
spl_ir_node_ref_t agg = emit_agg_construct(a, fc, arr);
|
||||
VEC(spl_ir_node_ref_t) vals;
|
||||
vec_init(vals);
|
||||
for (usize i = 0; i < pn->primary_expr.array_lit_expr.expr_list.size; i++) {
|
||||
fc->hint = elem;
|
||||
spl_ir_node_ref_t v =
|
||||
lower_expr(a, fc, pn->primary_expr.array_lit_expr.expr_list.data[i]);
|
||||
fc->hint = 0;
|
||||
v = coerce_to(a, fc, v, node_type(fc, v), elem);
|
||||
agg_construct_add(a, fc, agg, v);
|
||||
vec_push(vals, v);
|
||||
}
|
||||
spl_ir_node_ref_t agg = emit_agg_construct(a, fc, arr);
|
||||
for (usize i = 0; i < vals.size; i++)
|
||||
agg_construct_add(a, fc, agg, vals.data[i]);
|
||||
vec_free(vals);
|
||||
return agg;
|
||||
}
|
||||
case SPL_AST_ARGGREGATE_INIT: {
|
||||
@@ -1443,7 +1428,8 @@ static spl_ir_node_ref_t lower_primary(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_nod
|
||||
diag(a, fc, 0, "anonymous aggregate literal without context type");
|
||||
return 0;
|
||||
}
|
||||
spl_ir_node_ref_t agg = emit_agg_construct(a, fc, hint_t);
|
||||
VEC(spl_ir_node_ref_t) vals;
|
||||
vec_init(vals);
|
||||
for (usize j = 0; j < pn->primary_expr.aggregate_init.expr.size; j++) {
|
||||
spl_ast_node_t *item =
|
||||
node_at(a->sema, pn->primary_expr.aggregate_init.expr.data[j]);
|
||||
@@ -1456,17 +1442,34 @@ 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:自动取地址<E59CB0>?left = expr 语义<E8AFAD>?*/
|
||||
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 &&
|
||||
(v_t->kind == SPL_TYPE_STRUCT || v_t->kind == SPL_TYPE_UNION ||
|
||||
v_t->kind == SPL_TYPE_ENUM)) {
|
||||
spl_type_id_t lt = 0;
|
||||
spl_ir_node_ref_t addr =
|
||||
lower_lvalue(a, fc, item->aggregate_init_item.expr, <);
|
||||
if (addr)
|
||||
v = addr;
|
||||
}
|
||||
if (ft)
|
||||
v = coerce_to(a, fc, v, node_type(fc, v), ft);
|
||||
agg_construct_add(a, fc, agg, v);
|
||||
vec_push(vals, v);
|
||||
}
|
||||
spl_ir_node_ref_t agg = emit_agg_construct(a, fc, hint_t);
|
||||
for (usize i = 0; i < vals.size; i++)
|
||||
agg_construct_add(a, fc, agg, vals.data[i]);
|
||||
vec_free(vals);
|
||||
return agg;
|
||||
}
|
||||
spl_type_node_t *tt = tn(a->sema, tid);
|
||||
if (!tt)
|
||||
return 0;
|
||||
if (tt->kind == SPL_TYPE_ENUM) {
|
||||
spl_ir_node_ref_t agg = emit_agg_construct(a, fc, tid);
|
||||
VEC(spl_ir_node_ref_t) vals;
|
||||
vec_init(vals);
|
||||
for (usize j = 0; j < pn->primary_expr.aggregate_init.expr.size; j++) {
|
||||
spl_ast_node_t *item =
|
||||
node_at(a->sema, pn->primary_expr.aggregate_init.expr.data[j]);
|
||||
@@ -1477,7 +1480,7 @@ static spl_ir_node_ref_t lower_primary(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_nod
|
||||
diag(a, fc, 0, "unknown enum variant");
|
||||
continue;
|
||||
}
|
||||
agg_construct_add(a, fc, agg, const_int(a, fc, enum_tag_tid(a), (usize)vidx));
|
||||
vec_push(vals, const_int(a, fc, enum_tag_tid(a), (usize)vidx));
|
||||
if (item->aggregate_init_item.expr) {
|
||||
spl_type_id_t pt = enum_payload_tid(a, tid, vidx);
|
||||
fc->hint = pt;
|
||||
@@ -1485,17 +1488,23 @@ static spl_ir_node_ref_t lower_primary(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_nod
|
||||
fc->hint = 0;
|
||||
if (pt)
|
||||
pv = coerce_to(a, fc, pv, node_type(fc, pv), pt);
|
||||
agg_construct_add(a, fc, agg, pv);
|
||||
vec_push(vals, pv);
|
||||
}
|
||||
}
|
||||
spl_ir_node_ref_t agg = emit_agg_construct(a, fc, tid);
|
||||
for (usize i = 0; i < vals.size; i++)
|
||||
agg_construct_add(a, fc, agg, vals.data[i]);
|
||||
vec_free(vals);
|
||||
return agg;
|
||||
}
|
||||
if (tt->kind != SPL_TYPE_STRUCT) {
|
||||
diag(a, fc, 0, "aggregate literal target is not a struct");
|
||||
return 0;
|
||||
}
|
||||
spl_ir_node_ref_t agg = emit_agg_construct(a, fc, tid);
|
||||
spl_ir_node_ref_t agg = 0;
|
||||
usize nfields = tt->agg_field_types.size;
|
||||
VEC(spl_ir_node_ref_t) vals;
|
||||
vec_init(vals);
|
||||
for (usize i = 0; i < nfields; i++) {
|
||||
const char *fname = agg_field_name_at(a, tid, (isize)i);
|
||||
spl_ast_node_ref_t found = 0;
|
||||
@@ -1509,16 +1518,31 @@ static spl_ir_node_ref_t lower_primary(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_nod
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
agg_construct_add(a, fc, agg, const_int(a, fc, tt->agg_field_types.data[i], 0));
|
||||
vec_push(vals, const_int(a, fc, tt->agg_field_types.data[i], 0));
|
||||
continue;
|
||||
}
|
||||
spl_ast_node_t *item = node_at(a->sema, found);
|
||||
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:自动取地址<E59CB0>?left = expr 语义<E8AFAD>?*/
|
||||
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 &&
|
||||
(v_t->kind == SPL_TYPE_STRUCT || v_t->kind == SPL_TYPE_UNION ||
|
||||
v_t->kind == SPL_TYPE_ENUM)) {
|
||||
spl_type_id_t lt = 0;
|
||||
spl_ir_node_ref_t addr = lower_lvalue(a, fc, item->aggregate_init_item.expr, <);
|
||||
if (addr)
|
||||
v = addr;
|
||||
}
|
||||
v = coerce_to(a, fc, v, node_type(fc, v), tt->agg_field_types.data[i]);
|
||||
agg_construct_add(a, fc, agg, v);
|
||||
vec_push(vals, v);
|
||||
}
|
||||
agg = emit_agg_construct(a, fc, tid);
|
||||
for (usize i = 0; i < vals.size; i++)
|
||||
agg_construct_add(a, fc, agg, vals.data[i]);
|
||||
vec_free(vals);
|
||||
return agg;
|
||||
}
|
||||
case SPL_AST_BUILTIN_EXPR: {
|
||||
@@ -1695,7 +1719,12 @@ 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);
|
||||
}
|
||||
spl_type_id_t mt = vtt ? agg_member_type(a, vt, fname) : 0;
|
||||
/* enum 方法:在原 enum def 上查找 */
|
||||
spl_type_id_t lookup = vt;
|
||||
spl_type_id_t e0 = 0;
|
||||
if (vtt && is_enum_expand(a, vt, &e0))
|
||||
lookup = e0;
|
||||
spl_type_id_t mt = vtt ? agg_member_type(a, lookup, fname) : 0;
|
||||
spl_type_node_t *mtn = mt ? tn(a->sema, mt) : NULL;
|
||||
if (mt && mtn && mtn->kind == SPL_TYPE_FN) {
|
||||
out->fn_tid = mt;
|
||||
@@ -1730,6 +1759,22 @@ 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 <20>?全局数据 */
|
||||
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++) {
|
||||
spl_var_def_t *e = &gd->agg_def.data[i];
|
||||
if (e->name && strcmp(e->name, fname) == 0 && e->def_id) {
|
||||
spl_def_node_t *ed = def_at(a->sema, e->def_id);
|
||||
if (ed && ed->kind == SPL_DEF_VAR) {
|
||||
isize gi = gdata_index_by_def(a, e->def_id);
|
||||
if (gi >= 0)
|
||||
return emit_load(a, fc, e->type_id,
|
||||
emit_global_alloc(a, fc, e->type_id, (usize)gi));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
diag(a, fc, 0, "aggregate member is not a value");
|
||||
return 0;
|
||||
}
|
||||
@@ -1962,12 +2007,13 @@ static spl_ir_node_ref_t lower_binary(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node
|
||||
spl_ir_node_ref_t r = lower_expr(a, fc, rr);
|
||||
spl_type_id_t lt = underlying(a->sema, node_type(fc, l));
|
||||
spl_type_id_t rt = underlying(a->sema, node_type(fc, r));
|
||||
spl_type_node_t *ltt = tn(a->sema, lt);
|
||||
spl_type_node_t *rtt = tn(a->sema, rt);
|
||||
if (ltt && ltt->kind == SPL_TYPE_ENUM && rtt && rtt->kind == SPL_TYPE_ENUM) {
|
||||
spl_type_id_t le = 0, re = 0;
|
||||
int is_l_enum = is_enum_expand(a, lt, &le);
|
||||
int is_r_enum = is_enum_expand(a, rt, &re);
|
||||
if (is_l_enum && is_r_enum) {
|
||||
spl_type_id_t tag_t = enum_tag_tid(a);
|
||||
l = enum_tag_of(a, fc, lt, l);
|
||||
r = enum_tag_of(a, fc, rt, r);
|
||||
l = enum_tag_of(a, fc, le, l);
|
||||
r = enum_tag_of(a, fc, re, r);
|
||||
lt = tag_t;
|
||||
rt = tag_t;
|
||||
}
|
||||
@@ -2038,12 +2084,11 @@ static spl_ir_node_ref_t lower_range_value(spl_ast2ir_t *a, fnctx_t *fc, spl_ast
|
||||
spl_ir_node_ref_t b = lower_expr(a, fc, n->expr.op_expr.left);
|
||||
spl_type_id_t et = underlying(a->sema, node_type(fc, b));
|
||||
spl_type_id_t range_t = spl_type_range((spl_type_t *)&a->sema->type, et);
|
||||
spl_ir_node_ref_t e =
|
||||
n->expr.op_expr.right ? lower_expr(a, fc, n->expr.op_expr.right) : const_int(a, fc, et, 0);
|
||||
spl_ir_node_ref_t r = emit_agg_construct(a, fc, range_t);
|
||||
agg_construct_add(a, fc, r, b);
|
||||
if (n->expr.op_expr.right)
|
||||
agg_construct_add(a, fc, r, lower_expr(a, fc, n->expr.op_expr.right));
|
||||
else
|
||||
agg_construct_add(a, fc, r, const_int(a, fc, et, 0));
|
||||
agg_construct_add(a, fc, r, e);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -2116,16 +2161,53 @@ static spl_ir_node_ref_t lower_assign(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node
|
||||
spl_ast_node_t *pn = node_at(a->sema, ln->expr.op_expr.left);
|
||||
if (pn && pn->primary_expr.kind == SPL_AST_IDENT) {
|
||||
ir_env_t *it = env_find_def(fc, pn->resolved_def_id, pn->primary_expr.ident);
|
||||
if (!it || !it->slot) {
|
||||
spl_type_id_t lt = 0;
|
||||
spl_ir_node_ref_t target = 0;
|
||||
if (it && it->slot) {
|
||||
lt = it->tid;
|
||||
target = it->slot;
|
||||
} else {
|
||||
/* 全局 var(顶<EFBC88>?/ 命名空间裸名<E8A3B8>?*/
|
||||
spl_def_id_t def = pn->resolved_def_id;
|
||||
if (!def)
|
||||
def = root_lookup(a, pn->primary_expr.ident);
|
||||
if (def) {
|
||||
spl_def_node_t *d = def_at(a->sema, def);
|
||||
isize gi0 = (d && d->kind == SPL_DEF_VAR) ? gdata_index_by_def(a, def) : -1;
|
||||
if (gi0 >= 0) {
|
||||
lt = d->type_id;
|
||||
target = emit_global_alloc(a, fc, lt, (usize)gi0);
|
||||
} else if (fc->ns_tid) {
|
||||
spl_def_id_t gdef = def_for_type(a, fc->ns_tid);
|
||||
spl_def_node_t *gd = gdef ? def_at(a->sema, gdef) : NULL;
|
||||
for (usize i = 0; gd && i < gd->agg_def.size; i++) {
|
||||
spl_var_def_t *e = &gd->agg_def.data[i];
|
||||
if (e->name && strcmp(e->name, pn->primary_expr.ident) == 0 &&
|
||||
e->def_id) {
|
||||
spl_def_node_t *ed = def_at(a->sema, e->def_id);
|
||||
if (ed && ed->kind == SPL_DEF_VAR) {
|
||||
isize gi = gdata_index_by_def(a, e->def_id);
|
||||
if (gi >= 0) {
|
||||
lt = e->type_id;
|
||||
target = emit_global_alloc(a, fc, e->type_id, (usize)gi);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!target || !lt) {
|
||||
diag(a, fc, lr, "assignment target not writable");
|
||||
return 0;
|
||||
}
|
||||
spl_ir_node_ref_t cur = compound ? emit_load(a, fc, it->tid, it->slot) : 0;
|
||||
spl_ir_node_ref_t cur = compound ? emit_load(a, fc, lt, target) : 0;
|
||||
spl_ir_node_ref_t v = lower_expr(a, fc, rr);
|
||||
if (compound)
|
||||
v = lower_compound_op(a, fc, n->expr.op, it->tid, cur, v);
|
||||
v = coerce_to(a, fc, v, node_type(fc, v), it->tid);
|
||||
emit_store(a, fc, it->tid, it->slot, v);
|
||||
v = lower_compound_op(a, fc, n->expr.op, lt, cur, v);
|
||||
v = coerce_to(a, fc, v, node_type(fc, v), lt);
|
||||
emit_store(a, fc, lt, target, v);
|
||||
return v;
|
||||
}
|
||||
}
|
||||
@@ -2434,7 +2516,10 @@ static void lower_for(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node_t *b) {
|
||||
for (usize i = 0; i < nseq; i++) {
|
||||
if (!seqs[i].len)
|
||||
continue;
|
||||
spl_ir_node_ref_t l = coerce_to(a, fc, seqs[i].len, node_type(fc, seqs[i].len), iszt);
|
||||
spl_ir_node_ref_t lenv = seqs[i].len;
|
||||
if (seqs[i].kind == FOR_SLICE)
|
||||
lenv = emit_load(a, fc, kw_type(a, "usize"), seqs[i].len);
|
||||
spl_ir_node_ref_t l = coerce_to(a, fc, lenv, node_type(fc, lenv), iszt);
|
||||
if (!m) {
|
||||
m = l;
|
||||
} else {
|
||||
@@ -2472,7 +2557,12 @@ static void lower_for(spl_ast2ir_t *a, fnctx_t *fc, spl_ast_node_t *b) {
|
||||
v = emit_arith(a, fc, SPL_IR_ARITH_ADD, s->elem_tid, bg,
|
||||
coerce_to(a, fc, cur, iszt, s->elem_tid));
|
||||
} else {
|
||||
spl_ir_node_ref_t addr = emit_offset(a, fc, s->elem_tid, s->base_slot, cur);
|
||||
spl_ir_node_ref_t base = s->base_slot;
|
||||
if (s->kind == FOR_SLICE) {
|
||||
spl_type_id_t ep = spl_type_ptr((spl_type_t *)&a->sema->type, s->elem_tid);
|
||||
base = emit_load(a, fc, ep, s->base_slot);
|
||||
}
|
||||
spl_ir_node_ref_t addr = emit_offset(a, fc, s->elem_tid, base, cur);
|
||||
v = emit_load(a, fc, s->elem_tid, addr);
|
||||
}
|
||||
ir_env_t *it = env_find(fc, id_data[i]);
|
||||
@@ -2575,6 +2665,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):直接提<E68EA5>?payload,field_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);
|
||||
@@ -2693,7 +2784,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 已记录 fn_tid(spl_type_fn 不去重,fn_tid 唯一) */
|
||||
/* 懒扫描:IR func 已记<EFBFBD>?fn_tid(spl_type_fn 不去重,fn_tid 唯一<EFBFBD>?*/
|
||||
for (usize i = 1; i < a->ir.funcs.size; i++) {
|
||||
if (a->ir.funcs.data[i].fn_tid == fn_tid)
|
||||
return i;
|
||||
@@ -2709,7 +2800,7 @@ static void lower_func_body(spl_ast2ir_t *a, spl_ir_func_ref_t fid, spl_type_id_
|
||||
spl_type_node_t *ft = tn(a->sema, fn_tid);
|
||||
spl_type_id_t ret = (ft && ft->kind == SPL_TYPE_FN) ? ft->fn_type.ret : 0;
|
||||
fnctx_t fc;
|
||||
fc_init_ns(&fc, fid, ret, ns_tid);
|
||||
fc_init_ns(&fc, a, fid, ret, ns_tid);
|
||||
spl_ast_node_ref_vec_t *pl = &fn->fn_decl.param_list;
|
||||
usize nparams = (ft && ft->kind == SPL_TYPE_FN) ? ft->fn_type.params.size : 0;
|
||||
env_push(&fc);
|
||||
@@ -2774,9 +2865,136 @@ void spl_ast2ir_drop(spl_ast2ir_t *ast2ir) {
|
||||
for (usize i = 0; i < ast2ir->owned_names.size; i++)
|
||||
free(ast2ir->owned_names.data[i]);
|
||||
vec_free(ast2ir->owned_names);
|
||||
vec_free(ast2ir->gdata_ref);
|
||||
spl_ir_drop(&ast2ir->ir);
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* 全局数据(聚合类型下 / 顶层<E9A1B6>?var、const<73>?
|
||||
* ================================================================ */
|
||||
|
||||
/* 常量折叠:仅支持字面量(int/char/float/string/null)与一元负<E58583>?*/
|
||||
typedef struct {
|
||||
int const_init;
|
||||
isize int_v;
|
||||
double float_v;
|
||||
const char *cstr_v;
|
||||
} gfold_t;
|
||||
|
||||
static void fold_const_init(spl_ast2ir_t *a, spl_ast_node_ref_t ref, gfold_t *g) {
|
||||
spl_ast_node_t *n = node_at(a->sema, ref);
|
||||
if (!n || n->kind != SPL_AST_EXPR)
|
||||
return;
|
||||
if (n->expr.op == SPL_AST_PRIMARY_EXPR) {
|
||||
spl_ast_node_t *pn = node_at(a->sema, n->expr.op_expr.left);
|
||||
if (!pn)
|
||||
return;
|
||||
switch (pn->primary_expr.kind) {
|
||||
case SPL_AST_INTEGER:
|
||||
g->const_init = 1;
|
||||
g->int_v = pn->primary_expr.integer_expr;
|
||||
return;
|
||||
case SPL_AST_CHAR_LIT:
|
||||
g->const_init = 1;
|
||||
g->int_v = (isize)(unsigned char)pn->primary_expr.char_lit_expr;
|
||||
return;
|
||||
case SPL_AST_FLOAT:
|
||||
g->const_init = 1;
|
||||
g->float_v = pn->primary_expr.float_expr;
|
||||
return;
|
||||
case SPL_AST_NULL:
|
||||
g->const_init = 1;
|
||||
g->int_v = 0;
|
||||
return;
|
||||
case SPL_AST_STRING_LIT:
|
||||
g->const_init = 1;
|
||||
g->cstr_v = pn->primary_expr.string_lit_expr;
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (n->expr.op == SPL_AST_PREFIX_EXPR) {
|
||||
spl_ast_node_t *pp = node_at(a->sema, n->expr.op_expr.left);
|
||||
if (pp && pp->prefix_expr.kind == SPL_AST_MINUS_EXPR) {
|
||||
fold_const_init(a, pp->prefix_expr.postfix_expr, g);
|
||||
if (g->const_init)
|
||||
g->int_v = -g->int_v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void collect_gdata_list(spl_ast2ir_t *a, spl_ast_node_ref_vec_t *members) {
|
||||
for (usize i = 0; i < members->size; i++) {
|
||||
spl_ast_node_t *m = node_at(a->sema, members->data[i]);
|
||||
if (!m)
|
||||
continue;
|
||||
const char *mname = NULL;
|
||||
spl_ast_node_ref_t iexpr = 0;
|
||||
if (m->kind == SPL_AST_VAR_DECL) {
|
||||
mname = m->var_decl.name;
|
||||
iexpr = m->var_decl.expr;
|
||||
} else if (m->kind == SPL_AST_CONST_DECL) {
|
||||
mname = m->const_decl.name;
|
||||
iexpr = m->const_decl.expr;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
if (!mname || !m->resolved_def_id)
|
||||
continue;
|
||||
spl_def_node_t *d = def_at(a->sema, m->resolved_def_id);
|
||||
if (!d)
|
||||
continue;
|
||||
gfold_t g;
|
||||
memset(&g, 0, sizeof g);
|
||||
spl_type_id_t g_tid = d->type_id;
|
||||
if (iexpr)
|
||||
fold_const_init(a, iexpr, &g);
|
||||
/* 全局 value = type.const 节点(标量折叠值;聚合/无 init 零) */
|
||||
spl_ir_node_t v;
|
||||
memset(&v, 0, sizeof v);
|
||||
v.kind = SPL_IR_TYPE_CONST;
|
||||
v.type_const.tid = g_tid;
|
||||
spl_type_node_t *gt = tn(a->sema, underlying(a->sema, g_tid));
|
||||
if (g.const_init && gt && gt->kind == SPL_TYPE_INT)
|
||||
v.type_const.int_lit = (usize)g.int_v;
|
||||
else if (g.const_init && gt && gt->kind == SPL_TYPE_FLOAT)
|
||||
v.type_const.float_lit = g.float_v;
|
||||
else
|
||||
v.type_const.int_lit = 0;
|
||||
vec_push(a->ir.gdata, v);
|
||||
spl_ast2ir_gref_t gr = {m->resolved_def_id, a->ir.gdata.size - 1};
|
||||
vec_push(a->gdata_ref, gr);
|
||||
}
|
||||
}
|
||||
|
||||
static void collect_gdata(spl_ast2ir_t *a) {
|
||||
spl_ast_node_t *root = node_at(a->sema, a->sema->ast->root);
|
||||
if (!root || root->kind != SPL_AST_CONTAINER_ITEM)
|
||||
return;
|
||||
collect_gdata_list(a, &root->container_item.members);
|
||||
for (usize i = 0; i < root->container_item.members.size; i++) {
|
||||
spl_ast_node_ref_t mref = root->container_item.members.data[i];
|
||||
spl_ast_node_t *m = node_at(a->sema, mref);
|
||||
if (!m || m->kind != SPL_AST_TYPE_DECL)
|
||||
continue;
|
||||
spl_ast_node_t *te = node_at(a->sema, m->type_decl.type_expr);
|
||||
if (!te ||
|
||||
(te->type_expr.kind != SPL_AST_TYPE_STRUCT &&
|
||||
te->type_expr.kind != SPL_AST_TYPE_UNION && te->type_expr.kind != SPL_AST_TYPE_ENUM))
|
||||
continue;
|
||||
collect_gdata_list(a, &te->type_expr.aggregate_list);
|
||||
}
|
||||
}
|
||||
|
||||
/* def_id <20>?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)
|
||||
return (isize)a->gdata_ref.data[i].gdata_idx;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* 预登记:为所有函数(顶层 + 聚合方法)建 IR func
|
||||
* ================================================================ */
|
||||
@@ -2838,6 +3056,8 @@ void spl_ast2ir_run(spl_ast2ir_t *a) {
|
||||
spl_ast_node_t *root = node_at(a->sema, a->sema->ast->root);
|
||||
if (!root || root->kind != SPL_AST_CONTAINER_ITEM)
|
||||
return;
|
||||
vec_init(a->gdata_ref);
|
||||
collect_gdata(a);
|
||||
register_funcs(a);
|
||||
for (usize i = 0; i < root->container_item.members.size; i++) {
|
||||
spl_ast_node_ref_t mref = root->container_item.members.data[i];
|
||||
|
||||
Reference in New Issue
Block a user