From 535f472174fd386567bec7002f645183b80cb2ef Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Sun, 14 Oct 2012 23:19:58 +0200 Subject: [PATCH] added script labels in parser/interpreter --- src/loader/Interpreter.cpp | 26 ++++++++++++++++++-------- src/loader/ParsedSource.cpp | 10 +++++++++- src/loader/ParsedSource.h | 4 +++- src/loader/Parser.cpp | 8 +++++++- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/loader/Interpreter.cpp b/src/loader/Interpreter.cpp index 0fd2d88..bd7473a 100644 --- a/src/loader/Interpreter.cpp +++ b/src/loader/Interpreter.cpp @@ -343,9 +343,16 @@ void Interpreter::ReadObject(int typeId, int id, char *object, const PropertyLis void Interpreter::ReadScript(const std::vector &s, Script *script) { + std::map labels; int size(0); for (vector::const_iterator i(s.begin()), end(s.end()); i != end; ++i) { - if ((*i)->GetType() != ScriptToken::COMMAND) { + if ((*i)->GetType() == ScriptToken::LABEL) { + if (labels.count((*i)->Label())) { + throw Error("duplicate label " + (*i)->Label()); + } else { + labels[(*i)->Label()] = size; + } + } else if ((*i)->GetType() != ScriptToken::COMMAND) { throw Error("unexpected script token"); } ++size; @@ -423,6 +430,9 @@ void Interpreter::ReadScript(const std::vector &s, Script *script unsigned char *text(reinterpret_cast(alloc.Alloc(size))); int cursor(0); for (vector::const_iterator i(s.begin()), end(s.end()); i != end; ++i) { + if ((*i)->GetType() == ScriptToken::LABEL) { + continue; + } if ((*i)->GetType() != ScriptToken::COMMAND) { throw Error("unexpected script token"); } @@ -544,9 +554,9 @@ void Interpreter::ReadScriptAddress(const ScriptToken &t, unsigned char *dest) { if (t.GetType() != ScriptToken::IDENTIFIER) { throw Error("expected identifier for address"); } - if (source.IsDefined(t.GetIdentifier())) { - const ParsedDefinition &def(GetDefinition(t.GetIdentifier())); - void *addr(GetObject(def.type, t.GetIdentifier())); + if (source.IsDefined(t.Identifier())) { + const ParsedDefinition &def(GetDefinition(t.Identifier())); + void *addr(GetObject(def.type, t.Identifier())); *reinterpret_cast(dest) = addr; } else { throw Error("postponing values in scripts not implemented"); @@ -555,8 +565,8 @@ void Interpreter::ReadScriptAddress(const ScriptToken &t, unsigned char *dest) { void Interpreter::ReadScriptInteger(const ScriptToken &t, unsigned char *dest) { if (t.GetType() == ScriptToken::IDENTIFIER) { - if (source.IsDefined(t.GetIdentifier())) { - void *num(GetObject(TypeDescription::GetTypeId("Number"), t.GetIdentifier())); + if (source.IsDefined(t.Identifier())) { + void *num(GetObject(TypeDescription::GetTypeId("Number"), t.Identifier())); *reinterpret_cast(dest) = *reinterpret_cast(num); } else { throw Error("postponing values in scripts not implemented"); @@ -570,8 +580,8 @@ void Interpreter::ReadScriptInteger(const ScriptToken &t, unsigned char *dest) { void Interpreter::ReadScriptVector(const ScriptToken &t, unsigned char *dest) { if (t.GetType() == ScriptToken::IDENTIFIER) { - if (source.IsDefined(t.GetIdentifier())) { - void *vec(GetObject(TypeDescription::GetTypeId("Vector"), t.GetIdentifier())); + if (source.IsDefined(t.Identifier())) { + void *vec(GetObject(TypeDescription::GetTypeId("Vector"), t.Identifier())); *reinterpret_cast *>(dest) = *reinterpret_cast *>(vec); } else { throw Error("postponing values in scripts not implemented"); diff --git a/src/loader/ParsedSource.cpp b/src/loader/ParsedSource.cpp index 6b2fc80..8c3d3bd 100644 --- a/src/loader/ParsedSource.cpp +++ b/src/loader/ParsedSource.cpp @@ -485,7 +485,7 @@ const string &ScriptToken::CommandName() const { } } -const string &ScriptToken::GetIdentifier() const { +const string &ScriptToken::Identifier() const { if (type == IDENTIFIER) { return str; } else { @@ -493,6 +493,14 @@ const string &ScriptToken::GetIdentifier() const { } } +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; diff --git a/src/loader/ParsedSource.h b/src/loader/ParsedSource.h index 9ba5297..6a7a2d4 100644 --- a/src/loader/ParsedSource.h +++ b/src/loader/ParsedSource.h @@ -26,6 +26,7 @@ public: REGISTER, IDENTIFIER, LITERAL, + LABEL, }; ScriptToken(const std::string &, Type); @@ -39,7 +40,8 @@ public: Type GetType() const { return type; } const std::string &RegisterName() const; const std::string &CommandName() const; - const std::string &GetIdentifier() const; + const std::string &Identifier() const; + const std::string &Label() const; const Literal *GetLiteral() const; private: diff --git a/src/loader/Parser.cpp b/src/loader/Parser.cpp index 9ddae34..9641fad 100644 --- a/src/loader/Parser.cpp +++ b/src/loader/Parser.cpp @@ -371,7 +371,13 @@ Literal *Parser::ParseScript() { break; } case Token::IDENTIFIER: { - script.push_back(new ScriptToken(t.str, ScriptToken::IDENTIFIER)); + Token t2(GetToken()); + if (t2.type == Token::COLON) { + script.push_back(new ScriptToken(t.str, ScriptToken::LABEL)); + } else { + tok.Putback(t2); + script.push_back(new ScriptToken(t.str, ScriptToken::IDENTIFIER)); + } break; } case Token::REGISTER: { -- 2.39.2