[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [ANN] llua Higher-level C API for Lua
- From: steve donovan <steve.j.donovan@...>
- Date: Thu, 13 Mar 2014 20:25:59 +0200
On Mon, Mar 10, 2014 at 6:46 PM, steve donovan
<steve.j.donovan@gmail.com> wrote:
> sometimes. With a project of this nature, it's not always clear how
> far to go, and what common patterns to support - which is why I
> decided for an early release.
Correctness is generally more important than coverage, and I've tagged
a 0.3 release which is reasonably solid. Strings are now always
copied, unless you explicitly use llua_tostring on a reference. They
can be arbitrary byte sequences, and array_len(s) will give the
correct length.
Sometimes you don't want the overhead of a copy. It's possible to
force llua to return everything as Lua references - normally it will
try to convert to llua values whenever possible. So here the call to
the read method of the file object has L_REF:
void *P = obj_pool();
llua_verbose(stderr); // tell us of unrefs...
llua _G = llua_global(L);
#define G(name) llua_gets(_G,name)
// f = io.open(file,'rb'); text = in:read('*a'); f:close()
// Lua error convention: value or nil, errstr
llua in = llua_callf(G("io.open"),"ss",file,"rb",L_ERR);
if (value_is_error(in)) {
fprintf(stderr,"error: %s\n",in);
return 1;
}
llua text = llua_callf(in,"ms","read","*a",L_REF);
llua_callf(in,"m","close","");
// text here is a reference to a Lua string,
// can use llua_tostring() to get pointer.
// Note this works with an arbitrary binary file!
printf("size of %s was %d\n",file,llua_len(text));
unref(P) ; // all refs are freed.
//~ free L 0000000000306B80 ref 3 type table
//~ free L 0000000000306B80 ref 4 type function
//~ free L 0000000000306B80 ref 5 type userdata
//~ free L 0000000000306B80 ref 6 type string
Another noteworthy new feature is L_ERR, which is the usual Lua
calling convention, returning either the value or (nil,error-string).
In this example (see [1]) we're also using an object pool to clean up
all references. This allows for lazy yet correct programming
practices.
There's also a useful macro that implements iteration over a table.
I'm constantly having to look up how to do this, and suspect I'm not
alone. However, this is a thin wrapper over the basic use of lua_next
and requires good stack discipline; L_TKEY is (-2) and L_TVAL is (-1).
// all keys in _G beginning with 's'
FOR_TABLE(G) {
if (llua_callf(strfind,"vs",L_TKEY,"^s",L_VAL))
printf("match %s\n",lua_tostring(L,L_TKEY));
}
Note the new llua_callf type specifier 'v' which takes a stack index
(uses lua_pushvalue)
Documentation is currently 'under construction' and, besides the
readme, the best docs will be the examples.
steve d.
[1] https://github.com/stevedonovan/llua/blob/master/file-size.c