Poincare: Add a CommutativeOperation class

Change-Id: I420ff65050de513d7b7db94afed2e5bb9f044390
This commit is contained in:
Romain Goyet
2016-03-24 11:42:08 +01:00
parent 7f0a3f94bb
commit 3e5695de21
8 changed files with 73 additions and 62 deletions

View File

@@ -1,6 +1,7 @@
SFLAGS += -Ipoincare/include
objs += $(addprefix poincare/src/,\
addition.o\
commutative_operation.o\
context.o\
expression.o\
float.o\

View File

@@ -1,18 +1,14 @@
#ifndef POINCARE_ADDITION_H
#define POINCARE_ADDITION_H
#include <poincare/expression.h>
#include <poincare/commutative_operation.h>
class Addition : public Expression {
class Addition : public CommutativeOperation {
using CommutativeOperation::CommutativeOperation;
public:
Addition(Expression * first_operand, Expression * second_operand);
~Addition();
ExpressionLayout * createLayout(ExpressionLayout * parent) override;
float approximate(Context& context) override;
Type type() override;
private:
Expression * m_left;
Expression * m_right;
float operateApproximatevelyOn(float a, float b) override;
};
#endif

View File

@@ -0,0 +1,20 @@
#ifndef POINCARE_COMMUTATIVE_OPERATION_H
#define POINCARE_COMMUTATIVE_OPERATION_H
#include <poincare/expression.h>
class CommutativeOperation : public Expression {
public:
CommutativeOperation(Expression * first_operand, Expression * second_operand);
~CommutativeOperation();
Expression * operand(int i);
int numberOfOperands();
float approximate(Context& context) override;
protected:
virtual float operateApproximatevelyOn(float a, float b) = 0;
private:
int m_numberOfOperands;
Expression ** m_operands;
};
#endif

View File

@@ -1,21 +1,14 @@
#ifndef POINCARE_PRODUCT_H
#define POINCARE_PRODUCT_H
#include <poincare/expression.h>
#include <poincare/commutative_operation.h>
class Product : public Expression {
class Product : public CommutativeOperation {
using CommutativeOperation::CommutativeOperation;
public:
Product(Expression * first_factor, Expression * second_factor);
~Product();
ExpressionLayout * createLayout(ExpressionLayout * parent) override;
float approximate(Context& context) override;
Type type() override;
Expression * factor(int i);
int numberOfFactors();
private:
int m_numberOfFactors;
Expression ** m_factors;
float operateApproximatevelyOn(float a, float b) override;
};
#endif

View File

@@ -1,24 +1,15 @@
#include <poincare/addition.h>
#include "layout/horizontal_layout.h"
Addition::Addition(Expression * first_operand, Expression * second_operand) {
m_left = first_operand;
m_right = second_operand;
}
Expression::Type Addition::type() {
return Expression::Type::Addition;
}
Addition::~Addition() {
delete m_left;
delete m_right;
}
float Addition::approximate(Context& context) {
return m_left->approximate(context) + m_right->approximate(context);
float Addition::operateApproximatevelyOn(float a, float b) {
return a + b;
}
ExpressionLayout * Addition::createLayout(ExpressionLayout * parent) {
return new HorizontalLayout(parent, m_left, '+', m_right);
//FIXME: There can be more than two operands now! :-)
return new HorizontalLayout(parent, operand(0), '+', operand(1));
}

View File

@@ -0,0 +1,35 @@
#include <poincare/commutative_operation.h>
extern "C" {
#include <stdlib.h>
}
CommutativeOperation::CommutativeOperation(Expression * first_operand, Expression * second_operand) {
m_numberOfOperands = 2;
m_operands = (Expression **)malloc(2*sizeof(Expression *));
m_operands[0] = first_operand;
m_operands[1] = second_operand;
}
CommutativeOperation::~CommutativeOperation() {
for (int i=0; i<m_numberOfOperands; i++) {
delete m_operands[i];
}
free(m_operands);
}
int CommutativeOperation::numberOfOperands() {
return m_numberOfOperands;
}
Expression * CommutativeOperation::operand(int i) {
return m_operands[i];
}
float CommutativeOperation::approximate(Context& context) {
float result = m_operands[0]->approximate(context);
for (size_t i=1; i<m_numberOfOperands; i++) {
float next = m_operands[i]->approximate(context);
result = this->operateApproximatevelyOn(result, next);
}
return result;
}

View File

@@ -4,33 +4,8 @@ extern "C" {
#include <stdlib.h>
}
Product::Product(Expression * first_factor, Expression * second_factor) {
m_numberOfFactors = 2;
m_factors = (Expression **)malloc(2*sizeof(Expression *));
m_factors[0] = first_factor;
m_factors[1] = second_factor;
}
Product::~Product() {
for (int i=0; i<m_numberOfFactors; i++) {
delete m_factors[i];
}
}
float Product::approximate(Context& context) {
float result = m_factors[0]->approximate(context);
for (size_t i=1; i<m_numberOfFactors; i++) {
result *= m_factors[i]->approximate(context);
}
return result;
}
int Product::numberOfFactors() {
return m_numberOfFactors;
}
Expression * Product::factor(int i) {
return m_factors[i];
float Product::operateApproximatevelyOn(float a, float b) {
return a*b;
}
Expression::Type Product::type() {
@@ -39,5 +14,5 @@ Expression::Type Product::type() {
ExpressionLayout * Product::createLayout(ExpressionLayout * parent) {
//FIXME: There can be more than two factors now! :-)
return new HorizontalLayout(parent, m_factors[0], '*', m_factors[1]);
return new HorizontalLayout(parent, operand(0), '*', operand(1));
}

View File

@@ -7,8 +7,8 @@ Expression * SimplifyProductZero(Expression * e) {
return nullptr;
}
Product * p = (Product *)e;
for (int i=0; i<p->numberOfFactors(); i++) {
Expression * factor = p->factor(i);
for (int i=0; i<p->numberOfOperands(); i++) {
Expression * factor = p->operand(i);
if (factor->type() == Expression::Type::Integer) {
Integer * integer = (Integer *)factor;
if (*integer == Integer((native_int_t)0)) {