]> git.localhorst.tv Git - l2e.git/blob - src/loader/ParsedSource.cpp
13b1262f93410de52ce0f522bfb538f66531fa6a
[l2e.git] / src / loader / ParsedSource.cpp
1 /*
2  * ParsedSource.cpp
3  *
4  *  Created on: Aug 26, 2012
5  *      Author: holy
6  */
7
8 #include "ParsedSource.h"
9
10 #include <ostream>
11 #include <stdexcept>
12
13 using std::map;
14 using std::runtime_error;
15 using std::string;
16 using std::vector;
17
18 namespace loader {
19
20 ParsedSource::~ParsedSource() {
21         for (map<string, Declaration *>::const_iterator i(declarations.begin()), end(declarations.end()); i != end; ++i) {
22                 delete i->second;
23         }
24 }
25
26 void ParsedSource::AddDeclaration(Declaration *d) {
27         map<string, Declaration *>::iterator i(declarations.find(d->Identifier()));
28         if (i != declarations.end()) {
29                 if (d->TypeName() != i->second->TypeName()) {
30                         throw runtime_error("invalid redeclaration of " + i->second->TypeName() + " " + d->Identifier());
31                 }
32         } else {
33                 declarations.insert(std::make_pair(d->Identifier(), d));
34         }
35 }
36
37 void ParsedSource::AddDefinition(Definition *d) {
38         map<string, Definition *>::iterator i(definitions.find(d->Identifier()));
39         if (i != definitions.end()) {
40                 throw runtime_error("redefinition of " + i->second->TypeName() + " " + d->Identifier());
41         } else {
42                 definitions.insert(std::make_pair(d->Identifier(), d));
43         }
44 }
45
46 void ParsedSource::ExportDeclaration(Declaration *d) {
47         AddDeclaration(d);
48         exports.insert(d->Identifier());
49 }
50
51 void ParsedSource::ExportIdentifier(const std::string &i) {
52         if (declarations.count(i)) {
53                 exports.insert(i);
54         } else {
55                 throw runtime_error("cannot export undeclared identifier " + i);
56         }
57 }
58
59
60 bool ParsedSource::IsDeclared(const std::string &name) const {
61         return declarations.count(name);
62 }
63
64 Declaration &ParsedSource::GetDeclaration(const std::string &name) {
65         map<string, Declaration *>::const_iterator i(declarations.find(name));
66         if (i != declarations.end()) {
67                 return *i->second;
68         } else {
69                 throw runtime_error("undeclared identifier " + name);
70         }
71 }
72
73 const Declaration &ParsedSource::GetDeclaration(const std::string &name) const {
74         map<string, Declaration *>::const_iterator i(declarations.find(name));
75         if (i != declarations.end()) {
76                 return *i->second;
77         } else {
78                 throw runtime_error("undeclared identifier " + name);
79         }
80 }
81
82 bool ParsedSource::IsDefined(const std::string &name) const {
83         return definitions.count(name);
84 }
85
86 Definition &ParsedSource::GetDefinition(const std::string &name) {
87         map<string, Definition *>::const_iterator i(definitions.find(name));
88         if (i != definitions.end()) {
89                 return *i->second;
90         } else {
91                 throw runtime_error("undefined identifier " + name);
92         }
93 }
94
95 const Definition &ParsedSource::GetDefinition(const std::string &name) const {
96         map<string, Definition *>::const_iterator i(definitions.find(name));
97         if (i != definitions.end()) {
98                 return *i->second;
99         } else {
100                 throw runtime_error("undefined identifier " + name);
101         }
102 }
103
104
105 Definition::~Definition() {
106         if (isLiteral) {
107                 delete reinterpret_cast<Literal *>(value);
108         } else {
109                 delete reinterpret_cast<PropertyList *>(value);
110         }
111 }
112
113 void Definition::SetValue(Literal *v) {
114         value = v;
115         isLiteral = true;
116 }
117
118 void Definition::SetValue(PropertyList *v) {
119         value = v;
120         isLiteral = false;
121 }
122
123 Literal *Definition::GetLiteral() {
124         if (isLiteral) {
125                 return reinterpret_cast<Literal *>(value);
126         } else {
127                 throw runtime_error("tried to access properties as literal");
128         }
129 }
130
131 const Literal *Definition::GetLiteral() const {
132         if (isLiteral) {
133                 return reinterpret_cast<Literal *>(value);
134         } else {
135                 throw runtime_error("tried to access properties as literal");
136         }
137 }
138
139 PropertyList *Definition::GetProperties() {
140         if (!isLiteral) {
141                 return reinterpret_cast<PropertyList *>(value);
142         } else {
143                 throw runtime_error("tried to access literal value as property list");
144         }
145 }
146
147 const PropertyList *Definition::GetProperties() const {
148         if (!isLiteral) {
149                 return reinterpret_cast<PropertyList *>(value);
150         } else if (GetLiteral()->GetType() == Literal::OBJECT) {
151                 return GetLiteral()->GetProperties();
152         } else {
153                 throw runtime_error("tried to access literal value as property list");
154         }
155 }
156
157
158 PropertyList::~PropertyList() {
159         for (map<string, Value *>::iterator i(props.begin()), end(props.end()); i != end; ++i) {
160                 delete i->second;
161         }
162 }
163
164
165 Literal::Literal(const vector<Value *> &v)
166 : props(0)
167 , values(v)
168 , i1(0), i2(0)
169 , i3(0), i4(0)
170 , b(false)
171 , type(ARRAY_VALUES) {
172
173 }
174
175 Literal::Literal(const std::vector<PropertyList *> &pls)
176 : props(0)
177 , propertyLists(pls)
178 , i1(0), i2(0)
179 , i3(0), i4(0)
180 , b(false)
181 , type(ARRAY_PROPS) {
182
183 }
184
185 Literal::Literal(bool b)
186 : props(0)
187 , i1(0), i2(0)
188 , i3(0), i4(0)
189 , b(b)
190 , type(BOOLEAN) {
191
192 }
193
194 Literal::Literal(int r, int g, int b, int a)
195 : props(0)
196 , i1(r), i2(g)
197 , i3(b), i4(a)
198 , b(false)
199 , type(COLOR) {
200
201 }
202
203 Literal::Literal(int number)
204 : props(0)
205 , i1(number), i2(0)
206 , i3(0), i4(0)
207 , b(false)
208 , type(NUMBER) {
209
210 }
211
212 Literal::Literal(const string &str)
213 : props(0)
214 , str(str)
215 , i1(0), i2(0)
216 , i3(0), i4(0)
217 , b(false)
218 , type(STRING) {
219
220 }
221
222 Literal::Literal(int x, int y)
223 : props(0)
224 , i1(x), i2(y)
225 , i3(0), i4(0)
226 , b(false)
227 , type(VECTOR) {
228
229 }
230
231 Literal::Literal(const string &typeName, PropertyList *properties)
232 : props(properties)
233 , str(typeName)
234 , i1(0), i2(0)
235 , i3(0), i4(0)
236 , b(false)
237 , type(OBJECT) {
238
239 }
240
241 Literal::~Literal() {
242         switch (type) {
243                 case ARRAY_VALUES:
244                         for (vector<Value *>::const_iterator i(values.begin()), end(values.end()); i != end; ++i) {
245                                 delete *i;
246                         }
247                         break;
248                 case ARRAY_PROPS:
249                         for (vector<PropertyList *>::const_iterator i(propertyLists.begin()), end(propertyLists.end()); i != end; ++i) {
250                                 delete *i;
251                         }
252                         break;
253                 case OBJECT:
254                         delete props;
255                         break;
256                 default:
257                         break;
258         }
259 }
260
261
262 const vector<Value *> &Literal::GetValues() const {
263         if (type == ARRAY_VALUES) {
264                 return values;
265         } else {
266                 throw runtime_error("tried to access values of non-array literal");
267         }
268 }
269
270 const vector<PropertyList *> &Literal::GetPropertyLists() const {
271         if (type == ARRAY_PROPS) {
272                 return propertyLists;
273         } else {
274                 throw runtime_error("tried to access property lists of non-array literal");
275         }
276 }
277
278 bool Literal::GetBoolean() const {
279         if (type == BOOLEAN) {
280                 return b;
281         } else {
282                 throw runtime_error("tried to access boolean value of non-boolean literal");
283         }
284 }
285
286 int Literal::GetRed() const {
287         if (type == COLOR) {
288                 return i1;
289         } else {
290                 throw runtime_error("tried to access red component of non-color literal");
291         }
292 }
293
294 int Literal::GetGreen() const {
295         if (type == COLOR) {
296                 return i2;
297         } else {
298                 throw runtime_error("tried to access green component of non-color literal");
299         }
300 }
301
302 int Literal::GetBlue() const {
303         if (type == COLOR) {
304                 return i3;
305         } else {
306                 throw runtime_error("tried to access blue component of non-color literal");
307         }
308 }
309
310 int Literal::GetAlpha() const {
311         if (type == COLOR) {
312                 return i4;
313         } else {
314                 throw runtime_error("tried to access alpha component of non-color literal");
315         }
316 }
317
318 int Literal::GetNumber() const {
319         if (type == NUMBER) {
320                 return i1;
321         } else {
322                 throw runtime_error("tried to access numerical value of non-number literal");
323         }
324 }
325
326 const string &Literal::GetString() const {
327         if (type == STRING) {
328                 return str;
329         } else {
330                 throw runtime_error("tried to access string value of non-color literal");
331         }
332 }
333
334 int Literal::GetX() const {
335         if (type == VECTOR) {
336                 return i1;
337         } else {
338                 throw runtime_error("tried to access x component of non-vector literal");
339         }
340 }
341
342 int Literal::GetY() const {
343         if (type == VECTOR) {
344                 return i2;
345         } else {
346                 throw runtime_error("tried to access y component of non-vector literal");
347         }
348 }
349
350 const string &Literal::GetTypeName() const {
351         if (type == OBJECT) {
352                 return str;
353         } else {
354                 throw runtime_error("tried to access type name of non-object literal");
355         }
356 }
357
358 const PropertyList *Literal::GetProperties() const {
359         if (type == OBJECT) {
360                 return props;
361         } else {
362                 throw runtime_error("tried to access properties of non-object literal");
363         }
364 }
365
366
367 Value::~Value() {
368         if (isLiteral) {
369                 delete literal;
370         }
371 }
372
373 const Literal &Value::GetLiteral() const {
374         if (isLiteral) {
375                 return *literal;
376         } else {
377                 throw runtime_error("tried to access literal of identifier value");
378         }
379 }
380
381 const std::string &Value::GetIdentifier() const {
382         if (!isLiteral) {
383                 return identifier;
384         } else {
385                 throw runtime_error("tried to access identifier of literal value");
386         }
387 }
388
389 }
390
391
392 namespace std {
393
394 ostream &operator <<(ostream &out, const loader::ParsedSource &source) {
395         out << "parsed source file" << endl;
396         out << "declared objects: " << endl;
397         for (map<string, loader::Declaration *>::const_iterator i(source.Declarations().begin()), end(source.Declarations().end()); i != end; ++i) {
398                 out << " - " << i->first << " of type " << i->second->TypeName() << endl;
399         }
400         out << "defined objects: " << endl;
401         for (map<string, loader::Definition *>::const_iterator i(source.Definitions().begin()), end(source.Definitions().end()); i != end; ++i) {
402                 out << " - " << i->first << " of type " << i->second->TypeName() << endl;
403                 if (i->second->HasLiteralValue()) {
404                         out << "     literal value: " << *i->second->GetLiteral() << endl;
405                 }
406         }
407         out << "exported objects: " << endl;
408         for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
409                 out << " - " << *i << endl;
410         }
411         return out;
412 }
413
414 ostream &operator <<(ostream &out, const loader::Literal &l) {
415         switch (l.GetType()) {
416                 case loader::Literal::ARRAY_VALUES:
417                         out << "array of values";
418                         break;
419                 case loader::Literal::ARRAY_PROPS:
420                         out << "array of property lists";
421                         break;
422                 case loader::Literal::BOOLEAN:
423                         out << "boolean, " << (l.GetBoolean() ? "true" : "false");
424                         break;
425                 case loader::Literal::COLOR:
426                         out << "color, (" << l.GetRed() << ',' << l.GetGreen() << ',' << l.GetBlue() << ',' << l.GetAlpha() << ')';
427                         break;
428                 case loader::Literal::NUMBER:
429                         out << "number, " << l.GetNumber();
430                         break;
431                 case loader::Literal::STRING:
432                         out << "string, \"" << l.GetString() << '"';
433                         break;
434                 case loader::Literal::VECTOR:
435                         out << "vector, <" << l.GetX() << ',' << l.GetY() << '>';
436                         break;
437                 case loader::Literal::OBJECT:
438                         out << "object of type " << l.GetTypeName();
439                         break;
440         }
441         return out;
442 }
443
444 }