b6c87fa6d1616e482109ea26b80fcd5449dbf3b8
[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 SQIntegerType : public AtomicType {
88 public:
89     SQIntegerType()
90     {
91         this->name = "SQInteger";
92         assert(_instance == 0);
93         _instance = this;
94     }
95     virtual ~SQIntegerType()
96     {
97         assert(_instance == this);
98         _instance = NULL;
99     }
100
101     static SQIntegerType* instance()
102     {
103         return _instance;
104     }
105 private:
106     static SQIntegerType* _instance;
107 };
108
109 class HSQUIRRELVMType : public AtomicType {
110 public:
111     HSQUIRRELVMType()
112     {
113         this->name = "HSQUIRRELVM";
114         assert(_instance == 0);
115         _instance = this;
116     }
117     virtual ~HSQUIRRELVMType()
118     {
119         assert(_instance == this);
120         _instance = NULL;
121     }
122
123     static HSQUIRRELVMType* instance()
124     {
125         return _instance;
126     }
127 private:
128     static HSQUIRRELVMType* _instance;
129 };
130
131 class StringType : public AtomicType {
132 public:
133     StringType()
134     {
135         this->name = "string";
136         assert(_instance == 0);
137         _instance = this;
138     }
139     virtual ~StringType()
140     {
141         assert(_instance == this);
142         _instance = 0;
143     }
144
145     static StringType* instance()
146     {
147         return _instance;
148     }
149
150     virtual void write_c(std::ostream& out)
151     {
152         out << "std::string";
153     }
154
155 private:
156     static StringType* _instance;
157 };
158
159 class Parameter {
160 public:
161     std::string name;
162     Type type;
163 };
164
165 class ClassMember {
166 public:
167     virtual ~ClassMember()
168     { }
169
170     enum Visibility {
171         PUBLIC,
172         PROTECTED,
173         PRIVATE
174     };
175     Visibility visibility;
176 };
177
178 class Function : public ClassMember {
179 public:
180     Function() {
181       type = FUNCTION;
182       suspend = false;
183       custom = false;
184     }
185
186     enum FuncType {
187         FUNCTION,
188         CONSTRUCTOR,
189         DESTRUCTOR
190     };
191     FuncType type;
192     /// function should suspend squirrel VM after execution
193     bool suspend;
194     /// a custom wrapper (just pass along HSQUIRRELVM)
195     bool custom;
196     std::string docu_comment;
197     std::string name;
198     Type return_type;
199     std::vector<Parameter> parameters;
200 };
201
202 class Field : public ClassMember {
203 public:
204     Field()
205     {
206         has_const_value = false;
207     }
208
209     Type* type;
210     std::string docu_comment;
211     std::string name;
212     bool has_const_value;
213
214     union {
215         float const_float_value;
216         int const_int_value;
217     };
218     std::string const_string_value;
219 };
220
221 class Class : public AtomicType {
222 public:
223     ~Class() {
224         for(std::vector<ClassMember*>::iterator i = members.begin();
225                 i != members.end(); ++i)
226             delete *i;
227     }
228
229     std::vector<ClassMember*> members;
230     std::vector<Class*> super_classes;
231     std::vector<Class*> sub_classes;
232     std::string docu_comment;
233 };
234
235 class Namespace {
236 public:
237     Namespace() {
238         parent = 0;
239     }
240     virtual ~Namespace() {
241         for(std::vector<Function*>::iterator i = functions.begin();
242                 i != functions.end(); ++i)
243             delete *i;
244         for(std::vector<AtomicType*>::iterator i = types.begin();
245                 i != types.end(); ++i)
246             delete *i;
247         for(std::vector<Namespace*>::iterator i = namespaces.begin();
248                 i != namespaces.end(); ++i)
249             delete *i;
250     }
251     void add_type(AtomicType* type)
252     {
253         types.push_back(type);
254         type->parent = this;
255     }
256     void add_namespace(Namespace* ns)
257     {
258         namespaces.push_back(ns);
259         ns->parent = this;
260     }
261     AtomicType* _findType(const std::string& name, bool godown = false) {
262         for(std::vector<AtomicType*>::iterator i = types.begin();
263                 i != types.end(); ++i) {
264             AtomicType* type = *i;
265             if(type->name == name)
266                 return type;
267         }
268         if(godown && parent)
269             return parent->_findType(name, true);
270
271         return 0;
272     }
273
274     Namespace* _findNamespace(const std::string& name, bool godown = false) {
275         for(std::vector<Namespace*>::iterator i = namespaces.begin();
276                 i != namespaces.end(); ++i) {
277             Namespace* ns = *i;
278             if(ns->name == name)
279                 return ns;
280         }
281         if(godown && parent)
282             return parent->_findNamespace(name, true);
283
284         return 0;
285     }
286
287     Namespace* findNamespace(const std::string& name, bool godown = false) {
288         Namespace* ret = _findNamespace(name, godown);
289         if(!ret) {
290             std::ostringstream msg;
291             msg << "Couldn't find namespace '" << name << "'.";
292             throw std::runtime_error(msg.str());
293         }
294
295         return ret;
296     }
297
298     std::vector<Function*> functions;
299     std::vector<Field*> fields;
300     std::vector<AtomicType*> types;
301     std::vector<Namespace*> namespaces;
302
303     Namespace* parent;
304     std::string name;
305 };
306
307 class CompilationUnit : public Namespace {
308 public:
309 };
310
311 #endif