Add gensym and clean `or` macro to stepA of 19 implementations (part 3)
[jackhill/mal.git] / rust / src / bin / stepA_mal.rs
index 07dac10..a7a5c48 100644 (file)
@@ -349,7 +349,9 @@ fn main() {
     let _ = rep("(def! not (fn* (a) (if a false true)))", repl_env.clone());
     let _ = rep("(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))", repl_env.clone());
     let _ = rep("(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))", repl_env.clone());
-    let _ = rep("(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))", repl_env.clone());
+    let _ = rep("(def! *gensym-counter* (atom 0))", repl_env.clone());
+    let _ = rep("(def! gensym (fn* [] (symbol (str \"G__\" (swap! *gensym-counter* (fn* [x] (+ 1 x)))))))", repl_env.clone());
+    let _ = rep("(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) (let* (condvar (gensym)) `(let* (~condvar ~(first xs)) (if ~condvar ~condvar (or ~@(rest xs)))))))))", repl_env.clone());
 
     // Invoked with command line arguments
     let args = stdenv::args();