]> git.localhorst.tv Git - l2e.git/commitdiff
parse scripts
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 14 Oct 2012 13:31:29 +0000 (15:31 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 14 Oct 2012 13:31:29 +0000 (15:31 +0200)
src/loader/Interpreter.cpp
src/loader/ParsedSource.cpp
src/loader/ParsedSource.h
src/loader/Parser.cpp
src/loader/Parser.h
src/loader/fwd.h

index e8d4ec9ff5be63fae56efcde0e3eef8ead5c8867..8b9b56a2098eb9ae9a6a4002020f4973fdfa6675 100644 (file)
@@ -142,6 +142,8 @@ void Interpreter::ReadLiteral(int typeId, int id, char *object, const Literal &l
                        std::memcpy(object, literal.GetString().c_str(), literal.GetString().size());
                        object[literal.GetString().size()] = '\0';
                        break;
+               case Literal::SCRIPT:
+                       throw Error("script compiler not implemented");
                case Literal::STRING:
                        std::memcpy(object, literal.GetString().c_str(), literal.GetString().size());
                        object[literal.GetString().size()] = '\0';
@@ -151,7 +153,6 @@ void Interpreter::ReadLiteral(int typeId, int id, char *object, const Literal &l
                        break;
                case Literal::OBJECT:
                        throw Error("illogical branch: read literal object as non-object literal");
-                       break;
        }
 }
 
@@ -213,6 +214,8 @@ void *Interpreter::GetObject(int typeId, const Value &v) {
                                                values[typeId].push_back(str);
                                        }
                                        break;
+                               case Literal::SCRIPT:
+                                       throw Error("script compiler not implemented");
                                case Literal::STRING:
                                        {
                                                typeId = TypeDescription::GetTypeId("String");
index e1a1d0aa030e3100e0a831205407e611443fb4aa..6b2fc80413207811b90631c1bfc493982c95c5ee 100644 (file)
@@ -279,6 +279,16 @@ 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:
@@ -294,6 +304,11 @@ Literal::~Literal() {
                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;
        }
@@ -400,6 +415,14 @@ 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) {
@@ -423,6 +446,61 @@ const std::string &Value::GetIdentifier() const {
        }
 }
 
+
+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::GetIdentifier() const {
+       if (type == IDENTIFIER) {
+               return str;
+       } else {
+               throw runtime_error("access to identifier of non-identifier 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");
+       }
+}
+
 }
 
 
@@ -477,6 +555,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;
 }
