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