diff --git a/src/ludus/core.cljc b/src/ludus/core.cljc deleted file mode 100644 index 83ff37b..0000000 --- a/src/ludus/core.cljc +++ /dev/null @@ -1,28 +0,0 @@ -(ns ludus.core - (:require - [ludus.scanner :as scanner] - [ludus.parser :as parser] - [ludus.grammar :as grammar] - [ludus.interpreter :as interpreter] - [ludus.show :as show] - )) - -(defn run [source] - (println (str "Running some ludus source: " source)) - (let [scanned (scanner/scan source)] - (if (not-empty (:errors scanned)) - (do - (println "I found some scanning errors!") - (println (:errors scanned)) - ) - (let [parsed (parser/apply-parser grammar/script (:tokens scanned))] - (println "Scanned: ") - (println scanned) - (if (parser/fail? parsed) - (do - (println "I found some parsing errors!") - (println (parser/err-msg parsed)) - nil - ) - (let [interpreted (interpreter/interpret source parsed)] - (show/show interpreted))))))) \ No newline at end of file diff --git a/src/ludus/loader.clj b/src/ludus/loader.clj new file mode 100644 index 0000000..f8ba0a0 --- /dev/null +++ b/src/ludus/loader.clj @@ -0,0 +1,16 @@ +(ns ludus.loader + (:require [babashka.fs :as fs])) + +(defn cwd [] (fs/cwd)) + +(defn load-import + ([file] + (let [path (-> file (fs/canonicalize) (fs/file))] + (try (slurp path) + (catch java.io.FileNotFoundException _ + (throw (ex-info (str "File " path " not found") {:path path ::error true})))))) + ([file from] + (load-import + (fs/path + (if (= from :cwd) (fs/cwd) (fs/parent (fs/canonicalize from))) + (fs/path file))))) diff --git a/src/ludus/repl.clj b/src/ludus/repl.clj new file mode 100644 index 0000000..6455f48 --- /dev/null +++ b/src/ludus/repl.clj @@ -0,0 +1,124 @@ +(ns ludus.repl + (:require + [ludus.scanner :as scanner] + ;[ludus.parser :as parser] + [ludus.parser-new :as p] + [ludus.grammar :as g] + [ludus.interpreter :as interpreter] + [ludus.prelude :as prelude] + [ludus.show :as show] + [ludus.data :as data] + ;[ludus.process :as process] + )) + +(declare repl-prelude new-session) + +(def sessions (atom {})) + +(def current-session (atom nil)) + +(def prompt "=> ") + +(defn- exit [] + (println "\nGoodbye!") + (System/exit 0)) + +(def base-ctx (merge prelude/prelude ;process/process + {::repl true + "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)) + ([name] + (if-let [session (get @sessions name)] + (do + (swap! session #(assoc % :ctx (volatile! base-ctx))) + :ok) + (do + (println "No session named" name) + :error))))} + + :new + {:name "new" + ::data/type ::data/clj + :body (fn [name] + (let [session (new-session name)] + (reset! current-session session) + :ok))} + + :switch + {:name "switch" + ::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)))} + + :quit + {:name "quit" + ::data/type ::data/clj + :body (fn [] (exit))} + }})) + +(defn- new-session [name] + (let [session (atom {:name name + :ctx (volatile! base-ctx) + :history []})] + (swap! sessions #(assoc % name session)) + session)) + +(defn repl-loop [] + (let [session-atom @current-session + session @session-atom + orig-ctx (:ctx session) + pid (:pid session)] + (print (str (:name session) prompt)) + (flush) + (let [input (read-line)] + (cond + (= nil input) (exit) + + (= "" input) (recur) + + :else + (let [parsed (->> input + (scanner/scan) + :tokens + (p/apply-parser g/script))] + (if (= :err (:status parsed)) + (do + (println (p/err-msg parsed)) + (recur)) + (let [{result :result ctx :ctx pid- :pid} + (if pid + (interpreter/interpret-repl parsed orig-ctx pid) + (interpreter/interpret-repl parsed orig-ctx))] + (if (= result :error) + (recur) + (do + (println (show/show result)) + (when (not (= @ctx @orig-ctx)) + (swap! session-atom #(assoc % :ctx ctx))) + (when (not (= pid pid-)) + (swap! session-atom #(assoc % :pid pid-))) + (recur)))))))))) + +(defn launch [] + (println "Welcome to Ludus (v. 0.1.0-alpha)") + (let [session (new-session :ludus)] + (reset! current-session session) + (repl-loop))) +