lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]




On 25/10/15 07:37 PM, Egor Skriptunoff wrote:
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?
https://github.com/SoniEx2/loadx

--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.