diff options
Diffstat (limited to 'Source/Modules/lang.cxx')
-rw-r--r-- | Source/Modules/lang.cxx | 86 |
1 files changed, 80 insertions, 6 deletions
diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 3940a3001..9420ea719 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -319,8 +319,7 @@ overloading(0), multiinput(0), cplus_runtime(0), directors(0) { - Hash *symbols = NewHash(); - Setattr(symtabs, "", symbols); // create top level/global symbol table scope + symbolAddScope(""); // create top level/global symbol table scope argc_template_string = NewString("argc"); argv_template_string = NewString("argv[%d]"); @@ -1490,6 +1489,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 +1507,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 +2952,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 +2990,16 @@ int Language::variableWrapper(Node *n) { Delete(pname0); } if (make_set_wrapper) { + Setattr(n, "varset", "1"); functionWrapper(n); + } else { + Setattr(n, "feature:immutable", "1"); } /* 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,7 +3013,9 @@ 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); + Delattr(n, "varget"); Swig_restore(n); return SWIG_OK; } @@ -3049,11 +3059,10 @@ void Language::main(int argc, char *argv[]) { * ----------------------------------------------------------------------------- */ int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope) { + //Printf( stdout, "addSymbol: %s %s\n", s, scope ); Hash *symbols = Getattr(symtabs, scope ? scope : ""); if (!symbols) { - // New scope which has not been added by the target language - lazily created. - symbols = NewHash(); - Setattr(symtabs, scope, symbols); + symbols = symbolAddScope(scope); } else { Node *c = Getattr(symbols, s); if (c && (c != n)) { @@ -3070,6 +3079,71 @@ int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr } /* ----------------------------------------------------------------------------- + * Lanugage::symbolAddScope( const_String_or_char_ptr scopeName ) + * + * Creates a scope (symbols Hash) for given name. This method is auxilary, + * you don't have to call it - addSymbols will lazily create scopes automatically. + * If scope with given name already exists, then do nothing. + * Returns newly created (or already existing) scope. + * ----------------------------------------------------------------------------- */ +Hash* Language::symbolAddScope(const_String_or_char_ptr scope) { + Hash *symbols = symbolScopeLookup(scope); + if(!symbols) { + // Order in which to following parts are executed is important. In Lanugage + // constructor addScope("") is called to create a top level scope itself. + // Thus we must first add symbols hash to symtab and only then add pseudo + // symbol to top-level scope + + // New scope which has not been added by the target language - lazily created. + symbols = NewHash(); + Setattr(symtabs, scope, symbols); + + // Add the new scope as a symbol in the top level scope. + // Alternatively the target language must add it in before attempting to add symbols into the scope. + const_String_or_char_ptr top_scope = ""; + Hash *topscope_symbols = Getattr(symtabs, top_scope); + Hash *pseudo_symbol = NewHash(); + Setattr(pseudo_symbol, "sym:is_scope", "1"); + Setattr(topscope_symbols, scope, pseudo_symbol); + } + return symbols; +} + +/* ----------------------------------------------------------------------------- + * Lanugage::symbolSscopeLookup( const_String_or_char_ptr scope ) + * + * Lookup and returns a symtable (hash) representing given scope. Hash contains + * all symbols in this scope. + * ----------------------------------------------------------------------------- */ +Hash* Language::symbolScopeLookup( const_String_or_char_ptr scope ) { + Hash *symbols = Getattr(symtabs, scope ? scope : ""); + return symbols; +} + +/* ----------------------------------------------------------------------------- + * Lanugage::symbolScopeSymbolLookup( const_String_or_char_ptr scope ) + * + * For every scope there is a special pseudo-symbol in the top scope (""). It + * exists solely to detect name clashes. This pseudo symbol may contain a few properties, + * but you can more if you need to. This is also true fro top level scope (""). + * It contains a pseudo symbol with name "" (empty). Pseudo symbol contains the + * following properties: + * sym:scope = "1" - a flag that this is scope pseudo symbol + * + * Pseudo symbols are a Hash*, not a Node* (not that there is a difference + * in DOH) + * There is no difference from symbolLookup() method except for signature + * and return type. + * ----------------------------------------------------------------------------- */ +Hash* Language::symbolScopePseudoSymbolLookup( const_String_or_char_ptr scope ) +{ + /* Getting top scope */ + const_String_or_char_ptr top_scope = ""; + Hash *symbols = Getattr(symtabs, top_scope); + return Getattr(symbols, scope); +} + +/* ----------------------------------------------------------------------------- * Language::dumpSymbols() * ----------------------------------------------------------------------------- */ |