1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-19 12:09:42 +00:00

added missing button implementation for MessageBox

This commit is contained in:
Marc Zinnschlag 2010-08-22 11:14:14 +02:00
parent 72cc0a3983
commit 276a9db6f7
5 changed files with 367 additions and 347 deletions

View file

@ -10,16 +10,16 @@ namespace MWGui
class ConsoleInterpreterContext : public MWScript::InterpreterContext class ConsoleInterpreterContext : public MWScript::InterpreterContext
{ {
Console& mConsole; Console& mConsole;
public: public:
ConsoleInterpreterContext (Console& console, MWWorld::Environment& environment, ConsoleInterpreterContext (Console& console, MWWorld::Environment& environment,
MWWorld::Ptr reference); MWWorld::Ptr reference);
virtual void messageBox (const std::string& message, virtual void messageBox (const std::string& message,
const std::vector<std::string>& buttons); const std::vector<std::string>& buttons);
}; };
ConsoleInterpreterContext::ConsoleInterpreterContext (Console& console, ConsoleInterpreterContext::ConsoleInterpreterContext (Console& console,
MWWorld::Environment& environment, MWWorld::Ptr reference) MWWorld::Environment& environment, MWWorld::Ptr reference)
: MWScript::InterpreterContext (environment, : MWScript::InterpreterContext (environment,
@ -39,18 +39,18 @@ namespace MWGui
bool Console::compile (const std::string& cmd, Compiler::Output& output) bool Console::compile (const std::string& cmd, Compiler::Output& output)
{ {
try try
{ {
ErrorHandler::reset(); ErrorHandler::reset();
std::istringstream input (cmd + '\n'); std::istringstream input (cmd + '\n');
Compiler::Scanner scanner (*this, input, mCompilerContext.getExtensions()); Compiler::Scanner scanner (*this, input, mCompilerContext.getExtensions());
Compiler::LineParser parser (*this, mCompilerContext, output.getLocals(), Compiler::LineParser parser (*this, mCompilerContext, output.getLocals(),
output.getLiterals(), output.getCode(), true); output.getLiterals(), output.getCode(), true);
scanner.scan (parser); scanner.scan (parser);
return isGood(); return isGood();
} }
catch (const Compiler::SourceException& error) catch (const Compiler::SourceException& error)
@ -61,7 +61,7 @@ namespace MWGui
{ {
printError (std::string ("An exception has been thrown: ") + error.what()); printError (std::string ("An exception has been thrown: ") + error.what());
} }
return false; return false;
} }
@ -69,7 +69,7 @@ namespace MWGui
{ {
std::ostringstream error; std::ostringstream error;
error << "column " << loc.mColumn << " (" << loc.mLiteral << "):"; error << "column " << loc.mColumn << " (" << loc.mLiteral << "):";
printError (error.str()); printError (error.str());
printError ((type==ErrorMessage ? "error: " : "warning: ") + message); printError ((type==ErrorMessage ? "error: " : "warning: ") + message);
} }
@ -78,7 +78,7 @@ namespace MWGui
{ {
printError ((type==ErrorMessage ? "error: " : "warning: ") + message); printError ((type==ErrorMessage ? "error: " : "warning: ") + message);
} }
Console::Console(int w, int h, MWWorld::Environment& environment, Console::Console(int w, int h, MWWorld::Environment& environment,
const Compiler::Extensions& extensions) const Compiler::Extensions& extensions)
: Layout("openmw_console_layout.xml"), : Layout("openmw_console_layout.xml"),
@ -100,7 +100,7 @@ namespace MWGui
history->setOverflowToTheLeft(true); history->setOverflowToTheLeft(true);
history->setEditStatic(true); history->setEditStatic(true);
history->setVisibleVScroll(true); history->setVisibleVScroll(true);
// compiler // compiler
mCompilerContext.setExtensions (&extensions); mCompilerContext.setExtensions (&extensions);
} }
@ -196,7 +196,7 @@ namespace MWGui
Compiler::Locals locals; Compiler::Locals locals;
Compiler::Output output (locals); Compiler::Output output (locals);
if (compile (cm, output)) if (compile (cm + "\n", output))
{ {
try try
{ {
@ -205,7 +205,7 @@ namespace MWGui
MWScript::installOpcodes (interpreter); MWScript::installOpcodes (interpreter);
std::vector<Interpreter::Type_Code> code; std::vector<Interpreter::Type_Code> code;
output.getCode (code); output.getCode (code);
interpreter.run (&code[0], code.size()); interpreter.run (&code[0], code.size());
} }
catch (const std::exception& error) catch (const std::exception& error)
{ {
@ -216,4 +216,3 @@ namespace MWGui
command->setCaption(""); command->setCaption("");
} }
} }

View file

