4 * Created on: Aug 26, 2012
8 #include "ParsedSource.h"
16 using std::runtime_error;
22 ParsedSource::~ParsedSource() {
23 for (map<string, Declaration *>::const_iterator i(declarations.begin()), end(declarations.end()); i != end; ++i) {
28 void ParsedSource::AddDeclaration(Declaration *d) {
29 map<string, Declaration *>::iterator i(declarations.find(d->Identifier()));
30 if (i != declarations.end()) {
31 if (d->TypeName() != i->second->TypeName()) {
32 throw runtime_error("invalid redeclaration of " + i->second->TypeName() + " " + d->Identifier());
35 declarations.insert(std::make_pair(d->Identifier(), d));
39 void ParsedSource::AddDefinition(Definition *d) {
40 map<string, Definition *>::iterator i(definitions.find(d->Identifier()));
41 if (i != definitions.end()) {
42 throw runtime_error("redefinition of " + i->second->TypeName() + " " + d->Identifier());
44 definitions.insert(std::make_pair(d->Identifier(), d));
48 void ParsedSource::ExportDeclaration(Declaration *d) {
50 exports.insert(d->Identifier());
53 void ParsedSource::ExportIdentifier(const std::string &i) {
54 if (declarations.count(i)) {
57 throw runtime_error("cannot export undeclared identifier " + i);
62 bool ParsedSource::IsDeclared(const std::string &name) const {
63 return declarations.count(name);
66 Declaration &ParsedSource::GetDeclaration(const std::string &name) {
67 map<string, Declaration *>::const_iterator i(declarations.find(name));
68 if (i != declarations.end()) {
71 throw runtime_error("undeclared identifier " + name);
75 const Declaration &ParsedSource::GetDeclaration(const std::string &name) const {
76 map<string, Declaration *>::const_iterator i(declarations.find(name));
77 if (i != declarations.end()) {
80 throw runtime_error("undeclared identifier " + name);
84 bool ParsedSource::IsDefined(const std::string &name) const {
85 return definitions.count(name);
88 Definition &ParsedSource::GetDefinition(const std::string &name) {
89 map<string, Definition *>::const_iterator i(definitions.find(name));
90 if (i != definitions.end()) {
93 string msg("undefined identifier " + name);
94 map<string, Declaration *>::const_iterator i(declarations.find(name));
95 if (i != declarations.end()) {
96 msg += ", declared as " + i->second->TypeName();
98 msg += ", not declared";
100 throw runtime_error(msg);
104 const Definition &ParsedSource::GetDefinition(const std::string &name) const {
105 map<string, Definition *>::const_iterator i(definitions.find(name));
106 if (i != definitions.end()) {
109 string msg("undefined identifier " + name);
110 map<string, Declaration *>::const_iterator i(declarations.find(name));
111 if (i != declarations.end()) {
112 msg += ", declared as " + i->second->TypeName();
114 msg += ", not declared";
116 throw runtime_error(msg);
120 void ParsedSource::WriteHeader(std::ostream &out) const {
121 for (std::set<string>::const_iterator i(exports.begin()), end(exports.end()); i != end; ++i) {
122 out << GetDeclaration(*i).TypeName() << ' ' << *i << std::endl;
127 Definition::~Definition() {
129 delete reinterpret_cast<Literal *>(value);
131 delete reinterpret_cast<PropertyList *>(value);
135 void Definition::SetValue(Literal *v) {
140 void Definition::SetValue(PropertyList *v) {
145 Literal *Definition::GetLiteral() {
147 return reinterpret_cast<Literal *>(value);
149 throw runtime_error("tried to access properties as literal");
153 const Literal *Definition::GetLiteral() const {
155 return reinterpret_cast<Literal *>(value);
157 throw runtime_error("tried to access properties as literal");
161 PropertyList *Definition::GetProperties() {
163 return reinterpret_cast<PropertyList *>(value);
165 throw runtime_error("tried to access literal value as property list");
169 const PropertyList *Definition::GetProperties() const {
171 return reinterpret_cast<PropertyList *>(value);
172 } else if (GetLiteral()->GetType() == Literal::OBJECT) {
173 return GetLiteral()->GetProperties();
175 throw runtime_error("tried to access literal value as property list");
180 PropertyList::~PropertyList() {
181 for (map<string, Value *>::iterator i(props.begin()), end(props.end()); i != end; ++i) {
187 Literal::Literal(const vector<Value *> &v)
193 , type(ARRAY_VALUES) {
195 typeName = v.front()->GetLiteral().GetTypeName();
199 Literal::Literal(const string &typeName, const vector<PropertyList *> &pls)
206 , type(ARRAY_PROPS) {
210 Literal::Literal(bool b)
212 , typeName("Boolean")
220 Literal::Literal(int r, int g, int b, int a)
230 Literal::Literal(int number)
240 Literal::Literal(const string &dir, const string &path)
243 , str(CatPath(dir, path))
251 Literal::Literal(const string &str)
262 Literal::Literal(int x, int y)
272 Literal::Literal(const string &typeName, PropertyList *properties)
282 Literal::Literal(const vector<ScriptToken *> &s)
292 Literal::~Literal() {
295 for (vector<Value *>::const_iterator i(values.begin()), end(values.end()); i != end; ++i) {
300 for (vector<PropertyList *>::const_iterator i(propertyLists.begin()), end(propertyLists.end()); i != end; ++i) {
308 for (vector<ScriptToken *>::const_iterator i(script.begin()), end(script.end()); i != end; ++i) {
318 const vector<Value *> &Literal::GetValues() const {
319 if (type == ARRAY_VALUES) {
322 throw runtime_error("tried to access values of non-array literal");
326 const vector<PropertyList *> &Literal::GetPropertyLists() const {
327 if (type == ARRAY_PROPS) {
328 return propertyLists;
330 throw runtime_error("tried to access property lists of non-array literal");
334 bool Literal::GetBoolean() const {
335 if (type == BOOLEAN) {
338 throw runtime_error("tried to access boolean value of non-boolean literal");
342 int Literal::GetRed() const {
346 throw runtime_error("tried to access red component of non-color literal");
350 int Literal::GetGreen() const {
354 throw runtime_error("tried to access green component of non-color literal");
358 int Literal::GetBlue() const {
362 throw runtime_error("tried to access blue component of non-color literal");
366 int Literal::GetAlpha() const {
370 throw runtime_error("tried to access alpha component of non-color literal");
374 int Literal::GetNumber() const {
375 if (type == NUMBER) {
378 throw runtime_error("tried to access numerical value of non-number literal");
382 const string &Literal::GetString() const {
383 if (type == STRING) {
386 throw runtime_error("tried to access string value of non-color literal");
390 int Literal::GetX() const {
391 if (type == VECTOR) {
394 throw runtime_error("tried to access x component of non-vector literal");
398 int Literal::GetY() const {
399 if (type == VECTOR) {
402 throw runtime_error("tried to access y component of non-vector literal");
406 const string &Literal::GetTypeName() const {
410 const PropertyList *Literal::GetProperties() const {
411 if (type == OBJECT) {
414 throw runtime_error("tried to access properties of non-object literal");
418 const vector<ScriptToken *> &Literal::GetScript() const {
419 if (type == SCRIPT) {
422 throw runtime_error("tried to access script of non-script literal");
433 const Literal &Value::GetLiteral() const {
437 throw runtime_error("tried to access literal of identifier value");
441 const std::string &Value::GetIdentifier() const {
445 throw runtime_error("tried to access identifier of literal value");
450 ScriptToken::ScriptToken(const string &s, Type t)
454 if (type == LITERAL) {
455 throw runtime_error("cannot create script literal without literal");
459 ScriptToken::ScriptToken(Literal *l)
464 throw runtime_error("cannot create script literal without literal");
468 ScriptToken::~ScriptToken() {
472 const string &ScriptToken::RegisterName() const {
473 if (type == REGISTER) {
476 throw runtime_error("access to register name of non-register script token");
480 const string &ScriptToken::CommandName() const {
481 if (type == COMMAND) {
484 throw runtime_error("access to command name of non-command script token");
488 const string &ScriptToken::Identifier() const {
489 if (type == IDENTIFIER) {
492 throw runtime_error("access to identifier of non-identifier script token");
496 const string &ScriptToken::Label() const {
500 throw runtime_error("access to label of non-label script token");
504 const Literal *ScriptToken::GetLiteral() const {
505 if (type == LITERAL) {
508 throw runtime_error("access to literal value of non-literal script token");
517 ostream &operator <<(ostream &out, const loader::ParsedSource &source) {
518 out << "parsed source file" << endl;
519 out << "declared objects: " << endl;
520 for (map<string, loader::Declaration *>::const_iterator i(source.Declarations().begin()), end(source.Declarations().end()); i != end; ++i) {
521 out << " - " << i->first << " of type " << i->second->TypeName() << endl;
523 out << "defined objects: " << endl;
524 for (map<string, loader::Definition *>::const_iterator i(source.Definitions().begin()), end(source.Definitions().end()); i != end; ++i) {
525 out << " - " << i->first << " of type " << i->second->TypeName() << endl;
526 if (i->second->HasLiteralValue()) {
527 out << " literal value: " << *i->second->GetLiteral() << endl;
530 out << "exported objects: " << endl;
531 for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
532 out << " - " << *i << endl;
537 ostream &operator <<(ostream &out, const loader::Literal &l) {
538 switch (l.GetType()) {
539 case loader::Literal::ARRAY_VALUES:
540 out << "array of values";
542 case loader::Literal::ARRAY_PROPS:
543 out << "array of property lists";
545 case loader::Literal::BOOLEAN:
546 out << "boolean, " << (l.GetBoolean() ? "true" : "false");
548 case loader::Literal::COLOR:
549 out << "color, (" << l.GetRed() << ',' << l.GetGreen() << ',' << l.GetBlue() << ',' << l.GetAlpha() << ')';
551 case loader::Literal::NUMBER:
552 out << "number, " << l.GetNumber();
554 case loader::Literal::PATH:
555 out << "path, \"" << l.GetString() << '"';
557 case loader::Literal::STRING:
558 out << "string, \"" << l.GetString() << '"';
560 case loader::Literal::VECTOR:
561 out << "vector, <" << l.GetX() << ',' << l.GetY() << '>';
563 case loader::Literal::OBJECT:
564 out << "object of type " << l.GetTypeName();
566 case loader::Literal::SCRIPT: