From 4eaccb65390515fb833a58c92897a67b15803813 Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Mon, 11 Mar 2024 00:40:05 -0500 Subject: Add IF, clean up definitions --- eval.lua | 55 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/eval.lua b/eval.lua index 6179842..5e897e2 100644 --- a/eval.lua +++ b/eval.lua @@ -1,9 +1,9 @@ --- lam.eval local eval = {} -local read = require "read" local type = require "type" -local util = require "util" +local isNull, isList, isa, List, Cons = + type.isNull, type.isList, type.isa, type.List, type.Cons local unpack = table.unpack or unpack function eval.Env (inner, outer) @@ -30,7 +30,6 @@ function eval.Proc (params, body, env) inner[p.car] = a.car p, a = p.cdr, a.cdr end - -- pp.pp(self.body) return eval.eval( self.body, eval.Env(inner, self.env)) @@ -41,47 +40,59 @@ end local global = { begin = - function (args) - local a = args - while not type.isNull(a.cdr) do - a = a.cdr + function (r) + local r = r + while not isNull(r.cdr) do + r = r.cdr end - return a.car + return r.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 + function (r) + local r, a = r, 0 + while r.cdr do + r, a = r.cdr, a + r.car end - return acc + return a end, ["-"] = - function (args) - return args.car - args.cdr.car + function (r) + if isNull(r) then return -1 end + if isNull(r.cdr) then return (- r.car) end + local r, a = r.cdr, r.car + while r.cdr do + r, a = r.cdr, a - r.car + end + return a end, } function eval.eval (x, env) env = env or global - if type.isa(x, "Symbol") then + if isa(x, "Symbol") then return env[x] - elseif not type.isList(x) then + elseif not isList(x) then return x else local op, args = x.car, x.cdr if op == "quote" then - return args + return args.car 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), + Cons("begin", 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 else -- procedure local proc = eval.eval(op, env) local params = {} @@ -90,7 +101,7 @@ function eval.eval (x, env) table.insert(params, eval.eval(a.car, env)) a = a.cdr end - return proc(type.List(params)) + return proc(List(params)) end end end -- cgit 1.4.1-21-gabe81