Saltar para o conteúdo

Módulo:LuaCall/Testes

Origem: Wikipédia, a enciclopédia livre.

local p={}

function p.main(frame)
    local parent = frame.getParent(frame) or {}
    local reserved_value = {}
    local reserved_function, reserved_contents
    for k, v in pairs(parent.args or {}) do
        _G[k] = tonumber(v) or v -- transfere todos os parâmetros diretamente 
        						 -- para a tabela de variáveis globais
    end
    for k, v in pairs(frame.args or {}) do
        _G[k] = tonumber(v) or v -- transfere todos os parâmetros diretamente
        						 -- para a tabela de variáveis globais
    end
     --- Alas Scribunto NÃO implementa corrotinas, de acordo com
     --- http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#string.format
     --- isso não nos impedirá de tentar implementar uma única chamada de função ruim
    if _G[1] then
        reserved_function, reserved_contents = mw.ustring.match(_G[1], "^%s*(%a[^%s%(]*)%(([^%)]*)%)%s*$")
    end
    if reserved_contents then
        local reserved_counter = 0
        repeat
            reserved_counter = reserved_counter + 1
            reserved_value[reserved_counter] = _G[mw.ustring.match(reserved_contents, "([^%,]+)")]
            reserved_contents = mw.ustring.match(reserved_contents, "[^%,]+,(.*)$")
        until not reserved_contents
    end
    local reserved_arraypart = _G
    while mw.ustring.match(reserved_function, "%.") do
        reserved_functionpart, reserved_function = mw.ustring.match(reserved_function, "^(%a[^%.]*)%.(.*)$")
        reserved_arraypart = reserved_arraypart[reserved_functionpart]
    end
    local reserved_call = reserved_arraypart[reserved_function]
    if type(reserved_call) ~= "function" then
        return tostring(reserved_call)
    else 
    	reserved_output = {reserved_call(unpack(reserved_value))}
        return reserved_output[reserved_return or 1]
    end
end

local function tonumberOrString(v)
	return tonumber(v) or v:gsub("^\\", "", 1)
end

local function callWithTonumberOrStringOnPairs(f, ...)
	local args = {}
	for _, v in ... do
		table.insert(args, tonumberOrString(v))
	end
	return (f(unpack(args)))
end

--[[
------------------------------------------------------------------------------------
-- ipairsAtOffset

-- Este é um iterador para arranjos. Ele pode ser usado como ipairs, mas com 
-- i especificado como primeiro índice a ser iterado. i é um deslocamento a 
-- partir de 1.
--
------------------------------------------------------------------------------------
--]]
local function ipairsAtOffset(t, i)
	local f, s, i0 = ipairs(t)
	return f, s, i0+i
end

local function get(s)
	local G = _G; for _ in mw.text.gsplit(
		mw.text.trim(s, '%s'), '%s*%.%s*'
	) do
		G = G[_]
	end
	return G
end

