[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: help to (slightly) modify Lua interpreter
- From: Doug Rogers <doug.rogers@...>
- Date: Thu, 05 Nov 2009 13:59:11 -0500
Francesco Abbate wrote:
> I better thought about this problem and the __call metamethod does not
> make the affair since, for assignments, the syntax:
> m(i,j) = value
> will be invalid.
I've gotta get your GSL shell installed. I wrote a similar thing a few
years back but I never followed through to the end. I had to ditch GSL
anyway due to its license (which I mistakenly thought was LGPL when I
started the project). But I kept the Lua part, switching to another
vector/matrix package.
Well, you've inspired me to do some crazy coding. I use the __call
metamethod on a tensor (matrix of possibly more dimensions) to return an
element-reference object whose own __call metamethod allows access to
the element. I also provide set() and get() functions may be used for
the element-reference object. Finally, just for fun, I overload __index
and __newindex to get or set the element, but that requires a dummy index.
Below is the bottom portion of the code, followed by a run. The full
code follows that. I like the way that recursion, varargs and the
metamethods work together. A fuller code base would have checks on the
dimensions of items so that sub-tensors could be set, etc.
Enjoy!
-- Here we go...
p = tensor(2,3,4)
print(p:tostring())
-- Using call interface.
p(2,3,4)(234) -- __call with a value sets the element.
print(p(2,3,4)()) -- __call without a value gets the element.
print(p:tostring())
-- Using a dummy index to set/get values:
local _ = true -- Can be anything except nil.
p(1,2,3)[_] = 123
print(p(1,2,3)[_])
print(p:tostring())
-- Using set/get directly.
p(1,2,2):set(122)
print(p(1,2,2):get())
print(p:tostring())
Output:
{{{0,0,0,0},{0,0,0,0},{0,0,0,0}},{{0,0,0,0},{0,0,0,0},{0,0,0,0}}}
234
{{{0,0,0,0},{0,0,0,0},{0,0,0,0}},{{0,0,0,0},{0,0,0,0},{0,0,0,234}}}
123
{{{0,0,0,0},{0,0,123,0},{0,0,0,0}},{{0,0,0,0},{0,0,0,0},{0,0,0,234}}}
122
{{{0,0,0,0},{0,122,123,0},{0,0,0,0}},{{0,0,0,0},{0,0,0,0},{0,0,0,234}}}
The full code:
function elem_ref_set(ref, val)
ref.t[ref.i] = val
return val
end
function elem_ref_get(ref)
return ref.t[ref.i]
end
elem_ref_mt = {
__index = function (t, k)
if k == 'get' then return elem_ref_get end
if k == 'set' then return elem_ref_set end
return t.t[t.i]
end,
__newindex = function (t, k, v)
t.t[t.i] = v
end,
__call = function (t, val, ...)
if val == nil then
return t.t[t.i]
end
t.t[t.i] = val
return val
end
}
function elem_ref(t, i, ...)
if type(t[i]) ~= 'table' then
return setmetatable({ t = t, i = i }, elem_ref_mt)
end
return elem_ref(t[i], ...)
end
function tensor_tostring(m)
if type(m) ~= 'table' then
return tostring(m)
end
local t = { "{" }
for i, row in ipairs(m) do
if i > 1 then t[#t+1] = "," end
t[#t+1] = tensor_tostring(row)
end
t[#t+1] = "}"
return table.concat(t)
end
tensor_mt = {
__call = function (m, ...)
return elem_ref(m, ...)
end,
__index = { tostring = tensor_tostring },
}
function tensor_new(_,N,...)
if not N then
return 0
else
local m = {}
for i = 1, N do
m[i] = tensor_new(_, ...)
end
return setmetatable(m, tensor_mt)
end
end
-- This is for creation of tensors. This has nothing to do
-- with setting/getting elements.
tensor = setmetatable({}, { __call = tensor_new })
-- Here we go...
p = tensor(2,3,4)
print(p:tostring())
-- Using call interface.
p(2,3,4)(234) -- __call with a value sets the element.
print(p(2,3,4)()) -- __call without a value gets the element.
print(p:tostring())
-- Using a dummy index to set/get values:
local _ = true -- Can be anything except nil.
p(1,2,3)[_] = 123
print(p(1,2,3)[_])
print(p:tostring())
-- Using set/get directly.
p(1,2,2):set(122)
print(p(1,2,2):get())
print(p:tostring())
______________________________________________________________________________________
The information contained in this email transmission may contain proprietary and business
sensitive information. If you are not the intended recipient, you are hereby notified that
any review, dissemination, distribution or duplication of this communication is strictly
prohibited. Unauthorized interception of this e-mail is a violation of law. If you are not
the intended recipient, please contact the sender by reply email and immediately destroy all
copies of the original message.
Any technical data and/or information provided with or in this email may be subject to U.S.
export controls law. Export, diversion or disclosure contrary to U.S. law is prohibited.
Such technical data or information is not to be exported from the U.S. or given to any foreign
person in the U.S. without prior written authorization of Elbit Systems of America and the
appropriate U.S. Government agency.