diff options
Diffstat (limited to 'luaT/luaT.c')
-rw-r--r-- | luaT/luaT.c | 1079 |
1 files changed, 0 insertions, 1079 deletions
diff --git a/luaT/luaT.c b/luaT/luaT.c deleted file mode 100644 index 7b85ce3..0000000 --- a/luaT/luaT.c +++ /dev/null @@ -1,1079 +0,0 @@ -#include <stdlib.h> -#include <string.h> - -#include "luaT.h" - -void* luaT_alloc(lua_State *L, long size) -{ - void *ptr; - - if(size == 0) - return NULL; - - if(size < 0) - luaL_error(L, "$ Torch: invalid memory size -- maybe an overflow?"); - - ptr = malloc(size); - if(!ptr) - luaL_error(L, "$ Torch: not enough memory: you tried to allocate %dGB. Buy new RAM!", size/1073741824); - - return ptr; -} - -void* luaT_realloc(lua_State *L, void *ptr, long size) -{ - if(!ptr) - return(luaT_alloc(L, size)); - - if(size == 0) - { - luaT_free(L, ptr); - return NULL; - } - - if(size < 0) - luaL_error(L, "$ Torch: invalid memory size -- maybe an overflow?"); - - ptr = realloc(ptr, size); - if(!ptr) - luaL_error(L, "$ Torch: not enough memory: you tried to reallocate %dGB. Buy new RAM!", size/1073741824); - return ptr; -} - -void luaT_free(lua_State *L, void *ptr) -{ - free(ptr); -} - -void luaT_stackdump(lua_State *L) -{ - int i; - const char *tname = NULL; - int top = lua_gettop(L); - for(i = 1; i <= top; i++) - { - int t = lua_type(L, i); - printf("%3d. ", i); - switch(t) - { - case LUA_TSTRING: - printf("'%s'", lua_tostring(L,i)); - break; - case LUA_TBOOLEAN: - printf(lua_toboolean(L, i) ? "true" : "false"); - break; - case LUA_TNUMBER: - printf("%g", lua_tonumber(L,i)); - break; - case LUA_TUSERDATA: - tname = luaT_typename(L, i); - printf("userdata %lx [%s]", (long)lua_topointer(L, i), (tname ? tname : "not a Torch object")); - break; - case 10: - tname = luaT_typename(L, i); - printf("cdata %lx [%s]", (long)lua_topointer(L, i), (tname ? tname : "not a Torch object")); - break; - case LUA_TTABLE: - lua_pushvalue(L, i); - lua_rawget(L, LUA_REGISTRYINDEX); - if(lua_isstring(L, -1)) - tname = lua_tostring(L, -1); /*luaT_typenameid(L, lua_tostring(L, -1)); */ - else - tname = NULL; - lua_pop(L, 1); - if(tname) - printf("metatable [%s]", tname); - else - { - tname = luaT_typename(L, i); - printf("table %lx [%s]", (long)lua_topointer(L, i), (tname ? tname : "not a Torch object")); - } - break; - default: - printf("Lua object type: %s", lua_typename(L,t)); - break; - } - printf("\n"); - } - printf("---------------------------------------------\n"); -} - -/* metatable operator methods */ -static int luaT_mt__index(lua_State *L); -static int luaT_mt__newindex(lua_State *L); -static int luaT_mt__tostring(lua_State *L); -static int luaT_mt__add(lua_State *L); -static int luaT_mt__sub(lua_State *L); -static int luaT_mt__mul(lua_State *L); -static int luaT_mt__div(lua_State *L); -static int luaT_mt__mod(lua_State *L); -static int luaT_mt__pow(lua_State *L); -static int luaT_mt__unm(lua_State *L); -static int luaT_mt__concat(lua_State *L); -static int luaT_mt__len(lua_State *L); -static int luaT_mt__eq(lua_State *L); -static int luaT_mt__lt(lua_State *L); -static int luaT_mt__le(lua_State *L); -static int luaT_mt__call(lua_State *L); - -/* Constructor-metatable methods */ -static int luaT_cmt__call(lua_State *L); -static int luaT_cmt__newindex(lua_State *L); - -const char* luaT_newmetatable(lua_State *L, const char *tname, const char *parenttname, - lua_CFunction constructor, lua_CFunction destructor, lua_CFunction factory) -{ - lua_pushcfunction(L, luaT_lua_newmetatable); - lua_pushstring(L, tname); - (parenttname ? lua_pushstring(L, parenttname) : lua_pushnil(L)); - (constructor ? lua_pushcfunction(L, constructor) : lua_pushnil(L)); - (destructor ? lua_pushcfunction(L, destructor) : lua_pushnil(L)); - (factory ? lua_pushcfunction(L, factory) : lua_pushnil(L)); - lua_call(L, 5, 1); - return luaT_typenameid(L, tname); -} - -int luaT_pushmetatable(lua_State *L, const char *tname) -{ - lua_getfield(L, LUA_REGISTRYINDEX, tname); - if(lua_isnil(L, -1)) - { - lua_pop(L, 1); - return 0; - } - return 1; -} - -const char *luaT_typenameid(lua_State *L, const char *tname) -{ - if(luaT_pushmetatable(L, tname)) - { - const char *tnameid = NULL; - lua_rawget(L, LUA_REGISTRYINDEX); - if(lua_isstring(L, -1)) - tnameid = lua_tostring(L, -1); - lua_pop(L, 1); /* the string/nil */ - return tnameid; - } - return NULL; -} - -static const char cdataname[] = "" - "local _, ffi = pcall(require, 'ffi')\n" - "if ffi then\n" - " local id2name = {}\n" - " return function(cdata, name)\n" - " local id = tonumber(ffi.typeof(cdata))\n" - " if id then\n" - " if name then\n" - " id2name[id] = name\n" - " return name\n" - " else\n" - " return rawget(id2name, id)\n" - " end\n" - " end\n" - " return nil\n" - " end\n" - "else\n" - " return function() end\n" - "end\n"; - -static const char* luaT_cdataname(lua_State *L, int ud, const char *tname) -{ - lua_pushstring(L, "__cdataname"); - lua_rawget(L, LUA_REGISTRYINDEX); - if(lua_isnil(L,-1)) - { - lua_pop(L, 1); - - if(luaL_dostring(L, cdataname)) /* did something go wrong? */ - luaL_error(L, "internal error (could not load cdataname): %s", lua_tostring(L, -1)); - - lua_pushstring(L, "__cdataname"); - lua_pushvalue(L, -2); - lua_rawset(L, LUA_REGISTRYINDEX); - } - if(!lua_isfunction(L, -1)) /* should not happen */ - luaL_error(L, "internal error (cdataname is not a function)"); - - lua_pushvalue(L, ud); - if(tname) - lua_pushstring(L, tname); - if(lua_pcall(L, (tname ? 2 : 1), 1, 0)) - luaL_error(L, "internal error (cdataname): %s", lua_tostring(L, -1)); - - tname = lua_tostring(L, -1); - lua_pop(L, 1); - - return tname; -} - -const char* luaT_typename(lua_State *L, int ud) -{ - if(lua_type(L, ud) == 10) - return luaT_cdataname(L, ud, NULL); - else if(lua_getmetatable(L, ud)) - { - const char *tname = NULL; - lua_rawget(L, LUA_REGISTRYINDEX); - if(lua_isstring(L, -1)) - tname = lua_tostring(L, -1); - lua_pop(L, 1); /* the string/nil */ - return tname; - } - return NULL; -} - -void luaT_pushudata(lua_State *L, void *udata, const char *tname) -{ - if(udata) - { - void **udata_p = lua_newuserdata(L, sizeof(void*)); - *udata_p = udata; - if(!luaT_pushmetatable(L, tname)) - luaL_error(L, "Torch internal problem: cannot find metatable for type <%s>", tname); - lua_setmetatable(L, -2); - } - else - lua_pushnil(L); -} - -void *luaT_toudata(lua_State *L, int ud, const char *tname) -{ - void **p = lua_touserdata(L, ud); - if(p != NULL) /* value is a userdata? */ - { - if(!luaT_pushmetatable(L, tname)) - luaL_error(L, "Torch internal problem: cannot find metatable for type <%s>", tname); - - /* initialize the table we want to get the metatable on */ - /* note that we have to be careful with indices, as we just inserted stuff */ - lua_pushvalue(L, (ud < 0 ? ud - 1 : ud)); - while(lua_getmetatable(L, -1)) /* get the next metatable */ - { - lua_remove(L, -2); /* remove the previous metatable [or object, if first time] */ - if(lua_rawequal(L, -1, -2)) - { - lua_pop(L, 2); /* remove the two metatables */ - return *p; - } - } - lua_pop(L, 2); /* remove the two metatables */ - } - return NULL; -} - -int luaT_isudata(lua_State *L, int ud, const char *tname) -{ - if(luaT_toudata(L, ud, tname)) - return 1; - else - return 0; -} - -void *luaT_checkudata(lua_State *L, int ud, const char *tname) -{ - void *p = luaT_toudata(L, ud, tname); - if(!p) - luaT_typerror(L, ud, tname); - return p; -} - -void *luaT_getfieldcheckudata(lua_State *L, int ud, const char *field, const char *tname) -{ - void *p; - lua_getfield(L, ud, field); - if(lua_isnil(L, -1)) - luaL_error(L, "bad argument #%d (field %s does not exist)", ud, field); - p = luaT_toudata(L, -1, tname); - if(!p) - luaL_error(L, "bad argument #%d (field %s is not a %s)", ud, field, tname); - return p; -} - -void *luaT_getfieldchecklightudata(lua_State *L, int ud, const char *field) -{ - void *p; - lua_getfield(L, ud, field); - if(lua_isnil(L, -1)) - luaL_error(L, "bad argument #%d (field %s does not exist)", ud, field); - - if(!lua_islightuserdata(L, -1)) - luaL_error(L, "bad argument #%d (field %s is not a light userdata)", ud, field); - - p = lua_touserdata(L, -1); - - return p; -} - -double luaT_getfieldchecknumber(lua_State *L, int ud, const char *field) -{ - lua_getfield(L, ud, field); - if(lua_isnil(L, -1)) - luaL_error(L, "bad argument #%d (field %s does not exist)", ud, field); - if(!lua_isnumber(L, -1)) - luaL_error(L, "bad argument #%d (field %s is not a number)", ud, field); - return lua_tonumber(L, -1); -} - -int luaT_getfieldcheckint(lua_State *L, int ud, const char *field) -{ - lua_getfield(L, ud, field); - if(lua_isnil(L, -1)) - luaL_error(L, "bad argument #%d (field %s does not exist)", ud, field); - if(!lua_isnumber(L, -1)) - luaL_error(L, "bad argument #%d (field %s is not a number)", ud, field); - return (int)lua_tonumber(L, -1); -} - -const char* luaT_getfieldcheckstring(lua_State *L, int ud, const char *field) -{ - lua_getfield(L, ud, field); - if(lua_isnil(L, -1)) - luaL_error(L, "bad argument #%d (field %s does not exist)", ud, field); - if(!lua_isstring(L, -1)) - luaL_error(L, "bad argument #%d (field %s is not a string)", ud, field); - return lua_tostring(L, -1); -} - -int luaT_getfieldcheckboolean(lua_State *L, int ud, const char *field) -{ - lua_getfield(L, ud, field); - if(lua_isnil(L, -1)) - luaL_error(L, "bad argument #%d (field %s does not exist)", ud, field); - if(!lua_isboolean(L, -1)) - luaL_error(L, "bad argument #%d (field %s is not a boolean)", ud, field); - return lua_toboolean(L, -1); -} - -void luaT_getfieldchecktable(lua_State *L, int ud, const char *field) -{ - lua_getfield(L, ud, field); - if(lua_isnil(L, -1)) - luaL_error(L, "bad argument #%d (field %s does not exist)", ud, field); - if(!lua_istable(L, -1)) - luaL_error(L, "bad argument #%d (field %s is not a table)", ud, field); -} - -/**** type checks as in luaL ****/ -int luaT_typerror(lua_State *L, int ud, const char *tname) -{ - const char *msg; - const char *tnameud = luaT_typename(L, ud); - - if(!tnameud) - tnameud = lua_typename(L, ud); - - msg = lua_pushfstring(L, "%s expected, got %s", - tname, - (tnameud ? tnameud : "unknown object")); - - return luaL_argerror(L, ud, msg); -} - -int luaT_checkboolean(lua_State *L, int ud) -{ - if(!lua_isboolean(L, ud)) - luaT_typerror(L, ud, lua_typename(L, LUA_TBOOLEAN)); - return lua_toboolean(L, ud); -} - -int luaT_optboolean(lua_State *L, int ud, int def) -{ - if(lua_isnoneornil(L,ud)) - return def; - - return luaT_checkboolean(L, ud); -} - -void luaT_registeratname(lua_State *L, const struct luaL_Reg *methods, const char *name) -{ - int idx = lua_gettop(L); - - luaL_checktype(L, idx, LUA_TTABLE); - lua_pushstring(L, name); - lua_rawget(L, idx); - - if(lua_isnil(L, -1)) - { - lua_pop(L, 1); - lua_pushstring(L, name); - lua_newtable(L); - lua_rawset(L, idx); - - lua_pushstring(L, name); - lua_rawget(L, idx); - } - - luaL_register(L, NULL, methods); - lua_pop(L, 1); -} - - -/* utility functions */ -const char *luaT_classrootname(const char *tname) -{ - int i; - int sz = strlen(tname); - - for(i = 0; i < sz; i++) - { - if(tname[i] == '.') - return tname+i+1; - } - return tname; -} - -/* module_name must be a buffer at least as big as tname - * return true if the class is part of a module */ -int luaT_classmodulename(const char *tname, char *module_name) -{ - char chars[] = {'.', '\0'}; - size_t n; - n = strcspn(tname, chars); - strncpy(module_name, tname, n); - module_name[n] = '\0'; - return tname[n] == '.'; -} - -/* Lua only functions */ -int luaT_lua_newmetatable(lua_State *L) -{ - const char* tname = luaL_checkstring(L, 1); - char module_name[256]; - int is_in_module = 0; - is_in_module = luaT_classmodulename(tname, module_name); - - lua_settop(L, 5); - luaL_argcheck(L, lua_isnoneornil(L, 2) || lua_isstring(L, 2), 2, "parent class name or nil expected"); - luaL_argcheck(L, lua_isnoneornil(L, 3) || lua_isfunction(L, 3), 3, "constructor function or nil expected"); - luaL_argcheck(L, lua_isnoneornil(L, 4) || lua_isfunction(L, 4), 4, "destructor function or nil expected"); - luaL_argcheck(L, lua_isnoneornil(L, 5) || lua_isfunction(L, 5), 5, "factory function or nil expected"); - - if(is_in_module) - lua_getfield(L, LUA_GLOBALSINDEX, module_name); - else - lua_pushvalue(L, LUA_GLOBALSINDEX); - if(!lua_istable(L, 6)) - luaL_error(L, "while creating metatable %s: bad argument #1 (%s is an invalid module name)", tname, module_name); - - /* we first create the new metaclass if we have to */ - if(!luaT_pushmetatable(L, tname)) - { - /* create the metatable */ - lua_newtable(L); - - /* registry[name] = metatable */ - lua_pushvalue(L, -1); - lua_setfield(L, LUA_REGISTRYINDEX, tname); - - /* registry[metatable] = tname */ - lua_pushvalue(L, -1); - lua_pushstring(L, tname); - lua_rawset(L, LUA_REGISTRYINDEX); - - /* __index handling */ - lua_pushcfunction(L, luaT_mt__index); - lua_setfield(L, -2, "__index"); - - /* __newindex handling */ - lua_pushcfunction(L, luaT_mt__newindex); - lua_setfield(L, -2, "__newindex"); - - /* __typename contains the typename */ - lua_pushstring(L, tname); - lua_setfield(L, -2, "__typename"); - - /* __metatable is self */ - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__metatable"); - - /* by default, __version equals 1 */ - lua_pushnumber(L, 1); - lua_setfield(L, -2, "__version"); - - /* assign default operator functions */ - lua_pushcfunction(L, luaT_mt__tostring); - lua_setfield(L, -2, "__tostring"); - - lua_pushcfunction(L, luaT_mt__add); - lua_setfield(L, -2, "__add"); - - lua_pushcfunction(L, luaT_mt__sub); - lua_setfield(L, -2, "__sub"); - - lua_pushcfunction(L, luaT_mt__mul); - lua_setfield(L, -2, "__mul"); - - lua_pushcfunction(L, luaT_mt__div); - lua_setfield(L, -2, "__div"); - - lua_pushcfunction(L, luaT_mt__mod); - lua_setfield(L, -2, "__mod"); - - lua_pushcfunction(L, luaT_mt__pow); - lua_setfield(L, -2, "__pow"); - - lua_pushcfunction(L, luaT_mt__unm); - lua_setfield(L, -2, "__unm"); - - lua_pushcfunction(L, luaT_mt__concat); - lua_setfield(L, -2, "__concat"); - - lua_pushcfunction(L, luaT_mt__len); - lua_setfield(L, -2, "__len"); - - lua_pushcfunction(L, luaT_mt__eq); - lua_setfield(L, -2, "__eq"); - - lua_pushcfunction(L, luaT_mt__lt); - lua_setfield(L, -2, "__lt"); - - lua_pushcfunction(L, luaT_mt__le); - lua_setfield(L, -2, "__le"); - - lua_pushcfunction(L, luaT_mt__call); - lua_setfield(L, -2, "__call"); - } - - /* we assign the parent class if necessary */ - if(!lua_isnoneornil(L, 2)) - { - if(lua_getmetatable(L, -1)) - luaL_error(L, "class %s has been already assigned a parent class\n", tname); - else - { - const char* parenttname = luaL_checkstring(L, 2); - if(!luaT_pushmetatable(L, parenttname)) - luaL_error(L, "bad argument #2 (invalid parent class name %s)", parenttname); - lua_setmetatable(L, -2); - } - } - - /* register the destructor function */ - if(!lua_isnoneornil(L, 4)) - { - /* does it exists already? */ - lua_pushstring(L, "__gc"); - lua_rawget(L, -2); - - if(lua_isnil(L, -1)) - { - lua_pop(L, 1); /* pop nil */ - lua_pushstring(L, "__gc"); - lua_pushvalue(L, 4); - lua_rawset(L, -3); - } - else - luaL_error(L, "%s has been already assigned a destructor", tname); - } - - /* register the factory function */ - if(!lua_isnoneornil(L, 5)) - { - /* does it exists already? */ - lua_pushstring(L, "__factory"); - lua_rawget(L, -2); - - if(lua_isnil(L, -1)) - { - lua_pop(L, 1); /* pop nil */ - lua_pushstring(L, "__factory"); - lua_pushvalue(L, 5); - lua_rawset(L, -3); - } - else - luaL_error(L, "%s has been already assigned a factory", tname); - } - - /******** Constructor table and metatable ********/ - lua_pushstring(L, "__constructor"); - lua_rawget(L, -2); - if(lua_isnil(L, -1)) - { - lua_pop(L, 1); /* pop nil */ - lua_newtable(L); /* fancy table */ - lua_newtable(L); /* fancy metatable */ - - lua_pushvalue(L, -3); /* metatable */ - lua_setfield(L, -2, "__index"); /* so we can get the methods */ - - lua_pushcfunction(L, luaT_cmt__newindex); - lua_setfield(L, -2, "__newindex"); /* so we add new methods */ - - lua_pushcfunction(L, luaT_cmt__call); - lua_setfield(L, -2, "__call"); /* so we can create, we are here for only that */ - - lua_pushvalue(L, -3); - lua_setfield(L, -2, "__metatable"); /* redirect to metatable with methods */ - - lua_setmetatable(L, -2); /* constructor metatable is ... this fancy metatable */ - - /* set metatable[__constructor] = constructor-metatable */ - lua_pushstring(L, "__constructor"); - lua_pushvalue(L, -2); - lua_rawset(L, -4); - } - - /* register the constructor function */ - if(!lua_isnoneornil(L, 3)) - { - /* get constructor metatable */ - lua_getmetatable(L, -1); - - /* does it exists already? */ - lua_pushstring(L, "__new"); - lua_rawget(L, -2); - - if(lua_isnil(L, -1)) - { - lua_pop(L, 1); /* pop nil */ - lua_pushstring(L, "__new"); - lua_pushvalue(L, 3); - lua_rawset(L, -3); - - /* set "new" in the metatable too */ - lua_pushstring(L, "new"); - lua_pushvalue(L, 3); - lua_rawset(L, -5); - } - else - luaL_error(L, "%s has been already assigned a constructor", tname); - - /* pop constructor metatable */ - lua_pop(L, 1); - } - - /* module.name = constructor metatable */ - lua_setfield(L, 6, luaT_classrootname(tname)); - - return 1; /* returns the metatable */ -} - -/* Lua only utility functions */ - -/* add any custom type, provided the object has a metatable */ -int luaT_lua_metatype(lua_State *L) -{ - if( (lua_gettop(L) != 2) && (lua_gettop(L) != 3) ) - luaL_error(L, "expecting: string table [ctype]"); - - luaL_checkstring(L, 1); - luaL_checktype(L, 2, LUA_TTABLE); - - if(lua_gettop(L) == 3) - { - if(!luaT_cdataname(L, 3, lua_tostring(L, 1))) - luaL_error(L, "could not register cdata type -- missing ffi library?"); - } - - /* registry[name] = metatable */ - lua_pushvalue(L, 1); - lua_pushvalue(L, 2); - lua_rawset(L, LUA_REGISTRYINDEX); - - /* registry[metatable] = tname */ - lua_pushvalue(L, 2); - lua_pushvalue(L, 1); - lua_rawset(L, LUA_REGISTRYINDEX); - - return 0; -} - -/* return a userdata from a C pointer */ -/* you are better to know what you are doing */ -int luaT_lua_pushudata(lua_State *L) -{ - void *udata = NULL; - const char *tname = luaL_checkstring(L, 2); - - if(lua_type(L, 1) == 10) - udata = *((void**)lua_topointer(L, 1)); - else if(lua_isnumber(L, 1)) - udata = (void*)(long)lua_tonumber(L, 1); - else - luaL_argerror(L, 1, "expecting number or cdata"); - - luaT_pushudata(L, udata, tname); - - return 1; -} - -int luaT_lua_factory(lua_State *L) -{ - const char* tname = luaL_checkstring(L, 1); - if(luaT_pushmetatable(L, tname) && !lua_isnil(L, -1)) - { - lua_pushstring(L, "__factory"); - lua_rawget(L, -2); - } - else - { - lua_pushnil(L); - } - return 1; -} - -int luaT_lua_getconstructortable(lua_State *L) -{ - const char* tname = luaL_checkstring(L, 1); - if(luaT_pushmetatable(L, tname)) - { - lua_pushstring(L, "__constructor"); - lua_rawget(L, -2); - return 1; - } - return 0; -} - - -int luaT_lua_typename(lua_State *L) -{ - const char* tname = NULL; - luaL_checkany(L, 1); - if((tname = luaT_typename(L, 1))) - { - lua_pushstring(L, tname); - return 1; - } - return 0; -} - -int luaT_lua_isequal(lua_State *L) -{ - if(lua_isuserdata(L, 1) && lua_isuserdata(L, 2)) - { - void **u1, **u2; - luaL_argcheck(L, luaT_typename(L, 1), 1, "Torch object expected"); - luaL_argcheck(L, luaT_typename(L, 2), 2, "Torch object expected"); - - u1 = lua_touserdata(L, 1); - u2 = lua_touserdata(L, 2); - if(*u1 == *u2) - lua_pushboolean(L, 1); - else - lua_pushboolean(L, 0); - } - else if(lua_istable(L, 1) && lua_istable(L, 2)) - lua_pushboolean(L, lua_rawequal(L, 1, 2)); - else - lua_pushboolean(L, 0); - return 1; -} - -int luaT_lua_pointer(lua_State *L) -{ - if(lua_isuserdata(L, 1)) - { - void **ptr; - luaL_argcheck(L, luaT_typename(L, 1), 1, "Torch object expected"); - ptr = lua_touserdata(L, 1); - lua_pushnumber(L, (long)(*ptr)); - return 1; - } - else if(lua_istable(L, 1) || lua_isthread(L, 1) || lua_isfunction(L, 1)) - { - const void* ptr = lua_topointer(L, 1); - lua_pushnumber(L, (long)(ptr)); - return 1; - } - else if(lua_type(L, 1) == 10) /* cdata */ - { - /* we want the pointer holded by cdata */ - /* not the pointer on the cdata object */ - const void* ptr = *((void**)lua_topointer(L, 1)); - lua_pushnumber(L, (long)(ptr)); - return 1; - } - else if(lua_isstring(L, 1)) - { - const char* ptr = lua_tostring(L, 1); - lua_pushnumber(L, (long)(ptr)); - return 1; - } - else - luaL_error(L, "Torch object, table, thread, cdata or function expected"); - - return 0; -} - -int luaT_lua_setenv(lua_State *L) -{ - if(!lua_isfunction(L, 1) && !lua_isuserdata(L, 1)) - luaL_typerror(L, 1, "function or userdata"); - luaL_checktype(L, 2, LUA_TTABLE); - lua_setfenv(L, 1); - return 0; -} - -int luaT_lua_getenv(lua_State *L) -{ - if(!lua_isfunction(L, 1) && !lua_isuserdata(L, 1)) - luaL_typerror(L, 1, "function or userdata"); - lua_getfenv(L, 1); - return 1; -} - -int luaT_lua_getmetatable(lua_State *L) -{ - const char *tname = luaL_checkstring(L, 1); - if(luaT_pushmetatable(L, tname)) - return 1; - return 0; -} - -int luaT_lua_version(lua_State *L) -{ - luaL_checkany(L, 1); - - if(lua_type(L, 1) == 10) - { - const char *tname = luaT_cdataname(L, 1, NULL); - if(tname) - { - luaT_pushmetatable(L, tname); - lua_pushstring(L, "__version"); - lua_rawget(L, -2); - return 1; - } - return 0; - } - else if(lua_getmetatable(L, 1)) - { - lua_pushstring(L, "__version"); - lua_rawget(L, -2); - return 1; - } - return 0; -} - -int luaT_lua_setmetatable(lua_State *L) -{ - const char *tname = luaL_checkstring(L, 2); - luaL_checktype(L, 1, LUA_TTABLE); - - if(!luaT_pushmetatable(L, tname)) - luaL_error(L, "unknown typename %s\n", tname); - lua_setmetatable(L, 1); - - return 1; -} - -/* metatable operator methods */ -static int luaT_mt__index(lua_State *L) -{ - if(!lua_getmetatable(L, 1)) - luaL_error(L, "critical internal indexing error: no metatable found"); - - if(!lua_istable(L, -1)) - luaL_error(L, "critical internal indexing error: not a metatable"); - - /* test for __index__ method first */ - lua_getfield(L, -1, "__index__"); - if(!lua_isnil(L, -1)) - { - int result; - - if(!lua_isfunction(L, -1)) - luaL_error(L, "critical internal indexing error: __index__ is not a function"); - - lua_pushvalue(L, 1); - lua_pushvalue(L, 2); - - lua_call(L, 2, LUA_MULTRET); /* DEBUG: risque: faut vraiment retourner 1 ou 2 valeurs... */ - - result = lua_toboolean(L, -1); - lua_pop(L, 1); - - if(result) - return 1; - - /* on the stack: 1. the object 2. the value 3. the metatable */ - /* apparently, __index wants only one element returned */ - /* return lua_gettop(L)-3; */ - - } - else - lua_pop(L, 1); /* remove nil __index__ on the stack */ - - lua_pushvalue(L, 2); - lua_gettable(L, -2); - - return 1; -} - -static int luaT_mt__newindex(lua_State *L) -{ - if(!lua_getmetatable(L, 1)) - luaL_error(L, "critical internal indexing error: no metatable found"); - - if(!lua_istable(L, -1)) - luaL_error(L, "critical internal indexing error: not a metatable"); - - /* test for __newindex__ method first */ - lua_getfield(L, -1, "__newindex__"); - if(!lua_isnil(L, -1)) - { - int result; - - if(!lua_isfunction(L, -1)) - luaL_error(L, "critical internal indexing error: __newindex__ is not a function"); - - lua_pushvalue(L, 1); - lua_pushvalue(L, 2); - lua_pushvalue(L, 3); - - lua_call(L, 3, 1); /* DEBUG: risque: faut vraiment retourner qqch */ - - result = lua_toboolean(L, -1); - lua_pop(L, 1); - - if(result) - return 0; - } - else - lua_pop(L, 1); /* remove nil __newindex__ on the stack */ - - lua_pop(L, 1); /* pop the metatable */ - if(lua_istable(L, 1)) - lua_rawset(L, 1); - else - luaL_error(L, "the class %s cannot be indexed", luaT_typename(L, 1)); - - return 0; -} - -/* note: check dans metatable pour ca, donc necessaire */ -#define MT_DECLARE_OPERATOR(NAME, NIL_BEHAVIOR) \ - int luaT_mt__##NAME(lua_State *L) \ - { \ - if(!lua_getmetatable(L, 1)) \ - luaL_error(L, "internal error in __" #NAME ": no metatable"); \ - \ - lua_getfield(L, -1, "__" #NAME "__"); \ - if(lua_isnil(L, -1)) \ - { \ - NIL_BEHAVIOR; \ - } \ - else \ - { \ - if(lua_isfunction(L, -1)) \ - { \ - lua_insert(L, 1); /* insert function */ \ - lua_pop(L, 1); /* remove metatable */ \ - lua_call(L, lua_gettop(L)-1, LUA_MULTRET); /* we return the result of the call */ \ - return lua_gettop(L); \ - } \ - /* we return the thing the user left in __tostring__ */ \ - } \ - return 0; \ - } - -MT_DECLARE_OPERATOR(tostring, - lua_pushstring(L, luaT_typename(L, 1)); - return 1;) -MT_DECLARE_OPERATOR(add, luaL_error(L, "%s has no addition operator", luaT_typename(L, 1))) -MT_DECLARE_OPERATOR(sub, luaL_error(L, "%s has no substraction operator", luaT_typename(L, 1))) -MT_DECLARE_OPERATOR(mul, luaL_error(L, "%s has no multiplication operator", luaT_typename(L, 1))) -MT_DECLARE_OPERATOR(div, luaL_error(L, "%s has no division operator", luaT_typename(L, 1))) -MT_DECLARE_OPERATOR(mod, luaL_error(L, "%s has no modulo operator", luaT_typename(L, 1))) -MT_DECLARE_OPERATOR(pow, luaL_error(L, "%s has no power operator", luaT_typename(L, 1))) -MT_DECLARE_OPERATOR(unm, luaL_error(L, "%s has no negation operator", luaT_typename(L, 1))) -MT_DECLARE_OPERATOR(concat, luaL_error(L, "%s has no concat operator", luaT_typename(L, 1))) -MT_DECLARE_OPERATOR(len, luaL_error(L, "%s has no length operator", luaT_typename(L, 1))) -MT_DECLARE_OPERATOR(eq, - lua_settop(L, 2); - lua_pushcfunction(L, luaT_lua_isequal); - lua_insert(L, 1); - lua_call(L, 2, 1); - return 1;) -MT_DECLARE_OPERATOR(lt, luaL_error(L, "%s has no lower than operator", luaT_typename(L, 1))) -MT_DECLARE_OPERATOR(le, luaL_error(L, "%s has no lower or equal than operator", luaT_typename(L, 1))) -MT_DECLARE_OPERATOR(call, luaL_error(L, "%s has no call operator", luaT_typename(L, 1))) - - -/* constructor metatable methods */ -int luaT_cmt__call(lua_State *L) -{ - if(!lua_istable(L, 1)) - luaL_error(L, "internal error in __call: not a constructor table"); - - if(!lua_getmetatable(L, 1)) - luaL_error(L, "internal error in __call: no metatable available"); - - lua_pushstring(L, "__new"); - lua_rawget(L, -2); - - if(lua_isnil(L, -1)) - luaL_error(L, "no constructor available"); - - lua_remove(L, 1); /* remove constructor atable */ - lua_insert(L, 1); /* insert constructor */ - lua_pop(L, 1); /* remove fancy metatable */ - - lua_call(L, lua_gettop(L)-1, LUA_MULTRET); - return lua_gettop(L); -} - -int luaT_cmt__newindex(lua_State *L) -{ - if(!lua_istable(L, 1)) - luaL_error(L, "internal error in __newindex: not a constructor table"); - - if(!lua_getmetatable(L, 1)) - luaL_error(L, "internal error in __newindex: no metatable available"); - - lua_pushstring(L, "__metatable"); - lua_rawget(L, -2); - - if(!lua_istable(L, -1)) - luaL_error(L, "internal error in __newindex: no metaclass available"); - - lua_insert(L, 2); - lua_pop(L, 1); /* remove the metatable over the constructor table */ - - lua_rawset(L, -3); - - return 0; -} - -/******************** deprecated functions ********************/ -int luaT_pushmetaclass(lua_State *L, const char *tname) -{ - return luaT_pushmetatable(L, tname); -} - -const char* luaT_id(lua_State *L, int ud) -{ - return luaT_typename(L, ud); -} - -const char* luaT_id2typename(lua_State *L, const char *id) -{ - return id; -} - -const char* luaT_typename2id(lua_State *L, const char *tname) -{ - return luaT_typenameid(L, tname); -} - -int luaT_getmetaclass(lua_State *L, int index) -{ - return lua_getmetatable(L, index); -} - -const char* luaT_checktypename2id(lua_State *L, const char *tname) -{ - const char* id = luaT_typenameid(L, tname); - if(!id) - luaL_error(L, "unknown class <%s>", tname); - return id; -} - -void luaT_registeratid(lua_State *L, const struct luaL_Reg *methods, const char *id) -{ - luaT_registeratname(L, methods, id); -} - -/**************************************************************/ |