Added type checking for __custom functions
[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 parameter_spec;
197     std::string docu_comment;
198     std::string name;
199     Type return_type;
200     std::vector<Parameter> parameters;
201 };
202
203 class Field : public ClassMember {
204 public:
205     Field()
206     {
207         has_const_value = false;
208     }
209
210     Type* type;
211     std::string docu_comment;
212     std::string name;
213     bool has_const_value;
214
215     union {
216         float const_float_value;
217         int const_int_value;
218     };
219     std::string const_string_value;
220 };
221
222 class Class : public AtomicType {
223 public:
224     ~Class() {
225         for(std::vector<ClassMember*>::iterator i = members.begin();
226                 i != members.end(); ++i)
227             delete *i;
228     }
229
230     std::vector<ClassMember*> members;
231     std::vector<Class*> super_classes;
232     std::vector<Class*> sub_classes;
233     std::string docu_comment;
234 };
235
236 class Namespace {
237 public:
238     Namespace() {
239         parent = 0;
240     }
241     virtual ~Namespace() {
242         for(std::vector<Function*>::iterator i = functions.begin();
243                 i != functions.end(); ++i)
244             delete *i;
245         for(std::vector<AtomicType*>::iterator i = types.begin();
246                 i != types.end(); ++i)
247             delete *i;
248         for(std::vector<Namespace*>::iterator i = namespaces.begin();
249                 i != namespaces.end(); ++i)
250             delete *i;
251     }
252     void add_type(AtomicType* type)
253     {
254         types.push_back(type);
255         type->parent = this;
256     }
257     void add_namespace(Namespace* ns)
258     {
259         namespaces.push_back(ns);
260         ns->parent = this;
261     }
262     AtomicType* _findType(const std::string& name, bool godown = false) {
263         for(std::vector<AtomicType*>::iterator i = types.begin();
264                 i != types.end(); ++i) {
265             AtomicType* type = *i;
266             if(type->name == name)
267                 return type;
268         }
269         if(godown && parent)
270             return parent->_findType(name, true);
271
272         return 0;
273     }
274
275     Namespace* _findNamespace(const std::string& name, bool godown = false) {
276         for(std::vector<Namespace*>::iterator i = namespaces.begin();
277                 i != namespaces.end(); ++i) {
278             Namespace* ns = *i;
279             if(ns->name == name)
280                 return ns;
281         }
282         if(godown && parent)
283             return parent->_findNamespace(name, true);
284
285         return 0;
286     }
287
288     Namespace* findNamespace(const std::string& name, bool godown = false) {
289         Namespace* ret = _findNamespace(name, godown);
290         if(!ret) {
291             std::ostringstream msg;
292             msg << "Couldn't find namespace '" << name << "'.";
293             throw std::runtime_error(msg.str());
294         }
295
296         return ret;
297     }
298
299     std::vector<Function*> functions;
300     std::vector<Field*> fields;
301     std::vector<AtomicType*> types;
302     std::vector<Namespace*> namespaces;
303
304     Namespace* parent;
305     std::string name;
306 };
307
308 class CompilationUnit : public Namespace {
309 public:
310 };
311
312 #endif