204 lines
4.0 KiB
Lua
204 lines
4.0 KiB
Lua
local old_print = print
|
|
function print(...)
|
|
local info = debug.getinfo(2)
|
|
local line = info.currentline
|
|
local name = info.source
|
|
old_print(string.format("%i%s> ",line,name),...)
|
|
end
|
|
function log(...)
|
|
old_print(...)
|
|
end
|
|
function map(tab,func)
|
|
local new = {}
|
|
for index,item in pairs(tab) do
|
|
new[index] = func(item)
|
|
end
|
|
return new
|
|
end
|
|
-- HELPER FUNCTIONS
|
|
-- Insert every item in t1 into t0
|
|
function just(...)
|
|
local items = {...}
|
|
return function()
|
|
return table.unpack(items)
|
|
end
|
|
end
|
|
|
|
id = function(...) return ... end
|
|
|
|
function union(t0,t1)
|
|
for index,item in pairs(t0) do
|
|
t0[index] = t1
|
|
end
|
|
return t0
|
|
end
|
|
|
|
-- Iterate (ipairs without the index)
|
|
function iterate(...)
|
|
local iterator,tab,i = pairs(...)
|
|
return function(...)
|
|
local index,item = iterator(tab,i)
|
|
i = index
|
|
return item
|
|
end,tab,i
|
|
end
|
|
|
|
function indices(t)
|
|
if type(t) ~= "table" then
|
|
error(
|
|
string.format(
|
|
"Argument 1 '%s' must be a table",
|
|
tostring(t)
|
|
)
|
|
,2)
|
|
end
|
|
local indices = {}
|
|
for index,_ in pairs(t) do
|
|
table.insert(indices,index)
|
|
end
|
|
return indices
|
|
end
|
|
|
|
-- Ensures a table has a metatable
|
|
function ensure_metatable(t)
|
|
local meta = getmetatable(t)
|
|
if not meta then meta = {} setmetatable(t,meta) end
|
|
return meta
|
|
end
|
|
|
|
function strings(t,item)
|
|
ensure_metatable(t).__tostring = item
|
|
end
|
|
|
|
-- Makes a table callable
|
|
function calls(t,fun)
|
|
ensure_metatable(t).__call = fun
|
|
end
|
|
|
|
-- Makes a table record access
|
|
function indexes(t,fun)
|
|
ensure_metatable(t).__index = fun
|
|
end
|
|
|
|
-- Makes a table record setting
|
|
function modifies(t,fun)
|
|
ensure_metatable(t).__newindex = fun
|
|
end
|
|
|
|
-- Shallow table to string
|
|
function table_tostring(tab,sep)
|
|
local items = {}
|
|
for item in iterate(tab) do
|
|
table.insert(items,tostring(item))
|
|
end
|
|
return table.concat(items,sep)
|
|
end
|
|
|
|
function type_of(item)
|
|
local type_name = type(item)
|
|
if type_name == "table" then
|
|
local meta = getmetatable(item)
|
|
if not meta then
|
|
return "table"
|
|
else
|
|
return meta
|
|
end
|
|
else
|
|
return type_name
|
|
end
|
|
end
|
|
|
|
-- DEBUGGING FUNCTIONS
|
|
-- Runs a function
|
|
function assert_meta(...)
|
|
local metas = {...}
|
|
return function(x,raise,handler)
|
|
handler = handler or error
|
|
local meta = getmetatable(x)
|
|
for tab in iterate(metas) do
|
|
if meta == tab then return end
|
|
end
|
|
local s_metas = {}
|
|
for meta in iterate(metas) do
|
|
table.insert(s_metas,tostring(meta))
|
|
end
|
|
local level = 2
|
|
local msg = string.format(
|
|
"Expected metatables '%s' but got '%s'",
|
|
table.concat(s_metas,","),
|
|
type(x)
|
|
)
|
|
if raise then
|
|
level = 3
|
|
msg = string.format(raise,msg)
|
|
end
|
|
handler(msg,level)
|
|
end
|
|
end
|
|
|
|
function assert_type(...)
|
|
local types = {...}
|
|
return function(x,raise)
|
|
local t = type(x)
|
|
for name in iterate(types) do
|
|
if t == name then return end
|
|
end
|
|
local level = 2
|
|
local msg = string.format(
|
|
"Expected type '%s' but got '%s'",
|
|
table_tostring(types," or "),
|
|
type(x))
|
|
-- For argument errors
|
|
if raise then
|
|
level = 3
|
|
msg = string.format(raise,msg)
|
|
end
|
|
error(msg,level)
|
|
end
|
|
end
|
|
|
|
-- HELPER FUNCTIONS
|
|
function case_of(t)
|
|
return function(item,...)
|
|
return (t[item] or error(
|
|
string.format(
|
|
"Couldn't match '%s' in case.",
|
|
tostring(item)
|
|
),2
|
|
))(...)
|
|
end
|
|
end
|
|
|
|
-- Creates a (p)OOP class
|
|
function class(name)
|
|
local meta = {}
|
|
union(meta,{restrict = {}})
|
|
meta.__index = meta
|
|
strings(meta,just(name))
|
|
calls(meta,function(meta,...)
|
|
local new = {}
|
|
setmetatable(new,meta)
|
|
if meta.new then new:new(...) end
|
|
return new
|
|
end)
|
|
meta.__tostring = function(this)
|
|
if meta.string then return this:string() end
|
|
return name
|
|
end
|
|
return meta
|
|
end
|
|
|
|
-- Read a file's full contents
|
|
function read(path)
|
|
local file = io.open(path)
|
|
if not file then
|
|
error(
|
|
string.match("Could not open file '%s'.",path),3
|
|
)
|
|
end
|
|
local content = file:read("a")
|
|
return content
|
|
end
|
|
|
|
return _G
|