about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--eval.lua44
1 files changed, 35 insertions, 9 deletions
diff --git a/eval.lua b/eval.lua index e13fb97..714c67e 100644 --- a/eval.lua +++ b/eval.lua
@@ -48,17 +48,43 @@ function m.procedure (params, body, env)
48 return setmetatable(t, mt) 48 return setmetatable(t, mt)
49end 49end
50 50
51local specials = {
52m.specials = { 51m.specials = {
53 -- each of these takes R (a list of args) and E (an environment) 52 -- each of these takes R (a list of args) and E (an environment)
54 quote = 53 quote = function (r, e) return r[1] end,
55 function (r, e) return r[1] end, 54 quasiquote =
56 define = 55 function (r, e)
57 function (r, e) rawset(e, r[1], m.eval(r[2][1], e)) end, 56 local x = r[1]
58 lambda = 57 if not type.islist(x) or x == type.null then
59 function (r, e) return m.procedure(r[1], r[2], e) end, 58 return x
60 ["set!"] = 59 end
61 function (r, e) e[r[1]] = m.eval(r[2][1], e) end, 60 local QQ, fin = {}, nil
61 local car, cdr = x[1], x[2]
62 while cdr do
63 if type.islist(car) then
64 if car[1] == "unquote" then
65 table.insert(QQ,
66 m.eval(car[2][1], e))
67 elseif car[1] == "unquote-splicing" then
68 local usl = m.eval(car[2][1], e)
69 if not type.islist(usl) then
70 fin = usl
71 break
72 end
73 while usl[2] do
74 table.insert(QQ, usl[1])
75 usl = usl[2]
76 end
77 end
78 else
79 table.insert(QQ, car)
80 end
81 car, cdr = cdr[1], cdr[2]
82 end
83 return type.list(QQ, fin)
84 end,
85 define = function (r, e) rawset(e, r[1], m.eval(r[2][1], e)) end,
86 lambda = function (r, e) return m.procedure(r[1], r[2], e) end,
87 ["set!"] = function (r, e) e[r[1]] = m.eval(r[2][1], e) end,
62 ["if"] = 88 ["if"] =
63 function (r, e) 89 function (r, e)
64 local test, conseq, alt = 90 local test, conseq, alt =