1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-22 22:13:35 +02:00

Make ERM compile again.

This is not a proper clean up. It does not bring the code up to the
current state of the rest of the codebase. However, the module now
compiles again.
This commit is contained in:
Andreas Grois 2023-09-25 21:26:23 +02:00
parent b89fa254fc
commit 6225d8585d
3 changed files with 151 additions and 142 deletions

View File

@ -163,7 +163,7 @@ namespace ERMConverter
Variable operator()(const TVarExpNotMacro & val) const Variable operator()(const TVarExpNotMacro & val) const
{ {
if(val.val.has_value()) if(val.val.has_value())
return Variable(val.varsym, val.val.get()); return Variable(val.varsym, *val.val);
else else
return Variable(val.varsym, 0); return Variable(val.varsym, 0);
} }
@ -392,7 +392,7 @@ namespace ERMConverter
if(trig.params.has_value()) if(trig.params.has_value())
{ {
for(auto & p : trig.params.get()) for(auto & p : *trig.params)
optionParams.push_back(std::visit(BodyOption(), p)); optionParams.push_back(std::visit(BodyOption(), p));
} }
@ -572,7 +572,7 @@ namespace ERMConverter
{ {
if(option.params.has_value()) if(option.params.has_value())
{ {
for(auto & p : option.params.get()) for(auto & p : *option.params)
{ {
std::string macroName = std::visit(MC_S(), p); std::string macroName = std::visit(MC_S(), p);
@ -739,7 +739,7 @@ namespace ERMConverter
if(trig.params.has_value()) if(trig.params.has_value())
{ {
for(auto & p : trig.params.get()) for(auto & p : *trig.params)
optionParams.push_back(std::visit(BodyOption(), p)); optionParams.push_back(std::visit(BodyOption(), p));
} }
@ -759,10 +759,10 @@ namespace ERMConverter
break; break;
case 'H': //checking if string is empty case 'H': //checking if string is empty
{ {
if(!trig.params.has_value() || trig.params.get().size() != 1) if(!trig.params.has_value() || trig.params->size() != 1)
throw EScriptExecError("VR:H option takes exactly 1 parameter!"); throw EScriptExecError("VR:H option takes exactly 1 parameter!");
std::string opt = std::visit(VR_H(), trig.params.get()[0]); std::string opt = std::visit(VR_H(), (*trig.params)[0]);
boost::format fmt("ERM.VR(%s):H(%s)"); boost::format fmt("ERM.VR(%s):H(%s)");
fmt % v.str() % opt; fmt % v.str() % opt;
putLine(fmt.str()); putLine(fmt.str());
@ -770,10 +770,10 @@ namespace ERMConverter
break; break;
case 'U': case 'U':
{ {
if(!trig.params.has_value() || trig.params.get().size() != 1) if(!trig.params.has_value() || trig.params->size() != 1)
throw EScriptExecError("VR:H/U need 1 parameter!"); throw EScriptExecError("VR:H/U need 1 parameter!");
std::string opt = std::visit(VR_S(), trig.params.get()[0]); std::string opt = std::visit(VR_S(), (*trig.params)[0]);
boost::format fmt("ERM.VR(%s):%c(%s)"); boost::format fmt("ERM.VR(%s):%c(%s)");
fmt % v.str() % (trig.optionCode) % opt; fmt % v.str() % (trig.optionCode) % opt;
putLine(fmt.str()); putLine(fmt.str());
@ -781,10 +781,10 @@ namespace ERMConverter
break; break;
case 'M': //string operations case 'M': //string operations
{ {
if(!trig.params.has_value() || trig.params.get().size() < 2) if(!trig.params.has_value() || trig.params->size() < 2)
throw EScriptExecError("VR:M needs at least 2 parameters!"); throw EScriptExecError("VR:M needs at least 2 parameters!");
std::string opt = std::visit(VR_X(), trig.params.get()[0]); std::string opt = std::visit(VR_X(), (*trig.params)[0]);
int paramIndex = 1; int paramIndex = 1;
if(opt == "3") if(opt == "3")
@ -795,16 +795,16 @@ namespace ERMConverter
} }
else else
{ {
auto target = std::visit(VR_X(), trig.params.get()[paramIndex++]); auto target = std::visit(VR_X(), (*trig.params)[paramIndex++]);
boost::format fmt("%s = ERM.VR(%s):M%s("); boost::format fmt("%s = ERM.VR(%s):M%s(");
fmt % target % v.str() % opt; fmt % target % v.str() % opt;
put(fmt.str()); put(fmt.str());
} }
for(int i = paramIndex; i < trig.params.get().size(); i++) for(int i = paramIndex; i < trig.params->size(); i++)
{ {
opt = std::visit(VR_X(), trig.params.get()[i]); opt = std::visit(VR_X(), (*trig.params)[i]);
if(i > paramIndex) put(","); if(i > paramIndex) put(",");
put(opt); put(opt);
} }
@ -814,10 +814,10 @@ namespace ERMConverter
break; break;
case 'X': //bit xor case 'X': //bit xor
{ {
if(!trig.params.has_value() || trig.params.get().size() != 1) if(!trig.params.has_value() || trig.params->size() != 1)
throw EScriptExecError("VR:X option takes exactly 1 parameter!"); throw EScriptExecError("VR:X option takes exactly 1 parameter!");
std::string opt = std::visit(VR_X(), trig.params.get()[0]); std::string opt = std::visit(VR_X(), (*trig.params)[0]);
boost::format fmt("%s = bit.bxor(%s, %s)"); boost::format fmt("%s = bit.bxor(%s, %s)");
fmt % v.str() % v.str() % opt;putLine(fmt.str()); fmt % v.str() % v.str() % opt;putLine(fmt.str());
@ -831,10 +831,10 @@ namespace ERMConverter
break; break;
case 'S': //setting variable case 'S': //setting variable
{ {
if(!trig.params.has_value() || trig.params.get().size() != 1) if(!trig.params.has_value() || trig.params->size() != 1)
throw EScriptExecError("VR:S option takes exactly 1 parameter!"); throw EScriptExecError("VR:S option takes exactly 1 parameter!");
std::string opt = std::visit(VR_S(), trig.params.get()[0]); std::string opt = std::visit(VR_S(), (*trig.params)[0]);
put(v.str()); put(v.str());
put(" = "); put(" = ");
put(opt); put(opt);
@ -849,10 +849,10 @@ namespace ERMConverter
break; break;
case 'V': //convert string to value case 'V': //convert string to value
{ {
if(!trig.params.has_value() || trig.params.get().size() != 1) if(!trig.params.has_value() || trig.params->size() != 1)
throw EScriptExecError("VR:V option takes exactly 1 parameter!"); throw EScriptExecError("VR:V option takes exactly 1 parameter!");
std::string opt = std::visit(VR_X(), trig.params.get()[0]); std::string opt = std::visit(VR_X(), (*trig.params)[0]);
boost::format fmt("%s = tostring(%s)"); boost::format fmt("%s = tostring(%s)");
fmt % v.str() % opt; fmt % v.str() % opt;
putLine(fmt.str()); putLine(fmt.str());
@ -877,7 +877,7 @@ namespace ERMConverter
{ {
if(body.has_value()) if(body.has_value())
{ {
const ERM::Tbody & bo = body.get(); const ERM::Tbody & bo = *body;
for(int g=0; g<bo.size(); ++g) for(int g=0; g<bo.size(); ++g)
{ {
std::visit(visitor, bo[g]); std::visit(visitor, bo[g]);
@ -975,7 +975,7 @@ namespace ERMConverter
if(body.has_value()) if(body.has_value())
{ {
const ERM::Tbody & bo = body.get(); const ERM::Tbody & bo = *body;
if(bo.size() == 1) if(bo.size() == 1)
{ {
boost::format fmt("ERM.%s(%s)"); boost::format fmt("ERM.%s(%s)");
@ -983,7 +983,7 @@ namespace ERMConverter
fmt % params; fmt % params;
GenericReceiver gr(out, fmt.str(), (name == "DO")); GenericReceiver gr(out, fmt.str(), (name == "DO"));
bo[0].apply_visitor(gr); std::visit(gr,bo[0]);
} }
else else
{ {
@ -1044,7 +1044,7 @@ namespace ERMConverter
break; break;
} }
convertConditionInner(cond.rhs.get().get(), op); convertConditionInner(cond.rhs->get(), op);
} }
} }
@ -1067,7 +1067,7 @@ namespace ERMConverter
break; break;
} }
convertConditionInner(cond.rhs.get().get(), cond.ctype); convertConditionInner(cond.rhs->get(), cond.ctype);
} }
putLine(" then "); putLine(" then ");
@ -1081,7 +1081,7 @@ namespace ERMConverter
if(name=="if") if(name=="if")
{ {
if(condition.has_value()) if(condition.has_value())
convertCondition(condition.get()); convertCondition(*condition);
else else
putLine("if true then"); putLine("if true then");
} }
@ -1097,7 +1097,7 @@ namespace ERMConverter
{ {
if(condition.has_value()) if(condition.has_value())
{ {
convertCondition(condition.get()); convertCondition(*condition);
convert(name, identifier, body); convert(name, identifier, body);
putLine("end"); putLine("end");
} }
@ -1181,7 +1181,7 @@ namespace ERMConverter
{ {
(*out) << "{}"; (*out) << "{}";
} }
void operator()(const VNode & opt) const; void operator()(const boost::recursive_wrapper<VNode> & opt) const;
void operator()(const VSymbol & opt) const void operator()(const VSymbol & opt) const
{ {
@ -1192,7 +1192,7 @@ namespace ERMConverter
TLiteralEval tmp; TLiteralEval tmp;
(*out) << std::visit(tmp, opt); (*out) << std::visit(tmp, opt);
} }
void operator()(ERM const ::Tcommand & opt) const void operator()(const ERM::Tcommand & opt) const
{ {
//this is how FP works, evaluation == producing side effects //this is how FP works, evaluation == producing side effects
//TODO: can we evaluate to smth more useful? //TODO: can we evaluate to smth more useful?
@ -1202,9 +1202,9 @@ namespace ERMConverter
} }
}; };
void VOptionEval::operator()(const VNode & opt) const void VOptionEval::operator()(const boost::recursive_wrapper<VNode> & opt) const
{ {
VNode tmpn(opt); VNode tmpn(opt.get());
(*out) << "{"; (*out) << "{";
@ -1375,35 +1375,35 @@ struct ScriptScanner
} }
void operator()(const TERMline & cmd) const void operator()(const TERMline & cmd) const
{ {
if(cmd.which() == 0) //TCommand if(std::holds_alternative<Tcommand>(cmd)) //TCommand
{ {
Tcommand tcmd = std::get<Tcommand>(cmd); Tcommand tcmd = std::get<Tcommand>(cmd);
switch (tcmd.cmd.which()) struct Visitor
{ {
case 0: //trigger void operator()(const ERM::Ttrigger& t) const
{ {
Trigger trig; Trigger trig;
trig.line = lp; trig.line = l;
interpreter->triggers[ TriggerType(std::get<ERM::Ttrigger>(tcmd.cmd).name) ].push_back(trig); i->triggers[ TriggerType(t.name) ].push_back(trig);
} }
break; void operator()(const ERM::Tinstruction&) const
case 1: //instruction
{ {
interpreter->instructions.push_back(lp); i->instructions.push_back(l);
} }
break; void operator()(const ERM::Treceiver&) const {}
case 3: //post trigger void operator()(const ERM::TPostTrigger& pt) const
{ {
Trigger trig; Trigger trig;
trig.line = lp; trig.line = l;
interpreter->postTriggers[ TriggerType(std::get<ERM::TPostTrigger>(tcmd.cmd).name) ].push_back(trig); i->postTriggers[ TriggerType(pt.name) ].push_back(trig);
}
break;
default:
break;
}
} }
const decltype(interpreter)& i;
const LinePointer& l;
};
Visitor v{interpreter, lp};
std::visit(v, tcmd.cmd);
}
} }
}; };
@ -1421,9 +1421,7 @@ ERMInterpreter::~ERMInterpreter()
bool ERMInterpreter::isATrigger( const ERM::TLine & line ) bool ERMInterpreter::isATrigger( const ERM::TLine & line )
{ {
switch(line.which()) if(std::holds_alternative<ERM::TVExp>(line))
{
case 0: //v-exp
{ {
TVExp vexp = std::get<TVExp>(line); TVExp vexp = std::get<TVExp>(line);
if(vexp.children.empty()) if(vexp.children.empty())
@ -1442,47 +1440,66 @@ bool ERMInterpreter::isATrigger( const ERM::TLine & line )
break; break;
} }
} }
break; else if(std::holds_alternative<TERMline>(line))
case 1: //erm
{ {
TERMline ermline = std::get<TERMline>(line); TERMline ermline = std::get<TERMline>(line);
switch(ermline.which()) return std::holds_alternative<ERM::Tcommand>(ermline) && isCMDATrigger( std::get<ERM::Tcommand>(ermline) );
}
else
{ {
case 0: //tcmd
return isCMDATrigger( std::get<ERM::Tcommand>(ermline) );
break;
default:
return false;
break;
}
}
break;
default:
assert(0); //it should never happen
break;
}
assert(0); assert(0);
}
return false; return false;
} }
ERM::EVOtions ERMInterpreter::getExpType(const ERM::TVOption & opt) ERM::EVOtions ERMInterpreter::getExpType(const ERM::TVOption & opt)
{ {
//MAINTENANCE: keep it correct! struct Visitor
return static_cast<ERM::EVOtions>(opt.which()); {
ERM::EVOtions operator()(const boost::recursive_wrapper<ERM::TVExp>&) const
{
return ERM::EVOtions::VEXP;
}
ERM::EVOtions operator()(const ERM::TSymbol&) const
{
return ERM::EVOtions::SYMBOL;
}
ERM::EVOtions operator()(char) const
{
return ERM::EVOtions::CHAR;
}
ERM::EVOtions operator()(double) const
{
return ERM::EVOtions::DOUBLE;
}
ERM::EVOtions operator()(int) const
{
return ERM::EVOtions::INT;
}
ERM::EVOtions operator()(const ERM::Tcommand&) const
{
return ERM::EVOtions::TCMD;
}
ERM::EVOtions operator()(const ERM::TStringConstant&) const
{
return ERM::EVOtions::STRINGC;
}
};
const Visitor v;
return std::visit(v, opt);
} }
bool ERMInterpreter::isCMDATrigger(const ERM::Tcommand & cmd) bool ERMInterpreter::isCMDATrigger(const ERM::Tcommand & cmd)
{ {
switch (cmd.cmd.which()) struct Visitor
{ {
case 0: //trigger bool operator()(const ERM::Ttrigger&) const { return true; }
case 3: //post trigger bool operator()(const ERM::TPostTrigger&) const { return true; }
return true; bool operator()(const ERM::Tinstruction&) const { return false; }
break; bool operator()(const ERM::Treceiver&) const { return false; }
default: };
return false; const Visitor v;
break; return std::visit(v, cmd.cmd);
}
} }
ERM::TLine & ERMInterpreter::retrieveLine(const LinePointer & linePtr) ERM::TLine & ERMInterpreter::retrieveLine(const LinePointer & linePtr)
@ -1492,17 +1509,17 @@ ERM::TLine & ERMInterpreter::retrieveLine(const LinePointer & linePtr)
ERM::TTriggerBase & ERMInterpreter::retrieveTrigger(ERM::TLine & line) ERM::TTriggerBase & ERMInterpreter::retrieveTrigger(ERM::TLine & line)
{ {
if(line.which() == 1) if(std::holds_alternative<ERM::TERMline>(line))
{ {
ERM::TERMline &tl = std::get<ERM::TERMline>(line); ERM::TERMline &tl = std::get<ERM::TERMline>(line);
if(tl.which() == 0) if(std::holds_alternative<ERM::Tcommand>(tl))
{ {
ERM::Tcommand &tcm = std::get<ERM::Tcommand>(tl); ERM::Tcommand &tcm = std::get<ERM::Tcommand>(tl);
if(tcm.cmd.which() == 0) if(std::holds_alternative<ERM::Ttrigger>(tcm.cmd))
{ {
return std::get<ERM::Ttrigger>(tcm.cmd); return std::get<ERM::Ttrigger>(tcm.cmd);
} }
else if(tcm.cmd.which() == 3) else if(std::holds_alternative<ERM::TPostTrigger>(tcm.cmd))
{ {
return std::get<ERM::TPostTrigger>(tcm.cmd); return std::get<ERM::TPostTrigger>(tcm.cmd);
} }
@ -1569,6 +1586,40 @@ namespace VERMInterpreter
{ {
VOption convertToVOption(const ERM::TVOption & tvo) VOption convertToVOption(const ERM::TVOption & tvo)
{ {
struct OptionConverterVisitor
{
VOption operator()(const boost::recursive_wrapper<ERM::TVExp>& cmd) const
{
return boost::recursive_wrapper<VNode>(VNode(cmd.get()));
}
VOption operator()(const ERM::TSymbol & cmd) const
{
if(cmd.symModifier.empty())
return VSymbol(cmd.sym);
else
return boost::recursive_wrapper<VNode>(VNode(cmd));
}
VOption operator()(const char & cmd) const
{
return TLiteral(cmd);
}
VOption operator()(const double & cmd) const
{
return TLiteral(cmd);
}
VOption operator()(const int & cmd) const
{
return TLiteral(cmd);
}
VOption operator()(const ERM::Tcommand & cmd) const
{
return cmd;
}
VOption operator()(const ERM::TStringConstant & cmd) const
{
return TLiteral(cmd.str);
}
};
return std::visit(OptionConverterVisitor(), tvo); return std::visit(OptionConverterVisitor(), tvo);
} }
@ -1706,38 +1757,6 @@ namespace VERMInterpreter
return ret; return ret;
} }
VOption OptionConverterVisitor::operator()(ERM const ::TVExp & cmd) const
{
return VNode(cmd);
}
VOption OptionConverterVisitor::operator()(ERM const ::TSymbol & cmd) const
{
if(cmd.symModifier.empty())
return VSymbol(cmd.sym);
else
return VNode(cmd);
}
VOption OptionConverterVisitor::operator()(const char & cmd) const
{
return TLiteral(cmd);
}
VOption OptionConverterVisitor::operator()(const double & cmd) const
{
return TLiteral(cmd);
}
VOption OptionConverterVisitor::operator()(const int & cmd) const
{
return TLiteral(cmd);
}
VOption OptionConverterVisitor::operator()(ERM const ::Tcommand & cmd) const
{
return cmd;
}
VOption OptionConverterVisitor::operator()(ERM const ::TStringConstant & cmd) const
{
return TLiteral(cmd.str);
}
VermTreeIterator VOptionList::cdr() VermTreeIterator VOptionList::cdr()
{ {
VermTreeIterator ret(*this); VermTreeIterator ret(*this);

View File

@ -134,7 +134,7 @@ namespace VERMInterpreter
"TH", "TM" "TH", "TM"
}; };
for(int i=0; i<ARRAY_COUNT(validTriggers); ++i) for(int i=0; i<std::size(validTriggers); ++i)
{ {
if(validTriggers[i] == trig) if(validTriggers[i] == trig)
return static_cast<ETrigType>(i); return static_cast<ETrigType>(i);
@ -278,17 +278,6 @@ namespace VERMInterpreter
VermTreeIterator cdr(); VermTreeIterator cdr();
}; };
struct OptionConverterVisitor
{
VOption operator()(ERM const ::TVExp & cmd) const;
VOption operator()(ERM const ::TSymbol & cmd) const;
VOption operator()(const char & cmd) const;
VOption operator()(const double & cmd) const;
VOption operator()(const int & cmd) const;
VOption operator()(ERM const ::Tcommand & cmd) const;
VOption operator()(ERM const ::TStringConstant & cmd) const;
};
struct VNode struct VNode
{ {
private: private:

View File

@ -10,6 +10,7 @@
#pragma once #pragma once
#include <boost/spirit/home/support/unused.hpp> #include <boost/spirit/home/support/unused.hpp>
#include <boost/variant/recursive_wrapper.hpp>
namespace spirit = boost::spirit; namespace spirit = boost::spirit;