about summary refs log tree commit diff stats
path: root/eval.lua
diff options
context:
space:
mode:
authorCase Duckworth2024-02-21 22:20:45 -0600
committerCase Duckworth2024-02-21 22:20:45 -0600
commit65a1c1f8820425e5a531a1bd4d652390489d4f9c (patch)
tree5a2bcaba8244e11d764c29752ab1b5da68b2c6ad /eval.lua
parentAdd makefile (diff)
downloadlam-65a1c1f8820425e5a531a1bd4d652390489d4f9c.tar.gz
lam-65a1c1f8820425e5a531a1bd4d652390489d4f9c.zip
Fix weird eval problem
Don't do things ya don't get, kids
Diffstat (limited to 'eval.lua')
-rw-r--r--eval.lua95
1 files changed, 54 insertions, 41 deletions
diff --git a/eval.lua b/eval.lua index 3decded..d441859 100644 --- a/eval.lua +++ b/eval.lua
@@ -2,36 +2,53 @@
2 2
3local eval = {} 3local eval = {}
4local read = require "read" 4local read = require "read"
5local types = require "types"
6local util = require "util" 5local util = require "util"
7local pp = require "pp" 6local pp = require "pp"
8 7
9Env = types.Object:new { 8local function Type (x)
10 __type = "Environment", 9 if type(x) == "string" then
11 __extend = 10 return "Symbol"
12 function(self, parms, args, outer) 11 elseif type(x) == "number" then
13 for _, p in ipairs(parms) do 12 return "Number"
14 for _, a in ipairs(args) do 13 elseif getmetatable(x) and getmetatable(x).__type then
15 self[p] = a 14 return x.__type
16 end 15 elseif type(x) == "table" then
17 end 16 return "List"
18 getmetatable(self).__index = outer 17 else
19 end, 18 return type(x)
20} 19 end
20end
21 21
22Proc = types.Object:new { 22local Symbol = tostring
23 __type = "Procedure", 23local Number = tonumber
24 __call = 24
25 function (self, args) 25local function Env(inner, outer)
26 local e = Env:new() 26 return setmetatable(inner, { __type = "Environment", __index = outer, })
27 e:__extend(self.parms, 27end
28 util.table(args), 28
29 self.env) 29local function Proc(params, body, env)
30 return eval(self.body[1], e) 30 local p = {
31 end 31 params = params,
32} 32 body = body,
33 env = env,
34 }
35 local mt = {
36 __type = "Procedure",
37 __call =
38 function (self, ...)
39 local inner = {}
40 for _, p in ipairs(self.params) do
41 for _, a in ipairs({...}) do
42 inner[p] = a
43 end
44 end
45 return eval(self.body, Env(inner, self.env))
46 end,
47 }
48 return setmetatable(p, mt)
49end
33 50
34global_env = Env:new { 51local global_env = {
35 -- constants 52 -- constants
36 ["#t"] = true, 53 ["#t"] = true,
37 ["#f"] = false, 54 ["#f"] = false,
@@ -56,11 +73,11 @@ global_env = Env:new {
56 end, 73 end,
57 ["number?"] = 74 ["number?"] =
58 function(x) 75 function(x)
59 return types.Type(x) == "Number" 76 return Type(x) == "Number"
60 end, 77 end,
61 ["symbol?"] = 78 ["symbol?"] =
62 function(x) 79 function(x)
63 return types.Type(x) == "Symbol" 80 return Type(x) == "Symbol"
64 end, 81 end,
65 -- scheme functions 82 -- scheme functions
66 ["apply"] = 83 ["apply"] =
@@ -95,9 +112,9 @@ end
95 112
96function eval.eval (x, env) 113function eval.eval (x, env)
97 env = env or global_env 114 env = env or global_env
98 if types.Type(x) == "Symbol" then 115 if Type(x) == "Symbol" then
99 return env[x] 116 return env[x]
100 elseif types.Type(x) ~= "List" then 117 elseif type(x) ~= "table" then
101 return x 118 return x
102 else 119 else
103 local op = util.car(x) 120 local op = util.car(x)
@@ -107,19 +124,15 @@ function eval.eval (x, env)
107 elseif op == "define" then 124 elseif op == "define" then
108 local sym, exp = table.unpack(args) 125 local sym, exp = table.unpack(args)
109 env[sym] = eval(exp, env) 126 env[sym] = eval(exp, env)
110 elseif op == "set!" then 127 --[[
111 local sym, exp = table.unpack(args) 128 elseif op == "set!" then
112 env[sym] = eval(exp, env) 129 local sym, exp = table.unpack(args)
130 env[sym] = eval(exp, env) --]]
113 elseif op == "lambda" then 131 elseif op == "lambda" then
114 local parms = util.car(args) 132 local params = util.car(args)
115 local body = util.cdr(args) 133 local body = util.cdr(args)[1]
116 return Proc:new { 134 return Proc(params, body, env)
117 parms = parms,
118 body = body,
119 env = env,
120 }
121 else -- procedure call 135 else -- procedure call
122 pp(op)
123 local proc = eval(op, env) 136 local proc = eval(op, env)
124 local vals = util.map( 137 local vals = util.map(
125 function(v) return eval(v, env) end, 138 function(v) return eval(v, env) end,
@@ -142,4 +155,4 @@ return setmetatable(eval, { __call =
142 155
143--[[ 156--[[
144 (begin (define sq (lambda (x) (* x x))) (define rep (lambda (f) (lambda (x) (f (f x)))))) 157 (begin (define sq (lambda (x) (* x x))) (define rep (lambda (f) (lambda (x) (f (f x))))))
145-- ]] 158 -- ]]