diff options
author | Case Duckworth | 2024-03-21 17:55:21 -0500 |
---|---|---|
committer | Case Duckworth | 2024-03-21 17:55:21 -0500 |
commit | 4f4494a9b1057e1807488ed44b05d9fb9ce97b48 (patch) | |
tree | 682773855da708efd66f831eab36a895ddbd07a2 | |
parent | Correct bugs with whitespace and spurious opening parens (diff) | |
download | lam-4f4494a9b1057e1807488ed44b05d9fb9ce97b48.tar.gz lam-4f4494a9b1057e1807488ed44b05d9fb9ce97b48.zip |
Implment set!
-rw-r--r-- | eval.lua | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/eval.lua b/eval.lua index f58c36e..9b1c315 100644 --- a/eval.lua +++ b/eval.lua | |||
@@ -11,6 +11,16 @@ function eval.Env (inner, outer) | |||
11 | local mt = { | 11 | local mt = { |
12 | __type = "Environment", | 12 | __type = "Environment", |
13 | __index = outer, | 13 | __index = outer, |
14 | __newindex = | ||
15 | function (self, key, value) | ||
16 | if rawget(self, key) then | ||
17 | -- Set the current environment's value | ||
18 | rawset(self, key, value) | ||
19 | else | ||
20 | -- Set the outer value | ||
21 | getmetatable(self).__index[key] = value | ||
22 | end | ||
23 | end, | ||
14 | } | 24 | } |
15 | return setmetatable(inner, mt) | 25 | return setmetatable(inner, mt) |
16 | end | 26 | end |
@@ -54,8 +64,10 @@ function eval.eval (x, env) | |||
54 | if op == "quote" then | 64 | if op == "quote" then |
55 | return args.car | 65 | return args.car |
56 | elseif op == "define" or op == "def" then | 66 | elseif op == "define" or op == "def" then |
57 | env[args.car] = eval.eval(args.cdr.car, env) | 67 | rawset(env, args.car, eval.eval(args.cdr.car, env)) |
58 | return nil | 68 | return nil |
69 | elseif op == "set!" then | ||
70 | env[args.car] = eval.eval(args.cdr.car, env) | ||
59 | elseif op == "lambda" or op == "lam" then | 71 | elseif op == "lambda" or op == "lam" then |
60 | return eval.Proc(args.car, args.cdr, env) | 72 | return eval.Proc(args.car, args.cdr, env) |
61 | elseif op == "if" then | 73 | elseif op == "if" then |