]> git.localhorst.tv Git - l2e.git/blob - src/loader/ParsedSource.cpp
more information in parsed source and output
[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 void ParsedSource::AddDeclaration(Declaration *d) {
21         map<string, Declaration *>::iterator i(declarations.find(d->Identifier()));
22         if (i != declarations.end()) {
23                 if (d->TypeName() != i->second->TypeName()) {
24                         throw runtime_error("invalid redeclaration of " + i->second->TypeName() + " " + d->Identifier());
25                 }
26         } else {
27                 declarations.insert(std::make_pair(d->Identifier(), d));
28         }
29 }
30
31 void ParsedSource::AddDefinition(Definition *d) {
32         map<string, Definition *>::iterator i(definitions.find(d->Identifier()));
33         if (i != definitions.end()) {
34                 throw runtime_error("redefinition of " + i->second->TypeName() + " " + d->Identifier());
35         } else {
36                 definitions.insert(std::make_pair(d->Identifier(), d));
37         }
38 }
39
40 void ParsedSource::ExportDeclaration(Declaration *d) {
41         AddDeclaration(d);
42         exports.insert(d->Identifier());
43 }
44
45 void ParsedSource::ExportIdentifier(const std::string &i) {
46         if (declarations.count(i)) {
47                 exports.insert(i);
48         } else {
49                 throw runtime_error("cannot export undeclared identifier " + i);
50         }
51 }
52
53
54 void Definition::SetValue(Literal *v) {
55         value = v;
56         isLiteral = true;
57 }
58
59 void Definition::SetValue(PropertyList *v) {
60         value = v;
61         isLiteral = false;
62 }
63
64 Literal *Definition::GetLiteral() {
65         if (isLiteral) {
66                 return (Literal *)value;
67         } else {
68                 throw runtime_error("tried to access properties as literal");
69         }
70 }
71
72 const Literal *Definition::GetLiteral() const {
73         if (isLiteral) {
74                 return (Literal *)value;
75         } else {
76                 throw runtime_error("tried to access properties as literal");
77         }
78 }
79
80 PropertyList *Definition::GetProperties() {
81         if (!isLiteral) {
82                 return (PropertyList *)value;
83         } else {
84                 throw runtime_error("tried to access literal value as property list");
85         }
86 }
87
88 const PropertyList *Definition::GetProperties() const {
89         if (!isLiteral) {
90                 return (PropertyList *)value;
91         } else {
92                 throw runtime_error("tried to access literal value as property list");
93         }
94 }
95
96
97 PropertyList::~PropertyList() {
98         for (map<string, Value *>::iterator i(props.begin()), end(props.end()); i != end; ++i) {
99                 delete i->second;
100         }
101 }
102
103
104 Literal::Literal(const vector<Value *> &v)
105 : props(0)
106 , values(v)
107 , i1(0), i2(0)
108 , i3(0), i4(0)
109 , b(false)
110 , type(ARRAY_VALUES) {
111
112 }
113
114 Literal::Literal(const std::vector<PropertyList *> &pls)
115 : props(0)
116 , propertyLists(pls)
117 , i1(0), i2(0)
118 , i3(0), i4(0)
119 , b(false)
120 , type(ARRAY_PROPS) {
121
122 }
123
124 Literal::Literal(bool b)
125 : props(0)
126 , i1(0), i2(0)
127 , i3(0), i4(0)
128 , b(b)
129 , type(BOOLEAN) {
130
131 }
132
133 Literal::Literal(int r, int g, int b, int a)
134 : props(0)
135 , i1(r), i2(g)
136 , i3(b), i4(a)
137 , b(false)
138 , type(COLOR) {
139
140 }
141
142 Literal::Literal(int number)
143 : props(0)
144 , i1(number), i2(0)
145 , i3(0), i4(0)
146 , b(false)
147 , type(NUMBER) {
148
149 }
150
151 Literal::Literal(const string &str)
152 : props(0)
153 , str(str)
154 , i1(0), i2(0)
155 , i3(0), i4(0)
156 , b(false)
157 , type(STRING) {
158
159 }
160
161 Literal::Literal(int x, int y)
162 : props(0)
163 , i1(x), i2(y)
164 , i3(0), i4(0)
165 , b(false)
166 , type(VECTOR) {
167
168 }
169
170 Literal::Literal(const string &typeName, PropertyList *properties)
171 : props(properties)
172 , str(typeName)
173 , i1(0), i2(0)
174 , i3(0), i4(0)
175 , b(false)
176 , type(OBJECT) {
177
178 }
179
180
181 const vector<Value *> &Literal::GetValues() const {
182         if (type == ARRAY_VALUES) {
183                 return values;
184         } else {
185                 throw runtime_error("tried to access values of non-array literal");
186         }
187 }
188
189 const vector<PropertyList *> &Literal::GetPropertyLists() const {
190         if (type == ARRAY_PROPS) {
191                 return propertyLists;
192         } else {
193                 throw runtime_error("tried to access property lists of non-array literal");
194         }
195 }
196
197 bool Literal::GetBoolean() const {
198         if (type == BOOLEAN) {
199                 return b;
200         } else {
201                 throw runtime_error("tried to access boolean value of non-boolean literal");
202         }
203 }
204
205 int Literal::GetRed() const {
206         if (type == COLOR) {
207                 return i1;
208         } else {
209                 throw runtime_error("tried to access red component of non-color literal");
210         }
211 }
212
213 int Literal::GetGreen() const {
214         if (type == COLOR) {
215                 return i2;
216         } else {
217                 throw runtime_error("tried to access green component of non-color literal");
218         }
219 }
220
221 int Literal::GetBlue() const {
222         if (type == COLOR) {
223                 return i3;
224         } else {
225                 throw runtime_error("tried to access blue component of non-color literal");
226         }
227 }
228
229 int Literal::GetAlpha() const {
230         if (type == COLOR) {
231                 return i4;
232         } else {
233                 throw runtime_error("tried to access alpha component of non-color literal");
234         }
235 }
236
237 int Literal::GetNumber() const {
238         if (type == NUMBER) {
239                 return i1;
240         } else {
241                 throw runtime_error("tried to access numerical value of non-number literal");
242         }
243 }
244
245 const string &Literal::GetString() const {
246         if (type == STRING) {
247                 return str;
248         } else {
249                 throw runtime_error("tried to access string value of non-color literal");
250         }
251 }
252
253 int Literal::GetX() const {
254         if (type == VECTOR) {
255                 return i1;
256         } else {
257                 throw runtime_error("tried to access x component of non-vector literal");
258         }
259 }
260
261 int Literal::GetY() const {
262         if (type == VECTOR) {
263                 return i2;
264         } else {
265                 throw runtime_error("tried to access y component of non-vector literal");
266         }
267 }
268
269 const string &Literal::GetTypeName() const {
270         if (type == OBJECT) {
271                 return str;
272         } else {
273                 throw runtime_error("tried to access type name of non-object literal");
274         }
275 }
276
277 const PropertyList *Literal::GetProperties() const {
278         if (type == OBJECT) {
279                 return props;
280         } else {
281                 throw runtime_error("tried to access properties of non-object literal");
282         }
283 }
284
285 }
286
287
288 namespace std {
289
290 ostream &operator <<(ostream &out, const loader::ParsedSource &source) {
291         out << "parsed source file" << endl;
292         out << "declared objects: " << endl;
293         for (map<string, loader::Declaration *>::const_iterator i(source.Declarations().begin()), end(source.Declarations().end()); i != end; ++i) {
294                 out << " - " << i->first << " of type " << i->second->TypeName() << endl;
295         }
296         out << "defined objects: " << endl;
297         for (map<string, loader::Definition *>::const_iterator i(source.Definitions().begin()), end(source.Definitions().end()); i != end; ++i) {
298                 out << " - " << i->first << " of type " << i->second->TypeName() << endl;
299                 if (i->second->HasLiteralValue()) {
300                         out << "     literal value: " << *i->second->GetLiteral() << endl;
301                 }
302         }
303         out << "exported objects: " << endl;
304         for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
305                 out << " - " << *i << endl;
306         }
307         return out;
308 }
309
310 ostream &operator <<(ostream &out, const loader::Literal &l) {
311         switch (l.GetType()) {
312                 case loader::Literal::ARRAY_VALUES:
313                         out << "array of values";
314                         break;
315                 case loader::Literal::ARRAY_PROPS:
316                         out << "array of property lists";
317                         break;
318                 case loader::Literal::BOOLEAN:
319                         out << "boolean, " << (l.GetBoolean() ? "true" : "false");
320                         break;
321                 case loader::Literal::COLOR:
322                         out << "color, (" << l.GetRed() << ',' << l.GetGreen() << ',' << l.GetBlue() << ',' << l.GetAlpha() << ')';
323                         break;
324                 case loader::Literal::NUMBER:
325                         out << "number, " << l.GetNumber();
326                         break;
327                 case loader::Literal::STRING:
328                         out << "string, \"" << l.GetString() << '"';
329                         break;
330                 case loader::Literal::VECTOR:
331                         out << "vector, <" << l.GetX() << ',' << l.GetY() << '>';
332                         break;
333                 case loader::Literal::OBJECT:
334                         out << "object of type " << l.GetTypeName();
335                         break;
336         }
337         return out;
338 }
339
340 }