more squirrel warning fixes
[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), _const(false), _static(false), pointer(0), ref(0)
52     { }
53
54     void write_c_type(std::ostream& out)
55     {
56         if(_static)
57             out << "static ";        
58         if(_const)
59             out << "const ";
60         atomic_type->write_c(out);
61         for(int i = 0; i < pointer; ++i)
62             out << "*";
63         for(int i = 0; i < ref; ++i)
64             out << "&";
65     }
66
67     bool is_void() const
68     {
69         if(atomic_type == &BasicType::VOID && pointer == 0)
70             return true;
71         return false;
72     }
73
74     AtomicType* atomic_type;
75     bool _const;
76     bool _static;
77     // number of '*' in the type declaration...
78     int pointer;
79     // number of '&' in the type declaration...
80     int ref;
81 };
82
83 class StringType : public AtomicType {
84 public:
85     StringType()
86     {
87         this->name = "string";
88         assert(_instance == 0);
89         _instance = this;
90     }
91     virtual ~StringType()
92     {
93         assert(_instance == this);
94         _instance = 0;
95     }
96
97     static StringType* instance()
98     {
99         return _instance;
100     }
101
102     virtual void write_c(std::ostream& out)
103     {
104         out << "std::string";
105     }
106
107 private:
108     static StringType* _instance;   
109 };
110
111 class Parameter {
112 public:
113     std::string name;
114     Type type;
115 };
116
117 class ClassMember {
118 public:
119     virtual ~ClassMember()
120     { }
121
122     enum Visbility {
123         PUBLIC,
124         PROTECTED,
125         PRIVATE
126     };
127     Visbility visibility;
128 };
129
130 class Function : public ClassMember {
131 public:
132     enum FuncType {
133         FUNCTION,
134         CONSTRUCTOR,
135         DESTRUCTOR
136     };
137     FuncType type;
138     std::string name;
139     Type return_type;
140     std::vector<Parameter> parameters;
141 };
142
143 class Class : public AtomicType {
144 public:
145     ~Class() {
146         for(std::vector<ClassMember*>::iterator i = members.begin();
147                 i != members.end(); ++i)
148             delete *i;
149     }
150     
151     std::vector<ClassMember*> members;
152 };
153
154 class Namespace {
155 public:
156     Namespace() {
157         parent = 0;
158     }
159     virtual ~Namespace() {
160         for(std::vector<Function*>::iterator i = functions.begin();
161                 i != functions.end(); ++i)
162             delete *i;
163         for(std::vector<AtomicType*>::iterator i = types.begin();
164                 i != types.end(); ++i)
165             delete *i;
166         for(std::vector<Namespace*>::iterator i = namespaces.begin();
167                 i != namespaces.end(); ++i)
168             delete *i;
169     }
170     void add_type(AtomicType* type)
171     {
172         types.push_back(type);
173         type->parent = this;
174     }
175     void add_namespace(Namespace* ns)
176     {
177         namespaces.push_back(ns);
178         ns->parent = this;
179     }
180     Namespace* _findNamespace(const std::string& name, bool godown = false) {
181         for(std::vector<Namespace*>::iterator i = namespaces.begin();
182                 i != namespaces.end(); ++i) {
183             Namespace* ns = *i;
184             if(ns->name == name)
185                 return ns;
186         }
187         if(godown && parent)
188             return parent->_findNamespace(name, true);
189
190         return 0;
191     }
192
193     Namespace* findNamespace(const std::string& name, bool godown = false) {
194         Namespace* ret = _findNamespace(name, godown);
195         if(!ret) {
196             std::ostringstream msg;
197             msg << "Couldn't find namespace '" << name << "'.";
198             throw std::runtime_error(msg.str());
199         }
200
201         return ret;
202     }
203                                                                              
204     std::vector<Function*> functions;
205     std::vector<AtomicType*> types;
206     std::vector<Namespace*> namespaces;
207
208     Namespace* parent;
209     std::string name;
210 };
211
212 class CompilationUnit : public Namespace {
213 public:
214 };
215
216 #endif
217