1 From 6225d8585d215569c4a919171bea1915c306d1c8 Mon Sep 17 00:00:00 2001
2 From: Andreas Grois <andi@grois.info>
3 Date: Mon, 25 Sep 2023 21:26:23 +0200
4 Subject: [PATCH] Make ERM compile again.
6 This is not a proper clean up. It does not bring the code up to the
7 current state of the rest of the codebase. However, the module now
10 scripting/erm/ERMInterpreter.cpp | 279 +++++++++++++++++--------------
11 scripting/erm/ERMInterpreter.h | 13 +-
12 scripting/erm/ERMParser.h | 1 +
13 3 files changed, 151 insertions(+), 142 deletions(-)
15 diff --git a/scripting/erm/ERMInterpreter.cpp b/scripting/erm/ERMInterpreter.cpp
16 index 663cb35722..e4f60105ab 100644
17 --- a/scripting/erm/ERMInterpreter.cpp
18 +++ b/scripting/erm/ERMInterpreter.cpp
19 @@ -163,7 +163,7 @@ namespace ERMConverter
20 Variable operator()(const TVarExpNotMacro & val) const
\r
22 if(val.val.has_value())
\r
23 - return Variable(val.varsym, val.val.get());
\r
24 + return Variable(val.varsym, *val.val);
\r
26 return Variable(val.varsym, 0);
\r
28 @@ -392,7 +392,7 @@ namespace ERMConverter
30 if(trig.params.has_value())
\r
32 - for(auto & p : trig.params.get())
\r
33 + for(auto & p : *trig.params)
\r
34 optionParams.push_back(std::visit(BodyOption(), p));
\r
37 @@ -572,7 +572,7 @@ namespace ERMConverter
39 if(option.params.has_value())
\r
41 - for(auto & p : option.params.get())
\r
42 + for(auto & p : *option.params)
\r
44 std::string macroName = std::visit(MC_S(), p);
\r
46 @@ -739,7 +739,7 @@ namespace ERMConverter
48 if(trig.params.has_value())
\r
50 - for(auto & p : trig.params.get())
\r
51 + for(auto & p : *trig.params)
\r
52 optionParams.push_back(std::visit(BodyOption(), p));
\r
55 @@ -759,10 +759,10 @@ namespace ERMConverter
57 case 'H': //checking if string is empty
\r
59 - if(!trig.params.has_value() || trig.params.get().size() != 1)
\r
60 + if(!trig.params.has_value() || trig.params->size() != 1)
\r
61 throw EScriptExecError("VR:H option takes exactly 1 parameter!");
\r
63 - std::string opt = std::visit(VR_H(), trig.params.get()[0]);
\r
64 + std::string opt = std::visit(VR_H(), (*trig.params)[0]);
\r
65 boost::format fmt("ERM.VR(%s):H(%s)");
\r
66 fmt % v.str() % opt;
\r
68 @@ -770,10 +770,10 @@ namespace ERMConverter
72 - if(!trig.params.has_value() || trig.params.get().size() != 1)
\r
73 + if(!trig.params.has_value() || trig.params->size() != 1)
\r
74 throw EScriptExecError("VR:H/U need 1 parameter!");
\r
76 - std::string opt = std::visit(VR_S(), trig.params.get()[0]);
\r
77 + std::string opt = std::visit(VR_S(), (*trig.params)[0]);
\r
78 boost::format fmt("ERM.VR(%s):%c(%s)");
\r
79 fmt % v.str() % (trig.optionCode) % opt;
\r
81 @@ -781,10 +781,10 @@ namespace ERMConverter
83 case 'M': //string operations
\r
85 - if(!trig.params.has_value() || trig.params.get().size() < 2)
\r
86 + if(!trig.params.has_value() || trig.params->size() < 2)
\r
87 throw EScriptExecError("VR:M needs at least 2 parameters!");
\r
89 - std::string opt = std::visit(VR_X(), trig.params.get()[0]);
\r
90 + std::string opt = std::visit(VR_X(), (*trig.params)[0]);
\r
94 @@ -795,16 +795,16 @@ namespace ERMConverter
98 - auto target = std::visit(VR_X(), trig.params.get()[paramIndex++]);
\r
99 + auto target = std::visit(VR_X(), (*trig.params)[paramIndex++]);
\r
101 boost::format fmt("%s = ERM.VR(%s):M%s(");
\r
102 fmt % target % v.str() % opt;
\r
106 - for(int i = paramIndex; i < trig.params.get().size(); i++)
\r
107 + for(int i = paramIndex; i < trig.params->size(); i++)
\r
109 - opt = std::visit(VR_X(), trig.params.get()[i]);
\r
110 + opt = std::visit(VR_X(), (*trig.params)[i]);
\r
111 if(i > paramIndex) put(",");
\r
114 @@ -814,10 +814,10 @@ namespace ERMConverter
116 case 'X': //bit xor
\r
118 - if(!trig.params.has_value() || trig.params.get().size() != 1)
\r
119 + if(!trig.params.has_value() || trig.params->size() != 1)
\r
120 throw EScriptExecError("VR:X option takes exactly 1 parameter!");
\r
122 - std::string opt = std::visit(VR_X(), trig.params.get()[0]);
\r
123 + std::string opt = std::visit(VR_X(), (*trig.params)[0]);
\r
125 boost::format fmt("%s = bit.bxor(%s, %s)");
\r
126 fmt % v.str() % v.str() % opt;putLine(fmt.str());
\r
127 @@ -831,10 +831,10 @@ namespace ERMConverter
129 case 'S': //setting variable
\r
131 - if(!trig.params.has_value() || trig.params.get().size() != 1)
\r
132 + if(!trig.params.has_value() || trig.params->size() != 1)
\r
133 throw EScriptExecError("VR:S option takes exactly 1 parameter!");
\r
135 - std::string opt = std::visit(VR_S(), trig.params.get()[0]);
\r
136 + std::string opt = std::visit(VR_S(), (*trig.params)[0]);
\r
140 @@ -849,10 +849,10 @@ namespace ERMConverter
142 case 'V': //convert string to value
\r
144 - if(!trig.params.has_value() || trig.params.get().size() != 1)
\r
145 + if(!trig.params.has_value() || trig.params->size() != 1)
\r
146 throw EScriptExecError("VR:V option takes exactly 1 parameter!");
\r
148 - std::string opt = std::visit(VR_X(), trig.params.get()[0]);
\r
149 + std::string opt = std::visit(VR_X(), (*trig.params)[0]);
\r
150 boost::format fmt("%s = tostring(%s)");
\r
151 fmt % v.str() % opt;
\r
152 putLine(fmt.str());
\r
153 @@ -877,7 +877,7 @@ namespace ERMConverter
155 if(body.has_value())
\r
157 - const ERM::Tbody & bo = body.get();
\r
158 + const ERM::Tbody & bo = *body;
\r
159 for(int g=0; g<bo.size(); ++g)
\r
161 std::visit(visitor, bo[g]);
\r
162 @@ -975,7 +975,7 @@ namespace ERMConverter
164 if(body.has_value())
\r
166 - const ERM::Tbody & bo = body.get();
\r
167 + const ERM::Tbody & bo = *body;
\r
170 boost::format fmt("ERM.%s(%s)");
\r
171 @@ -983,7 +983,7 @@ namespace ERMConverter
174 GenericReceiver gr(out, fmt.str(), (name == "DO"));
\r
175 - bo[0].apply_visitor(gr);
\r
176 + std::visit(gr,bo[0]);
\r
180 @@ -1044,7 +1044,7 @@ namespace ERMConverter
184 - convertConditionInner(cond.rhs.get().get(), op);
\r
185 + convertConditionInner(cond.rhs->get(), op);
\r
189 @@ -1067,7 +1067,7 @@ namespace ERMConverter
193 - convertConditionInner(cond.rhs.get().get(), cond.ctype);
\r
194 + convertConditionInner(cond.rhs->get(), cond.ctype);
\r
198 @@ -1081,7 +1081,7 @@ namespace ERMConverter
201 if(condition.has_value())
\r
202 - convertCondition(condition.get());
\r
203 + convertCondition(*condition);
\r
205 putLine("if true then");
\r
207 @@ -1097,7 +1097,7 @@ namespace ERMConverter
209 if(condition.has_value())
\r
211 - convertCondition(condition.get());
\r
212 + convertCondition(*condition);
\r
213 convert(name, identifier, body);
\r
216 @@ -1181,7 +1181,7 @@ namespace ERMConverter
220 - void operator()(const VNode & opt) const;
\r
221 + void operator()(const boost::recursive_wrapper<VNode> & opt) const;
\r
223 void operator()(const VSymbol & opt) const
\r
225 @@ -1192,7 +1192,7 @@ namespace ERMConverter
227 (*out) << std::visit(tmp, opt);
\r
229 - void operator()(ERM const ::Tcommand & opt) const
\r
230 + void operator()(const ERM::Tcommand & opt) const
\r
232 //this is how FP works, evaluation == producing side effects
\r
233 //TODO: can we evaluate to smth more useful?
\r
234 @@ -1202,9 +1202,9 @@ namespace ERMConverter
238 - void VOptionEval::operator()(const VNode & opt) const
\r
239 + void VOptionEval::operator()(const boost::recursive_wrapper<VNode> & opt) const
\r
242 + VNode tmpn(opt.get());
\r
246 @@ -1375,35 +1375,35 @@ struct ScriptScanner
248 void operator()(const TERMline & cmd) const
\r
250 - if(cmd.which() == 0) //TCommand
\r
251 + if(std::holds_alternative<Tcommand>(cmd)) //TCommand
\r
253 Tcommand tcmd = std::get<Tcommand>(cmd);
\r
254 - switch (tcmd.cmd.which())
\r
257 - case 0: //trigger
\r
258 + void operator()(const ERM::Ttrigger& t) const
\r
262 - interpreter->triggers[ TriggerType(std::get<ERM::Ttrigger>(tcmd.cmd).name) ].push_back(trig);
\r
264 + i->triggers[ TriggerType(t.name) ].push_back(trig);
\r
267 - case 1: //instruction
\r
268 + void operator()(const ERM::Tinstruction&) const
\r
270 - interpreter->instructions.push_back(lp);
\r
271 + i->instructions.push_back(l);
\r
274 - case 3: //post trigger
\r
275 + void operator()(const ERM::Treceiver&) const {}
\r
276 + void operator()(const ERM::TPostTrigger& pt) const
\r
280 - interpreter->postTriggers[ TriggerType(std::get<ERM::TPostTrigger>(tcmd.cmd).name) ].push_back(trig);
\r
282 + i->postTriggers[ TriggerType(pt.name) ].push_back(trig);
\r
289 + const decltype(interpreter)& i;
\r
290 + const LinePointer& l;
\r
293 + Visitor v{interpreter, lp};
\r
294 + std::visit(v, tcmd.cmd);
\r
299 @@ -1421,68 +1421,85 @@ ERMInterpreter::~ERMInterpreter()
301 bool ERMInterpreter::isATrigger( const ERM::TLine & line )
\r
303 - switch(line.which())
\r
304 + if(std::holds_alternative<ERM::TVExp>(line))
\r
308 - TVExp vexp = std::get<TVExp>(line);
\r
309 - if(vexp.children.empty())
\r
311 + TVExp vexp = std::get<TVExp>(line);
\r
312 + if(vexp.children.empty())
\r
315 - switch (getExpType(vexp.children[0]))
\r
321 - return isCMDATrigger( std::get<ERM::Tcommand>(vexp.children[0]) );
\r
330 + switch (getExpType(vexp.children[0]))
\r
332 - TERMline ermline = std::get<TERMline>(line);
\r
333 - switch(ermline.which())
\r
336 - return isCMDATrigger( std::get<ERM::Tcommand>(ermline) );
\r
346 + return isCMDATrigger( std::get<ERM::Tcommand>(vexp.children[0]) );
\r
354 - assert(0); //it should never happen
\r
358 + else if(std::holds_alternative<TERMline>(line))
\r
360 + TERMline ermline = std::get<TERMline>(line);
\r
361 + return std::holds_alternative<ERM::Tcommand>(ermline) && isCMDATrigger( std::get<ERM::Tcommand>(ermline) );
\r
370 ERM::EVOtions ERMInterpreter::getExpType(const ERM::TVOption & opt)
\r
372 - //MAINTENANCE: keep it correct!
\r
373 - return static_cast<ERM::EVOtions>(opt.which());
\r
376 + ERM::EVOtions operator()(const boost::recursive_wrapper<ERM::TVExp>&) const
\r
378 + return ERM::EVOtions::VEXP;
\r
380 + ERM::EVOtions operator()(const ERM::TSymbol&) const
\r
382 + return ERM::EVOtions::SYMBOL;
\r
384 + ERM::EVOtions operator()(char) const
\r
386 + return ERM::EVOtions::CHAR;
\r
388 + ERM::EVOtions operator()(double) const
\r
390 + return ERM::EVOtions::DOUBLE;
\r
392 + ERM::EVOtions operator()(int) const
\r
394 + return ERM::EVOtions::INT;
\r
396 + ERM::EVOtions operator()(const ERM::Tcommand&) const
\r
398 + return ERM::EVOtions::TCMD;
\r
400 + ERM::EVOtions operator()(const ERM::TStringConstant&) const
\r
402 + return ERM::EVOtions::STRINGC;
\r
406 + return std::visit(v, opt);
\r
409 bool ERMInterpreter::isCMDATrigger(const ERM::Tcommand & cmd)
\r
411 - switch (cmd.cmd.which())
\r
414 - case 0: //trigger
\r
415 - case 3: //post trigger
\r
422 + bool operator()(const ERM::Ttrigger&) const { return true; }
\r
423 + bool operator()(const ERM::TPostTrigger&) const { return true; }
\r
424 + bool operator()(const ERM::Tinstruction&) const { return false; }
\r
425 + bool operator()(const ERM::Treceiver&) const { return false; }
\r
428 + return std::visit(v, cmd.cmd);
\r
431 ERM::TLine & ERMInterpreter::retrieveLine(const LinePointer & linePtr)
\r
432 @@ -1492,17 +1509,17 @@ ERM::TLine & ERMInterpreter::retrieveLine(const LinePointer & linePtr)
434 ERM::TTriggerBase & ERMInterpreter::retrieveTrigger(ERM::TLine & line)
\r
436 - if(line.which() == 1)
\r
437 + if(std::holds_alternative<ERM::TERMline>(line))
\r
439 ERM::TERMline &tl = std::get<ERM::TERMline>(line);
\r
440 - if(tl.which() == 0)
\r
441 + if(std::holds_alternative<ERM::Tcommand>(tl))
\r
443 ERM::Tcommand &tcm = std::get<ERM::Tcommand>(tl);
\r
444 - if(tcm.cmd.which() == 0)
\r
445 + if(std::holds_alternative<ERM::Ttrigger>(tcm.cmd))
\r
447 return std::get<ERM::Ttrigger>(tcm.cmd);
\r
449 - else if(tcm.cmd.which() == 3)
\r
450 + else if(std::holds_alternative<ERM::TPostTrigger>(tcm.cmd))
\r
452 return std::get<ERM::TPostTrigger>(tcm.cmd);
\r
454 @@ -1569,6 +1586,40 @@ namespace VERMInterpreter
456 VOption convertToVOption(const ERM::TVOption & tvo)
\r
458 + struct OptionConverterVisitor
\r
460 + VOption operator()(const boost::recursive_wrapper<ERM::TVExp>& cmd) const
\r
462 + return boost::recursive_wrapper<VNode>(VNode(cmd.get()));
\r
464 + VOption operator()(const ERM::TSymbol & cmd) const
\r
466 + if(cmd.symModifier.empty())
\r
467 + return VSymbol(cmd.sym);
\r
469 + return boost::recursive_wrapper<VNode>(VNode(cmd));
\r
471 + VOption operator()(const char & cmd) const
\r
473 + return TLiteral(cmd);
\r
475 + VOption operator()(const double & cmd) const
\r
477 + return TLiteral(cmd);
\r
479 + VOption operator()(const int & cmd) const
\r
481 + return TLiteral(cmd);
\r
483 + VOption operator()(const ERM::Tcommand & cmd) const
\r
487 + VOption operator()(const ERM::TStringConstant & cmd) const
\r
489 + return TLiteral(cmd.str);
\r
492 return std::visit(OptionConverterVisitor(), tvo);
\r
495 @@ -1706,38 +1757,6 @@ namespace VERMInterpreter
499 - VOption OptionConverterVisitor::operator()(ERM const ::TVExp & cmd) const
\r
501 - return VNode(cmd);
\r
503 - VOption OptionConverterVisitor::operator()(ERM const ::TSymbol & cmd) const
\r
505 - if(cmd.symModifier.empty())
\r
506 - return VSymbol(cmd.sym);
\r
508 - return VNode(cmd);
\r
510 - VOption OptionConverterVisitor::operator()(const char & cmd) const
\r
512 - return TLiteral(cmd);
\r
514 - VOption OptionConverterVisitor::operator()(const double & cmd) const
\r
516 - return TLiteral(cmd);
\r
518 - VOption OptionConverterVisitor::operator()(const int & cmd) const
\r
520 - return TLiteral(cmd);
\r
522 - VOption OptionConverterVisitor::operator()(ERM const ::Tcommand & cmd) const
\r
526 - VOption OptionConverterVisitor::operator()(ERM const ::TStringConstant & cmd) const
\r
528 - return TLiteral(cmd.str);
\r
531 VermTreeIterator VOptionList::cdr()
\r
533 VermTreeIterator ret(*this);
\r
534 diff --git a/scripting/erm/ERMInterpreter.h b/scripting/erm/ERMInterpreter.h
535 index baf3d317ee..ed25509777 100644
536 --- a/scripting/erm/ERMInterpreter.h
537 +++ b/scripting/erm/ERMInterpreter.h
538 @@ -134,7 +134,7 @@ namespace VERMInterpreter
542 - for(int i=0; i<ARRAY_COUNT(validTriggers); ++i)
\r
543 + for(int i=0; i<std::size(validTriggers); ++i)
\r
545 if(validTriggers[i] == trig)
\r
546 return static_cast<ETrigType>(i);
\r
547 @@ -278,17 +278,6 @@ namespace VERMInterpreter
548 VermTreeIterator cdr();
\r
551 - struct OptionConverterVisitor
\r
553 - VOption operator()(ERM const ::TVExp & cmd) const;
\r
554 - VOption operator()(ERM const ::TSymbol & cmd) const;
\r
555 - VOption operator()(const char & cmd) const;
\r
556 - VOption operator()(const double & cmd) const;
\r
557 - VOption operator()(const int & cmd) const;
\r
558 - VOption operator()(ERM const ::Tcommand & cmd) const;
\r
559 - VOption operator()(ERM const ::TStringConstant & cmd) const;
\r
565 diff --git a/scripting/erm/ERMParser.h b/scripting/erm/ERMParser.h
566 index 29d92e61b6..95b2ccbbf3 100644
567 --- a/scripting/erm/ERMParser.h
568 +++ b/scripting/erm/ERMParser.h
572 #include <boost/spirit/home/support/unused.hpp>
\r
573 +#include <boost/variant/recursive_wrapper.hpp>
\r
575 namespace spirit = boost::spirit;
\r