aboutsummaryrefslogtreecommitdiff
path: root/containers.lua
diff options
context:
space:
mode:
Diffstat (limited to 'containers.lua')
-rw-r--r--containers.lua172
1 files changed, 167 insertions, 5 deletions
diff --git a/containers.lua b/containers.lua
index e706831..cd3e7c0 100644
--- a/containers.lua
+++ b/containers.lua
@@ -1,4 +1,4 @@
-local List, Dict
+local List, Dict, Undict, _undict_mt, _dict_mt
local insert, remove, concat
do
local _obj_0 = table
@@ -226,6 +226,23 @@ local _list_mt = {
return _accum_0
end)())
end,
+ copy = function(self)
+ return List((function()
+ local _accum_0 = { }
+ local _len_0 = 1
+ for i = 1, #self do
+ _accum_0[_len_0] = self[i]
+ _len_0 = _len_0 + 1
+ end
+ return _accum_0
+ end)())
+ end,
+ reverse = function(self)
+ local n = #self
+ for i = 1, math.floor(n / 2) do
+ self[i], self[n - i + 1] = self[n - i + 1], self[i]
+ end
+ end,
reversed = function(self)
return List((function()
local _accum_0 = { }
@@ -236,6 +253,49 @@ local _list_mt = {
end
return _accum_0
end)())
+ end,
+ sort = function(self)
+ return table.sort(self)
+ end,
+ sort_by = function(self, fn)
+ local keys = setmetatable({ }, {
+ __index = function(self, k)
+ local key = fn(k)
+ self[k] = key
+ return key
+ end
+ })
+ return table.sort(self, function(a, b)
+ return keys[a] <= keys[b]
+ end)
+ end,
+ sorted = function(self)
+ local c = self:copy()
+ c:sort()
+ return c
+ end,
+ sorted_by = function(self, fn)
+ local c = self:copy()
+ c:sort_by(fn)
+ return c
+ end,
+ filter_by = function(self, keep)
+ local deleted = 0
+ for i = 1, #self do
+ if not (keep(self[i])) then
+ deleted = deleted + 1
+ elseif deleted > 0 then
+ self[i - deleted] = self[i]
+ end
+ end
+ for i = #self - deleted + 1, #self do
+ self[i] = nil
+ end
+ end,
+ filtered_by = function(self, keep)
+ local c = self:copy()
+ c:filter_by(keep)
+ return c
end
},
__newindex = function(self, k, v)
@@ -262,7 +322,91 @@ List = function(t)
return error("Unsupported List type: " .. type(t))
end
end
-local _dict_mt = {
+local compliments = setmetatable({ }, {
+ __mode = 'k'
+})
+_undict_mt = {
+ __index = function(self, k)
+ return not compliments[self][k] and true or nil
+ end,
+ __newindex = function(self, k, v)
+ if k then
+ compliments[self][k] = nil
+ else
+ compliments[self][k] = true
+ end
+ end,
+ __eq = function(self, other)
+ if not (type(other) == 'table' and getmetatable(other) == getmetatable(self)) then
+ return false
+ end
+ return compliments[self] == compliments[other]
+ end,
+ __len = function(self)
+ return math.huge
+ end,
+ __tostring = function(self)
+ return "~" .. _dict_mt.__tostring(compliments[self])
+ end,
+ as_nomsu = function(self)
+ return "~" .. _dict_mt.as_nomsu(compliments[self])
+ end,
+ as_lua = function(self)
+ return "~" .. __dict_mt.as_lua(compliments[self])
+ end,
+ __band = function(self, other)
+ if getmetatable(other) == _undict_mt then
+ return Undict(_dict_mt.__bor(compliments[self], compliments[other]))
+ else
+ return _dict_mt.__band(other, self)
+ end
+ end,
+ __bor = function(self, other)
+ if getmetatable(other) == _undict_mt then
+ return Undict(_dict_mt.__band(compliments[self], compliments[other]))
+ else
+ return Undict((function()
+ local _tbl_0 = { }
+ for k, v in pairs(compliments[self]) do
+ if not other[k] then
+ _tbl_0[k] = v
+ end
+ end
+ return _tbl_0
+ end)())
+ end
+ end,
+ __bxor = function(self, other)
+ if getmetatable(other) == _undict_mt then
+ return _dict_mt.__bxor(compliments[self], compliments[other])
+ else
+ return Undict(_dict_mt.__band(other, self))
+ end
+ end,
+ __bnot = function(self)
+ return Dict((function()
+ local _tbl_0 = { }
+ for k, v in pairs(compliments[self]) do
+ _tbl_0[k] = v
+ end
+ return _tbl_0
+ end)())
+ end
+}
+Undict = function(d)
+ local u = setmetatable({ }, _undict_mt)
+ compliments[u] = Dict((function()
+ local _tbl_0 = { }
+ for k, v in pairs(d) do
+ if v then
+ _tbl_0[k] = true
+ end
+ end
+ return _tbl_0
+ end)())
+ return u
+end
+_dict_mt = {
__type = "a Dict",
__eq = function(self, other)
if not (type(other) == 'table' and getmetatable(other) == getmetatable(self)) then
@@ -292,7 +436,7 @@ local _dict_mt = {
local _accum_0 = { }
local _len_0 = 1
for k, v in pairs(self) do
- _accum_0[_len_0] = "." .. tostring(k) .. " = " .. tostring(v)
+ _accum_0[_len_0] = v == true and "." .. as_nomsu(k) or "." .. tostring(k) .. " = " .. tostring(v)
_len_0 = _len_0 + 1
end
return _accum_0
@@ -303,7 +447,7 @@ local _dict_mt = {
local _accum_0 = { }
local _len_0 = 1
for k, v in pairs(self) do
- _accum_0[_len_0] = "." .. tostring(as_nomsu(k)) .. " = " .. tostring(as_nomsu(v))
+ _accum_0[_len_0] = v == true and "." .. as_nomsu(k) or "." .. tostring(as_nomsu(k)) .. " = " .. tostring(as_nomsu(v))
_len_0 = _len_0 + 1
end
return _accum_0
@@ -320,11 +464,22 @@ local _dict_mt = {
return _accum_0
end)(), ", ") .. "}"
end,
+ as_list = function(self)
+ return List((function()
+ local _accum_0 = { }
+ local _len_0 = 1
+ for k, v in pairs(self) do
+ _accum_0[_len_0] = k
+ _len_0 = _len_0 + 1
+ end
+ return _accum_0
+ end)())
+ end,
__band = function(self, other)
return Dict((function()
local _tbl_0 = { }
for k, v in pairs(self) do
- if other[k] ~= nil then
+ if other[k] then
_tbl_0[k] = v
end
end
@@ -332,6 +487,9 @@ local _dict_mt = {
end)())
end,
__bor = function(self, other)
+ if getmetatable(other) == _undict_mt then
+ return _undict_mt.__bor(other, self)
+ end
local ret = Dict((function()
local _tbl_0 = { }
for k, v in pairs(self) do
@@ -347,6 +505,9 @@ local _dict_mt = {
return ret
end,
__bxor = function(self, other)
+ if getmetatable(other) == _undict_mt then
+ return _undict_mt.__bxor(other, self)
+ end
local ret = Dict((function()
local _tbl_0 = { }
for k, v in pairs(self) do
@@ -363,6 +524,7 @@ local _dict_mt = {
end
return ret
end,
+ __bnot = Undict,
__add = function(self, other)
local ret = Dict((function()
local _tbl_0 = { }