mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-30 03:32:36 +00:00
added return and messagebox statements (messagebox does neither formating nor buttons yet)
This commit is contained in:
parent
8bb2a6039d
commit
fac8fb8fcb
@ -67,6 +67,14 @@ namespace SAInterpreter
|
||||
mFloats.at (index) = value;
|
||||
}
|
||||
|
||||
void Context::messageBox (const std::string& message,
|
||||
const std::vector<std::string>& buttons)
|
||||
{
|
||||
std::cout << "message box: " << message << std::endl;
|
||||
for (std::size_t i=0; i<buttons.size(); ++i)
|
||||
std::cout << " button " << i << ": " << buttons[i] << std::endl;
|
||||
}
|
||||
|
||||
void Context::report()
|
||||
{
|
||||
std::size_t i = 0;
|
||||
|
@ -35,6 +35,9 @@ namespace SAInterpreter
|
||||
|
||||
virtual void setLocalFloat (int index, float value);
|
||||
|
||||
virtual void messageBox (const std::string& message,
|
||||
const std::vector<std::string>& buttons);
|
||||
|
||||
void report();
|
||||
///< Write state to std::cout
|
||||
};
|
||||
|
@ -150,6 +150,16 @@ namespace
|
||||
{
|
||||
code.push_back (segment5 (19));
|
||||
}
|
||||
|
||||
void opReturn (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (segment5 (20));
|
||||
}
|
||||
|
||||
void opMessageBox (Compiler::Generator::CodeContainer& code, int buttons)
|
||||
{
|
||||
code.push_back (segment3 (0, buttons));
|
||||
}
|
||||
}
|
||||
|
||||
namespace Compiler
|
||||
@ -321,6 +331,22 @@ namespace Compiler
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define COMPILER_GENERATOR_H_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <components/interpreter/types.hpp>
|
||||
|
||||
@ -33,6 +34,11 @@ namespace Compiler
|
||||
void convert (CodeContainer& code, char fromType, char toType);
|
||||
|
||||
void squareRoot (CodeContainer& code);
|
||||
|
||||
void exit (CodeContainer& code);
|
||||
|
||||
void message (CodeContainer& code, Literals& literals, const std::string& message,
|
||||
int buttons);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,13 @@ namespace Compiler
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mState==MessageState || mState==MessageCommaState)
|
||||
{
|
||||
Generator::message (mCode, mLiterals, name, 0);
|
||||
mState = EndState;
|
||||
return false;
|
||||
}
|
||||
|
||||
return Parser::parseName (name, loc, scanner);
|
||||
}
|
||||
|
||||
@ -89,6 +96,13 @@ namespace Compiler
|
||||
case Scanner::K_long: mState = LongState; return true;
|
||||
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;
|
||||
}
|
||||
}
|
||||
else if (mState==SetLocalVarState && keyword==Scanner::K_to)
|
||||
@ -114,6 +128,12 @@ namespace Compiler
|
||||
if (code==Scanner::S_newline && mState==EndState)
|
||||
return false;
|
||||
|
||||
if (code==Scanner::S_comma && mState==MessageState)
|
||||
{
|
||||
mState = MessageCommaState;
|
||||
return true;
|
||||
}
|
||||
|
||||
return Parser::parseSpecial (code, loc, scanner);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ namespace Compiler
|
||||
BeginState,
|
||||
ShortState, LongState, FloatState,
|
||||
SetState, SetLocalVarState,
|
||||
MessageState, MessageCommaState,
|
||||
EndState
|
||||
};
|
||||
|
||||
|
@ -40,7 +40,7 @@ namespace Compiler
|
||||
K_if, K_endif, K_else, K_elseif,
|
||||
K_while, K_endwhile,
|
||||
K_return,
|
||||
K_messageBox,
|
||||
K_messagebox,
|
||||
K_set, K_to,
|
||||
K_getsquareroot
|
||||
};
|
||||
|
@ -19,7 +19,10 @@ namespace Interpreter
|
||||
|
||||
virtual void setLocalLong (int index, int value) = 0;
|
||||
|
||||
virtual void setLocalFloat (int index, float value) = 0;
|
||||
virtual void setLocalFloat (int index, float value) = 0;
|
||||
|
||||
virtual void messageBox (const std::string& message,
|
||||
const std::vector<std::string>& buttons) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
20
components/interpreter/controlopcodes.hpp
Normal file
20
components/interpreter/controlopcodes.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef INTERPRETER_CONTROLOPCODES_H_INCLUDED
|
||||
#define INTERPRETER_CONTROLOPCODES_H_INCLUDED
|
||||
|
||||
#include "opcodes.hpp"
|
||||
#include "runtime.hpp"
|
||||
|
||||
namespace Interpreter
|
||||
{
|
||||
class OpReturn : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
runtime.setPC (-1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -43,7 +43,12 @@ opcodes 0-511 unused
|
||||
opcodes 512-1023 reserved for extensions
|
||||
|
||||
Segment 3:
|
||||
opcodes 0-511 unused
|
||||
op 0: show message box with message string literal index in stack[0];
|
||||
buttons (if any) in stack[arg0]..stack[1];
|
||||
additional arguments (if any) in stack[arg0+n]..stack[arg0+1];
|
||||
n is determined according to the message string
|
||||
all arguments are removed from stack
|
||||
opcodes 1-511 unused
|
||||
opcodes 512-1023 reserved for extensions
|
||||
|
||||
Segment 4:
|
||||
@ -71,6 +76,7 @@ op 16: div (float) stack[1] by stack[0], pop twice, push result
|
||||
op 17: convert stack[1] from integer to float
|
||||
op 18: convert stack[1] from float to integer
|
||||
op 19: take square root of stack[0] (float)
|
||||
opcodes 20-33554431 unused
|
||||
op 20: return
|
||||
opcodes 21-33554431 unused
|
||||
opcodes 33554432-67108863 reserved for extensions
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "genericopcodes.hpp"
|
||||
#include "localopcodes.hpp"
|
||||
#include "mathopcodes.hpp"
|
||||
#include "controlopcodes.hpp"
|
||||
#include "miscopcodes.hpp"
|
||||
|
||||
namespace Interpreter
|
||||
{
|
||||
@ -36,6 +38,12 @@ namespace Interpreter
|
||||
interpreter.installSegment5 (15, new OpDivInt<Type_Integer>);
|
||||
interpreter.installSegment5 (16, new OpDivInt<Type_Float>);
|
||||
interpreter.installSegment5 (19, new OpSquareRoot);
|
||||
|
||||
// control structures
|
||||
interpreter.installSegment5 (20, new OpReturn);
|
||||
|
||||
// misc
|
||||
interpreter.installSegment3 (0, new OpMessageBox);
|
||||
}
|
||||
}
|
||||
|
||||
|
31
components/interpreter/miscopcodes.hpp
Normal file
31
components/interpreter/miscopcodes.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef INTERPRETER_MISCOPCODES_H_INCLUDED
|
||||
#define INTERPRETER_MISCOPCODES_H_INCLUDED
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "opcodes.hpp"
|
||||
#include "runtime.hpp"
|
||||
|
||||
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");
|
||||
|
||||
int index = runtime[0];
|
||||
runtime.pop();
|
||||
std::vector<std::string> buttons;
|
||||
runtime.getContext().messageBox (runtime.getStringLiteral (index), buttons);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
namespace Interpreter
|
||||
{
|
||||
@ -30,6 +31,21 @@ namespace Interpreter
|
||||
|
||||
return *reinterpret_cast<const float *> (&literalBlock[index]);
|
||||
}
|
||||
|
||||
std::string Runtime::getStringLiteral (int index) const
|
||||
{
|
||||
assert (index>=0 && index<static_cast<int> (mCode[3]));
|
||||
|
||||
const char *literalBlock =
|
||||
reinterpret_cast<const char *> (mCode + 4 + mCode[0] + mCode[1] + mCode[2]);
|
||||
|
||||
for (; index; --index)
|
||||
{
|
||||
literalBlock += std::strlen (literalBlock) + 1;
|
||||
}
|
||||
|
||||
return literalBlock;
|
||||
}
|
||||
|
||||
void Runtime::configure (const Interpreter::Type_Code *code, int codeSize)
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define INTERPRETER_RUNTIME_H_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
@ -29,7 +30,9 @@ namespace Interpreter
|
||||
int getIntegerLiteral (int index) const;
|
||||
|
||||
float getFloatLiteral (int index) const;
|
||||
|
||||
|
||||
std::string getStringLiteral (int index) const;
|
||||
|
||||
void configure (const Type_Code *code, int codeSize);
|
||||
///< \a context and \a code must exist as least until either configure, clear or
|
||||
/// the destructor is called. \a codeSize is given in 32-bit words.
|
||||
|
Loading…
x
Reference in New Issue
Block a user