001 (ns beowulf.core
002 (:require [beowulf.bootstrap :refer [EVAL oblist *options*]]
003 [beowulf.read :refer [READ]]
004 [clojure.java.io :as io]
005 [clojure.pprint :refer [pprint]]
006 [clojure.tools.cli :refer [parse-opts]]
007 [environ.core :refer [env]])
008 (:gen-class))
009
010 (def cli-options
011 [["-h" "--help"]
012 ["-p PROMPT" "--prompt PROMPT" "Set the REPL prompt to PROMPT"
013 :default "Sprecan::"]
014 ["-r INITFILE" "--read INITFILE" "Read Lisp functions from the file INITFILE"
015 :validate [#(and
016 (.exists (io/file %))
017 (.canRead (io/file %)))
018 "Could not find initfile"]]
019 ["-s" "--strict" "Strictly interpret the Lisp 1.5 language, without extensions."]
020 ["-t" "--trace" "Trace Lisp evaluation."]])
021
022 (defn repl
023 "Read/eval/print loop."
024 [prompt]
025 (loop []
026 (print prompt)
027 (flush)
028 (try
029 (let [input (read-line)]
030 (cond
031 (= input "quit") (throw (ex-info "\nFærwell!" {:cause :quit}))
032 input (println (str "> " (print-str (EVAL (READ input) @oblist))))
033 :else (println)))
034 (catch
035 Exception
036 e
037 (let [data (ex-data e)]
038 (println (.getMessage e))
039 (if
040 data
041 (case (:cause data)
042 :parse-failure (println (:failure data))
043 :strict nil ;; the message, which has already been printed, is enough.
044 :quit (throw e)
045 ;; default
046 (pprint data))))))
047 (recur)))
048
049 (defn -main
050 [& opts]
051 (let [args (parse-opts opts cli-options)]
052 (println
053 (str
054 "\nHider wilcuman. Béowulf is mín nama.\n"
055 (if
056 (System/getProperty "beowulf.version")
057 (str "Síðe " (System/getProperty "beowulf.version") "\n"))
058 (if
059 (:help (:options args))
060 (:summary args))
061 (if (:errors args)
062 (apply str (interpose "; " (:errors args))))
063 "\nSprecan 'quit' tó laéfan\n"))
064 (binding [*options* (:options args)]
065 (try
066 (repl (str (:prompt (:options args)) " "))
067 (catch
068 Exception
069 e
070 (let [data (ex-data e)]
071 (if
072 data
073 (case (:cause data)
074 :quit nil
075 ;; default
076 (pprint data))
077 (println e))))))))