fix namespace problems
[supertux.git] / tools / miniswig / tree.hpp
1 #ifndef __TREE_H__
2 #define __TREE_H__
3
4 #include <vector>
5 #include <string>
6 #include <iostream>
7 #include <sstream>
8 #include <stdexcept>
9 #include <assert.h>
10
11 class Namespace;
12
13 class AtomicType {
14 public:
15     AtomicType()
16         : parent(0)
17     { }
18     virtual ~AtomicType()
19     { }
20
21     virtual void write_c(std::ostream& out)
22     {
23         out << name;
24     }
25
26     std::string name;
27     Namespace* parent;
28 };
29
30 class BasicType : public AtomicType {
31 public:
32     static BasicType VOID;
33     static BasicType BOOL;
34     static BasicType CHAR;
35     static BasicType SHORT;
36     static BasicType INT;
37     static BasicType LONG;
38     static BasicType FLOAT;
39     static BasicType DOUBLE;
40
41 private:
42     BasicType(const std::string& name)
43     { 
44         this->name = name;
45     }                                     
46 };
47
48 class Type {
49 public:
50     Type() 
51         : atomic_type(0), _unsigned(false), _const(false), _static(false),
52         pointer(0), ref(0)
53     { }
54
55     void write_c_type(std::ostream& out)
56     {
57         if(_static)
58             out << "static ";        
59         if(_const)
60             out << "const ";
61         atomic_type->write_c(out);
62         for(int i = 0; i < pointer; ++i)
63             out << "*";
64         for(int i = 0; i < ref; ++i)
65             out << "&";
66     }
67
68     bool is_void() const
69     {
70         if(atomic_type == 0)
71             return true;
72         if(atomic_type == &BasicType::VOID && pointer == 0)
73             return true;
74         return false;
75     }
76
77     AtomicType* atomic_type;
78     bool _unsigned;
79     bool _const;
80     bool _static;
81     // number of '*' in the type declaration...
82     int pointer;
83     // number of '&' in the type declaration...
84     int ref;
85 };
86
87 class HSQUIRRELVMType : public AtomicType {
88 public:
89     HSQUIRRELVMType()
90     {
91         this->name = "HSQUIRRELVM";
92         assert(_instance == 0);
93         _instance = this;
94     }
95     virtual ~HSQUIRRELVMType()
96     {
97         assert(_instance == this);
98         _instance = 0;
99     }
100
101     static HSQUIRRELVMType* instance()
102     {
103         return _instance;
104     }
105 private:
106     static HSQUIRRELVMType* _instance;
107 };
108
109 class StringType : public AtomicType {
110 public:
111     StringType()
112     {
113         this->name = "string";
114         assert(_instance == 0);
115         _instance = this;
116     }
117     virtual ~StringType()
118     {
119         assert(_instance == this);
120         _instance = 0;
121     }
122
123     static StringType* instance()
124     {
125         return _instance;
126     }
127
128     virtual void write_c(std::ostream& out)
129     {
130         out << "std::string";
131     }
132
133 private:
134     static StringType* _instance;   
135 };
136
137 class Parameter {
138 public:
139     std::string name;
140     Type type;
141 };
142
143 class ClassMember {
144 public:
145     virtual ~ClassMember()
146     { }
147
148     enum Visbility {
149         PUBLIC,
150         PROTECTED,
151         PRIVATE
152     };
153     Visbility visibility;
154 };
155
156 class Function : public ClassMember {
157 public:
158     enum FuncType {
159         FUNCTION,
160         CONSTRUCTOR,
161         DESTRUCTOR
162     };
163     FuncType type;
164     std::string docu_comment;
165     std::string name;
166     Type return_type;
167     std::vector<Parameter> parameters;
168 };
169
170 class Field : public ClassMember {
171 public:
172     Field()
173     {
174         has_const_value = false;
175     }
176     
177     Type* type;
178     std::string docu_comment;
179     std::string name;
180     bool has_const_value;
181
182     union {
183         float const_float_value;
184         int const_int_value;
185     };
186     std::string const_string_value;
187 };
188
189 class Class : public AtomicType {
190 public:
191     ~Class() {
192         for(std::vector<ClassMember*>::iterator i = members.begin();
193                 i != members.end(); ++i)
194             delete *i;
195     }
196     
197     std::vector<ClassMember*> members;
198     std::vector<Class*> super_classes;
199     std::vector<Class*> sub_classes;
200     std::string docu_comment;
201 };
202
203 class Namespace {
204 public:
205     Namespace() {
206         parent = 0;
207     }
208     virtual ~Namespace() {
209         for(std::vector<Function*>::iterator i = functions.begin();
210                 i != functions.end(); ++i)
211             delete *i;
212         for(std::vector<AtomicType*>::iterator i = types.begin();
213                 i != types.end(); ++i)
214             delete *i;
215         for(std::vector<Namespace*>::iterator i = namespaces.begin();
216                 i != namespaces.end(); ++i)
217             delete *i;
218     }
219     void add_type(AtomicType* type)
220     {
221         types.push_back(type);
222         type->parent = this;
223     }
224     void add_namespace(Namespace* ns)
225     {
226         namespaces.push_back(ns);
227         ns->parent = this;
228     }
229     AtomicType* _findType(const std::string& name, bool godown = false) {
230         for(std::vector<AtomicType*>::iterator i = types.begin();
231                 i != types.end(); ++i) {
232             AtomicType* type = *i;
233             if(type->name == name)
234                 return type;
235         }
236         if(godown && parent)
237             return parent->_findType(name, true);
238
239         return 0;
240     }
241
242     Namespace* _findNamespace(const std::string& name, bool godown = false) {
243         for(std::vector<Namespace*>::iterator i = namespaces.begin();
244                 i != namespaces.end(); ++i) {
245             Namespace* ns = *i;
246             if(ns->name == name)
247                 return ns;
248         }
249         if(godown && parent)
250             return parent->_findNamespace(name, true);
251
252         return 0;
253     }
254
255     Namespace* findNamespace(const std::string& name, bool godown = false) {
256         Namespace* ret = _findNamespace(name, godown);
257         if(!ret) {
258             std::ostringstream msg;
259             msg << "Couldn't find namespace '" << name << "'.";
260             throw std::runtime_error(msg.str());
261         }
262
263         return ret;
264     }
265                                                                              
266     std::vector<Function*> functions;
267     std::vector<Field*> fields;
268     std::vector<AtomicType*> types;
269     std::vector<Namespace*> namespaces;
270
271     Namespace* parent;
272     std::string name;
273 };
274
275 class CompilationUnit : public Namespace {
276 public:
277 };
278
279 #endif
280