@ -9,46 +9,46 @@
#include "literals.hpp" #include "literals.hpp"
namespace namespace
{ {
void opPushInt (Compiler::Generator::CodeContainer& code, int value) void opPushInt (Compiler::Generator::CodeContainer& code, int value)
{ {
code.push_back (Compiler::Generator::segment0 (0, value)); code.push_back (Compiler::Generator::segment0 (0, value));
} }
void opFetchIntLiteral (Compiler::Generator::CodeContainer& code) void opFetchIntLiteral (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (4)); code.push_back (Compiler::Generator::segment5 (4));
} }
void opFetchFloatLiteral (Compiler::Generator::CodeContainer& code) void opFetchFloatLiteral (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (5)); code.push_back (Compiler::Generator::segment5 (5));
} }
void opIntToFloat (Compiler::Generator::CodeContainer& code) 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) void opFloatToInt (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (6)); code.push_back (Compiler::Generator::segment5 (6));
} }
void opStoreLocalShort (Compiler::Generator::CodeContainer& code) 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) void opStoreLocalLong (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (1)); code.push_back (Compiler::Generator::segment5 (1));
} }
void opStoreLocalFloat (Compiler::Generator::CodeContainer& code) void opStoreLocalFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (2)); code.push_back (Compiler::Generator::segment5 (2));
} }
void opNegateInt (Compiler::Generator::CodeContainer& code) void opNegateInt (Compiler::Generator::CodeContainer& code)
{ {
@ -99,46 +99,46 @@ namespace
{ {
code.push_back (Compiler::Generator::segment5 (16)); code.push_back (Compiler::Generator::segment5 (16));
} }
void opIntToFloat1 (Compiler::Generator::CodeContainer& code) 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) void opFloatToInt1 (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (18)); code.push_back (Compiler::Generator::segment5 (18));
} }
void opSquareRoot (Compiler::Generator::CodeContainer& code) void opSquareRoot (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (19)); code.push_back (Compiler::Generator::segment5 (19));
} }
void opReturn (Compiler::Generator::CodeContainer& code) void opReturn (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (20)); code.push_back (Compiler::Generator::segment5 (20));
} }
void opMessageBox (Compiler::Generator::CodeContainer& code, int buttons) void opMessageBox (Compiler::Generator::CodeContainer& code, int buttons)
{ {
code.push_back (Compiler::Generator::segment3 (0, buttons)); code.push_back (Compiler::Generator::segment3 (0, buttons));
} }
void opFetchLocalShort (Compiler::Generator::CodeContainer& code) 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) void opFetchLocalLong (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (22)); code.push_back (Compiler::Generator::segment5 (22));
} }
void opFetchLocalFloat (Compiler::Generator::CodeContainer& code) void opFetchLocalFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (23)); code.push_back (Compiler::Generator::segment5 (23));
} }
void opJumpForward (Compiler::Generator::CodeContainer& code, int offset) void opJumpForward (Compiler::Generator::CodeContainer& code, int offset)
{ {
@ -149,176 +149,176 @@ namespace
{ {
code.push_back (Compiler::Generator::segment0 (2, offset)); code.push_back (Compiler::Generator::segment0 (2, offset));
} }
void opSkipOnZero (Compiler::Generator::CodeContainer& code) void opSkipOnZero (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (24)); code.push_back (Compiler::Generator::segment5 (24));
} }
void opSkipOnNonZero (Compiler::Generator::CodeContainer& code) void opSkipOnNonZero (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (25)); code.push_back (Compiler::Generator::segment5 (25));
} }
void opEqualInt (Compiler::Generator::CodeContainer& code) void opEqualInt (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (26)); code.push_back (Compiler::Generator::segment5 (26));
} }
void opNonEqualInt (Compiler::Generator::CodeContainer& code) 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) 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) 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) 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) 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) void opEqualFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (32)); code.push_back (Compiler::Generator::segment5 (32));
} }
void opNonEqualFloat (Compiler::Generator::CodeContainer& code) 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) 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) 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) 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) 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) 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) 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) void opStoreGlobalLong (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (40)); code.push_back (Compiler::Generator::segment5 (40));
} }
void opStoreGlobalFloat (Compiler::Generator::CodeContainer& code) void opStoreGlobalFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (41)); code.push_back (Compiler::Generator::segment5 (41));
} }
void opFetchGlobalShort (Compiler::Generator::CodeContainer& code) 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) void opFetchGlobalLong (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (43)); code.push_back (Compiler::Generator::segment5 (43));
} }
void opFetchGlobalFloat (Compiler::Generator::CodeContainer& code) void opFetchGlobalFloat (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (44)); code.push_back (Compiler::Generator::segment5 (44));
} }
void opRandom (Compiler::Generator::CodeContainer& code) void opRandom (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (45)); code.push_back (Compiler::Generator::segment5 (45));
} }
void opScriptRunning (Compiler::Generator::CodeContainer& code) void opScriptRunning (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (46)); code.push_back (Compiler::Generator::segment5 (46));
} }
void opStartScript (Compiler::Generator::CodeContainer& code) void opStartScript (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (47)); code.push_back (Compiler::Generator::segment5 (47));
} }
void opStopScript (Compiler::Generator::CodeContainer& code) void opStopScript (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (48)); code.push_back (Compiler::Generator::segment5 (48));
} }
void opGetDistance (Compiler::Generator::CodeContainer& code) void opGetDistance (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (49)); code.push_back (Compiler::Generator::segment5 (49));
} }
void opGetSecondsPassed (Compiler::Generator::CodeContainer& code) void opGetSecondsPassed (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (50)); code.push_back (Compiler::Generator::segment5 (50));
} }
void opEnable (Compiler::Generator::CodeContainer& code) void opEnable (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (51)); code.push_back (Compiler::Generator::segment5 (51));
} }
void opDisable (Compiler::Generator::CodeContainer& code) void opDisable (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (52)); code.push_back (Compiler::Generator::segment5 (52));
} }
void opGetDisabled (Compiler::Generator::CodeContainer& code) void opGetDisabled (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (53)); code.push_back (Compiler::Generator::segment5 (53));
} }
void opEnableExplicit (Compiler::Generator::CodeContainer& code) void opEnableExplicit (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (54)); code.push_back (Compiler::Generator::segment5 (54));
} }
void opDisableExplicit (Compiler::Generator::CodeContainer& code) void opDisableExplicit (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (55)); code.push_back (Compiler::Generator::segment5 (55));
} }
void opGetDisabledExplicit (Compiler::Generator::CodeContainer& code) void opGetDisabledExplicit (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (56)); code.push_back (Compiler::Generator::segment5 (56));
} }
void opGetDistanceExplicit (Compiler::Generator::CodeContainer& code) void opGetDistanceExplicit (Compiler::Generator::CodeContainer& code)
{ {
code.push_back (Compiler::Generator::segment5 (57)); code.push_back (Compiler::Generator::segment5 (57));
} }
} }
namespace Compiler namespace Compiler
@ -327,31 +327,31 @@ namespace Compiler
{ {
void pushInt (CodeContainer& code, Literals& literals, int value) void pushInt (CodeContainer& code, Literals& literals, int value)
{ {
int index = literals.addInteger (value); int index = literals.addInteger (value);
opPushInt (code, index); opPushInt (code, index);
opFetchIntLiteral (code); opFetchIntLiteral (code);
} }
void pushFloat (CodeContainer& code, Literals& literals, float value) void pushFloat (CodeContainer& code, Literals& literals, float value)
{ {
int index = literals.addFloat (value); int index = literals.addFloat (value);
opPushInt (code, index); opPushInt (code, index);
opFetchFloatLiteral (code); opFetchFloatLiteral (code);
} }
void pushString (CodeContainer& code, Literals& literals, const std::string& value) void pushString (CodeContainer& code, Literals& literals, const std::string& value)
{ {
int index = literals.addString (value); int index = literals.addString (value);
opPushInt (code, index); opPushInt (code, index);
} }
void assignToLocal (CodeContainer& code, char localType, void assignToLocal (CodeContainer& code, char localType,
int localIndex, const CodeContainer& value, char valueType) int localIndex, const CodeContainer& value, char valueType)
{ {
opPushInt (code, localIndex); opPushInt (code, localIndex);
std::copy (value.begin(), value.end(), std::back_inserter (code)); std::copy (value.begin(), value.end(), std::back_inserter (code));
if (localType!=valueType) if (localType!=valueType)
{ {
if (localType=='f' && valueType=='l') if (localType=='f' && valueType=='l')
@ -363,26 +363,26 @@ namespace Compiler
opFloatToInt (code); opFloatToInt (code);
} }
} }
switch (localType) switch (localType)
{ {
case 'f': case 'f':
opStoreLocalFloat (code); opStoreLocalFloat (code);
break; break;
case 's': case 's':
opStoreLocalShort (code); opStoreLocalShort (code);
break; break;
case 'l': case 'l':
opStoreLocalLong (code); opStoreLocalLong (code);
break; break;
default: default:
assert (0); assert (0);
} }
} }
@ -392,21 +392,21 @@ namespace Compiler
switch (valueType) switch (valueType)
{ {
case 'l': case 'l':
opNegateInt (code); opNegateInt (code);
break; break;
case 'f': case 'f':
opNegateFloat (code); opNegateFloat (code);
break; break;
default: default:
assert (0); assert (0);
} }
} }
void add (CodeContainer& code, char valueType1, char valueType2) void add (CodeContainer& code, char valueType1, char valueType2)
{ {
if (valueType1=='l' && valueType2=='l') if (valueType1=='l' && valueType2=='l')
@ -420,7 +420,7 @@ namespace Compiler
if (valueType2=='l') if (valueType2=='l')
opIntToFloat (code); opIntToFloat (code);
opAddFloat (code); opAddFloat (code);
} }
} }
@ -438,11 +438,11 @@ namespace Compiler
if (valueType2=='l') if (valueType2=='l')
opIntToFloat (code); opIntToFloat (code);
opSubFloat (code); opSubFloat (code);
} }
} }
void mul (CodeContainer& code, char valueType1, char valueType2) void mul (CodeContainer& code, char valueType1, char valueType2)
{ {
if (valueType1=='l' && valueType2=='l') if (valueType1=='l' && valueType2=='l')
@ -456,11 +456,11 @@ namespace Compiler
if (valueType2=='l') if (valueType2=='l')
opIntToFloat (code); opIntToFloat (code);
opMulFloat (code); opMulFloat (code);
} }
} }
void div (CodeContainer& code, char valueType1, char valueType2) void div (CodeContainer& code, char valueType1, char valueType2)
{ {
if (valueType1=='l' && valueType2=='l') if (valueType1=='l' && valueType2=='l')
@ -474,11 +474,11 @@ namespace Compiler
if (valueType2=='l') if (valueType2=='l')
opIntToFloat (code); opIntToFloat (code);
opDivFloat (code); opDivFloat (code);
} }
} }
void convert (CodeContainer& code, char fromType, char toType) void convert (CodeContainer& code, char fromType, char toType)
{ {
if (fromType!=toType) if (fromType!=toType)
@ -491,28 +491,26 @@ namespace Compiler
throw std::logic_error ("illegal type conversion"); throw std::logic_error ("illegal type conversion");
} }
} }
void squareRoot (CodeContainer& code) void squareRoot (CodeContainer& code)
{ {
opSquareRoot (code); opSquareRoot (code);
} }
void exit (CodeContainer& code) void exit (CodeContainer& code)
{ {
opReturn (code); opReturn (code);
} }
void message (CodeContainer& code, Literals& literals, const std::string& message, void message (CodeContainer& code, Literals& literals, const std::string& message,
int buttons) int buttons)
{ {
assert (buttons==0);
int index = literals.addString (message); int index = literals.addString (message);
opPushInt (code, index); opPushInt (code, index);
opMessageBox (code, buttons); opMessageBox (code, buttons);
} }
void fetchLocal (CodeContainer& code, char localType, int localIndex) void fetchLocal (CodeContainer& code, char localType, int localIndex)
{ {
opPushInt (code, localIndex); opPushInt (code, localIndex);
@ -520,26 +518,26 @@ namespace Compiler
switch (localType) switch (localType)
{ {
case 'f': case 'f':
opFetchLocalFloat (code); opFetchLocalFloat (code);
break; break;
case 's': case 's':
opFetchLocalShort (code); opFetchLocalShort (code);
break; break;
case 'l': case 'l':
opFetchLocalLong (code); opFetchLocalLong (code);
break; break;
default: default:
assert (0); assert (0);
} }
} }
void jump (CodeContainer& code, int offset) void jump (CodeContainer& code, int offset)
{ {
if (offset>0) if (offset>0)
@ -549,27 +547,27 @@ namespace Compiler
else else
throw std::logic_error ("inifite loop"); throw std::logic_error ("inifite loop");
} }
void jumpOnZero (CodeContainer& code, int offset) void jumpOnZero (CodeContainer& code, int offset)
{ {
opSkipOnNonZero (code); opSkipOnNonZero (code);
if (offset<0) if (offset<0)
--offset; // compensate for skip instruction --offset; // compensate for skip instruction
jump (code, offset); jump (code, offset);
} }
void jumpOnNonZero (CodeContainer& code, int offset) void jumpOnNonZero (CodeContainer& code, int offset)
{ {
opSkipOnZero (code); opSkipOnZero (code);
if (offset<0) if (offset<0)
--offset; // compensate for skip instruction --offset; // compensate for skip instruction
jump (code, offset); jump (code, offset);
} }
void compare (CodeContainer& code, char op, char valueType1, char valueType2) void compare (CodeContainer& code, char op, char valueType1, char valueType2)
{ {
if (valueType1=='l' && valueType2=='l') if (valueType1=='l' && valueType2=='l')
@ -582,9 +580,9 @@ namespace Compiler
case 'L': opLessOrEqualInt (code); break; case 'L': opLessOrEqualInt (code); break;
case 'g': opGreaterThanInt (code); break; case 'g': opGreaterThanInt (code); break;
case 'G': opGreaterOrEqualInt (code); break; case 'G': opGreaterOrEqualInt (code); break;
default: default:
assert (0); assert (0);
} }
} }
@ -595,7 +593,7 @@ namespace Compiler
if (valueType2=='l') if (valueType2=='l')
opIntToFloat (code); opIntToFloat (code);
switch (op) switch (op)
{ {
case 'e': opEqualFloat (code); break; case 'e': opEqualFloat (code); break;
@ -604,28 +602,28 @@ namespace Compiler
case 'L': opLessOrEqualFloat (code); break; case 'L': opLessOrEqualFloat (code); break;
case 'g': opGreaterThanFloat (code); break; case 'g': opGreaterThanFloat (code); break;
case 'G': opGreaterOrEqualFloat (code); break; case 'G': opGreaterOrEqualFloat (code); break;
default: default:
assert (0); assert (0);
} }
} }
} }
void menuMode (CodeContainer& code) void menuMode (CodeContainer& code)
{ {
opMenuMode (code); opMenuMode (code);
} }
void assignToGlobal (CodeContainer& code, Literals& literals, char localType, void assignToGlobal (CodeContainer& code, Literals& literals, char localType,
const std::string& name, const CodeContainer& value, char valueType) const std::string& name, const CodeContainer& value, char valueType)
{ {
int index = literals.addString (name); int index = literals.addString (name);
opPushInt (code, index); opPushInt (code, index);
std::copy (value.begin(), value.end(), std::back_inserter (code)); std::copy (value.begin(), value.end(), std::back_inserter (code));
if (localType!=valueType) if (localType!=valueType)
{ {
if (localType=='f' && valueType=='l') if (localType=='f' && valueType=='l')
@ -637,30 +635,30 @@ namespace Compiler
opFloatToInt (code); opFloatToInt (code);
} }
} }
switch (localType) switch (localType)
{ {
case 'f': case 'f':
opStoreGlobalFloat (code); opStoreGlobalFloat (code);
break; break;
case 's': case 's':
opStoreGlobalShort (code); opStoreGlobalShort (code);
break; break;
case 'l': case 'l':
opStoreGlobalLong (code); opStoreGlobalLong (code);
break; break;
default: default:
assert (0); assert (0);
} }
} }
void fetchGlobal (CodeContainer& code, Literals& literals, char localType, void fetchGlobal (CodeContainer& code, Literals& literals, char localType,
const std::string& name) const std::string& name)
{ {
@ -671,36 +669,36 @@ namespace Compiler
switch (localType) switch (localType)
{ {
case 'f': case 'f':
opFetchGlobalFloat (code); opFetchGlobalFloat (code);
break; break;
case 's': case 's':
opFetchGlobalShort (code); opFetchGlobalShort (code);
break; break;
case 'l': case 'l':
opFetchGlobalLong (code); opFetchGlobalLong (code);
break; break;
default: default:
assert (0); assert (0);
} }
} }
void random (CodeContainer& code) void random (CodeContainer& code)
{ {
opRandom (code); opRandom (code);
} }
void scriptRunning (CodeContainer& code) void scriptRunning (CodeContainer& code)
{ {
opScriptRunning (code); opScriptRunning (code);
} }
void startScript (CodeContainer& code) void startScript (CodeContainer& code)
{ {
opStartScript (code); opStartScript (code);
@ -714,7 +712,7 @@ namespace Compiler
void getDistance (CodeContainer& code, Literals& literals, const std::string id) void getDistance (CodeContainer& code, Literals& literals, const std::string id)
{ {
if (id.empty()) if (id.empty())
{ {
opGetDistance (code); opGetDistance (code);
} }
else else
@ -722,14 +720,14 @@ namespace Compiler
int index = literals.addString (id); int index = literals.addString (id);
opPushInt (code, index); opPushInt (code, index);
opGetDistanceExplicit (code); opGetDistanceExplicit (code);
} }
} }
void getSecondsPassed (CodeContainer& code) void getSecondsPassed (CodeContainer& code)
{ {
opGetSecondsPassed (code); opGetSecondsPassed (code);
} }
void getDisabled (CodeContainer& code, Literals& literals, const std::string id) void getDisabled (CodeContainer& code, Literals& literals, const std::string id)
{ {
if (id.empty()) if (id.empty())
@ -743,11 +741,11 @@ namespace Compiler
opGetDisabledExplicit (code); opGetDisabledExplicit (code);
} }
} }
void enable (CodeContainer& code, Literals& literals, const std::string id) void enable (CodeContainer& code, Literals& literals, const std::string id)
{ {
if (id.empty()) if (id.empty())
{ {
opEnable (code); opEnable (code);
} }
else else
@ -755,13 +753,13 @@ namespace Compiler
int index = literals.addString (id); int index = literals.addString (id);
opPushInt (code, index); opPushInt (code, index);
opEnableExplicit (code); opEnableExplicit (code);
} }
} }
void disable (CodeContainer& code, Literals& literals, const std::string id) void disable (CodeContainer& code, Literals& literals, const std::string id)
{ {
if (id.empty()) if (id.empty())
{ {
opDisable (code); opDisable (code);
} }
else else
@ -773,4 +771,3 @@ namespace Compiler
} }
} }
} }

