From 892a27deef5ed289e486ad2f1296f726f70c359c Mon Sep 17 00:00:00 2001 From: Lars Mueller Date: Mon, 23 Mar 2020 20:20:43 +0100 Subject: [PATCH] rolling-9 --- class.lua | 2 +- func.lua | 6 +++ init.lua | 8 ++-- minetest.lua | 1 - mod.lua | 9 +++-- number.lua | 40 +++++++++++++++++++ table.lua | 106 +++++++++++++++++++++++++++++++++++++++++++-------- text.lua | 1 - 8 files changed, 148 insertions(+), 25 deletions(-) create mode 100644 func.lua diff --git a/class.lua b/class.lua index a46fdac..cbd3012 100644 --- a/class.lua +++ b/class.lua @@ -7,7 +7,7 @@ function define(name, def) end function new(classname, ...) local obj = get(classname).new(...) - obj = setmetatable(obj, {__index = classes[classname]}) -- TODO ? metatable add __call with setfenv + obj = setmetatable(obj, {__index = classes[classname]}) return obj end function get(classname) diff --git a/func.lua b/func.lua new file mode 100644 index 0000000..50fe6d7 --- /dev/null +++ b/func.lua @@ -0,0 +1,6 @@ +function curry(func, ...) + local args = {...} + return function(...) + return func(unpack(args), ...) + end +end \ No newline at end of file diff --git a/init.lua b/init.lua index df874d3..73eb3dc 100644 --- a/init.lua +++ b/init.lua @@ -3,7 +3,7 @@ if _VERSION then if _VERSION < "Lua 5" then error("Outdated Lua version! modlib requires Lua 5 or greater.") end - if _VERSION > "Lua 5.1" then -- TODO automatically use _ENV instead of s/getfenv if _VERSION > 5.1 + if _VERSION > "Lua 5.1" then -- not throwing error("Too new Lua version! modlib requires Lua 5.1 or smaller.") anymore unpack = unpack or table.unpack -- unpack was moved to table.unpack in Lua 5.2 loadstring = load @@ -47,14 +47,13 @@ local function loadfile_exports(filename) return env end --- TODO automatically know current mod - local components = { mod = {}, class = {}, conf = {}, data = {}, file = {}, + func = {}, log = {}, minetest = {}, number = {}, @@ -80,4 +79,7 @@ end modlib.mod.loadfile_exports = loadfile_exports +-- complete the string library (=metatable) with text helpers +modlib.table.complete(string, modlib.text) + _ml = modlib \ No newline at end of file diff --git a/minetest.lua b/minetest.lua index 887256f..d88075f 100644 --- a/minetest.lua +++ b/minetest.lua @@ -1,5 +1,4 @@ -- MT extension --- TODO add formspec queues and event system + sync handler delta_times={} delays={} callbacks={} diff --git a/mod.lua b/mod.lua index 9f40cdb..f537ad1 100644 --- a/mod.lua +++ b/mod.lua @@ -9,12 +9,13 @@ function include(modname, file) end -- loadfile with table env -function include_namespace(classname, filename) - _G[classname] = setmetatable(_G[classname] or {}, {__index = _G, __call = _G}) +function include_namespace(classname, filename, parent_namespace) + parent_namespace = parent_namespace or _G + parent_namespace[classname] = setmetatable(parent_namespace[classname] or {}, {__index = parent_namespace, __call = parent_namespace}) local class = assert(loadfile(filename)) - setfenv(class, _G[classname]) + setfenv(class, parent_namespace[classname]) class() - return _G[classname] + return parent_namespace[classname] end -- runs main.lua in table env diff --git a/number.lua b/number.lua index 2528167..7962e9b 100644 --- a/number.lua +++ b/number.lua @@ -3,3 +3,43 @@ function round(number, steps) -- Rounds a number steps = steps or 1 return math.floor(number * steps + 0.5) / steps end +local c0 = ("0"):byte() +local cA = ("A"):byte() +function default_digit_function(digit) + if digit <= 9 then + return string.char(c0+digit) + end + return string.char(cA+digit-10) +end +default_precision = 10 +function tostring(number, base, digit_function, precision) + digit_function = digit_function or default_digit_function + precision = precision or default_precision + local out = {} + if number < 0 then + table.insert(out, "-") + number = -number + end + local digit + while number >= base do + digit = math.floor(number % base) + table.insert(out, digit_function(digit)) + number = number / base + end + digit = math.floor(number) + table.insert(out, digit_function(digit)) + modlib.table.reverse(out) + number = number % 1 + if number >= math.pow(base, precision) then + table.insert(out, ".") + -- precision >= 0 eventually redundant + while precision >= 0 and number >= math.pow(base, precision) do + number = number * base + digit = math.floor(number % base) + table.insert(out, digit_function(digit)) + number = number - digit + precision = precision - 1 + end + end + return table.concat(out) +end \ No newline at end of file diff --git a/table.lua b/table.lua index e370e4c..23e5cfa 100644 --- a/table.lua +++ b/table.lua @@ -47,6 +47,8 @@ function tablecopy(t) return table.copy(t) end +copy = tablecopy + function count(table) local count = 0 for _ in pairs(table) do @@ -59,10 +61,29 @@ function is_empty(table) return next(table) == nil end +function foreach(t, func) + for k, v in pairs(t) do + func(k, v) + end +end + +function foreach_value(t, func) + for _, v in pairs(t) do + func(v) + end +end + +function foreach_key(t, func) + for k, _ in pairs(t) do + func(k) + end +end + function map(t, func) for k, v in pairs(t) do t[k]=func(v) end + return t end function process(t, func) @@ -79,14 +100,17 @@ function call(funcs, ...) end end -function merge_tables(table1, table2) - local table1copy = table.copy(table1) - for key, value in pairs(table2) do - table1copy[key] = value +function find(list, value) + for index, other_value in pairs(list) do + if value == other_value then + return index + end end - return table1copy + return false end +contains = find + function difference(table1, table2) local result={} for k, v in pairs(table2) do @@ -105,6 +129,31 @@ function add_all(dst, new) return dst end +function complete(dst, new) + for key, value in pairs(new) do + if dst[key] == nil then + dst[key] = value + end + end + return dst +end + +function merge_tables(table1, table2) + return add_all(copy(table1), table2) +end + +union = merge_tables + +function intersection(t1, t2) + local result = {} + for key, value in pairs(t1) do + if t2[key] then + result[key] = value + end + end + return result +end + function append(t1, t2) local l=#t1 for k, v in ipairs(t2) do @@ -192,15 +241,42 @@ function max(table) return best_value(table, function(v, m) return v > m end) end -function binary_search(list, value) - local min, size = 1, #list - while size > 1 do - local s_half = math.floor(size / 2) - local pivot = min + s_half - local element = list[pivot] - if value > element then - min = pivot - end - size = s_half +function default_comparator(a, b) + if a == b then + return 0 end + if a > b then + return 1 + end + return -1 +end + +function binary_search_comparator(comparator) + -- if found, returns index; if not found, returns -index for insertion + function binary_search(list, value) + local min, max = 1, #list + while min <= max do + local pivot = min + math.floor((max-min)/2) + local element = list[pivot] + local compared = comparator(value, element) + if compared == 0 then + return pivot + elseif compared > 0 then + min = pivot+1 + else + max = pivot-1 + end + end + return -min + end +end + +binary_search = binary_search_comparator(default_comparator) + +function reverse(list) + local len = #list + for i = 1, math.floor(#list/2) do + list[len-i+1], list[i] = list[i], list[len-i+1] + end + return list end \ No newline at end of file diff --git a/text.lua b/text.lua index c2ce358..1c91d0f 100644 --- a/text.lua +++ b/text.lua @@ -1,4 +1,3 @@ --- TODO probably set string metatables ? -- String helpers - split & trim at end & begin function upper_first(str) return str:sub(1,1):upper()..str:sub(2)