diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index ab69edf76..3e32a1dd8 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -245,9 +245,9 @@ protected: /* Properties */ int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const { return node()->getPolynomialCoefficients(context, symbolName, coefficients); } - bool hasSymbols(Context & context) const; - Expression replaceSymbols(Context & context) { return node()->replaceSymbols(context); } - Expression defaultReplaceSymbols(Context & context); + bool hasReplaceableSymbols(Context & context) const; + Expression replaceReplaceableSymbols(Context & context) { return node()->replaceReplaceableSymbols(context); } + Expression defaultReplaceReplaceableSymbols(Context & context); /* Simplification */ Expression denominator(Context & context, Preferences::AngleUnit angleUnit) const { return node()->denominator(context, angleUnit); } diff --git a/poincare/include/poincare/expression_node.h b/poincare/include/poincare/expression_node.h index e41efb86e..e8f559e32 100644 --- a/poincare/include/poincare/expression_node.h +++ b/poincare/include/poincare/expression_node.h @@ -106,7 +106,7 @@ public: /*!*/ virtual Expression setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit); virtual int polynomialDegree(Context & context, const char * symbolName) const; /*!*/ virtual int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const; - /*!*/ virtual Expression replaceSymbols(Context & context); + /*!*/ virtual Expression replaceReplaceableSymbols(Context & context); typedef bool (*isVariableTest)(const char * c); virtual int getVariables(Context & context, isVariableTest isVariable, char * variables, int maxSizeVariable) const; virtual float characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const; diff --git a/poincare/include/poincare/symbol.h b/poincare/include/poincare/symbol.h index e4abbe1c1..8c82ef03f 100644 --- a/poincare/include/poincare/symbol.h +++ b/poincare/include/poincare/symbol.h @@ -31,7 +31,7 @@ public: /* Simplification */ Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true) override; - Expression replaceSymbols(Context & context) override; + Expression replaceReplaceableSymbols(Context & context) override; /* Approximation */ Evaluation approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(context, angleUnit); } @@ -77,7 +77,7 @@ public: Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression); int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const; - Expression replaceSymbols(Context & context); + Expression replaceReplaceableSymbols(Context & context); private: SymbolNode * node() const { return static_cast(Expression::node()); } }; diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index 99f04ef9d..313b7bda3 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -221,16 +221,19 @@ void Expression::defaultSetChildrenInPlace(Expression other) { } } -bool Expression::hasSymbols(Context & context) const { +bool Expression::hasReplaceableSymbols(Context & context) const { return recursivelyMatches([](const Expression e, Context & context) { - return e.type() == ExpressionNode::Type::Symbol || e.type() == ExpressionNode::Type::Function; + return (e.type() == ExpressionNode::Type::Symbol + && !context.expressionForSymbol(static_cast(e)).isUninitialized()) + || (e.type() == ExpressionNode::Type::Function + && !context.expressionForSymbol(static_cast(e)).isUninitialized()); }, context); } -Expression Expression::defaultReplaceSymbols(Context & context) { +Expression Expression::defaultReplaceReplaceableSymbols(Context & context) { int nbChildren = numberOfChildren(); for (int i = 0; i < nbChildren; i++) { - childAtIndex(i).replaceSymbols(context); + childAtIndex(i).replaceReplaceableSymbols(context); } return *this; } @@ -327,12 +330,12 @@ Expression Expression::ExpressionWithoutSymbols(Expression e, Context & context) * symbols are likely to be defined circularly, in which case we return an * uninitialized expression.*/ int replacementCount = 0; - while (e.hasSymbols(context)) { + while (e.hasReplaceableSymbols(context)) { replacementCount++; if (replacementCount > k_maxSymbolReplacementsCount) { return Expression(); } - e = e.replaceSymbols(context); + e = e.replaceReplaceableSymbols(context); } return e; } diff --git a/poincare/src/expression_node.cpp b/poincare/src/expression_node.cpp index 574da2145..3b6de93e4 100644 --- a/poincare/src/expression_node.cpp +++ b/poincare/src/expression_node.cpp @@ -27,8 +27,8 @@ int ExpressionNode::getPolynomialCoefficients(Context & context, const char * sy return Expression(this).defaultGetPolynomialCoefficients(context, symbolName, coefficients); } -Expression ExpressionNode::replaceSymbols(Context & context) { - return Expression(this).defaultReplaceSymbols(context); +Expression ExpressionNode::replaceReplaceableSymbols(Context & context) { + return Expression(this).defaultReplaceReplaceableSymbols(context); } int ExpressionNode::getVariables(Context & context, isVariableTest isVariable, char * variables, int maxSizeVariable) const { diff --git a/poincare/src/symbol.cpp b/poincare/src/symbol.cpp index 5985e4634..294082fab 100644 --- a/poincare/src/symbol.cpp +++ b/poincare/src/symbol.cpp @@ -120,8 +120,8 @@ Expression SymbolNode::shallowReduce(Context & context, Preferences::AngleUnit a return Symbol(this).shallowReduce(context, angleUnit, replaceSymbols); } -Expression SymbolNode::replaceSymbols(Context & context) { - return Symbol(this).replaceSymbols(context); +Expression SymbolNode::replaceReplaceableSymbols(Context & context) { + return Symbol(this).replaceReplaceableSymbols(context); } template @@ -202,10 +202,10 @@ int Symbol::getPolynomialCoefficients(Context & context, const char * symbolName return 0; } -Expression Symbol::replaceSymbols(Context & context) { +Expression Symbol::replaceReplaceableSymbols(Context & context) { Expression e = context.expressionForSymbol(*this); if (e.isUninitialized()) { - e = Undefined(); + return *this; } replaceWithInPlace(e); return e;