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))