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; 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() void Context::report()
{ {
std::size_t i = 0; std::size_t i = 0;

@ -35,6 +35,9 @@ namespace SAInterpreter
virtual void setLocalFloat (int index, float value); virtual void setLocalFloat (int index, float value);
virtual void messageBox (const std::string& message,
const std::vector<std::string>& buttons);
void report(); void report();
///< Write state to std::cout ///< Write state to std::cout
}; };

@ -150,6 +150,16 @@ namespace
{ {
code.push_back (segment5 (19)); 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 namespace Compiler
@ -321,6 +331,22 @@ namespace Compiler
{ {
opSquareRoot (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);
}
} }
} }

@ -2,6 +2,7 @@
#define COMPILER_GENERATOR_H_INCLUDED #define COMPILER_GENERATOR_H_INCLUDED
#include <vector> #include <vector>
#include <string>
#include <components/interpreter/types.hpp> #include <components/interpreter/types.hpp>
@ -33,6 +34,11 @@ namespace Compiler
void convert (CodeContainer& code, char fromType, char toType); void convert (CodeContainer& code, char fromType, char toType);
void squareRoot (CodeContainer& code); 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; return false;
} }
if (mState==MessageState || mState==MessageCommaState)
{
Generator::message (mCode, mLiterals, name, 0);
mState = EndState;
return false;
}
return Parser::parseName (name, loc, scanner); return Parser::parseName (name, loc, scanner);
} }
@ -89,6 +96,13 @@ namespace Compiler
case Scanner::K_long: mState = LongState; return true; case Scanner::K_long: mState = LongState; return true;
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_return:
Generator::exit (mCode);
mState = EndState;
return true;
} }
} }
else if (mState==SetLocalVarState && keyword==Scanner::K_to) else if (mState==SetLocalVarState && keyword==Scanner::K_to)
@ -114,6 +128,12 @@ namespace Compiler
if (code==Scanner::S_newline && mState==EndState) if (code==Scanner::S_newline && mState==EndState)
return false; return false;
if (code==Scanner::S_comma && mState==MessageState)
{
mState = MessageCommaState;
return true;
}
return Parser::parseSpecial (code, loc, scanner); return Parser::parseSpecial (code, loc, scanner);
} }

@ -22,6 +22,7 @@ namespace Compiler
BeginState, BeginState,
ShortState, LongState, FloatState, ShortState, LongState, FloatState,
SetState, SetLocalVarState, SetState, SetLocalVarState,
MessageState, MessageCommaState,
EndState EndState
}; };

@ -40,7 +40,7 @@ namespace Compiler
K_if, K_endif, K_else, K_elseif, K_if, K_endif, K_else, K_elseif,
K_while, K_endwhile, K_while, K_endwhile,
K_return, K_return,
K_messageBox, K_messagebox,
K_set, K_to, K_set, K_to,
K_getsquareroot K_getsquareroot
}; };

@ -19,7 +19,10 @@ namespace Interpreter
virtual void setLocalLong (int index, int value) = 0; 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 opcodes 512-1023 reserved for extensions
Segment 3: 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 opcodes 512-1023 reserved for extensions
Segment 4: 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 17: convert stack[1] from integer to float
op 18: convert stack[1] from float to integer op 18: convert stack[1] from float to integer
op 19: take square root of stack[0] (float) 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 opcodes 33554432-67108863 reserved for extensions

@ -5,6 +5,8 @@
#include "genericopcodes.hpp" #include "genericopcodes.hpp"
#include "localopcodes.hpp" #include "localopcodes.hpp"
#include "mathopcodes.hpp" #include "mathopcodes.hpp"
#include "controlopcodes.hpp"
#include "miscopcodes.hpp"
namespace Interpreter namespace Interpreter
{ {
@ -36,6 +38,12 @@ namespace Interpreter
interpreter.installSegment5 (15, new OpDivInt<Type_Integer>); interpreter.installSegment5 (15, new OpDivInt<Type_Integer>);
interpreter.installSegment5 (16, new OpDivInt<Type_Float>); interpreter.installSegment5 (16, new OpDivInt<Type_Float>);
interpreter.installSegment5 (19, new OpSquareRoot); 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 <stdexcept>
#include <cassert> #include <cassert>
#include <cstring>
namespace Interpreter namespace Interpreter
{ {
@ -30,6 +31,21 @@ namespace Interpreter
return *reinterpret_cast<const float *> (&literalBlock[index]); 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) void Runtime::configure (const Interpreter::Type_Code *code, int codeSize)
{ {

@ -2,6 +2,7 @@
#define INTERPRETER_RUNTIME_H_INCLUDED #define INTERPRETER_RUNTIME_H_INCLUDED
#include <vector> #include <vector>
#include <string>
#include "types.hpp" #include "types.hpp"
@ -29,7 +30,9 @@ namespace Interpreter
int getIntegerLiteral (int index) const; int getIntegerLiteral (int index) const;
float getFloatLiteral (int index) const; float getFloatLiteral (int index) const;
std::string getStringLiteral (int index) const;
void configure (const Type_Code *code, int codeSize); void configure (const Type_Code *code, int codeSize);
///< \a context and \a code must exist as least until either configure, clear or ///< \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. /// the destructor is called. \a codeSize is given in 32-bit words.

Loading…
Cancel
Save