File: Synopsis/SymbolLookup/Scope.hh 1
2
3
4
5
6
7#ifndef Synopsis_SymbolLookup_Scope_hh_
8#define Synopsis_SymbolLookup_Scope_hh_
9
10#include <Synopsis/SymbolLookup/Symbol.hh>
11#include <map>
12#include <set>
13
14namespace Synopsis
15{
16namespace SymbolLookup
17{
18struct TypeError : std::exception
19{
20 TypeError(PTree::Encoding const &n, PTree::Encoding const &t)
21 : name(n), type(t) {}
22 virtual ~TypeError() throw() {}
23 virtual char const * what() const throw() { return "TypeError";}
24 PTree::Encoding name;
25 PTree::Encoding type;
26};
27
28struct Undefined : std::exception
29{
30 Undefined(PTree::Encoding const &n, PTree::Node const *ref = 0)
31 : name(n), ptree(ref) {}
32 virtual ~Undefined() throw() {}
33 virtual char const * what() const throw() { return "Undefined";}
34 PTree::Encoding name;
35 PTree::Node const * ptree;
36};
37
38struct MultiplyDefined : std::exception
39{
40 MultiplyDefined(PTree::Encoding const &n,
41 PTree::Node const *decl,
42 PTree::Node const *orig)
43 : name(n), declaration(decl), original(orig) {}
44 virtual ~MultiplyDefined() throw() {}
45 virtual char const * what() const throw() { return "MultiplyDefined";}
46 PTree::Encoding name;
47 PTree::Node const * declaration;
48 PTree::Node const * original;
49};
50
51class InternalError : public std::exception
52{
53public:
54 InternalError(std::string const &what) : my_what(what) {}
55 virtual ~InternalError() throw() {}
56 virtual char const * what() const throw() { return my_what.c_str();}
57private:
58 std::string my_what;
59};
60
61typedef std::set<Symbol const *> SymbolSet;
62
63class ScopeVisitor;
64
65
66class Scope
67{
68protected:
69 //. SymbolTable provides a mapping from (encoded) names to Symbols declared
70 //. in this scope.
71 typedef std::multimap<PTree::Encoding, Symbol const *> SymbolTable;
72 //. ScopeTable provides a mapping from scope nodes to Scopes,
73 //. which can be used to traverse the scope tree in parallel with
74 //. the associated parse tree. As this traversal is also done
75 //. during the parsing, the scopes can not be const.
76 typedef std::map<PTree::Node const *, Scope *> ScopeTable;
77
78public:
79 typedef SymbolTable::const_iterator symbol_iterator;
80 typedef ScopeTable::const_iterator scope_iterator;
81
82 typedef unsigned int LookupContext;
83 static LookupContext const DEFAULT = 0x0;
84 static LookupContext const SCOPE = 0x1;
85 static LookupContext const USING = 0x2;
86 static LookupContext const ELABORATE = 0x4;
87 static LookupContext const DECLARATION = 0x8;
88
89 Scope() : my_refcount(1) {}
90 Scope *ref() { ++my_refcount; return this;}
91 Scope const *ref() const { ++my_refcount; return this;}
92 void unref() const { if (!--my_refcount) delete this;}
93
94 virtual Scope const *outer_scope() const = 0;
95 Scope const *global_scope() const;
96
97 virtual void accept(ScopeVisitor *v) = 0;
98
99 symbol_iterator symbols_begin() const { return my_symbols.begin();}
100 symbol_iterator symbols_end() const { return my_symbols.end();}
101
102 scope_iterator scopes_begin() const { return my_scopes.begin();}
103 scope_iterator scopes_end() const { return my_scopes.end();}
104
105
106
107 void declare(PTree::Encoding const &name, Symbol const *symbol);
108
109
110 void declare_scope(PTree::Node const *, Scope *);
111
112
113
114
115
116 virtual void use(PTree::UsingDirective const *);
117
118
119 Scope *find_scope(PTree::Node const *) const;
120
121
122 Scope *find_scope(PTree::Encoding const &, Symbol const *) const;
123
124 void remove_scope(PTree::Node const*);
125
126
127
128
129
130 SymbolSet find(PTree::Encoding const &, LookupContext) const throw();
131
132
133 void remove(Symbol const *s);
134
135
136 SymbolSet lookup(PTree::Encoding const &, LookupContext = DEFAULT) const;
137
138 virtual SymbolSet unqualified_lookup(PTree::Encoding const &,
139 LookupContext = DEFAULT) const = 0;
140 virtual SymbolSet qualified_lookup(PTree::Encoding const &,
141 LookupContext = DEFAULT) const;
142
143protected:
144
145
146 virtual ~Scope();
147
148 SymbolTable my_symbols;
149 ScopeTable my_scopes;
150 mutable size_t my_refcount;
151};
152
153inline void Scope::declare_scope(PTree::Node const *node, Scope *scope)
154{
155 my_scopes[node] = scope->ref();
156}
157
158inline Scope *Scope::find_scope(PTree::Node const *node) const
159{
160 ScopeTable::const_iterator i = my_scopes.find(node);
161 return i == my_scopes.end() ? 0 : i->second;
162}
163
164inline Scope const *Scope::global_scope() const
165{
166 Scope const *scope = this;
167 while (Scope const *outer = scope->outer_scope())
168 scope = outer;
169 return scope;
170}
171
172}
173}
174
175#endif
Generated on Thu Apr 16 16:28:03 2009 by
synopsis (version devel)