]> git.localhorst.tv Git - l2e.git/blobdiff - src/loader/ParsedSource.cpp
added hard support for path names in source files
[l2e.git] / src / loader / ParsedSource.cpp
index 9d0f597e3d7c10ca0328586d8941f1f29ac48ff6..bceed089f0377f4a4678edc84414afa4d7c3084b 100644 (file)
@@ -7,6 +7,8 @@
 
 #include "ParsedSource.h"
 
+#include "utility.h"
+
 #include <ostream>
 #include <stdexcept>
 
@@ -17,6 +19,12 @@ using std::vector;
 
 namespace loader {
 
+ParsedSource::~ParsedSource() {
+       for (map<string, Declaration *>::const_iterator i(declarations.begin()), end(declarations.end()); i != end; ++i) {
+               delete i->second;
+       }
+}
+
 void ParsedSource::AddDeclaration(Declaration *d) {
        map<string, Declaration *>::iterator i(declarations.find(d->Identifier()));
        if (i != declarations.end()) {
@@ -28,6 +36,15 @@ void ParsedSource::AddDeclaration(Declaration *d) {
        }
 }
 
+void ParsedSource::AddDefinition(Definition *d) {
+       map<string, Definition *>::iterator i(definitions.find(d->Identifier()));
+       if (i != definitions.end()) {
+               throw runtime_error("redefinition of " + i->second->TypeName() + " " + d->Identifier());
+       } else {
+               definitions.insert(std::make_pair(d->Identifier(), d));
+       }
+}
+
 void ParsedSource::ExportDeclaration(Declaration *d) {
        AddDeclaration(d);
        exports.insert(d->Identifier());
@@ -42,6 +59,59 @@ void ParsedSource::ExportIdentifier(const std::string &i) {
 }
 
 
+bool ParsedSource::IsDeclared(const std::string &name) const {
+       return declarations.count(name);
+}
+
+Declaration &ParsedSource::GetDeclaration(const std::string &name) {
+       map<string, Declaration *>::const_iterator i(declarations.find(name));
+       if (i != declarations.end()) {
+               return *i->second;
+       } else {
+               throw runtime_error("undeclared identifier " + name);
+       }
+}
+
+const Declaration &ParsedSource::GetDeclaration(const std::string &name) const {
+       map<string, Declaration *>::const_iterator i(declarations.find(name));
+       if (i != declarations.end()) {
+               return *i->second;
+       } else {
+               throw runtime_error("undeclared identifier " + name);
+       }
+}
+
+bool ParsedSource::IsDefined(const std::string &name) const {
+       return definitions.count(name);
+}
+
+Definition &ParsedSource::GetDefinition(const std::string &name) {
+       map<string, Definition *>::const_iterator i(definitions.find(name));
+       if (i != definitions.end()) {
+               return *i->second;
+       } else {
+               throw runtime_error("undefined identifier " + name);
+       }
+}
+
+const Definition &ParsedSource::GetDefinition(const std::string &name) const {
+       map<string, Definition *>::const_iterator i(definitions.find(name));
+       if (i != definitions.end()) {
+               return *i->second;
+       } else {
+               throw runtime_error("undefined identifier " + name);
+       }
+}
+
+
+Definition::~Definition() {
+       if (isLiteral) {
+               delete reinterpret_cast<Literal *>(value);
+       } else {
+               delete reinterpret_cast<PropertyList *>(value);
+       }
+}
+
 void Definition::SetValue(Literal *v) {
        value = v;
        isLiteral = true;
@@ -54,7 +124,7 @@ void Definition::SetValue(PropertyList *v) {
 
 Literal *Definition::GetLiteral() {
        if (isLiteral) {
-               return (Literal *)value;
+               return reinterpret_cast<Literal *>(value);
        } else {
                throw runtime_error("tried to access properties as literal");
        }
@@ -62,7 +132,7 @@ Literal *Definition::GetLiteral() {
 
 const Literal *Definition::GetLiteral() const {
        if (isLiteral) {
-               return (Literal *)value;
+               return reinterpret_cast<Literal *>(value);
        } else {
                throw runtime_error("tried to access properties as literal");
        }
@@ -70,7 +140,7 @@ const Literal *Definition::GetLiteral() const {
 
 PropertyList *Definition::GetProperties() {
        if (!isLiteral) {
-               return (PropertyList *)value;
+               return reinterpret_cast<PropertyList *>(value);
        } else {
                throw runtime_error("tried to access literal value as property list");
        }
@@ -78,7 +148,9 @@ PropertyList *Definition::GetProperties() {
 
 const PropertyList *Definition::GetProperties() const {
        if (!isLiteral) {
-               return (PropertyList *)value;
+               return reinterpret_cast<PropertyList *>(value);
+       } else if (GetLiteral()->GetType() == Literal::OBJECT) {
+               return GetLiteral()->GetProperties();
        } else {
                throw runtime_error("tried to access literal value as property list");
        }
@@ -130,6 +202,25 @@ Literal::Literal(int r, int g, int b, int a)
 
 }
 
+Literal::Literal(int number)
+: props(0)
+, i1(number), i2(0)
+, i3(0), i4(0)
+, b(false)
+, type(NUMBER) {
+
+}
+
+Literal::Literal(const string &dir, const string &path)
+: props(0)
+, str(CatPath(dir, path))
+, i1(0), i2(0)
+, i3(0), i4(0)
+, b(false)
+, type(STRING) {
+
+}
+
 Literal::Literal(const string &str)
 : props(0)
 , str(str)
@@ -159,6 +250,154 @@ Literal::Literal(const string &typeName, PropertyList *properties)
 
 }
 
+Literal::~Literal() {
+       switch (type) {
+               case ARRAY_VALUES:
+                       for (vector<Value *>::const_iterator i(values.begin()), end(values.end()); i != end; ++i) {
+                               delete *i;
+                       }
+                       break;
+               case ARRAY_PROPS:
+                       for (vector<PropertyList *>::const_iterator i(propertyLists.begin()), end(propertyLists.end()); i != end; ++i) {
+                               delete *i;
+                       }
+                       break;
+               case OBJECT:
+                       delete props;
+                       break;
+               default:
+                       break;
+       }
+}
+
+
+const vector<Value *> &Literal::GetValues() const {
+       if (type == ARRAY_VALUES) {
+               return values;
+       } else {
+               throw runtime_error("tried to access values of non-array literal");
+       }
+}
+
+const vector<PropertyList *> &Literal::GetPropertyLists() const {
+       if (type == ARRAY_PROPS) {
+               return propertyLists;
+       } else {
+               throw runtime_error("tried to access property lists of non-array literal");
+       }
+}
+
+bool Literal::GetBoolean() const {
+       if (type == BOOLEAN) {
+               return b;
+       } else {
+               throw runtime_error("tried to access boolean value of non-boolean literal");
+       }
+}
+
+int Literal::GetRed() const {
+       if (type == COLOR) {
+               return i1;
+       } else {
+               throw runtime_error("tried to access red component of non-color literal");
+       }
+}
+
+int Literal::GetGreen() const {
+       if (type == COLOR) {
+               return i2;
+       } else {
+               throw runtime_error("tried to access green component of non-color literal");
+       }
+}
+
+int Literal::GetBlue() const {
+       if (type == COLOR) {
+               return i3;
+       } else {
+               throw runtime_error("tried to access blue component of non-color literal");
+       }
+}
+
+int Literal::GetAlpha() const {
+       if (type == COLOR) {
+               return i4;
+       } else {
+               throw runtime_error("tried to access alpha component of non-color literal");
+       }
+}
+
+int Literal::GetNumber() const {
+       if (type == NUMBER) {
+               return i1;
+       } else {
+               throw runtime_error("tried to access numerical value of non-number literal");
+       }
+}
+
+const string &Literal::GetString() const {
+       if (type == STRING) {
+               return str;
+       } else {
+               throw runtime_error("tried to access string value of non-color literal");
+       }
+}
+
+int Literal::GetX() const {
+       if (type == VECTOR) {
+               return i1;
+       } else {
+               throw runtime_error("tried to access x component of non-vector literal");
+       }
+}
+
+int Literal::GetY() const {
+       if (type == VECTOR) {
+               return i2;
+       } else {
+               throw runtime_error("tried to access y component of non-vector literal");
+       }
+}
+
+const string &Literal::GetTypeName() const {
+       if (type == OBJECT) {
+               return str;
+       } else {
+               throw runtime_error("tried to access type name of non-object literal");
+       }
+}
+
+const PropertyList *Literal::GetProperties() const {
+       if (type == OBJECT) {
+               return props;
+       } else {
+               throw runtime_error("tried to access properties of non-object literal");
+       }
+}
+
+
+Value::~Value() {
+       if (isLiteral) {
+               delete literal;
+       }
+}
+
+const Literal &Value::GetLiteral() const {
+       if (isLiteral) {
+               return *literal;
+       } else {
+               throw runtime_error("tried to access literal of identifier value");
+       }
+}
+
+const std::string &Value::GetIdentifier() const {
+       if (!isLiteral) {
+               return identifier;
+       } else {
+               throw runtime_error("tried to access identifier of literal value");
+       }
+}
+
 }
 
 
@@ -170,6 +409,13 @@ ostream &operator <<(ostream &out, const loader::ParsedSource &source) {
        for (map<string, loader::Declaration *>::const_iterator i(source.Declarations().begin()), end(source.Declarations().end()); i != end; ++i) {
                out << " - " << i->first << " of type " << i->second->TypeName() << endl;
        }
+       out << "defined objects: " << endl;
+       for (map<string, loader::Definition *>::const_iterator i(source.Definitions().begin()), end(source.Definitions().end()); i != end; ++i) {
+               out << " - " << i->first << " of type " << i->second->TypeName() << endl;
+               if (i->second->HasLiteralValue()) {
+                       out << "     literal value: " << *i->second->GetLiteral() << endl;
+               }
+       }
        out << "exported objects: " << endl;
        for (set<string>::const_iterator i(source.Exports().begin()), end(source.Exports().end()); i != end; ++i) {
                out << " - " << *i << endl;
@@ -177,4 +423,37 @@ ostream &operator <<(ostream &out, const loader::ParsedSource &source) {
        return out;
 }
 
+ostream &operator <<(ostream &out, const loader::Literal &l) {
+       switch (l.GetType()) {
+               case loader::Literal::ARRAY_VALUES:
+                       out << "array of values";
+                       break;
+               case loader::Literal::ARRAY_PROPS:
+                       out << "array of property lists";
+                       break;
+               case loader::Literal::BOOLEAN:
+                       out << "boolean, " << (l.GetBoolean() ? "true" : "false");
+                       break;
+               case loader::Literal::COLOR:
+                       out << "color, (" << l.GetRed() << ',' << l.GetGreen() << ',' << l.GetBlue() << ',' << l.GetAlpha() << ')';
+                       break;
+               case loader::Literal::NUMBER:
+                       out << "number, " << l.GetNumber();
+                       break;
+               case loader::Literal::PATH:
+                       out << "path, \"" << l.GetString() << '"';
+                       break;
+               case loader::Literal::STRING:
+                       out << "string, \"" << l.GetString() << '"';
+                       break;
+               case loader::Literal::VECTOR:
+                       out << "vector, <" << l.GetX() << ',' << l.GetY() << '>';
+                       break;
+               case loader::Literal::OBJECT:
+                       out << "object of type " << l.GetTypeName();
+                       break;
+       }
+       return out;
+}
+
 }