local readline = require('readline')
local socket = require('socket')
-local Nil, List, _pr_str = types.Nil, types.List, printer._pr_str
+local Nil, List, HashMap, _pr_str = types.Nil, types.List, types.HashMap, printer._pr_str
local M = {}
return Nil
end
+local function lua_to_mal(a)
+ if a == nil then
+ return Nil
+ elseif type(a) == "boolean" or type(a) == "number" or type(a) == "string" then
+ return a
+ elseif type(a) == "table" then
+ local first_key, _ = next(a)
+ if first_key == nil then
+ return List:new({})
+ elseif type(first_key) == "number" then
+ local list = {}
+ for i, v in ipairs(a) do
+ list[i] = lua_to_mal(v)
+ end
+ return List:new(list)
+ else
+ local hashmap = {}
+ for k, v in pairs(a) do
+ hashmap[lua_to_mal(k)] = lua_to_mal(v)
+ end
+ return HashMap:new(hashmap)
+ end
+ end
+ return tostring(a)
+end
+
+local function lua_eval(str)
+ local f, err = loadstring("return "..str)
+ if err then
+ types.throw("lua-eval: can't load code: "..err)
+ end
+ return lua_to_mal(f())
+end
+
M.ns = {
['='] = types._equal_Q,
throw = types.throw,
deref = function(a) return a.val end,
['reset!'] = function(a,b) a.val = b; return b end,
['swap!'] = swap_BANG,
+
+ ['lua-eval'] = lua_eval,
}
return M
--- /dev/null
+;; Testing basic Lua interop
+
+;;; lua-eval adds the string "return " to the beginning of the evaluated string
+;;; and supplies that to Lua's loadstring(). If complex programs are needed,
+;;; those can be wrapped by an anonymous function which is called immediately
+;;; (see the foo = 8 example below).
+
+(lua-eval "7")
+;=>7
+
+(lua-eval "'7'")
+;=>"7"
+
+(lua-eval "123 == 123")
+;=>true
+
+(lua-eval "123 == 456")
+;=>false
+
+(lua-eval "{7,8,9}")
+;=>(7 8 9)
+
+(lua-eval "{abc = 789}")
+;=>{"abc" 789}
+
+(lua-eval "print('hello')")
+; hello
+;=>nil
+
+(lua-eval "(function() foo = 8 end)()")
+(lua-eval "foo")
+;=>8
+
+(lua-eval "string.gsub('This sentence has five words', '%w+', function(w) return '*'..#w..'*' end)")
+;=>"*4* *8* *3* *4* *5*"
+
+(lua-eval "table.concat({3, 'a', 45, 'b'}, '|')")
+;=>"3|a|45|b"