; Tests for valence detection (apl-dfn-valence, apl-tradfn-valence)
; and unified dispatch (apl-call).

(define mkrv (fn (arr) (get arr :ravel)))
(define mknum (fn (n) (list :num n)))
(define mknm (fn (s) (list :name s)))
(define mkfg (fn (g) (list :fn-glyph g)))
(define mkmon (fn (g a) (list :monad (mkfg g) a)))
(define mkdyd (fn (g l r) (list :dyad (mkfg g) l r)))
(define mkasg (fn (n e) (list :assign n e)))
(define mkdfn (fn (stmts) (cons :dfn stmts)))

(apl-test
  "dfn-valence niladic body=42"
  (apl-dfn-valence (mkdfn (list (mknum 42))))
  :niladic)

(apl-test
  "dfn-valence monadic body=⍵+1"
  (apl-dfn-valence (mkdfn (list (mkdyd "+" (mknm "⍵") (mknum 1)))))
  :monadic)

(apl-test
  "dfn-valence dyadic body=⍺+⍵"
  (apl-dfn-valence (mkdfn (list (mkdyd "+" (mknm "⍺") (mknm "⍵")))))
  :dyadic)

(apl-test
  "dfn-valence dyadic mentions ⍺ via local"
  (apl-dfn-valence (mkdfn (list (mkasg "x" (mknm "⍺")) (mknm "x"))))
  :dyadic)

(apl-test
  "dfn-valence dyadic deep nest"
  (apl-dfn-valence
    (mkdfn (list (mkmon "-" (mkdyd "×" (mknm "⍺") (mknm "⍵"))))))
  :dyadic)

(apl-test "tradfn-valence niladic" (apl-tradfn-valence {:result "R" :omega nil :stmts (list) :alpha nil}) :niladic)

(apl-test "tradfn-valence monadic" (apl-tradfn-valence {:result "R" :omega "W" :stmts (list) :alpha nil}) :monadic)

(apl-test "tradfn-valence dyadic" (apl-tradfn-valence {:result "R" :omega "W" :stmts (list) :alpha "L"}) :dyadic)

(apl-test
  "apl-call dfn niladic"
  (mkrv (apl-call (mkdfn (list (mknum 42))) nil nil))
  (list 42))

(apl-test
  "apl-call dfn monadic"
  (mkrv
    (apl-call
      (mkdfn (list (mkdyd "+" (mknm "⍵") (mknum 1))))
      nil
      (apl-scalar 5)))
  (list 6))

(apl-test
  "apl-call dfn dyadic"
  (mkrv
    (apl-call
      (mkdfn (list (mkdyd "+" (mknm "⍺") (mknm "⍵"))))
      (apl-scalar 3)
      (apl-scalar 4)))
  (list 7))

(apl-test
  "apl-call tradfn dyadic"
  (mkrv (apl-call {:result "R" :omega "W" :stmts (list (mkasg "R" (mkdyd "×" (mknm "L") (mknm "W")))) :alpha "L"} (apl-scalar 6) (apl-scalar 7)))
  (list 42))

(apl-test
  "apl-call tradfn monadic"
  (mkrv (apl-call {:result "R" :omega "W" :stmts (list (mkasg "R" (mkmon "-" (mknm "W")))) :alpha nil} nil (apl-scalar 9)))
  (list -9))

(apl-test
  "apl-call tradfn niladic returns nil result"
  (apl-call {:result "R" :omega nil :stmts (list) :alpha nil} nil nil)
  nil)
