mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
* arithmetic and boolean operations on variables
* hopefully working DO receiver
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/assign/std/vector.hpp> // for 'operator+=()'
|
||||
|
||||
/*
|
||||
* ERMInterpreter.cpp, part of VCMI engine
|
||||
@@ -17,6 +18,7 @@
|
||||
|
||||
namespace spirit = boost::spirit;
|
||||
using namespace VERMInterpreter;
|
||||
using namespace boost::assign;
|
||||
|
||||
namespace ERMPrinter
|
||||
{
|
||||
@@ -580,11 +582,47 @@ struct VRPerformer : boost::static_visitor<>
|
||||
|
||||
void operator()(TVRLogic const& trig) const
|
||||
{
|
||||
//TODO
|
||||
int valr = interp->getIexp(trig.var).getInt();
|
||||
switch (trig.opcode)
|
||||
{
|
||||
case '&':
|
||||
const_cast<VRPerformer*>(this)->identifier.setTo(identifier.getInt() & valr);
|
||||
break;
|
||||
case '|':
|
||||
const_cast<VRPerformer*>(this)->identifier.setTo(identifier.getInt() | valr);
|
||||
break;
|
||||
case 'X':
|
||||
const_cast<VRPerformer*>(this)->identifier.setTo(identifier.getInt() ^ valr);
|
||||
break;
|
||||
default:
|
||||
throw EInterpreterError("Wrong opcode in VR logic expression!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void operator()(TVRArithmetic const& trig) const
|
||||
{
|
||||
//TODO
|
||||
IexpValStr rhs = interp->getIexp(trig.rhs);
|
||||
switch (trig.opcode)
|
||||
{
|
||||
case '+':
|
||||
const_cast<VRPerformer*>(this)->identifier += rhs;
|
||||
break;
|
||||
case '-':
|
||||
const_cast<VRPerformer*>(this)->identifier -= rhs;
|
||||
break;
|
||||
case '*':
|
||||
const_cast<VRPerformer*>(this)->identifier *= rhs;
|
||||
break;
|
||||
case ':':
|
||||
const_cast<VRPerformer*>(this)->identifier /= rhs;
|
||||
break;
|
||||
case '%':
|
||||
const_cast<VRPerformer*>(this)->identifier %= rhs;
|
||||
break;
|
||||
default:
|
||||
throw EInterpreterError("Wrong opcode in VR arithmetic!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void operator()(TNormalBodyOption const& trig) const
|
||||
{
|
||||
@@ -618,21 +656,37 @@ void VR_SPerformer::operator()(ERM::TIexp const& trig) const
|
||||
}
|
||||
|
||||
void VR_SPerformer::operator()(TVarConcatString const& cmp) const
|
||||
{}
|
||||
{
|
||||
throw EScriptExecError("String concatenation not allowed in VR S");
|
||||
}
|
||||
void VR_SPerformer::operator()(TStringConstant const& cmp) const
|
||||
{}
|
||||
{
|
||||
owner.identifier.setTo(cmp.str);
|
||||
}
|
||||
void VR_SPerformer::operator()(TCurriedString const& cmp) const
|
||||
{}
|
||||
{
|
||||
throw EScriptExecError("Curried string not allowed in VR S");
|
||||
}
|
||||
void VR_SPerformer::operator()(TSemiCompare const& cmp) const
|
||||
{}
|
||||
{
|
||||
throw EScriptExecError("Incomplete comparison not allowed in VR S");
|
||||
}
|
||||
void VR_SPerformer::operator()(TMacroUsage const& cmp) const
|
||||
{}
|
||||
{
|
||||
owner.identifier.setTo(owner.interp->getIexp(cmp));
|
||||
}
|
||||
void VR_SPerformer::operator()(TMacroDef const& cmp) const
|
||||
{}
|
||||
{
|
||||
throw EScriptExecError("Macro definition not allowed in VR S");
|
||||
}
|
||||
void VR_SPerformer::operator()(TVarpExp const& cmp) const
|
||||
{}
|
||||
{
|
||||
throw EScriptExecError("Write-only variable expression not allowed in VR S");
|
||||
}
|
||||
void VR_SPerformer::operator()(spirit::unused_type const& cmp) const
|
||||
{}
|
||||
{
|
||||
throw EScriptExecError("Expression not allowed in VR S");
|
||||
}
|
||||
|
||||
struct ConditionDisemboweler;
|
||||
|
||||
@@ -703,7 +757,11 @@ struct ERMExpDispatch : boost::static_visitor<>
|
||||
for(int it = startVal; it < stopVal; it += increment)
|
||||
{
|
||||
owner->getFuncVars(funNum)->getParam(16) = it;
|
||||
//owner->executeTriggerType(TriggerType("FU"), true, );
|
||||
ERMInterpreter::TIDPattern tip;
|
||||
std::vector<int> v1;
|
||||
v1 += funNum;
|
||||
insert(tip) (v1.size(), v1);
|
||||
owner->executeTriggerType(TriggerType("FU"), true, tip);
|
||||
it = owner->getFuncVars(funNum)->getParam(16);
|
||||
}
|
||||
}
|
||||
@@ -1041,7 +1099,7 @@ IexpValStr ERMInterpreter::getIexp( const ERM::TIdentifierInternal & tid ) const
|
||||
throw EScriptExecError("Identifier must be a valid i-expression to perform this operation!");
|
||||
}
|
||||
|
||||
void ERMInterpreter::executeTriggerType( VERMInterpreter::TriggerType tt, bool pre, const std::map< int, std::vector<int> > & identifier )
|
||||
void ERMInterpreter::executeTriggerType( VERMInterpreter::TriggerType tt, bool pre, const TIDPattern & identifier )
|
||||
{
|
||||
TtriggerListType & triggerList = pre ? triggers : postTriggers;
|
||||
|
||||
|
@@ -340,6 +340,129 @@ public:
|
||||
{
|
||||
val.stringvar = _val;
|
||||
}
|
||||
|
||||
#define OPERATOR_DEFINITION_FULL(OPSIGN) \
|
||||
template<typename T> \
|
||||
IexpValStr operator OPSIGN(const T & sec) const \
|
||||
{ \
|
||||
IexpValStr ret = *this; \
|
||||
switch (type) \
|
||||
{ \
|
||||
case INT: \
|
||||
case INTVAR: \
|
||||
ret.setTo(ret.getInt() OPSIGN sec); \
|
||||
break; \
|
||||
case FLOATVAR: \
|
||||
ret.setTo(ret.getFloat() OPSIGN sec); \
|
||||
break; \
|
||||
case STRINGVAR: \
|
||||
ret.setTo(ret.getString() OPSIGN sec); \
|
||||
break; \
|
||||
} \
|
||||
return ret; \
|
||||
} \
|
||||
IexpValStr operator OPSIGN(const IexpValStr & sec) const \
|
||||
{ \
|
||||
IexpValStr ret = *this; \
|
||||
switch (type) \
|
||||
{ \
|
||||
case INT: \
|
||||
case INTVAR: \
|
||||
ret.setTo(ret.getInt() OPSIGN sec.getInt()); \
|
||||
break; \
|
||||
case FLOATVAR: \
|
||||
ret.setTo(ret.getFloat() OPSIGN sec.getFloat()); \
|
||||
break; \
|
||||
case STRINGVAR: \
|
||||
ret.setTo(ret.getString() OPSIGN sec.getString()); \
|
||||
break; \
|
||||
} \
|
||||
return ret; \
|
||||
} \
|
||||
template<typename T> \
|
||||
IexpValStr & operator OPSIGN ## = (const T & sec) \
|
||||
{ \
|
||||
*this = *this OPSIGN sec; \
|
||||
return *this; \
|
||||
}
|
||||
|
||||
#define OPERATOR_DEFINITION(OPSIGN) \
|
||||
template<typename T> \
|
||||
IexpValStr operator OPSIGN(const T & sec) const \
|
||||
{ \
|
||||
IexpValStr ret = *this; \
|
||||
switch (type) \
|
||||
{ \
|
||||
case INT: \
|
||||
case INTVAR: \
|
||||
ret.setTo(ret.getInt() OPSIGN sec); \
|
||||
break; \
|
||||
case FLOATVAR: \
|
||||
ret.setTo(ret.getFloat() OPSIGN sec); \
|
||||
break; \
|
||||
} \
|
||||
return ret; \
|
||||
} \
|
||||
IexpValStr operator OPSIGN(const IexpValStr & sec) const \
|
||||
{ \
|
||||
IexpValStr ret = *this; \
|
||||
switch (type) \
|
||||
{ \
|
||||
case INT: \
|
||||
case INTVAR: \
|
||||
ret.setTo(ret.getInt() OPSIGN sec.getInt()); \
|
||||
break; \
|
||||
case FLOATVAR: \
|
||||
ret.setTo(ret.getFloat() OPSIGN sec.getFloat()); \
|
||||
break; \
|
||||
} \
|
||||
return ret; \
|
||||
} \
|
||||
template<typename T> \
|
||||
IexpValStr & operator OPSIGN ## = (const T & sec) \
|
||||
{ \
|
||||
*this = *this OPSIGN sec; \
|
||||
return *this; \
|
||||
}
|
||||
|
||||
#define OPERATOR_DEFINITION_INTEGER(OPSIGN) \
|
||||
template<typename T> \
|
||||
IexpValStr operator OPSIGN(const T & sec) const \
|
||||
{ \
|
||||
IexpValStr ret = *this; \
|
||||
switch (type) \
|
||||
{ \
|
||||
case INT: \
|
||||
case INTVAR: \
|
||||
ret.setTo(ret.getInt() OPSIGN sec); \
|
||||
break; \
|
||||
} \
|
||||
return ret; \
|
||||
} \
|
||||
IexpValStr operator OPSIGN(const IexpValStr & sec) const \
|
||||
{ \
|
||||
IexpValStr ret = *this; \
|
||||
switch (type) \
|
||||
{ \
|
||||
case INT: \
|
||||
case INTVAR: \
|
||||
ret.setTo(ret.getInt() OPSIGN sec.getInt()); \
|
||||
break; \
|
||||
} \
|
||||
return ret; \
|
||||
} \
|
||||
template<typename T> \
|
||||
IexpValStr & operator OPSIGN ## = (const T & sec) \
|
||||
{ \
|
||||
*this = *this OPSIGN sec; \
|
||||
return *this; \
|
||||
}
|
||||
|
||||
OPERATOR_DEFINITION_FULL(+)
|
||||
OPERATOR_DEFINITION(-)
|
||||
OPERATOR_DEFINITION(*)
|
||||
OPERATOR_DEFINITION(/)
|
||||
OPERATOR_DEFINITION_INTEGER(%)
|
||||
};
|
||||
|
||||
class ERMInterpreter
|
||||
@@ -351,6 +474,7 @@ class ERMInterpreter
|
||||
friend struct LVL2IexpDisemboweler;
|
||||
friend struct VR_SPerformer;
|
||||
friend struct ERMExpDispatch;
|
||||
friend struct VRPerformer;
|
||||
|
||||
std::vector<VERMInterpreter::FileInfo*> files;
|
||||
std::vector< VERMInterpreter::FileInfo* > fileInfos;
|
||||
@@ -382,7 +506,8 @@ class ERMInterpreter
|
||||
static ERM::EVOtions getExpType(const ERM::TVOption & opt);
|
||||
IexpValStr getVar(std::string toFollow, boost::optional<int> initVal) const;
|
||||
public:
|
||||
void executeTriggerType(VERMInterpreter::TriggerType tt, bool pre, const std::map< int, std::vector<int> > & identifier); //use this to run triggers
|
||||
typedef std::map< int, std::vector<int> > TIDPattern;
|
||||
void executeTriggerType(VERMInterpreter::TriggerType tt, bool pre, const TIDPattern & identifier); //use this to run triggers
|
||||
void init(); //sets up environment etc.
|
||||
void scanForScripts();
|
||||
|
||||
|
Reference in New Issue
Block a user