added menumode script function; added global variable handling in compiler and interpreter (openmw context still ignores global variables)

pull/7/head
Marc Zinnschlag 15 years ago
parent cdcc244fc5
commit f9c1548f80

@ -7,5 +7,10 @@ namespace SACompiler
{
return true;
}
char Context::getGlobalType (const std::string& name) const
{
return ' ';
}
}

@ -11,6 +11,9 @@ namespace SACompiler
virtual bool canDeclareLocals() const;
///< Is the compiler allowed to declare local variables?
virtual char getGlobalType (const std::string& name) const;
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
};
}

@ -74,6 +74,32 @@ namespace SAInterpreter
for (std::size_t i=0; i<buttons.size(); ++i)
std::cout << " button " << i << ": " << buttons[i] << std::endl;
}
bool Context::menuMode()
{
return false;
}
int Context::getGlobalShort (const std::string& name) const
{
return 0;
}
int Context::getGlobalLong (const std::string& name) const
{
return 0;
}
float Context::getGlobalFloat (const std::string& name) const
{
return 0;
}
void Context::setGlobalShort (const std::string& name, int value) {}
void Context::setGlobalLong (const std::string& name, int value) {}
void Context::setGlobalFloat (const std::string& name, float value) {}
void Context::report()
{

@ -38,6 +38,20 @@ namespace SAInterpreter
virtual void messageBox (const std::string& message,
const std::vector<std::string>& buttons);
virtual bool menuMode();
virtual int getGlobalShort (const std::string& name) const;
virtual int getGlobalLong (const std::string& name) const;
virtual float getGlobalFloat (const std::string& name) const;
virtual void setGlobalShort (const std::string& name, int value);
virtual void setGlobalLong (const std::string& name, int value);
virtual void setGlobalFloat (const std::string& name, float value);
void report();
///< Write state to std::cout
};

@ -29,6 +29,9 @@ namespace MWScript
{
return mType==Type_Full;
}
virtual char getGlobalType (const std::string& name) const { return ' '; }
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
};
}

@ -71,6 +71,41 @@ namespace MWScript
std::cerr << "error: message box buttons not supported" << std::endl;
}
bool InterpreterContext::menuMode()
{
return false;
}
int InterpreterContext::getGlobalShort (const std::string& name) const
{
return 0;
}
int InterpreterContext::getGlobalLong (const std::string& name) const
{
return 0;
}
float InterpreterContext::getGlobalFloat (const std::string& name) const
{
return 0;
}
void InterpreterContext::setGlobalShort (const std::string& name, int value)
{
}
void InterpreterContext::setGlobalLong (const std::string& name, int value)
{
}
void InterpreterContext::setGlobalFloat (const std::string& name, float value)
{
}
MWWorld::World& InterpreterContext::getWorld()
{
return *mEnvironment.mWorld;

@ -47,6 +47,20 @@ namespace MWScript
virtual void messageBox (const std::string& message,
const std::vector<std::string>& buttons);
virtual bool menuMode();
virtual int getGlobalShort (const std::string& name) const;
virtual int getGlobalLong (const std::string& name) const;
virtual float getGlobalFloat (const std::string& name) const;
virtual void setGlobalShort (const std::string& name, int value);
virtual void setGlobalLong (const std::string& name, int value);
virtual void setGlobalFloat (const std::string& name, float value);
MWWorld::World& getWorld();
MWSound::SoundManager& getSoundManager();

@ -1,6 +1,8 @@
#ifndef COMPILER_CONTEXT_H_INCLUDED
#define COMPILER_CONTEXT_H_INCLUDED
#include <string>
namespace Compiler
{
class Extensions;
@ -27,6 +29,9 @@ namespace Compiler
{
return mExtensions;
}
virtual char getGlobalType (const std::string& name) const = 0;
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
};
}

