mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-23 22:37:55 +02:00
* minor improvements in parser/interpreter
This commit is contained in:
@@ -568,8 +568,6 @@ ERM::TLine ERMInterpreter::retrieveLine( LinePointer linePtr ) const
|
|||||||
/////////
|
/////////
|
||||||
//code execution
|
//code execution
|
||||||
|
|
||||||
struct VRPerformer;
|
|
||||||
|
|
||||||
template<typename OwnerType>
|
template<typename OwnerType>
|
||||||
struct StandardBodyOptionItemVisitor : boost::static_visitor<>
|
struct StandardBodyOptionItemVisitor : boost::static_visitor<>
|
||||||
{
|
{
|
||||||
@@ -592,10 +590,10 @@ struct StandardBodyOptionItemVisitor : boost::static_visitor<>
|
|||||||
{
|
{
|
||||||
throw EScriptExecError("Semi comparison not allowed in this receiver");
|
throw EScriptExecError("Semi comparison not allowed in this receiver");
|
||||||
}
|
}
|
||||||
virtual void operator()(TMacroUsage const& cmp) const
|
// virtual void operator()(TMacroUsage const& cmp) const
|
||||||
{
|
// {
|
||||||
throw EScriptExecError("Macro usage not allowed in this receiver");
|
// throw EScriptExecError("Macro usage not allowed in this receiver");
|
||||||
}
|
// }
|
||||||
virtual void operator()(TMacroDef const& cmp) const
|
virtual void operator()(TMacroDef const& cmp) const
|
||||||
{
|
{
|
||||||
throw EScriptExecError("Macro definition not allowed in this receiver");
|
throw EScriptExecError("Macro definition not allowed in this receiver");
|
||||||
@@ -633,13 +631,13 @@ struct StandardReceiverVisitor : boost::static_visitor<>
|
|||||||
virtual void operator()(TNormalBodyOption const& trig) const = 0;
|
virtual void operator()(TNormalBodyOption const& trig) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VRPerformer;
|
||||||
struct VR_SPerformer : StandardBodyOptionItemVisitor<VRPerformer>
|
struct VR_SPerformer : StandardBodyOptionItemVisitor<VRPerformer>
|
||||||
{
|
{
|
||||||
explicit VR_SPerformer(VRPerformer & _owner);
|
explicit VR_SPerformer(VRPerformer & _owner);
|
||||||
using StandardBodyOptionItemVisitor<VRPerformer>::operator();
|
using StandardBodyOptionItemVisitor<VRPerformer>::operator();
|
||||||
|
|
||||||
void operator()(TStringConstant const& cmp) const OVERRIDE;
|
void operator()(TStringConstant const& cmp) const OVERRIDE;
|
||||||
void operator()(TMacroUsage const& cmp) const OVERRIDE;
|
|
||||||
void operator()(TIexp const& cmp) const OVERRIDE;
|
void operator()(TIexp const& cmp) const OVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -761,13 +759,20 @@ void VR_SPerformer::operator()(TStringConstant const& cmp) const
|
|||||||
{
|
{
|
||||||
owner.identifier.setTo(cmp.str);
|
owner.identifier.setTo(cmp.str);
|
||||||
}
|
}
|
||||||
void VR_SPerformer::operator()(TMacroUsage const& cmp) const
|
|
||||||
{
|
|
||||||
owner.identifier.setTo(owner.interp->getIexp(cmp));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ConditionDisemboweler;
|
struct ConditionDisemboweler;
|
||||||
|
|
||||||
|
struct OBPerformer;
|
||||||
|
struct OB_UPerformer : StandardBodyOptionItemVisitor<OBPerformer>
|
||||||
|
{
|
||||||
|
explicit OB_UPerformer(OBPerformer & owner) : StandardBodyOptionItemVisitor(owner)
|
||||||
|
{}
|
||||||
|
using StandardBodyOptionItemVisitor<OBPerformer>::operator();
|
||||||
|
|
||||||
|
virtual void operator()(TIexp const& cmp) const;
|
||||||
|
virtual void operator()(TVarpExp const& cmp) const;
|
||||||
|
};
|
||||||
|
|
||||||
struct OBPerformer : StandardReceiverVisitor<int3>
|
struct OBPerformer : StandardReceiverVisitor<int3>
|
||||||
{
|
{
|
||||||
OBPerformer(ERMInterpreter * _interpr, int3 objPos) : StandardReceiverVisitor(_interpr, objPos)
|
OBPerformer(ERMInterpreter * _interpr, int3 objPos) : StandardReceiverVisitor(_interpr, objPos)
|
||||||
@@ -807,7 +812,7 @@ struct OBPerformer : StandardReceiverVisitor<int3>
|
|||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'R': //eable all gamers to use object
|
case 'R': //enable all gamers to use object
|
||||||
{
|
{
|
||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
@@ -824,7 +829,10 @@ struct OBPerformer : StandardReceiverVisitor<int3>
|
|||||||
break;
|
break;
|
||||||
case 'U': //sgc of obj subtype
|
case 'U': //sgc of obj subtype
|
||||||
{
|
{
|
||||||
//TODO
|
if(trig.params.size() == 1)
|
||||||
|
boost::apply_visitor(OB_UPerformer(const_cast<OBPerformer&>(*this)), trig.params[0]);
|
||||||
|
else
|
||||||
|
throw EScriptExecError("OB:U takes exactly one parameter!");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -834,6 +842,15 @@ struct OBPerformer : StandardReceiverVisitor<int3>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void OB_UPerformer::operator()( TIexp const& cmp ) const
|
||||||
|
{
|
||||||
|
IexpValStr val = owner.interp->getIexp(cmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OB_UPerformer::operator()( TVarpExp const& cmp ) const
|
||||||
|
{
|
||||||
|
IexpValStr val = owner.interp->getIexp(cmp);
|
||||||
|
}
|
||||||
|
|
||||||
struct ERMExpDispatch : boost::static_visitor<>
|
struct ERMExpDispatch : boost::static_visitor<>
|
||||||
{
|
{
|
||||||
@@ -850,6 +867,39 @@ struct ERMExpDispatch : boost::static_visitor<>
|
|||||||
}
|
}
|
||||||
void operator()(Treceiver const& trig) const
|
void operator()(Treceiver const& trig) const
|
||||||
{
|
{
|
||||||
|
struct HLP
|
||||||
|
{
|
||||||
|
ERMInterpreter * ei;
|
||||||
|
HLP(ERMInterpreter * interp) : ei(interp)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int3 getPosFromIdentifier(ERM::Tidentifier tid, bool allowDummyFourth)
|
||||||
|
{
|
||||||
|
switch(tid.size())
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
int num = ei->getIexp(tid[0]).getInt();
|
||||||
|
return int3(ei->ermGlobalEnv->getStandardVar(num),
|
||||||
|
ei->ermGlobalEnv->getStandardVar(num+1),
|
||||||
|
ei->ermGlobalEnv->getStandardVar(num+2));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
if(tid.size() == 4 && !allowDummyFourth)
|
||||||
|
throw EScriptExecError("4 items in identifirer are not allowed for this receiver!");
|
||||||
|
|
||||||
|
return int3(ei->getIexp(tid[0]).getInt(),
|
||||||
|
ei->getIexp(tid[1]).getInt(),
|
||||||
|
ei->getIexp(tid[2]).getInt());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw EScriptExecError("This receiver takes 1 or 3 items in identifier!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
if(trig.name == "VR")
|
if(trig.name == "VR")
|
||||||
{
|
{
|
||||||
//check condition
|
//check condition
|
||||||
@@ -912,31 +962,25 @@ struct ERMExpDispatch : boost::static_visitor<>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(trig.name == "MO")
|
||||||
|
{
|
||||||
|
int3 objPos;
|
||||||
|
if(trig.identifier.is_initialized())
|
||||||
|
{
|
||||||
|
ERM::Tidentifier tid = trig.identifier.get();
|
||||||
|
objPos = HLP(owner).getPosFromIdentifier(tid, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw EScriptExecError("MO receiver must have an identifier!");
|
||||||
|
}
|
||||||
else if(trig.name == "OB")
|
else if(trig.name == "OB")
|
||||||
{
|
{
|
||||||
int3 objPos;
|
int3 objPos;
|
||||||
if(trig.identifier.is_initialized())
|
if(trig.identifier.is_initialized())
|
||||||
{
|
{
|
||||||
ERM::Tidentifier tid = trig.identifier.get();
|
ERM::Tidentifier tid = trig.identifier.get();
|
||||||
switch(tid.size())
|
objPos = HLP(owner).getPosFromIdentifier(tid, false);
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
int num = owner->getIexp(tid[0]).getInt();
|
|
||||||
objPos = int3(owner->ermGlobalEnv->getStandardVar(num),
|
|
||||||
owner->ermGlobalEnv->getStandardVar(num+1),
|
|
||||||
owner->ermGlobalEnv->getStandardVar(num+2));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
objPos = int3(owner->getIexp(tid[0]).getInt(),
|
|
||||||
owner->getIexp(tid[1]).getInt(),
|
|
||||||
owner->getIexp(tid[2]).getInt());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw EScriptExecError("OB receiver takes 1 or 3 items in identifier!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//execute body
|
//execute body
|
||||||
if(trig.body.is_initialized())
|
if(trig.body.is_initialized())
|
||||||
{
|
{
|
||||||
@@ -954,7 +998,7 @@ struct ERMExpDispatch : boost::static_visitor<>
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//unsupported or invalid trigger
|
//not supported or invalid trigger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void operator()(TPostTrigger const& trig) const
|
void operator()(TPostTrigger const& trig) const
|
||||||
@@ -1284,6 +1328,11 @@ IexpValStr ERMInterpreter::getIexp( const ERM::TIdentifierInternal & tid ) const
|
|||||||
throw EScriptExecError("Identifier must be a valid i-expression to perform this operation!");
|
throw EScriptExecError("Identifier must be a valid i-expression to perform this operation!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IexpValStr ERMInterpreter::getIexp( const ERM::TVarpExp & tid ) const
|
||||||
|
{
|
||||||
|
return boost::apply_visitor(LVL2IexpDisemboweler(const_cast<ERMInterpreter*>(this), IexpDisemboweler::GET), tid.var);
|
||||||
|
}
|
||||||
|
|
||||||
void ERMInterpreter::executeTriggerType( VERMInterpreter::TriggerType tt, bool pre, const TIDPattern & identifier, const std::vector<int> &funParams/*=std::vector<int>()*/ )
|
void ERMInterpreter::executeTriggerType( VERMInterpreter::TriggerType tt, bool pre, const TIDPattern & identifier, const std::vector<int> &funParams/*=std::vector<int>()*/ )
|
||||||
{
|
{
|
||||||
struct HLP
|
struct HLP
|
||||||
|
|||||||
@@ -471,14 +471,15 @@ public:
|
|||||||
|
|
||||||
class ERMInterpreter
|
class ERMInterpreter
|
||||||
{
|
{
|
||||||
friend class ScriptScanner;
|
/*not so*/ public:
|
||||||
friend class TriggerIdMatchHelper;
|
// friend class ScriptScanner;
|
||||||
friend class TriggerIdentifierMatch;
|
// friend class TriggerIdMatchHelper;
|
||||||
friend class ConditionDisemboweler;
|
// friend class TriggerIdentifierMatch;
|
||||||
friend struct LVL2IexpDisemboweler;
|
// friend class ConditionDisemboweler;
|
||||||
friend struct VR_SPerformer;
|
// friend struct LVL2IexpDisemboweler;
|
||||||
friend struct ERMExpDispatch;
|
// friend struct VR_SPerformer;
|
||||||
friend struct VRPerformer;
|
// friend struct ERMExpDispatch;
|
||||||
|
// friend struct VRPerformer;
|
||||||
|
|
||||||
std::vector<VERMInterpreter::FileInfo*> files;
|
std::vector<VERMInterpreter::FileInfo*> files;
|
||||||
std::vector< VERMInterpreter::FileInfo* > fileInfos;
|
std::vector< VERMInterpreter::FileInfo* > fileInfos;
|
||||||
@@ -500,6 +501,7 @@ class ERMInterpreter
|
|||||||
IexpValStr getIexp(const ERM::TIexp & iexp) const;
|
IexpValStr getIexp(const ERM::TIexp & iexp) const;
|
||||||
IexpValStr getIexp(const ERM::TMacroUsage & macro) const;
|
IexpValStr getIexp(const ERM::TMacroUsage & macro) const;
|
||||||
IexpValStr getIexp(const ERM::TIdentifierInternal & tid) const;
|
IexpValStr getIexp(const ERM::TIdentifierInternal & tid) const;
|
||||||
|
IexpValStr getIexp(const ERM::TVarpExp & tid) const;
|
||||||
|
|
||||||
static const std::string triggerSymbol, postTriggerSymbol, defunSymbol;
|
static const std::string triggerSymbol, postTriggerSymbol, defunSymbol;
|
||||||
|
|
||||||
@@ -509,6 +511,8 @@ class ERMInterpreter
|
|||||||
static bool isATrigger(const ERM::TLine & line);
|
static bool isATrigger(const ERM::TLine & line);
|
||||||
static ERM::EVOtions getExpType(const ERM::TVOption & opt);
|
static ERM::EVOtions getExpType(const ERM::TVOption & opt);
|
||||||
IexpValStr getVar(std::string toFollow, boost::optional<int> initVal) const;
|
IexpValStr getVar(std::string toFollow, boost::optional<int> initVal) const;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef std::map< int, std::vector<int> > TIDPattern;
|
typedef std::map< int, std::vector<int> > TIDPattern;
|
||||||
void executeInstructions(); //called when starting a new game, before most of the map settings are done
|
void executeInstructions(); //called when starting a new game, before most of the map settings are done
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ BOOST_FUSION_ADAPT_STRUCT(
|
|||||||
|
|
||||||
BOOST_FUSION_ADAPT_STRUCT(
|
BOOST_FUSION_ADAPT_STRUCT(
|
||||||
ERM::TVarpExp,
|
ERM::TVarpExp,
|
||||||
(ERM::TVarpExp::Tvartype, var)
|
(ERM::TVarExp, var)
|
||||||
)
|
)
|
||||||
|
|
||||||
BOOST_FUSION_ADAPT_STRUCT(
|
BOOST_FUSION_ADAPT_STRUCT(
|
||||||
@@ -355,7 +355,7 @@ namespace ERM
|
|||||||
/*qERMMacroUsage %= qi::lexeme[qi::lit("?$") >> *(qi::char_ - '$') >> qi::lit('$')];*/
|
/*qERMMacroUsage %= qi::lexeme[qi::lit("?$") >> *(qi::char_ - '$') >> qi::lit('$')];*/
|
||||||
varExp %= varExpNotMacro | ERMmacroUsage;
|
varExp %= varExpNotMacro | ERMmacroUsage;
|
||||||
iexp %= varExp | qi::int_;
|
iexp %= varExp | qi::int_;
|
||||||
varp %= qi::lit("?") >> (varExpNotMacro | ERMmacroUsage);
|
varp %= qi::lit("?") >> varExp;
|
||||||
comment %= *qi::char_;
|
comment %= *qi::char_;
|
||||||
commentLine %= (~qi::char_("!") >> comment | (qi::char_('!') >> (~qi::char_("?!$#[")) >> comment ));
|
commentLine %= (~qi::char_("!") >> comment | (qi::char_('!') >> (~qi::char_("?!$#[")) >> comment ));
|
||||||
cmdName %= qi::lexeme[qi::repeat(2)[qi::char_]];
|
cmdName %= qi::lexeme[qi::repeat(2)[qi::char_]];
|
||||||
@@ -373,7 +373,7 @@ namespace ERM
|
|||||||
semiCompare %= +qi::char_("<=>") >> iexp;
|
semiCompare %= +qi::char_("<=>") >> iexp;
|
||||||
curStr %= iexp >> string;
|
curStr %= iexp >> string;
|
||||||
varConcatString %= varExp >> qi::lit("+") >> string;
|
varConcatString %= varExp >> qi::lit("+") >> string;
|
||||||
bodyOptionItem %= varConcatString | curStr | string | semiCompare | ERMmacroUsage | ERMmacroDef | varp | iexp | qi::eps;
|
bodyOptionItem %= varConcatString | curStr | string | semiCompare | ERMmacroDef | varp | iexp | qi::eps;
|
||||||
exactBodyOptionList %= (bodyOptionItem % qi::lit("/"));
|
exactBodyOptionList %= (bodyOptionItem % qi::lit("/"));
|
||||||
normalBodyOption = qi::char_("A-Z+") > exactBodyOptionList;
|
normalBodyOption = qi::char_("A-Z+") > exactBodyOptionList;
|
||||||
bodyOption %= VRLogic | VRarithmetic | normalBodyOption;
|
bodyOption %= VRLogic | VRarithmetic | normalBodyOption;
|
||||||
|
|||||||
@@ -72,8 +72,7 @@ namespace ERM
|
|||||||
//write-only variable expression
|
//write-only variable expression
|
||||||
struct TVarpExp
|
struct TVarpExp
|
||||||
{
|
{
|
||||||
typedef boost::variant<TVarExpNotMacro, TMacroUsage> Tvartype;
|
TVarExp var;
|
||||||
Tvartype var;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//i-expression (identifier expression) - an integral constant, variable symbol or array symbol
|
//i-expression (identifier expression) - an integral constant, variable symbol or array symbol
|
||||||
@@ -115,7 +114,7 @@ namespace ERM
|
|||||||
TStringConstant string;
|
TStringConstant string;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef boost::variant<TVarConcatString, TStringConstant, TCurriedString, TSemiCompare, TMacroUsage, TMacroDef, TIexp, TVarpExp, boost::spirit::unused_type> TBodyOptionItem;
|
typedef boost::variant<TVarConcatString, TStringConstant, TCurriedString, TSemiCompare, TMacroDef, TIexp, TVarpExp, boost::spirit::unused_type> TBodyOptionItem;
|
||||||
|
|
||||||
typedef std::vector<TBodyOptionItem> TNormalBodyOptionList;
|
typedef std::vector<TBodyOptionItem> TNormalBodyOptionList;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user