b6f85546670cbe5538439a13cb8e22d5e85e7f54
[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 StringType : public AtomicType {
88 public:
89     StringType()
90     {
91         this->name = "string";
92         assert(_instance == 0);
93         _instance = this;
94     }
95     virtual ~StringType()
96     {
97         assert(_instance == this);
98         _instance = 0;
99     }
100
101     static StringType* instance()
102     {
103         return _instance;
104     }
105
106     virtual void write_c(std::ostream& out)
107     {
108         out << "std::string";
109     }
110
111 private:
112     static StringType* _instance;   
113 };
114
115 class Parameter {
116 public:
117     std::string name;
118     Type type;
119 };
120
121 class ClassMember {
122 public:
123     virtual ~ClassMember()
124     { }
125
126     enum Visbility {
127         PUBLIC,
128         PROTECTED,
129         PRIVATE
130     };
131     Visbility visibility;
132 };
133
134 class Function : public ClassMember {
135 public:
136     enum FuncType {
137         FUNCTION,
138         CONSTRUCTOR,
139         DESTRUCTOR
140     };
141     FuncType type;
142     std::string name;
143     Type return_type;
144     std::vector<Parameter> parameters;
145 };
146
147 class Class : public AtomicType {
148 public:
149     ~Class() {
150         for(std::vector<ClassMember*>::iterator i = members.begin();
151                 i != members.end(); ++i)
152             delete *i;
153     }
154     
155     std::vector<ClassMember*> members;
156 };
157
158 class Namespace {
159 public:
160     Namespace() {
161         parent = 0;
162     }
163     virtual ~Namespace() {
164         for(std::vector<Function*>::iterator i = functions.begin();
165                 i != functions.end(); ++i)
166             delete *i;
167         for(std::vector<AtomicType*>::iterator i = types.begin();
168                 i != types.end(); ++i)
169             delete *i;
170         for(std::vector<Namespace*>::iterator i = namespaces.begin();
171                 i != namespaces.end(); ++i)
172             delete *i;
173     }
174     void add_type(AtomicType* type)
175     {
176         types.push_back(type);
177         type->parent = this;
178     }
179     void add_namespace(Namespace* ns)
180     {
181         namespaces.push_back(ns);
182         ns->parent = this;
183     }
184     Namespace* _findNamespace(const std::string& name, bool godown = false) {
185         for(std::vector<Namespace*>::iterator i = namespaces.begin();
186                 i != namespaces.end(); ++i) {
187             Namespace* ns = *i;
188             if(ns->name == name)
189                 return ns;
190         }
191         if(godown && parent)
192             return parent->_findNamespace(name, true);
193
194         return 0;
195     }
196
197     Namespace* findNamespace(const std::string& name, bool godown = false) {
198         Namespace* ret = _findNamespace(name, godown);
199         if(!ret) {
200             std::ostringstream msg;
201             msg << "Couldn't find namespace '" << name << "'.";
202             throw std::runtime_error(msg.str());
203         }
204
205         return ret;
206     }
207                                                                              
208     std::vector<Function*> functions;
209     std::vector<AtomicType*> types;
210     std::vector<Namespace*> namespaces;
211
212     Namespace* parent;
213     std::string name;
214 };
215
216 class CompilationUnit : public Namespace {
217 public:
218 };
219
220 #endif
221