--[[
------------------------------------------------------------------------------------
-- call
--
-- Esta função geralmente é útil para depurar parâmetros de predefinições.
-- Prefixe o parâmetro com barra invertida (\) para forçar a interpretação do 
-- parâmetro como sequência (string).
-- A barra invertida inicial será removida antes de ser passada para a função Lua.
--
-- Exemplo:
--    {{#invoke:LuaCall/Testes|call|mw.log|a|1|2|3}} irá retornar os resultados de 
-- mw.log('a', 1, 2, 3)
--    {{#invoke:LuaCall/Testes|call|mw.logObject|\a|321|\321| \321 }} irá retornar os 
-- resultados de mw.logObject('a', 321, '321', ' \\321 ')
--
-- Este exemplo mostra a depuração para ver quais caracteres Unicode são permitidos
-- nos parâmetros das predefinições,
--    {{#invoke:LuaCall/Testes|call|mw.ustring.codepoint|{{#invoke:LuaCall/Testes|call|mw.ustring.char|0x0061}}}} 
-- retorna 97
--    {{#invoke:LuaCall/Testes|call|mw.ustring.codepoint|{{#invoke:LuaCall/Testes|call|mw.ustring.char|0x0000}}}} 
-- retorna 65533
--    {{#invoke:LuaCall/Testes|call|mw.ustring.codepoint|{{#invoke:LuaCall/Testes|call|mw.ustring.char|0x0001}}}} 
-- retorna 65533
--    {{#invoke:LuaCall/Testes|call|string.format|0x%04x|{{#invoke:LuaCall/Testes|call|mw.ustring.codepoint|{{#invoke:LuaCall/Testes|call|mw.ustring.char|0x0002}}}}}}
-- retorna 0xfffd
--    {{#invoke:LuaCall/Testes|call|string.format|0x%04x|{{#invoke:LuaCall/Testes|call|mw.ustring.codepoint|{{#invoke:LuaCall/Testes|call|mw.ustring.char|0x007e}}}}}}
-- retorna 0x007e
--    {{#invoke:LuaCall/Testes|call|string.format|0x%04x|{{#invoke:LuaCall/Testes|call|mw.ustring.codepoint|{{#invoke:LuaCall/Testes|call|mw.ustring.char|0x007f}}}}}}
-- retorna 0x007f
--    {{#invoke:LuaCall/Testes|call|string.format|0x%04x|{{#invoke:LuaCall/Testes|call|mw.ustring.codepoint|{{#invoke:LuaCall/Testes|call|mw.ustring.char|0x0080}}}}}}
-- retorna 0x0080
--    {{#invoke:LuaCall/Testes|call|string.format|0x%04x|{{#invoke:LuaCall/Testes|call|mw.ustring.codepoint|{{#invoke:LuaCall/Testes|call|mw.ustring.char|0x00a0}}}}}}
-- retorna 0x00a0
--
------------------------------------------------------------------------------------
--]]
function p.call(frame)
	return callWithTonumberOrStringOnPairs(get(frame.args[1]),
		ipairsAtOffset(frame.args, 1)
	)
end

--local TableTools = require('Módulo:TableTools/Testes')
--[[
------------------------------------------------------------------------------------
-- get
--
-- Exemplo:
--    {{#invoke:LuaCall/Testes|get| math.pi }} irá retornar o valor de math.pi
--    {{#invoke:LuaCall/Testes|get|math|pi}} irá retornar o valor de math.pi
--    {{#invoke:LuaCall/Testes|get| math |pi}} irá retornar o valor de _G[' math '].pi
--    {{#invoke:LuaCall/Testes|get|_G| math.pi }} irá retornar o valor de _G[' math.pi ']
--    {{#invoke:LuaCall/Testes|get|obj.a.5.c}} irá retornar o valor de obj.a['5'].c
--    {{#invoke:LuaCall/Testes|get|obj|a|5|c}} irá retornar o valor de obj.a[5].c
--
------------------------------------------------------------------------------------
--]]
function p.get(frame)
	-- #frame.args sempre retorna 0, independentemente do número de parâmetros 
	-- sem nome das predefinições, portanto, verifique manualmente
	if frame.args[2] == nil then
		-- não faça tonumber() para este estilo de argumentos,
		-- sempre trate isso como sequência (string),
		-- então 'obj.1' significará obj['1'] em vez de obj[1]
		return get(frame.args[1])
	else
		local G = _G
		for _, v in ipairs(frame.args) do
			G = G[tonumberOrString(v)]
		end
		return G
	end
end

--[[
------------------------------------------------------------------------------------
-- invoke
--
-- Esta função é usada por Predefinição:Invoke
--
------------------------------------------------------------------------------------
--]]
function p.invoke(frame)
	local pframe, usedpargs = frame:getParent(), {}
	-- obtém nomes de funções e módulos a partir dos argumentos parentais, se
	-- não forem fornecidos
	local pfargs = setmetatable({frame.args[1], frame.args[2]}, {__index = table})
	if not pfargs[1] then
		pfargs[1], usedpargs[1] = pframe.args[1], true
		if not pfargs[2] then
			pfargs[2], usedpargs[2] = pframe.args[2], true
		end
	elseif not pfargs[2] then
		pfargs[2], usedpargs[1] = pframe.args[1], true
	end
	-- reempacota argumentos sequenciais
	for i, v in ipairs(pframe.args) do
		if not usedpargs[i] then
			pfargs:insert(v)
			usedpargs[i] = true
		end
	end
	-- copia outros argumentos
	for k, v in pairs(pframe.args) do
		if not pfargs[k] and not usedpargs[k] then
			pfargs[k], usedpargs[k] = v, true
		end
	end
	-- #invoke o quadro parental para que o novo quadro tenha o mesmo parental
	return pframe:callParserFunction{name = '#invoke', args = pfargs}
end

return p