about summary refs log tree commit diff stats
path: root/eval.lua
diff options
context:
space:
mode:
Diffstat (limited to 'eval.lua')
-rw-r--r--eval.lua55
1 files changed, 33 insertions, 22 deletions
diff --git a/eval.lua b/eval.lua index 6179842..5e897e2 100644 --- a/eval.lua +++ b/eval.lua
@@ -1,9 +1,9 @@
1--- lam.eval 1--- lam.eval
2 2
3local eval = {} 3local eval = {}
4local read = require "read"
5local type = require "type" 4local type = require "type"
6local util = require "util" 5local isNull, isList, isa, List, Cons =
6 type.isNull, type.isList, type.isa, type.List, type.Cons
7local unpack = table.unpack or unpack 7local unpack = table.unpack or unpack
8 8
9function eval.Env (inner, outer) 9function eval.Env (inner, outer)
@@ -30,7 +30,6 @@ function eval.Proc (params, body, env)
30 inner[p.car] = a.car 30 inner[p.car] = a.car
31 p, a = p.cdr, a.cdr 31 p, a = p.cdr, a.cdr
32 end 32 end
33 -- pp.pp(self.body)
34 return eval.eval( 33 return eval.eval(
35 self.body, 34 self.body,
36 eval.Env(inner, self.env)) 35 eval.Env(inner, self.env))
@@ -41,47 +40,59 @@ end
41 40
42local global = { 41local global = {
43 begin = 42 begin =
44 function (args) 43 function (r)
45 local a = args 44 local r = r
46 while not type.isNull(a.cdr) do 45 while not isNull(r.cdr) do
47 a = a.cdr 46 r = r.cdr
48 end 47 end
49 return a.car 48 return r.car
50 end, 49 end,
51 ["+"] = 50 ["+"] =
52 function (args) 51 function (r)
53 local acc = 0 52 local r, a = r, 0
54 local car, cdr = args.car, args.cdr 53 while r.cdr do
55 while cdr do 54 r, a = r.cdr, a + r.car
56 acc = acc + car
57 car, cdr = cdr.car, cdr.cdr
58 end 55 end
59 return acc 56 return a
60 end, 57 end,
61 ["-"] = 58 ["-"] =
62 function (args) 59 function (r)
63 return args.car - args.cdr.car 60 if isNull(r) then return -1 end
61 if isNull(r.cdr) then return (- r.car) end
62 local r, a = r.cdr, r.car
63 while r.cdr do
64 r, a = r.cdr, a - r.car
65 end
66 return a
64 end, 67 end,
65} 68}
66 69
67function eval.eval (x, env) 70function eval.eval (x, env)
68 env = env or global 71 env = env or global
69 if type.isa(x, "Symbol") then 72 if isa(x, "Symbol") then
70 return env[x] 73 return env[x]
71 elseif not type.isList(x) then 74 elseif not isList(x) then
72 return x 75 return x
73 else 76 else
74 local op, args = x.car, x.cdr 77 local op, args = x.car, x.cdr
75 if op == "quote" then 78 if op == "quote" then
76 return args 79 return args.car
77 elseif op == "define" then 80 elseif op == "define" then
78 env[args.car] = eval.eval(args.cdr.car, env) 81 env[args.car] = eval.eval(args.cdr.car, env)
79 return nil 82 return nil
80 elseif op == "lambda" then 83 elseif op == "lambda" then
81 return eval.Proc( 84 return eval.Proc(
82 args.car, 85 args.car,
83 type.Cons("begin", args.cdr), 86 Cons("begin", args.cdr),
84 env) 87 env)
88 elseif op == "if" then
89 assert(not isNull(args.cdr), "Malformed 'if'")
90 local test, conseq, alt =
91 args.car, args.cdr.car, args.cdr.cdr.car
92 if eval.eval(test)
93 then return eval.eval(conseq)
94 else return eval.eval(alt)
95 end
85 else -- procedure 96 else -- procedure
86 local proc = eval.eval(op, env) 97 local proc = eval.eval(op, env)
87 local params = {} 98 local params = {}
@@ -90,7 +101,7 @@ function eval.eval (x, env)
90 table.insert(params, eval.eval(a.car, env)) 101 table.insert(params, eval.eval(a.car, env))
91 a = a.cdr 102 a = a.cdr
92 end 103 end
93 return proc(type.List(params)) 104 return proc(List(params))
94 end 105 end
95 end 106 end
96end 107end