@ -243,16 +243,29 @@ namespace Compiler
mFirst = false;
if (mNextOperand)
{
char type = mLocals.getType (name);
{
std::string name2 = toLower (name);
char type = mLocals.getType (name2);
if (type!=' ')
{
Generator::fetchLocal (mCode, type, mLocals.getIndex (name));
Generator::fetchLocal (mCode, type, mLocals.getIndex (name2));
mNextOperand = false;
mOperands.push_back (type=='f' ? 'f' : 'l');
return true;
}
type = getContext().getGlobalType (name2);
if (type!=' ')
{
Generator::fetchGlobal (mCode, mLiterals, type, name2);
mNextOperand = false;
mOperands.push_back (type=='f' ? 'f' : 'l');
return true;
}
}
else
{
@ -281,6 +294,16 @@ namespace Compiler
mNextOperand = false;
return true;
}
else if (keyword==Scanner::K_menumode)
{
mTokenLoc = loc;
Generator::menuMode (mCode);
mOperands.push_back ('l');
mNextOperand = false;
return true;
}
else
{
// check for custom extensions

@ -219,6 +219,41 @@ namespace
{
code.push_back (Compiler::Generator::segment5 (37));
}
void opMenuMode (Compiler::Generator::CodeContainer& code)
{
code.push_back (Compiler::Generator::segment5 (38));
}
void opStoreGlobalShort (Compiler::Generator::CodeContainer& code)
{
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));
}
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));
}
}
namespace Compiler
@ -511,6 +546,85 @@ namespace Compiler
}
}
}
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')
{
opIntToFloat (code);
}
else if ((localType=='l' || localType=='s') && valueType=='f')
{
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)
{
int index = literals.addString (name);
opPushInt (code, index);
switch (localType)
{
case 'f':
opFetchGlobalFloat (code);
break;
case 's':
opFetchGlobalShort (code);
break;
case 'l':
opFetchGlobalLong (code);
break;
default:
assert (0);
}
}
}
}

@ -90,6 +90,14 @@ namespace Compiler
void jumpOnNonZero (CodeContainer& code, int offset);
void compare (CodeContainer& code, char op, char valueType1, char valueType2);
void menuMode (CodeContainer& code);
void assignToGlobal (CodeContainer& code, Literals& literals, char localType,
const std::string& name, const CodeContainer& value, char valueType);
void fetchGlobal (CodeContainer& code, Literals& literals, char localType,
const std::string& name);
}
}

@ -61,8 +61,9 @@ namespace Compiler
if (mState==SetState)
{
// local variable?
std::string name2 = toLower (name);
// local variable?
char type = mLocals.getType (name2);
if (type!=' ')
{
@ -71,6 +72,15 @@ namespace Compiler
return true;
}
type = getContext().getGlobalType (name2);
if (type!=' ')
{
mName = name2;
mType = type;
mState = SetGlobalVarState;
return true;
}
getErrorHandler().error ("unknown variable", loc);
SkipParser skip (getErrorHandler(), getContext());
scanner.scan (skip);
@ -166,7 +176,20 @@ namespace Compiler
mState = EndState;
return true;
}
else if (mState==SetGlobalVarState && keyword==Scanner::K_to)
{
mExprParser.reset();
scanner.scan (mExprParser);
std::vector<Interpreter::Type_Code> code;
char type = mExprParser.append (code);
Generator::assignToGlobal (mCode, mLiterals, mType, mName, code, type);
mState = EndState;
return true;
}
return Parser::parseKeyword (keyword, loc, scanner);
}

@ -21,7 +21,7 @@ namespace Compiler
{
BeginState,
ShortState, LongState, FloatState,
SetState, SetLocalVarState,
SetState, SetLocalVarState, SetGlobalVarState,
MessageState, MessageCommaState,
EndState
};
@ -31,6 +31,7 @@ namespace Compiler
std::vector<Interpreter::Type_Code>& mCode;
State mState;
std::string mName;
char mType;
ExprParser mExprParser;
public:

@ -242,6 +242,7 @@ namespace Compiler
"messagebox",
"set", "to",
"getsquareroot",
"menumode",
0
};

@ -48,7 +48,8 @@ namespace Compiler
K_return,
K_messagebox,
K_set, K_to,
K_getsquareroot
K_getsquareroot,
K_menumode
};
enum special

@ -32,6 +32,20 @@ namespace Interpreter
std::vector<std::string> empty;
messageBox (message, empty);
}
virtual bool menuMode() = 0;
virtual int getGlobalShort (const std::string& name) const = 0;
virtual int getGlobalLong (const std::string& name) const = 0;
virtual float getGlobalFloat (const std::string& name) const = 0;
virtual void setGlobalShort (const std::string& name, int value) = 0;
virtual void setGlobalLong (const std::string& name, int value) = 0;
virtual void setGlobalFloat (const std::string& name, float value) = 0;
};
}

