#include "ParsedSource.h"
+#include "utility.h"
+
#include <ostream>
#include <stdexcept>
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()) {
}
}
+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());
}
+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 {
+ 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);
+ }
+}
+
+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 {
+ 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;
Literal *Definition::GetLiteral() {
if (isLiteral) {
- return (Literal *)value;
+ return reinterpret_cast<Literal *>(value);
} else {
throw runtime_error("tried to access properties as literal");
}
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");
}
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");
}
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");
}
, i1(0), i2(0)
, i3(0), i4(0)
, b(false)
-, type(ARRAY) {
+, type(ARRAY_VALUES) {
+ if (!v.empty()) {
+ typeName = v.front()->GetLiteral().GetTypeName();
+ }
+}
+
+Literal::Literal(const string &typeName, const vector<PropertyList *> &pls)
+: props(0)
+, typeName(typeName)
+, propertyLists(pls)
+, i1(0), i2(0)
+, i3(0), i4(0)
+, b(false)
+, type(ARRAY_PROPS) {
}
Literal::Literal(bool b)
: props(0)
+, typeName("Boolean")
, i1(0), i2(0)
, i3(0), i4(0)
, b(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)
}
+Literal::Literal(int number)
+: props(0)
+, typeName("Number")
+, i1(number), i2(0)
+, i3(0), i4(0)
+, b(false)
+, type(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)
Literal::Literal(int x, int y)
: props(0)
+, typeName("Vector")
, i1(x), i2(y)
, i3(0), i4(0)
, b(false)
Literal::Literal(const string &typeName, PropertyList *properties)
: props(properties)
-, str(typeName)
+, typeName(typeName)
, i1(0), i2(0)
, i3(0), i4(0)
, b(false)
}
+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 {
+ return typeName;
+}
+
+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");
+ }
+}
+
}
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;
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;
+}
+
}