index 64baaaa4d3cb99cec172e65acbdcb14f7e69fd72..9ba52972a4b5bcf797fc32fc62d80db9f183553e 100644 (file)
 
 namespace loader {
 
+class ScriptToken {
+
+public:
+       enum Type {
+               COMMAND,
+               REGISTER,
+               IDENTIFIER,
+               LITERAL,
+       };
+
+       ScriptToken(const std::string &, Type);
+       explicit ScriptToken(Literal *);
+       ~ScriptToken();
+private:
+       ScriptToken(const ScriptToken &);
+       ScriptToken &operator =(const ScriptToken &);
+
+public:
+       Type GetType() const { return type; }
+       const std::string &RegisterName() const;
+       const std::string &CommandName() const;
+       const std::string &GetIdentifier() const;
+       const Literal *GetLiteral() const;
+
+private:
+       Literal *literal;
+       std::string str;
+       Type type;
+
+};
+
+
 class Literal {
 
 public:
@@ -30,7 +62,8 @@ public:
                PATH,
                STRING,
                VECTOR,
-               OBJECT
+               OBJECT,
+               SCRIPT,
        };
 
 public:
@@ -43,6 +76,7 @@ public:
        Literal(const std::string &);
        Literal(int x, int y);
        Literal(const std::string &typeName, PropertyList *properties);
+       explicit Literal(const std::vector<ScriptToken *> &);
        ~Literal();
 private:
        Literal(const Literal &);
@@ -67,12 +101,14 @@ public:
        int GetY() const;
        const std::string &GetTypeName() const;
        const PropertyList *GetProperties() const;
+       const std::vector<ScriptToken *> &GetScript() const;
 
 private:
        PropertyList *props;
        std::string typeName, str;
        std::vector<Value *> values;
        std::vector<PropertyList *> propertyLists;
+       std::vector<ScriptToken *> script;
        int i1, i2, i3, i4;
        bool b;
        Type type;
index 183accbbb728f1cdca9c672b33a2a454c43d94e6..52585c4cdd0f11ba40829a7a039456a390674e6f 100644 (file)
@@ -112,6 +112,7 @@ bool Parser::BeginningOfLiteral(const Tokenizer::Token &t) const {
                case Tokenizer::Token::BRACKET_OPEN:
                case Tokenizer::Token::PARENTHESIS_OPEN:
                case Tokenizer::Token::NUMBER:
+               case Tokenizer::Token::SCRIPT_BEGIN:
                case Tokenizer::Token::STRING:
                case Tokenizer::Token::KEYWORD_FALSE:
                case Tokenizer::Token::KEYWORD_TRUE:
@@ -142,6 +143,10 @@ bool Parser::BeginOfPropertyList(const Tokenizer::Token &t) const {
        return t.type == Tokenizer::Token::ANGLE_BRACKET_OPEN;
 }
 
+bool Parser::BeginningOfScriptLiteral(const Tokenizer::Token &t) const {
+       return t.type == Tokenizer::Token::SCRIPT_BEGIN;
+}
+
 Definition *Parser::ParseDefinition() {
        string typeName(ParseTypeName());
        string identifier(ParseIdentifier());
@@ -218,7 +223,10 @@ Literal *Parser::ParseLiteral() {
        if (t.type == Tokenizer::Token::TYPE_NAME) {
                PropertyList *props(ParsePropertyList());
                return new Literal(t.str, props);
-       } else if (BeginningOfLiteral(t)) {
+       } else if (BeginningOfScriptLiteral(t)) {
+               tok.Putback(t);
+               return ParseScript();
+       } else if (BeginningOfPrimitiveLiteral(t)) {
                switch (t.type) {
                        case Tokenizer::Token::CHEVRON_OPEN:
                                tok.Putback(t);
@@ -340,6 +348,51 @@ Literal *Parser::ParseVector() {
        return new Literal(x.number, y.number);
 }
 
+Literal *Parser::ParseScript() {
+       std::string msg("error parsing script");
+       Tokenizer::Token t(GetToken());
+       AssertTokenType(t.type, Tokenizer::Token::SCRIPT_BEGIN, msg);
+
+       vector<ScriptToken *> script;
+       try {
+               while (t.type != Tokenizer::Token::SCRIPT_END) {
+                       if (BeginningOfPrimitiveLiteral(t)) {
+                               tok.Putback(t);
+                               script.push_back(new ScriptToken(ParseLiteral()));
+                       } else {
+                               switch (t.type) {
+                                       case Tokenizer::Token::COMMAND: {
+                                               Tokenizer::Token t2(GetToken());
+                                               AssertTokenType(t.type, Tokenizer::Token::IDENTIFIER, msg);
+                                               script.push_back(new ScriptToken(t2.str, ScriptToken::COMMAND));
+                                               break;
+                                       }
+                                       case Tokenizer::Token::IDENTIFIER: {
+                                               script.push_back(new ScriptToken(t.str, ScriptToken::IDENTIFIER));
+                                               break;
+                                       }
+                                       case Tokenizer::Token::REGISTER: {
+                                               Tokenizer::Token t2(GetToken());
+                                               AssertTokenType(t.type, Tokenizer::Token::IDENTIFIER, msg);
+                                               script.push_back(new ScriptToken(t2.str, ScriptToken::REGISTER));
+                                               break;
+                                       }
+                                       default:
+                                               throw Error(file, tok.Line(), string("unexpected token in script: ") + TokenTypeToString(t.type));
+                               }
+                       }
+                       t = GetToken();
+               }
+       } catch (...) {
+               for (vector<ScriptToken *>::const_iterator i(script.begin()), end(script.end()); i != end; ++i) {
+                       delete *i;
+               }
+               throw;
+       }
+       return new Literal(script);
+}
+
+
 void Parser::AssertTokenType(Tokenizer::Token::Type actual, Tokenizer::Token::Type expected) {
        if (expected != actual) {
                throw Error(file, tok.Line(), string("unexpected token ") + TokenTypeToString(actual) + ", expected " + TokenTypeToString(expected));
index 392e9b74de5504bc8a8fae64b1b548a117087bd2..963c37710a5fad58e3bd4bf2fb085888b745317a 100644 (file)
@@ -62,6 +62,7 @@ private:
        Literal *ParseArray();
        Literal *ParseColor();
        Literal *ParseVector();
+       Literal *ParseScript();
 
 private:
        void AssertTokenType(Tokenizer::Token::Type actual, Tokenizer::Token::Type expected);
@@ -69,6 +70,7 @@ private:
        bool BeginningOfLiteral(const Tokenizer::Token &) const;
        bool BeginningOfPrimitiveLiteral(const Tokenizer::Token &) const;
        bool BeginOfPropertyList(const Tokenizer::Token &) const;
+       bool BeginningOfScriptLiteral(const Tokenizer::Token &) const;
 
 private:
        std::string file;
index 2f908490569efc0be8e1bd9a550aaaf1e727a043..b8b8458b39ac6df9344aef349c0d1f00a36ef56b 100644 (file)
@@ -20,6 +20,7 @@ class PagedAllocator;
 class ParsedSource;
 class Parser;
 class PropertyList;
+class ScriptToken;
 class Tokenizer;
 class TypeDescription;
 class Value;