diff --git a/poincare/include/poincare/addition.h b/poincare/include/poincare/addition.h index 14e085b98..e9a210783 100644 --- a/poincare/include/poincare/addition.h +++ b/poincare/include/poincare/addition.h @@ -1,31 +1,23 @@ #ifndef POINCARE_ADDITION_H #define POINCARE_ADDITION_H -#include +#include #include #include -class Addition : public Expression { +class Addition : public BinaryOperation { + using BinaryOperation::BinaryOperation; public: - Addition(Expression ** operands, int numberOfOperands, bool cloneOperands = true); - ~Addition(); - const Expression * operand(int i) const override; - int numberOfOperands() const override; Type type() const override; - float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; - Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; - Expression * clone() const override; - Expression * cloneWithDifferentOperands(Expression** newOperands, - int numberOfOperands, bool cloneOperands = true) const override; ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override; + float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override; + Expression * cloneWithDifferentOperands(Expression** newOperands, + int numnerOfOperands, bool cloneOperands = true) const override; bool isCommutative() const override; private: - float operateApproximatevelyOn(float a, float b) const; - Expression * evaluateOn(Expression * a, Expression * b, Context& context, AngleUnit angleUnit) const; - Expression * evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context, AngleUnit angleUnit) const; - Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const; - const int m_numberOfOperands; - Expression ** m_operands; + Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context, AngleUnit angleUnit) const override; + Expression * evaluateOnFloatAndMatrix(Float * f, Matrix * m, Context& context, AngleUnit angleUnit) const override; + Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const override; }; #endif diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index 0d29442f6..419c38451 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -1,5 +1,4 @@ #include -#include extern "C" { #include #include @@ -8,113 +7,33 @@ extern "C" { #include "layout/string_layout.h" #include "layout/parenthesis_layout.h" -Addition::Addition(Expression ** operands, - int numberOfOperands, - bool cloneOperands) : m_numberOfOperands(numberOfOperands) { - assert(operands != nullptr); - assert(numberOfOperands >= 2); - m_operands = (Expression **)malloc(numberOfOperands*sizeof(Expression *)); - for (int i=0; iclone(); - } else { - m_operands[i] = operands[i]; - } - } -} - -Addition::~Addition() { - for (int i=0; i= 0); - assert(i < m_numberOfOperands); - return m_operands[i]; -} - Expression::Type Addition::type() const { return Type::Addition; } +ExpressionLayout * Addition::createLayout(DisplayMode displayMode) const { + ExpressionLayout** children_layouts = (ExpressionLayout **)malloc(3*sizeof(ExpressionLayout *)); + children_layouts[0] = m_operands[0]->createLayout(displayMode); + children_layouts[1] = new StringLayout("+", 1); + children_layouts[2] = m_operands[1]->type() == Type::Opposite ? new ParenthesisLayout(m_operands[1]->createLayout(displayMode)) : m_operands[1]->createLayout(displayMode); + return new HorizontalLayout(children_layouts, 3); +} + float Addition::approximate(Context& context, AngleUnit angleUnit) const { - float result = m_operands[0]->approximate(context, angleUnit); - for (int i=1; iapproximate(context, angleUnit); - result = this->operateApproximatevelyOn(result, next); - } - return result; -} - -Expression * Addition::evaluate(Context& context, AngleUnit angleUnit) const { - Expression * result = m_operands[0]->evaluate(context, angleUnit); - for (int i=1; ievaluate(context, angleUnit); - Expression * newResult = this->evaluateOn(result, next, context, angleUnit); - delete result; - result = newResult; - delete next; - } - assert(result == nullptr || result->type() == Type::Float || result->type() == Type::Matrix); - return result; -} - -Expression * Addition::clone() const { - return this->cloneWithDifferentOperands(m_operands, m_numberOfOperands, true); + return m_operands[0]->approximate(context, angleUnit)+m_operands[1]->approximate(context, angleUnit);; } Expression * Addition::cloneWithDifferentOperands(Expression** newOperands, int numberOfOperands, bool cloneOperands) const { - return new Addition(newOperands, numberOfOperands, cloneOperands); -} - -ExpressionLayout * Addition::createLayout(DisplayMode displayMode) const { - int number_of_children = 2*m_numberOfOperands-1; - ExpressionLayout** children_layouts = (ExpressionLayout **)malloc(number_of_children*sizeof(ExpressionLayout *)); - children_layouts[0] = m_operands[0]->createLayout(displayMode); - for (int i=1; itype() == Type::Opposite ? new ParenthesisLayout(m_operands[i]->createLayout(displayMode)) : m_operands[i]->createLayout(displayMode); - } - return new HorizontalLayout(children_layouts, number_of_children); + return new Addition(newOperands, cloneOperands); } bool Addition::isCommutative() const { return true; } -float Addition::operateApproximatevelyOn(float a, float b) const { - return a + b; -} - -Expression * Addition::evaluateOn(Expression * a, Expression * b, Context& context, AngleUnit angleUnit) const { - if (a == nullptr || b == nullptr) { - return nullptr; - } - assert(a->type() == Type::Float || a->type() == Type::Matrix); - assert(b->type() == Type::Float || b->type() == Type::Matrix); - Expression * result = nullptr; - if (a->type() == Type::Float && b->type() == Type::Float) { - result = new Float(a->approximate(context, angleUnit) + b->approximate(context, angleUnit)); - } - if (a->type() == Type::Float && b->type() == Type::Matrix) { - result = evaluateOnFloatAndMatrix((Float *)a, (Matrix *)b, context, angleUnit); - } - if (b->type() == Type::Float && a->type() == Type::Matrix) { - result = evaluateOnFloatAndMatrix((Float *)b, (Matrix *)a, context, angleUnit); - } - if (b->type() == Type::Matrix && a->type() == Type::Matrix) { - result = evaluateOnMatrices((Matrix *)a, (Matrix *)b, context, angleUnit); - } - return result; +Expression * Addition::evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context, AngleUnit angleUnit) const { + return evaluateOnFloatAndMatrix(f, m, context, angleUnit); } Expression * Addition::evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context, AngleUnit angleUnit) const { diff --git a/poincare/src/expression_parser.y b/poincare/src/expression_parser.y index beae77633..7f146435d 100644 --- a/poincare/src/expression_parser.y +++ b/poincare/src/expression_parser.y @@ -119,7 +119,7 @@ number: exp: number { $$ = $1; } | SYMBOL { $$ = new Symbol($1); } - | exp PLUS exp { Expression * terms[2] = {$1,$3}; $$ = new Addition(terms, 2, false); } + | exp PLUS exp { Expression * terms[2] = {$1,$3}; $$ = new Addition(terms, false); } | exp MINUS exp { Expression * terms[2] = {$1,$3}; $$ = new Subtraction(terms, false); } | exp MULTIPLY exp { Expression * terms[2] = {$1,$3}; $$ = new Multiplication(terms, false); } | exp DIVIDE exp { Expression * terms[2] = {$1,$3}; $$ = new Fraction(terms, false); } diff --git a/poincare/src/simplify/expression_builder.cpp b/poincare/src/simplify/expression_builder.cpp index da5cff6bc..59ae53db5 100644 --- a/poincare/src/simplify/expression_builder.cpp +++ b/poincare/src/simplify/expression_builder.cpp @@ -34,7 +34,7 @@ Expression * ExpressionBuilder::build(ExpressionMatch matches[]) { case Expression::Type::Addition: /* The children do not need to be cloned as they already have been * before. */ - result = new Addition(children_expressions, numberOfChildrenExpressions, false); + result = new Addition(children_expressions, false); break; case Expression::Type::Multiplication: /* The children do not need to be cloned as they already have been