From 4fb6e90474c8e9292df1a6210b8de260dd253ccb Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Sat, 23 Mar 2024 15:51:07 -0500 Subject: Break special forms out into their own table --- eval.lua | 53 ++++++++++++++++++++++++++++++++++++----------------- 1 file 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) return setmetatable(v, mt) end +local specials = { + quote = + function (args, env) + return args.car + end, + define = + function (args, env) + rawset(env, args.car, eval(args.cdr.car, env)) + return nil + end, + lambda = + function (args, env) + return Proc(args.car, args.cdr, env) + end, + ["set!"] = + function (args, env) + env[args.car] = eval(args.cdr.car, env) + return nil + end, + ["if"] = + function (args, env) + local test, conseq, alt = + args.car, args.cdr.car, args.cdr.cdr.car + if eval(test) + then return eval(conseq) + else return eval(alt) + end + end, + -- TODO: include, import, define-syntax, define-values(?) ... +} +-- Aliases +specials.lam = specials.lambda +specials.def = specials.define + function eval.eval (x, env) env = env or base.env if isa(x, "Symbol") then @@ -61,23 +95,8 @@ function eval.eval (x, env) return x else local op, args = x.car, x.cdr - if op == "quote" then - return args.car - elseif op == "define" or op == "def" then - rawset(env, args.car, eval.eval(args.cdr.car, env)) - return nil - elseif op == "set!" then - env[args.car] = eval.eval(args.cdr.car, env) - elseif op == "lambda" or op == "lam" then - return eval.Proc(args.car, args.cdr, env) - elseif op == "if" then - assert(not isNull(args.cdr), "Malformed 'if'") - local test, conseq, alt = - args.car, args.cdr.car, args.cdr.cdr.car - if eval.eval(test) - then return eval.eval(conseq) - else return eval.eval(alt) - end + if specials[op] then + return specials[op](args, env) else -- procedure local proc = eval.eval(op, env) local params = {} -- cgit 1.4.1-21-gabe81