4 * Created on: Aug 26, 2012
8 #include "ParsedSource.h"
14 using std::runtime_error;
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());
27 declarations.insert(std::make_pair(d->Identifier(), d));
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());
36 definitions.insert(std::make_pair(d->Identifier(), d));
40 void ParsedSource::ExportDeclaration(Declaration *d) {
42 exports.insert(d->Identifier());
45 void ParsedSource::ExportIdentifier(const std::string &i) {
46 if (declarations.count(i)) {
49 throw runtime_error("cannot export undeclared identifier " + i);
54 bool ParsedSource::IsDeclared(const std::string &name) const {
55 return declarations.count(name);
58 Declaration &ParsedSource::GetDeclaration(const std::string &name) {
59 map<string, Declaration *>::const_iterator i(declarations.find(name));
60 if (i != declarations.end()) {
63 throw runtime_error("undeclared identifier " + name);
67 const Declaration &ParsedSource::GetDeclaration(const std::string &name) const {
68 map<string, Declaration *>::const_iterator i(declarations.find(name));
69 if (i != declarations.end()) {
72 throw runtime_error("undeclared identifier " + name);
76 bool ParsedSource::IsDefined(const std::string &name) const {
77 return definitions.count(name);
80 Definition &ParsedSource::GetDefinition(const std::string &name) {
81 map<string, Definition *>::const_iterator i(definitions.find(name));
82 if (i != definitions.end()) {
85 throw runtime_error("undefined identifier " + name);
89 const Definition &ParsedSource::GetDefinition(const std::string &name) const {
90 map<string, Definition *>::const_iterator i(definitions.find(name));
91 if (i != definitions.end()) {
94 throw runtime_error("undefined identifier " + name);
99 void Definition::SetValue(Literal *v) {
104 void Definition::SetValue(PropertyList *v) {
109 Literal *Definition::GetLiteral() {
111 return (Literal *)value;
113 throw runtime_error("tried to access properties as literal");
117 const Literal *Definition::GetLiteral() const {
119 return (Literal *)value;
121 throw runtime_error("tried to access properties as literal");
125 PropertyList *Definition::GetProperties() {
127 return (PropertyList *)value;
129 throw runtime_error("tried to access literal value as property list");
133 const PropertyList *Definition::GetProperties() const {
135 return (PropertyList *)value;
137 throw runtime_error("tried to access literal value as property list");
142 PropertyList::~PropertyList() {
143 for (map<string, Value *>::iterator i(props.begin()), end(props.end()); i != end; ++i) {
149 Literal::Literal(const vector<Value *> &v)
155 , type(ARRAY_VALUES) {
159 Literal::Literal(const std::vector<PropertyList *> &pls)
165 , type(ARRAY_PROPS) {
169 Literal::Literal(bool b)
178 Literal::Literal(int r, int g, int b, int a)
187 Literal::Literal(int number)
196 Literal::Literal(const string &str)
206 Literal::Literal(int x, int y)
215 Literal::Literal(const string &typeName, PropertyList *properties)
226 const vector<Value *> &Literal::GetValues() const {
227 if (type == ARRAY_VALUES) {
230 throw runtime_error("tried to access values of non-array literal");
234 const vector<PropertyList *> &Literal::GetPropertyLists() const {
235 if (type == ARRAY_PROPS) {
236 return propertyLists;
238 throw runtime_error("tried to access property lists of non-array literal");
242 bool Literal::GetBoolean() const {
243 if (type == BOOLEAN) {
246 throw runtime_error("tried to access boolean value of non-boolean literal");
250 int Literal::GetRed() const {
254 throw runtime_error("tried to access red component of non-color literal");
258 int Literal::GetGreen() const {
262 throw runtime_error("tried to access green component of non-color literal");
266 int Literal::GetBlue() const {
270 throw runtime_error("tried to access blue component of non-color literal");
274 int Literal::GetAlpha() const {
278 throw runtime_error("tried to access alpha component of non-color literal");
282 int Literal::GetNumber() const {
283 if (type == NUMBER) {
286 throw runtime_error("tried to access numerical value of non-number literal");
290 const string &Literal::GetString() const {
291 if (type == STRING) {
294 throw runtime_error("tried to access string value of non-color literal");
298 int Literal::GetX() const {
299 if (type == VECTOR) {
302 throw runtime_error("tried to access x component of non-vector literal");
306 int Literal::GetY() const {
307 if (type == VECTOR) {
310 throw runtime_error("tried to access y component of non-vector literal");
314 const string &Literal::GetTypeName() const {
315 if (type == OBJECT) {
318 throw runtime_error("tried to access type name of non-object literal");
322 const PropertyList *Literal::GetProperties() const {
323 if (type == OBJECT) {
326 throw runtime_error("tried to access properties of non-object literal");
331 const Literal &Value::GetLiteral() const {
335 throw runtime_error("tried to access literal of identifier value");
339 const std::string &Value::GetIdentifier() const {
343 throw runtime_error("tried to access identifier of literal value");
352 ostream &operator <<(ostream &out, const loader::ParsedSource &source) {
353 out << "parsed source file" << endl;
354 out << "declared objects: " << endl;
355 for (map<string, loader::Declaration *>::const_iterator i(source.Declarations().begin()), end(source.Declarations().end()); i != end; ++i) {
356 out << " - " << i->first << " of type " << i->second->TypeName() << endl;
358 out << "defined objects: " << endl;
359 for (map<string, loader::Definition *>::const_iterator i(source.Definitions().begin()), end(source.Definitions().end()); i != end; ++i) {
360 out << " - " << i->first << " of type " << i->second->TypeName() << endl;
361 if (i->second->HasLiteralValue()) {
362 out << " literal value: " << *i->second->GetLiteral() << endl;
365 out << "exported objects: " << endl;
366 for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
367 out << " - " << *i << endl;
372 ostream &operator <<(ostream &out, const loader::Literal &l) {
373 switch (l.GetType()) {
374 case loader::Literal::ARRAY_VALUES:
375 out << "array of values";
377 case loader::Literal::ARRAY_PROPS:
378 out << "array of property lists";
380 case loader::Literal::BOOLEAN:
381 out << "boolean, " << (l.GetBoolean() ? "true" : "false");
383 case loader::Literal::COLOR:
384 out << "color, (" << l.GetRed() << ',' << l.GetGreen() << ',' << l.GetBlue() << ',' << l.GetAlpha() << ')';
386 case loader::Literal::NUMBER:
387 out << "number, " << l.GetNumber();
389 case loader::Literal::STRING:
390 out << "string, \"" << l.GetString() << '"';
392 case loader::Literal::VECTOR:
393 out << "vector, <" << l.GetX() << ',' << l.GetY() << '>';
395 case loader::Literal::OBJECT:
396 out << "object of type " << l.GetTypeName();