~subsetpark/ec

a37c903188ba035322c030f56c766089eab36556 — Zach Smith 9 months ago 32fb47a
Bugfix: make-element in vector math as well
6 files changed, 120 insertions(+), 39 deletions(-)

M main.janet
M src/calc.janet
A src/print.janet
A test-support.janet
M test/calc.janet
A test/regressions.janet
M main.janet => main.janet +16 -2
@@ 21,8 21,8 @@
    "s" (display-all (s :data))
    in))

(defn main
  [args]
(defn repl
  []
  (let [s (:new calc/Stack)]
    (while true
      (let [buf @""


@@ 31,3 31,17 @@
            after-commands (handle-commands in s)
            parsed (parser/parse after-commands)]
        (calc/push-all s parsed)))))

(defn handle-line
  [line]
  (let [s (:new calc/Stack)]
    (->> line
         (parser/parse)
         (calc/push-all s))
    (display-all (s :data))))

(defn main
  [_cmd & args]
  (if (empty? args)
    (repl)
    (handle-line (string/join args " "))))

M src/calc.janet => src/calc.janet +19 -15
@@ 45,18 45,24 @@
            self
            (reverse y))))

# TODO: Do we want to do something more sophisticated here?
(defmulti make-element [:number] [n] (:new Float n))
(defmulti make-element [_] [v] v)

(defn- inner-apply [op & args]
  (let [x (first args)]
    (if (Vector? x)
      (:new Vector
            (x :shape)
            (map (partial inner-apply op) ;(map |($ :data) args)))
      (let [f (op :fun-ref)
            unwrapped (map |($ :value) args)]

        (->> (f ;unwrapped)
             (make-element))))))

(defmethod apply-operation Operation
  [op & args]
  (defn inner-apply [op & args]
    (let [x (first args)]
      (if (Vector? x)
        (:new Vector
              (x :shape)
              (map (partial inner-apply op) ;(map |($ :data) args)))
        (let [f (op :fun-ref)
              unwrapped (map |($ :value) args)]
          (f ;unwrapped)))))

  (let [cmpr (comp length get-shape)
        largest (get-shape (extreme |(> (cmpr $0) (cmpr $1)) args))
        filled (map |(fill $ largest) args)]


@@ 92,10 98,6 @@
            arity
            (size stack))))

# TODO: Do we want to do something more sophisticated here?
(defmulti make-element [:number] [n] (:new Float n))
(defmulti make-element [_] [v] v)

(defmulti push [Stack Operation]
  [self op]
  (let [{:arity arity :type op-type} op]


@@ 105,7 107,9 @@
    (loop [_ :range [0 arity]]
      (array/push buf (pop self)))

    (push self (make-element (apply-operation op ;buf)))))
    (->> (apply-operation op ;buf)
         (make-element)
         (push self))))

(defmulti push [Stack _]
  [self item]

A src/print.janet => src/print.janet +23 -0
@@ 0,0 1,23 @@
(use fugue)

(import /src/calc)

(defgeneric p
  [val] (describe val))

(defmethod p calc/Int
  [n] (string (n :value)))

(defmethod p calc/Float
  [n] (string (n :value)))

(defmethod p calc/Operation
  [o] (string (o :type)))

(defmethod p calc/Adverb
  [a] (string (a :type)))

(defmethod p calc/Vector
  [v]
  (let [inner (map p (v :data))]
    (string "[" (string/join inner " ") "]")))

A test-support.janet => test-support.janet +24 -0
@@ 0,0 1,24 @@
(import /src/calc)

(use testament)

(defn unwrap
  [obj]
  (match obj
    {:data data} (map unwrap data)
    {:value value} value))

(defn vec=
  [val obj]
  (is (== val (unwrap obj))))

(defn wrap
  [& args]
  (calc/wrap ;(map |(if (number? $)
                      (:new calc/Int $)
                      $)
                   args)))

(defn pop-and-compare
  [val s]
  (is (= val (calc/value (calc/pop s)))))

M test/calc.janet => test/calc.janet +2 -22
@@ 4,23 4,7 @@
(import /src/adverbs :prefix "a/")

(use testament)

(defn- rec-data [vec]
  (match vec
    {:data data} (map rec-data data)
    {:value value} (rec-data value)
    data data))

(defn- vec=
  [val vec]
  (is (== val (rec-data vec))))

(defn- wrap
  [& args]
  (calc/wrap ;(map |(if (number? $)
                      (:new calc/Int $)
                      $)
                   args)))
(use /test-support)

(deftest vectors
  (def v (wrap 1 2 3))


@@ 32,7 16,7 @@
  (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 (= 6 (calc/apply-operation o/add (:new calc/Int 3) (:new calc/Int 3)))))
  (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)))


@@ 60,10 44,6 @@
            @[8 10 12]]]
        (calc/apply-operation o/add m filled)))

(defn- pop-and-compare
  [val s]
  (is (= val (calc/value (calc/pop s)))))

(deftest distribute-dyad-add
  (def s (:new calc/Stack))
  # Initial value

A test/regressions.janet => test/regressions.janet +36 -0
@@ 0,0 1,36 @@
(import /src/calc)
(import /src/parser)

(import /src/operations :prefix "o/")
(import /src/adverbs :prefix "a/")

(use testament)
(use /test-support)

(deftest regression1
  # [1] 1 + 1 +
  (def s (:new calc/Stack))
  (let [in (parser/parse "[1] 1 + 1 +")]
    (calc/push s (in 0))
    (vec= [1] (calc/peek s))
    (calc/push s (in 1))
    (vec= 1 (calc/peek s))
    (calc/push s (in 2))
    (vec= [2] (calc/peek s))
    (calc/push s (in 3))
    (vec= 1 (calc/peek s))
    (calc/push s (in 4)))

  (def res (calc/pop s))
  (vec= [3] res))

(deftest regression2
  # [4 5] 6 +  8 +
  (def s (:new calc/Stack))
  (let [in (parser/parse "[4 5] 6 + 8 +")]
    (calc/push-all s in))

  (def res (calc/pop s))
  (vec= [18 19] res))

(run-tests!)