; End-to-end pipeline tests: source string → tokenize → parse → eval-ast → array. ; Verifies the full stack as a single function call (apl-run). (define mkrv (fn (arr) (get arr :ravel))) (define mksh (fn (arr) (get arr :shape))) ; ---------- scalars ---------- (apl-test "apl-run \"42\" → scalar 42" (mkrv (apl-run "42")) (list 42)) (apl-test "apl-run \"¯7\" → scalar -7" (mkrv (apl-run "¯7")) (list -7)) ; ---------- strands ---------- (apl-test "apl-run \"1 2 3\" → vector" (mkrv (apl-run "1 2 3")) (list 1 2 3)) (apl-test "apl-run \"1 2 3\" shape" (mksh (apl-run "1 2 3")) (list 3)) ; ---------- dyadic arithmetic ---------- (apl-test "apl-run \"2 + 3\" → 5" (mkrv (apl-run "2 + 3")) (list 5)) (apl-run "2 × 3 + 4") ; right-to-left (apl-test "apl-run \"2 × 3 + 4\" → 14 (right-to-left)" (mkrv (apl-run "2 × 3 + 4")) (list 14)) (apl-test "apl-run \"1 2 3 + 4 5 6\" → 5 7 9" (mkrv (apl-run "1 2 3 + 4 5 6")) (list 5 7 9)) (apl-test "apl-run \"3 × 1 2 3 4\" → scalar broadcast" (mkrv (apl-run "3 × 1 2 3 4")) (list 3 6 9 12)) ; ---------- monadic primitives ---------- (apl-test "apl-run \"⍳5\" → 1..5" (mkrv (apl-run "⍳5")) (list 1 2 3 4 5)) (apl-test "apl-run \"-3\" → -3 (monadic negate)" (mkrv (apl-run "-3")) (list -3)) (apl-test "apl-run \"⌈/ 1 3 9 5 7\" → 9 (max-reduce)" (mkrv (apl-run "⌈/ 1 3 9 5 7")) (list 9)) (apl-test "apl-run \"⌊/ 4 7 2 9 1 3\" → 1 (min-reduce)" (mkrv (apl-run "⌊/ 4 7 2 9 1 3")) (list 1)) ; ---------- operators ---------- (apl-test "apl-run \"+/⍳5\" → 15" (mkrv (apl-run "+/⍳5")) (list 15)) (apl-test "apl-run \"×/⍳5\" → 120" (mkrv (apl-run "×/⍳5")) (list 120)) (apl-test "apl-run \"⌈/3 1 4 1 5 9 2\" → 9" (mkrv (apl-run "⌈/3 1 4 1 5 9 2")) (list 9)) (apl-test "apl-run \"+\\\\⍳5\" → triangular numbers" (mkrv (apl-run "+\\⍳5")) (list 1 3 6 10 15)) ; ---------- outer / inner products ---------- (apl-test "apl-run \"1 2 3 ∘.× 1 2 3\" → mult table values" (mkrv (apl-run "1 2 3 ∘.× 1 2 3")) (list 1 2 3 2 4 6 3 6 9)) (apl-test "apl-run \"1 2 3 +.× 4 5 6\" → dot product 32" (mkrv (apl-run "1 2 3 +.× 4 5 6")) (list 32)) ; ---------- shape ---------- (apl-test "apl-run \"⍴ 1 2 3 4 5\" → 5" (mkrv (apl-run "⍴ 1 2 3 4 5")) (list 5)) (apl-test "apl-run \"⍴⍳10\" → 10" (mkrv (apl-run "⍴⍳10")) (list 10)) ; ---------- comparison ---------- (apl-test "apl-run \"3 < 5\" → 1" (mkrv (apl-run "3 < 5")) (list 1)) (apl-test "apl-run \"5 = 5\" → 1" (mkrv (apl-run "5 = 5")) (list 1)) (apl-test "apl-run \"1 2 3 = 1 0 3\" → 1 0 1" (mkrv (apl-run "1 2 3 = 1 0 3")) (list 1 0 1)) ; ---------- famous one-liners ---------- (apl-test "apl-run \"+/(⍳10)\" → sum 1..10 = 55" (mkrv (apl-run "+/(⍳10)")) (list 55)) (apl-test "apl-run \"×/⍳10\" → 10! = 3628800" (mkrv (apl-run "×/⍳10")) (list 3628800)) (apl-test "apl-run \"⎕IO\" → 1" (mkrv (apl-run "⎕IO")) (list 1)) (apl-test "apl-run \"⎕ML\" → 1" (mkrv (apl-run "⎕ML")) (list 1)) (apl-test "apl-run \"⎕FR\" → 1248" (mkrv (apl-run "⎕FR")) (list 1248)) (apl-test "apl-run \"⎕TS\" shape (7)" (mksh (apl-run "⎕TS")) (list 7)) (apl-test "apl-run \"⎕FMT 42\" → \"42\"" (apl-run "⎕FMT 42") "42") (apl-test "apl-run \"⎕FMT 1 2 3\" → \"1 2 3\"" (apl-run "⎕FMT 1 2 3") "1 2 3") (apl-test "apl-run \"⎕FMT ⍳5\" → \"1 2 3 4 5\"" (apl-run "⎕FMT ⍳5") "1 2 3 4 5") (apl-test "apl-run \"⎕IO + 4\" → 5" (mkrv (apl-run "⎕IO + 4")) (list 5)) (apl-test "apl-run \"(10 20 30 40 50)[3]\" → 30" (mkrv (apl-run "(10 20 30 40 50)[3]")) (list 30)) (apl-test "apl-run \"(⍳10)[5]\" → 5" (mkrv (apl-run "(⍳10)[5]")) (list 5)) (apl-test "apl-run \"A ← 100 200 300 ⋄ A[2]\" → 200" (mkrv (apl-run "A ← 100 200 300 ⋄ A[2]")) (list 200)) (apl-test "apl-run \"V ← ⍳10 ⋄ V[3]\" → 3" (mkrv (apl-run "V ← ⍳10 ⋄ V[3]")) (list 3)) (apl-test "apl-run \"(10 20 30)[1]\" → 10 (1-indexed)" (mkrv (apl-run "(10 20 30)[1]")) (list 10)) (apl-test "apl-run \"V ← 10 20 30 40 50 ⋄ V[3] + 1\" → 31" (mkrv (apl-run "V ← 10 20 30 40 50 ⋄ V[3] + 1")) (list 31)) (apl-test "apl-run \"(⍳5)[3] × 7\" → 21" (mkrv (apl-run "(⍳5)[3] × 7")) (list 21)) (apl-test "decimal: 3.7 → 3.7" (mkrv (apl-run "3.7")) (list 3.7)) (apl-test "decimal: ¯2.5 → -2.5" (mkrv (apl-run "¯2.5")) (list -2.5)) (apl-test "decimal: 1.5 + 2.5 → 4" (mkrv (apl-run "1.5 + 2.5")) (list 4)) (apl-test "decimal: ⌊3.7 → 3" (mkrv (apl-run "⌊ 3.7")) (list 3)) (apl-test "decimal: ⌈3.7 → 4" (mkrv (apl-run "⌈ 3.7")) (list 4)) (apl-test "⎕← scalar passthrough" (mkrv (apl-run "⎕← 42")) (list 42)) (apl-test "⎕← vector passthrough" (mkrv (apl-run "⎕← 1 2 3")) (list 1 2 3)) (apl-test "string: 'abc' → 3-char vector" (mkrv (apl-run "'abc'")) (list "a" "b" "c")) (apl-test "string: 'a' is rank-0 scalar" (mksh (apl-run "'a'")) (list)) (apl-test "string: 'hello' shape (5)" (mksh (apl-run "'hello'")) (list 5)) (apl-test "named-fn: f ← {⍺+⍵} ⋄ 3 f 4 → 7" (mkrv (apl-run "f ← {⍺+⍵} ⋄ 3 f 4")) (list 7)) (apl-test "named-fn monadic: sq ← {⍵×⍵} ⋄ sq 7 → 49" (mkrv (apl-run "sq ← {⍵×⍵} ⋄ sq 7")) (list 49)) (apl-test "named-fn dyadic: hyp ← {((⍺×⍺)+⍵×⍵)} ⋄ 3 hyp 4 → 25" (mkrv (apl-run "hyp ← {((⍺×⍺)+⍵×⍵)} ⋄ 3 hyp 4")) (list 25)) (apl-test "named-fn: dbl ← {⍵+⍵} ⋄ dbl ⍳5" (mkrv (apl-run "dbl ← {⍵+⍵} ⋄ dbl ⍳5")) (list 2 4 6 8 10)) (apl-test "named-fn factorial via ∇ recursion" (mkrv (apl-run "fact ← {0=⍵:1 ⋄ ⍵×∇⍵-1} ⋄ fact 5")) (list 120)) (apl-test "named-fn used twice in expr: dbl ← {⍵+⍵} ⋄ (dbl 3) + dbl 4" (mkrv (apl-run "dbl ← {⍵+⍵} ⋄ (dbl 3) + dbl 4")) (list 14)) (apl-test "named-fn with vector arg: neg ← {-⍵} ⋄ neg 1 2 3" (mkrv (apl-run "neg ← {-⍵} ⋄ neg 1 2 3")) (list -1 -2 -3)) (apl-test "multi-axis: M[2;2] → center" (mkrv (apl-run "M ← (3 3) ⍴ ⍳9 ⋄ M[2;2]")) (list 5)) (apl-test "multi-axis: M[1;] → first row" (mkrv (apl-run "M ← (3 3) ⍴ ⍳9 ⋄ M[1;]")) (list 1 2 3)) (apl-test "multi-axis: M[;2] → second column" (mkrv (apl-run "M ← (3 3) ⍴ ⍳9 ⋄ M[;2]")) (list 2 5 8)) (apl-test "multi-axis: M[1 2;1 2] → 2x2 block" (mkrv (apl-run "M ← (2 3) ⍴ ⍳6 ⋄ M[1 2;1 2]")) (list 1 2 4 5)) (apl-test "multi-axis: M[1 2;1 2] shape (2 2)" (mksh (apl-run "M ← (2 3) ⍴ ⍳6 ⋄ M[1 2;1 2]")) (list 2 2)) (apl-test "multi-axis: M[;] full matrix" (mkrv (apl-run "M ← (2 2) ⍴ 10 20 30 40 ⋄ M[;]")) (list 10 20 30 40)) (apl-test "multi-axis: M[1;] shape collapsed" (mksh (apl-run "M ← (3 3) ⍴ ⍳9 ⋄ M[1;]")) (list 3)) (apl-test "multi-axis: select all rows of column 3" (mkrv (apl-run "M ← (4 3) ⍴ 1 2 3 4 5 6 7 8 9 10 11 12 ⋄ M[;3]")) (list 3 6 9 12))