@ -96,6 +96,13 @@ op 34: compare (float) stack[1] with stack[0]; pop twice; push 1 if lesser than
op 35: compare (float) stack[1] with stack[0]; pop twice; push 1 if lesser or equal, 0 else
op 36: compare (float) stack[1] with stack[0]; pop twice; push 1 if greater than, 0 else
op 37: compare (float) stack[1] with stack[0]; pop twice; push 1 if greater or equal, 0 else
opcodes 38-33554431 unused
op 38: push 1 if game is in menu mode, 0 else
op 39: store stack[0] in global short stack[1] and pop twice
op 40: store stack[0] in global long stack[1] and pop twice
op 41: store stack[0] in global float stack[1] and pop twice
op 42: replace stack[0] with global short stack[0]
op 43: replace stack[0] with global long stack[0]
op 44: replace stack[0] with global float stack[0]
opcodes 45-33554431 unused
opcodes 33554432-67108863 reserved for extensions

@ -23,7 +23,7 @@ namespace Interpreter
interpreter.installSegment5 (17, new OpIntToFloat1);
interpreter.installSegment5 (18, new OpFloatToInt1);
// local variables & literals
// local variables, global variables & literals
interpreter.installSegment5 (0, new OpStoreLocalShort);
interpreter.installSegment5 (1, new OpStoreLocalLong);
interpreter.installSegment5 (2, new OpStoreLocalFloat);
@ -32,6 +32,12 @@ namespace Interpreter
interpreter.installSegment5 (21, new OpFetchLocalShort);
interpreter.installSegment5 (22, new OpFetchLocalLong);
interpreter.installSegment5 (23, new OpFetchLocalFloat);
interpreter.installSegment5 (39, new OpStoreGlobalShort);
interpreter.installSegment5 (40, new OpStoreGlobalLong);
interpreter.installSegment5 (41, new OpStoreGlobalFloat);
interpreter.installSegment5 (42, new OpFetchGlobalShort);
interpreter.installSegment5 (43, new OpFetchGlobalLong);
interpreter.installSegment5 (44, new OpFetchGlobalFloat);
// math
interpreter.installSegment5 (9, new OpAddInt<Type_Integer>);
@ -77,7 +83,8 @@ namespace Interpreter
interpreter.installSegment0 (2, new OpJumpBackward);
// misc
interpreter.installSegment3 (0, new OpMessageBox);
interpreter.installSegment3 (0, new OpMessageBox);
interpreter.installSegment5 (38, new OpMenuMode);
}
}

@ -112,6 +112,99 @@ namespace Interpreter
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
}
};
class OpStoreGlobalShort : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
Type_Data data = runtime[0];
int index = runtime[1];
std::string name = runtime.getStringLiteral (index);
runtime.getContext().setGlobalShort (name, *reinterpret_cast<int *> (&data));
runtime.pop();
runtime.pop();
}
};
class OpStoreGlobalLong : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
Type_Data data = runtime[0];
int index = runtime[1];
std::string name = runtime.getStringLiteral (index);
runtime.getContext().setGlobalLong (name, *reinterpret_cast<int *> (&data));
runtime.pop();
runtime.pop();
}
};
class OpStoreGlobalFloat : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
Type_Data data = runtime[0];
int index = runtime[1];
std::string name = runtime.getStringLiteral (index);
runtime.getContext().setGlobalFloat (name, *reinterpret_cast<float *> (&data));
runtime.pop();
runtime.pop();
}
};
class OpFetchGlobalShort : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
int index = runtime[0];
std::string name = runtime.getStringLiteral (index);
int value = runtime.getContext().getGlobalShort (name);
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
}
};
class OpFetchGlobalLong : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
int index = runtime[0];
std::string name = runtime.getStringLiteral (index);
int value = runtime.getContext().getGlobalLong (name);
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
}
};
class OpFetchGlobalFloat : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
int index = runtime[0];
std::string name = runtime.getStringLiteral (index);
float value = runtime.getContext().getGlobalFloat (name);
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
}
};
}
#endif

@ -85,7 +85,17 @@ namespace Interpreter
std::vector<std::string> buttons;
runtime.getContext().messageBox (formattedMessage, buttons);
}
}
};
class OpMenuMode : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
runtime.push (runtime.getContext().menuMode());
}
};
}

Loading…
Cancel
Save