Last active
December 14, 2017 22:00
-
-
Save bmwalters/28aa036e99b6e459be250a8ce3599af4 to your computer and use it in GitHub Desktop.
comp.lua
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local compresult | |
local COMP = {} | |
function COMP:__index(k) | |
return COMP[k] or self:addop("index", k) | |
end | |
function COMP:__call(...) | |
return self:addop("call", ...) | |
end | |
function COMP:__len() | |
return self:addop("len") | |
end | |
function COMP.__lt(lhs, rhs) | |
if getmetatable(lhs) == COMP then | |
compresult = lhs:addop("lt", rhs) | |
else | |
compresult = rhs:addop("gt", lhs) | |
end | |
end | |
function COMP:__concat(rhs) | |
return self:addop("concat", rhs) | |
end | |
function COMP:addop(type, ...) | |
self.ops[#self.ops + 1] = { type = type, params = {...} } | |
return self | |
end | |
function COMP:func() | |
local ops = self.ops | |
self.ops = {} | |
return function(value) | |
local lastvalue | |
for _, op in ipairs(ops) do | |
if op.type == "index" then | |
lastvalue = value | |
value = value[op.params[1]] | |
elseif op.type == "call" then | |
local params = {} | |
for i, p in ipairs(op.params) do params[i] = p end | |
if params[1] == self then params[1] = lastvalue end | |
value = value(table.unpack(params)) | |
elseif op.type == "len" then | |
value = #value | |
elseif op.type == "lt" then | |
value = value < op.params[1] | |
elseif op.type == "gt" then | |
value = value > op.params[1] | |
elseif op.type == "concat" then | |
value = value .. op.params[1] | |
end | |
end | |
return value | |
end | |
end | |
debug.setmetatable(_G, { | |
__index = function(_, k) | |
if k:sub(1, 1) == "_" then | |
local oldval = _G[k:sub(2)] | |
_G[k:sub(2)] = setmetatable({ ops = {} }, COMP) | |
return setmetatable({}, { | |
__bor = function(_, rhs) | |
local f = (compresult or rhs):func() | |
compresult = nil | |
_G[k:sub(2)] = oldval | |
return f | |
end | |
}) | |
end | |
end | |
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dofile("comp.lua") | |
local FUNC = {} | |
FUNC.__index = FUNC | |
function FUNC:filter(f) | |
local out = {} | |
for _, v in ipairs(self) do | |
if f(v) then | |
out[#out + 1] = v | |
end | |
end | |
return setmetatable(out, FUNC) | |
end | |
function FUNC:map(f) | |
local out = {} | |
for i, v in ipairs(self) do | |
out[i] = f(v) | |
end | |
return setmetatable(out, FUNC) | |
end | |
function FUNC:foreach(f) | |
for _, v in ipairs(self) do | |
f(v) | |
end | |
end | |
function f(tab) | |
return setmetatable(tab, FUNC) | |
end | |
-- EXAMPLE | |
f{ { foo = "bar" }, { foo = "as" }, { foo = "baz" }, { foo = "qux" }, { foo = "cr" } } | |
:filter(_x | (#x.foo > 2)) | |
:map(_x | x.foo:sub(1, 1)) | |
:foreach(print) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dofile("comp.lua") | |
local transform = _x | x:upper() .. "!" | |
print(transform("hello world")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment