From 65a1c1f8820425e5a531a1bd4d652390489d4f9c Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Wed, 21 Feb 2024 22:20:45 -0600 Subject: Fix weird eval problem Don't do things ya don't get, kids --- eval.lua | 95 +++++++++++++++++++++++++++++++++++--------------------------- readme.txt | 16 +---------- types.lua | 37 ------------------------ 3 files changed, 55 insertions(+), 93 deletions(-) delete mode 100644 types.lua diff --git a/eval.lua b/eval.lua index 3decded..d441859 100644 --- a/eval.lua +++ b/eval.lua @@ -2,36 +2,53 @@ local eval = {} local read = require "read" -local types = require "types" local util = require "util" local pp = require "pp" -Env = types.Object:new { - __type = "Environment", - __extend = - function(self, parms, args, outer) - for _, p in ipairs(parms) do - for _, a in ipairs(args) do - self[p] = a - end - end - getmetatable(self).__index = outer - end, -} +local function Type (x) + if type(x) == "string" then + return "Symbol" + elseif type(x) == "number" then + return "Number" + elseif getmetatable(x) and getmetatable(x).__type then + return x.__type + elseif type(x) == "table" then + return "List" + else + return type(x) + end +end -Proc = types.Object:new { - __type = "Procedure", - __call = - function (self, args) - local e = Env:new() - e:__extend(self.parms, - util.table(args), - self.env) - return eval(self.body[1], e) - end -} +local Symbol = tostring +local Number = tonumber + +local function Env(inner, outer) + return setmetatable(inner, { __type = "Environment", __index = outer, }) +end + +local function Proc(params, body, env) + local p = { + params = params, + body = body, + env = env, + } + local mt = { + __type = "Procedure", + __call = + function (self, ...) + local inner = {} + for _, p in ipairs(self.params) do + for _, a in ipairs({...}) do + inner[p] = a + end + end + return eval(self.body, Env(inner, self.env)) + end, + } + return setmetatable(p, mt) +end -global_env = Env:new { +local global_env = { -- constants ["#t"] = true, ["#f"] = false, @@ -56,11 +73,11 @@ global_env = Env:new { end, ["number?"] = function(x) - return types.Type(x) == "Number" + return Type(x) == "Number" end, ["symbol?"] = function(x) - return types.Type(x) == "Symbol" + return Type(x) == "Symbol" end, -- scheme functions ["apply"] = @@ -95,9 +112,9 @@ end function eval.eval (x, env) env = env or global_env - if types.Type(x) == "Symbol" then + if Type(x) == "Symbol" then return env[x] - elseif types.Type(x) ~= "List" then + elseif type(x) ~= "table" then return x else local op = util.car(x) @@ -107,19 +124,15 @@ function eval.eval (x, env) elseif op == "define" then local sym, exp = table.unpack(args) env[sym] = eval(exp, env) - elseif op == "set!" then - local sym, exp = table.unpack(args) - env[sym] = eval(exp, env) + --[[ + elseif op == "set!" then + local sym, exp = table.unpack(args) + env[sym] = eval(exp, env) --]] elseif op == "lambda" then - local parms = util.car(args) - local body = util.cdr(args) - return Proc:new { - parms = parms, - body = body, - env = env, - } + local params = util.car(args) + local body = util.cdr(args)[1] + return Proc(params, body, env) else -- procedure call - pp(op) local proc = eval(op, env) local vals = util.map( function(v) return eval(v, env) end, @@ -142,4 +155,4 @@ return setmetatable(eval, { __call = --[[ (begin (define sq (lambda (x) (* x x))) (define rep (lambda (f) (lambda (x) (f (f x)))))) --- ]] + -- ]] diff --git a/readme.txt b/readme.txt index 20b41cf..76f571f 100644 --- a/readme.txt +++ b/readme.txt @@ -3,20 +3,6 @@ by C. Duckworth lam(n.) -- where you go when a scheme goes bad -major work in progress. as of right now ( 2024-02-21 ): -- (define sq (lambda (x) (* x x))) - -(sq 4) ;=> 16 -(sq (sq 4)) ;=> 256 - -- (define rep (lambda (f) (lambda (x) (f (f x))))) - -((rep sq) 4) ;=> ERROR -- trying to call a string value (Symbol, I think, x) - -sad face. - -however, +, *, all math.* functions and constants, begin, define, work. - -apply also works, i'm pretty sure. scheme-style.(was up late last night, think i got that in) +this is /very much/ a work in progress contributions/help WELCOME! diff --git a/types.lua b/types.lua deleted file mode 100644 index 042edce..0000000 --- a/types.lua +++ /dev/null @@ -1,37 +0,0 @@ ---- lam.types - -local types = {} - -function types.Type(x) - if type(x) == "string" then - -- Symbols are Lua strings - return "Symbol" - elseif type(x) == "number" then - -- Numbers are Lua numbers - return "Number" - elseif x.__type then - return x.__type - elseif type(x) == "table" then - -- Lists are Lua tables (non-adorned) - return "List" - else - return type(x) - end -end - -types.Object = { __type = "Object" } -function types.Object:new(o) - o = o or {} - setmetatable(o, self) - self.__index = self - return o -end - ---- Boxed types - --- Strings - --- Lists - ---- -return types -- cgit 1.4.1-21-gabe81