mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-24 00:00:44 +01:00
[poincare] Create a class opposite
Change-Id: Ib903a31d7ba76cd76b95464f701ea2605ff7392d
This commit is contained in:
@@ -23,6 +23,7 @@ objs += $(addprefix poincare/src/,\
|
||||
matrix.o\
|
||||
matrix_data.o\
|
||||
nth_root.o\
|
||||
opposite.o\
|
||||
parenthesis.o\
|
||||
power.o\
|
||||
product.o\
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <poincare/matrix.h>
|
||||
#include <poincare/matrix_data.h>
|
||||
#include <poincare/nth_root.h>
|
||||
#include <poincare/opposite.h>
|
||||
#include <poincare/parenthesis.h>
|
||||
#include <poincare/power.h>
|
||||
#include <poincare/product.h>
|
||||
|
||||
@@ -19,6 +19,7 @@ class Expression {
|
||||
Logarithm,
|
||||
Matrix,
|
||||
NthRoot,
|
||||
Opposite,
|
||||
Fraction,
|
||||
Parenthesis,
|
||||
Power,
|
||||
|
||||
26
poincare/include/poincare/opposite.h
Normal file
26
poincare/include/poincare/opposite.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef POINCARE_OPPOSITE_H
|
||||
#define POINCARE_OPPOSITE_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/matrix.h>
|
||||
#include <poincare/float.h>
|
||||
|
||||
class Opposite : public Expression {
|
||||
public:
|
||||
Opposite(Expression * operand, bool cloneOperands = true);
|
||||
~Opposite();
|
||||
const Expression * operand(int i) const override;
|
||||
int numberOfOperands() const override;
|
||||
Expression * clone() const override;
|
||||
Expression * evaluate(Context& context) const override;
|
||||
ExpressionLayout * createLayout() const override;
|
||||
float approximate(Context& context) const override;
|
||||
Type type() const override;
|
||||
Expression * cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numnerOfOperands, bool cloneOperands = true) const override;
|
||||
protected:
|
||||
Expression * m_operand;
|
||||
Expression * evaluateOnMatrix(Matrix * m, Context& context) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -112,13 +112,9 @@ mtxData:
|
||||
|
||||
number:
|
||||
DIGITS { $$ = new Integer($1.address, false); }
|
||||
| MINUS DIGITS { $$ = new Integer($2.address, true); }
|
||||
| DIGITS DOT DIGITS { $$ = new Float($1.address, $1.length, false, $3.address, $3.length, nullptr, 0, false); }
|
||||
| MINUS DIGITS DOT DIGITS { $$ = new Float($2.address, $2.length, true, $4.address, $4.length, nullptr, 0, false); }
|
||||
| DIGITS DOT DIGITS EE DIGITS { $$ = new Float($1.address, $1.length, false, $3.address, $3.length, $5.address, $5.length, false); }
|
||||
| MINUS DIGITS DOT DIGITS EE DIGITS { $$ = new Float($2.address, $2.length, true, $4.address, $4.length, $6.address, $6.length, false); }
|
||||
| DIGITS DOT DIGITS EE MINUS DIGITS { $$ = new Float($1.address, $1.length, false, $3.address, $3.length, $6.address, $6.length, true); }
|
||||
| MINUS DIGITS DOT DIGITS EE MINUS DIGITS { $$ = new Float($2.address, $2.length, true, $4.address, $4.length, $7.address, $7.length, true); }
|
||||
|
||||
exp:
|
||||
number { $$ = $1; }
|
||||
@@ -128,6 +124,7 @@ exp:
|
||||
| exp MULTIPLY exp { Expression * terms[2] = {$1,$3}; $$ = new Product(terms, 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); }
|
||||
| MINUS exp { $$ = new Opposite($2, false); }
|
||||
| LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = new Parenthesis($2, false); }
|
||||
| LEFT_BRACKET mtxData RIGHT_BRACKET { $$ = new Matrix($2); }
|
||||
| FUNCTION LEFT_PARENTHESIS lstData RIGHT_PARENTHESIS { $$ = $1; $1->setArgument($3, false);}
|
||||
|
||||
80
poincare/src/opposite.cpp
Normal file
80
poincare/src/opposite.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
#include <poincare/opposite.h>
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
}
|
||||
#include "layout/horizontal_layout.h"
|
||||
#include "layout/string_layout.h"
|
||||
|
||||
Opposite::Opposite(Expression * operand, bool cloneOperands) {
|
||||
assert(operand != nullptr);
|
||||
if (cloneOperands) {
|
||||
m_operand = operand->clone();
|
||||
} else {
|
||||
m_operand = operand;
|
||||
}
|
||||
}
|
||||
|
||||
Opposite::~Opposite() {
|
||||
delete m_operand;
|
||||
}
|
||||
|
||||
const Expression * Opposite::operand(int i) const {
|
||||
assert(i == 0);
|
||||
return m_operand;
|
||||
}
|
||||
|
||||
int Opposite::numberOfOperands() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Expression * Opposite::clone() const {
|
||||
return this->cloneWithDifferentOperands((Expression**)&m_operand, 1, true);
|
||||
}
|
||||
|
||||
Expression * Opposite::evaluate(Context& context) const {
|
||||
Expression * operandEvalutation = m_operand->evaluate(context);
|
||||
if (operandEvalutation == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
Expression * result = nullptr;
|
||||
if (operandEvalutation->type() == Type::Float) {
|
||||
result = new Float(this->approximate(context));
|
||||
}
|
||||
if (operandEvalutation->type() == Type::Matrix) {
|
||||
result = evaluateOnMatrix((Matrix *)operandEvalutation, context);
|
||||
}
|
||||
delete operandEvalutation;
|
||||
return result;
|
||||
}
|
||||
|
||||
ExpressionLayout * Opposite::createLayout() const {
|
||||
ExpressionLayout** children_layouts = (ExpressionLayout **)malloc(2*sizeof(ExpressionLayout *));
|
||||
char string[2] = {'-', '\0'};
|
||||
children_layouts[0] = new StringLayout(string, 1);
|
||||
children_layouts[1] = m_operand->createLayout();
|
||||
return new HorizontalLayout(children_layouts, 2);
|
||||
}
|
||||
|
||||
float Opposite::approximate(Context& context) const {
|
||||
return -m_operand->approximate(context);
|
||||
}
|
||||
|
||||
Expression::Type Opposite::type() const {
|
||||
return Expression::Type::Opposite;
|
||||
}
|
||||
|
||||
Expression * Opposite::cloneWithDifferentOperands(Expression** newOperands,
|
||||
int numberOfOperands, bool cloneOperands) const {
|
||||
assert(newOperands != nullptr);
|
||||
assert(numberOfOperands == 1);
|
||||
return new Opposite(newOperands[0], cloneOperands);
|
||||
}
|
||||
|
||||
Expression * Opposite::evaluateOnMatrix(Matrix * m, Context& context) const {
|
||||
Expression * operands[m->numberOfRows() * m->numberOfColumns()];
|
||||
for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) {
|
||||
operands[i] = new Float(- m->operand(i)->approximate(context));
|
||||
}
|
||||
return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
|
||||
}
|
||||
Reference in New Issue
Block a user