View file

@ -14,32 +14,32 @@ namespace Compiler
void LineParser::parseExpression (Scanner& scanner, const TokenLoc& loc) void LineParser::parseExpression (Scanner& scanner, const TokenLoc& loc)
{ {
mExprParser.reset(); mExprParser.reset();
if (!mExplicit.empty()) if (!mExplicit.empty())
{ {
mExprParser.parseName (mExplicit, loc, scanner); mExprParser.parseName (mExplicit, loc, scanner);
mExprParser.parseSpecial (Scanner::S_ref, loc, scanner); mExprParser.parseSpecial (Scanner::S_ref, loc, scanner);
} }
scanner.scan (mExprParser); scanner.scan (mExprParser);
char type = mExprParser.append (mCode); char type = mExprParser.append (mCode);
mState = EndState; mState = EndState;
switch (type) switch (type)
{ {
case 'l': case 'l':
Generator::message (mCode, mLiterals, "%g", 0); Generator::message (mCode, mLiterals, "%g", 0);
break; break;
case 'f': case 'f':
Generator::message (mCode, mLiterals, "%f", 0); Generator::message (mCode, mLiterals, "%f", 0);
break; break;
default: default:
throw std::runtime_error ("unknown expression result type"); throw std::runtime_error ("unknown expression result type");
} }
} }
@ -52,14 +52,14 @@ namespace Compiler
{} {}
bool LineParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner) bool LineParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
{ {
if (mAllowExpression && mState==BeginState) if (mAllowExpression && mState==BeginState)
{ {
scanner.putbackInt (value, loc); scanner.putbackInt (value, loc);
parseExpression (scanner, loc); parseExpression (scanner, loc);
return true; return true;
} }
return Parser::parseInt (value, loc, scanner); return Parser::parseInt (value, loc, scanner);
} }
@ -71,7 +71,7 @@ namespace Compiler
parseExpression (scanner, loc); parseExpression (scanner, loc);
return true; return true;
} }
return Parser::parseFloat (value, loc, scanner); return Parser::parseFloat (value, loc, scanner);
} }
@ -87,11 +87,11 @@ namespace Compiler
scanner.scan (skip); scanner.scan (skip);
return false; return false;
} }
std::string name2 = toLower (name); std::string name2 = toLower (name);
char type = mLocals.getType (name2); char type = mLocals.getType (name2);
if (type!=' ') if (type!=' ')
{ {
getErrorHandler().error ("can't re-declare local variable", loc); getErrorHandler().error ("can't re-declare local variable", loc);
@ -99,14 +99,14 @@ namespace Compiler
scanner.scan (skip); scanner.scan (skip);
return false; return false;
} }
mLocals.declare (mState==ShortState ? 's' : (mState==LongState ? 'l' : 'f'), mLocals.declare (mState==ShortState ? 's' : (mState==LongState ? 'l' : 'f'),
name2); name2);
mState = EndState; mState = EndState;
return true; return true;
} }
if (mState==SetState) if (mState==SetState)
{ {
std::string name2 = toLower (name); std::string name2 = toLower (name);
@ -119,7 +119,7 @@ namespace Compiler
mState = SetLocalVarState; mState = SetLocalVarState;
return true; return true;
} }
type = getContext().getGlobalType (name2); type = getContext().getGlobalType (name2);
if (type!=' ') if (type!=' ')
{ {
@ -127,18 +127,18 @@ namespace Compiler
mType = type; mType = type;
mState = SetGlobalVarState; mState = SetGlobalVarState;
return true; return true;
} }
getErrorHandler().error ("unknown variable", loc); getErrorHandler().error ("unknown variable", loc);
SkipParser skip (getErrorHandler(), getContext()); SkipParser skip (getErrorHandler(), getContext());
scanner.scan (skip); scanner.scan (skip);
return false; return false;
} }
if (mState==MessageState || mState==MessageCommaState) if (mState==MessageState || mState==MessageCommaState)
{ {
std::string arguments; std::string arguments;
for (std::size_t i=0; i<name.size(); ++i) for (std::size_t i=0; i<name.size(); ++i)
{ {
if (name[i]=='%') if (name[i]=='%')
@ -167,46 +167,52 @@ namespace Compiler
mExprParser.reset(); mExprParser.reset();
mExprParser.parseArguments (arguments, scanner, mCode, true); mExprParser.parseArguments (arguments, scanner, mCode, true);
} }
// for now skip buttons
SkipParser skip (getErrorHandler(), getContext());
scanner.scan (skip);
Generator::message (mCode, mLiterals, name, 0); mName = name;
mState = EndState; mButtons = 0;
return false;
mState = MessageButtonState;
return true;
} }
if (mState==MessageButtonState || mState==MessageButtonCommaState)
{
Generator::pushString (mCode, mLiterals, name);
mState = MessageButtonState;
++mButtons;
return true;
}
if (mState==BeginState && mAllowExpression) if (mState==BeginState && mAllowExpression)
{ {
std::string name2 = toLower (name); std::string name2 = toLower (name);
char type = mLocals.getType (name2); char type = mLocals.getType (name2);
if (type!=' ') if (type!=' ')
{ {
scanner.putbackName (name, loc); scanner.putbackName (name, loc);
parseExpression (scanner, loc); parseExpression (scanner, loc);
return true; return true;
} }
type = getContext().getGlobalType (name2); type = getContext().getGlobalType (name2);
if (type!=' ') if (type!=' ')
{ {
scanner.putbackName (name, loc); scanner.putbackName (name, loc);
parseExpression (scanner, loc); parseExpression (scanner, loc);
return true; return true;
} }
} }
if (mState==BeginState && getContext().isId (name)) if (mState==BeginState && getContext().isId (name))
{ {
mState = PotentialExplicitState; mState = PotentialExplicitState;
mExplicit = toLower (name); mExplicit = toLower (name);
return true; return true;
} }
return Parser::parseName (name, loc, scanner); return Parser::parseName (name, loc, scanner);
} }
@ -215,60 +221,60 @@ namespace Compiler
if (mState==BeginState || mState==ExplicitState) if (mState==BeginState || mState==ExplicitState)
{ {
switch (keyword) switch (keyword)
{ {
case Scanner::K_enable: case Scanner::K_enable:
Generator::enable (mCode, mLiterals, mExplicit); Generator::enable (mCode, mLiterals, mExplicit);
mState = EndState; mState = EndState;
return true; return true;
case Scanner::K_disable: case Scanner::K_disable:
Generator::disable (mCode, mLiterals, mExplicit); Generator::disable (mCode, mLiterals, mExplicit);
mState = EndState; mState = EndState;
return true; return true;
} }
// check for custom extensions // check for custom extensions
if (const Extensions *extensions = getContext().getExtensions()) if (const Extensions *extensions = getContext().getExtensions())
{ {
std::string argumentType; std::string argumentType;
if (extensions->isInstruction (keyword, argumentType, mState==ExplicitState)) if (extensions->isInstruction (keyword, argumentType, mState==ExplicitState))
{ {
mExprParser.parseArguments (argumentType, scanner, mCode, true); mExprParser.parseArguments (argumentType, scanner, mCode, true);
extensions->generateInstructionCode (keyword, mCode, mLiterals, mExplicit); extensions->generateInstructionCode (keyword, mCode, mLiterals, mExplicit);
mState = EndState; mState = EndState;
return true; return true;
} }
} }
if (mAllowExpression) if (mAllowExpression)
{ {
if (keyword==Scanner::K_getdisabled || keyword==Scanner::K_getdistance) if (keyword==Scanner::K_getdisabled || keyword==Scanner::K_getdistance)
{ {
scanner.putbackKeyword (keyword, loc); scanner.putbackKeyword (keyword, loc);
parseExpression (scanner, loc); parseExpression (scanner, loc);
return true; return true;
} }
if (const Extensions *extensions = getContext().getExtensions()) if (const Extensions *extensions = getContext().getExtensions())
{ {
char returnType; char returnType;
std::string argumentType; std::string argumentType;
if (extensions->isFunction (keyword, returnType, argumentType, if (extensions->isFunction (keyword, returnType, argumentType,
!mExplicit.empty())) !mExplicit.empty()))
{ {
scanner.putbackKeyword (keyword, loc); scanner.putbackKeyword (keyword, loc);
parseExpression (scanner, loc); parseExpression (scanner, loc);
return true; return true;
} }
} }
} }
} }
if (mState==BeginState) if (mState==BeginState)
{ {
switch (keyword) switch (keyword)
@ -278,39 +284,39 @@ namespace Compiler
case Scanner::K_float: mState = FloatState; return true; case Scanner::K_float: mState = FloatState; return true;
case Scanner::K_set: mState = SetState; return true; case Scanner::K_set: mState = SetState; return true;
case Scanner::K_messagebox: mState = MessageState; return true; case Scanner::K_messagebox: mState = MessageState; return true;
case Scanner::K_return: case Scanner::K_return:
Generator::exit (mCode); Generator::exit (mCode);
mState = EndState; mState = EndState;
return true; return true;
case Scanner::K_startscript: case Scanner::K_startscript:
mExprParser.parseArguments ("c", scanner, mCode, true); mExprParser.parseArguments ("c", scanner, mCode, true);
Generator::startScript (mCode); Generator::startScript (mCode);
mState = EndState; mState = EndState;
return true; return true;
case Scanner::K_stopscript: case Scanner::K_stopscript:
mExprParser.parseArguments ("c", scanner, mCode, true); mExprParser.parseArguments ("c", scanner, mCode, true);
Generator::stopScript (mCode); Generator::stopScript (mCode);
mState = EndState; mState = EndState;
return true; return true;
} }
} }
else if (mState==SetLocalVarState && keyword==Scanner::K_to) else if (mState==SetLocalVarState && keyword==Scanner::K_to)
{ {
mExprParser.reset(); mExprParser.reset();
scanner.scan (mExprParser); scanner.scan (mExprParser);
std::vector<Interpreter::Type_Code> code; std::vector<Interpreter::Type_Code> code;
char type = mExprParser.append (code); char type = mExprParser.append (code);
Generator::assignToLocal (mCode, mLocals.getType (mName), Generator::assignToLocal (mCode, mLocals.getType (mName),
mLocals.getIndex (mName), code, type); mLocals.getIndex (mName), code, type);
mState = EndState; mState = EndState;
return true; return true;
} }
@ -318,16 +324,16 @@ namespace Compiler
{ {
mExprParser.reset(); mExprParser.reset();
scanner.scan (mExprParser); scanner.scan (mExprParser);
std::vector<Interpreter::Type_Code> code; std::vector<Interpreter::Type_Code> code;
char type = mExprParser.append (code); char type = mExprParser.append (code);
Generator::assignToGlobal (mCode, mLiterals, mType, mName, code, type); Generator::assignToGlobal (mCode, mLiterals, mType, mName, code, type);
mState = EndState; mState = EndState;
return true; return true;
} }
if (mAllowExpression) if (mAllowExpression)
{ {
if (keyword==Scanner::K_getsquareroot || keyword==Scanner::K_menumode || if (keyword==Scanner::K_getsquareroot || keyword==Scanner::K_menumode ||
@ -336,10 +342,10 @@ namespace Compiler
{ {
scanner.putbackKeyword (keyword, loc); scanner.putbackKeyword (keyword, loc);
parseExpression (scanner, loc); parseExpression (scanner, loc);
return true; return true;
} }
} }
return Parser::parseKeyword (keyword, loc, scanner); return Parser::parseKeyword (keyword, loc, scanner);
} }
@ -347,30 +353,42 @@ namespace Compiler
{ {
if (code==Scanner::S_newline && (mState==EndState || mState==BeginState)) if (code==Scanner::S_newline && (mState==EndState || mState==BeginState))
return false; return false;
if (code==Scanner::S_comma && mState==MessageState) if (code==Scanner::S_comma && mState==MessageState)
{ {
mState = MessageCommaState; mState = MessageCommaState;
return true; return true;
} }
if (code==Scanner::S_ref && mState==PotentialExplicitState) if (code==Scanner::S_ref && mState==PotentialExplicitState)
{ {
mState = ExplicitState; mState = ExplicitState;
return true; 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 && if (mAllowExpression && mState==BeginState &&
(code==Scanner::S_open || code==Scanner::S_minus)) (code==Scanner::S_open || code==Scanner::S_minus))
{ {
scanner.putbackSpecial (code, loc); scanner.putbackSpecial (code, loc);
parseExpression (scanner, loc); parseExpression (scanner, loc);
return true; return true;
} }
return Parser::parseSpecial (code, loc, scanner); return Parser::parseSpecial (code, loc, scanner);
} }
void LineParser::reset() void LineParser::reset()
{ {
mState = BeginState; mState = BeginState;
@ -378,4 +396,3 @@ namespace Compiler
mExplicit.clear(); mExplicit.clear();
} }
} }

