added return and messagebox statements (messagebox does neither formating nor buttons yet)

actorid
Marc Zinnschlag 15 years ago
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;
};
}

@ -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);
}
}

@ -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…
Cancel
Save