stage1 初步实现
This commit is contained in:
@@ -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 为假 → trap(HALT) */
|
||||
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>?payload,field_tid = 变体具体类型 */
|
||||
/* enum 布局 = tag(0) + payload(8):直接提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);
|
||||
@@ -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_tid(spl_type_fn 不去重,fn_tid 唯一<EFBFBD>?*/
|
||||
/* 懒扫描:IR func 已记fn_tid(spl_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)
|
||||
|
||||
Reference in New Issue
Block a user