diff --git a/poincare/include/poincare/binary_operation.h b/poincare/include/poincare/binary_operation.h new file mode 100644 index 000000000..1e487ef7f --- /dev/null +++ b/poincare/include/poincare/binary_operation.h @@ -0,0 +1,16 @@ +#ifndef POINCARE_BINARY_OPERATION_H +#define POINCARE_BINARY_OPERATION_H + +#include + +class BinaryOperation : public Expression { + public: + BinaryOperation(Expression ** operands, bool cloneOperands = true); + ~BinaryOperation(); + Expression * operand(int i) override; + int numberOfOperands() override; + protected: + Expression * m_operands[2]; +}; + +#endif diff --git a/poincare/include/poincare/fraction.h b/poincare/include/poincare/fraction.h index b1e0690f5..20c602908 100644 --- a/poincare/include/poincare/fraction.h +++ b/poincare/include/poincare/fraction.h @@ -1,19 +1,15 @@ #ifndef POINCARE_FRACTION_H #define POINCARE_FRACTION_H -#include +#include -class Fraction : public Expression { +class Fraction : public BinaryOperation { + using BinaryOperation::BinaryOperation; public: - Fraction(Expression * numerator, Expression * denominator); - ~Fraction(); ExpressionLayout * createLayout(ExpressionLayout * parent) override; float approximate(Context& context) override; Type type() override; Expression * clone() override; - private: - Expression * m_numerator; - Expression * m_denominator; }; #endif diff --git a/poincare/include/poincare/leaf_expression.h b/poincare/include/poincare/leaf_expression.h new file mode 100644 index 000000000..875a2046b --- /dev/null +++ b/poincare/include/poincare/leaf_expression.h @@ -0,0 +1,12 @@ +#ifndef POINCARE_LEAF_EXPRESSION_H +#define POINCARE_LEAF_EXPRESSION_H + +#include + +class LeafExpression : public Expression { + public: + Expression * operand(int i) override; + int numberOfOperands() override; +}; + +#endif diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h index d630bf7aa..0c91f2ccd 100644 --- a/poincare/include/poincare/power.h +++ b/poincare/include/poincare/power.h @@ -1,19 +1,15 @@ #ifndef POINCARE_POWER_H #define POINCARE_POWER_H -#include +#include -class Power : public Expression { +class Power : public BinaryOperation { + using BinaryOperation::BinaryOperation; public: - Power(Expression * base, Expression * exponent); - ~Power(); ExpressionLayout * createLayout(ExpressionLayout * parent) override; float approximate(Context& context) override; Type type() override; Expression * clone() override; - private: - Expression * m_base; - Expression * m_exponent; }; #endif diff --git a/poincare/include/poincare/subtraction.h b/poincare/include/poincare/subtraction.h index 79a394c93..7dac515d3 100644 --- a/poincare/include/poincare/subtraction.h +++ b/poincare/include/poincare/subtraction.h @@ -1,19 +1,15 @@ #ifndef POINCARE_SUBSTRACTION_H #define POINCARE_SUBSTRACTION_H -#include +#include -class Subtraction : public Expression { +class Subtraction : public BinaryOperation { + using BinaryOperation::BinaryOperation; public: - Subtraction(Expression * first_operand, Expression * second_operand); - ~Subtraction(); ExpressionLayout * createLayout(ExpressionLayout * parent) override; float approximate(Context& context) override; Type type() override; Expression * clone() override; - private: - Expression * m_left; - Expression * m_right; }; #endif diff --git a/poincare/src/binary_operation.cpp b/poincare/src/binary_operation.cpp new file mode 100644 index 000000000..05f396809 --- /dev/null +++ b/poincare/src/binary_operation.cpp @@ -0,0 +1,31 @@ +#include +extern "C" { +#include +} + +BinaryOperation::BinaryOperation(Expression ** operands, bool cloneOperands) { + assert(operands != nullptr); + assert(operands[0] != nullptr); + assert(operands[1] != nullptr); + if (cloneOperands) { + m_operands[0] = operands[0]->clone(); + m_operands[1] = operands[1]->clone(); + } else { + m_operands[0] = operands[0]; + m_operands[1] = operands[1]; + } +} + +BinaryOperation::~BinaryOperation() { + delete m_operands[1]; + delete m_operands[0]; +} + +int BinaryOperation::numberOfOperands() { + return 2; +} + +Expression * BinaryOperation::operand(int i) { + assert(i>0 && i<=2); + return m_operands[i]; +} diff --git a/poincare/src/expression_parser.y b/poincare/src/expression_parser.y index 67c24f403..505f1505b 100644 --- a/poincare/src/expression_parser.y +++ b/poincare/src/expression_parser.y @@ -79,11 +79,11 @@ Root: exp: INTEGER { $$ = new Integer($1); } | SYMBOL { $$ = new Symbol($1); } - | exp PLUS exp { Expression * terms[2] = {$1,$3}; $$ = new Addition(terms, 2, true); } - | exp MINUS exp { $$ = new Subtraction($1,$3); } - | exp MULTIPLY exp { Expression * terms[2] = {$1,$3}; $$ = new Product(terms, 2, true); } - | exp DIVIDE exp { $$ = new Fraction($1,$3); } - | exp POW exp { $$ = new Power($1,$3); } + | exp PLUS exp { Expression * terms[2] = {$1,$3}; $$ = new Addition(terms, 2, false); } + | exp MINUS exp { Expression * terms[2] = {$1,$3}; $$ = new Subtraction(terms, false); } + | exp MULTIPLY exp { Expression * terms[2] = {$1,$3}; $$ = new Product(terms, 2, false); } + | exp DIVIDE exp { Expression * terms[2] = {$1,$3}; $$ = new Fraction(terms, false); } + | exp POW exp { Expression * terms[2] = {$1,$3}; $$ = new Power(terms, false); } | LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = $2; } ; diff --git a/poincare/src/fraction.cpp b/poincare/src/fraction.cpp index 7f39bdc1b..a5172bc3a 100644 --- a/poincare/src/fraction.cpp +++ b/poincare/src/fraction.cpp @@ -2,27 +2,17 @@ #include #include "layout/fraction_layout.h" -Fraction::Fraction(Expression * numerator, Expression * denominator) : - m_numerator(numerator), - m_denominator(denominator) { -} - -Fraction::~Fraction() { - delete m_denominator; - delete m_numerator; -} - Expression * Fraction::clone() { - return new Fraction(m_numerator->clone(), m_denominator->clone()); + return new Fraction(m_operands, true); } ExpressionLayout * Fraction::createLayout(ExpressionLayout * parent) { - return new FractionLayout(parent, m_numerator, m_denominator); + return new FractionLayout(parent, m_operands[0], m_operands[1]); } float Fraction::approximate(Context& context) { // TODO: handle division by zero - return m_numerator->approximate(context)/m_denominator->approximate(context); + return m_operands[0]->approximate(context)/m_operands[1]->approximate(context); } Expression::Type Fraction::type() { diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index 1a9d5c852..d9c53835d 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -2,22 +2,12 @@ #include #include "layout/exponent_layout.h" -Power::Power(Expression * base, Expression * exponent) : - m_base(base), - m_exponent(exponent) { -} - -Power::~Power() { - delete m_exponent; - delete m_base; -} - Expression * Power::clone() { - return new Power(m_base->clone(), m_exponent->clone()); + return new Power(m_operands, true); } float Power::approximate(Context& context) { - return powf(m_base->approximate(context), m_exponent->approximate(context)); + return powf(m_operands[0]->approximate(context), m_operands[1]->approximate(context)); } Expression::Type Power::type() { @@ -25,5 +15,5 @@ Expression::Type Power::type() { } ExpressionLayout * Power::createLayout(ExpressionLayout * parent) { - return new ExponentLayout(parent, m_base, m_exponent); + return new ExponentLayout(parent, m_operands[0], m_operands[1]); } diff --git a/poincare/src/subtraction.cpp b/poincare/src/subtraction.cpp index 02c46f821..7f82f02db 100644 --- a/poincare/src/subtraction.cpp +++ b/poincare/src/subtraction.cpp @@ -1,22 +1,12 @@ #include #include "layout/horizontal_layout.h" -Subtraction::Subtraction(Expression * first_operand, Expression * second_operand) { - m_left = first_operand; - m_right = second_operand; -} - -Subtraction::~Subtraction() { - delete m_left; - delete m_right; -} - Expression * Subtraction::clone() { - return new Subtraction(m_left->clone(), m_right->clone()); + return new Subtraction(m_operands, true); } float Subtraction::approximate(Context& context) { - return m_left->approximate(context) - m_right->approximate(context); + return m_operands[0]->approximate(context) - m_operands[1]->approximate(context); } Expression::Type Subtraction::type() { @@ -24,5 +14,5 @@ Expression::Type Subtraction::type() { } ExpressionLayout * Subtraction::createLayout(ExpressionLayout * parent) { - return new HorizontalLayout(parent, m_left, '-', m_right); + return new HorizontalLayout(parent, m_operands[0], '-', m_operands[1]); }