(import /src/calc) (import /src/print) (import /src/parser) (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 [elem] (printf "%s: %s" (string (elem :type)) (elem :doc))) (defn describe-all [q] (each item (q :data) (describe item)) "") (defn handle-commands [in s] (when (= (string in) "") (os/exit 0)) (case (freeze (string/trim in)) "." (display (calc/peek s)) "p" (display (calc/pop s)) "s" (display-all (s :data)) "?" (describe-all (calc/pop s)) "??" (display-help) in)) (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))))))))) (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 " "))))