diff options
Diffstat (limited to 'src/lua/tolua_tm.c')
-rw-r--r-- | src/lua/tolua_tm.c | 585 |
1 files changed, 0 insertions, 585 deletions
diff --git a/src/lua/tolua_tm.c b/src/lua/tolua_tm.c deleted file mode 100644 index 8fd7b28d..00000000 --- a/src/lua/tolua_tm.c +++ /dev/null @@ -1,585 +0,0 @@ -/* tolua: tag methods -** Support code for Lua bindings. -** Written by Waldemar Celes -** TeCGraf/PUC-Rio -** Jul 1998 -** $Id: tolua_tm.c,v 1.2 2001/11/26 23:00:27 darkgod Exp $ -*/ - -/* This code is free software; you can redistribute it and/or modify it. -** The software provided hereunder is on an "as is" basis, and -** the author has no obligation to provide maintenance, support, updates, -** enhancements, or modifications. -*/ - -#include "tolua.h" -#include "tolua_tm.h" -#include "tolua_tt.h" -#include "tolua_rg.h" - -#include <string.h> - - - -/* Global tables created in Lua registry: - tolua_tbl_class: indexed by instance tags, stores the class tables. - tolua_tbl_clone: indexed by memory address, stores the tag indicanting - it is a clone. - tolua_tbl_mate: indexed by memory address, stores the associate instance - table. - - General tags stored in Lua registry: - tolua_tag_global; - tolua_tag_module; - tolua_tag_class; - tolua_tag_instance; - tolua_tag_linstance; - tolua_tag_indirect; -*/ - -/* internal function prototype */ -static void setmethods (lua_State* L); - -static void settag (lua_State* L, int lo, char* tag_registry_field) -{ - toluaI_getregistry(L,tag_registry_field); - lua_pushvalue(L,lo); - lua_settag(L,(int)lua_tonumber(L,-2)); - lua_pop(L,2); -} - -void toluaI_tm_global (lua_State* L, int lo) -{ - settag(L,lo,"tolua_tag_global"); -} - -void toluaI_tm_module (lua_State* L, int lo) -{ - settag(L,lo,"tolua_tag_module"); -} - -void toluaI_tm_setclass (lua_State* L, int lo) -{ - settag(L,lo,"tolua_tag_class"); -} - -void toluaI_tm_class (lua_State* L, int lo, char* name) -{ - int tag_class; - int tag = lua_newtag(L); - char* type = toluaI_tt_concat("class ",name); - toluaI_getregistry(L,"tolua_tag_class"); - tag_class = (int)lua_tonumber(L,-1); - lua_copytagmethods(L,tag,tag_class); - toluaI_tt_register(L,tag,type); - toluaI_tt_sethierarchy(L,tag,tag_class); - lua_pushvalue(L,lo); - lua_settag(L,tag); - lua_pop(L,2); /* tag_class and lo */ -} - -void toluaI_tm_instance (lua_State* L, int tag, int lo) -{ - toluaI_getregistry(L,"tolua_tbl_class"); - lua_pushnumber(L,tag); - lua_pushvalue(L,lo); - lua_settable(L,-3); - toluaI_getregistry(L,"tolua_tag_instance"); - lua_copytagmethods(L,tag,(int)lua_tonumber(L,-1)); - lua_pop(L,2); /* tbl_class and tag_instance */ -} - -void toluaI_tm_linstance (lua_State* L, int tag, int lo) -{ - toluaI_getregistry(L,"tolua_tbl_class"); - lua_pushnumber(L,tag); - lua_pushvalue(L,lo); - lua_settable(L,-3); - toluaI_getregistry(L,"tolua_tag_linstance"); - lua_copytagmethods(L,tag,(int)lua_tonumber(L,-1)); - lua_pop(L,2); /* tbl_class and tag_linstance */ -} - -void* tolua_doclone (lua_State* L, void* value, int tag) -{ - toluaI_getregistry(L,"tolua_tbl_clone"); - lua_pushuserdata(L,value); - lua_pushnumber(L,tag); - lua_settable(L,-3); - lua_pop(L,1); - return value; -} - -void* tolua_copy (lua_State* L, void* value, unsigned int size) -{ - void* clone = (void*)malloc(size); - if (clone) - memcpy(clone,value,size); - else - tolua_error(L,"insuficient memory"); - return clone; -} - -static void toluaI_tm_undoclone (lua_State* L, int tag, void* clone) -{ - toluaI_getregistry(L,"tolua_tbl_clone"); - lua_pushuserdata(L,clone); - lua_gettable(L,-2); - if (lua_isnumber(L,-1) && lua_tonumber(L,-1)==tag) - { - lua_pushuserdata(L,clone); - lua_pushnil(L); - lua_settable(L,-4); - - /* get base class */ - toluaI_getregistry(L,"tolua_tbl_class"); - lua_pushnumber(L,tag); - lua_rawget(L,-2); - - /* look for destructor */ - lua_pushstring(L,"delete"); - lua_gettable(L,-2); - if (lua_iscfunction(L,-1)) - { - lua_pushusertag(L,clone,tag); - lua_call(L,1,0); - } - else - { - free(clone); /* no destructor: use raw free */ - lua_pop(L,1); /* the nil function value */ - } - lua_pop(L,2); /* tbl_class and class method table */ - } - lua_pop(L,2); /* table and value */ -} - -void toluaI_tm_pushmate (lua_State* L, int lo) -{ - toluaI_getregistry(L,"tolua_tbl_mate"); - lua_pushvalue(L,lo); - lua_rawget(L,-2); - lua_insert(L,-2); - lua_pop(L,1); -} - -void toluaI_tm_pushclass (lua_State* L, int lo) -{ - toluaI_getregistry(L,"tolua_tbl_class"); - lua_pushnumber(L,lua_tag(L,lo)); - lua_rawget(L,-2); - lua_insert(L,-2); - lua_pop(L,1); -} - -int toluaI_gettag (lua_State* L, char* tagname) -{ - int tag; - toluaI_getregistry(L,tagname); - tag = (int)lua_tonumber(L,-1); - lua_pop(L,1); - return tag; -} - -void toluaI_tm_init (lua_State* L) -{ - lua_newtable(L); toluaI_setregistry(L,"tolua_tbl_class"); - lua_newtable(L); toluaI_setregistry(L,"tolua_tbl_clone"); - lua_newtable(L); toluaI_setregistry(L,"tolua_tbl_mate"); - - lua_pushnumber(L,lua_newtag(L)); toluaI_setregistry(L,"tolua_tag_global"); - lua_pushnumber(L,lua_newtag(L)); toluaI_setregistry(L,"tolua_tag_module"); - lua_pushnumber(L,lua_newtag(L)); toluaI_setregistry(L,"tolua_tag_class"); - lua_pushnumber(L,lua_newtag(L)); toluaI_setregistry(L,"tolua_tag_instance"); - lua_pushnumber(L,lua_newtag(L)); toluaI_setregistry(L,"tolua_tag_linstance"); - lua_pushnumber(L,lua_newtag(L)); toluaI_setregistry(L,"tolua_tag_indirect"); - - toluaI_tt_register(L,toluaI_gettag(L,"tolua_tag_global"),"generic variable"); - toluaI_tt_register(L,toluaI_gettag(L,"tolua_tag_module"),"generic module"); - toluaI_tt_register(L,toluaI_gettag(L,"tolua_tag_class"),"generic class"); - toluaI_tt_register(L,toluaI_gettag(L,"tolua_tag_indirect"),"generic indirect"); - toluaI_tt_register(L,toluaI_gettag(L,"tolua_tag_instance"),"generic instance"); - toluaI_tt_register(L,toluaI_gettag(L,"tolua_tag_linstance"),"generic lua instance"); - - /* allows modules and classes to be used as ordinary tables */ - toluaI_tt_sethierarchy(L,toluaI_gettag(L,"tolua_tag_module"),tolua_tag_table); - toluaI_tt_sethierarchy(L,toluaI_gettag(L,"tolua_tag_class"),tolua_tag_table); - - setmethods(L); -} - -static int map (lua_State* L) -{ - int m = lua_gettop(L); - /* do not pass string fields starting with a dot */ - if (!lua_isstring(L,1) || *lua_tostring(L,1)!='.') - { - lua_getglobals(L); - lua_pushvalue(L,1); - lua_pushvalue(L,m); - lua_rawset(L,-3); - lua_pop(L,1); - } - return 0; -} - -void toluaI_tm_using (lua_State* L, int module) -{ - lua_newtable(L); - lua_settag(L,toluaI_gettag(L,"tolua_tag_indirect")); - lua_pushstring(L,".module"); - lua_pushvalue(L,module); - lua_settable(L,-3); - - lua_getglobal(L,"foreach"); - lua_pushvalue(L,module); - lua_pushvalue(L,-3); - lua_pushcclosure(L,map,1); - lua_call(L,2,0); - - lua_getglobal(L,"foreach"); - lua_pushvalue(L,module); - lua_pushstring(L,".get"); - lua_gettable(L,-2); - lua_insert(L,-2); - lua_pop(L,1); /* module table */ - lua_pushvalue(L,-3); - lua_pushcclosure(L,map,1); - lua_call(L,2,0); - lua_pop(L,1); /* indirect table */ -} - -/********************************************************** tag methods */ - -/* tag methods coded in C */ - -/* generic gettable */ -static void oo_gettable (lua_State* L, int table, int base, int index) -{ - while (lua_istable(L,base)) - { - lua_pushvalue(L,index); - lua_rawget(L,base); - if (!lua_isnil(L,-1)) - return; /* returned value already on the top */ - else if (lua_isnumber(L,index)) - { - lua_pushstring(L,"operator_get"); - lua_rawget(L,base); - if (!lua_isnil(L,-1)) - { - lua_pushvalue(L,table); - lua_pushvalue(L,index); - lua_call(L,2,1); - return; - } - } - else - { - lua_pushstring(L,".get"); - lua_rawget(L,base); - if (!lua_isnil(L,-1)) - { - lua_pushvalue(L,index); - lua_rawget(L,-2); - if (!lua_isnil(L,-1)) - { - lua_pushvalue(L,table); - lua_pushvalue(L,index); /* need to access array field (?) */ - lua_call(L,2,1); - return; - } - } - } - lua_pushstring(L,".base"); lua_rawget(L,base); - base = lua_gettop(L); - } - lua_pushnil(L); -} - -/* generic settable */ -static int oo_settable (lua_State* L, int table, int base, int index, int value) -{ - while (lua_istable(L,base)) - { - lua_pushstring(L,".set"); - lua_rawget(L,base); - if (!lua_isnil(L,-1)) - { - lua_pushvalue(L,index); - lua_rawget(L,-2); - if (!lua_isnil(L,-1)) - { - lua_pushvalue(L,table); - lua_pushvalue(L,value); - lua_call(L,2,0); - return 1; - } - } - lua_pushstring(L,".base"); lua_rawget(L,base); - base = lua_gettop(L); - } - return 0; -} - -/* class tag methods */ -static int class_index (lua_State* L) -{ - int table = 1; - int index = 2; - oo_gettable(L,table,table,index); - return 1; -} -static int class_settable (lua_State* L) -{ - int table = 1; - int index = 2; - int value = 3; - if (oo_settable(L,table,table,index,value) == 0) - { - lua_pushvalue(L,table); - lua_pushvalue(L,index); - lua_pushvalue(L,value); - lua_rawset(L,-3); - } - return 0; -} - -/* instance tags */ -static int instance_gettable (lua_State* L) -{ - int table = 1; - int index = 2; - toluaI_tm_pushmate(L,table); /* pushes mate */ - if (!lua_isnil(L,-1)) /* if there's a mate table */ - { - lua_pushvalue(L,index); - lua_rawget(L,-2); - if (!lua_isnil(L,-1)) /* if field in mate table exists */ - return 1; - } - toluaI_tm_pushclass(L,table); /* pushes base */ - oo_gettable(L,table,lua_gettop(L),index); - return 1; -} -static int instance_settable (lua_State* L) -{ - int table = 1; - int index = 2; - int value = 3; - toluaI_tm_pushclass(L,table); /* pushes base */ - if (lua_isnumber(L,index)) - { - lua_pushstring(L,"operator_set"); - lua_rawget(L,-2); - if (!lua_isnil(L,-1)) - {/* the stack here is: table,index,value,base,operator */ - /* call operator passing table, index, and value */ - lua_insert(L,1); - lua_pop(L,1); /* base */ - lua_call(L,3,0); - return 0; - } - } - if (oo_settable(L,table,4,index,value) == 0) - { - toluaI_tm_pushmate(L,table); /* pushes mate */ - if (lua_isnil(L,-1)) - { - /* creates mate table */ - lua_newtable(L); - toluaI_getregistry(L,"tolua_tbl_mate"); - lua_pushvalue(L,table); /* that is the userdata */ - lua_pushvalue(L,-3); - lua_rawset(L,-3); - lua_pop(L,1); /* tbl_mate */ - } - /* the mate table is on the top */ - lua_pushvalue(L,index); - lua_pushvalue(L,value); - lua_rawset(L,-3); - } - return 0; -} -static int instance_gc (lua_State* L) -{ - toluaI_tm_undoclone(L,lua_tag(L,1),lua_touserdata(L,1)); - return 0; -} -static int gen_operator (lua_State* L) -{ - int op1 = 1; - int op2 = 2; - int event = 3; - char* name = toluaI_tt_concat("operator_",lua_tostring(L,event)); - lua_pushstring(L,name); - lua_gettable(L,op1); - lua_pushvalue(L,op1); - lua_pushvalue(L,op2); - lua_call(L,2,1); - return 1; -} -static int instance_operator (lua_State* L) -{ - return gen_operator(L); -} -static int instance_relational (lua_State* L) -{ - gen_operator(L); - if ((int)lua_tonumber(L,-1)==0) lua_pushnil(L); - return 1; -} - -/* lua instance tags */ -static int linstance_index (lua_State* L) -{ - toluaI_tm_pushclass(L,1); - oo_gettable(L,1,3,2); /* table,base,index */ - return 1; -} - - -/* module tag methods */ -static int module_index (lua_State* L) -{ - int table = 1; - int index = 2; - lua_pushstring(L,".get"); - lua_rawget(L,table); - if (!lua_isnil(L,-1)) - { - lua_pushvalue(L,index); - lua_rawget(L,-2); - if (!lua_isnil(L,-1)) - { - lua_call(L,0,1); - return 1; - } - } - lua_pushnil(L); - return 1; -} -static int module_settable (lua_State* L) -{ - int table = 1; - int index = 2; - int value = 3; - lua_pushstring(L,".set"); - lua_rawget(L,table); - if (!lua_isnil(L,-1)) - { - lua_pushvalue(L,index); - lua_rawget(L,-2); - if (!lua_isnil(L,-1)) - { - lua_pushvalue(L,value); - lua_call(L,1,0); - return 0; - } - } - lua_pushvalue(L,index); - lua_pushvalue(L,value); - lua_rawset(L,table); - return 0; -} - -/* global variable tag methods */ -static int global_getglobal (lua_State* L) -{ - int value = 2; - lua_pushstring(L,".get"); - lua_rawget(L,value); - lua_call(L,0,1); - return 1; -} -static int global_setglobal (lua_State* L) -{ - int value = 2; - int newvalue = 3; - lua_pushstring(L,".set"); - lua_rawget(L,value); - if (lua_isnil(L,-1)) - lua_error(L,"value of const variable cannot be changed"); - else - { - lua_pushvalue(L,newvalue); - lua_call(L,1,0); - } - return 0; -} - -/* indirect tag methods */ -static int indirect_getglobal (lua_State* L) -{ - int varname = 1; - int value = 2; - lua_pushstring(L,".module"); - lua_gettable(L,value); - lua_pushvalue(L,varname); - lua_gettable(L,-2); - return 1; -} -static int indirect_setglobal (lua_State* L) -{ - int varname = 1; - int value = 2; - int newvalue = 3; - lua_pushstring(L,".module"); - lua_gettable(L,value); - lua_pushvalue(L,varname); - lua_pushvalue(L,newvalue); - lua_settable(L,-3); - return 0; -} - -static void setmethods (lua_State* L) -{ - /* global variable */ - lua_pushcfunction(L,global_getglobal); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_global"),"getglobal"); - lua_pushcfunction(L,global_setglobal); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_global"),"setglobal"); - - /* module */ - lua_pushcfunction(L,module_index); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_module"),"index"); - lua_pushcfunction(L,module_settable); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_module"),"settable"); - - /* class */ - lua_pushcfunction(L,class_index); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_class"),"index"); - lua_pushcfunction(L,class_settable); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_class"),"settable"); - - /* instance */ - lua_pushcfunction(L,instance_gettable); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"gettable"); - lua_pushcfunction(L,instance_settable); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"settable"); - lua_pushcfunction(L,instance_operator); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"add"); - lua_pushcfunction(L,instance_operator); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"sub"); - lua_pushcfunction(L,instance_operator); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"mul"); - lua_pushcfunction(L,instance_operator); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"div"); - lua_pushcfunction(L,instance_relational); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"lt"); - lua_pushcfunction(L,instance_gc); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"gc"); - - /* lua instance */ - lua_pushcfunction(L,linstance_index); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_linstance"),"index"); - - /* indirect */ - lua_pushcfunction(L,indirect_getglobal); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_indirect"),"getglobal"); - lua_pushcfunction(L,indirect_setglobal); - lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_indirect"),"setglobal"); -} - - - |