feat(stdlib/S1.1): DeclId for every declaration — additive DeclTable [additive]

Build a DeclTable in parallel with the import facts: every RawDeclRef
(source / imported / namespaced / C-imported) gets a stable DeclId carrying
source path, display name, AST node identity, span, and DeclKind. Namespace
targets record their members' DeclIds (NamespaceTarget.member_ids). A generic
struct's template is keyed by DeclId in a parallel struct_template_by_decl
store, written alongside the live name-keyed struct_template_map.

A Debug-only round-trip cross-check (RawDeclRef -> DeclId -> AST node ptr)
asserts the table identifies the same node across the corpus, run from
buildDeclTable and pinned by a unit test.

Additive (S0.1 class: mirror): the old maps stay active and lowering still
consumes them; nothing reads the DeclTable / struct_template_by_decl for
selection yet (the S4 cutover does). Generated IR + output bytes are unchanged
by construction.

Gate over the baseline-green corpus: zig build, zig build test (424/424),
bash tests/run_examples.sh (540 passed) — all exit 0; single-author output
byte-identical (37 .ir snapshots unchanged).
This commit is contained in:
agra
2026-06-09 11:25:04 +03:00
parent 864a14e42b
commit 8058be2538
5 changed files with 348 additions and 1 deletions

View File

@@ -628,6 +628,10 @@ pub const ProgramIndex = struct {
/// `imports.buildImportFacts`, carrying each alias's resolved target path.
/// Borrowed view.
namespace_edges: ?*imports.NamespaceEdges = null,
/// Stable `DeclId` for every declaration, built by `imports.buildDeclTable`
/// in parallel with the import facts. Borrowed view; nothing in lowering
/// consumes it for selection yet (additive — S4 makes it the fact-store key).
decl_table: ?*imports.DeclTable = null,
// ── Declaration maps ──
/// Function name → AST decl.
@@ -649,6 +653,11 @@ pub const ProgramIndex = struct {
type_alias_map: std.StringHashMap(TypeId) = std.StringHashMap(TypeId).init(std.heap.page_allocator),
/// Generic struct name → template.
struct_template_map: std.StringHashMap(StructTemplate) = std.StringHashMap(StructTemplate).init(std.heap.page_allocator),
/// `DeclId` → generic struct template — the DeclId-keyed analogue of
/// `struct_template_map`, built in parallel during `registerStructDecl`.
/// Nothing reads it for selection yet; `struct_template_map` stays the live
/// consumer until the S4 cutover.
struct_template_by_decl: std.AutoHashMap(imports.DeclId, StructTemplate) = std.AutoHashMap(imports.DeclId, StructTemplate).init(std.heap.page_allocator),
/// Protocol name → protocol info.
protocol_decl_map: std.StringHashMap(ProtocolDeclInfo) = std.StringHashMap(ProtocolDeclInfo).init(std.heap.page_allocator),
/// Protocol name → AST node.
@@ -687,7 +696,7 @@ pub const ProgramIndex = struct {
pub fn deinit(self: *ProgramIndex) void {
// Owned maps only — module_scopes / import_graph / flat_import_graph /
// module_fns / module_decls / namespace_edges are borrowed.
// module_fns / module_decls / namespace_edges / decl_table are borrowed.
self.import_flags.deinit();
self.fn_ast_map.deinit();
self.qualified_fn_source.deinit();
@@ -695,6 +704,7 @@ pub const ProgramIndex = struct {
self.global_names.deinit();
self.type_alias_map.deinit();
self.struct_template_map.deinit();
self.struct_template_by_decl.deinit();
self.protocol_decl_map.deinit();
self.protocol_ast_map.deinit();
self.module_const_map.deinit();