about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorCase Duckworth2024-03-23 15:51:07 -0500
committerCase Duckworth2024-03-23 15:51:27 -0500
commit4fb6e90474c8e9292df1a6210b8de260dd253ccb (patch)
treeae56acdb2d090ed36184b36635f41b692a652188
parentAdd a bunch of base functions (diff)
downloadlam-4fb6e90474c8e9292df1a6210b8de260dd253ccb.tar.gz
lam-4fb6e90474c8e9292df1a6210b8de260dd253ccb.zip
Break special forms out into their own table
-rw-r--r--eval.lua53
1 files changed, 36 insertions, 17 deletions
diff --git a/eval.lua b/eval.lua index 9b1c315..610b902 100644 --- a/eval.lua +++ b/eval.lua
@@ -53,6 +53,40 @@ function eval.Proc (params, body, env)
53 return setmetatable(v, mt) 53 return setmetatable(v, mt)
54end 54end
55 55
56local specials = {
57 quote =
58 function (args, env)
59 return args.car
60 end,
61 define =
62 function (args, env)
63 rawset(env, args.car, eval(args.cdr.car, env))
64 return nil
65 end,
66 lambda =
67 function (args, env)
68 return Proc(args.car, args.cdr, env)
69 end,
70 ["set!"] =
71 function (args, env)
72 env[args.car] = eval(args.cdr.car, env)
73 return nil
74 end,
75 ["if"] =
76 function (args, env)
77 local test, conseq, alt =
78 args.car, args.cdr.car, args.cdr.cdr.car
79 if eval(test)
80 then return eval(conseq)
81 else return eval(alt)
82 end
83 end,
84 -- TODO: include, import, define-syntax, define-values(?) ...
85}
86-- Aliases
87specials.lam = specials.lambda
88specials.def = specials.define
89
56function eval.eval (x, env) 90function eval.eval (x, env)
57 env = env or base.env 91 env = env or base.env
58 if isa(x, "Symbol") then 92 if isa(x, "Symbol") then
@@ -61,23 +95,8 @@ function eval.eval (x, env)
61 return x 95 return x
62 else 96 else
63 local op, args = x.car, x.cdr 97 local op, args = x.car, x.cdr
64 if op == "quote" then 98 if specials[op] then
65 return args.car 99 return specials[op](args, env)
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
81 else -- procedure 100 else -- procedure
82 local proc = eval.eval(op, env) 101 local proc = eval.eval(op, env)
83 local params = {} 102 local params = {}