lua-users home
lua-l archive

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


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