More minor repl improvements

This commit is contained in:
Scott Richmond 2022-05-27 20:02:32 -04:00
parent bad0591408
commit 18bcf6d8c6

View File

@ -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)")