Merge pull request #406 from chr15m/lib-alias-hacks
[jackhill/mal.git] / lua / stepA_mal.lua
index db31789..dd9ab81 100755 (executable)
@@ -2,6 +2,7 @@
 
 local table = require('table')
 
+package.path = '../lua/?.lua;' .. package.path
 local readline = require('readline')
 local utils = require('utils')
 local types = require('types')
@@ -51,7 +52,7 @@ end
 function macroexpand(ast, env)
     while is_macro_call(ast, env) do
         local mac = env:get(ast[1])
-        ast = mac.fn(unpack(ast:slice(2)))
+        ast = mac.fn(table.unpack(ast:slice(2)))
     end
     return ast
 end
@@ -81,9 +82,10 @@ function EVAL(ast, env)
 
     -- apply list
     ast = macroexpand(ast, env)
-    if not types._list_Q(ast) then return ast end
+    if not types._list_Q(ast) then return eval_ast(ast, env) end
 
     local a0,a1,a2,a3 = ast[1], ast[2],ast[3],ast[4]
+    if not a0 then return ast end
     local a0sym = types._symbol_Q(a0) and a0.val or ""
     if 'def!' == a0sym then
         return env:set(a1, EVAL(a2, env))
@@ -128,13 +130,13 @@ function EVAL(ast, env)
     elseif 'if' == a0sym then
         local cond = EVAL(a1, env)
         if cond == types.Nil or cond == false then
-            if a3 then ast = a3 else return types.Nil end -- TCO
+            if #ast > 3 then ast = a3 else return types.Nil end -- TCO
         else
             ast = a2 -- TCO
         end
     elseif 'fn*' == a0sym then
         return types.MalFunc:new(function(...)
-            return EVAL(a2, Env:new(env, a1, arg))
+            return EVAL(a2, Env:new(env, a1, table.pack(...)))
         end, a2, env, a1)
     else
         local args = eval_ast(ast, env)
@@ -143,7 +145,7 @@ function EVAL(ast, env)
             ast = f.ast
             env = Env:new(f.env, f.params, args) -- TCO
         else
-            return f(unpack(args))
+            return f(table.unpack(args))
         end
     end
   end
@@ -173,7 +175,9 @@ rep("(def! *host-language* \"lua\")")
 rep("(def! not (fn* (a) (if a false true)))")
 rep("(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))")
 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)))))))")
-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))))))))")
+rep("(def! inc (fn* [x] (+ x 1)))")
+rep("(def! gensym (let* [counter (atom 0)] (fn* [] (symbol (str \"G__\" (swap! counter inc))))))")
+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)))))))))")
 
 function print_exception(exc)
     if exc then