}
}
+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());
}
+Literal::Literal(int number)
+: props(0)
+, i1(number), i2(0)
+, i3(0), i4(0)
+, b(false)
+, type(NUMBER) {
+
+}
+
Literal::Literal(const string &str)
: props(0)
, str(str)
}
+
+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");
+ }
+}
+
}
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::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;
+}
+
}
class Literal {
+public:
enum Type {
ARRAY_VALUES,
ARRAY_PROPS,
explicit Literal(const std::vector<PropertyList *> &);
explicit Literal(bool);
Literal(int r, int g, int b, int a = 255);
+ explicit Literal(int number);
Literal(const std::string &);
Literal(int x, int y);
Literal(const std::string &typeName, PropertyList *properties);
+public:
+ Type GetType() const { return type; }
+
+ const std::vector<Value *> &GetValues() const;
+ const std::vector<PropertyList *> &GetPropertyLists() const;
+ bool GetBoolean() const;
+ int GetRed() const;
+ int GetGreen() const;
+ int GetBlue() const;
+ int GetAlpha() const;
+ int GetNumber() const;
+ const std::string &GetString() const;
+ int GetX() const;
+ int GetY() const;
+ const std::string &GetTypeName() const;
+ const PropertyList *GetProperties() const;
+
private:
PropertyList *props;
std::string str;
public:
void AddDeclaration(Declaration *);
+ void AddDefinition(Definition *);
void ExportDeclaration(Declaration *);
void ExportIdentifier(const std::string &);
- const std::map<std::string, Declaration *> Declarations() const { return declarations; }
- const std::set<std::string> Exports() const { return exports; }
+ const std::map<std::string, Declaration *> &Declarations() const { return declarations; }
+ const std::map<std::string, Definition *> &Definitions() const { return definitions; }
+ const std::set<std::string> &Exports() const { return exports; }
private:
std::map<std::string, Declaration *> declarations;
+ std::map<std::string, Definition *> definitions;
std::set<std::string> exports;
};
namespace std {
ostream &operator <<(ostream &, const loader::ParsedSource &);
+ostream &operator <<(ostream &, const loader::Literal &);
}
Tokenizer::Token t(GetToken());
tok.Putback(t);
if (BeginOfPropertyList(t)) {
- PropertyList *propertyList(ParsePropertyList());
- Definition *dfn(new Definition(typeName, identifier));
- dfn->SetValue(propertyList);
- return dfn;
+ auto_ptr<PropertyList> propertyList(ParsePropertyList());
+ auto_ptr<Definition> dfn(new Definition(typeName, identifier));
+ dfn->SetValue(propertyList.release());
+ product.AddDefinition(dfn.get());
+ return dfn.release();
} else if (BeginningOfLiteral(t)) {
- Literal *literal(ParseLiteral());
- Definition *dfn(new Definition(typeName, identifier));
- dfn->SetValue(literal);
- return dfn;
+ auto_ptr<Literal> literal(ParseLiteral());
+ auto_ptr<Definition> dfn(new Definition(typeName, identifier));
+ dfn->SetValue(literal.release());
+ product.AddDefinition(dfn.get());
+ return dfn.release();
} else {
return new Declaration(typeName, identifier);
}