mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-24 03:47:18 +02:00
* minor improvements in parser/interpreter
This commit is contained in:
parent
4eef7aa83b
commit
6014edb7ea
@ -568,8 +568,6 @@ ERM::TLine ERMInterpreter::retrieveLine( LinePointer linePtr ) const
|
||||
/////////
|
||||
//code execution
|
||||
|
||||
struct VRPerformer;
|
||||
|
||||
template<typename OwnerType>
|
||||
struct StandardBodyOptionItemVisitor : boost::static_visitor<>
|
||||
{
|
||||
@ -592,10 +590,10 @@ struct StandardBodyOptionItemVisitor : boost::static_visitor<>
|
||||
{
|
||||
throw EScriptExecError("Semi comparison not allowed in this receiver");
|
||||
}
|
||||
virtual void operator()(TMacroUsage const& cmp) const
|
||||
{
|
||||
throw EScriptExecError("Macro usage not allowed in this receiver");
|
||||
}
|
||||
// virtual void operator()(TMacroUsage const& cmp) const
|
||||
// {
|
||||
// throw EScriptExecError("Macro usage not allowed in this receiver");
|
||||
// }
|
||||
virtual void operator()(TMacroDef const& cmp) const
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
struct VRPerformer;
|
||||
struct VR_SPerformer : StandardBodyOptionItemVisitor<VRPerformer>
|
||||
{
|
||||
explicit VR_SPerformer(VRPerformer & _owner);
|
||||
using StandardBodyOptionItemVisitor<VRPerformer>::operator();
|
||||
|
||||
void operator()(TStringConstant const& cmp) const OVERRIDE;
|
||||
void operator()(TMacroUsage 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);
|
||||
}
|
||||
void VR_SPerformer::operator()(TMacroUsage const& cmp) const
|
||||
{
|
||||
owner.identifier.setTo(owner.interp->getIexp(cmp));
|
||||
}
|
||||
|
||||
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>
|
||||
{
|
||||
OBPerformer(ERMInterpreter * _interpr, int3 objPos) : StandardReceiverVisitor(_interpr, objPos)
|
||||
@ -807,7 +812,7 @@ struct OBPerformer : StandardReceiverVisitor<int3>
|
||||
//TODO
|
||||
}
|
||||
break;
|
||||
case 'R': //eable all gamers to use object
|
||||
case 'R': //enable all gamers to use object
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
@ -824,7 +829,10 @@ struct OBPerformer : StandardReceiverVisitor<int3>
|
||||
break;
|
||||
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;
|
||||
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<>
|
||||
{
|
||||
@ -850,6 +867,39 @@ struct ERMExpDispatch : boost::static_visitor<>
|
||||
}
|
||||
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")
|
||||
{
|
||||
//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")
|
||||
{
|
||||
int3 objPos;
|
||||
if(trig.identifier.is_initialized())
|
||||
{
|
||||
ERM::Tidentifier tid = trig.identifier.get();
|
||||
switch(tid.size())
|
||||
{
|
||||
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;
|
||||
}
|
||||
objPos = HLP(owner).getPosFromIdentifier(tid, false);
|
||||
|
||||
//execute body
|
||||
if(trig.body.is_initialized())
|
||||
{
|
||||
@ -954,7 +998,7 @@ struct ERMExpDispatch : boost::static_visitor<>
|
||||
}
|
||||
else
|
||||
{
|
||||
//unsupported or invalid trigger
|
||||
//not supported or invalid trigger
|
||||
}
|
||||
}
|
||||
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!");
|
||||
}
|
||||
|
||||
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>()*/ )
|
||||
{
|
||||
struct HLP
|
||||
|
@ -471,14 +471,15 @@ public:
|
||||
|
||||
class ERMInterpreter
|
||||
{
|
||||
friend class ScriptScanner;
|
||||
friend class TriggerIdMatchHelper;
|
||||
friend class TriggerIdentifierMatch;
|
||||
friend class ConditionDisemboweler;
|
||||
friend struct LVL2IexpDisemboweler;
|
||||
friend struct VR_SPerformer;
|
||||
friend struct ERMExpDispatch;
|
||||
friend struct VRPerformer;
|
||||
/*not so*/ public:
|
||||
// friend class ScriptScanner;
|
||||
// friend class TriggerIdMatchHelper;
|
||||
// friend class TriggerIdentifierMatch;
|
||||
// friend class ConditionDisemboweler;
|
||||
// friend struct LVL2IexpDisemboweler;
|
||||
// friend struct VR_SPerformer;
|
||||
// friend struct ERMExpDispatch;
|
||||
// friend struct VRPerformer;
|
||||
|
||||
std::vector<VERMInterpreter::FileInfo*> files;
|
||||
std::vector< VERMInterpreter::FileInfo* > fileInfos;
|
||||
@ -500,6 +501,7 @@ class ERMInterpreter
|
||||
IexpValStr getIexp(const ERM::TIexp & iexp) const;
|
||||
IexpValStr getIexp(const ERM::TMacroUsage & macro) const;
|
||||
IexpValStr getIexp(const ERM::TIdentifierInternal & tid) const;
|
||||
IexpValStr getIexp(const ERM::TVarpExp & tid) const;
|
||||
|
||||
static const std::string triggerSymbol, postTriggerSymbol, defunSymbol;
|
||||
|
||||
@ -509,6 +511,8 @@ class ERMInterpreter
|
||||
static bool isATrigger(const ERM::TLine & line);
|
||||
static ERM::EVOtions getExpType(const ERM::TVOption & opt);
|
||||
IexpValStr getVar(std::string toFollow, boost::optional<int> initVal) const;
|
||||
|
||||
|
||||
public:
|
||||
typedef std::map< int, std::vector<int> > TIDPattern;
|
||||
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(
|
||||
ERM::TVarpExp,
|
||||
(ERM::TVarpExp::Tvartype, var)
|
||||
(ERM::TVarExp, var)
|
||||
)
|
||||
|
||||
BOOST_FUSION_ADAPT_STRUCT(
|
||||
@ -355,7 +355,7 @@ namespace ERM
|
||||
/*qERMMacroUsage %= qi::lexeme[qi::lit("?$") >> *(qi::char_ - '$') >> qi::lit('$')];*/
|
||||
varExp %= varExpNotMacro | ERMmacroUsage;
|
||||
iexp %= varExp | qi::int_;
|
||||
varp %= qi::lit("?") >> (varExpNotMacro | ERMmacroUsage);
|
||||
varp %= qi::lit("?") >> varExp;
|
||||
comment %= *qi::char_;
|
||||
commentLine %= (~qi::char_("!") >> comment | (qi::char_('!') >> (~qi::char_("?!$#[")) >> comment ));
|
||||
cmdName %= qi::lexeme[qi::repeat(2)[qi::char_]];
|
||||
@ -373,7 +373,7 @@ namespace ERM
|
||||
semiCompare %= +qi::char_("<=>") >> iexp;
|
||||
curStr %= iexp >> 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("/"));
|
||||
normalBodyOption = qi::char_("A-Z+") > exactBodyOptionList;
|
||||
bodyOption %= VRLogic | VRarithmetic | normalBodyOption;
|
||||
|
@ -72,8 +72,7 @@ namespace ERM
|
||||
//write-only variable expression
|
||||
struct TVarpExp
|
||||
{
|
||||
typedef boost::variant<TVarExpNotMacro, TMacroUsage> Tvartype;
|
||||
Tvartype var;
|
||||
TVarExp var;
|
||||
};
|
||||
|
||||
//i-expression (identifier expression) - an integral constant, variable symbol or array symbol
|
||||
@ -115,7 +114,7 @@ namespace ERM
|
||||
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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user