aboutsummaryrefslogtreecommitdiff
path: root/clojure/src/step2_eval.clj
diff options
context:
space:
mode:
authorJoel Martin <github@martintribe.org>2014-03-24 16:32:24 -0500
committerJoel Martin <github@martintribe.org>2014-03-24 16:32:24 -0500
commit3169070063b2cb877200117ebb384269d73bcb93 (patch)
tree23de3db1ea5c37afd21a45b6ed7771f56a08c0c4 /clojure/src/step2_eval.clj
downloadmal-3169070063b2cb877200117ebb384269d73bcb93.tar.gz
mal-3169070063b2cb877200117ebb384269d73bcb93.zip
Current state of mal for Clojure West lighting talk.
Diffstat (limited to 'clojure/src/step2_eval.clj')
-rw-r--r--clojure/src/step2_eval.clj61
1 files changed, 61 insertions, 0 deletions
diff --git a/clojure/src/step2_eval.clj b/clojure/src/step2_eval.clj
new file mode 100644
index 0000000..6ff9eb3
--- /dev/null
+++ b/clojure/src/step2_eval.clj
@@ -0,0 +1,61 @@
+(ns step2-eval
+ (:require [clojure.repl]
+ [types]
+ [readline]
+ [reader]))
+
+(declare EVAL)
+
+;; read
+(defn READ [& [strng]]
+ (let [line (if strng strng (read-line))]
+ (reader/read-string strng)))
+
+;; eval
+(defn eval-ast [ast env]
+ (cond
+ (symbol? ast) (or (get env ast)
+ (throw (Error. (str ast " not found"))))
+
+ (seq? ast) (doall (map #(EVAL % env) ast))
+
+ (vector? ast) (vec (doall (map #(EVAL % env) ast)))
+
+ (map? ast) (apply hash-map (doall (map #(EVAL % env)
+ (mapcat identity ast))))
+
+ :else ast))
+
+(defn EVAL [ast env]
+ ;;(prn "EVAL" ast (keys @env)) (flush)
+ (if (not (seq? ast))
+ (eval-ast ast env)
+
+ ;; apply list
+ (let [el (eval-ast ast env)
+ f (first el)
+ args (rest el)]
+ (apply f args))))
+
+;; print
+(defn PRINT [exp] (pr-str exp))
+
+;; repl
+(def repl-env {'+ +
+ '- -
+ '* *
+ '/ /})
+(defn rep
+ [strng]
+ (PRINT (EVAL (READ strng), repl-env)))
+
+(defn -main [& args]
+ (loop []
+ (let [line (readline/readline "user> ")]
+ (when line
+ (when-not (re-seq #"^\s*$|^\s*;.*$" line) ; blank/comment
+ (try
+ (println (rep line))
+ (catch Throwable e
+ (clojure.repl/pst e))))
+ (recur)))))