diff options
Diffstat (limited to 'eval.lua')
-rw-r--r-- | eval.lua | 39 |
1 files changed, 6 insertions, 33 deletions
diff --git a/eval.lua b/eval.lua index 5e897e2..e926bc4 100644 --- a/eval.lua +++ b/eval.lua | |||
@@ -1,6 +1,7 @@ | |||
1 | --- lam.eval | 1 | --- lam.eval |
2 | 2 | ||
3 | local eval = {} | 3 | local eval = {} |
4 | local base = require "base" | ||
4 | local type = require "type" | 5 | local type = require "type" |
5 | local isNull, isList, isa, List, Cons = | 6 | local isNull, isList, isa, List, Cons = |
6 | type.isNull, type.isList, type.isa, type.List, type.Cons | 7 | type.isNull, type.isList, type.isa, type.List, type.Cons |
@@ -30,6 +31,7 @@ function eval.Proc (params, body, env) | |||
30 | inner[p.car] = a.car | 31 | inner[p.car] = a.car |
31 | p, a = p.cdr, a.cdr | 32 | p, a = p.cdr, a.cdr |
32 | end | 33 | end |
34 | pp.pp(self.body) | ||
33 | return eval.eval( | 35 | return eval.eval( |
34 | self.body, | 36 | self.body, |
35 | eval.Env(inner, self.env)) | 37 | eval.Env(inner, self.env)) |
@@ -38,37 +40,8 @@ function eval.Proc (params, body, env) | |||
38 | return setmetatable(v, mt) | 40 | return setmetatable(v, mt) |
39 | end | 41 | end |
40 | 42 | ||
41 | local global = { | ||
42 | begin = | ||
43 | function (r) | ||
44 | local r = r | ||
45 | while not isNull(r.cdr) do | ||
46 | r = r.cdr | ||
47 | end | ||
48 | return r.car | ||
49 | end, | ||
50 | ["+"] = | ||
51 | function (r) | ||
52 | local r, a = r, 0 | ||
53 | while r.cdr do | ||
54 | r, a = r.cdr, a + r.car | ||
55 | end | ||
56 | return a | ||
57 | end, | ||
58 | ["-"] = | ||
59 | function (r) | ||
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 | ||
67 | end, | ||
68 | } | ||
69 | |||
70 | function eval.eval (x, env) | 43 | function eval.eval (x, env) |
71 | env = env or global | 44 | env = env or base.env |
72 | if isa(x, "Symbol") then | 45 | if isa(x, "Symbol") then |
73 | return env[x] | 46 | return env[x] |
74 | elseif not isList(x) then | 47 | elseif not isList(x) then |
@@ -77,13 +50,13 @@ function eval.eval (x, env) | |||
77 | local op, args = x.car, x.cdr | 50 | local op, args = x.car, x.cdr |
78 | if op == "quote" then | 51 | if op == "quote" then |
79 | return args.car | 52 | return args.car |
80 | elseif op == "define" then | 53 | elseif op == "define" or op == "def" then |
81 | env[args.car] = eval.eval(args.cdr.car, env) | 54 | env[args.car] = eval.eval(args.cdr.car, env) |
82 | return nil | 55 | return nil |
83 | elseif op == "lambda" then | 56 | elseif op == "lambda" or op == "lam" then |
84 | return eval.Proc( | 57 | return eval.Proc( |
85 | args.car, | 58 | args.car, |
86 | Cons("begin", args.cdr), | 59 | Cons("begin", args.cdr), -- i don't like this |
87 | env) | 60 | env) |
88 | elseif op == "if" then | 61 | elseif op == "if" then |
89 | assert(not isNull(args.cdr), "Malformed 'if'") | 62 | assert(not isNull(args.cdr), "Malformed 'if'") |