From 2f7b1f4860e7b37f301b29153c2c50e6fc55519f Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Fri, 8 Apr 2016 15:29:08 +0200 Subject: [PATCH] Add the cloneWithNewOperands method. This allows to replace the operands of an expression with new ones. Change-Id: I3c2d183bbdbcc43b776f7ce2a302216c52e494bd --- poincare/Makefile | 4 ++-- poincare/include/poincare/addition.h | 3 ++- poincare/include/poincare/binary_operation.h | 1 + .../include/poincare/commutative_operation.h | 1 + poincare/include/poincare/cosine.h | 3 ++- poincare/include/poincare/expression.h | 2 ++ poincare/include/poincare/fraction.h | 3 ++- poincare/include/poincare/function.h | 5 +++-- poincare/include/poincare/leaf_expression.h | 2 ++ poincare/include/poincare/power.h | 3 ++- poincare/include/poincare/product.h | 3 ++- poincare/include/poincare/sine.h | 3 ++- poincare/include/poincare/subtraction.h | 3 ++- poincare/include/poincare/tangent.h | 3 ++- poincare/src/addition.cpp | 5 +++-- poincare/src/binary_operation.cpp | 4 ++++ poincare/src/commutative_operation.cpp | 6 +++++- poincare/src/cosine.cpp | 15 +++++++++++---- poincare/src/float.cpp | 4 ++-- poincare/src/fraction.cpp | 13 ++++++++++--- poincare/src/function.cpp | 14 ++++++++++---- poincare/src/leaf_expression.cpp | 6 ++++++ poincare/src/power.cpp | 16 +++++++++++----- poincare/src/product.cpp | 11 ++++++----- poincare/src/sine.cpp | 12 +++++++++--- poincare/src/subtraction.cpp | 9 +++++++-- poincare/src/tangent.cpp | 12 +++++++++--- ...ddition_integer.cpp => simplify_addition.cpp} | 0 .../test/{simplify.cpp => simplify_product.cpp} | 0 29 files changed, 120 insertions(+), 46 deletions(-) rename poincare/test/{simplify_addition_integer.cpp => simplify_addition.cpp} (100%) rename poincare/test/{simplify.cpp => simplify_product.cpp} (100%) diff --git a/poincare/Makefile b/poincare/Makefile index 3e95d26b0..6300d73fd 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -36,8 +36,8 @@ tests += $(addprefix poincare/test/,\ fraction.cpp\ integer.cpp\ product.cpp\ - simplify.cpp\ - simplify_addition_integer.cpp\ + simplify_addition.cpp\ + simplify_product.cpp\ trigo.cpp\ subtraction.cpp\ ) diff --git a/poincare/include/poincare/addition.h b/poincare/include/poincare/addition.h index 591c020b3..f9c771efa 100644 --- a/poincare/include/poincare/addition.h +++ b/poincare/include/poincare/addition.h @@ -8,7 +8,8 @@ class Addition : public CommutativeOperation { public: Type type() override; float operateApproximatevelyOn(float a, float b) override; - Expression * clone() override; + Expression * cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands = true) override; protected: char operatorChar() override; }; diff --git a/poincare/include/poincare/binary_operation.h b/poincare/include/poincare/binary_operation.h index 1e487ef7f..27994342b 100644 --- a/poincare/include/poincare/binary_operation.h +++ b/poincare/include/poincare/binary_operation.h @@ -9,6 +9,7 @@ class BinaryOperation : public Expression { ~BinaryOperation(); Expression * operand(int i) override; int numberOfOperands() override; + Expression * clone() override; protected: Expression * m_operands[2]; }; diff --git a/poincare/include/poincare/commutative_operation.h b/poincare/include/poincare/commutative_operation.h index d38a6103d..282eeca85 100644 --- a/poincare/include/poincare/commutative_operation.h +++ b/poincare/include/poincare/commutative_operation.h @@ -12,6 +12,7 @@ class CommutativeOperation : public Expression { float approximate(Context& context) override; ExpressionLayout * createLayout() override; bool isCommutative() override; + Expression * clone() override; protected: virtual float operateApproximatevelyOn(float a, float b) = 0; virtual char operatorChar() = 0; diff --git a/poincare/include/poincare/cosine.h b/poincare/include/poincare/cosine.h index 31f376375..54844d3c3 100644 --- a/poincare/include/poincare/cosine.h +++ b/poincare/include/poincare/cosine.h @@ -8,7 +8,8 @@ class Cosine : public Function { Cosine(Expression * arg, bool clone_arg=true): Function(arg, (char*) "cos", clone_arg) {} float approximate(Context& context) override; Type type() override; - Expression * clone() override; + Expression * cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands = true) override; }; #endif diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 9a08d7cf8..bfb12d9f7 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -28,6 +28,8 @@ class Expression { virtual Expression * operand(int i) = 0; virtual int numberOfOperands() = 0; virtual Expression * clone() = 0; + virtual Expression * cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands = true) = 0; // TODO: Consider std::unique_ptr - see https://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Ownership_and_Smart_Pointers diff --git a/poincare/include/poincare/fraction.h b/poincare/include/poincare/fraction.h index 23fbe9352..3f7e03d49 100644 --- a/poincare/include/poincare/fraction.h +++ b/poincare/include/poincare/fraction.h @@ -9,7 +9,8 @@ class Fraction : public BinaryOperation { ExpressionLayout * createLayout() override; float approximate(Context& context) override; Type type() override; - Expression * clone() override; + Expression * cloneWithDifferentOperands(Expression** newOperands, + int numnerOfOperands, bool cloneOperands = true) override; }; #endif diff --git a/poincare/include/poincare/function.h b/poincare/include/poincare/function.h index 576832d25..6259a2043 100644 --- a/poincare/include/poincare/function.h +++ b/poincare/include/poincare/function.h @@ -5,15 +5,16 @@ class Function : public Expression { public: - Function(Expression * arg, char* function_name, bool clone_operands=true); + Function(Expression * arg, char* functionName, bool cloneOperands=true); ~Function(); ExpressionLayout * createLayout() override; Expression * operand(int i) override; int numberOfOperands() override; + Expression * clone() override; protected: Expression * m_arg; private: - char* m_function_name; + char* m_functionName; }; #endif diff --git a/poincare/include/poincare/leaf_expression.h b/poincare/include/poincare/leaf_expression.h index 875a2046b..e1482c753 100644 --- a/poincare/include/poincare/leaf_expression.h +++ b/poincare/include/poincare/leaf_expression.h @@ -7,6 +7,8 @@ class LeafExpression : public Expression { public: Expression * operand(int i) override; int numberOfOperands() override; + Expression * cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands = true) override; }; #endif diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h index 4f567a1df..c360ffe8c 100644 --- a/poincare/include/poincare/power.h +++ b/poincare/include/poincare/power.h @@ -9,7 +9,8 @@ class Power : public BinaryOperation { ExpressionLayout * createLayout() override; float approximate(Context& context) override; Type type() override; - Expression * clone() override; + Expression * cloneWithDifferentOperands(Expression** newOperands, + int numnerOfOperands, bool cloneOperands = true) override; }; #endif diff --git a/poincare/include/poincare/product.h b/poincare/include/poincare/product.h index 4b4b50be1..5984187d2 100644 --- a/poincare/include/poincare/product.h +++ b/poincare/include/poincare/product.h @@ -8,7 +8,8 @@ class Product : public CommutativeOperation { public: Type type() override; float operateApproximatevelyOn(float a, float b) override; - Expression * clone() override; + Expression * cloneWithDifferentOperands(Expression** newOperands, + int numnerOfOperands, bool cloneOperands = true) override; protected: char operatorChar() override; }; diff --git a/poincare/include/poincare/sine.h b/poincare/include/poincare/sine.h index fe53563a0..f46039c14 100644 --- a/poincare/include/poincare/sine.h +++ b/poincare/include/poincare/sine.h @@ -8,7 +8,8 @@ class Sine : public Function { Sine(Expression * arg, bool clone_arg=true): Function(arg, (char*) "sin", clone_arg) {} float approximate(Context& context) override; Type type() override; - Expression * clone() override; + Expression * cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands = true) override; }; #endif diff --git a/poincare/include/poincare/subtraction.h b/poincare/include/poincare/subtraction.h index 5054bf390..1e0ebfa24 100644 --- a/poincare/include/poincare/subtraction.h +++ b/poincare/include/poincare/subtraction.h @@ -9,7 +9,8 @@ class Subtraction : public BinaryOperation { ExpressionLayout * createLayout() override; float approximate(Context& context) override; Type type() override; - Expression * clone() override; + Expression * cloneWithDifferentOperands(Expression** newOperands, + int numnerOfOperands, bool cloneOperands = true) override; }; #endif diff --git a/poincare/include/poincare/tangent.h b/poincare/include/poincare/tangent.h index 06ffbae06..a0b495f81 100644 --- a/poincare/include/poincare/tangent.h +++ b/poincare/include/poincare/tangent.h @@ -8,7 +8,8 @@ class Tangent : public Function { Tangent(Expression * arg, bool clone_arg=true): Function(arg, (char*) "tan", clone_arg) {} float approximate(Context& context) override; Type type() override; - Expression * clone() override; + Expression * cloneWithDifferentOperands(Expression** newOperands, + int numnerOfOperands, bool cloneOperands = true) override; }; #endif diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index 0783002dc..a9acd08a6 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -5,8 +5,9 @@ Expression::Type Addition::type() { return Expression::Type::Addition; } -Expression * Addition::clone() { - return new Addition(m_operands, m_numberOfOperands, true); +Expression * Addition::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) { + return new Addition(newOperands, numberOfOperands, cloneOperands); } float Addition::operateApproximatevelyOn(float a, float b) { diff --git a/poincare/src/binary_operation.cpp b/poincare/src/binary_operation.cpp index 05f396809..76b948c01 100644 --- a/poincare/src/binary_operation.cpp +++ b/poincare/src/binary_operation.cpp @@ -29,3 +29,7 @@ Expression * BinaryOperation::operand(int i) { assert(i>0 && i<=2); return m_operands[i]; } + +Expression * BinaryOperation::clone() { + return this->cloneWithDifferentOperands(m_operands, 2, true); +} diff --git a/poincare/src/commutative_operation.cpp b/poincare/src/commutative_operation.cpp index 8ce561859..514c8eb10 100644 --- a/poincare/src/commutative_operation.cpp +++ b/poincare/src/commutative_operation.cpp @@ -8,6 +8,7 @@ extern "C" { #include "layout/string_layout.h" CommutativeOperation::CommutativeOperation(Expression ** operands, int numberOfOperands, bool cloneOperands) { + assert(operands != nullptr); assert(numberOfOperands >= 2); m_numberOfOperands = numberOfOperands; m_operands = (Expression **)malloc(numberOfOperands*sizeof(Expression *)); @@ -37,6 +38,10 @@ Expression * CommutativeOperation::operand(int i) { return m_operands[i]; } +Expression * CommutativeOperation::clone() { + return this->cloneWithDifferentOperands(m_operands, m_numberOfOperands, true); +} + float CommutativeOperation::approximate(Context& context) { float result = m_operands[0]->approximate(context); for (size_t i=1; i +} + #include #include "layout/horizontal_layout.h" -Expression * Cosine::clone() { - return new Cosine(m_arg, true); -} - Expression::Type Cosine::type() { return Expression::Type::Cosine; } +Expression * Cosine::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) { + assert(numberOfOperands == 1); + assert(newOperands != nullptr); + return new Cosine(*newOperands, cloneOperands); +} + float Cosine::approximate(Context& context) { // FIXME: use cosine obviously. return m_arg->approximate(context); diff --git a/poincare/src/float.cpp b/poincare/src/float.cpp index 9fa6d7b73..cb102dc3c 100644 --- a/poincare/src/float.cpp +++ b/poincare/src/float.cpp @@ -1,7 +1,7 @@ -#include -#include extern "C" { #include +#include +#include } #include diff --git a/poincare/src/fraction.cpp b/poincare/src/fraction.cpp index 10893c814..4dc67c94f 100644 --- a/poincare/src/fraction.cpp +++ b/poincare/src/fraction.cpp @@ -1,9 +1,16 @@ -#include +extern "C" { +#include #include +} + +#include #include "layout/fraction_layout.h" -Expression * Fraction::clone() { - return new Fraction(m_operands, true); +Expression * Fraction::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) { + assert(numberOfOperands == 2); + assert(newOperands != nullptr); + return new Fraction(newOperands, cloneOperands); } ExpressionLayout * Fraction::createLayout() { diff --git a/poincare/src/function.cpp b/poincare/src/function.cpp index ab3bf0c47..a40c8f014 100644 --- a/poincare/src/function.cpp +++ b/poincare/src/function.cpp @@ -1,14 +1,16 @@ extern "C" { +#include #include } #include #include "layout/horizontal_layout.h" #include "layout/string_layout.h" -Function::Function(Expression * arg, char* function_name, bool clone_operands) { +Function::Function(Expression * arg, char* functionName, bool cloneOperands) { + assert(arg != nullptr); m_arg = (Expression *)malloc(sizeof(Expression)); - m_function_name = function_name; - if (clone_operands) { + m_functionName = functionName; + if (cloneOperands) { m_arg = arg->clone(); } else { m_arg = arg; @@ -19,9 +21,13 @@ Function::~Function() { delete m_arg; } +Expression * Function::clone() { + return this->cloneWithDifferentOperands(&m_arg, 1, true); +} + ExpressionLayout * Function::createLayout() { ExpressionLayout** children_layouts = (ExpressionLayout **)malloc(4*sizeof(ExpressionLayout *)); - children_layouts[0] = new StringLayout(m_function_name, strlen(m_function_name)); + children_layouts[0] = new StringLayout(m_functionName, strlen(m_functionName)); char string[2] = {'(', '\0'}; children_layouts[1] = new StringLayout(string, 1); children_layouts[2] = m_arg->createLayout(); diff --git a/poincare/src/leaf_expression.cpp b/poincare/src/leaf_expression.cpp index e397634b0..8d9a0eadc 100644 --- a/poincare/src/leaf_expression.cpp +++ b/poincare/src/leaf_expression.cpp @@ -12,3 +12,9 @@ Expression * LeafExpression::operand(int i) { assert(false); return nullptr; } + +Expression * LeafExpression::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) { + assert(false); + return nullptr; +} diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index 6eb6cb2f4..a5abf4389 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -1,11 +1,11 @@ -#include +extern "C" { +#include #include -#include "layout/exponent_layout.h" - -Expression * Power::clone() { - return new Power(m_operands, true); } +#include +#include "layout/exponent_layout.h" + float Power::approximate(Context& context) { return powf(m_operands[0]->approximate(context), m_operands[1]->approximate(context)); } @@ -14,6 +14,12 @@ Expression::Type Power::type() { return Expression::Type::Power; } +Expression * Power::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) { + assert(numberOfOperands == 2); + return new Power(newOperands, cloneOperands); +} + ExpressionLayout * Power::createLayout() { return new ExponentLayout(m_operands[0]->createLayout(), m_operands[1]->createLayout()); } diff --git a/poincare/src/product.cpp b/poincare/src/product.cpp index 7fefa4ca1..4556cf63e 100644 --- a/poincare/src/product.cpp +++ b/poincare/src/product.cpp @@ -1,11 +1,12 @@ -#include -#include "layout/horizontal_layout.h" extern "C" { -#include +#include } -Expression * Product::clone() { - return new Product(m_operands, m_numberOfOperands, true); +#include + +Expression * Product::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) { + return new Product(newOperands, numberOfOperands, cloneOperands); } float Product::operateApproximatevelyOn(float a, float b) { diff --git a/poincare/src/sine.cpp b/poincare/src/sine.cpp index fb3d7003c..57e2f3233 100644 --- a/poincare/src/sine.cpp +++ b/poincare/src/sine.cpp @@ -1,8 +1,14 @@ #include -#include "layout/horizontal_layout.h" -Expression * Sine::clone() { - return new Sine(m_arg, true); +extern "C" { +#include +} + +Expression * Sine::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) { + assert(newOperands != nullptr); + assert(numberOfOperands == 1); + return new Sine(*newOperands, cloneOperands); } Expression::Type Sine::type() { diff --git a/poincare/src/subtraction.cpp b/poincare/src/subtraction.cpp index ced5648c6..a57c67df6 100644 --- a/poincare/src/subtraction.cpp +++ b/poincare/src/subtraction.cpp @@ -1,12 +1,17 @@ extern "C" { +#include #include } + #include #include "layout/horizontal_layout.h" #include "layout/string_layout.h" -Expression * Subtraction::clone() { - return new Subtraction(m_operands, true); +Expression * Subtraction::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) { + assert(newOperands != nullptr); + assert(numberOfOperands == 2); + return new Subtraction(newOperands, cloneOperands); } float Subtraction::approximate(Context& context) { diff --git a/poincare/src/tangent.cpp b/poincare/src/tangent.cpp index 6eb92af4c..482684ba5 100644 --- a/poincare/src/tangent.cpp +++ b/poincare/src/tangent.cpp @@ -1,8 +1,14 @@ #include -#include "layout/horizontal_layout.h" -Expression * Tangent::clone() { - return new Tangent(m_arg, true); +extern "C" { +#include +} + +Expression * Tangent::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) { + assert(newOperands != nullptr); + assert(numberOfOperands == 1); + return new Tangent(*newOperands, cloneOperands); } Expression::Type Tangent::type() { diff --git a/poincare/test/simplify_addition_integer.cpp b/poincare/test/simplify_addition.cpp similarity index 100% rename from poincare/test/simplify_addition_integer.cpp rename to poincare/test/simplify_addition.cpp diff --git a/poincare/test/simplify.cpp b/poincare/test/simplify_product.cpp similarity index 100% rename from poincare/test/simplify.cpp rename to poincare/test/simplify_product.cpp