View file

@ -12,9 +12,9 @@ namespace Compiler
{ {
class Locals; class Locals;
class Literals; class Literals;
/// \brief Line parser, to be used in console scripts and as part of ScriptParser /// \brief Line parser, to be used in console scripts and as part of ScriptParser
class LineParser : public Parser class LineParser : public Parser
{ {
enum State enum State
@ -22,31 +22,32 @@ namespace Compiler
BeginState, BeginState,
ShortState, LongState, FloatState, ShortState, LongState, FloatState,
SetState, SetLocalVarState, SetGlobalVarState, SetState, SetLocalVarState, SetGlobalVarState,
MessageState, MessageCommaState, MessageState, MessageCommaState, MessageButtonState, MessageButtonCommaState,
EndState, EndState,
PotentialExplicitState, ExplicitState PotentialExplicitState, ExplicitState
}; };
Locals& mLocals; Locals& mLocals;
Literals& mLiterals; Literals& mLiterals;
std::vector<Interpreter::Type_Code>& mCode; std::vector<Interpreter::Type_Code>& mCode;
State mState; State mState;
std::string mName; std::string mName;
int mButtons;
std::string mExplicit; std::string mExplicit;
char mType; char mType;
ExprParser mExprParser; ExprParser mExprParser;
bool mAllowExpression; bool mAllowExpression;
void parseExpression (Scanner& scanner, const TokenLoc& loc); void parseExpression (Scanner& scanner, const TokenLoc& loc);
public: public:
LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals, LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
Literals& literals, std::vector<Interpreter::Type_Code>& code, Literals& literals, std::vector<Interpreter::Type_Code>& code,
bool allowExpression = false); bool allowExpression = false);
///< \param allowExpression Allow lines consisting of a naked expression ///< \param allowExpression Allow lines consisting of a naked expression
/// (result is send to the messagebox interface) /// (result is send to the messagebox interface)
virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner); virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner);
///< Handle an int token. ///< Handle an int token.
/// \return fetch another token? /// \return fetch another token?
@ -67,9 +68,9 @@ namespace Compiler
virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner); virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner);
///< Handle a special character token. ///< Handle a special character token.
/// \return fetch another token? /// \return fetch another token?
void reset(); void reset();
///< Reset parser to clean state. ///< Reset parser to clean state.
}; };
} }

