allow custom wrapper 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 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     Function() {
159       type = FUNCTION;
160       suspend = false;
161       custom = false;
162     }
163   
164     enum FuncType {
165         FUNCTION,
166         CONSTRUCTOR,
167         DESTRUCTOR
168     };
169     FuncType type;
170     /// function should suspend squirrel VM after execution
171     bool suspend;
172     /// a custom wrapper (just pass along HSQUIRRELVM)
173     bool custom;
174     std::string docu_comment;
175     std::string name;
176     Type return_type;
177     std::vector<Parameter> parameters;
178 };
179
180 class Field : public ClassMember {
181 public:
182     Field()
183     {
184         has_const_value = false;
185     }
186     
187     Type* type;
188     std::string docu_comment;
189     std::string name;
190     bool has_const_value;
191
192     union {
193         float const_float_value;
194         int const_int_value;
195     };
196     std::string const_string_value;
197 };
198
199 class Class : public AtomicType {
200 public:
201     ~Class() {
202         for(std::vector<ClassMember*>::iterator i = members.begin();
203                 i != members.end(); ++i)
204             delete *i;
205     }
206     
207     std::vector<ClassMember*> members;
208     std::vector<Class*> super_classes;
209     std::vector<Class*> sub_classes;
210     std::string docu_comment;
211 };
212
213 class Namespace {
214 public:
215     Namespace() {
216         parent = 0;
217     }
218     virtual ~Namespace() {
219         for(std::vector<Function*>::iterator i = functions.begin();
220                 i != functions.end(); ++i)
221             delete *i;
222         for(std::vector<AtomicType*>::iterator i = types.begin();
223                 i != types.end(); ++i)
224             delete *i;
225         for(std::vector<Namespace*>::iterator i = namespaces.begin();
226                 i != namespaces.end(); ++i)
227             delete *i;
228     }
229     void add_type(AtomicType* type)
230     {
231         types.push_back(type);
232         type->parent = this;
233     }
234     void add_namespace(Namespace* ns)
235     {
236         namespaces.push_back(ns);
237         ns->parent = this;
238     }
239     AtomicType* _findType(const std::string& name, bool godown = false) {
240         for(std::vector<AtomicType*>::iterator i = types.begin();
241                 i != types.end(); ++i) {
242             AtomicType* type = *i;
243             if(type->name == name)
244                 return type;
245         }
246         if(godown && parent)
247             return parent->_findType(name, true);
248
249         return 0;
250     }
251
252     Namespace* _findNamespace(const std::string& name, bool godown = false) {
253         for(std::vector<Namespace*>::iterator i = namespaces.begin();
254                 i != namespaces.end(); ++i) {
255             Namespace* ns = *i;
256             if(ns->name == name)
257                 return ns;
258         }
259         if(godown && parent)
260             return parent->_findNamespace(name, true);
261
262         return 0;
263     }
264
265     Namespace* findNamespace(const std::string& name, bool godown = false) {
266         Namespace* ret = _findNamespace(name, godown);
267         if(!ret) {
268             std::ostringstream msg;
269             msg << "Couldn't find namespace '" << name << "'.";
270             throw std::runtime_error(msg.str());
271         }
272
273         return ret;
274     }
275                                                                              
276     std::vector<Function*> functions;
277     std::vector<Field*> fields;
278     std::vector<AtomicType*> types;
279     std::vector<Namespace*> namespaces;
280
281     Namespace* parent;
282     std::string name;
283 };
284
285 class CompilationUnit : public Namespace {
286 public:
287 };
288
289 #endif
290