On Sun, Oct 25, 2015 at 8:29 PM, Patrick Donnelly
<batrick@batbytes.com <mailto:batrick@batbytes.com>> wrote:
The existing functionality (debug.upvaluejoin) is all you need to do
what you want:
- Declare locals to be exported:
local x = 1
export("x", function() return x end) -- **
local y = 2
export("y", function() return y end)
- hook the load function which creates locals with the names of the
exported locals and then joins them to the loaded chunk, something
like:
Patrick, thanks for the idea!
It is quite workable, albeit rather anti-aesthetic due to exporting
new function body for every local:
local a, b, c = 1, 2, 3
export("x", function() return a end)
export("y", function() return b end)
export("z", function() return c end)
local f = load_with_upvalues("print(x + y + z); x, y, z = x+1, y*2,
z^3")
Compare with this nice-and-easy thing I wanted:
local a, b, c = 1, 2, 3
local f = load_with_upvalues(@a, @b, @c, "upvalue x, y, z; print(x +
y + z); x, y, z = x+1, y*2, z^3")
local new_chunk = "local x,y; return function(...)"..chunk.." end"
local f = original_load(new_chunk)()
-- join exported upvalues on f
There is one little problem with your solution: if the program is
stored as .luac-file with debug info stripped, it is impossible to
distinguish between upvalues x and y in function f: both have the same
name = "(*no name)" and the same value = nil.
Upvalue indices don't contain useful information also:
"Upvalues have no particular order, as they are active through the
whole function. They are numbered in an arbitrary order." (c)Lua manual
To solve this problem, the upvalues should contain its names as values:
local new_chunk = "local x,y = 'x','y'; return
function(...)"..chunk.." end"
Let's think about optimization of this clumsy sequence of export() lines:
local x1, x2, x3, x4, x5, x6, x7
export("x1", function() return x1 end)
export("x2", function() return x2 end)
...
export("x7", function() return x7 end)
We can export N variables using only 1+log(N) parameters: 1 string and
log(N) functions:
local x1, x2, x3, x4, x5, x6, x7
export_all("x1,x2,x3,x4,x5,x6,x7",
function()x1()x3()x5()x7()end,
function()x2()x3()x6()x7()end,
function()x4()x5()x6()x7()end
)
Now we can detect the correspondence of 7 upvalues (partially shared
between 3 functions) to 7 variable names.
But I think the code has gotten even more clumsy...
Any new ideas?