From 276a9db6f7a4029215ba232ec5a1b7a1e05f07f8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 22 Aug 2010 11:14:14 +0200 Subject: [PATCH] added missing button implementation for MessageBox --- apps/openmw/mwgui/console.cpp | 35 ++- components/compiler/generator.cpp | 339 ++++++++++++------------- components/compiler/lineparser.cpp | 185 ++++++++------ components/compiler/lineparser.hpp | 21 +- components/interpreter/miscopcodes.hpp | 134 +++++----- 5 files changed, 367 insertions(+), 347 deletions(-) diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index d9148028f2..468cae456b 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -10,16 +10,16 @@ namespace MWGui class ConsoleInterpreterContext : public MWScript::InterpreterContext { Console& mConsole; - + public: - - ConsoleInterpreterContext (Console& console, MWWorld::Environment& environment, + + ConsoleInterpreterContext (Console& console, MWWorld::Environment& environment, MWWorld::Ptr reference); virtual void messageBox (const std::string& message, - const std::vector& buttons); + const std::vector& buttons); }; - + ConsoleInterpreterContext::ConsoleInterpreterContext (Console& console, MWWorld::Environment& environment, MWWorld::Ptr reference) : MWScript::InterpreterContext (environment, @@ -39,18 +39,18 @@ namespace MWGui bool Console::compile (const std::string& cmd, Compiler::Output& output) { try - { + { ErrorHandler::reset(); - + std::istringstream input (cmd + '\n'); - + Compiler::Scanner scanner (*this, input, mCompilerContext.getExtensions()); - + Compiler::LineParser parser (*this, mCompilerContext, output.getLocals(), output.getLiterals(), output.getCode(), true); - + scanner.scan (parser); - + return isGood(); } catch (const Compiler::SourceException& error) @@ -61,7 +61,7 @@ namespace MWGui { printError (std::string ("An exception has been thrown: ") + error.what()); } - + return false; } @@ -69,7 +69,7 @@ namespace MWGui { std::ostringstream error; error << "column " << loc.mColumn << " (" << loc.mLiteral << "):"; - + printError (error.str()); printError ((type==ErrorMessage ? "error: " : "warning: ") + message); } @@ -78,7 +78,7 @@ namespace MWGui { printError ((type==ErrorMessage ? "error: " : "warning: ") + message); } - + Console::Console(int w, int h, MWWorld::Environment& environment, const Compiler::Extensions& extensions) : Layout("openmw_console_layout.xml"), @@ -100,7 +100,7 @@ namespace MWGui history->setOverflowToTheLeft(true); history->setEditStatic(true); history->setVisibleVScroll(true); - + // compiler mCompilerContext.setExtensions (&extensions); } @@ -196,7 +196,7 @@ namespace MWGui Compiler::Locals locals; Compiler::Output output (locals); - if (compile (cm, output)) + if (compile (cm + "\n", output)) { try { @@ -205,7 +205,7 @@ namespace MWGui MWScript::installOpcodes (interpreter); std::vector code; output.getCode (code); - interpreter.run (&code[0], code.size()); + interpreter.run (&code[0], code.size()); } catch (const std::exception& error) { @@ -216,4 +216,3 @@ namespace MWGui command->setCaption(""); } } - diff --git a/components/compiler/generator.cpp b/components/compiler/generator.cpp index 0be2c41511..c5262616bc 100644 --- a/components/compiler/generator.cpp +++ b/components/compiler/generator.cpp @@ -9,46 +9,46 @@ #include "literals.hpp" namespace -{ +{ void opPushInt (Compiler::Generator::CodeContainer& code, int value) { code.push_back (Compiler::Generator::segment0 (0, value)); } - + void opFetchIntLiteral (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (4)); } - + void opFetchFloatLiteral (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (5)); } - + void opIntToFloat (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (3)); + code.push_back (Compiler::Generator::segment5 (3)); } - + void opFloatToInt (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (6)); } - + void opStoreLocalShort (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (0)); + code.push_back (Compiler::Generator::segment5 (0)); } - + void opStoreLocalLong (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (1)); } - + void opStoreLocalFloat (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (2)); - } + } void opNegateInt (Compiler::Generator::CodeContainer& code) { @@ -99,46 +99,46 @@ namespace { code.push_back (Compiler::Generator::segment5 (16)); } - + void opIntToFloat1 (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (17)); + code.push_back (Compiler::Generator::segment5 (17)); } - + void opFloatToInt1 (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (18)); - } + } void opSquareRoot (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (19)); - } + } void opReturn (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (20)); - } - + } + void opMessageBox (Compiler::Generator::CodeContainer& code, int buttons) { code.push_back (Compiler::Generator::segment3 (0, buttons)); } - + void opFetchLocalShort (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (21)); + code.push_back (Compiler::Generator::segment5 (21)); } - + void opFetchLocalLong (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (22)); } - + void opFetchLocalFloat (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (23)); - } + } void opJumpForward (Compiler::Generator::CodeContainer& code, int offset) { @@ -149,176 +149,176 @@ namespace { code.push_back (Compiler::Generator::segment0 (2, offset)); } - + void opSkipOnZero (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (24)); - } - + } + void opSkipOnNonZero (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (25)); - } - + } + void opEqualInt (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (26)); } - + void opNonEqualInt (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (27)); + code.push_back (Compiler::Generator::segment5 (27)); } - + void opLessThanInt (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (28)); + code.push_back (Compiler::Generator::segment5 (28)); } - + void opLessOrEqualInt (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (29)); + code.push_back (Compiler::Generator::segment5 (29)); } - + void opGreaterThanInt (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (30)); + code.push_back (Compiler::Generator::segment5 (30)); } - + void opGreaterOrEqualInt (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (31)); + code.push_back (Compiler::Generator::segment5 (31)); } - + void opEqualFloat (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (32)); } - + void opNonEqualFloat (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (33)); + code.push_back (Compiler::Generator::segment5 (33)); } - + void opLessThanFloat (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (34)); + code.push_back (Compiler::Generator::segment5 (34)); } - + void opLessOrEqualFloat (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (35)); + code.push_back (Compiler::Generator::segment5 (35)); } - + void opGreaterThanFloat (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (36)); + code.push_back (Compiler::Generator::segment5 (36)); } - + void opGreaterOrEqualFloat (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (37)); - } + code.push_back (Compiler::Generator::segment5 (37)); + } void opMenuMode (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (38)); - } - + code.push_back (Compiler::Generator::segment5 (38)); + } + void opStoreGlobalShort (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (39)); + code.push_back (Compiler::Generator::segment5 (39)); } - + void opStoreGlobalLong (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (40)); } - + void opStoreGlobalFloat (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (41)); - } + } void opFetchGlobalShort (Compiler::Generator::CodeContainer& code) { - code.push_back (Compiler::Generator::segment5 (42)); + code.push_back (Compiler::Generator::segment5 (42)); } - + void opFetchGlobalLong (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (43)); } - + void opFetchGlobalFloat (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (44)); - } - + } + void opRandom (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (45)); - } - + } + void opScriptRunning (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (46)); - } - + } + void opStartScript (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (47)); - } - + } + void opStopScript (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (48)); - } - + } + void opGetDistance (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (49)); - } - + } + void opGetSecondsPassed (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (50)); - } + } void opEnable (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (51)); - } + } void opDisable (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (52)); - } + } void opGetDisabled (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (53)); - } + } void opEnableExplicit (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (54)); - } + } void opDisableExplicit (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (55)); - } + } void opGetDisabledExplicit (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (56)); } - + void opGetDistanceExplicit (Compiler::Generator::CodeContainer& code) { code.push_back (Compiler::Generator::segment5 (57)); - } + } } namespace Compiler @@ -327,31 +327,31 @@ namespace Compiler { void pushInt (CodeContainer& code, Literals& literals, int value) { - int index = literals.addInteger (value); + int index = literals.addInteger (value); opPushInt (code, index); - opFetchIntLiteral (code); + opFetchIntLiteral (code); } - + void pushFloat (CodeContainer& code, Literals& literals, float value) { - int index = literals.addFloat (value); + int index = literals.addFloat (value); opPushInt (code, index); opFetchFloatLiteral (code); } - + void pushString (CodeContainer& code, Literals& literals, const std::string& value) { - int index = literals.addString (value); + int index = literals.addString (value); opPushInt (code, index); } - + void assignToLocal (CodeContainer& code, char localType, int localIndex, const CodeContainer& value, char valueType) - { + { opPushInt (code, localIndex); std::copy (value.begin(), value.end(), std::back_inserter (code)); - + if (localType!=valueType) { if (localType=='f' && valueType=='l') @@ -363,26 +363,26 @@ namespace Compiler opFloatToInt (code); } } - + switch (localType) { case 'f': - + opStoreLocalFloat (code); break; - + case 's': opStoreLocalShort (code); break; - + case 'l': opStoreLocalLong (code); break; - + default: - + assert (0); } } @@ -392,21 +392,21 @@ namespace Compiler switch (valueType) { case 'l': - + opNegateInt (code); break; - + case 'f': - + opNegateFloat (code); break; - + default: - + assert (0); } } - + void add (CodeContainer& code, char valueType1, char valueType2) { if (valueType1=='l' && valueType2=='l') @@ -420,7 +420,7 @@ namespace Compiler if (valueType2=='l') opIntToFloat (code); - + opAddFloat (code); } } @@ -438,11 +438,11 @@ namespace Compiler if (valueType2=='l') opIntToFloat (code); - + opSubFloat (code); } } - + void mul (CodeContainer& code, char valueType1, char valueType2) { if (valueType1=='l' && valueType2=='l') @@ -456,11 +456,11 @@ namespace Compiler if (valueType2=='l') opIntToFloat (code); - + opMulFloat (code); - } - } - + } + } + void div (CodeContainer& code, char valueType1, char valueType2) { if (valueType1=='l' && valueType2=='l') @@ -474,11 +474,11 @@ namespace Compiler if (valueType2=='l') opIntToFloat (code); - + opDivFloat (code); - } + } } - + void convert (CodeContainer& code, char fromType, char toType) { if (fromType!=toType) @@ -491,28 +491,26 @@ namespace Compiler throw std::logic_error ("illegal type conversion"); } } - + void squareRoot (CodeContainer& code) { opSquareRoot (code); } - + void exit (CodeContainer& code) { opReturn (code); - } - + } + void message (CodeContainer& code, Literals& literals, const std::string& message, int buttons) { - assert (buttons==0); - int index = literals.addString (message); - + opPushInt (code, index); opMessageBox (code, buttons); } - + void fetchLocal (CodeContainer& code, char localType, int localIndex) { opPushInt (code, localIndex); @@ -520,26 +518,26 @@ namespace Compiler switch (localType) { case 'f': - + opFetchLocalFloat (code); break; - + case 's': opFetchLocalShort (code); break; - + case 'l': opFetchLocalLong (code); break; - + default: - + assert (0); - } + } } - + void jump (CodeContainer& code, int offset) { if (offset>0) @@ -549,27 +547,27 @@ namespace Compiler else throw std::logic_error ("inifite loop"); } - + void jumpOnZero (CodeContainer& code, int offset) { opSkipOnNonZero (code); - + if (offset<0) --offset; // compensate for skip instruction - + jump (code, offset); } void jumpOnNonZero (CodeContainer& code, int offset) { opSkipOnZero (code); - + if (offset<0) --offset; // compensate for skip instruction - - jump (code, offset); + + jump (code, offset); } - + void compare (CodeContainer& code, char op, char valueType1, char valueType2) { if (valueType1=='l' && valueType2=='l') @@ -582,9 +580,9 @@ namespace Compiler case 'L': opLessOrEqualInt (code); break; case 'g': opGreaterThanInt (code); break; case 'G': opGreaterOrEqualInt (code); break; - + default: - + assert (0); } } @@ -595,7 +593,7 @@ namespace Compiler if (valueType2=='l') opIntToFloat (code); - + switch (op) { case 'e': opEqualFloat (code); break; @@ -604,28 +602,28 @@ namespace Compiler case 'L': opLessOrEqualFloat (code); break; case 'g': opGreaterThanFloat (code); break; case 'G': opGreaterOrEqualFloat (code); break; - + default: - + assert (0); } - } + } } - + void menuMode (CodeContainer& code) { opMenuMode (code); } - + void assignToGlobal (CodeContainer& code, Literals& literals, char localType, const std::string& name, const CodeContainer& value, char valueType) { int index = literals.addString (name); - + opPushInt (code, index); std::copy (value.begin(), value.end(), std::back_inserter (code)); - + if (localType!=valueType) { if (localType=='f' && valueType=='l') @@ -637,30 +635,30 @@ namespace Compiler opFloatToInt (code); } } - + switch (localType) { case 'f': - + opStoreGlobalFloat (code); break; - + case 's': opStoreGlobalShort (code); break; - + case 'l': opStoreGlobalLong (code); break; - + default: - + assert (0); - } + } } - + void fetchGlobal (CodeContainer& code, Literals& literals, char localType, const std::string& name) { @@ -671,36 +669,36 @@ namespace Compiler switch (localType) { case 'f': - + opFetchGlobalFloat (code); break; - + case 's': opFetchGlobalShort (code); break; - + case 'l': opFetchGlobalLong (code); break; - + default: - + assert (0); - } + } } - + void random (CodeContainer& code) { opRandom (code); } - + void scriptRunning (CodeContainer& code) { opScriptRunning (code); } - + void startScript (CodeContainer& code) { opStartScript (code); @@ -714,7 +712,7 @@ namespace Compiler void getDistance (CodeContainer& code, Literals& literals, const std::string id) { if (id.empty()) - { + { opGetDistance (code); } else @@ -722,14 +720,14 @@ namespace Compiler int index = literals.addString (id); opPushInt (code, index); opGetDistanceExplicit (code); - } - } - + } + } + void getSecondsPassed (CodeContainer& code) { opGetSecondsPassed (code); } - + void getDisabled (CodeContainer& code, Literals& literals, const std::string id) { if (id.empty()) @@ -743,11 +741,11 @@ namespace Compiler opGetDisabledExplicit (code); } } - + void enable (CodeContainer& code, Literals& literals, const std::string id) { if (id.empty()) - { + { opEnable (code); } else @@ -755,13 +753,13 @@ namespace Compiler int index = literals.addString (id); opPushInt (code, index); opEnableExplicit (code); - } + } } - + void disable (CodeContainer& code, Literals& literals, const std::string id) { if (id.empty()) - { + { opDisable (code); } else @@ -773,4 +771,3 @@ namespace Compiler } } } - diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index 927990a328..b4c79c972e 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -14,32 +14,32 @@ namespace Compiler void LineParser::parseExpression (Scanner& scanner, const TokenLoc& loc) { mExprParser.reset(); - + if (!mExplicit.empty()) { mExprParser.parseName (mExplicit, loc, scanner); mExprParser.parseSpecial (Scanner::S_ref, loc, scanner); } - + scanner.scan (mExprParser); - + char type = mExprParser.append (mCode); - mState = EndState; - + mState = EndState; + switch (type) { case 'l': - - Generator::message (mCode, mLiterals, "%g", 0); + + Generator::message (mCode, mLiterals, "%g", 0); break; - + case 'f': - - Generator::message (mCode, mLiterals, "%f", 0); + + Generator::message (mCode, mLiterals, "%f", 0); break; - + default: - + throw std::runtime_error ("unknown expression result type"); } } @@ -52,14 +52,14 @@ namespace Compiler {} bool LineParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner) - { + { if (mAllowExpression && mState==BeginState) { scanner.putbackInt (value, loc); parseExpression (scanner, loc); return true; } - + return Parser::parseInt (value, loc, scanner); } @@ -71,7 +71,7 @@ namespace Compiler parseExpression (scanner, loc); return true; } - + return Parser::parseFloat (value, loc, scanner); } @@ -87,11 +87,11 @@ namespace Compiler scanner.scan (skip); return false; } - + std::string name2 = toLower (name); - + char type = mLocals.getType (name2); - + if (type!=' ') { getErrorHandler().error ("can't re-declare local variable", loc); @@ -99,14 +99,14 @@ namespace Compiler scanner.scan (skip); return false; } - + mLocals.declare (mState==ShortState ? 's' : (mState==LongState ? 'l' : 'f'), name2); - + mState = EndState; return true; } - + if (mState==SetState) { std::string name2 = toLower (name); @@ -119,7 +119,7 @@ namespace Compiler mState = SetLocalVarState; return true; } - + type = getContext().getGlobalType (name2); if (type!=' ') { @@ -127,18 +127,18 @@ namespace Compiler mType = type; mState = SetGlobalVarState; return true; - } - + } + getErrorHandler().error ("unknown variable", loc); SkipParser skip (getErrorHandler(), getContext()); scanner.scan (skip); - return false; + return false; } - + if (mState==MessageState || mState==MessageCommaState) { std::string arguments; - + for (std::size_t i=0; iisInstruction (keyword, argumentType, mState==ExplicitState)) { mExprParser.parseArguments (argumentType, scanner, mCode, true); - + extensions->generateInstructionCode (keyword, mCode, mLiterals, mExplicit); mState = EndState; return true; } - } - + } + if (mAllowExpression) { if (keyword==Scanner::K_getdisabled || keyword==Scanner::K_getdistance) { scanner.putbackKeyword (keyword, loc); parseExpression (scanner, loc); - return true; + return true; } if (const Extensions *extensions = getContext().getExtensions()) { char returnType; std::string argumentType; - + if (extensions->isFunction (keyword, returnType, argumentType, !mExplicit.empty())) { scanner.putbackKeyword (keyword, loc); parseExpression (scanner, loc); - return true; + return true; } - } + } } } - + if (mState==BeginState) { switch (keyword) @@ -278,39 +284,39 @@ namespace Compiler case Scanner::K_float: mState = FloatState; return true; case Scanner::K_set: mState = SetState; return true; case Scanner::K_messagebox: mState = MessageState; return true; - + case Scanner::K_return: - + Generator::exit (mCode); mState = EndState; return true; - + case Scanner::K_startscript: - mExprParser.parseArguments ("c", scanner, mCode, true); + mExprParser.parseArguments ("c", scanner, mCode, true); Generator::startScript (mCode); mState = EndState; - return true; - + return true; + case Scanner::K_stopscript: - mExprParser.parseArguments ("c", scanner, mCode, true); + mExprParser.parseArguments ("c", scanner, mCode, true); Generator::stopScript (mCode); mState = EndState; - return true; + return true; } } else if (mState==SetLocalVarState && keyword==Scanner::K_to) { mExprParser.reset(); scanner.scan (mExprParser); - + std::vector code; char type = mExprParser.append (code); - + Generator::assignToLocal (mCode, mLocals.getType (mName), mLocals.getIndex (mName), code, type); - + mState = EndState; return true; } @@ -318,16 +324,16 @@ namespace Compiler { mExprParser.reset(); scanner.scan (mExprParser); - + std::vector code; char type = mExprParser.append (code); - + Generator::assignToGlobal (mCode, mLiterals, mType, mName, code, type); - + mState = EndState; return true; } - + if (mAllowExpression) { if (keyword==Scanner::K_getsquareroot || keyword==Scanner::K_menumode || @@ -336,10 +342,10 @@ namespace Compiler { scanner.putbackKeyword (keyword, loc); parseExpression (scanner, loc); - return true; - } + return true; + } } - + return Parser::parseKeyword (keyword, loc, scanner); } @@ -347,30 +353,42 @@ namespace Compiler { if (code==Scanner::S_newline && (mState==EndState || mState==BeginState)) return false; - + if (code==Scanner::S_comma && mState==MessageState) { mState = MessageCommaState; return true; } - + if (code==Scanner::S_ref && mState==PotentialExplicitState) { mState = ExplicitState; return true; } - + + if (code==Scanner::S_newline && mState==MessageButtonState) + { + Generator::message (mCode, mLiterals, mName, mButtons); + return false; + } + + if (code==Scanner::S_comma && mState==MessageButtonState) + { + mState = MessageButtonCommaState; + return true; + } + if (mAllowExpression && mState==BeginState && (code==Scanner::S_open || code==Scanner::S_minus)) { scanner.putbackSpecial (code, loc); parseExpression (scanner, loc); - return true; + return true; } - + return Parser::parseSpecial (code, loc, scanner); } - + void LineParser::reset() { mState = BeginState; @@ -378,4 +396,3 @@ namespace Compiler mExplicit.clear(); } } - diff --git a/components/compiler/lineparser.hpp b/components/compiler/lineparser.hpp index c407d3b6b8..531b7762f0 100644 --- a/components/compiler/lineparser.hpp +++ b/components/compiler/lineparser.hpp @@ -12,9 +12,9 @@ namespace Compiler { class Locals; class Literals; - + /// \brief Line parser, to be used in console scripts and as part of ScriptParser - + class LineParser : public Parser { enum State @@ -22,31 +22,32 @@ namespace Compiler BeginState, ShortState, LongState, FloatState, SetState, SetLocalVarState, SetGlobalVarState, - MessageState, MessageCommaState, + MessageState, MessageCommaState, MessageButtonState, MessageButtonCommaState, EndState, PotentialExplicitState, ExplicitState }; - Locals& mLocals; + Locals& mLocals; Literals& mLiterals; std::vector& mCode; State mState; std::string mName; + int mButtons; std::string mExplicit; char mType; ExprParser mExprParser; bool mAllowExpression; - + void parseExpression (Scanner& scanner, const TokenLoc& loc); - + public: - + LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals, Literals& literals, std::vector& code, bool allowExpression = false); ///< \param allowExpression Allow lines consisting of a naked expression /// (result is send to the messagebox interface) - + virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner); ///< Handle an int token. /// \return fetch another token? @@ -67,9 +68,9 @@ namespace Compiler virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner); ///< Handle a special character token. /// \return fetch another token? - + void reset(); - ///< Reset parser to clean state. + ///< Reset parser to clean state. }; } diff --git a/components/interpreter/miscopcodes.hpp b/components/interpreter/miscopcodes.hpp index 8d05c58da6..7e7dcd18a7 100644 --- a/components/interpreter/miscopcodes.hpp +++ b/components/interpreter/miscopcodes.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "opcodes.hpp" #include "runtime.hpp" @@ -15,24 +16,33 @@ namespace Interpreter class OpMessageBox : public Opcode1 { public: - + virtual void execute (Runtime& runtime, unsigned int arg0) { - if (arg0!=0) - throw std::logic_error ("message box buttons not implemented yet"); - - // message + // buttons + std::vector buttons; + + for (std::size_t i=0; i buttons; - + runtime.getContext().messageBox (formattedMessage, buttons); - } - }; - + } + }; + class OpMenuMode : public Opcode0 { public: - + virtual void execute (Runtime& runtime) { runtime.push (runtime.getContext().menuMode()); - } + } }; - + class OpRandom : public Opcode0 { public: - + virtual void execute (Runtime& runtime) { double r = static_cast (std::rand()) / RAND_MAX; // [0, 1) - + Type_Integer limit = runtime[0].mInteger; - + if (limit<0) throw std::runtime_error ( "random: argument out of range (Don't be so negative!)"); - + Type_Integer value = static_cast (r*limit); // [o, limit) - + runtime[0].mInteger = value; - } - }; - + } + }; + class OpGetSecondsPassed : public Opcode0 { public: - + virtual void execute (Runtime& runtime) { Type_Float duration = runtime.getContext().getSecondsPassed(); - + runtime.push (duration); - } + } }; - + class OpEnable : public Opcode0 { public: - + virtual void execute (Runtime& runtime) { runtime.getContext().enable(); - } - }; - + } + }; + class OpDisable : public Opcode0 { public: - + virtual void execute (Runtime& runtime) { runtime.getContext().disable(); - } - }; - + } + }; + class OpGetDisabled : public Opcode0 { public: - + virtual void execute (Runtime& runtime) { runtime.push (runtime.getContext().isDisabled()); - } - }; - + } + }; + class OpEnableExplicit : public Opcode0 { public: - + virtual void execute (Runtime& runtime) { int index = runtime[0].mInteger; runtime.pop(); std::string id = runtime.getStringLiteral (index); - + runtime.getContext().enable (id); - } - }; - + } + }; + class OpDisableExplicit : public Opcode0 { public: - + virtual void execute (Runtime& runtime) { int index = runtime[0].mInteger; runtime.pop(); std::string id = runtime.getStringLiteral (index); - + runtime.getContext().disable (id); - } - }; - + } + }; + class OpGetDisabledExplicit : public Opcode0 { public: - + virtual void execute (Runtime& runtime) { int index = runtime[0].mInteger; runtime.pop(); std::string id = runtime.getStringLiteral (index); - + runtime.push (runtime.getContext().isDisabled (id)); - } - }; - + } + }; + } #endif -