~subsetpark/ec

ref: 4457018244c48dcde004539d1d7b2e5a86af294f ec/main.janet -rw-r--r-- 1.8 KiB
44570182 — Zach Smith Add ec#1 regression 11 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
(import /src/calc)
(import /src/print)
(import /src/parser)

(defn handle-signal
  [input]
  (let [str (string input)]
    (when (= str "") (os/exit 0))
    str))

(defn- display
  [data]
  (print (print/p data))
  "")

(defn- display-all
  [stack]
  (let [inner (map print/p stack)]
    (print (string/join inner " ")))
  "")

(defn- display-help
  []
  (each [k v] (pairs parser/dictionary)
    (printf "%s: %s" k (string (v :type))))
  "")

(defn- describe-all
  [q]
  (defn- describe
    [elem]
    (printf "%s\n\n%s: %s"
            (print/p elem)
            (string (elem :type))
            (elem :doc)))
  (each item (q :data)
    (describe item))
  "")

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

(defn handle-commands
  [s input]
  (each token input
    (match token
      @[:special patt] (handle-special s patt)
      _ (calc/push s token))))

(defn- prompt
  [s]
  (->> s
       (calc/peek)
       (print/p)
       (string/format "(%s)> ")))

(defn repl
  []
  (def s (:new calc/Stack))
  (while true
    (def bak (array/slice (s :data)))
    (try (->> (getline (prompt s) @"" parser/dictionary)
              (handle-signal)
              (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)
         (handle-commands s))
    (display-all (s :data))))

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