1

I work on Lua electronic device simulation plug in.
I want to make it good in design and usability, as most probably a lot of users are far from IT and debugging.
Users describe device in Lua and plug in translates it via Lua C API.
Users may misspell function names, variables types and arguments order.
Good manual helps but application shouldn't crash or provide bad described errors. I didn't find any "best practices" and want to ask experience users as I'm quite new to Lua.

Arguments' order and type

At the moment Lua functions are declared like this:

typedef struct lua_bind_func
{
    int32_t ( *lua_c_api ) ( lua_State* );
    const char* lua_func_name;
} lua_bind_func;

And then

{.lua_func_name="state_to_string", .lua_c_api=&lua_state_to_string},

In order to check that argument order and types are passed correct:

Create macros:

#define STRING (&lua_isstring)
#define INT (&lua_isinteger)
#define USER (&lua_islightuserdata)

Add an array to the list:

int ( *args[16] ) ( lua_State*, int index );

Change function list:

{.lua_func_name="set_callback", .lua_c_api=&lua_set_callback, .args={INT, INT}}

Argument list checker:

static void
SAFE_EXECUTE ( lua_State* L, void* curfunc )
{
    int argnum = lua_gettop ( L );
    for ( int i=0; lua_c_api_list[i].lua_func_name; i++ )
    {
        if ( curfunc == lua_c_api_list[i].lua_c_api )
        {
            for ( int argcount=0; lua_c_api_list[i].args[argcount]; argcount++ )
            {
                if ( argnum < argcount+1 )
                {
                    IDSIMMODEL* model = ( IDSIMMODEL* ) lua_get_model_obj ( L );
                    print_error ( model, "Too few arguments passed to the function \"%s\"", lua_c_api_list[i].lua_func_name );
                }
                else if ( !lua_c_api_list[i].args[argcount] ( L, argcount+1 ) )
                {
                    IDSIMMODEL* model = ( IDSIMMODEL* ) lua_get_model_obj ( L );
                    print_error ( model, "Argument %d is of wrong type", argcount+1 );
                }
            }
        }
    }
}

Then I can check argument order, their types and can create corresponding error message with mini help:

SAFE_EXECUTE ( L, &lua_set_callback );

The code doesn't handle extra arguments, but it's easy to add.
Question: Is it OK scenario or may be there is a better one?

Misspelled function names

For example I have the following code:

set_callback(time + 100 * MSEC, PC_EVENT)   
set_calback(time + 200 * MSEC, PC_EVENT)
set_callback(time + 333 * MSEC, PC_EVENT)   

The second one is misspelled and after this part no code is executed.
I can't understand how to catch a call to undefined function in C in order to raise adequate error.

Other pitfalls

Maybe there are more possible pitfalls I don't know about?

pugnator
  • 665
  • 10
  • 27
  • 1
    Normally you just check the arguments passed in right in the `lua_CFunction` function itself by calling `lua_check*` provided by lua's API. It's not clear why you need to put them into a link list at all. If you need more control over how lua scripts are executed, functions like `pcall` and `xpcall` can be helpful here. You can also simulate python's keyword argument parameters by using lua-tables, in which case, parameter order doesn't matter as much. – greatwolf Feb 20 '15 at 02:24
  • The reason is to make it more demonstrative and each check is just single line loop check. But the idea with table is very interesting. Can you reply it as a question? – pugnator Feb 20 '15 at 07:34
  • 1
    It might be helpful if you post the binding code that shows how you're checking the arguments and how you're calling the underlying C function. Note also you don't need to make your own `lua_bind_func` struct, the lua-api already provides something like that -- it's called `luaL_Reg`. – greatwolf Feb 20 '15 at 09:02
  • I updated the question. Yes, it will degrade performance, but this can be disabled in script. It is for debug purposes only – pugnator Feb 20 '15 at 19:30

1 Answers1

1

To use Lua to run scripts that call C functions you need to:

  • Write every C function to be exported to Lua using the Lua protocol to get arguments and return values.
  • Export these C functions to Lua as global variables or fields in a table.
  • Run your user scripts catching syntax errors and execution errors, using protected calls.
  • Optionally provide user scripts with an environment to resolve global variables.

The C API provides functions to do all that without too much work.

See the standard C libraries that are included in Lua's source code. Start with the simplest ones, like math or os.

Read also the book Programming in Lua.

lhf
  • 70,581
  • 9
  • 108
  • 149