code wiki / (root) / nx_bills_store_gate.nx

nx_bills_store_gate.nx source

↩ module page · 83 lines · 4147 B

1// nx_bills_store_gate.nx -- proves the per-respondent BILL STORE: add bills -> they persist + round-trip, 2// they feed the nx_bills engine (overdue / monthly-total / per-category), and two people are isolated. 3// Hermetic /tmp prefix. Exits 0 iff ALL pass. license_tier: ORIGINAL 4import "nx_syscalls.nx" 5import "nx_money.nx" 6import "nx_bills.nx" 7import "nx_bills_store.nx" 8 9func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 10func g_putn(v: i64) -> i64 { 11 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 12 var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 13 let d: *u8 = sys_mmap(24); var k: i64 = 0 14 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 15 var j: i64 = k - 1 16 while j >= 0 { sys_write(1, ((d as i64)+j) as *u8, 1); j = j - 1 } 17 return 0 18} 19func chk(name: *u8, got: i64, want: i64, st: *i64) -> i64 { 20 if got == want { st[0] = st[0] + 1; g_puts(" PASS "); g_puts(name); g_puts("\n") } 21 else { st[1] = st[1] + 1; g_puts(" FAIL "); g_puts(name); g_puts(" got="); g_putn(got); g_puts(" want="); g_putn(want); g_puts("\n") } 22 return 0 23} 24 25func main() -> i64 { 26 let st: *i64 = sys_mmap(16) as *i64 27 st[0] = 0; st[1] = 0 28 29 // hermetic prefix "/tmp/bills_<us>-" 30 let pfx: *u8 = sys_mmap(64) 31 var pp: i64 = 0 32 let pre: *u8 = "/tmp/bills_\x00" as *u8 33 while pre[pp] != (0 as u8) { pfx[pp] = pre[pp]; pp = pp + 1 } 34 let us: i64 = sys_now_us() 35 let tmp: *u8 = sys_mmap(32); var m: i64 = us; var kk: i64 = 0 36 if m == 0 { tmp[0] = 0x30 as u8; kk = 1 } 37 while m > 0 { tmp[kk] = (0x30 + (m % 10)) as u8; m = m / 10; kk = kk + 1 } 38 var z: i64 = kk - 1 39 while z >= 0 { pfx[pp] = tmp[z]; pp = pp + 1; z = z - 1 } 40 pfx[pp] = 0x2d as u8; pp = pp + 1; pfx[pp] = 0 as u8 41 42 let who: *u8 = "operator\x00" as *u8 43 44 // fresh: no bills 45 chk("fresh respondent -> 0 bills", bs_count(pfx, who), 0, st) 46 47 // add 3 real bills: insurance $1800/6mo due-15 unpaid; mortgage $2000/mo due-1 paid; utility $50/mo due-10 unpaid 48 chk("add insurance bill", bs_add(pfx, who, 180000, 6, 15, BL_INSURANCE, 0), 0, st) 49 chk("add mortgage bill", bs_add(pfx, who, 200000, 1, 1, BL_HOUSING, 1), 0, st) 50 chk("add utility bill", bs_add(pfx, who, 5000, 1, 10, BL_UTILITY, 0), 0, st) 51 chk("now 3 bills (persisted across reads)", bs_count(pfx, who), 3, st) 52 53 // load them back into the engine arrays 54 let amt: *i64 = sys_mmap(8 * 64) as *i64 55 let cad: *i64 = sys_mmap(8 * 64) as *i64 56 let due: *i64 = sys_mmap(8 * 64) as *i64 57 let cat: *i64 = sys_mmap(8 * 64) as *i64 58 let paid: *i64 = sys_mmap(8 * 64) as *i64 59 let n: i64 = bs_load(pfx, who, amt, cad, due, cat, paid, 64) 60 chk("load returns 3", n, 3, st) 61 // field round-trip (bill 0 = the insurance bill) 62 chk("bill0 amount = 180000c ($1800)", amt[0], 180000, st) 63 chk("bill0 cadence = 6 (semiannual)", cad[0], 6, st) 64 chk("bill0 due_day = 15", due[0], 15, st) 65 chk("bill0 category = INSURANCE", cat[0], BL_INSURANCE, st) 66 chk("bill0 paid = 0 (unpaid)", paid[0], 0, st) 67 chk("bill2 amount = 5000c ($50, the utility)", amt[2], 5000, st) 68 69 // the store FEEDS the engine: overdue today=20 -> insurance(15,unpaid) + utility(10,unpaid) = 2 (mortgage paid) 70 let oidx: *i64 = sys_mmap(8 * 64) as *i64 71 chk("engine overdue(today=20) over the REAL bills = 2", bl_overdue(due, paid, 20, n, oidx), 2, st) 72 // monthly total: $300 (insurance/6) + $2000 (mortgage) + $50 (utility) = $2350 73 chk("engine monthly total = 235000c ($2350)", bl_monthly_total(amt, cad, n), 235000, st) 74 chk("engine insurance monthly = 30000c ($300)", bl_category_monthly(amt, cad, cat, n, BL_INSURANCE), 30000, st) 75 76 // a different respondent is isolated (per-user) 77 chk("different respondent -> 0 bills (isolated)", bs_count(pfx, "someone_else\x00" as *u8), 0, st) 78 79 g_puts("nx_bills_store_gate: PASS="); g_putn(st[0]); g_puts(" FAIL="); g_putn(st[1]); g_puts("\n") 80 if st[1] == 0 { g_puts("SITUATION BILL-STORE: GREEN\n"); return 0 } 81 g_puts("SITUATION BILL-STORE: RED\n") 82 return 1 83}