diff options
author | Case Duckworth | 2024-03-21 22:42:13 -0500 |
---|---|---|
committer | Case Duckworth | 2024-03-21 22:42:13 -0500 |
commit | cf430149b8e7317eceb8ac0f36e7b5f7d32a8bdb (patch) | |
tree | 682773855da708efd66f831eab36a895ddbd07a2 | |
parent | Refactor eval (diff) | |
download | lam-cf430149b8e7317eceb8ac0f36e7b5f7d32a8bdb.tar.gz lam-cf430149b8e7317eceb8ac0f36e7b5f7d32a8bdb.zip |
Revert "Refactor eval"
This reverts commit 1d5041ff7bf92458d6d07ac6a03f2747dce9b9b1.
-rw-r--r-- | eval.lua | 75 |
1 files changed, 27 insertions, 48 deletions
diff --git a/eval.lua b/eval.lua index 39a5bbe..9b1c315 100644 --- a/eval.lua +++ b/eval.lua | |||
@@ -1,12 +1,13 @@ | |||
1 | --- lam.eval | 1 | --- lam.eval |
2 | 2 | ||
3 | local eval = {} | ||
3 | local base = require "base" | 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 |
7 | local unpack = table.unpack or unpack | 8 | local unpack = table.unpack or unpack |
8 | 9 | ||
9 | local function Env (inner, outer) | 10 | function eval.Env (inner, outer) |
10 | local mt = { | 11 | local mt = { |
11 | __type = "Environment", | 12 | __type = "Environment", |
12 | __index = outer, | 13 | __index = outer, |
@@ -24,7 +25,7 @@ local function Env (inner, outer) | |||
24 | return setmetatable(inner, mt) | 25 | return setmetatable(inner, mt) |
25 | end | 26 | end |
26 | 27 | ||
27 | local function Proc (params, body, env) | 28 | function eval.Proc (params, body, env) |
28 | local v = { | 29 | local v = { |
29 | params = params, | 30 | params = params, |
30 | body = body, | 31 | body = body, |
@@ -41,51 +42,18 @@ local function Proc (params, body, env) | |||
41 | p, a = p.cdr, a.cdr | 42 | p, a = p.cdr, a.cdr |
42 | end | 43 | end |
43 | local b = self.body | 44 | local b = self.body |
44 | local e = Env(inner, self.env) | 45 | local e = eval.Env(inner, self.env) |
45 | while not isNull(b.cdr) do | 46 | while not isNull(b.cdr) do |
46 | eval(b.car, e) | 47 | eval.eval(b.car, e) |
47 | b = b.cdr | 48 | b = b.cdr |
48 | end | 49 | end |
49 | return eval(b.car, e) | 50 | return eval.eval(b.car, e) |
50 | end, | 51 | end, |
51 | } | 52 | } |
52 | return setmetatable(v, mt) | 53 | return setmetatable(v, mt) |
53 | end | 54 | end |
54 | 55 | ||
55 | local specials = { | 56 | function eval.eval (x, env) |
56 | quote = | ||
57 | function (args, env) | ||
58 | return args.car | ||
59 | end, | ||
60 | define = | ||
61 | function (args, env) | ||
62 | rawset(env, args.car, eval(args.cdr.car, env)) | ||
63 | return nil | ||
64 | end, | ||
65 | lambda = | ||
66 | function (args, env) | ||
67 | return Proc(args.car, args.cdr, env) | ||
68 | end, | ||
69 | ["set!"] = | ||
70 | function (args, env) | ||
71 | env[args.car] = eval(args.cdr.car, env) | ||
72 | return nil | ||
73 | end, | ||
74 | ["if"] = | ||
75 | function (args, env) | ||
76 | local test, conseq, alt = | ||
77 | args.car, args.cdr.car, args.cdr.cdr.car | ||
78 | if eval(test) | ||
79 | then return eval(conseq) | ||
80 | else return eval(alt) | ||
81 | end | ||
82 | end, | ||
83 | } | ||
84 | -- Aliases | ||
85 | specials.lam = specials.lambda | ||
86 | specials.def = specials.define | ||
87 | |||
88 | local function eval (x, env) | ||
89 | env = env or base.env | 57 | env = env or base.env |
90 | if isa(x, "Symbol") then | 58 | if isa(x, "Symbol") then |
91 | return env[x] | 59 | return env[x] |
@@ -93,14 +61,29 @@ local function eval (x, env) | |||
93 | return x | 61 | return x |
94 | else | 62 | else |
95 | local op, args = x.car, x.cdr | 63 | local op, args = x.car, x.cdr |
96 | if specials[op] then | 64 | if op == "quote" then |
97 | return specials[op](args, env) | 65 | return args.car |
66 | elseif op == "define" or op == "def" then | ||
67 | rawset(env, args.car, eval.eval(args.cdr.car, env)) | ||
68 | return nil | ||
69 | elseif op == "set!" then | ||
70 | env[args.car] = eval.eval(args.cdr.car, env) | ||
71 | elseif op == "lambda" or op == "lam" then | ||
72 | return eval.Proc(args.car, args.cdr, env) | ||
73 | elseif op == "if" then | ||
74 | assert(not isNull(args.cdr), "Malformed 'if'") | ||
75 | local test, conseq, alt = | ||
76 | args.car, args.cdr.car, args.cdr.cdr.car | ||
77 | if eval.eval(test) | ||
78 | then return eval.eval(conseq) | ||
79 | else return eval.eval(alt) | ||
80 | end | ||
98 | else -- procedure | 81 | else -- procedure |
99 | local proc = eval(op, env) | 82 | local proc = eval.eval(op, env) |
100 | local params = {} | 83 | local params = {} |
101 | local a = args | 84 | local a = args |
102 | while a.cdr do | 85 | while a.cdr do |
103 | table.insert(params, eval(a.car, env)) | 86 | table.insert(params, eval.eval(a.car, env)) |
104 | a = a.cdr | 87 | a = a.cdr |
105 | end | 88 | end |
106 | return proc(List(params)) | 89 | return proc(List(params)) |
@@ -109,8 +92,4 @@ local function eval (x, env) | |||
109 | end | 92 | end |
110 | 93 | ||
111 | --- | 94 | --- |
112 | return { | 95 | return eval |
113 | Env = Env, | ||
114 | Proc = Proc, | ||
115 | eval = eval, | ||
116 | } | ||