Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

/ray/src/vm/input/nspcinfo.cc

Go to the documentation of this file.
00001 /*
00002  * vm/input/nspcinfo.cc
00003  * 
00004  * VM namespace information. 
00005  * 
00006  * Copyright (c) 2004 by Wolfgang Wieser ] wwieser (a) gmx <*> de [ 
00007  * 
00008  * This file may be distributed and/or modified under the terms of the 
00009  * GNU General Public License version 2 as published by the Free Software 
00010  * Foundation. (See COPYING.GPL for details.)
00011  * 
00012  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014  * 
00015  */
00016 
00017 #include "nspcinfo.h"
00018 #include <lib/lex/strtreedump.h>
00019 #include <lib/lex/fastval2str.h>
00020 
00021 
00022 namespace VM
00023 {
00024 
00025 const char *NamespaceInfo::NSType2String(NSType t)
00026 {
00027     switch(t)
00028     {
00029         case NSNamespace:  return("namespace");
00030         case NSClass:      return("class");
00031     }
00032     return("???");
00033 }
00034 
00035 
00036 const char *NamespaceInfo::SymbolEntryE::ExtID2String(ExtID e)
00037 {
00038     switch(e)
00039     {
00040         case ExtUnknown:   return("[unknown]");
00041         case ExtFunction:  return("function");
00042         case ExtVariable:  return("variable");
00043     }
00044     return("???");
00045 }
00046 
00047 
00048 TLString NamespaceInfo::SymbolEntryB::CompleteName() const
00049 {
00050     TLString tmp;
00051     
00052     const SymbolEntryE *see=ep();
00053     if(see)
00054     {
00055         Assert(symref>=0);
00056         
00057         if(see->nspc)
00058         {
00059             tmp=see->nspc->CompleteName();
00060             if(see->nspc->parent)
00061             {  tmp+="::";  }
00062         }
00063         else
00064         {  tmp="???::";  }
00065         
00066         tmp+=see->name;
00067     }
00068     else
00069     {
00070         Assert(symref<0);
00071         
00072         char ntmp[sizeof(SymRef)*2+1+1],*e=ntmp;
00073         *e++='@';
00074         e=FastInt2String(e,-symref,/*base=*/0);
00075         *e='\0';
00076         tmp+=ntmp;
00077     }
00078     
00079     return(tmp);
00080 }
00081 
00082 
00083 bool NamespaceInfo::SymbolEntryB::CompareTo(const SymbolEntryB &e) const
00084 {
00085     const SymbolEntryE *seA=ep(),*seB=e.ep();
00086     if(seA && seB)
00087     {
00088         if(seA->extid!=seB->extid)  return(0);
00089         
00090         // Both non-internal symbols. 
00091         switch(seA->extid)
00092         {
00093             case SymbolEntryE::ExtUnknown:
00094                 break;
00095             case SymbolEntryE::ExtFunction:
00096                 if(seA->ftype!=seB->ftype)  return(0);
00097                 break;
00098             case SymbolEntryE::ExtVariable:
00099                 if(seA->vtype!=seB->vtype)  return(0);
00100                 break;
00101             default: Assert(0);
00102         }
00103         
00104         // Otherwise (non-internal) the name must be set. 
00105         Assert(seA->name);
00106         Assert(seB->name);
00107         return(seA->name==seB->name);
00108     }
00109     
00110     if(!seA && !seB)
00111     {
00112         // For internal symbols, the symrefs must match. 
00113         return(symref==e.symref);
00114     }
00115     
00116     // Comparing internal with non-internal symbol. 
00117     return(0);
00118 }
00119 
00120 
00121 NamespaceInfo::SymbolEntryE &NamespaceInfo::SymbolEntryE::operator=(
00122     const SymbolEntryE &se)
00123 {
00124     symref=se.symref;
00125     
00126     extid=se.extid;
00127     ftype=se.ftype;
00128     vtype=se.vtype;
00129     name=se.name;
00130     nspc=se.nspc;
00131     linked=se.linked;
00132     
00133     return(*this);
00134 }
00135 
00136 
00137 NamespaceInfo::SymbolEntryE::SymbolEntryE(const SymbolEntryE &se) : 
00138     SymbolEntryB(se),
00139     extid(se.extid),
00140     ftype(se.ftype),
00141     vtype(se.vtype),
00142     name(se.name),
00143     nspc(se.nspc),
00144     linked(se.linked)
00145 {
00146     // empty
00147 }
00148 
00149 NamespaceInfo::SymbolEntryE::SymbolEntryE(NamespaceInfo *_nspc) : 
00150     SymbolEntryB(),
00151     extid(ExtUnknown),
00152     ftype(),
00153     vtype(),
00154     name(),
00155     nspc(_nspc),
00156     linked(NULL)
00157 {
00158     // empty
00159 }
00160 
00161 //------------------------------------------------------------------------------
00162 
00163 void NamespaceInfo::SortNamespaceTree()
00164 {
00165     // No child? Then nothing to do at all. 
00166     if(down.IsEmpty()) return;
00167     
00168     if(down.first()==down.last())
00169     {
00170         // One child. No sorting here, just go on to child. 
00171         down.first()->SortNamespaceTree();
00172         return;
00173     }
00174     
00175     /*if(down.first()->next==down.last())
00176     {
00177         // 2 children. Sorting is easy. 
00178         // NOT IMPLEMENTED; using general case below. 
00179         return;
00180     }*/
00181     
00182     // Several children. Go sorting. 
00183     down.MergeSort(_Operators());
00184     
00185     // Recursively process children: 
00186     for(NamespaceInfo *i=down.first(); i; i=i->next)
00187     {  i->SortNamespaceTree();  }
00188 }
00189 
00190 
00191 TLString NamespaceInfo::CompleteName() const
00192 {
00193     if(!parent)
00194     {  return TLString("::");  }
00195     
00196     TLString res(name);
00197     for(const NamespaceInfo *i=parent; i; i=i->parent)
00198     {
00199         if(!i->name)  continue;
00200         res.prepend(i->name+"::");
00201     }
00202     
00203     return(res);
00204 }
00205 
00206 
00207 void NamespaceInfo::DumpTree(StringTreeDump &dump,bool IDs_resolved,
00208     bool recurse) const
00209 {
00210     TLString tmp;
00211     tmp.sprintf(
00212         "%s %s\n"
00213         "  link_info_set=%s, linked=%s, children: %d\n"
00214         ,parent ? NSType2String(nstype) : "NAMESPACE",
00215         parent ? name.str() : "ROOT",
00216         link_info_set ? "yes" : "no",linked ? "yes" : "no",(int)down.count());
00217     dump+=tmp;
00218     uint32 scnt=0;
00219     for(SymbolList::Iterator i(symbol); i; i++,scnt++)
00220     {
00221         const SymbolEntryE *se=*i;
00222         tmp.sprintf(
00223             "  symbol[%u]={ extid=%s, ftype=%s, vtype=%s, name=%s, "
00224             "symref=%d }\n",
00225             (uint)scnt,
00226             SymbolEntryE::ExtID2String(se->extid),
00227             se->ftype.TypeString().str(),
00228             se->vtype.TypeString().str(),
00229             se->name.str(),
00230             (int)se->symref);
00231         dump+=tmp;
00232         // No internal symbols in this queue. 
00233         Assert(se->symref>=0 && se->nspc==this);
00234     }
00235     tmp.deref();
00236     
00237     // Recurse: 
00238     if(recurse && !down.IsEmpty())
00239     {
00240         dump.AddIndent();
00241         for(NamespaceInfo *i=down.first(); i; i=i->next)
00242         {  i->DumpTree(dump,IDs_resolved,recurse);  }
00243         dump.SubIndent();
00244     }
00245 }
00246 
00247 
00248 void NamespaceInfo::_AddChild(NamespaceInfo *child)
00249 {
00250     Assert(!(child->next || down.last()==child));
00251     
00252     // Add to the child list: 
00253     down.append(child);
00254     
00255     // Must have a non-NULL name unless it is the root. 
00256     // Obviously, *child cannot be the root. 
00257     Assert(child->name);
00258     
00259     // Add to the name-to-child map: 
00260     int _unused_ rv=map_name2child.store(child,/*allow_update=*/0);
00261     Assert(rv==0);
00262 }
00263 
00264 void NamespaceInfo::_DelChild(NamespaceInfo *child)
00265 {
00266     // Remove from child list: 
00267     if(child->next || down.last()==child)
00268     {  down.dequeue(child);  }
00269     
00270     // We need the name to remove from the B-tree. . 
00271     Assert(child->name);
00272     // Also remove from name-to-child map: 
00273     int _unused_ rv=map_name2child.remove(child);
00274     Assert(rv==0);
00275 }
00276 
00277 
00278 void NamespaceInfo::AddChild(NamespaceInfo *child)
00279 {
00280     if(!child)  return;  // Important; linker relies on it. 
00281     
00282     Assert(!child->parent);
00283     child->parent=this;
00284     
00285     _AddChild(child);
00286 }
00287 
00288 
00289 NamespaceInfo::NamespaceInfo(const TLString &_name,NamespaceInfo *_parent,
00290     NSType _nstype) : 
00291     LinkedListBase<NamespaceInfo>(),
00292     parent(_parent),
00293     down(),
00294     name(_name),
00295     nstype(_nstype),
00296     asm_loc(),
00297     linked(NULL),
00298     symbol(/*size of chunk*/16,/*old chunks*/1),
00299     map_name2child(/*m=*/_nstype==NSNamespace ? 16 : 6)
00300 {
00301     link_info_set=0;
00302     recursion_flag=0;
00303     
00304     // Register at parent. 
00305     if(parent)
00306     {  parent->_AddChild(this);  }
00307 }
00308 
00309 NamespaceInfo::~NamespaceInfo()
00310 {
00311     // Delete all children: 
00312     while(!down.IsEmpty())
00313     {  delete down.PopFirst();  }
00314     
00315     linked=NULL;
00316     // symbol tidies up itself. 
00317     
00318     // Unregister at parent. 
00319     if(parent)
00320     {  parent->_DelChild(this);  }
00321 }
00322 
00323 }  // end of namespace VM

Generated on Sat Feb 19 22:33:47 2005 for Ray by doxygen 1.3.5