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