diff --git a/poincare/Makefile b/poincare/Makefile index a6c0524b9..7ffd237cb 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -106,6 +106,7 @@ poincare_src += $(addprefix poincare/src/,\ matrix_reduced_row_echelon_form.cpp \ multiplication.cpp \ n_ary_expression.cpp \ + n_ary_infix_expression.cpp \ naperian_logarithm.cpp \ norm_cdf.cpp \ norm_cdf2.cpp \ diff --git a/poincare/include/poincare/addition.h b/poincare/include/poincare/addition.h index 37ca11506..346c6c11a 100644 --- a/poincare/include/poincare/addition.h +++ b/poincare/include/poincare/addition.h @@ -2,15 +2,15 @@ #define POINCARE_ADDITION_H #include -#include +#include #include namespace Poincare { -class AdditionNode final : public NAryExpressionNode { +class AdditionNode final : public NAryInfixExpressionNode { friend class Addition; public: - using NAryExpressionNode::NAryExpressionNode; + using NAryInfixExpressionNode::NAryInfixExpressionNode; // Tree size_t size() const override { return sizeof(AdditionNode); } diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 6e71cc117..4639195aa 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -120,6 +120,7 @@ class Expression : public TreeHandle { friend class MatrixNode; friend class NaperianLogarithmNode; friend class NAryExpressionNode; + friend class NAryInfixExpressionNode; friend class StoreNode; friend class SymbolNode; friend class UnitNode; diff --git a/poincare/include/poincare/expression_node.h b/poincare/include/poincare/expression_node.h index 8e56f3126..c08435fc3 100644 --- a/poincare/include/poincare/expression_node.h +++ b/poincare/include/poincare/expression_node.h @@ -20,6 +20,7 @@ class ExpressionNode : public TreeNode { friend class AdditionNode; friend class DivisionNode; friend class NAryExpressionNode; + friend class NAryInfixExpressionNode; friend class PowerNode; friend class SymbolNode; public: diff --git a/poincare/include/poincare/multiplication.h b/poincare/include/poincare/multiplication.h index 4c75085a7..fbd62e143 100644 --- a/poincare/include/poincare/multiplication.h +++ b/poincare/include/poincare/multiplication.h @@ -2,14 +2,14 @@ #define POINCARE_MULTIPLICATION_H #include -#include +#include namespace Poincare { -class MultiplicationNode final : public NAryExpressionNode { +class MultiplicationNode final : public NAryInfixExpressionNode { friend class Addition; public: - using NAryExpressionNode::NAryExpressionNode; + using NAryInfixExpressionNode::NAryInfixExpressionNode; // Tree size_t size() const override { return sizeof(MultiplicationNode); } diff --git a/poincare/include/poincare/n_ary_expression.h b/poincare/include/poincare/n_ary_expression.h index b91095cbb..ed5a65846 100644 --- a/poincare/include/poincare/n_ary_expression.h +++ b/poincare/include/poincare/n_ary_expression.h @@ -3,8 +3,6 @@ #include -// NAryExpressions are additions and multiplications - namespace Poincare { class NAryExpressionNode : public ExpressionNode { // TODO: VariableArityExpressionNode? @@ -20,9 +18,6 @@ public: } void eraseNumberOfChildren() override { m_numberOfChildren = 0; } - // Properties - bool childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const override; - // Comparison typedef int (*ExpressionOrder)(const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted); @@ -37,9 +32,6 @@ protected: /* With a pool of size < 120k and TreeNode of size 20, a node can't have more * than 6144 children which fit in uint16_t. */ uint16_t m_numberOfChildren; -private: - int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; - int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; }; class NAryExpression : public Expression { diff --git a/poincare/include/poincare/n_ary_infix_expression.h b/poincare/include/poincare/n_ary_infix_expression.h new file mode 100644 index 000000000..545741474 --- /dev/null +++ b/poincare/include/poincare/n_ary_infix_expression.h @@ -0,0 +1,23 @@ +#ifndef POINCARE_N_ARY_INFIX_EXPRESSION_H +#define POINCARE_N_ARY_INFIX_EXPRESSION_H + +#include + +// NAryInfixExpressionNode are additions and multiplications + +namespace Poincare { + +class NAryInfixExpressionNode : public NAryExpressionNode { +public: + using NAryExpressionNode::NAryExpressionNode; + // Properties + bool childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const override; +protected: + // Order + int simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; + int simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const override; +}; + +} + +#endif \ No newline at end of file diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index 3a3b5f926..f647d6c4d 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -57,7 +57,7 @@ int MultiplicationNode::getPolynomialCoefficients(Context * context, const char } bool MultiplicationNode::childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const { - if (NAryExpressionNode::childAtIndexNeedsUserParentheses(child, childIndex)) { + if (NAryInfixExpressionNode::childAtIndexNeedsUserParentheses(child, childIndex)) { return true; } Type types[] = {Type::Subtraction, Type::Addition}; diff --git a/poincare/src/n_ary_expression.cpp b/poincare/src/n_ary_expression.cpp index e0fdc1cd7..2303cc0d4 100644 --- a/poincare/src/n_ary_expression.cpp +++ b/poincare/src/n_ary_expression.cpp @@ -1,5 +1,4 @@ #include -#include #include extern "C" { #include @@ -9,21 +8,6 @@ extern "C" { namespace Poincare { -bool NAryExpressionNode::childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const { - /* Expressions like "-2" require parentheses in Addition/Multiplication except - * when they are the first operand. */ - if (childIndex != 0 - && ((child.isNumber() && static_cast(child).sign() == Sign::Negative) - || child.type() == Type::Opposite)) - { - return true; - } - if (child.type() == Type::Conjugate) { - return childAtIndexNeedsUserParentheses(child.childAtIndex(0), childIndex); - } - return false; -} - void NAryExpressionNode::sortChildrenInPlace(ExpressionOrder order, Context * context, bool canSwapMatrices, bool canBeInterrupted) { Expression reference(this); const int childrenCount = reference.numberOfChildren(); @@ -60,44 +44,6 @@ Expression NAryExpressionNode::squashUnaryHierarchyInPlace() { return std::move(reference); } -// Private - -int NAryExpressionNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { - int m = numberOfChildren(); - int n = e->numberOfChildren(); - for (int i = 1; i <= m; i++) { - // The NULL node is the least node type. - if (n < i) { - return 1; - } - int order = SimplificationOrder(childAtIndex(m-i), e->childAtIndex(n-i), ascending, canBeInterrupted, ignoreParentheses); - if (order != 0) { - return order; - } - } - // The NULL node is the least node type. - if (n > m) { - return ascending ? -1 : 1; - } - return 0; -} - -int NAryExpressionNode::simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { - int m = numberOfChildren(); - if (m == 0) { - return -1; - } - /* Compare e to last term of hierarchy. */ - int order = SimplificationOrder(childAtIndex(m-1), e, ascending, canBeInterrupted, ignoreParentheses); - if (order != 0) { - return order; - } - if (m > 1) { - return ascending ? 1 : -1; - } - return 0; -} - void NAryExpression::mergeSameTypeChildrenInPlace() { // Multiplication is associative: a*(b*c)->a*b*c // The same goes for Addition diff --git a/poincare/src/n_ary_infix_expression.cpp b/poincare/src/n_ary_infix_expression.cpp new file mode 100644 index 000000000..0433c143a --- /dev/null +++ b/poincare/src/n_ary_infix_expression.cpp @@ -0,0 +1,57 @@ +#include +#include + +namespace Poincare { + +bool NAryInfixExpressionNode::childAtIndexNeedsUserParentheses(const Expression & child, int childIndex) const { + /* Expressions like "-2" require parentheses in Addition/Multiplication except + * when they are the first operand. */ + if (childIndex != 0 + && ((child.isNumber() && static_cast(child).sign() == Sign::Negative) + || child.type() == Type::Opposite)) + { + return true; + } + if (child.type() == Type::Conjugate) { + return childAtIndexNeedsUserParentheses(child.childAtIndex(0), childIndex); + } + return false; +} + +int NAryInfixExpressionNode::simplificationOrderSameType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { + int m = numberOfChildren(); + int n = e->numberOfChildren(); + for (int i = 1; i <= m; i++) { + // The NULL node is the least node type. + if (n < i) { + return 1; + } + int order = SimplificationOrder(childAtIndex(m-i), e->childAtIndex(n-i), ascending, canBeInterrupted, ignoreParentheses); + if (order != 0) { + return order; + } + } + // The NULL node is the least node type. + if (n > m) { + return ascending ? -1 : 1; + } + return 0; +} + +int NAryInfixExpressionNode::simplificationOrderGreaterType(const ExpressionNode * e, bool ascending, bool canBeInterrupted, bool ignoreParentheses) const { + int m = numberOfChildren(); + if (m == 0) { + return -1; + } + /* Compare e to last term of hierarchy. */ + int order = SimplificationOrder(childAtIndex(m-1), e, ascending, canBeInterrupted, ignoreParentheses); + if (order != 0) { + return order; + } + if (m > 1) { + return ascending ? 1 : -1; + } + return 0; +} + +} \ No newline at end of file