]> git.localhorst.tv Git - l2e.git/blobdiff - src/loader/ParsedSource.cpp
lousy implementation of "array of identifiers" type
[l2e.git] / src / loader / ParsedSource.cpp
index b019fe76bc4f5fb6c09ebae980c86a1319936481..90597475726663807fdc2beaa5b8f1d7fc627c98 100644 (file)
@@ -1,12 +1,7 @@
-/*
- * ParsedSource.cpp
- *
- *  Created on: Aug 26, 2012
- *      Author: holy
- */
-
 #include "ParsedSource.h"
 
+#include "utility.h"
+
 #include <ostream>
 #include <stdexcept>
 
@@ -17,6 +12,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()) {
@@ -82,7 +83,14 @@ Definition &ParsedSource::GetDefinition(const std::string &name) {
        if (i != definitions.end()) {
                return *i->second;
        } else {
-               throw runtime_error("undefined identifier " + name);
+               string msg("undefined identifier " + name);
+               map<string, Declaration *>::const_iterator i(declarations.find(name));
+               if (i != declarations.end()) {
+                       msg += ", declared as " + i->second->TypeName();
+               } else {
+                       msg += ", not declared";
+               }
+               throw runtime_error(msg);
        }
 }
 
@@ -91,11 +99,32 @@ const Definition &ParsedSource::GetDefinition(const std::string &name) const {
        if (i != definitions.end()) {
                return *i->second;
        } else {
-               throw runtime_error("undefined identifier " + name);
+               string msg("undefined identifier " + name);
+               map<string, Declaration *>::const_iterator i(declarations.find(name));
+               if (i != declarations.end()) {
+                       msg += ", declared as " + i->second->TypeName();
+               } else {
+                       msg += ", not declared";
+               }
+               throw runtime_error(msg);
+       }
+}
+
+void ParsedSource::WriteHeader(std::ostream &out) const {
+       for (std::set<string>::const_iterator i(exports.begin()), end(exports.end()); i != end; ++i) {
+               out << GetDeclaration(*i).TypeName() << ' ' << *i << std::endl;
        }
 }
 
 
+Definition::~Definition() {
+       if (isLiteral) {
+               delete reinterpret_cast<Literal *>(value);
+       } else {
+               delete reinterpret_cast<PropertyList *>(value);
+       }
+}
+
 void Definition::SetValue(Literal *v) {
        value = v;
        isLiteral = true;
@@ -108,7 +137,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");
        }
@@ -116,7 +145,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");
        }
@@ -124,7 +153,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");
        }
@@ -132,7 +161,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");
        }
@@ -153,11 +184,14 @@ Literal::Literal(const vector<Value *> &v)
 , i3(0), i4(0)
 , b(false)
 , type(ARRAY_VALUES) {
-
+       if (!v.empty()) {
+               typeName = v.front()->GetLiteral().GetTypeName();
+       }
 }
 
-Literal::Literal(const std::vector<PropertyList *> &pls)
+Literal::Literal(const string &typeName, const vector<PropertyList *> &pls)
 : props(0)
+, typeName(typeName)
 , propertyLists(pls)
 , i1(0), i2(0)
 , i3(0), i4(0)
@@ -166,8 +200,20 @@ Literal::Literal(const std::vector<PropertyList *> &pls)
 
 }
 
+Literal::Literal(const string &typeName, const vector<string> &ids)
+: props(0)
+, typeName(typeName)
+, identifiers(ids)
+, i1(0), i2(0)
+, i3(0), i4(0)
+, b(false)
+, type(ARRAY_IDENTS) {
+
+}
+
 Literal::Literal(bool b)
 : props(0)
+, typeName("Boolean")
 , i1(0), i2(0)
 , i3(0), i4(0)
 , b(b)
@@ -177,6 +223,7 @@ Literal::Literal(bool b)
 
 Literal::Literal(int r, int g, int b, int a)
 : props(0)
+, typeName("Color")
 , i1(r), i2(g)
 , i3(b), i4(a)
 , b(false)
@@ -186,6 +233,7 @@ Literal::Literal(int r, int g, int b, int a)
 
 Literal::Literal(int number)
 : props(0)
+, typeName("Number")
 , i1(number), i2(0)
 , i3(0), i4(0)
 , b(false)
@@ -193,8 +241,20 @@ Literal::Literal(int number)
 
 }
 
+Literal::Literal(const string &dir, const string &path)
+: props(0)
+, typeName("Path")
+, str(CatPath(dir, path))
+, i1(0), i2(0)
+, i3(0), i4(0)
+, b(false)
+, type(STRING) {
+
+}
+
 Literal::Literal(const string &str)
 : props(0)
+, typeName("String")
 , str(str)
 , i1(0), i2(0)
 , i3(0), i4(0)
