(import /src/calc) (import /src/operations :prefix "o/") (import /src/adverbs :prefix "a/") (use testament) (use /test-support) (deftest vectors (def v (wrap 1 2 3)) (def v2 (wrap 2 5 10)) (vec= [4 5 6] (calc/apply-operation o/add v (:new calc/Int 3))) (vec= [3 7 13] (calc/apply-operation o/add v v2)) (vec= [-2 -1 0] (calc/apply-operation o/sub v (:new calc/Int 3))) (vec= [2 1 0] (calc/apply-operation o/sub (:new calc/Int 3) v)) (is (vec= 6 (calc/apply-operation o/add (:new calc/Int 3) (:new calc/Int 3))))) (deftest matrices (is (thrown? (wrap (wrap 1) (wrap 1 2))) "Inner quotations are of differing sizes") (def m (wrap (wrap 1 2 3) (wrap 4 5 6))) (is (= [2 3] (calc/get-shape m))) (def filled (calc/fill m [2 2 3])) (is (= [2 2 3] (calc/get-shape filled))) (vec= @[@[@[1 2 3] @[4 5 6]] @[@[1 2 3] @[4 5 6]]] filled) (is (thrown? (calc/fill m [2 3 3])) "Vectors can be filled into shapes that share a suffix") (vec= @[@[@[2 4 6] @[8 10 12]] @[@[2 4 6] @[8 10 12]]] (calc/apply-operation o/add m filled))) (deftest distribute-add (def s (:new calc/Stack)) # Initial value (calc/push s (:new calc/Int 0)) # Operands (calc/push s (wrap 1 2 3)) # Operator (calc/push s (quote-wrap o/add)) (calc/push s a/distribute) (pop-and-compare 6 s)) (deftest distribute-multiple-operations (def s (:new calc/Stack)) (calc/push s (:new calc/Int 0)) (calc/push s (wrap 1 2 3)) (calc/push s (quote-wrap 3 o/mul o/add)) (calc/push s a/distribute) (pop-and-compare 18 s)) (deftest apply-quotation (def s (:new calc/Stack)) (calc/push s (quote-wrap 1 2 3)) (calc/push s a/apply-quotation) (pop-and-compare 3 s) (pop-and-compare 2 s) (pop-and-compare 1 s) (is (empty? (s :data)))) (deftest apply-vector (def s (:new calc/Stack)) (calc/push s (wrap 1 2 3)) (calc/push s a/apply-quotation) (pop-and-compare 3 s) (pop-and-compare 2 s) (pop-and-compare 1 s) (is (empty? (s :data)))) (deftest apply-operation (def s (:new calc/Stack)) (calc/push s (:new calc/Int 3)) (calc/push s (:new calc/Int 5)) (calc/push s (quote-wrap o/add)) (calc/push s a/apply-quotation) (pop-and-compare 8 s) (is (empty? (s :data)))) (deftest wrap-stack (def s (:new calc/Stack)) (calc/push s (:new calc/Int 3)) (calc/push s (:new calc/Int 4)) (calc/push s a/wrap-stack) (def vec (calc/pop s)) (is (= [2] (calc/shape vec))) (is (empty? (s :data)))) (deftest wrap-quotations (def s (:new calc/Stack)) (calc/push s (wrap 1 2)) (calc/push s (wrap 2 4)) (calc/push s a/wrap-stack) (def vec (calc/pop s)) (is (= [2 2] (calc/shape vec))) (is (empty? (s :data)))) (deftest wrap-failure (def s (:new calc/Stack)) (calc/push s (wrap 1)) (calc/push s (wrap 2 4)) (is (thrown? (calc/push s a/wrap-stack)) "Wrapping a stack requires homogeneous data")) (deftest get-arity (is (= 2 (calc/get-arity (quote-wrap o/add))) "A quoted operation's arity is the operation's arity") (is (= 3 (calc/get-arity (quote-wrap o/add o/add))) ``` A composition of operations' arity is the greatest of the individual operations' arities, each adjusted for the out-arity of the one prior ```) (is (= 2 (calc/get-arity (quote-wrap o/add 2 o/add))) "Interposed numbers will reduce the arity of a quotation") (is (= 0 (calc/get-arity (:new calc/Int 2))) "A number's arity is 0") (is (= 0 (calc/get-arity (quote-wrap 2))) "A quoted number's arity is 0") (is (= 0 (calc/get-arity (quote-wrap 2 2 2 2))) "A quoted sequence of numbers is 0") (is (= 0 (calc/get-arity (quote-wrap 2 2 o/add))) "A quoted operation is 0 if the quote enough values to fulfill it")) (run-tests!)