Module:LuaCall: Difference between revisions

From Test Wiki
Content deleted Content added
This module is complicated enough as is. You don't need to add even more tangential functions, when p.call was working perfectly fine for months
Locusta (talk | contribs)
Note: Since imported from Wikipedia, this is licensed as Creative Commons Attribution-ShareAlike License 4.0.
 
(6 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 144: 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