Skip to content

Commit

Permalink
Features added:
Browse files Browse the repository at this point in the history
1. *e returns the most recently thrown error in the REPL.
2. If multiple forms are submitted at the REPL, then forms are evaluated in order until
   an error occurs. If an error occurs, the error is printed. Otherwise the value of the
   last form is printed and assigned to *1.
3. Line numbers are shown for all printed errors.
  • Loading branch information
arthuredelstein committed Feb 21, 2013
1 parent dd3c876 commit d906c47
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 23 deletions.
4 changes: 4 additions & 0 deletions src/cljs/cljs/core.cljs
Expand Up @@ -42,6 +42,10 @@
^{:doc "bound in a repl thread to the third most recent value printed"}
*3)

(def
^{:doc "bound in a repl thread to the error object most recently thrown"}
*e)

(defn truth_
"Internal - do not use!"
[x]
Expand Down
72 changes: 49 additions & 23 deletions src/cljs/cljs/repl.cljs
Expand Up @@ -4,35 +4,61 @@
[cljs.reader :as reader]))

(def ^:dynamic *debug* false)
(def ^:dynamic *e nil)

(defn prompt [] (str *ns-sym* "=> "))

(defn read-forms [text]
;; Save and restore *ns-sym*
(binding [*ns-sym* *ns-sym*]
(reader/read-string (str "(do " text ")"))))

(defn eval-print [text]
(defn evaluate-next-form
"Evaluates next clojure form in reader. Returns a map, containing
either resulting value and emitted javascript, or an error
object, or {:finished true}."
[rdr]
(try
(let [env (assoc (ana/empty-env) :context :expr)
forms (read-forms text)
_ (when *debug* (println "READ:" (pr-str forms)))
body (ana/analyze env forms)
_ (when *debug* (println "ANALYZED:" (pr-str (:form body))))
res (comp/emit-str body)
_ (when *debug* (println "EMITTED:" (pr-str res)))
value (js/eval res)]
(set! *3 *2)
(set! *2 *1)
(set! *1 value)
(binding [*out* *rtn*] (print (pr-str value))
{:value value :js res}))
(let [form (reader/read rdr false ::finished-reading)
_ (when *debug* (println "READ:" (pr-str form)))]
(if (= form ::finished-reading)
{:finished true}
(let [env (assoc (ana/empty-env) :context :expr)
body (ana/analyze env form)
_ (when *debug* (println "ANALYZED:" (pr-str (:form body))))
res (comp/emit-str body)
_ (when *debug* (println "EMITTED:" (pr-str res)))
value (js/eval res)]
{:value value :js res})))
(catch js/Error e
(set! *e e)
(binding [*out* *err*] (print (.-stack e)))
{:error (.-stack e)})))
{:error e :line-number (reader/get-line-number rdr)})))

(defn evaluate-code
"Evaluates some text from REPL input. If multiple forms are
present, evaluates in sequence until one throws an error
or the last form is reached. The result from the last
evaluated form is returned. *1, *2, *3, and *e are updated
appropriately."
[text]
(let [rdr (reader/indexing-push-back-reader text)]
(loop [last-output nil]
(let [output (evaluate-next-form rdr)]
(if-not (:finished output)
(if-let [err (:error output)]
(do (set! clojure.core/*e err)
output)
(recur output))
(do (set! *3 *2)
(set! *2 *1)
(set! *1 (:value last-output))
last-output))))))

(defn print-error [{:keys [error line-number]}]
(print error "at line" line-number))

(defn eval-print [input]
(let [evaluated (evaluate-code input)]
(if (:error evaluated)
(binding [*out* *err*] (print-error evaluated))
(try
(binding [*out* *rtn*] (pr (:value evaluated)))
(catch js/Error e
(binding [*out* *err*] (println err)))))))

(defn complete-form? [text]
(try
(reader/read-string text)
Expand Down

0 comments on commit d906c47

Please sign in to comment.