1 Jan 04:19
Re: A question about table's length
Eike Decker <zet23t <at> googlemail.com>
2010-01-01 03:19:54 GMT
2010-01-01 03:19:54 GMT
This looks terribly interesting ... generating bindings into C code in such a way is something that I would greatly endorse. Even more if it cooperates nicely with JIT compilation.
Happy new Year,
Eike
On Dec 31, 2009 8:02 PM, "Mike Pall" <mikelu-0912 <at> mike.de> wrote:Mark Hamburg wrote: > Side note to Mike Pall on that subject: You mentioned the > possibility of tea...
This is dependent on the last work item on the status page: access
to structured binary data plus the FFI. Once this is in place, it
should be quite easy. You can just cut'n'paste your C struct
definitions and allocate userdata objects holding such a struct
(or a union, an array or a nested mix of them).
I haven't given much thought to the API yet, but it might look
something like this:
ffi.def[[
struct foo {
uint16_t bar, baz;
int i;
double d;
};
struct foo *foo_in(void);
void foo_out(struct foo *);
]]
local lib = ffi.bindlib("myfoolib")
local a = lib.foo_in()
local b = ffi.new("struct foo")
b.i = a.i + 10
b.bar = bit.bxor(a.bar, a.baz)
b.baz = 0x1234
b.d = a.d - 1.5
lib.foo_out(b)
-- Nice side-effect: efficient, mutable buffers for Lua.
local buf = ffi.new("uint8_t[?]", n)
for i=0,n-1 do
buf[i] = i
end
io.write(buf) -- Extended to understand binary data.
As you can see, this allows one to access C structs just like Lua
tables. Obviously these structs can be exchanged with the C side
via the FFI. All operations on these structures can be reduced by
the JIT compiler to essentially the same machine code a C compiler
would produce.
Objects allocated on the Lua side are special userdatas and
garbage collected as usual. Data passed in from the C side gets a
tiny userdata wrapper (which may be optimized away by the JIT
compiler). The userdata wrapper is GCed, but the data itself is
owned by the C side and needs manual lifetime management. You can
associate a __gc metamethod to signal the C side.
These special userdatas have no metatable by default, but redirect
index/newindex to internal accessor functions. You can augment
them with your own index/newindex or other metamethods to get
OO-like behavior.
This is just the basic infrastructure. Automatic C library wrappers
or higher-level bindings can be implemented on top of it in pure
Lua. This could even be extended to create (mostly) automatic and
highly-efficient C++ bindings, but this is notoriously difficult.
At least that's the plan ...
--Mike
As a new example it shows how to easily combine steps
in a sequece to form a new primitive operator. In this case: map
tonumber and filter out actual numbers.
The main function is "seq" that creates a sequence from an iterator.
The "map" and "filter" operators are included as basic operators (it
is easy to roll your own). Finally two examples show how to use all
this...
Bye,
Wim
local type = type
function seq(f, state, key)
local function self(s, k, ...)
if type(s) == "function" then
f = s(self, f, k, ...) or f
return self, state, key
else
return f(s, k)
end
end
return self, state, key
end
function filter(seq, f, test)
local function self(s, k, ...)
if k ~= nil then
if test(k, ...) then
return k, ...
end
return self(s, f(s, k))
end
end
return function(s, k)
return self(s, f(s, k))
end
end
function map(seq, f, op)
local function self(k, ...)
if k ~= nil then
return op(k, ...)
end
end
return function(s, k)
return self(f(s, k))
end
end
-- -- only example code below this line -- --
-- a first simple example showing the use of "seq", "map" and "filter"
local function is_odd(i, x)
return x%2 == 1
end
local function square(i, x)
return i, x^2
end
list = {1,2,3,4,5,6,7,8,9,10}
for i, x in seq(ipairs(list)) (map, square) (filter, is_odd) do
print(i, x)
end
-- a seconde example that shows how to easily combine steps in a sequence
local function is_number(i, x)
return type(x) == "number"
end
local function to_number(i, x)
return i, tonumber(x)
end
local function select_numbers(seq)
seq(map, to_number)(filter, is_number)
end
list = {"1", "2", "aap", "3", false, "4", 5, {}}
for i, x in seq(ipairs(list)) (select_numbers) do
print(i, x)
end
RSS Feed