stage2 修复全局变量未完成的问题 提供错误处理解析

This commit is contained in:
zzy committed 2026-09-25 13:46:07 +08:00
1 parent c0a86ea552
commit 0b8f649818
11 files changed
+317 -18

No files matched your search

+78
View File
@@ -44,6 +44,7 @@ sema: *Sema,
ir: *IrBuilder,
ast: *Ast,
def2ir_map: Map,
glob_gidx: Map, // def_id -> gidx+1(全局变量)
loop_stack: Vec, // LoopCtx
defer_stack: Vec, // ast node ref
cur_ret_lang: usize,
@@ -105,6 +106,62 @@ fn ir_map_put(self: *Ast2Ir, def_id: usize, val: usize) {
match Map.put(&self.def2ir_map, &def_id as *u8, &val as *u8) { .Ok => {}, .Err(e) => {} }
}
fn glob_get(self: *Ast2Ir, def_id: usize, out: *usize): bool {
match Map.get(&self.glob_gidx, &def_id as *u8, out as *u8) {
.Found => { ret true; },
.NotFound => { ret false; },
}
ret false;
}
fn glob_put(self: *Ast2Ir, def_id: usize, val: usize) {
match Map.put(&self.glob_gidx, &def_id as *u8, &val as *u8) { .Ok => {}, .Err(e) => {} }
}
// 顶层 var/const → 模块全局(alloc 于静态存储;引用是 *T 指针常量)。
fn emit_global_var(self: *Ast2Ir, d: *Node) {
if d == null || d.resolved_def_id == 0 { ret; }
var def_id = d.resolved_def_id;
var existing: usize = 0;
if glob_get(self, def_id, &existing) { ret; }
var lang = LangType.def_lang_id(&self.sema.types, def_id);
var ir = to_ir_type(self, lang);
if ir == 0 { ret; }
var init_ref: usize = 0;
match d.body {
.VarDecl(x) => { init_ref = x.init_expr; },
.ConstDecl(x) => { init_ref = x.init_expr; },
_ => {},
}
var zero = true;
var bytes = Vec.blank(1, 1);
if init_ref != 0 {
var inode = Ast.node(self.ast, init_ref);
if inode != null {
match inode.body {
.ExprIntLit(bi) => {
var v: u64 = 0;
match BigInt.to_u64(&v, bi.value) { .Ok => {}, .Err(e) => {} }
var bits = LangType.int_bits(&self.sema.types, ir);
var size = bits / 8;
if size != 0 {
zero = false;
var i: usize = 0;
while i < size {
var b = ((v >> (8 * i)) & 255) as u8;
match Vec.push(&bytes, &b as *u8) { .Ok => {}, .Err(e) => {} }
i = i + 1;
}
}
},
_ => {},
}
}
}
var gidx = IrBuilder.add_global(self.ir, ir, zero, bytes);
glob_put(self, def_id, gidx + 1);
}
fn kind_is(self: *Ast2Ir, lang_id: usize, want: LangKind): bool {
var e = ltn(self, lang_id);
if e == null { ret false; }
@@ -608,6 +665,13 @@ fn emit_lvalue(self: *Ast2Ir, ref: usize): usize {
.ExprIdent(x) => {
var d = defn(self, n.resolved_def_id);
if d != null && @enum2int(d.kind) == @enum2int(DefKind.Fn) { ret 0; }
var g: usize = 0;
if glob_get(self, n.resolved_def_id, &g) {
var lang = node_lang(n);
var ir = to_ir_type(self, lang);
var ptr_ir = TypeTable.make_ptr(&self.sema.types.ir, ir);
ret IrBuilder.type_const_global(self.ir, ptr_ir, g - 1);
}
var slot: usize = 0;
if !ir_map_get(self, n.resolved_def_id, &slot) { ret 0; }
ret slot;
@@ -935,6 +999,13 @@ fn emit_ident(self: *Ast2Ir, n: *Node): usize {
if !ir_map_get(self, n.resolved_def_id, &fn_ref) { ret 0; }
ret IrBuilder.type_const_fn(self.ir, node_ir(self, n), fn_ref);
}
var g: usize = 0;
if glob_get(self, n.resolved_def_id, &g) {
var ir = node_ir(self, n);
var ptr_ir = TypeTable.make_ptr(&self.sema.types.ir, ir);
var ptr = IrBuilder.type_const_global(self.ir, ptr_ir, g - 1);
ret IrBuilder.mem_load(self.ir, ir, ptr);
}
var slot: usize = 0;
if !ir_map_get(self, n.resolved_def_id, &slot) { ret 0; }
ret IrBuilder.mem_load(self.ir, node_ir(self, n), slot);
@@ -1961,6 +2032,8 @@ fn emit_container_reserve(self: *Ast2Ir, ref: usize) {
}
},
.TopLevelBlock(x) => { emit_container_reserve(self, dref); },
.VarDecl(_) => { emit_global_var(self, d); },
.ConstDecl(_) => { emit_global_var(self, d); },
_ => {},
}
}
@@ -1997,6 +2070,8 @@ fn emit_container_body(self: *Ast2Ir, ref: usize) {
}
},
.TopLevelBlock(x) => { emit_container_body(self, dref); },
.VarDecl(_) => {},
.ConstDecl(_) => {},
_ => {},
}
}
@@ -2070,6 +2145,8 @@ fn new(builder: *IrBuilder, sema: *Sema, diag: *Diag): Ast2Ir {
.ast = sema.ast,
.def2ir_map = Map.new(@sizeof(usize), @alignof(usize), @sizeof(usize), @alignof(usize),
hash_kind_usize()),
.glob_gidx = Map.new(@sizeof(usize), @alignof(usize), @sizeof(usize), @alignof(usize),
hash_kind_usize()),
.loop_stack = Vec.blank(@sizeof(LoopCtx), @alignof(LoopCtx)),
.defer_stack = Vec.blank(@sizeof(usize), @alignof(usize)),
.cur_ret_lang = 0,
@@ -2089,6 +2166,7 @@ fn drop(self: *Ast2Ir) {
Vec.drop(&self.loop_stack);
Vec.drop(&self.defer_stack);
Map.drop(&self.def2ir_map);
Map.drop(&self.glob_gidx);
var k: usize = 0;
while k < self.owned.len {
match Vec.get(&self.owned, k) {