mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-31 23:15:41 +00:00
Merge branch 'script'
This commit is contained in:
commit
9a6f012578
27 changed files with 821 additions and 79 deletions
|
@ -57,6 +57,11 @@ namespace MWClass
|
|||
|
||||
data->mCreatureStats.mLevel = ref->base->data.level;
|
||||
|
||||
data->mCreatureStats.mHello = ref->base->AI.hello;
|
||||
data->mCreatureStats.mFight = ref->base->AI.fight;
|
||||
data->mCreatureStats.mFlee = ref->base->AI.flee;
|
||||
data->mCreatureStats.mAlarm = ref->base->AI.alarm;
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
}
|
||||
|
|
|
@ -70,12 +70,12 @@ namespace MWClass
|
|||
}
|
||||
}
|
||||
|
||||
// creature stats
|
||||
if(ref->base->npdt52.gold != -10)
|
||||
{
|
||||
for (int i=0; i<27; ++i)
|
||||
data->mNpcStats.mSkill[i].setBase (ref->base->npdt52.skills[i]);
|
||||
|
||||
// creature stats
|
||||
data->mCreatureStats.mAttributes[0].set (ref->base->npdt52.strength);
|
||||
data->mCreatureStats.mAttributes[1].set (ref->base->npdt52.intelligence);
|
||||
data->mCreatureStats.mAttributes[2].set (ref->base->npdt52.willpower);
|
||||
|
@ -95,6 +95,11 @@ namespace MWClass
|
|||
/// \todo do something with npdt12 maybe:p
|
||||
}
|
||||
|
||||
data->mCreatureStats.mHello = ref->base->AI.hello;
|
||||
data->mCreatureStats.mFight = ref->base->AI.fight;
|
||||
data->mCreatureStats.mFlee = ref->base->AI.flee;
|
||||
data->mCreatureStats.mAlarm = ref->base->AI.alarm;
|
||||
|
||||
// store
|
||||
ptr.getRefData().setCustomData (data.release());
|
||||
}
|
||||
|
|
|
@ -86,13 +86,12 @@ void MessageBoxManager::createMessageBox (const std::string& message)
|
|||
|
||||
bool MessageBoxManager::createInteractiveMessageBox (const std::string& message, const std::vector<std::string>& buttons)
|
||||
{
|
||||
/// \todo Don't write this kind of error message to cout. Either discard the old message box
|
||||
/// silently or throw an exception.
|
||||
if(mInterMessageBoxe != NULL) {
|
||||
std::cout << "there is a MessageBox already" << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::cout << "interactive MessageBox: " << message << " - ";
|
||||
std::copy (buttons.begin(), buttons.end(), std::ostream_iterator<std::string> (std::cout, ", "));
|
||||
std::cout << std::endl;
|
||||
|
||||
mInterMessageBoxe = new InteractiveMessageBox(*this, message, buttons);
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@ namespace MWMechanics
|
|||
Spells mSpells;
|
||||
ActiveSpells mActiveSpells;
|
||||
MagicEffects mMagicEffects;
|
||||
int mHello;
|
||||
int mFight;
|
||||
int mFlee;
|
||||
int mAlarm;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <components/interpreter/runtime.hpp>
|
||||
#include <components/interpreter/opcodes.hpp>
|
||||
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
|
||||
#include "interpretercontext.hpp"
|
||||
#include "ref.hpp"
|
||||
|
||||
|
@ -88,6 +90,95 @@ namespace MWScript
|
|||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpAiWander : public Interpreter::Opcode1
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
// Interpreter::Type_Float range = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
// Interpreter::Type_Float duration = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
// Interpreter::Type_Float time = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
// discard additional idle arguments for now
|
||||
// discard additional arguments (reset), because we have no idea what they mean.
|
||||
for (unsigned int i=0; i<arg0; ++i) runtime.pop();
|
||||
|
||||
std::cout << "AiWanter" << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpSetHello : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
MWWorld::Class::get (ptr).getCreatureStats (ptr).mHello = value;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpSetFight : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
MWWorld::Class::get (ptr).getCreatureStats (ptr).mFight = value;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpSetFlee : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
MWWorld::Class::get (ptr).getCreatureStats (ptr).mFlee = value;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpSetAlarm : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
MWWorld::Class::get (ptr).getCreatureStats (ptr).mAlarm = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const int opcodeAiTravel = 0x20000;
|
||||
|
@ -96,6 +187,16 @@ namespace MWScript
|
|||
const int opcodeAiEscortExplicit = 0x20003;
|
||||
const int opcodeGetAiPackageDone = 0x200007c;
|
||||
const int opcodeGetAiPackageDoneExplicit = 0x200007d;
|
||||
const int opcodeAiWander = 0x20010;
|
||||
const int opcodeAiWanderExplicit = 0x20011;
|
||||
const int opcodeSetHello = 0x200015e;
|
||||
const int opcodeSetHelloExplicit = 0x200015d;
|
||||
const int opcodeSetFight = 0x200015e;
|
||||
const int opcodeSetFightExplicit = 0x200015f;
|
||||
const int opcodeSetFlee = 0x2000160;
|
||||
const int opcodeSetFleeExplicit = 0x2000161;
|
||||
const int opcodeSetAlarm = 0x2000162;
|
||||
const int opcodeSetAlarmExplicit = 0x2000163;
|
||||
|
||||
void registerExtensions (Compiler::Extensions& extensions)
|
||||
{
|
||||
|
@ -103,9 +204,16 @@ namespace MWScript
|
|||
opcodeAiTravelExplicit);
|
||||
extensions.registerInstruction ("aiescort", "cffff/l", opcodeAiEscort,
|
||||
opcodeAiEscortExplicit);
|
||||
extensions.registerInstruction ("aiwander", "fff/llllllllll", opcodeAiWander,
|
||||
opcodeAiWanderExplicit);
|
||||
|
||||
extensions.registerFunction ("getaipackagedone", 'l', "", opcodeGetAiPackageDone,
|
||||
opcodeGetAiPackageDoneExplicit);
|
||||
|
||||
extensions.registerInstruction ("sethello", "l", opcodeSetHello, opcodeSetHelloExplicit);
|
||||
extensions.registerInstruction ("setfight", "l", opcodeSetFight, opcodeSetFightExplicit);
|
||||
extensions.registerInstruction ("setflee", "l", opcodeSetFlee, opcodeSetFleeExplicit);
|
||||
extensions.registerInstruction ("setalarm", "l", opcodeSetAlarm, opcodeSetAlarmExplicit);
|
||||
}
|
||||
|
||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||
|
@ -114,9 +222,19 @@ namespace MWScript
|
|||
interpreter.installSegment3 (opcodeAiTravelExplicit, new OpAiTravel<ExplicitRef>);
|
||||
interpreter.installSegment3 (opcodeAiEscort, new OpAiEscort<ImplicitRef>);
|
||||
interpreter.installSegment3 (opcodeAiEscortExplicit, new OpAiEscort<ExplicitRef>);
|
||||
interpreter.installSegment3 (opcodeAiWander, new OpAiWander<ImplicitRef>);
|
||||
interpreter.installSegment3 (opcodeAiWanderExplicit, new OpAiWander<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeGetAiPackageDone, new OpGetAiPackageDone<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeGetAiPackageDoneExplicit,
|
||||
new OpGetAiPackageDone<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetHello, new OpSetHello<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetHelloExplicit, new OpSetHello<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetFight, new OpSetFight<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetFightExplicit, new OpSetFight<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetFlee, new OpSetFlee<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetFleeExplicit, new OpSetFlee<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetAlarm, new OpSetAlarm<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeSetAlarmExplicit, new OpSetAlarm<ExplicitRef>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "scriptmanager.hpp"
|
||||
|
||||
namespace MWScript
|
||||
{
|
||||
CompilerContext::CompilerContext (Type type)
|
||||
|
@ -21,6 +23,18 @@ namespace MWScript
|
|||
return MWBase::Environment::get().getWorld()->getGlobalVariableType (name);
|
||||
}
|
||||
|
||||
char CompilerContext::getMemberType (const std::string& name, const std::string& id) const
|
||||
{
|
||||
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPtr (id, false);
|
||||
|
||||
std::string script = MWWorld::Class::get (ptr).getScript (ptr);
|
||||
|
||||
if (script.empty())
|
||||
return ' ';
|
||||
|
||||
return MWBase::Environment::get().getScriptManager()->getLocals (script).getType (name);
|
||||
}
|
||||
|
||||
bool CompilerContext::isId (const std::string& name) const
|
||||
{
|
||||
return
|
||||
|
|
|
@ -30,6 +30,9 @@ namespace MWScript
|
|||
/// 'l: long, 's': short, 'f': float, ' ': does not exist.
|
||||
virtual char getGlobalType (const std::string& name) const;
|
||||
|
||||
virtual char getMemberType (const std::string& name, const std::string& id) const;
|
||||
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
|
||||
|
||||
virtual bool isId (const std::string& name) const;
|
||||
///< Does \a name match an ID, that can be referenced?
|
||||
};
|
||||
|
|
|
@ -11,7 +11,10 @@
|
|||
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
#include "../mwmechanics/npcstats.hpp"
|
||||
|
||||
#include "interpretercontext.hpp"
|
||||
#include "ref.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
@ -54,11 +57,71 @@ namespace MWScript
|
|||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpClearForceRun : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
MWWorld::Class::get (ptr).getNpcStats (ptr).mForceRun = false;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpForceRun : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
MWWorld::Class::get (ptr).getNpcStats (ptr).mForceRun = true;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpClearForceSneak : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
MWWorld::Class::get (ptr).getNpcStats (ptr).mForceSneak = false;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R>
|
||||
class OpForceSneak : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
MWWorld::Class::get (ptr).getNpcStats (ptr).mForceSneak = true;
|
||||
}
|
||||
};
|
||||
|
||||
const int numberOfControls = 7;
|
||||
|
||||
const int opcodeEnable = 0x200007e;
|
||||
const int opcodeDisable = 0x2000085;
|
||||
const int opcodeToggleCollision = 0x2000130;
|
||||
const int opcodeClearForceRun = 0x2000154;
|
||||
const int opcodeClearForceRunExplicit = 0x2000155;
|
||||
const int opcodeForceRun = 0x2000156;
|
||||
const int opcodeForceRunExplicit = 0x2000157;
|
||||
const int opcodeClearForceSneak = 0x2000158;
|
||||
const int opcodeClearForceSneakExplicit = 0x2000159;
|
||||
const int opcodeForceSneak = 0x200015a;
|
||||
const int opcodeForceSneakExplicit = 0x200015b;
|
||||
|
||||
const char *controls[numberOfControls] =
|
||||
{
|
||||
|
@ -79,6 +142,16 @@ namespace MWScript
|
|||
|
||||
extensions.registerInstruction ("togglecollision", "", opcodeToggleCollision);
|
||||
extensions.registerInstruction ("tcl", "", opcodeToggleCollision);
|
||||
|
||||
extensions.registerInstruction ("clearforcerun", "", opcodeClearForceRun,
|
||||
opcodeClearForceRunExplicit);
|
||||
extensions.registerInstruction ("forcerun", "", opcodeForceRun,
|
||||
opcodeForceRunExplicit);
|
||||
|
||||
extensions.registerInstruction ("clearforcesneak", "", opcodeClearForceSneak,
|
||||
opcodeClearForceSneakExplicit);
|
||||
extensions.registerInstruction ("forcesneak", "", opcodeForceSneak,
|
||||
opcodeForceSneakExplicit);
|
||||
}
|
||||
|
||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||
|
@ -90,6 +163,20 @@ namespace MWScript
|
|||
}
|
||||
|
||||
interpreter.installSegment5 (opcodeToggleCollision, new OpToggleCollision);
|
||||
|
||||
interpreter.installSegment5 (opcodeClearForceRun, new OpClearForceRun<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeForceRun, new OpForceRun<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeClearForceSneak, new OpClearForceSneak<ImplicitRef>);
|
||||
interpreter.installSegment5 (opcodeForceSneak, new OpForceSneak<ImplicitRef>);
|
||||
|
||||
interpreter.installSegment5 (opcodeClearForceRunExplicit,
|
||||
new OpClearForceRun<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeForceRunExplicit,
|
||||
new OpForceRun<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeClearForceSneakExplicit,
|
||||
new OpClearForceSneak<ExplicitRef>);
|
||||
interpreter.installSegment5 (opcodeForceSneakExplicit,
|
||||
new OpForceSneak<ExplicitRef>);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,9 @@ op 0x2000c: PCLowerRank
|
|||
op 0x2000d: PCJoinFaction
|
||||
op 0x2000e: PCGetRank implicit
|
||||
op 0x2000f: PCGetRank explicit
|
||||
opcodes 0x20010-0x3ffff unused
|
||||
op 0x20010: AiWander
|
||||
op 0x20011: AiWander, explicit reference
|
||||
opcodes 0x20012-0x3ffff unused
|
||||
|
||||
Segment 4:
|
||||
(not implemented yet)
|
||||
|
@ -147,4 +149,20 @@ op 0x2000150: ForceGreeting, explicit reference
|
|||
op 0x2000151: ToggleFullHelp
|
||||
op 0x2000152: Goodbye
|
||||
op 0x2000153: DontSaveObject (left unimplemented)
|
||||
opcodes 0x2000154-0x3ffffff unused
|
||||
op 0x2000154: ClearForceRun
|
||||
op 0x2000155: ClearForceRun, explicit reference
|
||||
op 0x2000156: ForceRun
|
||||
op 0x2000157: ForceRun, explicit reference
|
||||
op 0x2000158: ClearForceSneak
|
||||
op 0x2000159: ClearForceSneak, explicit reference
|
||||
op 0x200015a: ForceSneak
|
||||
op 0x200015b: ForceSneak, explicit reference
|
||||
op 0x200015c: SetHello
|
||||
op 0x200015d: SetHello, explicit reference
|
||||
op 0x200015e: SetFight
|
||||
op 0x200015f: SetFight, explicit reference
|
||||
op 0x2000160: SetFlee
|
||||
op 0x2000161: SetFlee, explicit reference
|
||||
op 0x2000162: SetAlarm
|
||||
op 0x2000163: SetAlarm, explicit reference
|
||||
opcodes 0x2000164-0x3ffffff unused
|
||||
|
|
|
@ -104,7 +104,7 @@ namespace MWScript
|
|||
extensions.registerInstruction ("enableclassmenu", "", opcodeEnableClassMenu);
|
||||
extensions.registerInstruction ("enablenamemenu", "", opcodeEnableNameMenu);
|
||||
extensions.registerInstruction ("enableracemenu", "", opcodeEnableRaceMenu);
|
||||
extensions.registerInstruction ("enablestatsreviewmenu", "",
|
||||
extensions.registerInstruction ("enablestatreviewmenu", "",
|
||||
opcodeEnableStatsReviewMenu);
|
||||
|
||||
extensions.registerInstruction ("enableinventorymenu", "", opcodeEnableInventoryMenu);
|
||||
|
|
|
@ -270,6 +270,84 @@ namespace MWScript
|
|||
MWBase::Environment::get().getWorld()->disable (ref);
|
||||
}
|
||||
|
||||
int InterpreterContext::getMemberShort (const std::string& id, const std::string& name) const
|
||||
{
|
||||
const MWWorld::Ptr ptr = getReference (id, false);
|
||||
|
||||
std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr);
|
||||
|
||||
int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 's');
|
||||
|
||||
ptr.getRefData().setLocals (
|
||||
*MWBase::Environment::get().getWorld()->getStore().scripts.find (scriptId));
|
||||
return ptr.getRefData().getLocals().mShorts[index];
|
||||
}
|
||||
|
||||
int InterpreterContext::getMemberLong (const std::string& id, const std::string& name) const
|
||||
{
|
||||
const MWWorld::Ptr ptr = getReference (id, false);
|
||||
|
||||
std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr);
|
||||
|
||||
int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'l');
|
||||
|
||||
ptr.getRefData().setLocals (
|
||||
*MWBase::Environment::get().getWorld()->getStore().scripts.find (scriptId));
|
||||
return ptr.getRefData().getLocals().mLongs[index];
|
||||
}
|
||||
|
||||
float InterpreterContext::getMemberFloat (const std::string& id, const std::string& name) const
|
||||
{
|
||||
const MWWorld::Ptr ptr = getReference (id, false);
|
||||
|
||||
std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr);
|
||||
|
||||
int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'f');
|
||||
|
||||
ptr.getRefData().setLocals (
|
||||
*MWBase::Environment::get().getWorld()->getStore().scripts.find (scriptId));
|
||||
return ptr.getRefData().getLocals().mFloats[index];
|
||||
}
|
||||
|
||||
void InterpreterContext::setMemberShort (const std::string& id, const std::string& name, int value)
|
||||
{
|
||||
const MWWorld::Ptr ptr = getReference (id, false);
|
||||
|
||||
std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr);
|
||||
|
||||
int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 's');
|
||||
|
||||
ptr.getRefData().setLocals (
|
||||
*MWBase::Environment::get().getWorld()->getStore().scripts.find (scriptId));
|
||||
ptr.getRefData().getLocals().mShorts[index] = value;
|
||||
}
|
||||
|
||||
void InterpreterContext::setMemberLong (const std::string& id, const std::string& name, int value)
|
||||
{
|
||||
const MWWorld::Ptr ptr = getReference (id, false);
|
||||
|
||||
std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr);
|
||||
|
||||
int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'l');
|
||||
|
||||
ptr.getRefData().setLocals (
|
||||
*MWBase::Environment::get().getWorld()->getStore().scripts.find (scriptId));
|
||||
ptr.getRefData().getLocals().mLongs[index] = value;
|
||||
}
|
||||
|
||||
void InterpreterContext::setMemberFloat (const std::string& id, const std::string& name, float value)
|
||||
{
|
||||
const MWWorld::Ptr ptr = getReference (id, false);
|
||||
|
||||
std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr);
|
||||
|
||||
int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'f');
|
||||
|
||||
ptr.getRefData().setLocals (
|
||||
*MWBase::Environment::get().getWorld()->getStore().scripts.find (scriptId));
|
||||
ptr.getRefData().getLocals().mFloats[index] = value;
|
||||
}
|
||||
|
||||
MWWorld::Ptr InterpreterContext::getReference()
|
||||
{
|
||||
return getReference ("", true);
|
||||
|
|
|
@ -107,6 +107,18 @@ namespace MWScript
|
|||
|
||||
virtual void disable (const std::string& id = "");
|
||||
|
||||
virtual int getMemberShort (const std::string& id, const std::string& name) const;
|
||||
|
||||
virtual int getMemberLong (const std::string& id, const std::string& name) const;
|
||||
|
||||
virtual float getMemberFloat (const std::string& id, const std::string& name) const;
|
||||
|
||||
virtual void setMemberShort (const std::string& id, const std::string& name, int value);
|
||||
|
||||
virtual void setMemberLong (const std::string& id, const std::string& name, int value);
|
||||
|
||||
virtual void setMemberFloat (const std::string& id, const std::string& name, float value);
|
||||
|
||||
MWWorld::Ptr getReference();
|
||||
///< Reference, that the script is running from (can be empty)
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <components/compiler/scanner.hpp>
|
||||
#include <components/compiler/context.hpp>
|
||||
#include <components/compiler/exception.hpp>
|
||||
|
||||
#include "extensions.hpp"
|
||||
|
||||
|
@ -46,8 +47,14 @@ namespace MWScript
|
|||
if (!mErrorHandler.isGood())
|
||||
Success = false;
|
||||
}
|
||||
catch (...)
|
||||
catch (const Compiler::SourceException&)
|
||||
{
|
||||
// error has already been reported via error handler
|
||||
Success = false;
|
||||
}
|
||||
catch (const std::exception& error)
|
||||
{
|
||||
std::cerr << "An exception has been thrown: " << error.what() << std::endl;
|
||||
Success = false;
|
||||
}
|
||||
|
||||
|
@ -140,6 +147,9 @@ namespace MWScript
|
|||
{
|
||||
if (!compile (name))
|
||||
{
|
||||
/// \todo Handle case of cyclic member variable access. Currently this could look up
|
||||
/// the whole application in an endless recursion.
|
||||
|
||||
// failed -> ignore script from now on.
|
||||
std::vector<Interpreter::Type_Code> empty;
|
||||
mScripts.insert (std::make_pair (name, std::make_pair (empty, Compiler::Locals())));
|
||||
|
@ -156,4 +166,43 @@ namespace MWScript
|
|||
{
|
||||
return mGlobalScripts;
|
||||
}
|
||||
|
||||
int ScriptManager::getLocalIndex (const std::string& scriptId, const std::string& variable,
|
||||
char type)
|
||||
{
|
||||
const ESM::Script *script = mStore.scripts.find (scriptId);
|
||||
|
||||
int offset = 0;
|
||||
int size = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 's':
|
||||
|
||||
offset = 0;
|
||||
size = script->data.numShorts;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
|
||||
offset = script->data.numShorts;
|
||||
size = script->data.numLongs;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
|
||||
offset = script->data.numShorts+script->data.numLongs;
|
||||
size = script->data.numFloats;
|
||||
|
||||
default:
|
||||
|
||||
throw std::runtime_error ("invalid variable type");
|
||||
}
|
||||
|
||||
for (int i=0; i<size; ++i)
|
||||
if (script->varNames.at (i+offset)==variable)
|
||||
return i;
|
||||
|
||||
throw std::runtime_error ("unable to access local variable " + variable + " of " + scriptId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,10 @@ namespace MWScript
|
|||
///< Return locals for script \a name.
|
||||
|
||||
GlobalScripts& getGlobalScripts();
|
||||
|
||||
int getLocalIndex (const std::string& scriptId, const std::string& variable, char type);
|
||||
///< Return index of the variable of the given name and type in the given script. Will
|
||||
/// throw an exception, if there is no such script or variable or the type does not match.
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -10,33 +10,35 @@ namespace Compiler
|
|||
class Context
|
||||
{
|
||||
const Extensions *mExtensions;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
Context() : mExtensions (0) {}
|
||||
|
||||
|
||||
virtual ~Context() {}
|
||||
|
||||
|
||||
virtual bool canDeclareLocals() const = 0;
|
||||
///< Is the compiler allowed to declare local variables?
|
||||
|
||||
|
||||
void setExtensions (const Extensions *extensions = 0)
|
||||
{
|
||||
mExtensions = extensions;
|
||||
}
|
||||
|
||||
|
||||
const Extensions *getExtensions() const
|
||||
{
|
||||
return mExtensions;
|
||||
}
|
||||
|
||||
|
||||
virtual char getGlobalType (const std::string& name) const = 0;
|
||||
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
|
||||
|
||||
|
||||
virtual char getMemberType (const std::string& name, const std::string& id) const = 0;
|
||||
///< 'l: long, 's': short, 'f': float, ' ': does not exist.
|
||||
|
||||
virtual bool isId (const std::string& name) const = 0;
|
||||
///< Does \a name match an ID, that can be referenced?
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -195,10 +195,31 @@ namespace Compiler
|
|||
return parseArguments (arguments, scanner, mCode);
|
||||
}
|
||||
|
||||
bool ExprParser::handleMemberAccess (const std::string& name)
|
||||
{
|
||||
mMemberOp = false;
|
||||
|
||||
std::string name2 = toLower (name);
|
||||
std::string id = toLower (mExplicit);
|
||||
|
||||
char type = getContext().getMemberType (name2, id);
|
||||
|
||||
if (type!=' ')
|
||||
{
|
||||
Generator::fetchMember (mCode, mLiterals, type, name2, id);
|
||||
mNextOperand = false;
|
||||
mExplicit.clear();
|
||||
mOperands.push_back (type=='f' ? 'f' : 'l');
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ExprParser::ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
||||
Literals& literals, bool argument)
|
||||
: Parser (errorHandler, context), mLocals (locals), mLiterals (literals),
|
||||
mNextOperand (true), mFirst (true), mArgument (argument)
|
||||
mNextOperand (true), mFirst (true), mArgument (argument), mRefOp (false), mMemberOp (false)
|
||||
{}
|
||||
|
||||
bool ExprParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
|
||||
|
@ -251,7 +272,12 @@ namespace Compiler
|
|||
Scanner& scanner)
|
||||
{
|
||||
if (!mExplicit.empty())
|
||||
{
|
||||
if (mMemberOp && handleMemberAccess (name))
|
||||
return true;
|
||||
|
||||
return Parser::parseName (name, loc, scanner);
|
||||
}
|
||||
|
||||
mFirst = false;
|
||||
|
||||
|
@ -281,7 +307,7 @@ namespace Compiler
|
|||
return true;
|
||||
}
|
||||
|
||||
if (mExplicit.empty() && getContext().isId (name))
|
||||
if (mExplicit.empty() && getContext().isId (name2))
|
||||
{
|
||||
mExplicit = name;
|
||||
return true;
|
||||
|
@ -497,6 +523,12 @@ namespace Compiler
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!mMemberOp && code==Scanner::S_member)
|
||||
{
|
||||
mMemberOp = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return Parser::parseSpecial (code, loc, scanner);
|
||||
}
|
||||
|
||||
|
@ -609,6 +641,7 @@ namespace Compiler
|
|||
mFirst = true;
|
||||
mExplicit.clear();
|
||||
mRefOp = false;
|
||||
mMemberOp = false;
|
||||
Parser::reset();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace Compiler
|
|||
bool mArgument;
|
||||
std::string mExplicit;
|
||||
bool mRefOp;
|
||||
bool mMemberOp;
|
||||
|
||||
int getPriority (char op) const;
|
||||
|
||||
|
@ -53,6 +54,8 @@ namespace Compiler
|
|||
|
||||
int parseArguments (const std::string& arguments, Scanner& scanner);
|
||||
|
||||
bool handleMemberAccess (const std::string& name);
|
||||
|
||||
public:
|
||||
|
||||
ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
||||
|
|
|
@ -260,6 +260,36 @@ namespace
|
|||
code.push_back (Compiler::Generator::segment5 (44));
|
||||
}
|
||||
|
||||
void opStoreMemberShort (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (Compiler::Generator::segment5 (59));
|
||||
}
|
||||
|
||||
void opStoreMemberLong (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (Compiler::Generator::segment5 (60));
|
||||
}
|
||||
|
||||
void opStoreMemberFloat (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (Compiler::Generator::segment5 (61));
|
||||
}
|
||||
|
||||
void opFetchMemberShort (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (Compiler::Generator::segment5 (62));
|
||||
}
|
||||
|
||||
void opFetchMemberLong (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (Compiler::Generator::segment5 (63));
|
||||
}
|
||||
|
||||
void opFetchMemberFloat (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (Compiler::Generator::segment5 (64));
|
||||
}
|
||||
|
||||
void opRandom (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (Compiler::Generator::segment5 (45));
|
||||
|
@ -644,7 +674,7 @@ namespace Compiler
|
|||
|
||||
if (localType!=valueType)
|
||||
{
|
||||
if (localType=='f' && valueType=='l')
|
||||
if (localType=='f' && (valueType=='l' || valueType=='s'))
|
||||
{
|
||||
opIntToFloat (code);
|
||||
}
|
||||
|
@ -707,6 +737,88 @@ namespace Compiler
|
|||
}
|
||||
}
|
||||
|
||||
void assignToMember (CodeContainer& code, Literals& literals, char localType,
|
||||
const std::string& name, const std::string& id, const CodeContainer& value, char valueType)
|
||||
{
|
||||
int index = literals.addString (name);
|
||||
|
||||
opPushInt (code, index);
|
||||
|
||||
index = literals.addString (id);
|
||||
|
||||
opPushInt (code, index);
|
||||
|
||||
std::copy (value.begin(), value.end(), std::back_inserter (code));
|
||||
|
||||
if (localType!=valueType)
|
||||
{
|
||||
if (localType=='f' && (valueType=='l' || valueType=='s'))
|
||||
{
|
||||
opIntToFloat (code);
|
||||
}
|
||||
else if ((localType=='l' || localType=='s') && valueType=='f')
|
||||
{
|
||||
opFloatToInt (code);
|
||||
}
|
||||
}
|
||||
|
||||
switch (localType)
|
||||
{
|
||||
case 'f':
|
||||
|
||||
opStoreMemberFloat (code);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
|
||||
opStoreMemberShort (code);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
|
||||
opStoreMemberLong (code);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
assert (0);
|
||||
}
|
||||
}
|
||||
|
||||
void fetchMember (CodeContainer& code, Literals& literals, char localType,
|
||||
const std::string& name, const std::string& id)
|
||||
{
|
||||
int index = literals.addString (name);
|
||||
|
||||
opPushInt (code, index);
|
||||
|
||||
index = literals.addString (id);
|
||||
|
||||
opPushInt (code, index);
|
||||
|
||||
switch (localType)
|
||||
{
|
||||
case 'f':
|
||||
|
||||
opFetchMemberFloat (code);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
|
||||
opFetchMemberShort (code);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
|
||||
opFetchMemberLong (code);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
assert (0);
|
||||
}
|
||||
}
|
||||
|
||||
void random (CodeContainer& code)
|
||||
{
|
||||
opRandom (code);
|
||||
|
|
|
@ -101,6 +101,12 @@ namespace Compiler
|
|||
void fetchGlobal (CodeContainer& code, Literals& literals, char localType,
|
||||
const std::string& name);
|
||||
|
||||
void assignToMember (CodeContainer& code, Literals& literals, char memberType,
|
||||
const std::string& name, const std::string& id, const CodeContainer& value, char valueType);
|
||||
|
||||
void fetchMember (CodeContainer& code, Literals& literals, char memberType,
|
||||
const std::string& name, const std::string& id);
|
||||
|
||||
void random (CodeContainer& code);
|
||||
|
||||
void scriptRunning (CodeContainer& code);
|
||||
|
|
|
@ -18,7 +18,10 @@ namespace Compiler
|
|||
if (!mExplicit.empty())
|
||||
{
|
||||
mExprParser.parseName (mExplicit, loc, scanner);
|
||||
mExprParser.parseSpecial (Scanner::S_ref, loc, scanner);
|
||||
if (mState==MemberState)
|
||||
mExprParser.parseSpecial (Scanner::S_member, loc, scanner);
|
||||
else
|
||||
mExprParser.parseSpecial (Scanner::S_ref, loc, scanner);
|
||||
}
|
||||
|
||||
scanner.scan (mExprParser);
|
||||
|
@ -110,12 +113,13 @@ namespace Compiler
|
|||
if (mState==SetState)
|
||||
{
|
||||
std::string name2 = toLower (name);
|
||||
mName = name2;
|
||||
|
||||
// local variable?
|
||||
char type = mLocals.getType (name2);
|
||||
if (type!=' ')
|
||||
{
|
||||
mName = name2;
|
||||
mType = type;
|
||||
mState = SetLocalVarState;
|
||||
return true;
|
||||
}
|
||||
|
@ -123,12 +127,27 @@ namespace Compiler
|
|||
type = getContext().getGlobalType (name2);
|
||||
if (type!=' ')
|
||||
{
|
||||
mName = name2;
|
||||
mType = type;
|
||||
mState = SetGlobalVarState;
|
||||
return true;
|
||||
}
|
||||
|
||||
mState = SetPotentialMemberVarState;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mState==SetMemberVarState)
|
||||
{
|
||||
mMemberName = toLower (name);
|
||||
char type = getContext().getMemberType (mMemberName, mName);
|
||||
|
||||
if (type!=' ')
|
||||
{
|
||||
mState = SetMemberVarState2;
|
||||
mType = type;
|
||||
return true;
|
||||
}
|
||||
|
||||
getErrorHandler().error ("unknown variable", loc);
|
||||
SkipParser skip (getErrorHandler(), getContext());
|
||||
scanner.scan (skip);
|
||||
|
@ -256,6 +275,7 @@ namespace Compiler
|
|||
{
|
||||
scanner.putbackKeyword (keyword, loc);
|
||||
parseExpression (scanner, loc);
|
||||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -269,6 +289,7 @@ namespace Compiler
|
|||
{
|
||||
scanner.putbackKeyword (keyword, loc);
|
||||
parseExpression (scanner, loc);
|
||||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -333,6 +354,19 @@ namespace Compiler
|
|||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
else if (mState==SetMemberVarState2 && keyword==Scanner::K_to)
|
||||
{
|
||||
mExprParser.reset();
|
||||
scanner.scan (mExprParser);
|
||||
|
||||
std::vector<Interpreter::Type_Code> code;
|
||||
char type = mExprParser.append (code);
|
||||
|
||||
Generator::assignToMember (mCode, mLiterals, mType, mMemberName, mName, code, type);
|
||||
|
||||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mAllowExpression)
|
||||
{
|
||||
|
@ -342,6 +376,7 @@ namespace Compiler
|
|||
{
|
||||
scanner.putbackKeyword (keyword, loc);
|
||||
parseExpression (scanner, loc);
|
||||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -366,6 +401,14 @@ namespace Compiler
|
|||
return true;
|
||||
}
|
||||
|
||||
if (code==Scanner::S_member && mState==PotentialExplicitState)
|
||||
{
|
||||
mState = MemberState;
|
||||
parseExpression (scanner, loc);
|
||||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (code==Scanner::S_newline && mState==MessageButtonState)
|
||||
{
|
||||
Generator::message (mCode, mLiterals, mName, mButtons);
|
||||
|
@ -378,11 +421,18 @@ namespace Compiler
|
|||
return true;
|
||||
}
|
||||
|
||||
if (code==Scanner::S_member && mState==SetPotentialMemberVarState)
|
||||
{
|
||||
mState = SetMemberVarState;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mAllowExpression && mState==BeginState &&
|
||||
(code==Scanner::S_open || code==Scanner::S_minus))
|
||||
{
|
||||
scanner.putbackSpecial (code, loc);
|
||||
parseExpression (scanner, loc);
|
||||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,10 +21,11 @@ namespace Compiler
|
|||
{
|
||||
BeginState,
|
||||
ShortState, LongState, FloatState,
|
||||
SetState, SetLocalVarState, SetGlobalVarState,
|
||||
SetState, SetLocalVarState, SetGlobalVarState, SetPotentialMemberVarState,
|
||||
SetMemberVarState, SetMemberVarState2,
|
||||
MessageState, MessageCommaState, MessageButtonState, MessageButtonCommaState,
|
||||
EndState,
|
||||
PotentialExplicitState, ExplicitState
|
||||
PotentialExplicitState, ExplicitState, MemberState
|
||||
};
|
||||
|
||||
Locals& mLocals;
|
||||
|
@ -32,6 +33,7 @@ namespace Compiler
|
|||
std::vector<Interpreter::Type_Code>& mCode;
|
||||
State mState;
|
||||
std::string mName;
|
||||
std::string mMemberName;
|
||||
int mButtons;
|
||||
std::string mExplicit;
|
||||
char mType;
|
||||
|
|
|
@ -360,6 +360,8 @@ namespace Compiler
|
|||
special = S_open;
|
||||
else if (c==')')
|
||||
special = S_close;
|
||||
else if (c=='.')
|
||||
special = S_member;
|
||||
else if (c=='=')
|
||||
{
|
||||
if (get (c))
|
||||
|
|
|
@ -65,7 +65,8 @@ namespace Compiler
|
|||
S_cmpEQ, S_cmpNE, S_cmpLT, S_cmpLE, S_cmpGT, S_cmpGE,
|
||||
S_plus, S_minus, S_mult, S_div,
|
||||
S_comma,
|
||||
S_ref
|
||||
S_ref,
|
||||
S_member
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -65,6 +65,19 @@ namespace Interpreter
|
|||
virtual void enable (const std::string& id = "") = 0;
|
||||
|
||||
virtual void disable (const std::string& id = "") = 0;
|
||||
|
||||
virtual int getMemberShort (const std::string& id, const std::string& name) const = 0;
|
||||
|
||||
virtual int getMemberLong (const std::string& id, const std::string& name) const = 0;
|
||||
|
||||
virtual float getMemberFloat (const std::string& id, const std::string& name) const = 0;
|
||||
|
||||
virtual void setMemberShort (const std::string& id, const std::string& name, int value) = 0;
|
||||
|
||||
virtual void setMemberLong (const std::string& id, const std::string& name, int value) = 0;
|
||||
|
||||
virtual void setMemberFloat (const std::string& id, const std::string& name, float value)
|
||||
= 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -121,5 +121,11 @@ op 58: report string literal index in stack[0];
|
|||
additional arguments (if any) in stack[n]..stack[1];
|
||||
n is determined according to the message string
|
||||
all arguments are removed from stack
|
||||
opcodes 59-33554431 unused
|
||||
op 59: store stack[0] in member short stack[2] of object with ID stack[1]
|
||||
op 60: store stack[0] in member long stack[2] of object with ID stack[1]
|
||||
op 61: store stack[0] in member float stack[2] of object with ID stack[1]
|
||||
op 62: replace stack[0] with member short stack[1] of object with ID stack[0]
|
||||
op 63: replace stack[0] with member short stack[1] of object with ID stack[0]
|
||||
op 64: replace stack[0] with member short stack[1] of object with ID stack[0]
|
||||
opcodes 65-33554431 unused
|
||||
opcodes 33554432-67108863 reserved for extensions
|
||||
|
|
|
@ -40,6 +40,12 @@ namespace Interpreter
|
|||
interpreter.installSegment5 (42, new OpFetchGlobalShort);
|
||||
interpreter.installSegment5 (43, new OpFetchGlobalLong);
|
||||
interpreter.installSegment5 (44, new OpFetchGlobalFloat);
|
||||
interpreter.installSegment5 (59, new OpStoreMemberShort);
|
||||
interpreter.installSegment5 (60, new OpStoreMemberLong);
|
||||
interpreter.installSegment5 (61, new OpStoreMemberFloat);
|
||||
interpreter.installSegment5 (62, new OpFetchMemberShort);
|
||||
interpreter.installSegment5 (63, new OpFetchMemberLong);
|
||||
interpreter.installSegment5 (64, new OpFetchMemberFloat);
|
||||
|
||||
// math
|
||||
interpreter.installSegment5 (9, new OpAddInt<Type_Integer>);
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
#include "context.hpp"
|
||||
|
||||
namespace Interpreter
|
||||
{
|
||||
{
|
||||
class OpStoreLocalShort : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
|
@ -20,13 +20,13 @@ namespace Interpreter
|
|||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class OpStoreLocalLong : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
|
@ -36,13 +36,13 @@ namespace Interpreter
|
|||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class OpStoreLocalFloat : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Float data = runtime[0].mFloat;
|
||||
|
@ -52,71 +52,71 @@ namespace Interpreter
|
|||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class OpFetchIntLiteral : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer intValue = runtime.getIntegerLiteral (runtime[0].mInteger);
|
||||
runtime[0].mInteger = intValue;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class OpFetchFloatLiteral : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Float floatValue = runtime.getFloatLiteral (runtime[0].mInteger);
|
||||
runtime[0].mFloat = floatValue;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class OpFetchLocalShort : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0].mInteger;
|
||||
int value = runtime.getContext().getLocalShort (index);
|
||||
runtime[0].mInteger = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class OpFetchLocalLong : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0].mInteger;
|
||||
int index = runtime[0].mInteger;
|
||||
int value = runtime.getContext().getLocalLong (index);
|
||||
runtime[0].mInteger = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class OpFetchLocalFloat : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0].mInteger;
|
||||
float value = runtime.getContext().getLocalFloat (index);
|
||||
runtime[0].mFloat = value;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class OpStoreGlobalShort : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
|
@ -128,13 +128,13 @@ namespace Interpreter
|
|||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class OpStoreGlobalLong : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
|
@ -146,13 +146,13 @@ namespace Interpreter
|
|||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class OpStoreGlobalFloat : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Float data = runtime[0].mFloat;
|
||||
|
@ -164,48 +164,158 @@ namespace Interpreter
|
|||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class OpFetchGlobalShort : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0].mInteger;
|
||||
int index = runtime[0].mInteger;
|
||||
std::string name = runtime.getStringLiteral (index);
|
||||
Type_Integer value = runtime.getContext().getGlobalShort (name);
|
||||
runtime[0].mInteger = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class OpFetchGlobalLong : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0].mInteger;
|
||||
int index = runtime[0].mInteger;
|
||||
std::string name = runtime.getStringLiteral (index);
|
||||
Type_Integer value = runtime.getContext().getGlobalLong (name);
|
||||
runtime[0].mInteger = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class OpFetchGlobalFloat : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0].mInteger;
|
||||
std::string name = runtime.getStringLiteral (index);
|
||||
Type_Float value = runtime.getContext().getGlobalFloat (name);
|
||||
runtime[0].mFloat = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class OpStoreMemberShort : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
Type_Integer index = runtime[1].mInteger;
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
index = runtime[2].mInteger;
|
||||
std::string variable = runtime.getStringLiteral (index);
|
||||
|
||||
runtime.getContext().setMemberShort (id, variable, data);
|
||||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
}
|
||||
};
|
||||
|
||||
class OpStoreMemberLong : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
Type_Integer index = runtime[1].mInteger;
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
index = runtime[2].mInteger;
|
||||
std::string variable = runtime.getStringLiteral (index);
|
||||
|
||||
runtime.getContext().setMemberLong (id, variable, data);
|
||||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
}
|
||||
};
|
||||
|
||||
class OpStoreMemberFloat : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Float data = runtime[0].mFloat;
|
||||
Type_Integer index = runtime[1].mInteger;
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
index = runtime[2].mInteger;
|
||||
std::string variable = runtime.getStringLiteral (index);
|
||||
|
||||
runtime.getContext().setMemberFloat (id, variable, data);
|
||||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
}
|
||||
};
|
||||
|
||||
class OpFetchMemberShort : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer index = runtime[0].mInteger;
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
index = runtime[1].mInteger;
|
||||
std::string variable = runtime.getStringLiteral (index);
|
||||
runtime.pop();
|
||||
|
||||
int value = runtime.getContext().getMemberShort (id, variable);
|
||||
runtime[0].mInteger = value;
|
||||
}
|
||||
};
|
||||
|
||||
class OpFetchMemberLong : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer index = runtime[0].mInteger;
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
index = runtime[1].mInteger;
|
||||
std::string variable = runtime.getStringLiteral (index);
|
||||
runtime.pop();
|
||||
|
||||
int value = runtime.getContext().getMemberLong (id, variable);
|
||||
runtime[0].mInteger = value;
|
||||
}
|
||||
};
|
||||
|
||||
class OpFetchMemberFloat : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer index = runtime[0].mInteger;
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
index = runtime[1].mInteger;
|
||||
std::string variable = runtime.getStringLiteral (index);
|
||||
runtime.pop();
|
||||
|
||||
float value = runtime.getContext().getMemberFloat (id, variable);
|
||||
runtime[0].mFloat = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue