From bbaff0e0c204c2fab216f6501dc8c11b4425b4bc Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Mon, 4 Mar 2024 21:01:27 -0600 Subject: Ugghhhh totally not working --- types.lua | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 103 insertions(+), 19 deletions(-) (limited to 'types.lua') diff --git a/types.lua b/types.lua index d4c8d14..e4813b2 100644 --- a/types.lua +++ b/types.lua @@ -1,28 +1,112 @@ --- lam.types local types = {} +local util = require "util" +table.unpack = table.unpack or unpack -types.luatype = type - -function types.lamtype (x) - if types.luatype(x) == "string" then - return "symbol" - elseif types.luatype(x) == "number" then - return "number" - elseif getmetatable(x) and getmetatable(x).__type then - return getmetatable(x).__type - elseif types.luatype(x) == "table" then - return "list" - else - return types.luatype(x) +--- Converting between types + +types.globalns = {} -- namespace + +types.Symbol = + function (name, ns, aliases) + ns = ns or types.globalns + aliases = aliases or {} + if ns[name] then return ns[name] end + local sym = { name = name, aliases = aliases } + ns[name] = sym + for _,a in ipairs(aliases) do + ns[a] = sym + end + local mt = { + __type = "Symbol", + __tostring = function (self) return self.name end, + } + return setmetatable(sym, mt) + end + +types.Number = tonumber + +types.String = + function (str) + local s = { + value = str, + escape = + function(self) + return self:gsub("\"", "\\\"") + end, + } + local mt = { + __type = "String", + __tostring = + function (self) + return string.format( + "\"%s\"", + self:escape()) + end, + } + return setmetatable(s, mt) + end + +types.Cons = + function (a, b) + assert(a ~= nil and b ~= nil, + "Need two non-nil arguments in a pair") + local s = { a, b } + local mt = { + __type = "Pair", + __tostring = + function (p) + local out = {} + local car, cdr = p[1], p[2] + while cdr do + table.insert(out, tostring(car)) + if type(cdr) == "table" then + car = cdr[1] + cdr = cdr[2] + else + table.insert(out, ".") + table.insert(out, cdr) + break + end + end + return "("..table.concat(out, " ")..")" + end + + } + return setmetatable(s, mt) end -end -types["number?"] = function (x) return types.lamtype(x) == "number" end -types["symbol?"] = function (x) return types.lamtype(x) == "symbol" end -types["list?"] = function (x) return types.lamtype(x) == "list" end -types["procedure?"] = function (x) return types.lamtype(x) == "procedure" end -types["null?"] = function (x) return x == {} end +types.List = + function (tbl) + local function tolist(base, items) + if #items == 0 then return base end + return tolist( + types.Cons(table.remove(items), base), + items) + end + return tolist({}, tbl) + end + +--- Determining types + +types.lamtype = + function (x) + if type(x) == "number" then + return "Number" + elseif getmetatable(x) and getmetatable(x).__type then + return getmetatable(x).__type + else + return type(x) + end + end + +--- Type predicates + +types.isa = + function (x, t) + return types.lamtype(x) == t + end --- return types -- cgit 1.4.1-21-gabe81