mirror of
https://github.com/vcmi/vcmi.git
synced 2025-04-15 11:46:56 +02:00
* checking ERM conditions should work now
This commit is contained in:
parent
36d29424f0
commit
86a7cd12ff
@ -633,9 +633,11 @@ struct ERMExecEnvironment
|
||||
: ermGlobalEnv(erm), trigEnv(trig), funcVars(funvars)
|
||||
{}
|
||||
|
||||
template<typename T>
|
||||
T* getVar(std::string toFollow, boost::optional<int> initVal)
|
||||
IexpValStr getVar(std::string toFollow, boost::optional<int> initVal)
|
||||
{
|
||||
IexpValStr ret;
|
||||
ret.type = IexpValStr::WRONGVAL;
|
||||
|
||||
int initV;
|
||||
bool hasInit = false;
|
||||
if(initVal.is_initialized())
|
||||
@ -650,7 +652,19 @@ struct ERMExecEnvironment
|
||||
endNum = 1;
|
||||
//TODO: support
|
||||
}
|
||||
T* ret;
|
||||
if(toFollow.size() == 0)
|
||||
{
|
||||
if(hasInit)
|
||||
{
|
||||
ret.val.val = initV;
|
||||
ret.type = IexpValStr::INT;
|
||||
}
|
||||
else
|
||||
throw EIexpProblem("No input to getVar!");
|
||||
|
||||
return ret;
|
||||
}
|
||||
//now we have at least one element in toFollow
|
||||
for(int b=toFollow.size()-1; b>=endNum; --b)
|
||||
{
|
||||
bool retIt = b == endNum+1; //if we should return the value are currently at
|
||||
@ -674,14 +688,20 @@ struct ERMExecEnvironment
|
||||
if(initV > 0 && initV <= FunctionLocalVars::NUM_FLOATINGS)
|
||||
{
|
||||
if(funcVars)
|
||||
ret = (T*)funcVars->floats + initV - 1;
|
||||
{
|
||||
ret.val.flvar = &funcVars->getFloat(initV);
|
||||
ret.type = IexpValStr::FLOATVAR;
|
||||
}
|
||||
else
|
||||
throw EIexpProblem("Function context not available!");
|
||||
}
|
||||
else if(initV < 0 && initV >= -TriggerLocalVars::EVAR_NUM)
|
||||
{
|
||||
if(trigEnv)
|
||||
ret = (T*)trigEnv->ermLocalVars.evar - initV + 1; //minus is important!
|
||||
{
|
||||
ret.val.flvar = &trigEnv->ermLocalVars.getEvar(initV);
|
||||
ret.type = IexpValStr::FLOATVAR;
|
||||
}
|
||||
else
|
||||
throw EIexpProblem("No trigger context available!");
|
||||
}
|
||||
@ -697,7 +717,10 @@ struct ERMExecEnvironment
|
||||
else if(cr >= 'f' && cr <= 't')
|
||||
{
|
||||
if(retIt)
|
||||
ret = &ermGlobalEnv->getQuickVar(cr);
|
||||
{
|
||||
ret.val.integervar = &ermGlobalEnv->getQuickVar(cr);
|
||||
ret.type = IexpValStr::INTVAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(hasInit)
|
||||
@ -713,15 +736,13 @@ struct ERMExecEnvironment
|
||||
{
|
||||
if(hasInit)
|
||||
{
|
||||
if(initV > 0 && initV <= ERMEnvironment::NUM_STANDARDS)
|
||||
if(retIt)
|
||||
{
|
||||
if(retIt)
|
||||
ret = ermGlobalEnv->standardVars + initV - 1;
|
||||
else
|
||||
initV = ermGlobalEnv->standardVars[initV-1];
|
||||
ret.val.integervar = &ermGlobalEnv->getStandardVar(initV);
|
||||
ret.type = IexpValStr::INTVAR;
|
||||
}
|
||||
else
|
||||
throw EIexpProblem("standard variable index out of range");
|
||||
initV = ermGlobalEnv->getStandardVar(initV);
|
||||
}
|
||||
else
|
||||
throw EIexpProblem("standard variable cannot be used in this context!");
|
||||
@ -734,19 +755,17 @@ struct ERMExecEnvironment
|
||||
{
|
||||
if(hasInit)
|
||||
{
|
||||
if(initV > 0 && initV <= FunctionLocalVars::NUM_PARAMETERS)
|
||||
if(funcVars)
|
||||
{
|
||||
if(funcVars)
|
||||
if(retIt)
|
||||
{
|
||||
if(retIt)
|
||||
ret = funcVars->params + initV-1;
|
||||
else
|
||||
initV = funcVars->params[initV-1];
|
||||
ret.val.integervar = &funcVars->getParam(initV);
|
||||
ret.type = IexpValStr::INTVAR;
|
||||
}
|
||||
else throw EIexpProblem("Function parameters cannot be used outside a function!");
|
||||
else
|
||||
initV = funcVars->getParam(initV);
|
||||
}
|
||||
else
|
||||
throw EIexpProblem("Parameter number out of range");
|
||||
else throw EIexpProblem("Function parameters cannot be used outside a function!");
|
||||
}
|
||||
else
|
||||
throw EIexpProblem("Specify which function parameter should be used");
|
||||
@ -760,9 +779,12 @@ struct ERMExecEnvironment
|
||||
if(funcVars)
|
||||
{
|
||||
if(retIt)
|
||||
ret = funcVars->locals + initV-1;
|
||||
{
|
||||
ret.val.integervar = &funcVars->getLocal(initV);
|
||||
ret.type = IexpValStr::INTVAR;
|
||||
}
|
||||
else
|
||||
initV = funcVars->params[initV - 1];
|
||||
initV = funcVars->getLocal(initV);
|
||||
}
|
||||
else
|
||||
throw EIexpProblem("Function local variables cannot be used outside a function!");
|
||||
@ -772,9 +794,12 @@ struct ERMExecEnvironment
|
||||
if(trigEnv)
|
||||
{
|
||||
if(retIt)
|
||||
ret = trigEnv->ermLocalVars.yvar - initV + 1;
|
||||
{
|
||||
ret.val.integervar = &trigEnv->ermLocalVars.getYvar(initV);
|
||||
ret.type = IexpValStr::INTVAR;
|
||||
}
|
||||
else
|
||||
initV = trigEnv->ermLocalVars.yvar[-initV + 1];
|
||||
initV = trigEnv->ermLocalVars.getYvar(initV);
|
||||
}
|
||||
else
|
||||
throw EIexpProblem("Trigger local variables cannot be used outside triggers!");
|
||||
@ -792,15 +817,17 @@ struct ERMExecEnvironment
|
||||
if(retIt)
|
||||
{
|
||||
//these C-style casts are here just to shut up compiler errors
|
||||
if(initV > 0 && initV <= ermGlobalEnv->NUM_STRINGS)
|
||||
if(initV > 0 )
|
||||
{
|
||||
ret = (T*)ermGlobalEnv->strings + initV - 1;
|
||||
ret.val.stringvar = &ermGlobalEnv->getZVar(initV);
|
||||
ret.type = IexpValStr::STRINGVAR;
|
||||
}
|
||||
else if(initV < 0 && initV >= -FunctionLocalVars::NUM_STRINGS)
|
||||
else if(initV < 0)
|
||||
{
|
||||
if(funcVars)
|
||||
{
|
||||
ret = (T*)funcVars->strings + initV - 1;
|
||||
ret.val.stringvar = &funcVars->getString(initV);
|
||||
ret.type = IexpValStr::STRINGVAR;
|
||||
}
|
||||
else
|
||||
throw EIexpProblem("Function local string variables cannot be used outside functions!");
|
||||
@ -829,76 +856,71 @@ namespace IexpDisemboweler
|
||||
enum EDir{GET, SET};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct LVL2IexpDisemboweler : boost::static_visitor<>
|
||||
struct LVL2IexpDisemboweler : boost::static_visitor<IexpValStr>
|
||||
{
|
||||
T * inout;
|
||||
IexpDisemboweler::EDir dir;
|
||||
/*const*/ ERMExecEnvironment * env;
|
||||
|
||||
LVL2IexpDisemboweler(T * in_out, /*const*/ ERMExecEnvironment * _env, IexpDisemboweler::EDir _dir)
|
||||
: inout(in_out), env(_env), dir(_dir) //writes value to given var
|
||||
LVL2IexpDisemboweler(/*const*/ ERMExecEnvironment * _env, IexpDisemboweler::EDir _dir)
|
||||
: env(_env), dir(_dir) //writes value to given var
|
||||
{}
|
||||
|
||||
void processNotMacro(const TVarExpNotMacro & val) const
|
||||
IexpValStr processNotMacro(const TVarExpNotMacro & val) const
|
||||
{
|
||||
if(val.questionMark.is_initialized())
|
||||
throw EIexpProblem("Question marks ('?') are not allowed in getter i-expressions");
|
||||
|
||||
//const-cast just to do some code-reuse...
|
||||
*inout = *const_cast<ERMExecEnvironment*>(env)->getVar<T>(val.varsym, val.val);
|
||||
return env->getVar(val.varsym, val.val);
|
||||
|
||||
}
|
||||
|
||||
void operator()(TVarExpNotMacro const& val) const
|
||||
IexpValStr operator()(TVarExpNotMacro const& val) const
|
||||
{
|
||||
processNotMacro(val);
|
||||
return processNotMacro(val);
|
||||
}
|
||||
void operator()(TMacroUsage const& val) const
|
||||
IexpValStr operator()(TMacroUsage const& val) const
|
||||
{
|
||||
std::map<std::string, ERM::TVarExpNotMacro>::const_iterator it =
|
||||
env->ermGlobalEnv->macroBindings.find(val .macro);
|
||||
if(it == env->ermGlobalEnv->macroBindings.end())
|
||||
throw EUsageOfUndefinedMacro(val.macro);
|
||||
else
|
||||
processNotMacro(it->second);
|
||||
|
||||
return processNotMacro(it->second);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct LVL1IexpDisemboweler : boost::static_visitor<>
|
||||
struct LVL1IexpDisemboweler : boost::static_visitor<IexpValStr>
|
||||
{
|
||||
T * inout;
|
||||
IexpDisemboweler::EDir dir;
|
||||
/*const*/ ERMExecEnvironment * env;
|
||||
|
||||
LVL1IexpDisemboweler(T * in_out, /*const*/ ERMExecEnvironment * _env, IexpDisemboweler::EDir _dir)
|
||||
: inout(in_out), env(_env), dir(_dir) //writes value to given var
|
||||
LVL1IexpDisemboweler(/*const*/ ERMExecEnvironment * _env, IexpDisemboweler::EDir _dir)
|
||||
: env(_env), dir(_dir) //writes value to given var
|
||||
{}
|
||||
void operator()(int const & constant) const
|
||||
IexpValStr operator()(int const & constant) const
|
||||
{
|
||||
if(dir == IexpDisemboweler::GET)
|
||||
{
|
||||
*inout = constant;
|
||||
IexpValStr ret;
|
||||
ret.val.val = constant;
|
||||
ret.type = IexpValStr::INT;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw EIexpProblem("Cannot set a constant!");
|
||||
}
|
||||
}
|
||||
void operator()(TVarExp const & var) const
|
||||
IexpValStr operator()(TVarExp const & var) const
|
||||
{
|
||||
boost::apply_visitor(LVL2IexpDisemboweler<T>(inout, env, dir), var);
|
||||
return boost::apply_visitor(LVL2IexpDisemboweler(env, dir), var);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T ERMInterpreter::getIexp( const ERM::TIexp & iexp, /*const*/ Trigger * trig /*= NULL*/, /*const*/ FunctionLocalVars * fun /*= NULL*/) const
|
||||
IexpValStr ERMInterpreter::getIexp( const ERM::TIexp & iexp, /*const*/ Trigger * trig /*= NULL*/, /*const*/ FunctionLocalVars * fun /*= NULL*/) const
|
||||
{
|
||||
T ret;
|
||||
ERMExecEnvironment env(ermGlobalEnv, trig, fun);
|
||||
boost::apply_visitor(LVL1IexpDisemboweler<T>(&ret, &env, IexpDisemboweler::GET), iexp);
|
||||
return ret;
|
||||
return boost::apply_visitor(LVL1IexpDisemboweler(&env, IexpDisemboweler::GET), iexp);
|
||||
}
|
||||
|
||||
void ERMInterpreter::executeTriggerType( VERMInterpreter::TriggerType tt, bool pre, const std::map< int, std::vector<int> > & identifier )
|
||||
@ -936,6 +958,131 @@ ERM::Ttrigger ERMInterpreter::retrieveTrigger( ERM::TLine line )
|
||||
throw ELineProblem("Given line is not an ERM trigger!");
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool compareExp(const T & lhs, const T & rhs, std::string op)
|
||||
{
|
||||
if(op == "<")
|
||||
{
|
||||
return lhs < rhs;
|
||||
}
|
||||
else if(op == ">")
|
||||
{
|
||||
return lhs > rhs;
|
||||
}
|
||||
else if(op == ">=" || op == "=>")
|
||||
{
|
||||
return lhs >= rhs;
|
||||
}
|
||||
else if(op == "<=" || op == "=<")
|
||||
{
|
||||
return lhs <= rhs;
|
||||
}
|
||||
else if(op == "==")
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
else if(op == "<>" || op == "><")
|
||||
{
|
||||
return lhs != rhs;
|
||||
}
|
||||
else
|
||||
throw EScriptExecError(std::string("Wrong comparison sign: ") + op);
|
||||
}
|
||||
|
||||
struct ConditionDisemboweler : boost::static_visitor<bool>
|
||||
{
|
||||
ConditionDisemboweler(ERMInterpreter * _ei) : ei(_ei)
|
||||
{}
|
||||
|
||||
bool operator()(TComparison const & cmp) const
|
||||
{
|
||||
IexpValStr lhs = ei->getIexp(cmp.lhs),
|
||||
rhs = ei->getIexp(cmp.rhs);
|
||||
switch (lhs.type)
|
||||
{
|
||||
case IexpValStr::FLOATVAR:
|
||||
switch (rhs.type)
|
||||
{
|
||||
case IexpValStr::FLOATVAR:
|
||||
return compareExp(*lhs.val.flvar, *rhs.val.flvar, cmp.compSign);
|
||||
break;
|
||||
default:
|
||||
throw EScriptExecError("Incompatible types for comparison");
|
||||
}
|
||||
break;
|
||||
case IexpValStr::INT:
|
||||
switch (rhs.type)
|
||||
{
|
||||
case IexpValStr::INT:
|
||||
return compareExp(lhs.val.val, rhs.val.val, cmp.compSign);
|
||||
break;
|
||||
case IexpValStr::INTVAR:
|
||||
return compareExp(lhs.val.val, *rhs.val.integervar, cmp.compSign);
|
||||
default:
|
||||
throw EScriptExecError("Incompatible types for comparison");
|
||||
}
|
||||
break;
|
||||
case IexpValStr::INTVAR:
|
||||
switch (rhs.type)
|
||||
{
|
||||
case IexpValStr::INT:
|
||||
return compareExp(*lhs.val.integervar, rhs.val.val, cmp.compSign);
|
||||
break;
|
||||
case IexpValStr::INTVAR:
|
||||
return compareExp(*lhs.val.integervar, *rhs.val.integervar, cmp.compSign);
|
||||
default:
|
||||
throw EScriptExecError("Incompatible types for comparison");
|
||||
}
|
||||
break;
|
||||
case IexpValStr::STRINGVAR:
|
||||
switch (rhs.type)
|
||||
{
|
||||
case IexpValStr::STRINGVAR:
|
||||
return compareExp(*lhs.val.stringvar, *rhs.val.stringvar, cmp.compSign);
|
||||
break;
|
||||
default:
|
||||
throw EScriptExecError("Incompatible types for comparison");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw EScriptExecError("Wrong type of left iexp!");
|
||||
}
|
||||
//we should never reach this place
|
||||
}
|
||||
bool operator()(int const & flag) const
|
||||
{
|
||||
return ei->ermGlobalEnv->getFlag(flag);
|
||||
}
|
||||
private:
|
||||
ERMInterpreter * ei;
|
||||
};
|
||||
|
||||
bool ERMInterpreter::checkCondition( ERM::Tcondition cond )
|
||||
{
|
||||
bool ret = boost::apply_visitor(ConditionDisemboweler(this), cond.cond);
|
||||
if(cond.rhs.is_initialized())
|
||||
{ //taking care of rhs expression
|
||||
bool rhs = checkCondition(cond.rhs.get().get());
|
||||
switch (cond.ctype)
|
||||
{
|
||||
case '&':
|
||||
ret &= rhs;
|
||||
break;
|
||||
case '|':
|
||||
ret |= rhs;
|
||||
break;
|
||||
case 'X':
|
||||
ret ^= rhs;
|
||||
break;
|
||||
default:
|
||||
throw EInterpreterProblem(std::string("Strange - wrong condition connection (") + cond.ctype + ") !");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const std::string ERMInterpreter::triggerSymbol = "trigger";
|
||||
const std::string ERMInterpreter::postTriggerSymbol = "postTrigger";
|
||||
const std::string ERMInterpreter::defunSymbol = "defun";
|
||||
@ -953,7 +1100,16 @@ struct TriggerIdMatchHelper : boost::static_visitor<>
|
||||
|
||||
void operator()(TIexp const& iexp) const
|
||||
{
|
||||
ret = interpreter->getIexp<int>(iexp, trig);
|
||||
IexpValStr val = interpreter->getIexp(iexp, trig);
|
||||
switch(val.type)
|
||||
{
|
||||
case IexpValStr::INT:
|
||||
ret = val.val.val;
|
||||
case IexpValStr::INTVAR:
|
||||
ret = *val.val.integervar;
|
||||
default:
|
||||
throw EScriptExecError("Incompatible i-exp type!");
|
||||
}
|
||||
}
|
||||
void operator()(TArithmeticOp const& arop) const
|
||||
{
|
||||
@ -963,6 +1119,8 @@ struct TriggerIdMatchHelper : boost::static_visitor<>
|
||||
|
||||
bool TriggerIdentifierMatch::tryMatch( Trigger * interptrig ) const
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
const ERM::Ttrigger & trig = ERMInterpreter::retrieveTrigger(ermEnv->retrieveLine(interptrig->line));
|
||||
if(trig.identifier.is_initialized())
|
||||
{
|
||||
@ -970,7 +1128,7 @@ bool TriggerIdentifierMatch::tryMatch( Trigger * interptrig ) const
|
||||
ERM::Tidentifier tid = trig.identifier.get();
|
||||
std::map< int, std::vector<int> >::const_iterator it = matchToIt.find(tid.size());
|
||||
if(it == matchToIt.end())
|
||||
return false;
|
||||
ret = false;
|
||||
else
|
||||
{
|
||||
const std::vector<int> & pattern = it->second;
|
||||
@ -980,17 +1138,29 @@ bool TriggerIdentifierMatch::tryMatch( Trigger * interptrig ) const
|
||||
boost::apply_visitor(TriggerIdMatchHelper(val, ermEnv, interptrig), tid[g]);
|
||||
if(pattern[g] != val)
|
||||
{
|
||||
return false;
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(allowNoIdetifier)
|
||||
ret = allowNoIdetifier;
|
||||
}
|
||||
|
||||
//check condition
|
||||
if(ret)
|
||||
{
|
||||
if(trig.condition.is_initialized())
|
||||
{
|
||||
return ermEnv->checkCondition(trig.condition.get());
|
||||
}
|
||||
else //no condition
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
VERMInterpreter::ERMEnvironment::ERMEnvironment()
|
||||
@ -1004,6 +1174,36 @@ VERMInterpreter::ERMEnvironment::ERMEnvironment()
|
||||
flags[g] = false;
|
||||
}
|
||||
|
||||
int & VERMInterpreter::ERMEnvironment::getQuickVar( const char letter )
|
||||
{
|
||||
assert(letter >= 'f' && letter <= 't'); //it should be check by another function, just making sure here
|
||||
return quickVars[letter - 'f'];
|
||||
}
|
||||
|
||||
int & VERMInterpreter::ERMEnvironment::getStandardVar( int num )
|
||||
{
|
||||
if(num < 1 || num > NUM_STANDARDS)
|
||||
throw EScriptExecError("Number of standard variable out of bounds");
|
||||
|
||||
return standardVars[num-1];
|
||||
}
|
||||
|
||||
std::string & VERMInterpreter::ERMEnvironment::getZVar( int num )
|
||||
{
|
||||
if(num < 1 || num > NUM_STRINGS)
|
||||
throw EScriptExecError("Number of string variable out of bounds");
|
||||
|
||||
return strings[num-1];
|
||||
}
|
||||
|
||||
bool & VERMInterpreter::ERMEnvironment::getFlag( int num )
|
||||
{
|
||||
if(num < 1 || num > NUM_FLAGS)
|
||||
throw EScriptExecError("Number of flag out of bounds");
|
||||
|
||||
return flags[num-1];
|
||||
}
|
||||
|
||||
VERMInterpreter::TriggerLocalVars::TriggerLocalVars()
|
||||
{
|
||||
for(int g=0; g<EVAR_NUM; ++g)
|
||||
@ -1012,6 +1212,23 @@ VERMInterpreter::TriggerLocalVars::TriggerLocalVars()
|
||||
yvar[g] = 0;
|
||||
}
|
||||
|
||||
double & VERMInterpreter::TriggerLocalVars::getEvar( int num )
|
||||
{
|
||||
num = -num;
|
||||
if(num < 1 || num > EVAR_NUM)
|
||||
throw EScriptExecError("Number of trigger local floating point variable out of bounds");
|
||||
|
||||
return evar[num-1];
|
||||
}
|
||||
|
||||
int & VERMInterpreter::TriggerLocalVars::getYvar( int num )
|
||||
{
|
||||
if(num < 1 || num > YVAR_NUM)
|
||||
throw EScriptExecError("Number of trigger local variable out of bounds");
|
||||
|
||||
return yvar[num-1];
|
||||
}
|
||||
|
||||
bool VERMInterpreter::Environment::isBound( const std::string & name, bool globalOnly ) const
|
||||
{
|
||||
std::map<std::string, TVOption>::const_iterator it = symbols.find(name);
|
||||
@ -1064,3 +1281,36 @@ bool VERMInterpreter::Environment::unbind( const std::string & name, EUnbindMode
|
||||
//neither bound nor have lexical parent
|
||||
return false;
|
||||
}
|
||||
|
||||
int & VERMInterpreter::FunctionLocalVars::getParam( int num )
|
||||
{
|
||||
if(num < 1 || num > NUM_PARAMETERS)
|
||||
throw EScriptExecError("Number of parameter out of bounds");
|
||||
|
||||
return params[num-1];
|
||||
}
|
||||
|
||||
int & VERMInterpreter::FunctionLocalVars::getLocal( int num )
|
||||
{
|
||||
if(num < 1 || num > NUM_LOCALS)
|
||||
throw EScriptExecError("Number of local variable out of bounds");
|
||||
|
||||
return locals[num-1];
|
||||
}
|
||||
|
||||
std::string & VERMInterpreter::FunctionLocalVars::getString( int num )
|
||||
{
|
||||
num = -num; //we deal with negative indices
|
||||
if(num < 1 || num > NUM_PARAMETERS)
|
||||
throw EScriptExecError("Number of function local string variable out of bounds");
|
||||
|
||||
return strings[num-1];
|
||||
}
|
||||
|
||||
double & VERMInterpreter::FunctionLocalVars::getFloat( int num )
|
||||
{
|
||||
if(num < 1 || num > NUM_FLOATINGS)
|
||||
throw EScriptExecError("Number of float var out of bounds");
|
||||
|
||||
return floats[num-1];
|
||||
}
|
||||
|
@ -125,25 +125,33 @@ namespace VERMInterpreter
|
||||
struct TriggerLocalVars
|
||||
{
|
||||
static const int EVAR_NUM = 100; //number of evar locals
|
||||
double evar[EVAR_NUM]; //negative indices
|
||||
|
||||
static const int YVAR_NUM = 100; //number of yvar locals
|
||||
int yvar[YVAR_NUM];
|
||||
TriggerLocalVars();
|
||||
|
||||
double & getEvar(int num);
|
||||
int & getYvar(int num);
|
||||
private:
|
||||
double evar[EVAR_NUM]; //negative indices
|
||||
int yvar[YVAR_NUM];
|
||||
|
||||
};
|
||||
|
||||
struct FunctionLocalVars
|
||||
{
|
||||
static const int NUM_PARAMETERS = 16; //number of function parameters
|
||||
int params[NUM_PARAMETERS]; //x-vars
|
||||
|
||||
static const int NUM_LOCALS = 100;
|
||||
int locals[NUM_LOCALS]; //y-vars
|
||||
|
||||
static const int NUM_STRINGS = 10;
|
||||
std::string strings[NUM_STRINGS]; //z-vars (negative indices)
|
||||
|
||||
static const int NUM_FLOATINGS = 100;
|
||||
|
||||
int & getParam(int num);
|
||||
int & getLocal(int num);
|
||||
std::string & getString(int num);
|
||||
double & getFloat(int num);
|
||||
private:
|
||||
int params[NUM_PARAMETERS]; //x-vars
|
||||
int locals[NUM_LOCALS]; //y-vars
|
||||
std::string strings[NUM_STRINGS]; //z-vars (negative indices)
|
||||
double floats[NUM_FLOATINGS]; //e-vars (positive indices)
|
||||
};
|
||||
|
||||
@ -151,22 +159,22 @@ namespace VERMInterpreter
|
||||
{
|
||||
ERMEnvironment();
|
||||
static const int NUM_QUICKS = 't' - 'f' + 1; //it should be 15
|
||||
int quickVars[NUM_QUICKS]; //referenced by letter ('f' to 't' inclusive)
|
||||
int & getQuickVar(const char letter)
|
||||
{
|
||||
assert(letter >= 'f' && letter <= 't'); //it should be check by another function, just makign sure here
|
||||
return quickVars[letter - 'f'];
|
||||
}
|
||||
int & getQuickVar(const char letter);
|
||||
int & getStandardVar(int num);
|
||||
std::string & getZVar(int num);
|
||||
bool & getFlag(int num);
|
||||
|
||||
static const int NUM_STANDARDS = 1000;
|
||||
int standardVars[NUM_STANDARDS]; //v-vars
|
||||
|
||||
static const int NUM_STRINGS = 1000;
|
||||
std::string strings[NUM_STRINGS]; //z-vars (positive indices)
|
||||
|
||||
std::map<std::string, ERM::TVarExpNotMacro> macroBindings;
|
||||
|
||||
static const int NUM_FLAGS = 1000;
|
||||
private:
|
||||
int quickVars[NUM_QUICKS]; //referenced by letter ('f' to 't' inclusive)
|
||||
int standardVars[NUM_STANDARDS]; //v-vars
|
||||
std::string strings[NUM_STRINGS]; //z-vars (positive indices)
|
||||
bool flags[NUM_FLAGS];
|
||||
};
|
||||
|
||||
@ -294,11 +302,24 @@ struct TriggerIdentifierMatch
|
||||
bool tryMatch(VERMInterpreter::Trigger * interptrig) const;
|
||||
};
|
||||
|
||||
struct IexpValStr
|
||||
{
|
||||
union
|
||||
{
|
||||
int val;
|
||||
int * integervar;
|
||||
double * flvar;
|
||||
std::string * stringvar;
|
||||
} val;
|
||||
enum {WRONGVAL, INT, INTVAR, FLOATVAR, STRINGVAR} type;
|
||||
};
|
||||
|
||||
class ERMInterpreter
|
||||
{
|
||||
friend class ScriptScanner;
|
||||
friend class TriggerIdMatchHelper;
|
||||
friend class TriggerIdentifierMatch;
|
||||
friend class ConditionDisemboweler;
|
||||
|
||||
std::vector<VERMInterpreter::FileInfo*> files;
|
||||
std::vector< VERMInterpreter::FileInfo* > fileInfos;
|
||||
@ -314,7 +335,7 @@ class ERMInterpreter
|
||||
|
||||
|
||||
template<typename T> void setIexp(const ERM::TIexp & iexp, const T & val, VERMInterpreter::Trigger * trig = NULL);
|
||||
template<typename T> T getIexp(const ERM::TIexp & iexp, /*const*/ VERMInterpreter::Trigger * trig = NULL, /*const*/ VERMInterpreter::FunctionLocalVars * fun = NULL) const;
|
||||
IexpValStr getIexp(const ERM::TIexp & iexp, /*const*/ VERMInterpreter::Trigger * trig = NULL, /*const*/ VERMInterpreter::FunctionLocalVars * fun = NULL) const;
|
||||
|
||||
static const std::string triggerSymbol, postTriggerSymbol, defunSymbol;
|
||||
|
||||
@ -333,4 +354,5 @@ public:
|
||||
void scanScripts(); //scans for functions, triggers etc.
|
||||
|
||||
ERMInterpreter();
|
||||
bool checkCondition( ERM::Tcondition cond );
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user