Modules | Files | Inheritance Tree | Inheritance Graph | Name Index | Config
File: Synopsis/Parser/C++/syn/dict.cc
    1| // Synopsis C++ Parser: dict.cc source file
    2| // Implementation of the Dictionary class
    3| 
    4| // $Id: dict.cc,v 1.13 2002/12/23 07:35:09 chalky Exp $
    5| //
    6| // This file is a part of Synopsis.
    7| // Copyright (C) 2001, 2002 Stephen Davies
    8| //
    9| // Synopsis is free software; you can redistribute it and/or modify it
   10| // under the terms of the GNU General Public License as published by
   11| // the Free Software Foundation; either version 2 of the License, or
   12| // (at your option) any later version.
   13| //
   14| // This program is distributed in the hope that it will be useful,
   15| // but WITHOUT ANY WARRANTY; without even the implied warranty of
   16| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   17| // General Public License for more details.
   18| //
   19| // You should have received a copy of the GNU General Public License
   20| // along with this program; if not, write to the Free Software
   21| // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   22| // 02111-1307, USA.
   23| 
   24| // $Log: dict.cc,v $
   25| // Revision 1.13  2002/12/23 07:35:09  chalky
   26| // Clean up formatting from using astyle a while ago.
   27| //
   28| // Revision 1.12  2002/11/17 12:11:43  chalky
   29| // Reformatted all files with astyle --style=ansi, renamed fakegc.hh
   30| //
   31| //
   32| 
   33| 
   34| #include "dict.hh"
   35| #include "ast.hh"
   36| #include "type.hh"
   37| 
   38| #include <map>
   39| #include <vector>
   40| #include <list>
   41| #include <string>
   42| #include <iostream>
   43| 
   44| typedef std::multimap<std::string, Types::Named*> name_map;
   45| 
   46| //. Define nested class
   47| struct Dictionary::Data
   48| {
   49|     name_map map;
   50| };
   51| 
   52| //. Constructor
   53| Dictionary::Dictionary()
   54| {
   55|     m = new Data;
   56| }
   57| 
   58| //. Destructor
   59| Dictionary::~Dictionary()
   60| {
   61|     delete m;
   62| }
   63| 
   64| //. Quick check if the name is in the dict
   65| bool
   66| Dictionary::has_key(const std::string& name)
   67| {
   68|     return m->map.find(name) != m->map.end();
   69| }
   70| 
   71| //. Lookup single
   72| //. TODO: the forward filtering could probably be done much simpler!
   73| //. TODO: The exception throwing is heavy too, besides all the vector copying!
   74| Types::Named*
   75| Dictionary::lookup(const std::string& name)
   76| {
   77|     name_map::iterator iter = m->map.lower_bound(name);
   78|     name_map::iterator end = m->map.upper_bound(name);
   79| 
   80|     // Check for not found
   81|     if (iter == end)
   82|         throw KeyError(name);
   83| 
   84|     Types::Namedtype = iter->second;
   85|     if (++iter == end)
   86|         return type;
   87| 
   88|     // Check for Unknown types
   89|     if (dynamic_cast<Types::Unknown*>(type))
   90|     {
   91|         // Skip further unknown types
   92|         while (iter != end && dynamic_cast<Types::Unknown*>(iter->second))
   93|             ++iter;
   94|         if (iter == end)
   95|             // No choice but to return the Unknown
   96|             return type;
   97|         type = (iter++)->second;
   98|         // Any other types that aren't unknown cause error
   99|         while (iter != end && dynamic_cast<Types::Unknown*>(iter->second))
  100|             ++iter;
  101|         if (iter == end)
  102|             // No more non-Unknown types, so return the one we found
  103|             return type;
  104|     }
  105|     // Create exception object
  106|     MultipleError exc;
  107|     exc.types.push_back(type);
  108|     do
  109|         exc.types.push_back(iter->second);
  110|     while (++iter != end);
  111|     throw exc;
  112| }
  113| 
  114| //. Lookup multiple
  115| std::vector<Types::Named*>
  116| Dictionary::lookupMultiple(const std::string& name) throw (KeyError)
  117| {
  118|     name_map::iterator iter = m->map.lower_bound(name);
  119|     name_map::iterator end = m->map.upper_bound(name);
  120| 
  121|     // Check for not found
  122|     if (iter == end)
  123|         throw KeyError(name);
  124| 
  125|     // Store type pointers in a vector
  126|     std::vector<Types::Named*> types;
  127|     do
  128|         types.push_back(iter->second);
  129|     while (++iter != end);
  130|     return types;
  131| }
  132| 
  133| void
  134| Dictionary::insert(Types::Named* type)
  135| {
  136|     std::string key = type->name().back();
  137|     m->map.insert(name_map::value_type(keytype));
  138| }
  139| 
  140| void
  141| Dictionary::insert(AST::Declaration* decl)
  142| {
  143|     Types::Declareddeclared = new Types::Declared(decl->name(), decl);
  144|     insert(declared);
  145|     if (AST::Functionfunc = dynamic_cast<AST::Function*>(decl))
  146|         // Also insert real (unmangled) name of functions
  147|         m->map.insert(name_map::value_type(func->realname(), declared));
  148| }
  149| 
  150| void
  151| Dictionary::dump()
  152| {
  153|     name_map::iterator iter = m->map.begin(), end = m->map.end();
  154|     std::cout << "Dumping dictionary: " << m->map.size() << " items.\n";
  155|     while (iter != end)
  156|     {
  157|         name_map::value_type p = *iter++;
  158|         std::cout << "   " << p.first << "\t-> " << p.second->name() << "\n";
  159|     }
  160|     std::cout.flush();
  161| }
  162| // vim: set ts=8 sts=4 sw=4 et: