{"name":"showcase.nu","source":"// ============================================================\n// showcase.nu — NURL language showcase\n// A tiny expression evaluator + utility library\n// Demonstrates: generics, traits, enums, pattern match, closures,\n//               try-operator, defer, slices, foreach, recursion\n// ============================================================\n\n// ── FFI: pull in a few C runtime symbols ─────────────────────\n// Note: puts, malloc, free are auto-declared by the compiler runtime\n\n// ── Constants & globals ──────────────────────────────────────\n: i MAX_DEPTH 32\n: s GREETING `NURL showcase v1\\n`\n: ~ i eval_count 0  // mutable: counts evaluations\n\n// ── Basic generic identity + pair struct ─────────────────────\n@ id [T] T x → T { ^ x }\n\n: Pair {\n    s key\n    i value\n}\n\n@ mk_pair s k i x → Pair {\n    ^ @ Pair { k x }\n}\n\n// ── A trait with a default-ish implementation per type ───────\n% Show {\n    @ show i n → s\n}\n\n% Show i {\n    @ show i n → s { ^ ( nurl_str_int n ) }\n}\n\n% Show b {\n    @ show b x → s { ^ ? x `T` `F` }\n}\n\n// ── Expression AST as a tagged enum ──────────────────────────\n// Ast ::= Num(i)\n//       | Neg(*Ast)\n//       | Bin(i op, *Ast lhs, *Ast rhs)      // op: 0=+ 1=- 2=* 3=/\n: | Ast {\n    Num i\n    Neg * Ast\n    Bin i * Ast * Ast\n}\n\n// ── Heap-allocate an Ast node (tiny helper) ──────────────────\n@ box_ast Ast node → *Ast {\n    : *Ast p # *Ast ( malloc Z Ast )\n    = . p 0 node  // *p = node  (field 0 of the boxed struct)\n    ^ p\n}\n\n// ── Evaluator returning an Option (division-by-zero → None) ──\n@ eval * Ast e → ?i {\n    = eval_count + eval_count 1\n\n    ?? . e 0 {\n        Num n → @ ?i { T n }\n        Neg inner → {\n            : vv \\ ( eval inner )\n            ^ @ ?i { T - 0 vv }\n        }\n        Bin op l r → {\n            : va \\ ( eval l )\n            : vb \\ ( eval r )\n            ? == op 0 @ ?i { T + va vb }\n            ? == op 1 @ ?i { T - va vb }\n            ? == op 2 @ ?i { T * va vb }\n            ? == op 3 {\n                ? == vb 0\n                @ ?i { F 0 }  // None on /0\n                @ ?i { T / va vb }\n            }\n            @ ?i { F 0 }  // unknown op → None\n        }\n    }\n}\n\n// ── Higher-order: map a closure over a slice, returning new slice\n@ map_i [T] [T src ( @ i T ) f → [i {\n    : i n . src length\n    : *i buf # *i ( malloc * n 8 )\n    : ~ i idx 0\n    ~ < idx n {\n        : T item . src idx\n        = . buf idx ( f item )\n        = idx + idx 1\n    }\n    ^ @ [i { buf n }\n}\n\n// ── Recursive factorial (classic) ────────────────────────────\n@ fact i n → i {\n    ? <= n 1 1 * n ( fact - n 1 )\n}\n\n// ── A function we can map over a slice ──────────────────────\n@ bump i x → i { + x 100 }\n\n// ── A demo that wires everything together ───────────────────\n@ run_demo → v {\n    ( puts GREETING )\n\n    // defer: runs on function exit, LIFO\n    ; { ( puts `bye from run_demo\\n` ) }\n\n    // Build:  (3 + 4) * -(10 / 2)    → 7 * -5 = -35\n    : *Ast three ( box_ast @ Ast { Num 3 } )\n    : *Ast four ( box_ast @ Ast { Num 4 } )\n    : *Ast ten ( box_ast @ Ast { Num 10 } )\n    : *Ast two ( box_ast @ Ast { Num 2 } )\n    : *Ast sum ( box_ast @ Ast { Bin 0 three four } )\n    : *Ast div ( box_ast @ Ast { Bin 3 ten two } )\n    : *Ast neg ( box_ast @ Ast { Neg div } )\n    : *Ast root ( box_ast @ Ast { Bin 2 sum neg } )\n\n    : ?i result ( eval root )\n\n    ?? result {\n        _ → ( puts `evaluated\\n` )\n    }\n\n    // Map a function over a slice\n    : [i nums [i | 1 2 3 4 5]\n\n    ~ n nums {\n        ( puts ( show ( bump n ) ) )\n    }\n\n    // Traits dispatching on type\n    ( puts ( show 42 ) )\n    ( puts ( show T ) )\n\n    // Pair + id\n    : Pair p ( mk_pair `answer` ( id [i] 42 ) )\n    ( puts . p key )\n\n    // Division by zero → None propagates via \\\n    : *Ast zero ( box_ast @ Ast { Num 0 } )\n    : *Ast bad ( box_ast @ Ast { Bin 3 three zero } )\n    : ?i r2 ( eval bad )\n    ?? r2 {\n        _ → ( puts `(got None as expected)\\n` )\n    }\n\n    ( puts ( show eval_count ) )\n}\n\n// ── Entry point ──────────────────────────────────────────────\n@ main → i {\n    ( run_demo )\n    ( puts ( show ( fact 10 ) ) )  // 3628800\n    ^ 0\n}\n","bytes":4682}