Documentation for this module may be created at Module:Tools/τεκμηρίωση

-- some functions useful in lua

local tools = {}

-- memory management

-- copy of an array not cloning the content objects (http://lua-users.org/wiki/CopyTable)
local function shallowcopy(orig)
    local orig_type = type(orig)
    local copy
    if orig_type == 'table' then
        copy = {}
        for orig_key, orig_value in pairs(orig) do
            copy[orig_key] = orig_value
        end
    else -- number, string, boolean, etc
        copy = orig
    end
    return copy
end

tools.shallowcopy = shallowcopy

-- (http://lua-users.org/wiki/CopyTable)
local function deepcopy(orig)
    local orig_type = type(orig)
    local copy
    if orig_type == 'table' then
        copy = {}
        for orig_key, orig_value in next, orig, nil do
            copy[deepcopy(orig_key)] = deepcopy(orig_value)
        end
        setmetatable(copy, deepcopy(getmetatable(orig)))
    else -- number, string, boolean, etc
        copy = orig
    end
    return copy
end

tools.deepcopy = deepcopy


--[[

Nombre d'élément dans un dictionnaire

--]]

function tools.tablelength(T)
  local count = 0
  for _ in pairs(T) do count = count + 1 end
  return count
end


--[[

Nouveau tableau sans le premier élément

--]]

function tools.tail(list)
    return { select(2, unpack(list)) }
end


function tools.tableConcat(t1,t2)
    for i=1,#t2 do
        t1[#t1+1] = t2[i]
    end
    return t1
end


--[[

Une classe destinée à servir d'ensemble pour tester rapidement l'appartenance d'un élément à une liste ou un ensemble

--]]

local Set = {} -- the table representing the class, which will double as the metatable for the instances
Set.__index = Set -- failed table lookups on the instances should fallback to the class table, to get methods

function Set:new(init, o)
    local obj = o or {} 
    setmetatable(obj, self)
    
    obj.value = init
    obj.prop_set = {}
    
    for _, val in pairs(init) do
    	obj.prop_set[val] = true
    end

    return obj
end

function Set:is_in(key)
    return self.prop_set[key] ~= nil
end

tools.Set = Set

--[[
	Programmation fonctionnelle, application d'une fonction sur chaque élément d'un tableau
	map(f,{a, b, c, ...}) = {f(a), f(b), f(c), ...} 
--]]


local function map(func, array)
  local new_array = {}
  for i,v in ipairs(array) do
    new_array[i] = func(v)
  end
  return new_array
end

tools.map = map

function tools.formatTableWithLastSep(vector, sep, lastsep)
	local descr = table.concat(vector, sep, 1, #vector-1)
	if #vector > 1 then
		descr = descr .. lastsep .. vector[#vector]
	else 
		descr = vector[1]
	end
	return descr
end

local function dump_to_console(val, indent)
	indent = indent or ""
	if type(val) == "table" then
		for a, b in pairs(val) do
			mw.log(indent .. a .. "=>")
			dump_to_console(b, indent .. "   ") 
		end
	else
		mw.log(indent .. tostring(val))
	end
end

tools.dump_to_console = dump_to_console
tools.dump = dump_to_console

local function splitStr(val) -- transforme en table les chaînes venant du Wikitexte qui utilisent des virgules de séparatin
	if type(val) == 'string' then
		val = mw.text.split(val, ",")
	end
	return val
end

tools.splitStr = splitStr

-- utility : stack manipulation functions
-- Console tests : 
-- plop = {} ; p.append(plop, "a") ; p.append(plop, "a") ; p.push(plop, "b")  ; p.append(plop, "c") ; p.push(plop, "a") ; mw.log(p. dump_to_console(plop)) ; p.shove_off(plop) ; p.pop(plop) ; mw.log(plop)

local function pop(list)
	local ind=1
	if list[0] then
		ind = 0
	end
	local elem = list[ind]
	table.remove(list, ind)
	return elem, list
end

tools.pop = pop

local function push(list, elem)
	if elem[0] then
		table.insert(list, 0, elem)
	else
		table.insert(list, 1, elem)
	end
end

tools.push = push


tools.append = function(list, elem)
	table.insert(list, #list+1, elem)
end

tools.shove_off = function(list, elem)
	table.remove(list, elem, #list+1)
end
tools.remove_last = tools.shove_off


return tools