code wiki / (root) / nx_decl_base.nx

nx_decl_base.nx source

↩ module page · 118 lines · 4249 B

1// nx_decl_base.nx -- shared base struct for the #tag declarator family. 2// 3// license_tier: ORIGINAL 4// 5// Object-oriented composition discipline: every `nx_decl_*` primitive 6// shares a HEADER struct (seed, modifier, is_valid) that's validated 7// + initialized centrally. Derived types compose by EMBEDDING (as the 8// first pointer field) and delegating the header validate to this 9// module. 10// 11// Today's `nx_decl_*` family duplicates the same validation 5 times 12// (random_environment, simple_scene, combat_arena, dungeon_floor, 13// townscape). This file centralizes that into ONE base. Migration 14// is additive: existing declarators keep their current shape; new 15// declarators can compose via `NxDeclBase` and `nx_decl_base_init`. 16// 17// Pattern (OO in substrate-procedural style): 18// 19// struct NxFooDecl { 20// base: *NxDeclBase, // pointer to shared header 21// foo_specific_a: nx_int, 22// foo_specific_b: nx_int, 23// } 24// 25// func nx_decl_foo(out: *NxFooDecl, modifier: nx_int, seed: nx_int) -> nx_int { 26// let base: *NxDeclBase = nx_decl_base_alloc() 27// let ok: nx_int = nx_decl_base_init(base, modifier, seed) 28// if ok == 0 { return 0 } 29// out.base = base 30// // ... fill foo-specific fields ... 31// return 1 32// } 33// 34// Then `out.base.is_valid`, `out.base.modifier`, `out.base.seed` are 35// uniform across the family. Inheritance discipline: substrate- 36// procedural has no method dispatch, but composition + a shared 37// init/validate is the practical equivalent. 38// 39// Per cardinals: 40// - DRY-through-shared-libraries: 5 copies of the same validate 41// collapse to one. 42// - Build-the-engine-not-instances: this IS the engine for the 43// #tag family. 44 45// nx_safety_envelope: 46// intended_use: AUTO_APPLIED -- primitive-specific tuning queued 47// sil_target: SIL1 48// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail] 49// verdict: NOT_YET_EVALUATED 50 51import "nx_syscalls.nx" 52import "nx_types.nx" 53import "nx_tier.nx" 54const NX_MAGIC_2654435761: i64 = 2654435761 55const NX_MAGIC_374761393: i64 = 374761393 56 57// ---- The shared header struct ----------------------------------- 58struct NxDeclBase { 59 seed: nx_int, 60 modifier: nx_int, 61 is_valid: nx_int, 62} 63 64// ---- The modifier enum (single source of truth) ----------------- 65// Lifted from nx_decl_random_environment.nx so every declarator 66// references the SAME constants -- no per-file definitions. 67const NX_DECL_MOD_REAL: nx_int = 0 68const NX_DECL_MOD_FANTASY: nx_int = 1 69const NX_DECL_MOD_SCI_FI: nx_int = 2 70const NX_DECL_MOD_N: nx_int = 3 71 72func nx_decl_mod_is_valid(m: nx_int) -> nx_int { 73 if m < 0 { return 0 } 74 if m >= NX_DECL_MOD_N { return 0 } 75 return 1 76} 77 78// Elm-style reflection. 79func nx_decl_mod_name(m: nx_int) -> *u8 { 80 if m == NX_DECL_MOD_REAL { return "REAL" as *u8 } 81 if m == NX_DECL_MOD_FANTASY { return "FANTASY" as *u8 } 82 if m == NX_DECL_MOD_SCI_FI { return "SCI_FI" as *u8 } 83 return "<invalid modifier>" as *u8 84} 85 86// ---- Centralized init/validate ---------------------------------- 87// 88// Returns 1 on success (base populated), 0 on invalid modifier (base 89// has is_valid=0 and is otherwise undefined). Caller checks the 90// return value OR base.is_valid -- they say the same thing. 91func nx_decl_base_init(base: *NxDeclBase, modifier: nx_int, seed: nx_int) -> nx_int { 92 if nx_decl_mod_is_valid(modifier) == 0 { 93 base.is_valid = 0 94 return 0 95 } 96 base.seed = seed 97 base.modifier = modifier 98 base.is_valid = 1 99 return 1 100} 101 102// Allocator for callers that prefer composition-by-pointer. 103func nx_decl_base_alloc() -> *NxDeclBase { 104 let raw: *u8 = sys_mmap(48) 105 let b: *NxDeclBase = raw as *NxDeclBase 106 return b 107} 108 109// ---- Shared seed-mixing helper (Knuth multiplicative hash mod N) - 110// 111// Every declarator uses this for deterministic per-field salting. 112// Single source of truth so future hash-algorithm swaps are one edit. 113func nx_decl_hash_mod(seed: nx_int, salt: nx_int, modulus: nx_int) -> nx_int { 114 let mixed: nx_int = seed * NX_MAGIC_2654435761 + salt * NX_MAGIC_374761393 115 var v: nx_int = mixed % modulus 116 if v < 0 { v = 0 - v } 117 return v 118}