@@ -205,6 +265,7 @@ Literal::Literal(const string &str)
 
 Literal::Literal(int x, int y)
 : props(0)
+, typeName("Vector")
 , i1(x), i2(y)
 , i3(0), i4(0)
 , b(false)
@@ -214,7 +275,7 @@ Literal::Literal(int x, int y)
 
 Literal::Literal(const string &typeName, PropertyList *properties)
 : props(properties)
-, str(typeName)
+, typeName(typeName)
 , i1(0), i2(0)
 , i3(0), i4(0)
 , b(false)
@@ -222,6 +283,41 @@ Literal::Literal(const string &typeName, PropertyList *properties)
 
 }
 
+Literal::Literal(const vector<ScriptToken *> &s)
+: props(0)
+, script(s)
+, i1(0), i2(0)
+, i3(0), i4(0)
+, b(false)
+, type(SCRIPT) {
+
+}
+
+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;
+               case SCRIPT:
+                       for (vector<ScriptToken *>::const_iterator i(script.begin()), end(script.end()); i != end; ++i) {
+                               delete *i;
+                       }
+                       break;
+               default:
+                       break;
+       }
+}
+
 
 const vector<Value *> &Literal::GetValues() const {
        if (type == ARRAY_VALUES) {
@@ -239,6 +335,14 @@ const vector<PropertyList *> &Literal::GetPropertyLists() const {
        }
 }
 
+const vector<string> &Literal::GetIdentifiers() const {
+       if (type == ARRAY_IDENTS) {
+               return identifiers;
+       } else {
+               throw runtime_error("tried to access identifiers of non-array literal");
+       }
+}
+
 bool Literal::GetBoolean() const {
        if (type == BOOLEAN) {
                return b;
@@ -312,11 +416,7 @@ int Literal::GetY() const {
 }
 
 const string &Literal::GetTypeName() const {
-       if (type == OBJECT) {
-               return str;
-       } else {
-               throw runtime_error("tried to access type name of non-object literal");
-       }
+       return typeName;
 }
 
 const PropertyList *Literal::GetProperties() const {
@@ -327,6 +427,100 @@ const PropertyList *Literal::GetProperties() const {
        }
 }
 
+const vector<ScriptToken *> &Literal::GetScript() const {
+       if (type == SCRIPT) {
+               return script;
+       } else {
+               throw runtime_error("tried to access script of non-script 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");
+       }
+}
+
+
+ScriptToken::ScriptToken(const string &s, Type t)
+: literal(0)
+, str(s)
+, type(t) {
+       if (type == LITERAL) {
+               throw runtime_error("cannot create script literal without literal");
+       }
+}
+
+ScriptToken::ScriptToken(Literal *l)
+: literal(l)
+, str()
+, type(LITERAL) {
+       if (!literal) {
+               throw runtime_error("cannot create script literal without literal");
+       }
+}
+
+ScriptToken::~ScriptToken() {
+       delete literal;
+}
+
+const string &ScriptToken::RegisterName() const {
+       if (type == REGISTER) {
+               return str;
+       } else {
+               throw runtime_error("access to register name of non-register script token");
+       }
+}
+
+const string &ScriptToken::CommandName() const {
+       if (type == COMMAND) {
+               return str;
+       } else {
+               throw runtime_error("access to command name of non-command script token");
+       }
+}
+
+const string &ScriptToken::Identifier() const {
+       if (type == IDENTIFIER) {
+               return str;
+       } else {
+               throw runtime_error("access to identifier of non-identifier script token");
+       }
+}
+
+const string &ScriptToken::Label() const {
+       if (type == LABEL) {
+               return str;
+       } else {
+               throw runtime_error("access to label of non-label script token");
+       }
+}
+
+const Literal *ScriptToken::GetLiteral() const {
+       if (type == LITERAL) {
+               return literal;
+       } else {
+               throw runtime_error("access to literal value of non-literal script token");
+       }
+}
+
 }
 
 
@@ -360,6 +554,9 @@ ostream &operator <<(ostream &out, const loader::Literal &l) {
                case loader::Literal::ARRAY_PROPS:
                        out << "array of property lists";
                        break;
+               case loader::Literal::ARRAY_IDENTS:
+                       out << "array of identifiers";
+                       break;
                case loader::Literal::BOOLEAN:
                        out << "boolean, " << (l.GetBoolean() ? "true" : "false");
                        break;
@@ -369,6 +566,9 @@ ostream &operator <<(ostream &out, const loader::Literal &l) {
                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;
@@ -378,6 +578,9 @@ ostream &operator <<(ostream &out, const loader::Literal &l) {
                case loader::Literal::OBJECT:
                        out << "object of type " << l.GetTypeName();
                        break;
+               case loader::Literal::SCRIPT:
+                       out << "script";
+                       break;
        }
        return out;
 }