diff --git a/src/ludus/repl.clj b/src/ludus/repl.clj index 2da3262..035e54d 100644 --- a/src/ludus/repl.clj +++ b/src/ludus/repl.clj @@ -4,7 +4,10 @@ [ludus.parser :as parser] [ludus.interpreter :as interpreter] [ludus.prelude :as prelude] - [ludus.show :as show])) + [ludus.show :as show] + [ludus.data :as data])) + +(declare repl-prelude new-session) (def sessions (atom {})) @@ -12,31 +15,71 @@ (def prompt "=> ") +(def base-ctx (merge prelude/prelude + {::repl true "foo" :bar + "repl" + { + ::data/struct true + ::data/type ::data/ns + ::data/name "repl" + + :flush + {:name "flush" + ::data/type ::data/clj + :body (fn [] + (let [session @current-session] + (swap! session #(assoc % :ctx (volatile! base-ctx))) + :ok))} + + :new + {:name "new" + ::data/type ::data/clj + :body (fn [name] + (let [session (new-session name)] + (reset! current-session session) + :ok))} + + :swap + {:name "swap" + ::data/type ::data/clj + :body (fn [name] + (if-let [session (get @sessions name)] + (do + (reset! current-session session) + :ok) + (do + (println "No session named" name) + :error)))} + }})) + (defn- new-session [name] (let [session (atom { :name name - :ctx (volatile! (merge prelude/prelude {::repl true})) + :ctx (volatile! base-ctx) :history []})] (swap! sessions #(assoc % name session)) session)) -(defn repl-loop [session-atom] - (let [session @session-atom] +(defn repl-loop [] + (let [session-atom @current-session + session @session-atom + orig-ctx (:ctx session)] (print (str (:name session) prompt)) (flush) (let [input (read-line) parsed (-> input (scanner/scan) (parser/parse)) {result :result ctx :ctx} (interpreter/interpret-repl parsed (:ctx session))] (if (= result ::interpreter/error) - (repl-loop session-atom) + (repl-loop) (do (println (show/show result)) - (swap! session-atom #(assoc % :ctx ctx)) - (repl-loop session-atom)))))) + (when (not (= @ctx @orig-ctx)) + (swap! session-atom #(assoc % :ctx ctx))) + (repl-loop)))))) (defn launch [] (println "Welcome to Ludus (v. 0.1.0-alpha)") (let [session (new-session "ludus")] (reset! current-session session) - (repl-loop session))) + (repl-loop)))