@@ -491,7 +491,7 @@ namespace FlatModelica
491491 virtual bool isLiteral () const = 0;
492492
493493 virtual std::unique_ptr<ExpressionBase> clone () const = 0;
494- virtual Expression eval (const Expression::VariableEvaluator &var_eval) const = 0;
494+ virtual Expression eval (const Expression::VariableEvaluator &var_eval, int recursion_level = 0 ) const = 0;
495495
496496 virtual void print (std::ostream &os) const = 0;
497497 };
@@ -503,7 +503,7 @@ namespace FlatModelica
503503 : _value(value) {}
504504
505505 std::unique_ptr<ExpressionBase> clone () const override { return std::make_unique<Integer>(*this ); }
506- Expression eval (const Expression::VariableEvaluator&) const override { return Expression (_value); }
506+ Expression eval (const Expression::VariableEvaluator&, int ) const override { return Expression (_value); }
507507
508508 bool isInteger () const override { return true ; }
509509 bool isBooleanish () const override { return true ; }
@@ -526,7 +526,7 @@ namespace FlatModelica
526526 : _value(value) {}
527527
528528 std::unique_ptr<ExpressionBase> clone () const override { return std::make_unique<Real>(*this ); }
529- Expression eval (const Expression::VariableEvaluator&) const override { return Expression (_value); }
529+ Expression eval (const Expression::VariableEvaluator&, int ) const override { return Expression (_value); }
530530
531531 bool isReal () const override { return true ; }
532532 bool isBooleanish () const override { return true ; }
@@ -549,7 +549,7 @@ namespace FlatModelica
549549 : _value(value) {}
550550
551551 std::unique_ptr<ExpressionBase> clone () const override { return std::make_unique<Boolean>(*this ); }
552- Expression eval (const Expression::VariableEvaluator&) const override { return Expression (_value); }
552+ Expression eval (const Expression::VariableEvaluator&, int ) const override { return Expression (_value); }
553553
554554 bool isBoolean () const override { return true ; }
555555 bool isBooleanish () const override { return true ; }
@@ -572,7 +572,7 @@ namespace FlatModelica
572572 String (const QJsonValue &value);
573573
574574 std::unique_ptr<ExpressionBase> clone () const override { return std::make_unique<String>(*this ); }
575- Expression eval (const Expression::VariableEvaluator&) const override { return Expression (_value); }
575+ Expression eval (const Expression::VariableEvaluator&, int ) const override { return Expression (_value); }
576576
577577 bool isString () const override { return true ; }
578578 bool isLiteral () const override { return true ; }
@@ -596,7 +596,7 @@ namespace FlatModelica
596596 Enum (const QJsonObject &value);
597597
598598 std::unique_ptr<ExpressionBase> clone () const override { return std::make_unique<Enum>(*this ); }
599- Expression eval (const Expression::VariableEvaluator &var_eval) const override ;
599+ Expression eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const override ;
600600
601601 bool isEnum () const override { return true ; }
602602 bool isLiteral () const override { return true ; }
@@ -619,7 +619,7 @@ namespace FlatModelica
619619 Cref (const QJsonObject &value);
620620
621621 std::unique_ptr<ExpressionBase> clone () const override { return std::make_unique<Cref>(*this ); }
622- Expression eval (const Expression::VariableEvaluator &var_eval) const override ;
622+ Expression eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const override ;
623623
624624 bool isLiteral () const override { return false ; }
625625 void print (std::ostream &os) const override ;
@@ -640,7 +640,7 @@ namespace FlatModelica
640640 Array (const QJsonArray &value);
641641
642642 std::unique_ptr<ExpressionBase> clone () const override { return std::make_unique<Array>(*this ); }
643- Expression eval (const Expression::VariableEvaluator &var_eval) const override ;
643+ Expression eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const override ;
644644
645645 bool isArray () const override { return true ; }
646646 bool isLiteral () const override ;
@@ -664,7 +664,7 @@ namespace FlatModelica
664664 Range (const QJsonObject &value);
665665
666666 std::unique_ptr<ExpressionBase> clone () const override { return std::make_unique<Range>(*this ); }
667- Expression eval (const Expression::VariableEvaluator &var_eval) const override ;
667+ Expression eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const override ;
668668
669669 bool isLiteral () const override ;
670670
@@ -686,7 +686,7 @@ namespace FlatModelica
686686 Call (const QJsonObject &value, bool isRecord);
687687
688688 std::unique_ptr<ExpressionBase> clone () const override { return std::make_unique<Call>(*this ); }
689- Expression eval (const Expression::VariableEvaluator &var_eval) const override ;
689+ Expression eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const override ;
690690
691691 bool isCall () const override { return true ; }
692692 bool isLiteral () const override { return false ; }
@@ -733,7 +733,7 @@ namespace FlatModelica
733733 IteratorCall (const QJsonObject &value);
734734
735735 std::unique_ptr<ExpressionBase> clone () const override { return std::make_unique<IteratorCall>(*this ); }
736- Expression eval (const Expression::VariableEvaluator &var_eval) const override ;
736+ Expression eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const override ;
737737
738738 bool isLiteral () const override { return false ; }
739739
@@ -755,7 +755,7 @@ namespace FlatModelica
755755 Binary (const QJsonObject &value);
756756
757757 std::unique_ptr<ExpressionBase> clone () const override { return std::make_unique<Binary>(*this ); }
758- Expression eval (const Expression::VariableEvaluator &var_eval) const override ;
758+ Expression eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const override ;
759759
760760 bool isLiteral () const override { return false ; }
761761 void print (std::ostream &os) const override ;
@@ -778,7 +778,7 @@ namespace FlatModelica
778778 Unary (const QJsonObject &value);
779779
780780 std::unique_ptr<ExpressionBase> clone () const override { return std::make_unique<Unary>(*this ); }
781- Expression eval (const Expression::VariableEvaluator &var_eval) const override ;
781+ Expression eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const override ;
782782
783783 bool isLiteral () const override { return false ; }
784784 void print (std::ostream &os) const override ;
@@ -801,7 +801,7 @@ namespace FlatModelica
801801 IfExp (const QJsonObject &value);
802802
803803 std::unique_ptr<ExpressionBase> clone () const override { return std::make_unique<IfExp>(*this ); }
804- Expression eval (const Expression::VariableEvaluator &var_eval) const override ;
804+ Expression eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const override ;
805805
806806 bool isLiteral () const override { return false ; }
807807 void print (std::ostream &os) const override ;
@@ -1336,9 +1336,10 @@ namespace FlatModelica
13361336 _index = value[" index" ].toInt ();
13371337 }
13381338
1339- Expression Enum::eval (const Expression::VariableEvaluator &var_eval) const
1339+ Expression Enum::eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const
13401340 {
13411341 Q_UNUSED (var_eval);
1342+ Q_UNUSED (recursion_level);
13421343 return Expression (_name, _index);
13431344 }
13441345
@@ -1404,9 +1405,13 @@ namespace FlatModelica
14041405 }
14051406 }
14061407
1407- Expression Cref::eval (const Expression::VariableEvaluator &var_eval) const
1408+ Expression Cref::eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const
14081409 {
1409- return Expression (var_eval (_name));
1410+ if (recursion_level > 100 ) {
1411+ throw std::runtime_error (" Recursion limit reached" );
1412+ }
1413+
1414+ return var_eval (_name).evaluate (var_eval, recursion_level + 1 );
14101415 }
14111416
14121417 void Cref::print (std::ostream &os) const
@@ -1467,13 +1472,13 @@ namespace FlatModelica
14671472 }
14681473 }
14691474
1470- Expression Array::eval (const Expression::VariableEvaluator &var_eval) const
1475+ Expression Array::eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const
14711476 {
14721477 std::vector<Expression> elems;
14731478 elems.reserve (_elements.size ());
14741479
14751480 for (auto &e: _elements) {
1476- elems.emplace_back (e.evaluate (var_eval));
1481+ elems.emplace_back (e.evaluate (var_eval, recursion_level ));
14771482 }
14781483
14791484 return Expression (std::move (elems));
@@ -1550,11 +1555,11 @@ namespace FlatModelica
15501555 }
15511556 }
15521557
1553- Expression Range::eval (const Expression::VariableEvaluator &var_eval) const
1558+ Expression Range::eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const
15541559 {
1555- auto start = _start.evaluate (var_eval);
1556- auto stop = _stop.evaluate (var_eval);
1557- auto step = _step.isNull () ? Expression () : _step.evaluate (var_eval);
1560+ auto start = _start.evaluate (var_eval, recursion_level );
1561+ auto stop = _stop.evaluate (var_eval, recursion_level );
1562+ auto step = _step.isNull () ? Expression () : _step.evaluate (var_eval, recursion_level );
15581563 return Expression (std::make_unique<Range>(std::move (start), std::move (step), std::move (stop)));
15591564 }
15601565
@@ -1610,13 +1615,13 @@ namespace FlatModelica
16101615 }
16111616 }
16121617
1613- Expression Call::eval (const Expression::VariableEvaluator &var_eval) const
1618+ Expression Call::eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const
16141619 {
16151620 std::vector<Expression> args;
16161621 args.reserve (_args.size ());
16171622
16181623 for (auto &a: _args) {
1619- args.emplace_back (a.evaluate (var_eval));
1624+ args.emplace_back (a.evaluate (var_eval, recursion_level ));
16201625 }
16211626
16221627 switch (djb2_hash (_name.c_str ())) {
@@ -1797,9 +1802,10 @@ namespace FlatModelica
17971802 }
17981803 }
17991804
1800- Expression IteratorCall::eval (const Expression::VariableEvaluator &var_eval) const
1805+ Expression IteratorCall::eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const
18011806 {
18021807 Q_UNUSED (var_eval);
1808+ Q_UNUSED (recursion_level);
18031809 return Expression (std::make_unique<IteratorCall>(*this ));
18041810 }
18051811
@@ -1846,32 +1852,32 @@ namespace FlatModelica
18461852 _e2.deserialize (value[" rhs" ]);
18471853 }
18481854
1849- Expression Binary::eval (const Expression::VariableEvaluator &var_eval) const
1855+ Expression Binary::eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const
18501856 {
18511857 switch (_op.type ()) {
1852- case Operator::Add: return _e1.evaluate (var_eval) + _e2.evaluate (var_eval);
1853- case Operator::Sub: return _e1.evaluate (var_eval) - _e2.evaluate (var_eval);
1854- case Operator::Mul: return _e1.evaluate (var_eval) * _e2.evaluate (var_eval);
1855- case Operator::Div: return _e1.evaluate (var_eval) / _e2.evaluate (var_eval);
1856- case Operator::Pow: return _e1.evaluate (var_eval) ^ _e2.evaluate (var_eval);
1857- case Operator::AddEW: return Expression::addEw (_e1.evaluate (var_eval), _e2.evaluate (var_eval));
1858- case Operator::SubEW: return Expression::subEw (_e1.evaluate (var_eval), _e2.evaluate (var_eval));
1859- case Operator::MulEW: return Expression::mulEw (_e1.evaluate (var_eval), _e2.evaluate (var_eval));
1860- case Operator::DivEW: return Expression::divEw (_e1.evaluate (var_eval), _e2.evaluate (var_eval));
1861- case Operator::PowEW: return Expression::powEw (_e1.evaluate (var_eval), _e2.evaluate (var_eval));
1858+ case Operator::Add: return _e1.evaluate (var_eval, recursion_level ) + _e2.evaluate (var_eval, recursion_level );
1859+ case Operator::Sub: return _e1.evaluate (var_eval, recursion_level ) - _e2.evaluate (var_eval, recursion_level );
1860+ case Operator::Mul: return _e1.evaluate (var_eval, recursion_level ) * _e2.evaluate (var_eval, recursion_level );
1861+ case Operator::Div: return _e1.evaluate (var_eval, recursion_level ) / _e2.evaluate (var_eval, recursion_level );
1862+ case Operator::Pow: return _e1.evaluate (var_eval, recursion_level ) ^ _e2.evaluate (var_eval, recursion_level );
1863+ case Operator::AddEW: return Expression::addEw (_e1.evaluate (var_eval, recursion_level ), _e2.evaluate (var_eval, recursion_level ));
1864+ case Operator::SubEW: return Expression::subEw (_e1.evaluate (var_eval, recursion_level ), _e2.evaluate (var_eval, recursion_level ));
1865+ case Operator::MulEW: return Expression::mulEw (_e1.evaluate (var_eval, recursion_level ), _e2.evaluate (var_eval, recursion_level ));
1866+ case Operator::DivEW: return Expression::divEw (_e1.evaluate (var_eval, recursion_level ), _e2.evaluate (var_eval, recursion_level ));
1867+ case Operator::PowEW: return Expression::powEw (_e1.evaluate (var_eval, recursion_level ), _e2.evaluate (var_eval, recursion_level ));
18621868 // Special handling of 'and' and 'or' to avoid evaluating both sides unless it's necessary.
18631869 case Operator::And: return expBinaryEWOp (_e1, _e2, [&] (auto &e1 , auto &e2 ) {
1864- return e1 .evaluate (var_eval) && e2 .evaluate (var_eval);
1870+ return e1 .evaluate (var_eval, recursion_level ) && e2 .evaluate (var_eval, recursion_level );
18651871 }, " and" );
18661872 case Operator::Or: return expBinaryEWOp (_e1, _e2, [&] (auto &e1 , auto &e2 ) {
1867- return e1 .evaluate (var_eval) || e2 .evaluate (var_eval);
1873+ return e1 .evaluate (var_eval, recursion_level ) || e2 .evaluate (var_eval, recursion_level );
18681874 }, " or" );
1869- case Operator::Equal: return Expression (_e1.evaluate (var_eval) == _e2.evaluate (var_eval));
1870- case Operator::NotEqual: return Expression (_e1.evaluate (var_eval) != _e2.evaluate (var_eval));
1871- case Operator::Less: return Expression (_e1.evaluate (var_eval) < _e2.evaluate (var_eval));
1872- case Operator::LessEq: return Expression (_e1.evaluate (var_eval) <= _e2.evaluate (var_eval));
1873- case Operator::Greater: return Expression (_e1.evaluate (var_eval) > _e2.evaluate (var_eval));
1874- case Operator::GreaterEq: return Expression (_e1.evaluate (var_eval) >= _e2.evaluate (var_eval));
1875+ case Operator::Equal: return Expression (_e1.evaluate (var_eval, recursion_level ) == _e2.evaluate (var_eval, recursion_level ));
1876+ case Operator::NotEqual: return Expression (_e1.evaluate (var_eval, recursion_level ) != _e2.evaluate (var_eval, recursion_level ));
1877+ case Operator::Less: return Expression (_e1.evaluate (var_eval, recursion_level ) < _e2.evaluate (var_eval, recursion_level ));
1878+ case Operator::LessEq: return Expression (_e1.evaluate (var_eval, recursion_level ) <= _e2.evaluate (var_eval, recursion_level ));
1879+ case Operator::Greater: return Expression (_e1.evaluate (var_eval, recursion_level ) > _e2.evaluate (var_eval, recursion_level ));
1880+ case Operator::GreaterEq: return Expression (_e1.evaluate (var_eval, recursion_level ) >= _e2.evaluate (var_eval, recursion_level ));
18751881 default : break ;
18761882 }
18771883
@@ -1917,11 +1923,11 @@ namespace FlatModelica
19171923 _op.deserialize (value[" op" ]);
19181924 }
19191925
1920- Expression Unary::eval (const Expression::VariableEvaluator &var_eval) const
1926+ Expression Unary::eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const
19211927 {
19221928 switch (_op.type ()) {
1923- case Operator::Sub: return -_e.evaluate (var_eval);
1924- case Operator::Not: return !_e.evaluate (var_eval);
1929+ case Operator::Sub: return -_e.evaluate (var_eval, recursion_level );
1930+ case Operator::Not: return !_e.evaluate (var_eval, recursion_level );
19251931 default : break ;
19261932 }
19271933
@@ -1981,10 +1987,10 @@ namespace FlatModelica
19811987 _false_e.deserialize (value[" false" ]);
19821988 }
19831989
1984- Expression IfExp::eval (const Expression::VariableEvaluator &var_eval) const
1990+ Expression IfExp::eval (const Expression::VariableEvaluator &var_eval, int recursion_level ) const
19851991 {
1986- return _condition.evaluate (var_eval).boolValue () ?
1987- _true_e.evaluate (var_eval) : _false_e.evaluate (var_eval);
1992+ return _condition.evaluate (var_eval, recursion_level ).boolValue () ?
1993+ _true_e.evaluate (var_eval, recursion_level ) : _false_e.evaluate (var_eval, recursion_level );
19881994 }
19891995
19901996 void IfExp::print (std::ostream &os) const
@@ -2227,9 +2233,9 @@ namespace FlatModelica
22272233 * name as a string and returns the variables value as a double.
22282234 * \param var_eval
22292235 */
2230- Expression Expression::evaluate (const VariableEvaluator &var_eval) const
2236+ Expression Expression::evaluate (const VariableEvaluator &var_eval, int recursion_level ) const
22312237 {
2232- return Expression (_value->eval (var_eval));
2238+ return Expression (_value->eval (var_eval, recursion_level ));
22332239 }
22342240
22352241 /* !
0 commit comments