about summary refs log tree commit diff stats
path: root/eval.lua
diff options
context:
space:
mode:
authorCase Duckworth2024-02-22 00:23:32 -0600
committerCase Duckworth2024-02-22 00:23:32 -0600
commit5328b62221a3839dca117d71a4703f3ad719c9ce (patch)
tree7212235f569e765d3a4ebed0e8d21b64d905bf3a /eval.lua
parentRemove spurious require (diff)
downloadlam-5328b62221a3839dca117d71a4703f3ad719c9ce.tar.gz
lam-5328b62221a3839dca117d71a4703f3ad719c9ce.zip
Add global and types libraries
Diffstat (limited to 'eval.lua')
-rw-r--r--eval.lua119
1 files changed, 22 insertions, 97 deletions
diff --git a/eval.lua b/eval.lua index d441859..cdf4612 100644 --- a/eval.lua +++ b/eval.lua
@@ -4,23 +4,10 @@ local eval = {}
4local read = require "read" 4local read = require "read"
5local util = require "util" 5local util = require "util"
6local pp = require "pp" 6local pp = require "pp"
7local global = require "global"
8local types = require("types")
7 9
8local function Type (x) 10if not table.unpack then table.unpack = unpack end
9 if type(x) == "string" then
10 return "Symbol"
11 elseif type(x) == "number" then
12 return "Number"
13 elseif getmetatable(x) and getmetatable(x).__type then
14 return x.__type
15 elseif type(x) == "table" then
16 return "List"
17 else
18 return type(x)
19 end
20end
21
22local Symbol = tostring
23local Number = tonumber
24 11
25local function Env(inner, outer) 12local function Env(inner, outer)
26 return setmetatable(inner, { __type = "Environment", __index = outer, }) 13 return setmetatable(inner, { __type = "Environment", __index = outer, })
@@ -48,73 +35,11 @@ local function Proc(params, body, env)
48 return setmetatable(p, mt) 35 return setmetatable(p, mt)
49end 36end
50 37
51local global_env = { 38function eval.eval (x, e)
52 -- constants 39 e = e or global
53 ["#t"] = true, 40 if types.lamtype(x) == "Symbol" then
54 ["#f"] = false, 41 return e[x]
55 -- basic math 42 elseif types.luatype(x) ~= "table" then
56 ["+"] =
57 function (...)
58 print(...)
59 return util.reduce(
60 {...}, 0,
61 function (a, b) return a + b end)
62 end,
63 ["*"] =
64 function (...)
65 return util.reduce(
66 {...}, 1,
67 function (a, b) return a * b end)
68 end,
69 -- scheme predicates
70 ["null?"] =
71 function(x)
72 return x == {}
73 end,
74 ["number?"] =
75 function(x)
76 return Type(x) == "Number"
77 end,
78 ["symbol?"] =
79 function(x)
80 return Type(x) == "Symbol"
81 end,
82 -- scheme functions
83 ["apply"] =
84 function(fn, ...)
85 local args = {...}
86 local last = args[#args]
87 assert(type(last)=="table", "Bad apply")
88 table.remove(args)
89 for _,v in ipairs(last) do
90 table.insert(args, v)
91 end
92 return fn(table.unpack(args))
93 end,
94 ["begin"] =
95 function(...)
96 local xs = {...}
97 return xs[#xs]
98 end,
99 ["map"] =
100 function(fn, ...)
101 return util.map(fn, {...})
102 end,
103 ["car"] = util.car,
104 ["cdr"] = util.cdr,
105 ["list"] = function(...) return {...} end,
106}
107
108-- Math
109for k, v in pairs(math) do
110 global_env[k] = v
111end
112
113function eval.eval (x, env)
114 env = env or global_env
115 if Type(x) == "Symbol" then
116 return env[x]
117 elseif type(x) ~= "table" then
118 return x 43 return x
119 else 44 else
120 local op = util.car(x) 45 local op = util.car(x)
@@ -123,20 +48,24 @@ function eval.eval (x, env)
123 return args[1] 48 return args[1]
124 elseif op == "define" then 49 elseif op == "define" then
125 local sym, exp = table.unpack(args) 50 local sym, exp = table.unpack(args)
126 env[sym] = eval(exp, env) 51 e[sym] = eval(exp, e)
127 --[[ 52 --[[
128 elseif op == "set!" then 53 elseif op == "set!" then
129 local sym, exp = table.unpack(args) 54 local sym, exp = table.unpack(args)
130 env[sym] = eval(exp, env) --]] 55 e[sym] = eval(exp, e) --]]
131 elseif op == "lambda" then 56 elseif op == "lambda" then
132 local params = util.car(args) 57 local params = util.car(args)
133 local body = util.cdr(args)[1] 58 local body = util.cdr(args)
134 return Proc(params, body, env) 59 table.insert(body, 1, "begin")
60 return Proc(params,
61 body,
62 e)
135 else -- procedure call 63 else -- procedure call
136 local proc = eval(op, env) 64 local proc = eval(op, e)
137 local vals = util.map( 65 local vals = {}
138 function(v) return eval(v, env) end, 66 for k, v in pairs(args) do
139 args) 67 vals[k] = eval(v, e)
68 end
140 return proc(table.unpack(vals)) 69 return proc(table.unpack(vals))
141 end 70 end
142 end 71 end
@@ -144,15 +73,11 @@ end
144 73
145--- 74---
146return setmetatable(eval, { __call = 75return setmetatable(eval, { __call =
147 function(_, x, env) 76 function(_, x, e)
148 local success, result = 77 local success, result =
149 pcall(eval.eval, x, env) 78 pcall(eval.eval, x, e)
150 if success then return result 79 if success then return result
151 else return ("ERROR: " .. result) 80 else return ("ERROR: " .. result)
152 end 81 end
153 end 82 end
154}) 83})
155
156--[[
157 (begin (define sq (lambda (x) (* x x))) (define rep (lambda (f) (lambda (x) (f (f x))))))
158 -- ]]