1 #include "ParsedSource.h"
9 using std::runtime_error;
15 ParsedSource::~ParsedSource() {
16 for (map<string, Declaration *>::const_iterator i(declarations.begin()), end(declarations.end()); i != end; ++i) {
21 void ParsedSource::AddDeclaration(Declaration *d) {
22 map<string, Declaration *>::iterator i(declarations.find(d->Identifier()));
23 if (i != declarations.end()) {
24 if (d->TypeName() != i->second->TypeName()) {
25 throw runtime_error("invalid redeclaration of " + i->second->TypeName() + " " + d->Identifier());
28 declarations.insert(std::make_pair(d->Identifier(), d));
32 void ParsedSource::AddDefinition(Definition *d) {
33 map<string, Definition *>::iterator i(definitions.find(d->Identifier()));
34 if (i != definitions.end()) {
35 throw runtime_error("redefinition of " + i->second->TypeName() + " " + d->Identifier());
37 definitions.insert(std::make_pair(d->Identifier(), d));
41 void ParsedSource::ExportDeclaration(Declaration *d) {
43 exports.insert(d->Identifier());
46 void ParsedSource::ExportIdentifier(const std::string &i) {
47 if (declarations.count(i)) {
50 throw runtime_error("cannot export undeclared identifier " + i);
55 bool ParsedSource::IsDeclared(const std::string &name) const {
56 return declarations.count(name);
59 Declaration &ParsedSource::GetDeclaration(const std::string &name) {
60 map<string, Declaration *>::const_iterator i(declarations.find(name));
61 if (i != declarations.end()) {
64 throw runtime_error("undeclared identifier " + name);
68 const Declaration &ParsedSource::GetDeclaration(const std::string &name) const {
69 map<string, Declaration *>::const_iterator i(declarations.find(name));
70 if (i != declarations.end()) {
73 throw runtime_error("undeclared identifier " + name);
77 bool ParsedSource::IsDefined(const std::string &name) const {
78 return definitions.count(name);
81 Definition &ParsedSource::GetDefinition(const std::string &name) {
82 map<string, Definition *>::const_iterator i(definitions.find(name));
83 if (i != definitions.end()) {
86 string msg("undefined identifier " + name);
87 map<string, Declaration *>::const_iterator i(declarations.find(name));
88 if (i != declarations.end()) {
89 msg += ", declared as " + i->second->TypeName();
91 msg += ", not declared";
93 throw runtime_error(msg);
97 const Definition &ParsedSource::GetDefinition(const std::string &name) const {
98 map<string, Definition *>::const_iterator i(definitions.find(name));
99 if (i != definitions.end()) {
102 string msg("undefined identifier " + name);
103 map<string, Declaration *>::const_iterator i(declarations.find(name));
104 if (i != declarations.end()) {
105 msg += ", declared as " + i->second->TypeName();
107 msg += ", not declared";
109 throw runtime_error(msg);
113 void ParsedSource::WriteHeader(std::ostream &out) const {
114 for (std::set<string>::const_iterator i(exports.begin()), end(exports.end()); i != end; ++i) {
115 out << GetDeclaration(*i).TypeName() << ' ' << *i << std::endl;
120 Definition::~Definition() {
122 delete reinterpret_cast<Literal *>(value);
124 delete reinterpret_cast<PropertyList *>(value);
128 void Definition::SetValue(Literal *v) {
133 void Definition::SetValue(PropertyList *v) {
138 Literal *Definition::GetLiteral() {
140 return reinterpret_cast<Literal *>(value);
142 throw runtime_error("tried to access properties as literal");
146 const Literal *Definition::GetLiteral() const {
148 return reinterpret_cast<Literal *>(value);
150 throw runtime_error("tried to access properties as literal");
154 PropertyList *Definition::GetProperties() {
156 return reinterpret_cast<PropertyList *>(value);
158 throw runtime_error("tried to access literal value as property list");
162 const PropertyList *Definition::GetProperties() const {
164 return reinterpret_cast<PropertyList *>(value);
165 } else if (GetLiteral()->GetType() == Literal::OBJECT) {
166 return GetLiteral()->GetProperties();
168 throw runtime_error("tried to access literal value as property list");
173 PropertyList::~PropertyList() {
174 for (map<string, Value *>::iterator i(props.begin()), end(props.end()); i != end; ++i) {
180 Literal::Literal(const vector<Value *> &v)
186 , type(ARRAY_VALUES) {
188 typeName = v.front()->GetLiteral().GetTypeName();
192 Literal::Literal(const string &typeName, const vector<PropertyList *> &pls)
199 , type(ARRAY_PROPS) {
203 Literal::Literal(const string &typeName, const vector<string> &ids)
210 , type(ARRAY_IDENTS) {
214 Literal::Literal(bool b)
216 , typeName("Boolean")
224 Literal::Literal(int r, int g, int b, int a)
234 Literal::Literal(int number)
244 Literal::Literal(const string &dir, const string &path)
247 , str(CatPath(dir, path))
255 Literal::Literal(const string &str)
266 Literal::Literal(int x, int y)
276 Literal::Literal(const string &typeName, PropertyList *properties)
286 Literal::Literal(const vector<ScriptToken *> &s)
296 Literal::~Literal() {
299 for (vector<Value *>::const_iterator i(values.begin()), end(values.end()); i != end; ++i) {
304 for (vector<PropertyList *>::const_iterator i(propertyLists.begin()), end(propertyLists.end()); i != end; ++i) {
312 for (vector<ScriptToken *>::const_iterator i(script.begin()), end(script.end()); i != end; ++i) {
322 const vector<Value *> &Literal::GetValues() const {
323 if (type == ARRAY_VALUES) {
326 throw runtime_error("tried to access values of non-array literal");
330 const vector<PropertyList *> &Literal::GetPropertyLists() const {
331 if (type == ARRAY_PROPS) {
332 return propertyLists;
334 throw runtime_error("tried to access property lists of non-array literal");
338 const vector<string> &Literal::GetIdentifiers() const {
339 if (type == ARRAY_IDENTS) {
342 throw runtime_error("tried to access identifiers of non-array literal");
346 bool Literal::GetBoolean() const {
347 if (type == BOOLEAN) {
350 throw runtime_error("tried to access boolean value of non-boolean literal");
354 int Literal::GetRed() const {
358 throw runtime_error("tried to access red component of non-color literal");
362 int Literal::GetGreen() const {
366 throw runtime_error("tried to access green component of non-color literal");
370 int Literal::GetBlue() const {
374 throw runtime_error("tried to access blue component of non-color literal");
378 int Literal::GetAlpha() const {
382 throw runtime_error("tried to access alpha component of non-color literal");
386 int Literal::GetNumber() const {
387 if (type == NUMBER) {
390 throw runtime_error("tried to access numerical value of non-number literal");
394 const string &Literal::GetString() const {
395 if (type == STRING) {
398 throw runtime_error("tried to access string value of non-color literal");
402 int Literal::GetX() const {
403 if (type == VECTOR) {
406 throw runtime_error("tried to access x component of non-vector literal");
410 int Literal::GetY() const {
411 if (type == VECTOR) {
414 throw runtime_error("tried to access y component of non-vector literal");
418 const string &Literal::GetTypeName() const {
422 const PropertyList *Literal::GetProperties() const {
423 if (type == OBJECT) {
426 throw runtime_error("tried to access properties of non-object literal");
430 const vector<ScriptToken *> &Literal::GetScript() const {
431 if (type == SCRIPT) {
434 throw runtime_error("tried to access script of non-script literal");
445 const Literal &Value::GetLiteral() const {
449 throw runtime_error("tried to access literal of identifier value");
453 const std::string &Value::GetIdentifier() const {
457 throw runtime_error("tried to access identifier of literal value");
462 ScriptToken::ScriptToken(const string &s, Type t)
466 if (type == LITERAL) {
467 throw runtime_error("cannot create script literal without literal");
471 ScriptToken::ScriptToken(Literal *l)
476 throw runtime_error("cannot create script literal without literal");
480 ScriptToken::~ScriptToken() {
484 const string &ScriptToken::RegisterName() const {
485 if (type == REGISTER) {
488 throw runtime_error("access to register name of non-register script token");
492 const string &ScriptToken::CommandName() const {
493 if (type == COMMAND) {
496 throw runtime_error("access to command name of non-command script token");
500 const string &ScriptToken::Identifier() const {
501 if (type == IDENTIFIER) {
504 throw runtime_error("access to identifier of non-identifier script token");
508 const string &ScriptToken::Label() const {
512 throw runtime_error("access to label of non-label script token");
516 const Literal *ScriptToken::GetLiteral() const {
517 if (type == LITERAL) {
520 throw runtime_error("access to literal value of non-literal script token");
529 ostream &operator <<(ostream &out, const loader::ParsedSource &source) {
530 out << "parsed source file" << endl;
531 out << "declared objects: " << endl;
532 for (map<string, loader::Declaration *>::const_iterator i(source.Declarations().begin()), end(source.Declarations().end()); i != end; ++i) {
533 out << " - " << i->first << " of type " << i->second->TypeName() << endl;
535 out << "defined objects: " << endl;
536 for (map<string, loader::Definition *>::const_iterator i(source.Definitions().begin()), end(source.Definitions().end()); i != end; ++i) {
537 out << " - " << i->first << " of type " << i->second->TypeName() << endl;
538 if (i->second->HasLiteralValue()) {
539 out << " literal value: " << *i->second->GetLiteral() << endl;
542 out << "exported objects: " << endl;
543 for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
544 out << " - " << *i << endl;
549 ostream &operator <<(ostream &out, const loader::Literal &l) {
550 switch (l.GetType()) {
551 case loader::Literal::ARRAY_VALUES:
552 out << "array of values";
554 case loader::Literal::ARRAY_PROPS:
555 out << "array of property lists";
557 case loader::Literal::ARRAY_IDENTS:
558 out << "array of identifiers";
560 case loader::Literal::BOOLEAN:
561 out << "boolean, " << (l.GetBoolean() ? "true" : "false");
563 case loader::Literal::COLOR:
564 out << "color, (" << l.GetRed() << ',' << l.GetGreen() << ',' << l.GetBlue() << ',' << l.GetAlpha() << ')';
566 case loader::Literal::NUMBER:
567 out << "number, " << l.GetNumber();
569 case loader::Literal::PATH:
570 out << "path, \"" << l.GetString() << '"';
572 case loader::Literal::STRING:
573 out << "string, \"" << l.GetString() << '"';
575 case loader::Literal::VECTOR:
576 out << "vector, <" << l.GetX() << ',' << l.GetY() << '>';
578 case loader::Literal::OBJECT:
579 out << "object of type " << l.GetTypeName();
581 case loader::Literal::SCRIPT: