diff --git a/impls/lua/env.lua b/impls/lua/env.lua index b4e824f6d1..4b318e5b4f 100644 --- a/impls/lua/env.lua +++ b/impls/lua/env.lua @@ -13,11 +13,7 @@ function Env:new(outer, binds, exprs) if binds then for i, b in ipairs(binds) do if binds[i].val == '&' then - local new_exprs = types.List:new() - for j = i, #exprs do - table.insert(new_exprs, exprs[j]) - end - data[binds[i+1].val] = new_exprs + data[binds[i+1].val] = types.List.slice(exprs, i) break end data[binds[i].val] = exprs[i] diff --git a/impls/lua/step8_macros.lua b/impls/lua/step8_macros.lua index c1ee1e69b2..ce12dc864e 100755 --- a/impls/lua/step8_macros.lua +++ b/impls/lua/step8_macros.lua @@ -116,7 +116,7 @@ function EVAL(ast, env) local f = EVAL(a0, env) local args = types.slice(ast, 2) if types._macro_Q(f) then - ast = f.fn(table.unpack(args)) + ast = f.fn(table.unpack(args)) -- TCO else args = utils.map(function(x) return EVAL(x,env) end, args) if types._malfunc_Q(f) then diff --git a/impls/lua/step9_try.lua b/impls/lua/step9_try.lua index f621447384..a6fe507d5f 100755 --- a/impls/lua/step9_try.lua +++ b/impls/lua/step9_try.lua @@ -99,23 +99,24 @@ function EVAL(ast, env) mac.ismacro = true return env:set(a1.val, mac) elseif 'try*' == a0sym then + if a2 == nil or a2[1].val ~= 'catch*' then + ast = a1 -- TCO + else local exc, result = nil, nil xpcall(function() result = EVAL(a1, env) end, function(err) exc = err end) - if exc ~= nil then + if exc == nil then + return result + else if types._malexception_Q(exc) then exc = exc.val end - if a2 and a2[1].val == 'catch*' then - result = EVAL(a2[3], Env:new(env, {a2[2]}, {exc})) - else - types.throw(exc) - end + ast, env = a2[3], Env:new(env, {a2[2]}, {exc}) -- TCO end - return result + end elseif 'do' == a0sym then utils.map(function(x) return EVAL(x, env) end, types.slice(ast, 2, #ast - 1)) ast = ast[#ast] -- TCO @@ -134,7 +135,7 @@ function EVAL(ast, env) local f = EVAL(a0, env) local args = types.slice(ast, 2) if types._macro_Q(f) then - ast = f.fn(table.unpack(args)) + ast = f.fn(table.unpack(args)) -- TCO else args = utils.map(function(x) return EVAL(x,env) end, args) if types._malfunc_Q(f) then diff --git a/impls/lua/stepA_mal.lua b/impls/lua/stepA_mal.lua index 49f8a78d00..242b1cdda4 100755 --- a/impls/lua/stepA_mal.lua +++ b/impls/lua/stepA_mal.lua @@ -100,23 +100,24 @@ function EVAL(ast, env) mac.ismacro = true return env:set(a1.val, mac) elseif 'try*' == a0sym then + if a2 == nil or a2[1].val ~= 'catch*' then + ast = a1 -- TCO + else local exc, result = nil, nil xpcall(function() result = EVAL(a1, env) end, function(err) exc = err end) - if exc ~= nil then + if exc == nil then + return result + else if types._malexception_Q(exc) then exc = exc.val end - if a2 and a2[1].val == 'catch*' then - result = EVAL(a2[3], Env:new(env, {a2[2]}, {exc})) - else - types.throw(exc) - end + ast, env = a2[3], Env:new(env, {a2[2]}, {exc}) -- TCO end - return result + end elseif 'do' == a0sym then utils.map(function(x) return EVAL(x, env) end, types.slice(ast, 2, #ast - 1)) ast = ast[#ast] -- TCO @@ -135,7 +136,7 @@ function EVAL(ast, env) local f = EVAL(a0, env) local args = types.slice(ast, 2) if types._macro_Q(f) then - ast = f.fn(table.unpack(args)) + ast = f.fn(table.unpack(args)) -- TCO else args = utils.map(function(x) return EVAL(x,env) end, args) if types._malfunc_Q(f) then