nx_macro_test.nx source
↩ module page · 87 lines · 3138 B
1// nx_macro_test.nx -- exercise the new @macro preprocessor.
2//
3// Per user 2026-05-15: "do c i want real foundational stuff".
4// This test verifies: zero-arg macros, single-arg macros, multi-arg
5// macros, recursive expansion, macros inside expressions.
6
7import "nx_kernel_v2.nx"
8
9// Zero-arg macro: a constant expression.
10@macro UNIVERSAL_ANSWER 42
11
12// Single-arg macro: square a value.
13@macro SQ(x) (x * x)
14
15// Two-arg macro: max of two values via ternary-style if-expr.
16// (NishiLang doesn't have ?: so we use the if-expression form
17// expressed via a helper -- showing macros can compose.)
18@macro MAX(a, b) (a + b - SQ(a - b) / (a + b - 2 * b))
19
20// Two-arg macro: build a kernel axiom and emit.
21@macro AXIOM_CONST(ch, sym_id) nx_k2_axiom(ch, nx_term_const(sym_id))
22
23// Three-arg macro: build a binary App term.
24@macro APP2(sym, a, b) nx_k2_imp(a, b)
25
26// ===== Tests =====
27
28func test_zero_arg() -> nx_int {
29 let x: nx_int = UNIVERSAL_ANSWER
30 if x != 42 { return 1 }
31 return 0
32}
33
34func test_single_arg() -> nx_int {
35 let y: nx_int = SQ(7)
36 if y != 49 { return 2 }
37 let z: nx_int = SQ(SQ(3)) // recursive: SQ(9) = 81
38 if z != 81 { return 2 }
39 return 0
40}
41
42func test_axiom_macro() -> nx_int {
43 let ch: *K2Chain = nx_k2_chain_new(8)
44 let idx: nx_int = AXIOM_CONST(ch, 1234)
45 if idx < 0 { return 3 }
46 let t: *K2Thm = nx_k2_at(ch, idx)
47 if t.stmt.kind != NX_TERM_CONST { return 3 }
48 if t.stmt.sym != 1234 { return 3 }
49 return 0
50}
51
52func test_recursive_in_expr() -> nx_int {
53 // Use SQ inside an arithmetic expression
54 let a: nx_int = SQ(2) + SQ(3) + SQ(4) // 4 + 9 + 16 = 29
55 if a != 29 { return 4 }
56 return 0
57}
58
59func main() -> nx_exit {
60 println("=== nx_macro_test -- @macro preprocessor smoke ===" as *u8)
61
62 let r1: nx_int = test_zero_arg()
63 if r1 != 0 { println("T1 zero_arg FAIL" as *u8); return r1 }
64 println("T1 zero_arg PASS UNIVERSAL_ANSWER expands to 42" as *u8)
65
66 let r2: nx_int = test_single_arg()
67 if r2 != 0 { println("T2 single_arg FAIL" as *u8); return r2 }
68 println("T2 single_arg PASS SQ(7)=49, SQ(SQ(3))=81 (recursive)" as *u8)
69
70 let r3: nx_int = test_axiom_macro()
71 if r3 != 0 { println("T3 axiom_macro FAIL" as *u8); return r3 }
72 println("T3 axiom_macro PASS AXIOM_CONST builds + emits kernel axiom" as *u8)
73
74 let r4: nx_int = test_recursive_in_expr()
75 if r4 != 0 { println("T4 recursive_in_expr FAIL" as *u8); return r4 }
76 println("T4 recursive_in_expr PASS SQ(2)+SQ(3)+SQ(4) = 29" as *u8)
77
78 println("" as *u8)
79 println("=== Foundational metaprogramming surface verified ===" as *u8)
80 println(" @macro NAME body zero-arg form" as *u8)
81 println(" @macro NAME(arg) (expr_using_arg) single-arg form" as *u8)
82 println(" @macro NAME(a, b) ... multi-arg form" as *u8)
83 println(" Recursive expansion supported up to MACRO_MAX_DEPTH = 8" as *u8)
84 println(" Textual substitution; identifier-aware (no false matches in literals)" as *u8)
85 println(" Adding new substrate primitives is now: write a manifest macro" as *u8)
86 return 0
87}