From a72ff678da253fce46e8e4648f6e4cf5ce1ea9b4 Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Sun, 10 Mar 2024 21:39:53 -0500 Subject: uh new start --- eval.lua | 126 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 70 insertions(+), 56 deletions(-) (limited to 'eval.lua') diff --git a/eval.lua b/eval.lua index 806148d..6179842 100644 --- a/eval.lua +++ b/eval.lua @@ -2,21 +2,20 @@ local eval = {} local read = require "read" +local type = require "type" local util = require "util" -local pp = require "pp" -local global = require "global" -local types = require "types" -table.unpack = table.unpack or unpack +local unpack = table.unpack or unpack ---- Environments and Parameters --- these aren't in types.lua to avoid a circular dependency - -local function Env(inner, outer) - return setmetatable(inner, { __type = "Environment", __index = outer, }) +function eval.Env (inner, outer) + local mt = { + __type = "Environment", + __index = outer, + } + return setmetatable(inner, mt) end -local function Proc(params, body, env) - local p = { +function eval.Proc (params, body, env) + local v = { params = params, body = body, env = env, @@ -24,62 +23,77 @@ local function Proc(params, body, env) local mt = { __type = "Procedure", __call = - function (self, ...) + function (self, args) local inner = {} - for _, p in ipairs(self.params) do - for _, a in ipairs({...}) do - inner[p] = a - end + local p, a = self.params, args + while p.cdr and a.cdr do + inner[p.car] = a.car + p, a = p.cdr, a.cdr end - return eval(self.body, Env(inner, self.env)) + -- pp.pp(self.body) + return eval.eval( + self.body, + eval.Env(inner, self.env)) end, } - return setmetatable(p, mt) + return setmetatable(v, mt) end -function eval.eval (x, e) - e = e or global - if types.lamtype(x) == "Symbol" then - return e[x] - elseif types.luatype(x) ~= "table" then +local global = { + begin = + function (args) + local a = args + while not type.isNull(a.cdr) do + a = a.cdr + end + return a.car + end, + ["+"] = + function (args) + local acc = 0 + local car, cdr = args.car, args.cdr + while cdr do + acc = acc + car + car, cdr = cdr.car, cdr.cdr + end + return acc + end, + ["-"] = + function (args) + return args.car - args.cdr.car + end, +} + +function eval.eval (x, env) + env = env or global + if type.isa(x, "Symbol") then + return env[x] + elseif not type.isList(x) then return x else - local op = util.car(x) - local args = util.cdr(x) - if op == types.Symbol("quote") then - return args[1] - elseif op == types.Symbol("define") then - local sym, exp = table.unpack(args) - e[sym] = eval(exp, e) - --[[ - elseif op == "set!" then - local sym, exp = table.unpack(args) - e[sym] = eval(exp, e) --]] - elseif op == types.Symbol("lambda") then - local params = util.car(args) - local body = util.cdr(args) - table.insert(body, 1, "begin") - return Proc(params, - body, - e) - else -- procedure call - local proc = eval(op, e) - local vals = {} - for k, v in pairs(args) do - vals[k] = eval(v, e) + local op, args = x.car, x.cdr + if op == "quote" then + return args + elseif op == "define" then + env[args.car] = eval.eval(args.cdr.car, env) + return nil + elseif op == "lambda" then + return eval.Proc( + args.car, + type.Cons("begin", args.cdr), + env) + else -- procedure + local proc = eval.eval(op, env) + local params = {} + local a = args + while a.cdr do + table.insert(params, eval.eval(a.car, env)) + a = a.cdr end - return proc(table.unpack(vals)) + return proc(type.List(params)) end end end --- -return setmetatable(eval, { __call = - function(_, x, e) - local success, result = - pcall(eval.eval, x, e) - if success then return result - else return ("ERROR: " .. result) - end - end -}) +return eval -- cgit 1.4.1-21-gabe81