More minor repl improvements
This commit is contained in:
parent
bad0591408
commit
18bcf6d8c6
|
@ -1,11 +1,11 @@
|
||||||
(ns ludus.repl
|
(ns ludus.repl
|
||||||
(:require
|
(:require
|
||||||
[ludus.scanner :as scanner]
|
[ludus.scanner :as scanner]
|
||||||
[ludus.parser :as parser]
|
[ludus.parser :as parser]
|
||||||
[ludus.interpreter :as interpreter]
|
[ludus.interpreter :as interpreter]
|
||||||
[ludus.prelude :as prelude]
|
[ludus.prelude :as prelude]
|
||||||
[ludus.show :as show]
|
[ludus.show :as show]
|
||||||
[ludus.data :as data]))
|
[ludus.data :as data]))
|
||||||
|
|
||||||
(declare repl-prelude new-session)
|
(declare repl-prelude new-session)
|
||||||
|
|
||||||
|
@ -15,40 +15,59 @@
|
||||||
|
|
||||||
(def prompt "=> ")
|
(def prompt "=> ")
|
||||||
|
|
||||||
|
(defn- exit []
|
||||||
|
(println "\nGoodbye!")
|
||||||
|
(System/exit 0))
|
||||||
|
|
||||||
(def base-ctx (merge prelude/prelude
|
(def base-ctx (merge prelude/prelude
|
||||||
{::repl true
|
{::repl true
|
||||||
"repl"
|
"repl"
|
||||||
{::data/struct true
|
{::data/struct true
|
||||||
::data/type ::data/ns
|
::data/type ::data/ns
|
||||||
::data/name "repl"
|
::data/name "repl"
|
||||||
|
|
||||||
:flush
|
:flush
|
||||||
{:name "flush"
|
{:name "flush"
|
||||||
::data/type ::data/clj
|
::data/type ::data/clj
|
||||||
:body (fn []
|
:body (fn
|
||||||
(let [session @current-session]
|
([]
|
||||||
(swap! session #(assoc % :ctx (volatile! base-ctx)))
|
(let [session @current-session]
|
||||||
:ok))}
|
(swap! session #(assoc % :ctx (volatile! base-ctx)))
|
||||||
|
:ok))
|
||||||
|
([name]
|
||||||
|
(if-let [session (get @sessions name)]
|
||||||
|
(do
|
||||||
|
(swap! session #(assoc % :ctx (volatile! base-ctx)))
|
||||||
|
:ok)
|
||||||
|
(do
|
||||||
|
(println "No session named" name)
|
||||||
|
:error))))}
|
||||||
|
|
||||||
:new
|
:new
|
||||||
{:name "new"
|
{:name "new"
|
||||||
::data/type ::data/clj
|
::data/type ::data/clj
|
||||||
:body (fn [name]
|
:body (fn [name]
|
||||||
(let [session (new-session name)]
|
(let [session (new-session name)]
|
||||||
(reset! current-session session)
|
(reset! current-session session)
|
||||||
:ok))}
|
:ok))}
|
||||||
|
|
||||||
:switch
|
:switch
|
||||||
{:name "switch"
|
{:name "switch"
|
||||||
::data/type ::data/clj
|
::data/type ::data/clj
|
||||||
:body (fn [name]
|
:body (fn [name]
|
||||||
(if-let [session (get @sessions name)]
|
(if-let [session (get @sessions name)]
|
||||||
(do
|
(do
|
||||||
(reset! current-session session)
|
(reset! current-session session)
|
||||||
:ok)
|
:ok)
|
||||||
(do
|
(do
|
||||||
(println "No session named" name)
|
(println "No session named" name)
|
||||||
:error)))}}}))
|
:error)))}
|
||||||
|
|
||||||
|
:quit
|
||||||
|
{:name "quit"
|
||||||
|
::data/type ::data/clj
|
||||||
|
:body (fn [] (exit))}
|
||||||
|
}}))
|
||||||
|
|
||||||
(defn- new-session [name]
|
(defn- new-session [name]
|
||||||
(let [session (atom {:name name
|
(let [session (atom {:name name
|
||||||
|
@ -57,27 +76,29 @@
|
||||||
(swap! sessions #(assoc % name session))
|
(swap! sessions #(assoc % name session))
|
||||||
session))
|
session))
|
||||||
|
|
||||||
(defn- exit []
|
|
||||||
(println "\nGoodbye!")
|
|
||||||
(System/exit 0))
|
|
||||||
|
|
||||||
(defn repl-loop []
|
(defn repl-loop []
|
||||||
(let [session-atom @current-session
|
(let [session-atom @current-session
|
||||||
session @session-atom
|
session @session-atom
|
||||||
orig-ctx (:ctx session)]
|
orig-ctx (:ctx session)]
|
||||||
(print (str (:name session) prompt))
|
(print (str (:name session) prompt))
|
||||||
(flush)
|
(flush)
|
||||||
(let [raw-input (read-line)
|
(let [raw-input (read-line)]
|
||||||
input (if raw-input raw-input (exit))
|
(cond
|
||||||
parsed (-> input (scanner/scan) (parser/parse))
|
(= nil raw-input) (exit)
|
||||||
{result :result ctx :ctx} (interpreter/interpret-repl parsed (:ctx session))]
|
|
||||||
(if (= result ::interpreter/error)
|
(= "" raw-input) (recur)
|
||||||
(repl-loop)
|
|
||||||
(do
|
:else
|
||||||
(println (show/show result))
|
(let [input (if raw-input raw-input (exit))
|
||||||
(when (not (= @ctx @orig-ctx))
|
parsed (-> input (scanner/scan) (parser/parse))
|
||||||
(swap! session-atom #(assoc % :ctx ctx)))
|
{result :result ctx :ctx} (interpreter/interpret-repl parsed (:ctx session))]
|
||||||
(repl-loop))))))
|
(if (= result ::interpreter/error)
|
||||||
|
(recur)
|
||||||
|
(do
|
||||||
|
(println (show/show result))
|
||||||
|
(when (not (= @ctx @orig-ctx))
|
||||||
|
(swap! session-atom #(assoc % :ctx ctx)))
|
||||||
|
(recur))))))))
|
||||||
|
|
||||||
(defn launch []
|
(defn launch []
|
||||||
(println "Welcome to Ludus (v. 0.1.0-alpha)")
|
(println "Welcome to Ludus (v. 0.1.0-alpha)")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user