diff --git a/poincare/include/poincare/absolute_value.h b/poincare/include/poincare/absolute_value.h index 9f015601d..9e23e40dc 100644 --- a/poincare/include/poincare/absolute_value.h +++ b/poincare/include/poincare/absolute_value.h @@ -14,6 +14,12 @@ public: Expression * clone() const override; Sign sign() const override { return Sign::Positive; } private: + Expression * setSign(Sign s, Context & context, AngleUnit angleUnit) override; + ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override; + int writeTextInBuffer(char * buffer, int bufferSize) const override { + return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "abs"); + } + Expression * shallowSimplify(Context& context, AngleUnit angleUnit) override; template static Complex computeOnComplex(const Complex c, AngleUnit angleUnit); virtual Evaluation * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return EvaluationEngine::map(this, context, angleUnit,computeOnComplex); @@ -21,12 +27,6 @@ private: virtual Evaluation * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return EvaluationEngine::map(this, context, angleUnit, computeOnComplex); } - ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override; - int writeTextInBuffer(char * buffer, int bufferSize) const override { - return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, "abs"); - } - Expression * shallowSimplify(Context& context, AngleUnit angleUnit) override; - Expression * setSign(Sign s, Context & context, AngleUnit angleUnit) override; }; } diff --git a/poincare/include/poincare/addition.h b/poincare/include/poincare/addition.h index 247d63c77..1d7fd71d5 100644 --- a/poincare/include/poincare/addition.h +++ b/poincare/include/poincare/addition.h @@ -16,6 +16,7 @@ class Addition : public DynamicHierarchy { public: Type type() const override; Expression * clone() const override; + /* Evaluation */ template static Complex compute(const Complex c, const Complex d); template static Evaluation * computeOnMatrices(Evaluation * m, Evaluation * n) { return EvaluationEngine::elementWiseOnComplexMatrices(m, n, compute); @@ -24,6 +25,25 @@ public: return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute); } private: + /* Layout */ + ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override { + return LayoutEngine::createInfixLayout(this, floatDisplayMode, complexFormat, name()); + } + int writeTextInBuffer(char * buffer, int bufferSize) const override { + return LayoutEngine::writeInfixExpressionTextInBuffer(this, buffer, bufferSize, name()); + } + static const char * name() { return "+"; } + + /* Simplification */ + Expression * shallowSimplify(Context& context, AngleUnit angleUnit) override; + Expression * shallowBeautify(Context & context, AngleUnit angleUnit) override; + Expression * factorizeOnCommonDenominator(Context & context, AngleUnit angleUnit); + void factorizeChildren(Expression * e1, Expression * e2, Context & context, AngleUnit angleUnit); + static const Rational RationalFactor(Expression * e); + static bool TermsHaveIdenticalNonRationalFactors(const Expression * e1, const Expression * e2); + bool isUselessOperand(const Rational * r) override; + + /* Evaluation */ template static Evaluation * computeOnMatrixAndComplex(Evaluation * m, const Complex * c) { return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute); } @@ -33,21 +53,6 @@ private: virtual Evaluation * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return EvaluationEngine::mapReduce(this, context, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); } - Expression * shallowSimplify(Context& context, AngleUnit angleUnit) override; - ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override { - return LayoutEngine::createInfixLayout(this, floatDisplayMode, complexFormat, name()); - } - int writeTextInBuffer(char * buffer, int bufferSize) const override { - return LayoutEngine::writeInfixExpressionTextInBuffer(this, buffer, bufferSize, name()); - } - static const char * name() { return "+"; } - /* Simplification */ - Expression * shallowBeautify(Context & context, AngleUnit angleUnit) override; - Expression * factorizeOnCommonDenominator(Context & context, AngleUnit angleUnit); - void factorizeChildren(Expression * e1, Expression * e2, Context & context, AngleUnit angleUnit); - static const Rational RationalFactor(Expression * e); - static bool TermsHaveIdenticalNonRationalFactors(const Expression * e1, const Expression * e2); - bool isUselessOperand(const Rational * r) override; }; } diff --git a/poincare/include/poincare/arc_cosine.h b/poincare/include/poincare/arc_cosine.h index 47a68f256..f6dacaa1d 100644 --- a/poincare/include/poincare/arc_cosine.h +++ b/poincare/include/poincare/arc_cosine.h @@ -13,14 +13,7 @@ public: Type type() const override; Expression * clone() const override; private: - template static Complex computeOnComplex(const Complex c, AngleUnit angleUnit); - virtual Evaluation * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { - return EvaluationEngine::map(this, context, angleUnit,computeOnComplex); - } - virtual Evaluation * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { - return EvaluationEngine::map(this, context, angleUnit, computeOnComplex); - } - Expression * shallowSimplify(Context& context, AngleUnit angleUnit) override; + /* Layout */ ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override { return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name()); } @@ -30,6 +23,16 @@ private: const char * name() const { return "acos"; } + /* Simplification */ + Expression * shallowSimplify(Context& context, AngleUnit angleUnit) override; + /* Evaluation */ + template static Complex computeOnComplex(const Complex c, AngleUnit angleUnit); + virtual Evaluation * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { + return EvaluationEngine::map(this, context, angleUnit,computeOnComplex); + } + virtual Evaluation * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { + return EvaluationEngine::map(this, context, angleUnit, computeOnComplex); + } }; } diff --git a/poincare/include/poincare/arc_sine.h b/poincare/include/poincare/arc_sine.h index ef6eb972e..b5b321849 100644 --- a/poincare/include/poincare/arc_sine.h +++ b/poincare/include/poincare/arc_sine.h @@ -13,14 +13,7 @@ public: Type type() const override; Expression * clone() const override; private: - template static Complex computeOnComplex(const Complex c, AngleUnit angleUnit); - virtual Evaluation * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { - return EvaluationEngine::map(this, context, angleUnit,computeOnComplex); - } - virtual Evaluation * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { - return EvaluationEngine::map(this, context, angleUnit, computeOnComplex); - } - Expression * shallowSimplify(Context & context, AngleUnit angleUnit) override; + /* Layout */ ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override { return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name()); } @@ -28,6 +21,16 @@ private: return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name()); } const char * name() const { return "asin"; } + /* Simplification */ + Expression * shallowSimplify(Context & context, AngleUnit angleUnit) override; + /* Evaluation */ + template static Complex computeOnComplex(const Complex c, AngleUnit angleUnit); + virtual Evaluation * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { + return EvaluationEngine::map(this, context, angleUnit,computeOnComplex); + } + virtual Evaluation * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { + return EvaluationEngine::map(this, context, angleUnit, computeOnComplex); + } }; } diff --git a/poincare/include/poincare/arc_tangent.h b/poincare/include/poincare/arc_tangent.h index 4b6a0fa12..7deef412a 100644 --- a/poincare/include/poincare/arc_tangent.h +++ b/poincare/include/poincare/arc_tangent.h @@ -13,14 +13,7 @@ public: Type type() const override; Expression * clone() const override; private: - template static Complex computeOnComplex(const Complex c, AngleUnit angleUnit); - virtual Evaluation * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { - return EvaluationEngine::map(this, context, angleUnit,computeOnComplex); - } - virtual Evaluation * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { - return EvaluationEngine::map(this, context, angleUnit, computeOnComplex); - } - Expression * shallowSimplify(Context& context, AngleUnit angleUnit) override; + /* Layout */ ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override { return LayoutEngine::createPrefixLayout(this, floatDisplayMode, complexFormat, name()); } @@ -28,6 +21,16 @@ private: return LayoutEngine::writePrefixExpressionTextInBuffer(this, buffer, bufferSize, name()); } const char * name() const { return "atan"; } + /* Simplification */ + Expression * shallowSimplify(Context& context, AngleUnit angleUnit) override; + /* Evaluation */ + template static Complex computeOnComplex(const Complex c, AngleUnit angleUnit); + virtual Evaluation * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { + return EvaluationEngine::map(this, context, angleUnit,computeOnComplex); + } + virtual Evaluation * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { + return EvaluationEngine::map(this, context, angleUnit, computeOnComplex); + } }; } diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index c03669a7e..5988d16fa 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -108,13 +108,6 @@ public: virtual ~Expression() = default; virtual Expression * clone() const = 0; - enum class Sign { - Negative = -1, - Unknown = 0, - Positive = 1 - }; - virtual Sign sign() const { return Sign::Unknown; } - /* Poor man's RTTI */ virtual Type type() const = 0; @@ -124,8 +117,8 @@ public: static bool shouldStopProcessing(); /* Hierarchy */ - Expression * editableOperand(int i) { return const_cast(operand(i)); } virtual const Expression * operand(int i) const = 0; + Expression * editableOperand(int i) { return const_cast(operand(i)); } virtual int numberOfOperands() const = 0; Expression * parent() const { return m_parent; } void setParent(Expression * parent) { m_parent = parent; } @@ -133,10 +126,18 @@ public: virtual void replaceOperand(const Expression * oldOperand, Expression * newOperand, bool deleteOldOperand = true) = 0; Expression * replaceWith(Expression * newOperand, bool deleteAfterReplace = true); virtual void swapOperands(int i, int j) = 0; - //void removeFromParent(); + /* Properties */ + enum class Sign { + Negative = -1, + Unknown = 0, + Positive = 1 + }; + virtual Sign sign() const { return Sign::Unknown; } + typedef bool (*ExpressionTest)(const Expression * e); + bool recursivelyMatches(ExpressionTest test) const; - // Comparison + /* Comparison */ /* isIdenticalTo is the "easy" equality, it returns true if both trees have * same structures and all their nodes have same types and values (ie, * sqrt(pi^2) is NOT identical to pi). */ @@ -150,13 +151,9 @@ public: ExpressionLayout * createLayout(FloatDisplayMode floatDisplayMode = FloatDisplayMode::Default, ComplexFormat complexFormat = ComplexFormat::Default) const; // Returned object must be deleted virtual int writeTextInBuffer(char * buffer, int bufferSize) const = 0; - /* Simplification */ static void simplify(Expression ** expressionAddress, Context & context, AngleUnit angleUnit = AngleUnit::Default); - typedef bool (*ExpressionTest)(const Expression * e); - bool recursivelyMatches(ExpressionTest test) const; - /* Evaluation Engine * The function evaluate creates a new expression and thus mallocs memory. * Do not forget to delete the new expression to avoid leaking. */ @@ -171,7 +168,8 @@ protected: typedef double DoublePrecision; template static T epsilon(); - /* Simplification order returns: + /* Simplification */ + /* SimplificationOrder returns: * 1 if e1 > e2 * -1 if e1 < e2 * 0 if e1 == e @@ -182,20 +180,9 @@ protected: * same non-rational factors together (ie Pi, 2*Pi). */ static int SimplificationOrder(const Expression * e1, const Expression * e2); private: - /* Simplification */ - Expression * deepBeautify(Context & context, AngleUnit angleUnit); - Expression * deepSimplify(Context & context, AngleUnit angleUnit); - // TODO: should be virtual pure - virtual Expression * shallowSimplify(Context & context, AngleUnit angleUnit) { return this; }; - virtual Expression * shallowBeautify(Context & context, AngleUnit angleUnit) { return this; }; - /* Layout Engine */ - virtual ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const = 0; - /* Evaluation Engine */ - virtual Evaluation * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const = 0; - virtual Evaluation * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const = 0; - + /* Properties */ virtual Expression * setSign(Sign s, Context & context, AngleUnit angleUnit) { assert(false); return nullptr; } - + /* Comparison */ /* In the simplification order, most expressions are compared by only * comparing their types. However hierarchical expressions of same type would * compare their operands and thus need to reimplement @@ -203,8 +190,19 @@ private: * (ie +, *, ^, !) have specific rules to group like terms together and thus * reimplement simplificationOrderGreaterType. */ virtual int simplificationOrderGreaterType(const Expression * e) const { return -1; } + //TODO: What should be the implementation for complex? virtual int simplificationOrderSameType(const Expression * e) const { return 0; } - /* TODO: What should be the implementation for complex? */ + /* Layout Engine */ + virtual ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const = 0; + /* Simplification */ + Expression * deepBeautify(Context & context, AngleUnit angleUnit); + Expression * deepSimplify(Context & context, AngleUnit angleUnit); + // TODO: should be virtual pure + virtual Expression * shallowSimplify(Context & context, AngleUnit angleUnit) { return this; }; + virtual Expression * shallowBeautify(Context & context, AngleUnit angleUnit) { return this; }; + /* Evaluation Engine */ + virtual Evaluation * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const = 0; + virtual Evaluation * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const = 0; Expression * m_parent; }; diff --git a/poincare/include/poincare/multiplication.h b/poincare/include/poincare/multiplication.h index aeb546f87..affdbd22d 100644 --- a/poincare/include/poincare/multiplication.h +++ b/poincare/include/poincare/multiplication.h @@ -24,20 +24,10 @@ public: return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute); } template static Evaluation * computeOnMatrices(Evaluation * m, Evaluation * n); - - static bool HaveSameNonRationalFactors(const Expression * e1, const Expression * e2); - Expression * createDenominator(Context & context, AngleUnit angleUnit); - void leastCommonMultiple(Expression * factor, Context & context, AngleUnit angleUnit); private: - template static Evaluation * computeOnMatrixAndComplex(Evaluation * m, const Complex * c) { - return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute); - } - virtual Evaluation * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { - return EvaluationEngine::mapReduce(this, context, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); - } - virtual Evaluation * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { - return EvaluationEngine::mapReduce(this, context, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); - } + /* Property */ + Expression * setSign(Sign s, Context & context, AngleUnit angleUnit) override; + /* Layout */ ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override; int writeTextInBuffer(char * buffer, int bufferSize) const override; /* Simplification */ @@ -47,6 +37,9 @@ private: void factorizeBase(Expression * e1, Expression * e2, Context & context, AngleUnit angleUnit); void factorizeExponent(Expression * e1, Expression * e2, Context & context, AngleUnit angleUnit); Expression * distributeOnChildAtIndex(int index, Context & context, AngleUnit angleUnit); + Expression * createDenominator(Context & context, AngleUnit angleUnit); + void leastCommonMultiple(Expression * factor, Context & context, AngleUnit angleUnit); + static bool HaveSameNonRationalFactors(const Expression * e1, const Expression * e2); static bool TermsHaveIdenticalBase(const Expression * e1, const Expression * e2); static bool TermsHaveIdenticalNonUnitaryExponent(const Expression * e1, const Expression * e2); static bool TermHasRationalBase(const Expression * e); @@ -56,10 +49,19 @@ private: static const Rational * RationalFactorInExpression(const Expression * e); static const Expression * CreateExponent(Expression * e); bool isUselessOperand(const Rational * r) override; - // Warning: mergeNegativePower not always returns a multiplication: *(b^-1,c^-1) -> (bc)^-1 Expression * shallowBeautify(Context & context, AngleUnit angleUnit) override; + // Warning: mergeNegativePower not always returns a multiplication: *(b^-1,c^-1) -> (bc)^-1 Expression * mergeNegativePower(Context & context, AngleUnit angleUnit); - Expression * setSign(Sign s, Context & context, AngleUnit angleUnit) override; + /* Evaluation */ + template static Evaluation * computeOnMatrixAndComplex(Evaluation * m, const Complex * c) { + return EvaluationEngine::elementWiseOnComplexAndComplexMatrix(c, m, compute); + } + virtual Evaluation * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { + return EvaluationEngine::mapReduce(this, context, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); + } + virtual Evaluation * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { + return EvaluationEngine::mapReduce(this, context, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); + } }; } diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h index 8bc324d07..081dfb500 100644 --- a/poincare/include/poincare/power.h +++ b/poincare/include/poincare/power.h @@ -13,38 +13,42 @@ class Power : public StaticHierarchy<2> { friend class Multiplication; friend class NthRoot; friend class SquareRoot; + friend class Addition; public: Type type() const override; Expression * clone() const override; Sign sign() const override; template static Complex compute(const Complex c, const Complex d); - Expression * createDenominator(Context & context, AngleUnit angleUnit); private: constexpr static float k_maxNumberOfSteps = 10000.0f; + /* Property */ + Expression * setSign(Sign s, Context & context, AngleUnit angleUnit) override; + /* Layout */ + ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override; + int writeTextInBuffer(char * buffer, int bufferSize) const override { + return LayoutEngine::writeInfixExpressionTextInBuffer(this, buffer, bufferSize, name()); + } + static const char * name() { return "^"; } + /* Simplify */ + Expression * shallowSimplify(Context& context, AngleUnit angleUnit) override; + Expression * shallowBeautify(Context & context, AngleUnit angleUnit) override; + int simplificationOrderGreaterType(const Expression * e) const override; + int simplificationOrderSameType(const Expression * e) const override; + Expression * simplifyPowerPower(Power * p, Expression * r, Context & context, AngleUnit angleUnit); + Expression * createDenominator(Context & context, AngleUnit angleUnit); + Expression * simplifyPowerMultiplication(Multiplication * m, Expression * r, Context & context, AngleUnit angleUnit); + Expression * simplifyRationalRationalPower(Expression * result, Rational * a, Rational * b, Context & context, AngleUnit angleUnit); + static Expression * CreateSimplifiedIntegerRationalPower(Integer i, Rational * r, bool isDenominator); + /* Evaluation */ template static Evaluation * computeOnComplexAndMatrix(const Complex * c, Evaluation * n); template static Evaluation * computeOnMatrixAndComplex(Evaluation * m, const Complex * d); template static Evaluation * computeOnMatrices(Evaluation * m, Evaluation * n); - virtual Evaluation * privateEvaluate(SinglePrecision p, Context& context, AngleUnit angleUnit) const override { return EvaluationEngine::mapReduce(this, context, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); } virtual Evaluation * privateEvaluate(DoublePrecision p, Context& context, AngleUnit angleUnit) const override { return EvaluationEngine::mapReduce(this, context, angleUnit, compute, computeOnComplexAndMatrix, computeOnMatrixAndComplex, computeOnMatrices); } - Expression * setSign(Sign s, Context & context, AngleUnit angleUnit) override; - Expression * shallowSimplify(Context& context, AngleUnit angleUnit) override; - Expression * shallowBeautify(Context & context, AngleUnit angleUnit) override; - ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override; - int writeTextInBuffer(char * buffer, int bufferSize) const override { - return LayoutEngine::writeInfixExpressionTextInBuffer(this, buffer, bufferSize, name()); - } - static const char * name() { return "^"; } - int simplificationOrderGreaterType(const Expression * e) const override; - int simplificationOrderSameType(const Expression * e) const override; - Expression * simplifyPowerPower(Power * p, Expression * r, Context & context, AngleUnit angleUnit); - Expression * simplifyPowerMultiplication(Multiplication * m, Expression * r, Context & context, AngleUnit angleUnit); - Expression * simplifyRationalRationalPower(Expression * result, Rational * a, Rational * b, Context & context, AngleUnit angleUnit); - static Expression * CreateSimplifiedIntegerRationalPower(Integer i, Rational * r, bool isDenominator); }; } diff --git a/poincare/src/absolute_value.cpp b/poincare/src/absolute_value.cpp index b8adf2c40..1176104d9 100644 --- a/poincare/src/absolute_value.cpp +++ b/poincare/src/absolute_value.cpp @@ -18,6 +18,17 @@ Expression * AbsoluteValue::clone() const { return a; } +Expression * AbsoluteValue::setSign(Sign s, Context & context, AngleUnit angleUnit) { + assert(s == Sign::Positive); + return this; +} + +ExpressionLayout * AbsoluteValue::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const { + assert(floatDisplayMode != FloatDisplayMode::Default); + assert(complexFormat != ComplexFormat::Default); + return new AbsoluteValueLayout(operand(0)->createLayout(floatDisplayMode, complexFormat)); +} + Expression * AbsoluteValue::shallowSimplify(Context& context, AngleUnit angleUnit) { if (operand(0)->sign() == Sign::Positive) { return replaceWith(editableOperand(0), true); @@ -30,20 +41,9 @@ Expression * AbsoluteValue::shallowSimplify(Context& context, AngleUnit angleUni return this; } -Expression * AbsoluteValue::setSign(Sign s, Context & context, AngleUnit angleUnit) { - assert(s == Sign::Positive); - return this; -} - template Complex AbsoluteValue::computeOnComplex(const Complex c, AngleUnit angleUnit) { return Complex::Float(c.r()); } -ExpressionLayout * AbsoluteValue::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const { - assert(floatDisplayMode != FloatDisplayMode::Default); - assert(complexFormat != ComplexFormat::Default); - return new AbsoluteValueLayout(operand(0)->createLayout(floatDisplayMode, complexFormat)); -} - } diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index 30e672c6f..b6cdc134c 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -20,10 +20,7 @@ Expression * Addition::clone() const { return new Addition(operands(), numberOfOperands(), true); } -template -Complex Addition::compute(const Complex c, const Complex d) { - return Complex::Cartesian(c.a()+d.a(), c.b()+d.b()); -} +/* Simplication */ Expression * Addition::shallowSimplify(Context& context, AngleUnit angleUnit) { /* TODO: optimize, do we have to restart index = 0 at every merging? */ @@ -159,11 +156,17 @@ Expression * Addition::shallowBeautify(Context & context, AngleUnit angleUnit) { return squashUnaryHierarchy(); } - bool Addition::isUselessOperand(const Rational * r) { return r->isZero(); } +/* Evaluation */ + +template +Complex Addition::compute(const Complex c, const Complex d) { + return Complex::Cartesian(c.a()+d.a(), c.b()+d.b()); +} + template Poincare::Complex Poincare::Addition::compute(Poincare::Complex, Poincare::Complex); template Poincare::Complex Poincare::Addition::compute(Poincare::Complex, Poincare::Complex); diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index ccbc14f51..9090f820a 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -16,10 +16,10 @@ int poincare_expression_yyparse(Poincare::Expression ** expressionOutput); namespace Poincare { -static Expression::CircuitBreaker sCircuitBreaker = nullptr; - #include +/* Constructor & Destructor */ + Expression * Expression::parse(char const * string) { if (string[0] == 0) { return nullptr; @@ -38,6 +38,10 @@ Expression * Expression::parse(char const * string) { return expression; } +/* Circuit breaker */ + +static Expression::CircuitBreaker sCircuitBreaker = nullptr; + void Expression::setCircuitBreaker(CircuitBreaker cb) { sCircuitBreaker = cb; } @@ -49,6 +53,53 @@ bool Expression::shouldStopProcessing() { return sCircuitBreaker(); } +/* Hierarchy */ + +bool Expression::hasAncestor(const Expression * e) const { + assert(m_parent != this); + if (m_parent == e) { + return true; + } + if (m_parent == nullptr) { + return false; + } + return m_parent->hasAncestor(e); +} + +Expression * Expression::replaceWith(Expression * newOperand, bool deleteAfterReplace) { + assert(m_parent != nullptr); + m_parent->replaceOperand(this, newOperand, deleteAfterReplace); + return newOperand; +} + +/* Properties */ + +bool Expression::recursivelyMatches(ExpressionTest test) const { + if (test(this)) { + return true; + } + for (int i = 0; i < numberOfOperands(); i++) { + if (test(operand(i))) { + return true; + } + } + return false; +} + +/* Comparison */ + +int Expression::SimplificationOrder(const Expression * e1, const Expression * e2) { + if (e1->type() > e2->type()) { + return -(e2->simplificationOrderGreaterType(e1)); + } else if (e1->type() == e2->type()) { + return e1->simplificationOrderSameType(e2); + } else { + return e1->simplificationOrderGreaterType(e2); + } +} + +/* Layout */ + ExpressionLayout * Expression::createLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const { switch (floatDisplayMode) { case FloatDisplayMode::Default: @@ -68,6 +119,8 @@ ExpressionLayout * Expression::createLayout(FloatDisplayMode floatDisplayMode, C } } +/* Simplification */ + void Expression::simplify(Expression ** expressionAddress, Context & context, AngleUnit angleUnit) { if (angleUnit == AngleUnit::Default) { angleUnit = Preferences::sharedPreferences()->angleUnit(); @@ -95,50 +148,7 @@ Expression * Expression::deepBeautify(Context & context, AngleUnit angleUnit) { return e; } -bool Expression::recursivelyMatches(ExpressionTest test) const { - if (test(this)) { - return true; - } - for (int i = 0; i < numberOfOperands(); i++) { - if (test(operand(i))) { - return true; - } - } - return false; -} - -bool Expression::hasAncestor(const Expression * e) const { - assert(m_parent != this); - if (m_parent == e) { - return true; - } - if (m_parent == nullptr) { - return false; - } - return m_parent->hasAncestor(e); -} - -Expression * Expression::replaceWith(Expression * newOperand, bool deleteAfterReplace) { - assert(m_parent != nullptr); - m_parent->replaceOperand(this, newOperand, deleteAfterReplace); - return newOperand; -} - -/*void Expression::removeFromParent() { - assert(m_parent != nullptr); - assert(m_parent->type() == Expression::Type::Addition || m_parent->type() == Expression::Type::Multiplication); // Weak assertion. We just want to make sure this is actually a DynamicHierarchy - static_cast(m_parent)->removeOperand(this); -}*/ - -int Expression::SimplificationOrder(const Expression * e1, const Expression * e2) { - if (e1->type() > e2->type()) { - return -(e2->simplificationOrderGreaterType(e1)); - } else if (e1->type() == e2->type()) { - return e1->simplificationOrderSameType(e2); - } else { - return e1->simplificationOrderGreaterType(e2); - } -} +/* Evaluation */ template Evaluation * Expression::evaluate(Context& context, AngleUnit angleUnit) const { switch (angleUnit) {