about summary refs log tree commit diff stats
path: root/eval.lua
diff options
context:
space:
mode:
authorCase Duckworth2024-03-10 21:39:53 -0500
committerCase Duckworth2024-03-10 21:39:53 -0500
commita72ff678da253fce46e8e4648f6e4cf5ce1ea9b4 (patch)
treea82501fca97f4adc272d05145548d10cabe3ea2a /eval.lua
parentUgghhhh totally not working (diff)
downloadlam-a72ff678da253fce46e8e4648f6e4cf5ce1ea9b4.tar.gz
lam-a72ff678da253fce46e8e4648f6e4cf5ce1ea9b4.zip
uh new start
Diffstat (limited to 'eval.lua')
-rw-r--r--eval.lua126
1 files changed, 70 insertions, 56 deletions
diff --git a/eval.lua b/eval.lua index 806148d..6179842 100644 --- a/eval.lua +++ b/eval.lua
@@ -2,21 +2,20 @@
2 2
3local eval = {} 3local eval = {}
4local read = require "read" 4local read = require "read"
5local type = require "type"
5local util = require "util" 6local util = require "util"
6local pp = require "pp" 7local unpack = table.unpack or unpack
7local global = require "global"
8local types = require "types"
9table.unpack = table.unpack or unpack
10 8
11--- Environments and Parameters 9function eval.Env (inner, outer)
12-- these aren't in types.lua to avoid a circular dependency 10 local mt = {
13 11 __type = "Environment",
14local function Env(inner, outer) 12 __index = outer,
15 return setmetatable(inner, { __type = "Environment", __index = outer, }) 13 }
14 return setmetatable(inner, mt)
16end 15end
17 16
18local function Proc(params, body, env) 17function eval.Proc (params, body, env)
19 local p = { 18 local v = {
20 params = params, 19 params = params,
21 body = body, 20 body = body,
22 env = env, 21 env = env,
@@ -24,62 +23,77 @@ local function Proc(params, body, env)
24 local mt = { 23 local mt = {
25 __type = "Procedure", 24 __type = "Procedure",
26 __call = 25 __call =
27 function (self, ...) 26 function (self, args)
28 local inner = {} 27 local inner = {}
29 for _, p in ipairs(self.params) do 28 local p, a = self.params, args
30 for _, a in ipairs({...}) do 29 while p.cdr and a.cdr do
31 inner[p] = a 30 inner[p.car] = a.car
32 end 31 p, a = p.cdr, a.cdr
33 end 32 end
34 return eval(self.body, Env(inner, self.env)) 33 -- pp.pp(self.body)
34 return eval.eval(
35 self.body,
36 eval.Env(inner, self.env))
35 end, 37 end,
36 } 38 }
37 return setmetatable(p, mt) 39 return setmetatable(v, mt)
38end 40end
39 41
40function eval.eval (x, e) 42local global = {
41 e = e or global 43 begin =
42 if types.lamtype(x) == "Symbol" then 44 function (args)
43 return e[x] 45 local a = args
44 elseif types.luatype(x) ~= "table" then 46 while not type.isNull(a.cdr) do
47 a = a.cdr
48 end
49 return a.car
50 end,
51 ["+"] =
52 function (args)
53 local acc = 0
54 local car, cdr = args.car, args.cdr
55 while cdr do
56 acc = acc + car
57 car, cdr = cdr.car, cdr.cdr
58 end
59 return acc
60 end,
61 ["-"] =
62 function (args)
63 return args.car - args.cdr.car
64 end,
65}
66
67function eval.eval (x, env)
68 env = env or global
69 if type.isa(x, "Symbol") then
70 return env[x]
71 elseif not type.isList(x) then
45 return x 72 return x
46 else 73 else
47 local op = util.car(x) 74 local op, args = x.car, x.cdr
48 local args = util.cdr(x) 75 if op == "quote" then
49 if op == types.Symbol("quote") then 76 return args
50 return args[1] 77 elseif op == "define" then
51 elseif op == types.Symbol("define") then 78 env[args.car] = eval.eval(args.cdr.car, env)
52 local sym, exp = table.unpack(args) 79 return nil
53 e[sym] = eval(exp, e) 80 elseif op == "lambda" then
54 --[[ 81 return eval.Proc(
55 elseif op == "set!" then 82 args.car,
56 local sym, exp = table.unpack(args) 83 type.Cons("begin", args.cdr),
57 e[sym] = eval(exp, e) --]] 84 env)
58 elseif op == types.Symbol("lambda") then 85 else -- procedure
59 local params = util.car(args) 86 local proc = eval.eval(op, env)
60 local body = util.cdr(args) 87 local params = {}
61 table.insert(body, 1, "begin") 88 local a = args
62 return Proc(params, 89 while a.cdr do
63 body, 90 table.insert(params, eval.eval(a.car, env))
64 e) 91 a = a.cdr
65 else -- procedure call
66 local proc = eval(op, e)
67 local vals = {}
68 for k, v in pairs(args) do
69 vals[k] = eval(v, e)
70 end 92 end
71 return proc(table.unpack(vals)) 93 return proc(type.List(params))
72 end 94 end
73 end 95 end
74end 96end
75 97
76--- 98---
77return setmetatable(eval, { __call = 99return eval
78 function(_, x, e)
79 local success, result =
80 pcall(eval.eval, x, e)
81 if success then return result
82 else return ("ERROR: " .. result)
83 end
84 end
85})