Re: Converting strings to enum values (C API)
[
Date Prev][
Date Next][
Thread Prev][
Thread Next]
[
Date Index]
[
Thread Index]
- Subject: Re: Converting strings to enum values (C API)
 
- From: Tom N Harris <telliamed@...>
 
- Date: 2013年12月10日 16:48:12 -0500
 
On Monday, December 09, 2013 11:26:40 AM Marc Lepage wrote:
> That seems to work well enough. Mapping tables stored in the registry.
> Would it be beneficial to use upvalues instead? (Pros/cons? Performance?) I
> haven't really done upvalues from C, I will check the docs.
This is how I did a simple string to number converter.
typedef struct EnumVal { const char *s; int v; } EnumVal;
static int s_enumvalue(const char* name, const EnumVal * lst) {
 int idx;
 for (idx=0; lst[idx].s; idx++)
 if (strcmp(lst[idx].s, name) == 0)
 return idx;
 return -1;
}
static int l_enumvalue(lua_State *L) {
 const char *name = luaL_checkstring(L, 1);
 /* Lookup name in memo table */
 lua_pushvalue(L, 1);
 lua_gettable(L, lua_upvalueindex(1));
 if (lua_isnil(L, -1)) {
 /* Lookup name in static struct */
 const EnumVal * lst = lua_touserdata(L, lua_upvalueindex(2));
 int idx = s_enumvalue(name, lst);
 if (idx != -1) {
 lua_pop(L, 1); /* remove nil from lua_gettable */
 /* Memoize */
 lua_pushinteger(L, lst[idx].v);
 lua_pushvalue(L, 1);
 lua_pushvalue(L, -2);
 lua_settable(L, lua_upvalueindex(1));
 }
 /* else unknown, return nil (already on stack) */
 }
 return 1;
}
int new_enumerator(lua_State *L, const EnumVal enums []) {
 lua_newtable(L);
 lua_pushlightuserdata(L, (void*)enums);
 lua_pushcclosure(L, l_enumvalue, 2);
 return 1;
}
Going from numbers to strings probably doesn't need a Lua table. If the 
enumeration is consecutive numbers, a C array is fastest. Or just use a switch 
statement which the compiler will turn into a jump table. But then you have to 
each name/value twice, in the array and again in the switch. If you have a lot 
of them and want to use an automated API generator, building Lua tables ahead 
of time will make your code look cleaner. Just have `reg_lut` return the 
getter and setter table on the Lua stack then push each closure taking the 
upvalue instead of reading the registry.
-- 
tom <telliamed@whoopdedo.org>