Module:LuaCall: Difference between revisions

From Test Wiki
Content deleted Content added
re-factoring
Locusta (talk | contribs)
Note: Since imported from Wikipedia, this is licensed as Creative Commons Attribution-ShareAlike License 4.0.
 
(15 intermediate revisions by 5 users not shown)
Line 1: Line 1:
-- Imported from Wikipedia
-- Licensed as CC BY-SA 4.0
-- See edit history for attribution
local p={}
local p={}


function p.main(frame)
function p.main(frame)
local parent=frame.getParent(frame) or {}
local parent = frame.getParent(frame) or {}
local reserved_value={}
local reserved_value = {}
local reserved_function,reserved_contents
local reserved_function, reserved_contents
for k,v in pairs(parent.args or {}) do
for k, v in pairs(parent.args or {}) do
_G[k]=tonumber(v) or v -- transfer every parameter directly to the global variable table
_G[k] = tonumber(v) or v -- transfer every parameter directly to the global variable table
end
end
for k,v in pairs(frame.args or {}) do
for k, v in pairs(frame.args or {}) do
_G[k]=tonumber(v) or v -- transfer every parameter directly to the global variable table
_G[k] = tonumber(v) or v -- transfer every parameter directly to the global variable table
end
end
--- Alas Scribunto does NOT implement coroutines, according to
--- Alas Scribunto does NOT implement coroutines, according to
Line 15: Line 18:
--- this will not stop us from trying to implement one single lousy function call
--- this will not stop us from trying to implement one single lousy function call
if _G[1] then
if _G[1] then
reserved_function,reserved_contents=mw.ustring.match(_G[1],"^%s*(%a[^%s%(]*)%(([^%)]*)%)%s*$")
reserved_function, reserved_contents = mw.ustring.match(_G[1], "^%s*(%a[^%s%(]*)%(([^%)]*)%)%s*$")
end
end
if reserved_contents then
if reserved_contents then
local reserved_counter=0
local reserved_counter = 0
repeat
repeat
reserved_counter=reserved_counter+1
reserved_counter = reserved_counter + 1
reserved_value[reserved_counter]=_G[mw.ustring.match(reserved_contents,"([^%,]+)")]
reserved_value[reserved_counter] = _G[mw.ustring.match(reserved_contents, "([^%,]+)")]
reserved_contents=mw.ustring.match(reserved_contents,"[^%,]+,(.*)$")
reserved_contents = mw.ustring.match(reserved_contents, "[^%,]+,(.*)$")
until not reserved_contents
until not reserved_contents
end
end
local reserved_arraypart=_G
local reserved_arraypart = _G
while mw.ustring.match(reserved_function,"%.") do
while mw.ustring.match(reserved_function, "%.") do
reserved_functionpart,reserved_function=mw.ustring.match(reserved_function,"^(%a[^%.]*)%.(.*)$")
reserved_functionpart, reserved_function = mw.ustring.match(reserved_function, "^(%a[^%.]*)%.(.*)$")
reserved_arraypart=reserved_arraypart[reserved_functionpart]
reserved_arraypart = reserved_arraypart[reserved_functionpart]
end
end
local reserved_call=reserved_arraypart[reserved_function]
local reserved_call = reserved_arraypart[reserved_function]
if type(reserved_call)~="function" then
if type(reserved_call) ~= "function" then
return tostring(reserved_call)
return tostring(reserved_call)
else
else reserved_output={reserved_call(unpack(reserved_value))}
reserved_output = {reserved_call(unpack(reserved_value))}
return reserved_output[reserved_return or 1]
return reserved_output[reserved_return or 1]
end
end
Line 48: Line 52:
end
end
return (f(unpack(args)))
return (f(unpack(args)))
end

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


Line 108: Line 104:
return callWithTonumberOrStringOnPairs(get(frame.args[1]),
return callWithTonumberOrStringOnPairs(get(frame.args[1]),
ipairsAtOffset(frame.args, 1)
ipairsAtOffset(frame.args, 1)
)
end

--[[
------------------------------------------------------------------------------------
-- call_s
--
-- Like call(), but passing all arguments as string (no conversion)
------------------------------------------------------------------------------------
--]]
function p.call_s(frame)
-- unpack() not work on metatable
--return get(frame.args[1])(unpack(frame.args, 2))
return get(frame.args[1])(
unpack(pairs2Array(ipairsAtOffset(frame.args, 1)))
)
)
end
end
Line 167: Line 148:
--]]
--]]
function p.invoke(frame)
function p.invoke(frame)
local pframe, usedpargs = frame:getParent(), {}
local func
-- get module and function names from parent args if not provided
local offset
if frame.args[1] ~= nil then
local pfargs = setmetatable({frame.args[1], frame.args[2]}, {__index = table})
if not pfargs[1] then
local m = require('Module:' .. frame.args[1])
pfargs[1], usedpargs[1] = pframe.args[1], true
if frame.args[2] ~= nil then
func = m[frame.args[2]]
if not pfargs[2] then
pfargs[2], usedpargs[2] = pframe.args[2], true
frame.args = frame:getParent().args
offset = 0
else
frame.args = frame:getParent().args
func = m[frame.args[1]]
offset = 1
end
end
elseif not pfargs[2] then
else
pfargs[2], usedpargs[1] = pframe.args[1], true
frame.args = frame:getParent().args
func = require('Module:' .. frame.args[1])[frame.args[2]]
offset = 2
end
end
-- repack sequential args
local args = {}
for _, v in ipairsAtOffset(frame.args, offset) do
for i, v in ipairs(pframe.args) do
if not usedpargs[i] then
table.insert(args, v)
pfargs:insert(v)
usedpargs[i] = true
end
end
-- copy other args
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
end
-- #invoke off parent frame so the new frame has the same parent
frame.args = args
return pframe:callParserFunction{name = '#invoke', args = pfargs}
return func(frame)
end
end