diff options
author | Case Duckworth | 2024-03-23 15:51:07 -0500 |
---|---|---|
committer | Case Duckworth | 2024-03-23 15:51:27 -0500 |
commit | 4fb6e90474c8e9292df1a6210b8de260dd253ccb (patch) | |
tree | ae56acdb2d090ed36184b36635f41b692a652188 | |
parent | Add a bunch of base functions (diff) | |
download | lam-4fb6e90474c8e9292df1a6210b8de260dd253ccb.tar.gz lam-4fb6e90474c8e9292df1a6210b8de260dd253ccb.zip |
Break special forms out into their own table
-rw-r--r-- | eval.lua | 53 |
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) |
54 | end | 54 | end |
55 | 55 | ||
56 | local 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 | ||
87 | specials.lam = specials.lambda | ||
88 | specials.def = specials.define | ||
89 | |||
56 | function eval.eval (x, env) | 90 | function 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 = {} |