lua-users home
lua-l archive

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


I've put together a few helper macros for creating tables of constant values
in Lua.  They are useful in situations where you would like scripts to have
access to a set of values without allowing the scripts to modify the values
or the set.

For example, I have used this code to generate a table of the VK_xxx and
DIK_xxx key constants for Windows programming.  It could also be useful for
generating a table of error strings, mathematical constants, etc.

Here's an example...

First, define the table in C.  I find it convenient to group the CONST_TABLE
definitions together with my lua_register() calls.

    int num_var = 42;
    char str_var[] = "this is str_var";

    CONST_TABLE_BEGIN( "MY_TABLE" )
        CONST_NUM_VAR( num_var )
        CONST_STR_VAR( str_var )
        CONST_NUM( "foo",  7 )
        CONST_STR( "bar", "this is bar")
    CONST_TABLE_END


Then, once the table is initialized, you can do this in Lua:

    print( MY_TABLE.num_var )
    42
    print( MY_TABLE.str_var )
    this is str_var
    print( MY_TABLE.foo )
    7
    print( MY_TABLE.bar )
    this is bar

The table is "constant" because all of these things generate an error:

    MY_TABLE = 9
    MY_TABLE.str_var = 5
    MY_TABLE.new_var = "new variable"

The error message is:

    Cannot modify constant table: MY_TABLE

One unfortunate limitation of the macros is that you can't directly use
#defined values.  This is because the C pre-processor isn't reentrant.  So,
for example, this fails:

  #define PI 3.14

  CONST_TABLE_BEGIN( "MATH_TABLE" )
      CONST_NUM( "PI", PI )
  CONST_TABLE_END

My workaround is:

  #define PI 3.14

  CONST_TABLE_BEGIN( "MATH_TABLE" )
      double pi = PI;
      CONST_NUM( "PI", pi )
  CONST_TABLE_END

Perhaps someone can think of a better solution.

The code follows.  Anyone is free to use it any way, and I hope that someone
DOES find it useful.  :-)

ashley

--- cut here ---

#define CONST_TABLE_BEGIN( TABLE_NAME ) \
    {\
    lua_Object table = lua_createtable();\
    lua_pushobject( table );\
    lua_setglobal( TABLE_NAME );\
    lua_dostring( "function tmp() error(\
    \"Cannot modify constant table: " TABLE_NAME "\" ) end" );

#define CONST_NUM( NAME, VALUE) \
    lua_pushobject( table );\
    lua_pushstring( ( char * ) NAME );\
    lua_pushnumber( VALUE );\
    lua_settable();

#define CONST_NUM_VAR( NAME ) \
    lua_pushobject( table );\
    lua_pushstring( ( char * ) #NAME );\
    lua_pushnumber( NAME );\
    lua_settable();

#define CONST_STR( NAME, VALUE ) \
    lua_pushobject( table );\
    lua_pushstring( ( char * ) NAME );\
    lua_pushstring( VALUE );\
    lua_settable();

#define CONST_STR_VAR( NAME ) \
    lua_pushobject( table );\
    lua_pushstring( ( char * ) #NAME );\
    lua_pushstring( ( char * ) NAME );\
    lua_settable();

#define CONST_TABLE_END \
    int tag = lua_newtag();\
    lua_pushobject( table );\
    lua_settag( tag );\
    lua_pushobject( table );\
    lua_pushobject( lua_getglobal( "tmp" ) );\
    lua_settagmethod( tag, "settable" );\
    lua_pushobject( table );\
    lua_pushobject( lua_getglobal( "tmp" ) );\
    lua_settagmethod( tag, "setglobal" );\
    }

--- cut here ---