{"name":"chaotic-showcase.nu","source":"// ============================================================\n// chaotic-showcase.nu — an ADVERSARIAL grammar stress test.\n//\n// Purpose (pre-1.0 grammar lock): the existing example/stdlib corpus is\n// broad but structurally narrow — systems/byte-codec code, cellular\n// automata, emulators, agents. None of it pushes three corners of the\n// language at once. This single file deliberately combines all three to\n// see whether Grammar v2.2 is genuinely complete or whether something\n// needs to change before the v1.0 lock:\n//\n//   (A) FLOAT / VECTOR prefix-arithmetic DENSITY — deeply nested\n//       prefix `+ * - / .` over a Vec3 type. This is the worst case for\n//       fixed prefix arity with no closing token (the open A3 question).\n//   (B) DEEP RECURSIVE ADT + multi-payload PATTERN MATCHING — a symbolic\n//       expression tree (`Expr`) with `*Expr` children, differentiated\n//       and simplified by recursive `??` match. No recursive enum exists\n//       anywhere else in the tree.\n//   (C) HIGHER-ORDER PARSER COMBINATORS — a parser is a closure\n//       `(@ ?*Expr *PState)`; `p_chainl` RETURNS a closure that CAPTURES\n//       two other closures + a scalar. Closures-capturing-closures is the\n//       hardest case for type-dependent capture + escape analysis.\n//\n// The pipeline: parse a formula string into an Expr tree (C), symbolically\n// differentiate + simplify it (B), then evaluate both over Vec3 math (A).\n// ============================================================\n\n$ `stdlib/core/string.nu`\n$ `stdlib/core/mem.nu`\n$ `stdlib/std/float.nu`\n\n// ── Axis A: Vec3 + dense prefix float arithmetic ────────────────────\n\n: Vec3 { f x f y f z }\n\n@ v3 f x f y f z → Vec3 { ^ @ Vec3 { x y z } }\n\n@ v3_add Vec3 a Vec3 b → Vec3 {\n    ^ @ Vec3 { + . a x . b x + . a y . b y + . a z . b z }\n}\n\n@ v3_scale Vec3 a f s → Vec3 {\n    ^ @ Vec3 { * . a x s * . a y s * . a z s }\n}\n\n@ v3_dot Vec3 a Vec3 b → f {\n    // + (+ (ax*bx) (ay*by)) (az*bz) — fully nested, no grouping tokens.\n    ^ + + * . a x . b x * . a y . b y * . a z . b z\n}\n\n@ v3_cross Vec3 a Vec3 b → Vec3 {\n    ^ @ Vec3 {\n        - * . a y . b z * . a z . b y\n        - * . a z . b x * . a x . b z\n        - * . a x . b y * . a y . b x\n    }\n}\n\n@ v3_len Vec3 a → f { ^ ( float_sqrt ( v3_dot a a ) ) }\n\n@ v3_norm Vec3 a → Vec3 { : f l ( v3_len a ) ^ ( v3_scale a / 1.0 l ) }\n\n// ── Axis B: a recursive symbolic-expression ADT ─────────────────────\n//\n// Children are boxed as `*Expr` (raw pointer payloads). This is the only\n// recursive enum in the codebase.\n\n: | Expr {\n    Num f\n    Var\n    Add * Expr * Expr\n    Mul * Expr * Expr\n    Neg * Expr\n    Sin * Expr\n    Cos * Expr\n}\n\n@ ebox Expr e → *Expr {\n    : *Expr p ( alloc [Expr] 1 )\n    = . p 0 e\n    ^ p\n}\n\n@ e_num f x → *Expr { ^ ( ebox @ Expr { Num x } ) }\n\n@ e_var → *Expr { ^ ( ebox @ Expr { Var } ) }\n\n@ e_add * Expr a * Expr b → *Expr { ^ ( ebox @ Expr { Add a b } ) }\n\n@ e_mul * Expr a * Expr b → *Expr { ^ ( ebox @ Expr { Mul a b } ) }\n\n@ e_neg * Expr a → *Expr { ^ ( ebox @ Expr { Neg a } ) }\n\n@ e_sin * Expr a → *Expr { ^ ( ebox @ Expr { Sin a } ) }\n\n@ e_cos * Expr a → *Expr { ^ ( ebox @ Expr { Cos a } ) }\n\n// Evaluate the tree at x = xv. Recursive match with 2-payload binding.\n@ e_eval * Expr p f xv → f {\n    : Expr e . p 0\n    ?? e {\n        Num c → c\n        Var → xv\n        Add a b → + ( e_eval a xv ) ( e_eval b xv )\n        Mul a b → *( e_eval a xv ) ( e_eval b xv )\n        Neg a → - 0.0 ( e_eval a xv )\n        Sin a → ( float_sin ( e_eval a xv ) )\n        Cos a → ( float_cos ( e_eval a xv ) )\n    }\n}\n\n// Symbolic differentiation d/dx — the autodiff core. Each arm rebuilds a\n// fresh subtree from the recursive results.\n@ e_diff * Expr p → *Expr {\n    : Expr e . p 0\n    ?? e {\n        Num c → ( e_num 0.0 )\n        Var → ( e_num 1.0 )\n        Add a b → ( e_add ( e_diff a ) ( e_diff b ) )\n        Mul a b → ( e_add ( e_mul ( e_diff a ) b ) ( e_mul a ( e_diff b ) ) )\n        Neg a → ( e_neg ( e_diff a ) )\n        Sin a → ( e_mul ( e_cos a ) ( e_diff a ) )\n        Cos a → ( e_neg ( e_mul ( e_sin a ) ( e_diff a ) ) )\n    }\n}\n\n// Constant-folding + identity simplification. Nested `??` inside arms —\n// pattern-matching depth stress.\n@ e_simplify * Expr p → *Expr {\n    : Expr e . p 0\n    ?? e {\n        Add a b → {\n            : *Expr sa ( e_simplify a )\n            : *Expr sb ( e_simplify b )\n            : Expr ea . sa 0\n            : Expr eb . sb 0\n            ?? ea {\n                Num x → ?? eb {\n                    Num y → ( e_num + x y )\n                    _ → ( e_add sa sb )\n                }\n                _ → ( e_add sa sb )\n            }\n        }\n        Mul a b → {\n            : *Expr sa ( e_simplify a )\n            : *Expr sb ( e_simplify b )\n            : Expr ea . sa 0\n            : Expr eb . sb 0\n            ?? ea {\n                Num x → ?? eb {\n                    Num y → ( e_num * x y )\n                    _ → ( e_mul sa sb )\n                }\n                _ → ( e_mul sa sb )\n            }\n        }\n        _ → ( ebox e )\n    }\n}\n\n// ── Axis C: parser combinators (closures returning closures) ────────\n\n: PState { s text i len i pos }\n\n@ ps_new s input → *PState {\n    : *PState ps ( alloc [PState] 1 )\n    = . ps text input\n    = . ps len ( nurl_str_len input )\n    = . ps pos 0\n    ^ ps\n}\n\n@ p_peek * PState ps i ch → b {\n    ? >= . ps pos . ps len { ^ F } {}\n    ^ == ( nurl_str_get . ps text . ps pos ) ch\n}\n\n@ p_advance * PState ps → v { = . ps pos + . ps pos 1 }\n\n@ p_skip_ws * PState ps → v { ~ ( p_peek ps 32 ) { ( p_advance ps ) } }\n\n@ p_digit * PState ps → b {\n    ? >= . ps pos . ps len { ^ F } {}\n    : i c ( nurl_str_get . ps text . ps pos )\n    ^ & >= c 48 <= c 57\n}\n\n@ p_number * PState ps → ?*Expr {\n    : ~ f val 0.0\n    : ~ i any 0\n    ~ ( p_digit ps ) {\n        : i d - ( nurl_str_get . ps text . ps pos ) 48\n        = val + * val 10.0 # f d\n        ( p_advance ps )\n        = any 1\n    }\n    ? == any 0 { ^ @ ?*Expr { F } } {}\n    ? ( p_peek ps 46 ) {\n        ( p_advance ps )\n        : ~ f scale 0.1\n        ~ ( p_digit ps ) {\n            : i d - ( nurl_str_get . ps text . ps pos ) 48\n            = val + val * scale # f d\n            = scale * scale 0.1\n            ( p_advance ps )\n        }\n    } {}\n    ^ @ ?*Expr { T ( e_num val ) }\n}\n\n// atom := 'x' | number | '(' expr ')' | '-' atom | 's' atom | 'c' atom\n@ p_atom * PState ps → ?*Expr {\n    ( p_skip_ws ps )\n    ? ( p_peek ps 120 ) { ( p_advance ps ) ^ @ ?*Expr { T ( e_var ) } } {}\n    ? ( p_peek ps 40 ) {\n        ( p_advance ps )\n        : ?*Expr inner ( p_expr ps )\n        ( p_skip_ws ps )\n        ? ( p_peek ps 41 ) { ( p_advance ps ) } {}\n        ^ inner\n    } {}\n    ? ( p_peek ps 45 ) {\n        ( p_advance ps )\n        : ?*Expr a ( p_atom ps )\n        ^ ?? a { T e → @ ?*Expr { T ( e_neg e ) } F → @ ?*Expr { F } }\n    } {}\n    ? ( p_peek ps 115 ) {\n        ( p_advance ps )\n        : ?*Expr a ( p_atom ps )\n        ^ ?? a { T e → @ ?*Expr { T ( e_sin e ) } F → @ ?*Expr { F } }\n    } {}\n    ? ( p_peek ps 99 ) {\n        ( p_advance ps )\n        : ?*Expr a ( p_atom ps )\n        ^ ?? a { T e → @ ?*Expr { T ( e_cos e ) } F → @ ?*Expr { F } }\n    } {}\n    ^ ( p_number ps )\n}\n\n// The combinator: left-associative chain of `sub` separated by `opch`,\n// folded with `build`. RETURNS a closure that CAPTURES sub, opch, build.\n@ p_chainl ( @ ?*Expr * PState ) sub i opch ( @ *Expr * Expr * Expr ) build → ( @ ?*Expr * PState ) {\n    ^ \\ * PState ps → ?*Expr {\n        : ?*Expr first ( sub ps )\n        ?? first {\n            F → @ ?*Expr { F }\n            T lhs → {\n                : ~ * Expr acc lhs\n                ( p_skip_ws ps )\n                ~ ( p_peek ps opch ) {\n                    ( p_advance ps )\n                    : ?*Expr r ( sub ps )\n                    ?? r { T rhs → { = acc ( build acc rhs ) } F → {} }\n                    ( p_skip_ws ps )\n                }\n                @ ?*Expr { T acc }\n            }\n        }\n    }\n}\n\n// term := atom (('*') atom)*   — built via the combinator.\n@ p_term * PState ps → ?*Expr {\n    : ( @ ?*Expr * PState ) mulp ( p_chainl\n    \\ * PState s → ?*Expr { ( p_atom s ) }\n    42\n    \\ * Expr a * Expr b → *Expr { ( e_mul a b ) } )\n    ^ ( mulp ps )\n}\n\n// expr := term (('+') term)*   — also via the combinator.\n@ p_expr * PState ps → ?*Expr {\n    : ( @ ?*Expr * PState ) addp ( p_chainl\n    \\ * PState s → ?*Expr { ( p_term s ) }\n    43\n    \\ * Expr a * Expr b → *Expr { ( e_add a b ) } )\n    ^ ( addp ps )\n}\n\n@ pf f x → v { ( nurl_print ( float_to_string x ) ) }\n\n@ main → i {\n    // ── Axis A: dense vector math ──────────────────────────────\n    : Vec3 a ( v3 1.0 2.0 3.0 )\n    : Vec3 b ( v3 4.0 5.0 6.0 )\n    ( nurl_print `dot=` ) ( pf ( v3_dot a b ) ) ( nurl_print `\\n` )\n    ( nurl_print `len=` ) ( pf ( v3_len a ) ) ( nurl_print `\\n` )\n    : Vec3 c ( v3_cross a b )\n    ( nurl_print `cross=` ) ( pf . c x ) ( nurl_print ` ` ) ( pf . c y ) ( nurl_print ` ` ) ( pf . c z ) ( nurl_print `\\n` )\n    : Vec3 d ( v3_add a ( v3_scale b 2.0 ) )\n    ( nurl_print `a+2b.x=` ) ( pf . d x ) ( nurl_print `\\n` )\n\n    // ── Axis C: parse a formula ───────────────────────────────\n    : s formula `x*x + 3.0*x + s(x)`\n    : *PState ps ( ps_new formula )\n    : ?*Expr parsed ( p_expr ps )\n    ?? parsed {\n        F → { ( nurl_print `parse failed\\n` ) ^ 1 }\n        T tree → {\n            // ── Axis B: differentiate + simplify + eval ───────\n            : *Expr dtree ( e_simplify ( e_diff tree ) )\n            ( nurl_print `f(2)=` ) ( pf ( e_eval tree 2.0 ) ) ( nurl_print `\\n` )\n            ( nurl_print `f'(2)=` ) ( pf ( e_eval dtree 2.0 ) ) ( nurl_print `\\n` )\n            ( nurl_print `f(0)=` ) ( pf ( e_eval tree 0.0 ) ) ( nurl_print `\\n` )\n        }\n    }\n    ^ 0\n}\n","bytes":10126}