mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Scribunto
synced 2024-11-25 00:26:44 +00:00
90 lines
2.2 KiB
Lua
90 lines
2.2 KiB
Lua
|
|
||
|
local setmetatable, getmetatable, tostring, load, pairs, ipairs, next, assert, unpack
|
||
|
= setmetatable, getmetatable, tostring, load, pairs, ipairs, next, assert, unpack
|
||
|
local tconcat
|
||
|
= table.concat
|
||
|
local strformat
|
||
|
= string.format
|
||
|
local cowrap, yield
|
||
|
= coroutine.wrap, coroutine.yield
|
||
|
local _G = _G
|
||
|
|
||
|
setfenv(1,{})
|
||
|
|
||
|
local sb_meta = {
|
||
|
__tostring = function(self) return tconcat(self); end;
|
||
|
__call = function(self,v) self[#self+1] = tostring(v); return self; end;
|
||
|
__index = {
|
||
|
add = function(self,v)
|
||
|
self[#self+1] = tostring(v)
|
||
|
return self
|
||
|
end;
|
||
|
addquoted = function(self, v)
|
||
|
self[#self+1] = strformat('%q', tostring(v))
|
||
|
return self
|
||
|
end;
|
||
|
compile = function(self, chunk_name)
|
||
|
local localvars = self.localvars
|
||
|
local params = self.params
|
||
|
if not next(localvars) and not params then
|
||
|
local chunkthread = cowrap(function()
|
||
|
for _,chunk in ipairs(self) do
|
||
|
yield(chunk)
|
||
|
end
|
||
|
yield(nil)
|
||
|
end)
|
||
|
return assert(load(chunkthread,chunk_name))
|
||
|
end
|
||
|
local locals, ilocals = {}, 0
|
||
|
local chunkthread = cowrap(function()
|
||
|
if next(localvars) then
|
||
|
yield 'local '
|
||
|
for k,v in pairs(localvars) do
|
||
|
yield(k)
|
||
|
if next(localvars,k) then
|
||
|
yield ','
|
||
|
end
|
||
|
ilocals = ilocals+1
|
||
|
locals[ilocals] = v
|
||
|
end
|
||
|
yield ' = ...; '
|
||
|
end
|
||
|
yield 'return function('
|
||
|
if params then
|
||
|
yield(params)
|
||
|
end
|
||
|
yield ') '
|
||
|
for _,chunk in ipairs(self) do
|
||
|
yield(chunk)
|
||
|
end
|
||
|
yield '\nend'
|
||
|
yield(nil)
|
||
|
end)
|
||
|
local funcbuilder = assert(load(chunkthread,chunk_name))
|
||
|
return funcbuilder(unpack(locals,1,ilocals))
|
||
|
end;
|
||
|
localvar = function(self, val)
|
||
|
local lv = self.localvars
|
||
|
local i = 1
|
||
|
local lvname
|
||
|
while true do
|
||
|
lvname = '__lv_' .. i
|
||
|
if not lv[lvname] then
|
||
|
break
|
||
|
end
|
||
|
i = i + 1
|
||
|
end
|
||
|
lv[lvname] = val
|
||
|
return lvname
|
||
|
end;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
local function stringbuilder()
|
||
|
return setmetatable({localvars={}}, sb_meta)
|
||
|
end
|
||
|
|
||
|
_G.stringbuilder = stringbuilder
|
||
|
|
||
|
return stringbuilder
|