มอดูล:LuaCall

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
_Gk=tonumber(v) or v -- transfer every parameter directly to the global variable table
end
for k,v in pairs(frame.args or {}) do
_Gk=tonumber(v) or v -- transfer every parameter directly to the global variable table
end
--- Alas Scribunto does NOT implement coroutines, according to
--- http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#string.format
--- this will not stop us from trying to implement one single lousy function call
if _G1 then
reserved_function,reserved_contents=mw.ustring.match(_G1,"^%s*(%a^%s%(*)%((^%)*)%)%s*$")
end
if reserved_contents then
local reserved_counter=0
repeat
reserved_counter=reserved_counter+1
reserved_valuereserved_counter=_Gmw.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_arraypartreserved_functionpart
end
local reserved_call=reserved_arraypartreserved_function
if type(reserved_call)~="function" then
return tostring(reserved_call)
else reserved_output={reserved_call(unpack(reserved_value))}
return reserved_outputreserved_return or 1
end
end
local function tonumberOrString(v)
	return tonumber(v) or v:gsub("^\\", "", 1)
end
local function pairs2ArrayWithFunc(f, ...)
	local args = {}
	for _, v in ... do
		table.insert(args, f(v))
	end
	return args
end
local function pairs2Array(...)
	local args = {}
	for _, v in ... do
		table.insert(args, v)
	end
	return args
end
--
------------------------------------------------------------------------------------
-- ipairsAtOffset
-- This is an iterator for arrays. It can be used like ipairs, but with
-- specified i as first index to iterate. i is an offset from 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
local function call(s, args, ret)
	if ret then
		return ({get(s)(unpack(args))})tonumber(ret)
	end
	return get(s)(unpack(args))
end
--
------------------------------------------------------------------------------------
-- call
--
-- This function is usually useful for debugging template parameters.
-- Prefix parameter with backslash (\) to force interpreting parameter as string.
-- The leading backslash will be removed before passed to Lua function.
--
-- Example:
--    3 will return results of mw.log('a', 1, 2, 3)
--     \321  will return results of mw.logObject('a', 321, '321', ' \\321 ')
--
-- This example show the debugging to see which Unicode characters are allowed in template parameters,
--     return 97
--     return 65533
--     return 65533
--     return 0xfffd
--     return 0x007e
--     return 0x007f
--     return 0x0080
--     return 0x00a0
--
------------------------------------------------------------------------------------
--
function p.call(frame)
	return call(frame.args1,
		pairs2ArrayWithFunc(tonumberOrString, ipairsAtOffset(frame.args, 1)),
		frame.args'return'
	)
end
--
------------------------------------------------------------------------------------
-- call_n
--
-- Like call(), but passing all arguments as number
------------------------------------------------------------------------------------
--
function p.call_n(frame)
	return call(frame.args1,
		pairs2ArrayWithFunc(tonumber, ipairsAtOffset(frame.args, 1)),
		frame.args'return'
	)
end
--
------------------------------------------------------------------------------------
-- call_s
--
-- Like call(), but passing all arguments as string (no conversion)
------------------------------------------------------------------------------------
--
function p.call_s(frame)
	-- unpack() not work on metatable
	-- enclosing result in (), so that it will return only 1st element of result
	--return (get(frame.args1)(unpack(frame.args, 2)))
	return call(frame.args1,
		pairs2Array(ipairsAtOffset(frame.args, 1)),
		frame.args'return'
	)
end
--local TableTools = require('Module:TableTools')
--
------------------------------------------------------------------------------------
-- get
--
-- Example:
--     math.pi  will return value of math.pi
--    pi will return value of math.pi
--    pi will return value of _G' math '.pi
--     math.pi  will return value of _G' math.pi '
--    obj.a.5.c will return value of obj.a'5'.c
--    c will return value of obj.a5.c
--
------------------------------------------------------------------------------------
--
function p.get(frame)
	-- #frame.args always return 0, regardless of number of unnamed
	-- template parameters, so check manually instead
	if frame.args2 == nil then
		-- not do tonumber() for this args style,
		-- always treat it as string,
		-- so 'obj.1' will mean obj'1' rather obj1
		return get(frame.args1)
	else
		local G = _G
		for _, v in ipairs(frame.args) do
			G = GtonumberOrString(v)
		end
		return G
	end
end
--
------------------------------------------------------------------------------------
-- invoke
--
-- This function is used by Template:Invoke
--
------------------------------------------------------------------------------------
--
function p.invoke(frame)
	local func
	local offset
	if frame.args1 ~= nil then
		local m = require('Module:' .. frame.args1)
		if frame.args2 ~= nil then
			func = mframe.args2
			frame.args = frame:getParent().args
			offset = 0
		else
			frame.args = frame:getParent().args
			func = mframe.args1
			offset = 1
		end
	else
		frame.args = frame:getParent().args
		func = require('Module:' .. frame.args1)frame.args2
		offset = 2
	end
	local args = {}
	for _, v in ipairsAtOffset(frame.args, offset) do
		table.insert(args, v)
	end
	frame.args = args
	return func(frame)
end
return p