(ns narjure.repl (:require [narjure.narsese :refer [parse]] [instaparse.core :as i] [clojure.string :refer [trim]] [clojure.tools.nrepl.middleware :refer [set-descriptor!]] [narjure.cycle :as cycle])) | |
(defonce narsese-repl-mode (atom false)) | |
(defn start-narsese-repl! [] (reset! narsese-repl-mode true) (println "Narsese repl was started.")) | |
(defn stop-narsese-repl! [] (reset! narsese-repl-mode false) (println "Narsese repl was stopped.")) | |
(defonce db (atom (cycle/default-memory))) | |
(defn clear-db! [] (reset! db (cycle/default-memory))) | |
(defn collect! [{:keys [statement truth] :as task}] (swap! db cycle/task->buffer task) [statement truth]) | |
(defn- parse-int [s] (try (Integer/parseInt s) (catch Exception _))) | |
(defn- wrap-code [code] (str "(narjure.repl/handle-narsese \ code "\")")) | |
(defn run [n] (swap! db cycle/do-cycles n) (cycle/print-results! @db) (swap! db dissoc :forward-inf-results :local-inf-results :answers) nil) | |
(defn- get-result [code] (let [result (parse code)] (if-not (i/failure? result) (collect! result) result))) | |
(defn handle-narsese [code] (let [n (parse-int (trim code))] (cond (integer? n) (do (run n) nil) (= "stop!" (trim code)) (stop-narsese-repl!) (= \* (first code)) (do (clear-db!) nil) (= \/ (first code)) :default (get-result code)))) | |
(defn narsese-handler [handler] (fn [args & tail] (apply handler (if @narsese-repl-mode [(update args :code wrap-code)] (cons args tail))))) | |
(set-descriptor! #'narsese-handler {:expects #{"eval"} :handles {"stdin" {:doc "Parses Narsese" :requires #{"code" "Code."}}}}) | |