- Made miniswig support HSQUIRRELVM arguments (and realized it was not needed
[supertux.git] / tools / miniswig / tree.h
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 name;
165     Type return_type;
166     std::vector<Parameter> parameters;
167 };
168
169 class Class : public AtomicType {
170 public:
171     ~Class() {
172         for(std::vector<ClassMember*>::iterator i = members.begin();
173                 i != members.end(); ++i)
174             delete *i;
175     }
176     
177     std::vector<ClassMember*> members;
178 };
179
180 class Namespace {
181 public:
182     Namespace() {
183         parent = 0;
184     }
185     virtual ~Namespace() {
186         for(std::vector<Function*>::iterator i = functions.begin();
187                 i != functions.end(); ++i)
188             delete *i;
189         for(std::vector<AtomicType*>::iterator i = types.begin();
190                 i != types.end(); ++i)
191             delete *i;
192         for(std::vector<Namespace*>::iterator i = namespaces.begin();
193                 i != namespaces.end(); ++i)
194             delete *i;
195     }
196     void add_type(AtomicType* type)
197     {
198         types.push_back(type);
199         type->parent = this;
200     }
201     void add_namespace(Namespace* ns)
202     {
203         namespaces.push_back(ns);
204         ns->parent = this;
205     }
206     AtomicType* _findType(const std::string& name, bool godown = false) {
207         for(std::vector<AtomicType*>::iterator i = types.begin();
208                 i != types.end(); ++i) {
209             AtomicType* type = *i;
210             if(type->name == name)
211                 return type;
212         }
213         if(godown && parent)
214             return parent->_findType(name, true);
215
216         return 0;
217     }
218
219     Namespace* _findNamespace(const std::string& name, bool godown = false) {
220         for(std::vector<Namespace*>::iterator i = namespaces.begin();
221                 i != namespaces.end(); ++i) {
222             Namespace* ns = *i;
223             if(ns->name == name)
224                 return ns;
225         }
226         if(godown && parent)
227             return parent->_findNamespace(name, true);
228
229         return 0;
230     }
231
232     Namespace* findNamespace(const std::string& name, bool godown = false) {
233         Namespace* ret = _findNamespace(name, godown);
234         if(!ret) {
235             std::ostringstream msg;
236             msg << "Couldn't find namespace '" << name << "'.";
237             throw std::runtime_error(msg.str());
238         }
239
240         return ret;
241     }
242                                                                              
243     std::vector<Function*> functions;
244     std::vector<AtomicType*> types;
245     std::vector<Namespace*> namespaces;
246
247     Namespace* parent;
248     std::string name;
249 };
250
251 class CompilationUnit : public Namespace {
252 public:
253 };
254
255 #endif
256