View file

@ -6,6 +6,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <algorithm>
#include "opcodes.hpp" #include "opcodes.hpp"
#include "runtime.hpp" #include "runtime.hpp"
@ -15,24 +16,33 @@ namespace Interpreter
class OpMessageBox : public Opcode1 class OpMessageBox : public Opcode1
{ {
public: public:
virtual void execute (Runtime& runtime, unsigned int arg0) virtual void execute (Runtime& runtime, unsigned int arg0)
{ {
if (arg0!=0) // buttons
throw std::logic_error ("message box buttons not implemented yet"); std::vector<std::string> buttons;
// message for (std::size_t i=0; i<arg0; ++i)
{
int index = runtime[0].mInteger;
runtime.pop();
buttons.push_back (runtime.getStringLiteral (index));
}
std::reverse (buttons.begin(), buttons.end());
// message
int index = runtime[0].mInteger; int index = runtime[0].mInteger;
runtime.pop(); runtime.pop();
std::string message = runtime.getStringLiteral (index); std::string message = runtime.getStringLiteral (index);
// additional parameters // additional parameters
std::string formattedMessage; std::string formattedMessage;
for (std::size_t i=0; i<message.size(); ++i) for (std::size_t i=0; i<message.size(); ++i)
{ {
char c = message[i]; char c = message[i];
if (c!='%') if (c!='%')
formattedMessage += c; formattedMessage += c;
else else
@ -41,7 +51,7 @@ namespace Interpreter
if (i<message.size()) if (i<message.size())
{ {
c = message[i]; c = message[i];
if (c=='S' || c=='s') if (c=='S' || c=='s')
{ {
int index = runtime[0].mInteger; int index = runtime[0].mInteger;
@ -52,7 +62,7 @@ namespace Interpreter
{ {
Type_Integer value = runtime[0].mInteger; Type_Integer value = runtime[0].mInteger;
runtime.pop(); runtime.pop();
std::ostringstream out; std::ostringstream out;
out << value; out << value;
formattedMessage += out.str(); formattedMessage += out.str();
@ -63,10 +73,10 @@ namespace Interpreter
{ {
++i; ++i;
} }
float value = runtime[0].mFloat; float value = runtime[0].mFloat;
runtime.pop(); runtime.pop();
std::ostringstream out; std::ostringstream out;
out << value; out << value;
formattedMessage += out.str(); formattedMessage += out.str();
@ -75,135 +85,131 @@ namespace Interpreter
formattedMessage += "%"; formattedMessage += "%";
else else
{ {
formattedMessage += "%"; formattedMessage += "%";
formattedMessage += c; formattedMessage += c;
} }
} }
} }
} }
// buttons (not implemented)
std::vector<std::string> buttons;
runtime.getContext().messageBox (formattedMessage, buttons); runtime.getContext().messageBox (formattedMessage, buttons);
} }
}; };
class OpMenuMode : public Opcode0 class OpMenuMode : public Opcode0
{ {
public: public:
virtual void execute (Runtime& runtime) virtual void execute (Runtime& runtime)
{ {
runtime.push (runtime.getContext().menuMode()); runtime.push (runtime.getContext().menuMode());
} }
}; };
class OpRandom : public Opcode0 class OpRandom : public Opcode0
{ {
public: public:
virtual void execute (Runtime& runtime) virtual void execute (Runtime& runtime)
{ {
double r = static_cast<double> (std::rand()) / RAND_MAX; // [0, 1) double r = static_cast<double> (std::rand()) / RAND_MAX; // [0, 1)
Type_Integer limit = runtime[0].mInteger; Type_Integer limit = runtime[0].mInteger;
if (limit<0) if (limit<0)
throw std::runtime_error ( throw std::runtime_error (
"random: argument out of range (Don't be so negative!)"); "random: argument out of range (Don't be so negative!)");
Type_Integer value = static_cast<Type_Integer> (r*limit); // [o, limit) Type_Integer value = static_cast<Type_Integer> (r*limit); // [o, limit)
runtime[0].mInteger = value; runtime[0].mInteger = value;
} }
}; };
class OpGetSecondsPassed : public Opcode0 class OpGetSecondsPassed : public Opcode0
{ {
public: public:
virtual void execute (Runtime& runtime) virtual void execute (Runtime& runtime)
{ {
Type_Float duration = runtime.getContext().getSecondsPassed(); Type_Float duration = runtime.getContext().getSecondsPassed();
runtime.push (duration); runtime.push (duration);
} }
}; };
class OpEnable : public Opcode0 class OpEnable : public Opcode0
{ {
public: public:
virtual void execute (Runtime& runtime) virtual void execute (Runtime& runtime)
{ {
runtime.getContext().enable(); runtime.getContext().enable();
} }
}; };
class OpDisable : public Opcode0 class OpDisable : public Opcode0
{ {
public: public:
virtual void execute (Runtime& runtime) virtual void execute (Runtime& runtime)
{ {
runtime.getContext().disable(); runtime.getContext().disable();
} }
}; };
class OpGetDisabled : public Opcode0 class OpGetDisabled : public Opcode0
{ {
public: public:
virtual void execute (Runtime& runtime) virtual void execute (Runtime& runtime)
{ {
runtime.push (runtime.getContext().isDisabled()); runtime.push (runtime.getContext().isDisabled());
} }
}; };
class OpEnableExplicit : public Opcode0 class OpEnableExplicit : public Opcode0
{ {
public: public:
virtual void execute (Runtime& runtime) virtual void execute (Runtime& runtime)
{ {
int index = runtime[0].mInteger; int index = runtime[0].mInteger;
runtime.pop(); runtime.pop();
std::string id = runtime.getStringLiteral (index); std::string id = runtime.getStringLiteral (index);
runtime.getContext().enable (id); runtime.getContext().enable (id);
} }
}; };
class OpDisableExplicit : public Opcode0 class OpDisableExplicit : public Opcode0
{ {
public: public:
virtual void execute (Runtime& runtime) virtual void execute (Runtime& runtime)
{ {
int index = runtime[0].mInteger; int index = runtime[0].mInteger;
runtime.pop(); runtime.pop();
std::string id = runtime.getStringLiteral (index); std::string id = runtime.getStringLiteral (index);
runtime.getContext().disable (id); runtime.getContext().disable (id);
} }
}; };
class OpGetDisabledExplicit : public Opcode0 class OpGetDisabledExplicit : public Opcode0
{ {
public: public:
virtual void execute (Runtime& runtime) virtual void execute (Runtime& runtime)
{ {
int index = runtime[0].mInteger; int index = runtime[0].mInteger;
runtime.pop(); runtime.pop();
std::string id = runtime.getStringLiteral (index); std::string id = runtime.getStringLiteral (index);
runtime.push (runtime.getContext().isDisabled (id)); runtime.push (runtime.getContext().isDisabled (id));
} }
}; };
} }
#endif #endif