Browse files

nspace.i example is working

  • Loading branch information...
1 parent 1c5a0f8 commit 295788c8a0002fe228d2e884cb370a525fb66a38 @v-for-vandal v-for-vandal committed Oct 29, 2013
Showing with 468 additions and 156 deletions.
  1. +235 −62 Lib/lua/luarun.swg
  2. +9 −1 Source/Modules/lang.cxx
  3. +224 −93 Source/Modules/lua.cxx
View
297 Lib/lua/luarun.swg
@@ -157,7 +157,8 @@ struct swig_lua_namespace {
};
struct swig_lua_class {
- const char *name;
+ const char *name; // Name that this class has in Lua
+ const char *fqname; // Fully qualified name - Scope + class name
swig_type_info **type;
lua_CFunction constructor;
void (*destructor)(void *);
@@ -511,7 +512,7 @@ SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss);
SWIGINTERN int SWIG_Lua_add_namespace_details(lua_State* L, swig_lua_namespace* ns)
{
int i = 0;
- /* There must be table at the top of the stack */
+ /* There must be namespace table (not metatable) at the top of the stack */
assert(lua_istable(L,-1));
SWIG_Lua_InstallConstants(L, ns->ns_constants);
@@ -539,10 +540,13 @@ SWIGINTERN int SWIG_Lua_add_namespace_details(lua_State* L, swig_lua_namespace*
*/
SWIGINTERN void SWIG_Lua_add_namespace_classes(lua_State* L, swig_lua_namespace* ns)
{
+ // There must be module/namespace table at the top of the stack
+ assert(lua_istable(L,-1));
+
swig_lua_class** classes = ns->ns_classes;
if( classes != 0 ) {
- while((*classes)->name != 0) {
+ while(*classes != 0) {
SWIG_Lua_class_register(L, *classes);
classes++;
}
@@ -556,6 +560,7 @@ SWIGINTERN void SWIG_Lua_add_namespace_classes(lua_State* L, swig_lua_namespace*
*/
SWIGINTERN int SWIG_Lua_namespace_register(lua_State* L, swig_lua_namespace* ns, bool reg)
{
+ int begin = lua_gettop(L);
assert(lua_istable(L,-1)); /* just in case. This is supposed to be module table or parent namespace table */
lua_checkstack(L,5);
lua_newtable(L); /* namespace itself */
@@ -582,11 +587,14 @@ SWIGINTERN int SWIG_Lua_namespace_register(lua_State* L, swig_lua_namespace* ns,
// Register all functions, variables etc
SWIG_Lua_add_namespace_details(L,ns);
+ // Register classes
+ SWIG_Lua_add_namespace_classes(L,ns);
swig_lua_namespace** sub_namespace = ns->ns_namespaces;
if( sub_namespace != 0) {
- while((*sub_namespace)->name != 0) {
+ while(*sub_namespace != 0) {
SWIG_Lua_namespace_register(L, *sub_namespace, true);
+ lua_pop(L,1); // removing sub-namespace table
sub_namespace++;
}
}
@@ -596,39 +604,45 @@ SWIGINTERN int SWIG_Lua_namespace_register(lua_State* L, swig_lua_namespace* ns,
lua_pushvalue(L,-2);
lua_rawset(L,-4); /* add namespace to module table */
}
+ assert(lua_gettop(L) == begin+1);
}
/* -----------------------------------------------------------------------------
* global variable support code: classes
* ----------------------------------------------------------------------------- */
-/* the class.get method, performs the lookup of class attributes */
+/* the class.get method, performs the lookup of class attributes
+ * Method can be called from Lua directly and recursively from itself. Thats why
+ * we can't use absolute stack positions
+ */
SWIGINTERN int SWIG_Lua_class_get(lua_State* L)
{
/* there should be 2 params passed in
(1) userdata (not the meta table)
(2) string name of the attribute
*/
+ int base = lua_gettop(L)-2;
+ lua_checkstack(L,5);
assert(lua_isuserdata(L,-2)); /* just in case */
lua_getmetatable(L,-2); /* get the meta table */
assert(lua_istable(L,-1)); /* just in case */
SWIG_Lua_get_table(L,".get"); /* find the .get table */
assert(lua_istable(L,-1)); /* just in case */
/* look for the key in the .get table */
- lua_pushvalue(L,2); /* key */
+ lua_pushvalue(L,base+2); /* key */
lua_rawget(L,-2);
lua_remove(L,-2); /* stack tidy, remove .get table */
if (lua_iscfunction(L,-1))
{ /* found it so call the fn & return its value */
- lua_pushvalue(L,1); /* the userdata */
+ lua_pushvalue(L,base+1); /* the userdata */
lua_call(L,1,1); /* 1 value in (userdata),1 out (result) */
lua_remove(L,-2); /* stack tidy, remove metatable */
return 1;
}
lua_pop(L,1); /* remove whatever was there */
/* ok, so try the .fn table */
- SWIG_Lua_get_table(L,".fn"); /* find the .get table */
+ SWIG_Lua_get_table(L,".fn"); /* find the .fn table */
assert(lua_istable(L,-1)); /* just in case */
- lua_pushvalue(L,2); /* key */
+ lua_pushvalue(L,base+2); /* key */
lua_rawget(L,-2); /* look for the fn */
lua_remove(L,-2); /* stack tidy, remove .fn table */
if (lua_isfunction(L,-1)) /* note: if its a C function or lua function */
@@ -642,60 +656,197 @@ SWIGINTERN int SWIG_Lua_class_get(lua_State* L)
SWIG_Lua_get_table(L,"__getitem"); /* find the __getitem fn */
if (lua_iscfunction(L,-1)) /* if its there */
{ /* found it so call the fn & return its value */
- lua_pushvalue(L,1); /* the userdata */
- lua_pushvalue(L,2); /* the parameter */
+ lua_pushvalue(L,base+1); /* the userdata */
+ lua_pushvalue(L,base+2); /* the parameter */
lua_call(L,2,1); /* 2 value in (userdata),1 out (result) */
lua_remove(L,-2); /* stack tidy, remove metatable */
return 1;
}
+ lua_pop(L,1);
+ // Search in base classes
+ // TODO: Different for elua_ltr
+ SWIG_Lua_get_table(L,".bases");
+ assert(lua_istable(L,-1));
+ int bases_count = lua_rawlen(L,-1);
+ if(bases_count>0)
+ {
+ int original_metatable = lua_absindex(L,-2);
+ int i;
+ int ret = 0; // Number of returned values
+ lua_pushvalue(L,base+1); // push userdata
+ lua_pushvalue(L,base+2); // Push key again
+ // Trick: temporaly replacing original metatable
+ // with metatable for base class and call getter
+ for(i=0;i<bases_count;i++) {
+ lua_rawgeti(L,-3,i+1); // get base metatable here
+ assert(lua_istable(L,-1));
+ assert(lua_isuserdata(L,-3));
+ lua_setmetatable(L,-3); // Set new metatable
+ assert(lua_isuserdata(L,-2));
+ ret = SWIG_Lua_class_get(L); // Forward call
+ assert(ret==0||ret==1);
+ if(ret>0)
+ break;
+ }
+ // Return original metatable back
+ lua_pushvalue(L,original_metatable);
+ lua_setmetatable(L,base+1);
+ if(ret>0)
+ {
+ // tidy stack. Stack currently is:
+ // --base--
+ // userdata
+ // key
+ // metatable
+ // .bases table
+ // userdata
+ // key : -2
+ // return value : -1
+ lua_remove(L,-2); // remove key
+ lua_remove(L,-2); // remove userdata
+ lua_remove(L,-2); // remove .bases
+ lua_remove(L,-2); // remove metatable
+ return 1;
+ } else {
+ lua_pop(L,2); // remove key and userdata
+ }
+ }
+ // Tidy stack:
+ // --base--
+ // userdata
+ // key
+ // metatable
+ // .bases table
+ lua_pop(L,2);
+ assert(lua_gettop(L)==base+2);
return 0; /* sorry not known */
}
-/* the class.set method, performs the lookup of class attributes */
-SWIGINTERN int SWIG_Lua_class_set(lua_State* L)
+/* helper for the class.set method, performs the lookup of class attributes
+ * Method can be called from SWIG_Lua_class_set or recursively from itself
+ */
+SWIGINTERN int SWIG_Lua_class_do_set(lua_State* L)
{
/* there should be 3 params passed in
(1) table (not the meta table)
(2) string name of the attribute
(3) any for the new value
printf("SWIG_Lua_class_set %p(%s) '%s' %p(%s)\n",
- lua_topointer(L,1),lua_typename(L,lua_type(L,1)),
- lua_tostring(L,2),
- lua_topointer(L,3),lua_typename(L,lua_type(L,3)));*/
+ lua_topointer(L,-3),lua_typename(L,lua_type(L,-3)),
+ lua_tostring(L,-2),
+ lua_topointer(L,-1),lua_typename(L,lua_type(L,-1)));*/
- assert(lua_isuserdata(L,1)); /* just in case */
- lua_getmetatable(L,1); /* get the meta table */
+ int base = lua_gettop(L) - 3;
+ lua_checkstack(L,5);
+ assert(lua_isuserdata(L,base+1)); /* just in case */
+ lua_getmetatable(L,base+1); /* get the meta table */
assert(lua_istable(L,-1)); /* just in case */
SWIG_Lua_get_table(L,".set"); /* find the .set table */
if (lua_istable(L,-1))
{
/* look for the key in the .set table */
- lua_pushvalue(L,2); /* key */
+ lua_pushvalue(L,base+2); /* key */
lua_rawget(L,-2);
+ lua_remove(L,-2); /* tidy stack, remove .set table */
if (lua_iscfunction(L,-1))
{ /* found it so call the fn & return its value */
- lua_pushvalue(L,1); /* userdata */
- lua_pushvalue(L,3); /* value */
+ lua_pushvalue(L,base+1); /* userdata */
+ lua_pushvalue(L,base+3); /* value */
lua_call(L,2,0);
+ lua_remove(L,base+4); /*remove metatable*/
+ assert(lua_gettop(L) == base+3); // TODO:REMOVE
return 0;
}
lua_pop(L,1); /* remove the value */
+ } else {
+ lua_pop(L,1); /* remove the answer for .set table request*/
}
- lua_pop(L,1); /* remove the value .set table */
+ assert(lua_gettop(L) == base + 4); // TODO: REMOVE
/* NEW: looks for the __setitem() fn
this is a user provided set fn */
SWIG_Lua_get_table(L,"__setitem"); /* find the fn */
if (lua_iscfunction(L,-1)) /* if its there */
{ /* found it so call the fn & return its value */
- lua_pushvalue(L,1); /* the userdata */
- lua_pushvalue(L,2); /* the parameter */
- lua_pushvalue(L,3); /* the value */
+ lua_pushvalue(L,base+1); /* the userdata */
+ lua_pushvalue(L,base+2); /* the parameter */
+ lua_pushvalue(L,base+3); /* the value */
lua_call(L,3,0); /* 3 values in ,0 out */
lua_remove(L,-2); /* stack tidy, remove metatable */
- return 1;
+ return 0;
+ }
+ lua_pop(L,1); // remove value
+ assert(lua_gettop(L) == base + 4); // TODO: REMOVE
+
+ // Search among bases
+ int original_metatable = base+4;
+ assert(lua_gettop(L) == original_metatable); // Check that stack is correct
+ SWIG_Lua_get_table(L,".bases");
+ assert(lua_istable(L,-1));
+ int bases_count = lua_rawlen(L,-1);
+ if(bases_count>0)
+ {
+ int i = 0;
+ int ret = 0;
+ lua_pushvalue(L,base+1); // push userdata
+ lua_pushvalue(L,base+2); // Push key again
+ lua_pushvalue(L,base+3); // Push value again
+ // Trick: temporaly replacing original metatable
+ // with metatable for base class and call getter
+ for(i=0;i<bases_count;i++) {
+ lua_rawgeti(L,-4,i+1); // get base metatable here
+ assert(lua_istable(L,-1));
+ assert(lua_isuserdata(L,-4));
+ lua_setmetatable(L,-4); // Set new metatable
+ assert(lua_isuserdata(L,-3));
+ ret = SWIG_Lua_class_do_set(L); // Forward call
+ assert(ret==0||ret==-1);
+ if(ret==0)
+ break;
+ }
+ // Return original metatable back
+ lua_pushvalue(L,original_metatable);
+ lua_setmetatable(L,base+1);
+ if(ret==0)
+ {
+ // tidy stack. Stack currently is:
+ // --base--
+ // userdata
+ // key
+ // value
+ // metatable
+ // .bases table
+ // userdata
+ // key : -2
+ // value: -1
+ lua_pop(L,5);
+ return 0;
+ } else {
+ lua_pop(L,3); // remove userdata, key and value
+ }
+ }
+ lua_pop(L,1); // remove .bases_table
+
+ lua_pop(L,1); // remove metatable
+ assert(lua_gettop(L) == base+3);
+ return -1; // Indicator that search failed
+}
+
+/* This is actuall method exported to Lua. It calls SWIG_Lua_class_do_set and correctly
+ * handlers return value
+ */
+SWIGINTERN int SWIG_Lua_class_set(lua_State* L)
+{
+ int ret= SWIG_Lua_class_do_set(L);
+ if(ret==0)
+ return 0;
+ else if(ret==-1) {
+ SWIG_Lua_pushferrstring(L,"Assignment not possible. No setter/member with this name. For custom assignments implement __setitem method");
+ lua_error(L);
+ } else {
+ assert(0); // Internal implementation error
+ return 0;
}
- return 0;
}
/* the class.destruct method called by the interpreter */
@@ -752,23 +903,6 @@ SWIGINTERN int SWIG_Lua_class_disown(lua_State* L)
return 0;
}
-/* Constructor proxy. Used when class name entry in module is not class constructor,
-but special table instead. */
-SWIGINTERN int SWIG_Lua_constructor_proxy(lua_State* L)
-{
- /* unlimited number of parameters
- First one is our proxy table and we should remove it
- Other we should pass to real constructor
- */
- assert(lua_istable(L,1));
- lua_pushstring(L,".constructor");
- lua_rawget(L,1);
- assert(!lua_isnil(L,-1));
- lua_replace(L,1); /* replace our table with real constructor */
- lua_call(L,lua_gettop(L)-1,1);
- return 1;
-}
-
/* gets the swig class registry (or creates it) */
SWIGINTERN void SWIG_Lua_get_class_registry(lua_State* L)
{
@@ -829,15 +963,24 @@ SWIGINTERN void SWIG_Lua_add_class_static_details(lua_State* L, swig_lua_class*
}
/* helper to recursively add class details (attributes & operations) */
-SWIGINTERN void SWIG_Lua_add_class_details(lua_State* L,swig_lua_class* clss)
+SWIGINTERN void SWIG_Lua_add_class_instance_details(lua_State* L,swig_lua_class* clss)
{
int i;
- /* call all the base classes first: we can then override these later: */
+ // Add bases to .bases table
+ SWIG_Lua_get_table(L,".bases");
+ assert(lua_istable(L,-1)); /* just in case */
+ int bases_count = 0;
for(i=0;clss->bases[i];i++)
{
- SWIG_Lua_add_class_details(L,clss->bases[i]);
+ SWIG_Lua_get_class_metatable(L,clss->bases[i]->fqname);
+ // Base class must be already registered
+ assert(lua_istable(L,-1));
+ lua_rawseti(L,-2,i+1); // In lua indexing starts from 1
+ bases_count++;
}
- /* add fns */
+ assert(lua_rawlen(L,-1) == bases_count);
+ lua_pop(L,1); // remove .bases table
+ /* add attributes */
for(i=0;clss->attributes[i].name;i++){
SWIG_Lua_add_variable(L,clss->attributes[i].name,clss->attributes[i].getmethod,clss->attributes[i].setmethod);
}
@@ -851,7 +994,7 @@ SWIGINTERN void SWIG_Lua_add_class_details(lua_State* L,swig_lua_class* clss)
/* add operator overloads
these look ANY method which start with "__" and assume they
are operator overloads & add them to the metatable
- (this might mess up is someone defines a method __gc (the destructor)*/
+ (this might mess up if someone defines a method __gc (the destructor)*/
for(i=0;clss->methods[i].name;i++){
if (clss->methods[i].name[0]=='_' && clss->methods[i].name[1]=='_'){
SWIG_Lua_add_function(L,clss->methods[i].name,clss->methods[i].func);
@@ -884,13 +1027,13 @@ SWIGINTERN void SWIG_Lua_init_base_class(lua_State* L,swig_lua_class* clss)
/* Register class static methods,attributes etc as well as constructor proxy */
SWIGINTERN void SWIG_Lua_class_register_static(lua_State* L, swig_lua_class* clss)
{
+ int begin = lua_gettop(L);
lua_checkstack(L,5); /* just in case */
assert(lua_istable(L,-1)); /* just in case */
assert(strcmp(clss->name, clss->cls_static.name) == 0); /* in class those 2 must be equal */
- SWIG_Lua_namespace_register(L,&clss->cls_static, false);
+ SWIG_Lua_namespace_register(L,&clss->cls_static, true);
- SWIG_Lua_get_table(L,clss->name); // Get namespace table back
assert(lua_istable(L,-1)); /* just in case */
/* add its constructor to module with the name of the class
@@ -899,10 +1042,9 @@ SWIGINTERN void SWIG_Lua_class_register_static(lua_State* L, swig_lua_class* cls
(this overcomes the problem of pure virtual classes without constructors)*/
if (clss->constructor)
{
- SWIG_Lua_add_function(L,".constructor", clss->constructor);
lua_getmetatable(L,-1);
assert(lua_istable(L,-1)); /* just in case */
- SWIG_Lua_add_function(L,"__call", SWIG_Lua_constructor_proxy);
+ SWIG_Lua_add_function(L,"__call", clss->constructor);
lua_pop(L,1);
}
@@ -911,19 +1053,42 @@ SWIGINTERN void SWIG_Lua_class_register_static(lua_State* L, swig_lua_class* cls
/* clear stack */
lua_pop(L,1);
+ assert( lua_gettop(L) == begin );
}
-/* performs the entire class registration process */
-SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss)
+/* performs the instance(non-static) class registration process. Metatable for class is created
+ * and added to the class registry.
+ */
+SWIGINTERN void SWIG_Lua_class_register_instance(lua_State* L,swig_lua_class* clss)
{
- SWIG_Lua_class_register_static(L,clss);
-
+ int begin = lua_gettop(L);
+ // if name already there (class is already registered) then do nothing
+ SWIG_Lua_get_class_registry(L); /* get the registry */
+ lua_pushstring(L,clss->fqname); /* get the name */
+ lua_rawget(L,-2);
+ if(!lua_isnil(L,-1)) {
+ lua_pop(L,2);
+ assert(lua_gettop(L)==begin);
+ return;
+ }
+ lua_pop(L,2); // tidy stack
+ // Recursively initialize all bases
+ int i = 0;
+ for(i=0;clss->bases[i];i++)
+ {
+ SWIG_Lua_class_register_instance(L,clss->bases[i]);
+ }
+ // Again, get registry and push name
SWIG_Lua_get_class_registry(L); /* get the registry */
- lua_pushstring(L,clss->name); /* get the name */
+ lua_pushstring(L,clss->fqname); /* get the name */
lua_newtable(L); /* create the metatable */
/* add string of class name called ".type" */
lua_pushstring(L,".type");
- lua_pushstring(L,clss->name);
+ lua_pushstring(L,clss->fqname);
+ lua_rawset(L,-3);
+ /* add a table called bases */
+ lua_pushstring(L,".bases");
+ lua_newtable(L);
lua_rawset(L,-3);
/* add a table called ".get" */
lua_pushstring(L,".get");
@@ -948,10 +1113,18 @@ SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss)
/* add it */
lua_rawset(L,-3); /* metatable into registry */
lua_pop(L,1); /* tidy stack (remove registry) */
+ assert(lua_gettop(L)==begin);
- SWIG_Lua_get_class_metatable(L,clss->name);
- SWIG_Lua_add_class_details(L,clss); /* recursive adding of details (atts & ops) */
+ SWIG_Lua_get_class_metatable(L,clss->fqname);
+ SWIG_Lua_add_class_instance_details(L,clss); /* recursive adding of details (atts & ops) */
lua_pop(L,1); /* tidy stack (remove class metatable) */
+ assert( lua_gettop(L) == begin );
+}
+
+SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss)
+{
+ SWIG_Lua_class_register_instance(L,clss);
+ SWIG_Lua_class_register_static(L,clss);
}
/* -----------------------------------------------------------------------------
@@ -963,7 +1136,7 @@ SWIGINTERN void _SWIG_Lua_AddMetatable(lua_State* L,swig_type_info *type)
{
if (type->clientdata) /* there is clientdata: so add the metatable */
{
- SWIG_Lua_get_class_metatable(L,((swig_lua_class*)(type->clientdata))->name);
+ SWIG_Lua_get_class_metatable(L,((swig_lua_class*)(type->clientdata))->fqname);
if (lua_istable(L,-1))
{
lua_setmetatable(L,-2);
View
10 Source/Modules/lang.cxx
@@ -1490,6 +1490,7 @@ int Language::membervariableHandler(Node *n) {
Setattr(n, "type", type);
Setattr(n, "name", name);
Setattr(n, "sym:name", symname);
+ Delattr(n, "memberset");
/* Delete all attached typemaps and typemap attributes */
Iterator ki;
@@ -1507,6 +1508,7 @@ int Language::membervariableHandler(Node *n) {
Setattr(n, "sym:name", mrename_get);
Setattr(n, "memberget", "1");
functionWrapper(n);
+ Delattr(n, "memberget");
}
Delete(mrename_get);
Delete(mrename_set);
@@ -2951,11 +2953,14 @@ int Language::constantWrapper(Node *n) {
* ---------------------------------------------------------------------- */
int Language::variableWrapper(Node *n) {
- Swig_require("variableWrapper", n, "*name", "*sym:name", "*type", "?parms", NIL);
+ Swig_require("variableWrapper", n, "*name", "*sym:name", "*type", "?parms", "?varset", "?varget", NIL);
String *symname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *name = Getattr(n, "name");
+ Delattr(n,"varset");
+ Delattr(n,"varget");
+
/* If no way to set variables. We simply create functions */
int assignable = is_assignable(n);
int flags = use_naturalvar_mode(n);
@@ -2986,12 +2991,14 @@ int Language::variableWrapper(Node *n) {
Delete(pname0);
}
if (make_set_wrapper) {
+ Setattr(n, "varset", "1");
functionWrapper(n);
}
/* Restore parameters */
Setattr(n, "sym:name", symname);
Setattr(n, "type", type);
Setattr(n, "name", name);
+ Delattr(n, "varset");
/* Delete all attached typemaps and typemap attributes */
Iterator ki;
@@ -3005,6 +3012,7 @@ int Language::variableWrapper(Node *n) {
String *gname = Swig_name_get(NSpace, symname);
Setattr(n, "sym:name", gname);
Delete(gname);
+ Setattr(n, "varget", "1");
functionWrapper(n);
Swig_restore(n);
return SWIG_OK;
View
317 Source/Modules/lua.cxx
@@ -122,13 +122,20 @@ class LUA:public Language {
//String *s_vars_meta_tab; // metatable for variables
Hash* namespaces_hash;
+ // Parameters for current class. NIL if not parsing class
int have_constructor;
int have_destructor;
String *destructor_action;
String *class_symname;
+ String *class_fq_symname; // Fully qualified symname - NSpace + '.' + class_symname
+ String *class_static_nspace;
String *constructor_name;
- enum {
+ // Many wrappers forward calls to each other, for example staticmembervariableHandler
+ // forwards call to variableHandler, which, in turn, makes to call to functionWrapper.
+ // In order to access information about whether it is static member of class or just
+ // plain old variable an array current is kept and used as 'log' of call stack.
+ enum TState {
NO_CPP,
VARIABLE,
MEMBER_FUNC,
@@ -137,8 +144,12 @@ class LUA:public Language {
MEMBER_VAR,
CLASS_CONST,
STATIC_FUNC,
- STATIC_VAR
- }current;
+ STATIC_VAR,
+ STATIC_CONST, // enums and things like static const int x = 5;
+
+ STATES_COUNT
+ };
+ bool current[STATES_COUNT];
public:
@@ -175,10 +186,14 @@ class LUA:public Language {
have_destructor(0),
destructor_action(0),
class_symname(0),
- constructor_name(0),
- current(NO_CPP) {
+ class_fq_symname(0),
+ class_static_nspace(0),
+ constructor_name(0) {
namespaces_hash = NewHash();
+ for(int i = 0; i < STATES_COUNT; i++ )
+ current[i] = false;
}
+
~LUA() {
if(namespaces_hash)
Delete(namespaces_hash);
@@ -306,7 +321,9 @@ class LUA:public Language {
s_luacode = NewString("");
Swig_register_filebyname("luacode", s_luacode);
- current=NO_CPP;
+ current[NO_CPP] = true;
+ // Registering names schemes
+ Swig_name_register("member", "%m");
/* Standard stuff for the SWIG runtime section */
Swig_banner(f_begin);
@@ -473,6 +490,21 @@ class LUA:public Language {
* Create a function declaration and register it with the interpreter.
* --------------------------------------------------------------------- */
+ // Helper function. Remembers wrap name
+ void rememberWrapName(Node *n, String *wrapname) {
+ Setattr(n, "wrap:name", wrapname);
+ // If it is getter/setter, then write wrapname under
+ // wrap:memberset/wrap:memberget accordingly
+ if( Getattr(n, "memberset") )
+ Setattr(n, "memberset:wrap:name", wrapname);
+ if( Getattr(n, "varset") )
+ Setattr(n, "varset:wrap:name", wrapname);
+ if( Getattr(n, "memberget") )
+ Setattr(n, "memberget:wrap:name", wrapname);
+ if( Getattr(n, "varget") )
+ Setattr(n, "varget:wrap:name", wrapname);
+ }
+
virtual int functionWrapper(Node *n) {
REPORT("functionWrapper",n);
@@ -491,7 +523,7 @@ class LUA:public Language {
if (Getattr(n, "sym:overloaded")) {
overname = Getattr(n, "sym:overname");
} else {
- if (!addSymbol(iname, n, getNSpace())) {
+ if (!luaAddSymbol(iname, n)) {
Printf(stderr,"addSymbol(%s) failed\n",iname);
return SWIG_ERROR;
}
@@ -505,11 +537,13 @@ class LUA:public Language {
Wrapper_add_local(f, "SWIG_arg", "int SWIG_arg = 0");
- String *wname = Swig_name_wrapper(iname);
+ String* fqname = fully_qualified_name(iname);
+ String *wname = Swig_name_wrapper(fqname);
+ Delete(fqname);
if (overname) {
Append(wname, overname);
}
- if (current == CONSTRUCTOR) {
+ if (current[CONSTRUCTOR]) {
if( constructor_name != 0)
Delete(constructor_name);
constructor_name = Copy(wname);
@@ -552,12 +586,6 @@ class LUA:public Language {
}
- /* Which input argument to start with? */
- // int start = (current == MEMBER_FUNC || current == MEMBER_VAR || current == DESTRUCTOR) ? 1 : 0;
-
- /* Offset to skip over the attribute name */
- // int offset = (current == MEMBER_VAR) ? 1 : 0;
-
/* NEW LANGUAGE NOTE:***********************************************
from here on in, it gets rather hairy
this is the code to convert from the scripting language to C/C++
@@ -693,14 +721,7 @@ class LUA:public Language {
}
// Remember C name of the wrapping function
- Setattr(n, "wrap:name", wname);
- // If it is getter/setter, then write wname under
- // wrap:memberset/wrap:memberget accordingly
- if( Getattr(n, "memberset") )
- Setattr(n, "memberset:wrap:name", wname);
- if( Getattr(n, "memberget") )
- Setattr(n, "memberget:wrap:name", wname);
-
+ rememberWrapName(n, wname);
/* Emit the function call */
String *actioncode = emit_action(n);
@@ -777,7 +798,7 @@ class LUA:public Language {
Therefore we go though the whole function,
but do not write the code into the wrapper
*/
- if(current!=DESTRUCTOR) {
+ if(!current[DESTRUCTOR]) {
Wrapper_print(f, f_wrappers);
}
@@ -789,7 +810,7 @@ class LUA:public Language {
if (!Getattr(n, "sym:overloaded")) {
//REPORT("dispatchFunction", n);
// add_method(n, iname, wname, description);
- if (current==NO_CPP || current==STATIC_FUNC) { // emit normal fns & static fns
+ if (current[NO_CPP] || current[STATIC_FUNC]) { // emit normal fns & static fns
Hash* nspaceHash = getNamespaceHash( getNSpace() );
String* s_ns_methods_tab = Getattr(nspaceHash, "methods");
if(elua_ltr || eluac_ltr)
@@ -877,24 +898,19 @@ class LUA:public Language {
Printv(f->code, "}\n", NIL);
Wrapper_print(f, f_wrappers);
//add_method(symname,wname,0);
- if (current==NO_CPP || current==STATIC_FUNC) { // emit normal fns & static fns
+ if (current[NO_CPP] || current[STATIC_FUNC]) { // emit normal fns & static fns
Hash* nspaceHash = getNamespaceHash( getNSpace() );
String* s_ns_methods_tab = Getattr(nspaceHash, "methods");
Printv(s_ns_methods_tab, tab4, "{ \"", symname, "\",", wname, "},\n", NIL);
}
- if (current == CONSTRUCTOR) {
+ if (current[CONSTRUCTOR]) {
if( constructor_name != 0 )
Delete(constructor_name);
constructor_name = Copy(wname);
}
- Setattr(n, "wrap:name", wname);
- // If it is getter/setter, then write wname under
- // wrap:memberset/wrap:memberget accordingly
- if( Getattr(n, "memberset") )
- Setattr(n, "memberset:wrap:name", wname);
- if( Getattr(n, "memberget") )
- Setattr(n, "memberget:wrap:name", wname);
+ // Remember C name of the wrapping function
+ rememberWrapName(n, wname);
DelWrapper(f);
Delete(dispatch);
@@ -916,13 +932,14 @@ class LUA:public Language {
NEW LANGUAGE NOTE:END ************************************************/
// REPORT("variableWrapper", n);
String *iname = Getattr(n, "sym:name");
- current=VARIABLE;
+ String *unassignable = NewString("SWIG_Lua_set_immutable");
+ current[VARIABLE] = true;
// let SWIG generate the wrappers
int result = Language::variableWrapper(n);
- current=NO_CPP;
+ current[VARIABLE] = false;
// normally SWIG will generate 2 wrappers, a get and a set
// but in certain scenarios (immutable, or if its arrays), it will not
- String *getName = Swig_name_wrapper(Swig_name_get(getNSpace(), iname));
+ String *getName = Getattr(n,"varget:wrap:name");
String *setName = 0;
// checking whether it can be set to or not appears to be a very error prone issue
// I referred to the Language::variableWrapper() to find this out
@@ -934,14 +951,15 @@ class LUA:public Language {
Delete(tm);
if (assignable) {
- setName = Swig_name_wrapper(Swig_name_set(getNSpace(), iname));
+ setName = Getattr(n,"varset:wrap:name");
} else {
// how about calling a 'this is not settable' error message?
- setName = NewString("SWIG_Lua_set_immutable"); // error message
- //setName = NewString("0");
+ setName = unassignable;// error message
}
// register the variable
+ assert(setName != 0);
+ assert(getName != 0);
Hash* nspaceHash = getNamespaceHash( getNSpace() );
String* s_ns_methods_tab = Getattr(nspaceHash, "methods");
String* s_ns_var_tab = Getattr(nspaceHash, "attributes");
@@ -956,12 +974,11 @@ class LUA:public Language {
} else {
Printf(s_ns_var_tab, "%s{ \"%s\", %s, %s },\n", tab4, iname, getName, setName);
}
- if (getCurrentClass()) {
+ if (getCurrentClass()) { // TODO: REMOVE
Setattr(n, "luaclassobj:wrap:get", getName);
Setattr(n, "luaclassobj:wrap:set", setName);
} else {
- Delete(getName);
- Delete(setName);
+ Delete(unassignable);
}
return result;
}
@@ -978,8 +995,9 @@ class LUA:public Language {
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *tm;
+ //Printf( stdout, "Add constant %s, ns %s\n", iname, getNSpace() );// TODO: REMOVE
- if (!addSymbol(iname, n, getNSpace()))
+ if (!luaAddSymbol(iname, n))
return SWIG_ERROR;
/* Special hook for member pointer */
@@ -1035,7 +1053,7 @@ class LUA:public Language {
// REPORT("nativeWrapper", n);
String *symname = Getattr(n, "sym:name");
String *wrapname = Getattr(n, "wrap:name");
- if (!addSymbol(wrapname, n, getNSpace()))
+ if (!luaAddSymbol(wrapname, n))
return SWIG_ERROR;
Hash *nspaceHash = getNamespaceHash( getNSpace() );
@@ -1050,15 +1068,51 @@ class LUA:public Language {
* ------------------------------------------------------------ */
virtual int enumDeclaration(Node *n) {
- return Language::enumDeclaration(n);
+ // enumDeclaration supplied by Language is messing with NSpace.
+ // So this is the exact copy of function from Language with
+ // correct handling of namespaces
+ String *oldNSpace = getNSpace();
+ if( getCurrentClass() == 0 ) {
+ setNSpace(Getattr(n, "sym:nspace"));
+ }
+
+ if (!ImportMode) {
+ current[STATIC_CONST] = true;
+ emit_children(n);
+ current[STATIC_CONST] = false;
+ }
+
+ setNSpace(oldNSpace);
+
+ return SWIG_OK;
}
/* ------------------------------------------------------------
* enumvalueDeclaration()
* ------------------------------------------------------------ */
virtual int enumvalueDeclaration(Node *n) {
- return Language::enumvalueDeclaration(n);
+ if (getCurrentClass() && (cplus_mode != PUBLIC))
+ return SWIG_NOWRAP;
+
+ Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL);
+ String *value = Getattr(n, "value");
+ String *name = Getattr(n, "name");
+ String *tmpValue;
+
+ if (value)
+ tmpValue = NewString(value);
+ else
+ tmpValue = NewString(name);
+ Setattr(n, "value", tmpValue);
+
+ Setattr(n, "name", tmpValue); /* for wrapping of enums in a namespace when emit_action is used */
+ constantWrapper(n);
+
+ Delete(tmpValue);
+ Swig_restore(n);
+ // TODO: Backward compatibility: add ClassName_ConstantName member
+ return SWIG_OK;
}
/* ------------------------------------------------------------
@@ -1076,28 +1130,35 @@ class LUA:public Language {
virtual int classHandler(Node *n) {
//REPORT("classHandler", n);
- String *mangled_full_class_symname = 0;
- String *full_class_symname = 0;
+ String *mangled_class_fq_symname = 0;
String* nspace = getNSpace();
String* destructor_name = 0;
constructor_name = 0;
have_constructor = 0;
have_destructor = 0;
destructor_action = 0;
+ assert(class_static_nspace == 0);
+ assert(class_fq_symname == 0);
+ assert(class_symname == 0);
+
+ current[NO_CPP] = false;
class_symname = Getattr(n, "sym:name");
- if (!addSymbol(class_symname, n, nspace))
+ // We have to enforce nspace here, because technically we are already
+ // inside class parsing (getCurrentClass != 0), but we should register
+ // class in the it's parent namespace
+ if (!luaAddSymbol(class_symname, n, nspace))
return SWIG_ERROR;
if (nspace == 0)
- full_class_symname = NewStringf("%s", class_symname);
+ class_fq_symname = NewStringf("%s", class_symname);
else
- full_class_symname = NewStringf("%s.%s", nspace, class_symname);
+ class_fq_symname = NewStringf("%s.%s", nspace, class_symname);
- assert(full_class_symname != 0);
- mangled_full_class_symname = Swig_name_mangle(full_class_symname);
- Printf( stdout, "Mangled class symname %s\n", mangled_full_class_symname );
+ assert(class_fq_symname != 0);
+ mangled_class_fq_symname = Swig_name_mangle(class_fq_symname);
+ Printf( stdout, "Mangled class symname %s\n", mangled_class_fq_symname );
// not sure exactly how this works,
// but tcl has a static hashtable of all classes emitted and then only emits code for them once.
@@ -1107,9 +1168,9 @@ class LUA:public Language {
// * consider effect on template_specialization_defarg
static Hash *emitted = NewHash();
- if (Getattr(emitted, mangled_full_class_symname))
+ if (Getattr(emitted, mangled_class_fq_symname))
return SWIG_NOWRAP;
- Setattr(emitted, mangled_full_class_symname, "1");
+ Setattr(emitted, mangled_class_fq_symname, "1");
// We treat class T as both 'class' and 'namespace'. All static members, attributes
// and constants are considered part of namespace T, all members - part of the 'class'
@@ -1122,7 +1183,7 @@ class LUA:public Language {
// And we can guarantee that there will not be any name collision because names starting with 2 underscores
// and capital letter are forbiden to use in C++. So, under know circumstances could our class contain
// any member or subclass with name "__Static". Thus, never any name clash.
- Hash* non_static_cls = getNamespaceHash(full_class_symname, false);
+ Hash* non_static_cls = getNamespaceHash(class_fq_symname, false);
assert(non_static_cls != 0);
s_attr_tab = Getattr(non_static_cls, "attributes");
s_methods_tab = Getattr(non_static_cls, "methods");
@@ -1135,11 +1196,9 @@ class LUA:public Language {
* All constants are considered part of static part of class.
*/
- String *static_cls_key = NewStringf("%s%s__Static", full_class_symname, NSPACE_SEPARATOR);
- Hash *static_cls = getNamespaceHash(static_cls_key, false);
- if (static_cls == 0) {
- return SWIG_ERROR; // This cant be, so it is internal, implementation error
- }
+ class_static_nspace = NewStringf("%s%s__Static", class_fq_symname, NSPACE_SEPARATOR);
+ Hash *static_cls = getNamespaceHash(class_static_nspace, false);
+ assert(static_cls != 0);
Setattr(static_cls, "lua:no_namespaces", "1");
/* TODO: REMOVE
s_cls_methods_tab = Getattr(static_cls, "methods");
@@ -1160,17 +1219,18 @@ class LUA:public Language {
// Replacing namespace with namespace + class in order to static
// member be put inside class static area
- setNSpace(static_cls_key);
+ setNSpace(class_static_nspace);
// Generate normal wrappers
Language::classHandler(n);
// Restore correct nspace
setNSpace(nspace);
+ //Printf( stdout, "Class finished\n" ); TODO:REMOVE
SwigType *t = Copy(Getattr(n, "name"));
SwigType_add_pointer(t);
// Catch all: eg. a class with only static functions and/or variables will not have 'remembered'
- String *wrap_class = NewStringf("&_wrap_class_%s", mangled_full_class_symname);
+ String *wrap_class = NewStringf("&_wrap_class_%s", mangled_class_fq_symname);
SwigType_remember_clientdata(t, wrap_class);
String *rt = Copy(getClassType());
@@ -1182,12 +1242,12 @@ class LUA:public Language {
Printv( ns_classes, wrap_class, ",\n", NIL );
// Register the class structure with the type checker
- // Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_full_class_symname);
+ // Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_class_fq_symname);
// emit a function to be called to delete the object
// TODO: class_name -> full_class_name || mangled full_class_name
if (have_destructor) {
- destructor_name = NewStringf("swig_delete_%s", mangled_full_class_symname);
+ destructor_name = NewStringf("swig_delete_%s", mangled_class_fq_symname);
Printv(f_wrappers, "static void ", destructor_name, "(void *obj) {\n", NIL);
if (destructor_action) {
Printv(f_wrappers, SwigType_str(rt, "arg1"), " = (", SwigType_str(rt, 0), ") obj;\n", NIL);
@@ -1201,9 +1261,26 @@ class LUA:public Language {
}
Printf(f_wrappers, "}\n");
}
+ // Wrap constructor wrapper into one more proxy function. It will be used as class namespace __call method, thus
+ // allowing both
+ // Module.ClassName.StaticMethod to access static method/variable/constant
+ // Module.ClassName() to create new object
+ if (have_constructor) {
+ String* constructor_proxy_name = NewStringf("_proxy_%s", constructor_name);
+ Printv(f_wrappers, "static int ", constructor_proxy_name, "(lua_State *L) {\n", NIL);
+ Printv(f_wrappers,
+ tab4, "assert(lua_istable(L,1));\n",
+ tab4, "lua_pushcfunction(L,", constructor_name, ");\n",
+ tab4, "assert(!lua_isnil(L,-1));\n",
+ tab4, "lua_replace(L,1); /* replace our table with real constructor */\n",
+ tab4, "lua_call(L,lua_gettop(L)-1,1);\n",
+ tab4, "return 1;\n}\n", NIL);
+ Delete(constructor_name);
+ constructor_name = constructor_proxy_name;
+ }
- closeNamespaceHash(full_class_symname, f_wrappers);
- closeNamespaceHash(static_cls_key, f_wrappers);
+ closeNamespaceHash(class_fq_symname, f_wrappers);
+ closeNamespaceHash(class_static_nspace, f_wrappers);
/* TODO: REMOVE
@@ -1251,12 +1328,12 @@ class LUA:public Language {
}
}
- Printv(f_wrappers, "static swig_lua_class *swig_", mangled_full_class_symname, "_bases[] = {", base_class, "0};\n", NIL);
+ Printv(f_wrappers, "static swig_lua_class *swig_", mangled_class_fq_symname, "_bases[] = {", base_class, "0};\n", NIL);
Delete(base_class);
- Printv(f_wrappers, "static const char *swig_", mangled_full_class_symname, "_base_names[] = {", base_class_names, "0};\n", NIL);
+ Printv(f_wrappers, "static const char *swig_", mangled_class_fq_symname, "_base_names[] = {", base_class_names, "0};\n", NIL);
Delete(base_class_names);
- Printv(f_wrappers, "static swig_lua_class _wrap_class_", mangled_full_class_symname, " = { \"", class_symname, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL);
+ Printv(f_wrappers, "static swig_lua_class _wrap_class_", mangled_class_fq_symname, " = { \"", class_symname, "\", \"", class_fq_symname,"\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL);
// TODO: Replace with constructor_name
if (have_constructor) {
@@ -1285,7 +1362,7 @@ class LUA:public Language {
if (have_destructor) {
if (eluac_ltr) {
String* ns_methods_tab = Getattr(nspaceHash, "methods");
- Printv(ns_methods_tab, tab4, "{LSTRKEY(\"", "free_", mangled_full_class_symname, "\")", ", LFUNCVAL(", destructor_name, ")", "},\n", NIL);
+ Printv(ns_methods_tab, tab4, "{LSTRKEY(\"", "free_", mangled_class_fq_symname, "\")", ", LFUNCVAL(", destructor_name, ")", "},\n", NIL);
Printv(f_wrappers, ", ", destructor_name, NIL);
} else {
Printv(f_wrappers, ", ", destructor_name, NIL);
@@ -1295,15 +1372,21 @@ class LUA:public Language {
}
Printf(f_wrappers, ", %s, %s, ", s_methods_tab_name, s_attr_tab_name );
// TODO: Replace class_symname with class_name
- printNamespaceDefinition(static_cls_key, class_symname, f_wrappers);
+ printNamespaceDefinition(class_static_nspace, class_symname, f_wrappers);
Printf(f_wrappers, ", swig_%s_bases, swig_%s_base_names };\n\n",
- mangled_full_class_symname, mangled_full_class_symname);
+ mangled_class_fq_symname, mangled_class_fq_symname);
+
+ // Printv(f_wrappers, ", swig_", mangled_class_fq_symname, "_methods, swig_", mangled_class_fq_symname, "_attributes, swig_", mangled_class_fq_symname, "_bases };\n\n", NIL);
+ // Printv(s_cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, &_wrap_class_", mangled_class_fq_symname, "},\n", NIL);
- // Printv(f_wrappers, ", swig_", mangled_full_class_symname, "_methods, swig_", mangled_full_class_symname, "_attributes, swig_", mangled_full_class_symname, "_bases };\n\n", NIL);
- // Printv(s_cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, &_wrap_class_", mangled_full_class_symname, "},\n", NIL);
+ current[NO_CPP] = true;
Delete(t);
- Delete(mangled_full_class_symname);
- Delete(static_cls_key);
+ Delete(mangled_class_fq_symname);
+ Delete(class_static_nspace);
+ class_static_nspace = 0;
+ Delete(class_fq_symname);
+ class_fq_symname = 0;
+ class_symname = 0;
return SWIG_OK;
}
@@ -1327,9 +1410,9 @@ class LUA:public Language {
String *realname, *rname;
- current = MEMBER_FUNC;
+ current[MEMBER_FUNC] = true;
Language::memberfunctionHandler(n);
- current = NO_CPP;
+ current[MEMBER_FUNC] = false;
realname = iname ? iname : name;
rname = Getattr(n, "wrap:name");
@@ -1350,9 +1433,9 @@ class LUA:public Language {
String *symname = Getattr(n, "sym:name");
String *getter_name, *setter_name;
- current = MEMBER_VAR;
+ current[MEMBER_VAR] = true;
Language::membervariableHandler(n);
- current = NO_CPP;
+ current[MEMBER_VAR] = false;
getter_name = Getattr(n, "memberget:wrap:name");
assert(getter_name != 0);
if (!GetFlag(n, "feature:immutable")) {
@@ -1382,9 +1465,9 @@ class LUA:public Language {
virtual int constructorHandler(Node *n) {
// REPORT("constructorHandler", n);
- current = CONSTRUCTOR;
+ current[CONSTRUCTOR] = true;
Language::constructorHandler(n);
- current = NO_CPP;
+ current[CONSTRUCTOR] = false;
//constructor_name = NewString(Getattr(n, "sym:name"));
have_constructor = 1;
//Printf( stdout, "Constructor %s\n", constructor_name); TODO: REMOVE
@@ -1397,9 +1480,9 @@ class LUA:public Language {
virtual int destructorHandler(Node *n) {
REPORT("destructorHandler", n);
- current = DESTRUCTOR;
+ current[DESTRUCTOR] = true;
Language::destructorHandler(n);
- current = NO_CPP;
+ current[DESTRUCTOR] = false;
have_destructor = 1;
destructor_action = Getattr(n, "wrap:action");
return SWIG_OK;
@@ -1413,28 +1496,28 @@ class LUA:public Language {
virtual int staticmemberfunctionHandler(Node *n) {
REPORT("staticmemberfunctionHandler", n);
- current = STATIC_FUNC;
+ current[STATIC_FUNC] = true;
//String *symname = Getattr(n, "sym:name");
int result = Language::staticmemberfunctionHandler(n);
if (cparse_cplusplus && getCurrentClass()) {
Swig_restore(n);
}
- current = NO_CPP;
+ current[STATIC_FUNC] = false;;
if (result != SWIG_OK)
return result;
if (Getattr(n, "sym:nextSibling"))
return SWIG_OK;
- Swig_require("luaclassobj_staticmemberfunctionHandler", n, "luaclassobj:wrap:name", NIL);
+ //Swig_require("luaclassobj_staticmemberfunctionHandler", n, "luaclassobj:wrap:name", NIL);
//String *name = Getattr(n, "name");
//String *rname, *realname;
//realname = symname ? symname : name;
//rname = Getattr(n, "luaclassobj:wrap:name");
// TODO: Add backward compatibility here: add "ClassName_FuncName" to global table
//Printv(s_cls_methods_tab, tab4, "{\"", realname, "\", ", rname, "}, \n", NIL);
- Swig_restore(n);
+ //Swig_restore(n);
return SWIG_OK;
}
@@ -1454,7 +1537,7 @@ class LUA:public Language {
}
int result = Language::memberconstantHandler(n);
if (cparse_cplusplus && getCurrentClass())
- Swig_restore(n);
+ Swig_restore(n); // TODO: WTF ?
return result;
}
@@ -1465,9 +1548,10 @@ class LUA:public Language {
virtual int staticmembervariableHandler(Node *n) {
REPORT("staticmembervariableHandler",n);
- current = STATIC_VAR;
+ current[STATIC_VAR] = true;
//String *symname = Getattr(n, "sym:name");
int result = Language::staticmembervariableHandler(n);
+ current[STATIC_VAR] = false;
if (result != SWIG_OK)
return result;
@@ -1868,6 +1952,53 @@ class LUA:public Language {
Printf( output, "static swig_lua_namespace %s;\n", Getattr(nspace_hash, "cname") );
}
+
+ // Our implementation of addSymbol. Determines scope correctly, then calls Language::addSymbol
+ int luaAddSymbol(const String *s, const Node *n) {
+ String* scope = 0;
+ // If ouside class, than NSpace is used.
+ if( !getCurrentClass())
+ scope = getNSpace();
+ else {
+ // If inside class, then either class static namespace or class fully qualified name is used
+ assert(!current[NO_CPP]);
+ if(current[STATIC_FUNC] || current[STATIC_VAR] || current[STATIC_CONST] ) {
+ scope = class_static_nspace;
+ } else if(current[MEMBER_VAR] || current[CLASS_CONST] || current[CONSTRUCTOR] || current[DESTRUCTOR]
+ || current[MEMBER_FUNC] ) {
+ scope = class_fq_symname;
+ } else {
+ assert(0); // Can't be. Implementation error
+ }
+ assert(scope != 0);
+ }
+ return Language::addSymbol(s,n,scope);
+ }
+
+ // Overload. Enforces given scope. Actually, it simply forwards call to Language::addSymbol
+ int luaAddSymbol(const String*s, const Node*n, const_String_or_char_ptr scope) {
+ return Language::addSymbol(s,n,scope);
+ }
+
+ // Function creates fully qualified name of given symbol. Current NSpace and current class
+ // are used
+ String* fully_qualified_name(const_String_or_char_ptr name)
+ {
+ assert(name != 0);
+ String* scope= 0;
+ if( getCurrentClass() )
+ scope = class_fq_symname;
+ else
+ scope = getNSpace();
+
+ String *fqname = 0;
+ if( scope )
+ fqname = NewStringf("%s::%s",scope,name);
+ else
+ fqname = Copy(name);
+
+ return fqname;
+ }
};
/* NEW LANGUAGE NOTE:***********************************************

0 comments on commit 295788c

Please sign in to comment.