~subsetpark/ec

5b24c4463b2a541ae0a36ae7377481d3f947a5e6 — Zach Smith 9 months ago 90ec763
Refactor command handling
6 files changed, 55 insertions(+), 43 deletions(-)

M main.janet
M src/calc.janet
M src/parser.janet
M test-support.janet
M test/parser.janet
M test/regressions.janet
M main.janet => main.janet +33 -25
@@ 21,7 21,8 @@

(defn describe
  [elem]
  (printf "%s: %s"
  (printf "%s\n\n%s: %s"
          (print/p elem)
          (string (elem :type))
          (elem :doc)))



@@ 31,43 32,50 @@
    (describe item))
  "")

(defn handle-commands
  [in s]

  (when (= (string in) "") (os/exit 0))

  (case (freeze (string/trim in))
(defn handle-special
  [s special]
  (case (freeze (string/trim special))
    "." (display (calc/peek s))
    "p" (display (calc/pop s))
    "s" (display-all (s :data))
    "?" (describe-all (calc/pop s))
    "??" (display-help)
    in))
    "??" (display-help)))

(defn handle-commands
  [s input]
  (when (= (string input) "") (os/exit 0))
  
  (each token input
    (match token
      @[:special patt] (handle-special s patt)
      _ (calc/push s token))))


(defn repl
  []
  (let [s (:new calc/Stack)]
    (while true
      (let [buf @""
            prompt (string/format "(%s)> " (print/p (calc/peek s)))
            in (getline prompt buf parser/dictionary)
            after-commands (handle-commands in s)
            parsed (parser/parse after-commands)]

        (let [bak (array/slice (s :data))]
          (try (calc/push-all s parsed)
            ([err fib]
              (eprint err)
              (if (os/getenv "EC_TRACEBACK")
                (propagate err fib)
                (put s :data bak)))))))))
  (def s (:new calc/Stack))
  (while true
    (def bak (array/slice (s :data)))
    (try (as-> s _
               (calc/peek _)
               (print/p _)
               (string/format "(%s)> " _)
               (getline _ @"" parser/dictionary)
               (parser/parse _)
               (handle-commands s _))
         
         ([err fib]
          (eprint err)
          (if (os/getenv "EC_TRACEBACK")
            (propagate err fib)
            (put s :data bak))))))

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

(defn main

M src/calc.janet => src/calc.janet +0 -5
@@ 154,11 154,6 @@
  [self item]
  (array/push (self :data) item))

(defn push-all
  [stack args]
  (each arg args
    (push stack arg)))

(defn shape?
  [obj]
  (and (Quotation? obj) (all Number*? (obj :data))))

M src/parser.janet => src/parser.janet +12 -9
@@ 53,17 53,20 @@

(defn handle-word
  [patt]
  (or (dictionary patt)
      (errorf "syntax error: unknown word %s" patt)))
  (cond (index-of patt ["." "p" "s" "?" "??"])
        [:special patt]
        true
        (or (dictionary patt)
            (errorf "syntax error: unknown word %s" patt))))

(def- peg (peg/compile
            ~{:main (any (+ :s+ :brackets :token))
              :brackets (cmt (* "[" :main "]") ,handle-brackets)
              :number-part (some (+ :d "_"))
              :float (cmt (<- (* (? "-") :number-part "." :number-part)) ,handle-float)
              :int (cmt (<- (* (? "-") :number-part)) ,handle-int)
              :word (cmt (<- (some (if-not (+ :s (set "()[]")) 1))) ,handle-word)
              :token (+ :float :int :word)}))
           ~{:main (any (+ :s+ :brackets :token))
             :brackets (cmt (* "[" :main "]") ,handle-brackets)
             :number-part (some (+ :d "_"))
             :float (cmt (<- (* (? "-") :number-part "." :number-part)) ,handle-float)
             :int (cmt (<- (* (? "-") :number-part)) ,handle-int)
             :word (cmt (<- (some (if-not (+ :s (set "()[]")) 1))) ,handle-word)
             :token (+ :float :int :word)}))

(defn parse
  [str]

M test-support.janet => test-support.janet +5 -0
@@ 22,3 22,8 @@
(defn pop-and-compare
  [val s]
  (is (= val (calc/value (calc/pop s)))))

(defn push-all
  [stack args]
  (each arg args
    (calc/push stack arg)))

M test/parser.janet => test/parser.janet +3 -2
@@ 5,6 5,7 @@
(import /src/adverbs :prefix "a/")

(use testament)
(use /test-support)

(deftest brackets
  (let [[parsed] (parser/parse "[]")]


@@ 40,7 41,7 @@
(deftest pushable
  (let [s (:new calc/Stack)
        parsed (parser/parse "4 5 +")]
    (calc/push-all s parsed)
    (push-all s parsed)

    (is (= 1 (length (s :data))))
    (def res (first (s :data)))


@@ 51,7 52,7 @@
(deftest push-adverb
  (let [s (:new calc/Stack)
        parsed (parser/parse "0 [1 2 3] [+] /")]
    (calc/push-all s parsed)
    (push-all s parsed)

    (is (= 1 (length (s :data))))
    (def res (first (s :data)))

M test/regressions.janet => test/regressions.janet +2 -2
@@ 28,7 28,7 @@
  # [4 5] 6 +  8 +
  (def s (:new calc/Stack))
  (let [in (parser/parse "[4 5] 6 + 8 +")]
    (calc/push-all s in))
    (push-all s in))

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


@@ 37,7 37,7 @@
  # [2 3 4] 1 -
  (def s (:new calc/Stack))
  (let [in (parser/parse "[2 3 4] 1 -")]
    (calc/push-all s in))
    (push-all s in))

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