about summary refs log tree commit diff stats
path: root/types.lua
diff options
context:
space:
mode:
Diffstat (limited to 'types.lua')
-rw-r--r--types.lua122
1 files changed, 103 insertions, 19 deletions
diff --git a/types.lua b/types.lua index d4c8d14..e4813b2 100644 --- a/types.lua +++ b/types.lua
@@ -1,28 +1,112 @@
1--- lam.types 1--- lam.types
2 2
3local types = {} 3local types = {}
4local util = require "util"
5table.unpack = table.unpack or unpack
4 6
5types.luatype = type 7--- Converting between types
6 8
7function types.lamtype (x) 9types.globalns = {} -- namespace
8 if types.luatype(x) == "string" then 10
9 return "symbol" 11types.Symbol =
10 elseif types.luatype(x) == "number" then 12 function (name, ns, aliases)
11 return "number" 13 ns = ns or types.globalns
12 elseif getmetatable(x) and getmetatable(x).__type then 14 aliases = aliases or {}
13 return getmetatable(x).__type 15 if ns[name] then return ns[name] end
14 elseif types.luatype(x) == "table" then 16 local sym = { name = name, aliases = aliases }
15 return "list" 17 ns[name] = sym
16 else 18 for _,a in ipairs(aliases) do
17 return types.luatype(x) 19 ns[a] = sym
20 end
21 local mt = {
22 __type = "Symbol",
23 __tostring = function (self) return self.name end,
24 }
25 return setmetatable(sym, mt)
26 end
27
28types.Number = tonumber
29
30types.String =
31 function (str)
32 local s = {
33 value = str,
34 escape =
35 function(self)
36 return self:gsub("\"", "\\\"")
37 end,
38 }
39 local mt = {
40 __type = "String",
41 __tostring =
42 function (self)
43 return string.format(
44 "\"%s\"",
45 self:escape())
46 end,
47 }
48 return setmetatable(s, mt)
49 end
50
51types.Cons =
52 function (a, b)
53 assert(a ~= nil and b ~= nil,
54 "Need two non-nil arguments in a pair")
55 local s = { a, b }
56 local mt = {
57 __type = "Pair",
58 __tostring =
59 function (p)
60 local out = {}
61 local car, cdr = p[1], p[2]
62 while cdr do
63 table.insert(out, tostring(car))
64 if type(cdr) == "table" then
65 car = cdr[1]
66 cdr = cdr[2]
67 else
68 table.insert(out, ".")
69 table.insert(out, cdr)
70 break
71 end
72 end
73 return "("..table.concat(out, " ")..")"
74 end
75
76 }
77 return setmetatable(s, mt)
18 end 78 end
19end
20 79
21types["number?"] = function (x) return types.lamtype(x) == "number" end 80types.List =
22types["symbol?"] = function (x) return types.lamtype(x) == "symbol" end 81 function (tbl)
23types["list?"] = function (x) return types.lamtype(x) == "list" end 82 local function tolist(base, items)
24types["procedure?"] = function (x) return types.lamtype(x) == "procedure" end 83 if #items == 0 then return base end
25types["null?"] = function (x) return x == {} end 84 return tolist(
85 types.Cons(table.remove(items), base),
86 items)
87 end
88 return tolist({}, tbl)
89 end
90
91--- Determining types
92
93types.lamtype =
94 function (x)
95 if type(x) == "number" then
96 return "Number"
97 elseif getmetatable(x) and getmetatable(x).__type then
98 return getmetatable(x).__type
99 else
100 return type(x)
101 end
102 end
103
104--- Type predicates
105
106types.isa =
107 function (x, t)
108 return types.lamtype(x) == t
109 end
26 110
27--- 111---
28return types 112return types