about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--eval.lua39
1 files changed, 23 insertions, 16 deletions
diff --git a/eval.lua b/eval.lua index c2945bf..53292d0 100644 --- a/eval.lua +++ b/eval.lua
@@ -20,6 +20,28 @@ function m.environ (inner, outer)
20 return setmetatable(inner, mt) 20 return setmetatable(inner, mt)
21end 21end
22 22
23local function call_proc (proc, r)
24 local function doargs (p, r, e)
25 if p == type.null and r == type.null then return e end
26 if type.isa(p, "symbol") then
27 e[p] = r
28 return e
29 end
30 if p[1] == nil then error("Too many arguments") end
31 if r[1] == nil then error("Too few arguments") end
32 e[p[1]] = r[1]
33 doargs(p[2], r[2], e)
34 end
35
36 local e = doargs(proc.params, r, m.environ({}, proc.env))
37 local b = proc.body
38 while b[2] ~= type.null do
39 m.eval(b[1], e)
40 b = b[2]
41 end
42 return m.eval(b[1], e)
43end
44
23function m.procedure (params, body, env) 45function m.procedure (params, body, env)
24 local t = { 46 local t = {
25 params = params, 47 params = params,
@@ -28,22 +50,7 @@ function m.procedure (params, body, env)
28 } 50 }
29 local mt = { 51 local mt = {
30 __type = "procedure", 52 __type = "procedure",
31 __call = 53 __call = call_proc,
32 function (self, args)
33 local inner = {}
34 local p, a = self.params, args
35 while p[2] and a[2] do
36 inner[p[1]] = a[1]
37 p, a = p[2], a[2]
38 end
39 local b = self.body
40 local e = m.environ(inner, self.env)
41 while not b[2] == type.null do
42 m.eval(b[1], e)
43 b = b[2]
44 end
45 return m.eval(b[1], e)
46 end,
47 } 54 }
48 return setmetatable(t, mt) 55 return setmetatable(t, mt)
49end 56end