diff --git a/builtin_metatables.lua b/builtin_metatables.lua index e579e6c..f659ad3 100644 --- a/builtin_metatables.lua +++ b/builtin_metatables.lua @@ -1,6 +1,9 @@ require("text") local number_mt = { __type = "a Number", + __len = function(self) + return self + end, as_lua = tostring, as_nomsu = tostring, as_text = tostring, @@ -23,12 +26,24 @@ number_mt.__index = number_mt debug.setmetatable(0, number_mt) local bool_mt = { __type = "a Boolean", + __len = function(self) + return self and 1 or 0 + end, as_lua = tostring, as_nomsu = function(self) return self and "yes" or "no" end, as_text = function(self) return self and "yes" or "no" + end, + _and = function(self, cond) + return self and cond + end, + _or = function(self, cond) + return self or cond + end, + xor = function(self, cond) + return self == (not cond) end } bool_mt.__index = bool_mt @@ -37,6 +52,126 @@ local fn_mt = { __type = "an Action", as_text = function(self) return (tostring(self):gsub("function", "Action")) + end, + __add = function(self, other) + if type(self) == 'function' and type(other) == 'function' then + return function(...) + return (self(...) + other(...)) + end + elseif type(self) == 'function' then + return function(...) + return (self(...) + other) + end + else + return function(...) + return (self + other(...)) + end + end + end, + __sub = function(self, other) + if type(self) == 'function' and type(other) == 'function' then + return function(...) + return (self(...) - other(...)) + end + elseif type(self) == 'function' then + return function(...) + return (self(...) - other) + end + else + return function(...) + return (self - other(...)) + end + end + end, + __mul = function(self, other) + if type(self) == 'function' and type(other) == 'function' then + return function(...) + return (self(...) * other(...)) + end + elseif type(self) == 'function' then + return function(...) + return (self(...) * other) + end + else + return function(...) + return (self * other(...)) + end + end + end, + __div = function(self, other) + if type(self) == 'function' and type(other) == 'function' then + return function(...) + return (self(...)(other(...))) + end + elseif type(self) == 'function' then + return function(...) + return (self(...)(other)) + end + else + return function(...) + return (self(other(...))) + end + end + end, + __mod = function(self, other) + if type(self) == 'function' and type(other) == 'function' then + return function(...) + return (self(...) % other(...)) + end + elseif type(self) == 'function' then + return function(...) + return (self(...) % other) + end + else + return function(...) + return (self % other(...)) + end + end + end, + __band = function(self, other) + if type(self) == 'function' and type(other) == 'function' then + return function(...) + return (self(...) and other(...)) + end + elseif type(self) == 'function' then + return function(...) + return (self(...) and other) + end + else + return function(...) + return (self and other(...)) + end + end + end, + __bor = function(self, other) + if type(self) == 'function' and type(other) == 'function' then + return function(...) + return (self(...) or other(...)) + end + elseif type(self) == 'function' then + return function(...) + return (self(...) or other) + end + else + return function(...) + return (self or other(...)) + end + end + end, + __bxor = function(self, other) + if type(self) == 'function' and type(other) == 'function' then + return function(...) + return (self(...) ~= other(...)) + end + elseif type(self) == 'function' then + return function(...) + return (self(...) ~= other) + end + else + return function(...) + return (self ~= other(...)) + end + end end } fn_mt.__index = fn_mt diff --git a/builtin_metatables.moon b/builtin_metatables.moon index eb7e27e..ac8beff 100644 --- a/builtin_metatables.moon +++ b/builtin_metatables.moon @@ -3,6 +3,7 @@ require "text" number_mt = __type: "a Number" + __len: => @ as_lua: tostring as_nomsu: tostring as_text: tostring @@ -17,15 +18,59 @@ debug.setmetatable 0, number_mt bool_mt = __type: "a Boolean" + __len: => @ and 1 or 0 as_lua: tostring as_nomsu: => @ and "yes" or "no" as_text: => @ and "yes" or "no" + _and: (cond)=> @ and cond + _or: (cond)=> @ or cond + xor: (cond)=> @ == (not cond) bool_mt.__index = bool_mt debug.setmetatable true, bool_mt fn_mt = __type: "an Action" as_text: => (tostring(@)\gsub("function", "Action")) + __add: (other)=> + if type(@) == 'function' and type(other) == 'function' + (...)-> (@(...) + other(...)) + elseif type(@) == 'function' then (...)-> (@(...) + other) + else (...)-> (@ + other(...)) + __sub: (other)=> + if type(@) == 'function' and type(other) == 'function' + (...)-> (@(...) - other(...)) + elseif type(@) == 'function' then (...)-> (@(...) - other) + else (...)-> (@ - other(...)) + __mul: (other)=> + if type(@) == 'function' and type(other) == 'function' + (...)-> (@(...) * other(...)) + elseif type(@) == 'function' then (...)-> (@(...) * other) + else (...)-> (@ * other(...)) + __div: (other)=> + if type(@) == 'function' and type(other) == 'function' + (...)-> (@(...) other(...)) + elseif type(@) == 'function' then (...)-> (@(...) other) + else (...)-> (@ other(...)) + __mod: (other)=> + if type(@) == 'function' and type(other) == 'function' + (...)-> (@(...) % other(...)) + elseif type(@) == 'function' then (...)-> (@(...) % other) + else (...)-> (@ % other(...)) + __band: (other)=> + if type(@) == 'function' and type(other) == 'function' + (...)-> (@(...) and other(...)) + elseif type(@) == 'function' then (...)-> (@(...) and other) + else (...)-> (@ and other(...)) + __bor: (other)=> + if type(@) == 'function' and type(other) == 'function' + (...)-> (@(...) or other(...)) + elseif type(@) == 'function' then (...)-> (@(...) or other) + else (...)-> (@ or other(...)) + __bxor: (other)=> + if type(@) == 'function' and type(other) == 'function' + (...)-> (@(...) != other(...)) + elseif type(@) == 'function' then (...)-> (@(...) != other) + else (...)-> (@ != other(...)) fn_mt.__index = fn_mt debug.setmetatable (->), fn_mt