Merge branch 'master' of ssh://git.numworks.com:29418/CalcOS

Change-Id: I3e9fb6c960d26eebbfa4a28a4e0dfa0a2153e9f4
This commit is contained in:
Romain Goyet
2016-03-28 15:53:27 +02:00
35 changed files with 111 additions and 168 deletions

View File

@@ -66,7 +66,7 @@ static void interactive_expression_parsing() {
clear_screen();
Expression * e = Expression::parse(text_input);
if (e) {
ExpressionLayout * l = e->createLayout(nullptr);
ExpressionLayout * l = e->createLayout();
if (l) {
l->draw(KDPointMake(0,10));
delete l;

View File

@@ -24,7 +24,6 @@ objs += $(addprefix poincare/src/layout/,\
exponent_layout.o\
expression_layout.o\
fraction_layout.o\
function_layout.o\
horizontal_layout.o\
string_layout.o\
)

View File

@@ -6,10 +6,11 @@
class Addition : public CommutativeOperation {
using CommutativeOperation::CommutativeOperation;
public:
ExpressionLayout * createLayout(ExpressionLayout * parent) override;
Type type() override;
float operateApproximatevelyOn(float a, float b) override;
Expression * clone() override;
protected:
char operatorChar() override;
};
#endif

View File

@@ -10,8 +10,10 @@ class CommutativeOperation : public Expression {
Expression * operand(int i) override;
int numberOfOperands() override;
float approximate(Context& context) override;
ExpressionLayout * createLayout() override;
protected:
virtual float operateApproximatevelyOn(float a, float b) = 0;
virtual char operatorChar() = 0;
int m_numberOfOperands;
Expression ** m_operands;
};

View File

@@ -24,7 +24,7 @@ class Expression {
static Expression * parse(char const * string);
virtual ~Expression();
virtual ExpressionLayout * createLayout(ExpressionLayout * parent) = 0; // Returned object must be deleted
virtual ExpressionLayout * createLayout() = 0; // Returned object must be deleted
virtual Expression * operand(int i) = 0;
virtual int numberOfOperands() = 0;
virtual Expression * clone() = 0;

View File

@@ -7,12 +7,13 @@ extern "C" {
class ExpressionLayout {
public:
ExpressionLayout(ExpressionLayout * parent);
ExpressionLayout();
virtual ~ExpressionLayout();
void draw(KDPoint point);
KDPoint origin();
KDSize size();
void setParent(ExpressionLayout* parent);
protected:
virtual void render(KDPoint point) = 0;
virtual KDSize computeSize() = 0;
@@ -21,7 +22,7 @@ class ExpressionLayout {
private:
KDPoint absoluteOrigin();
//void computeLayout();//ExpressionLayout * parent, uint16_t childIndex);
ExpressionLayout * m_parent;
ExpressionLayout* m_parent;
bool m_sized, m_positioned;
KDRect m_frame;
};

View File

@@ -8,7 +8,7 @@ class Float : public LeafExpression {
Float(float f);
~Float();
ExpressionLayout * createLayout(ExpressionLayout * parent) override;
ExpressionLayout * createLayout() override;
float approximate(Context& context) override;
Type type() override;
Expression * clone() override;

View File

@@ -6,7 +6,7 @@
class Fraction : public BinaryOperation {
using BinaryOperation::BinaryOperation;
public:
ExpressionLayout * createLayout(ExpressionLayout * parent) override;
ExpressionLayout * createLayout() override;
float approximate(Context& context) override;
Type type() override;
Expression * clone() override;

View File

@@ -7,7 +7,7 @@ class Function : public Expression {
public:
Function(Expression * arg, char* function_name, bool clone_operands=true);
~Function();
ExpressionLayout * createLayout(ExpressionLayout * parent) override;
ExpressionLayout * createLayout() override;
Expression * operand(int i) override;
int numberOfOperands() override;
protected:

View File

@@ -34,7 +34,7 @@ class Integer : public LeafExpression {
virtual bool identicalTo(Expression * e);
*/
Expression * clone() override;
virtual ExpressionLayout * createLayout(ExpressionLayout * parent) override;
virtual ExpressionLayout * createLayout() override;
float approximate(Context& context) override;
private:
int8_t ucmp(const Integer &other) const; // -1, 0, or 1

View File

@@ -6,7 +6,7 @@
class Power : public BinaryOperation {
using BinaryOperation::BinaryOperation;
public:
ExpressionLayout * createLayout(ExpressionLayout * parent) override;
ExpressionLayout * createLayout() override;
float approximate(Context& context) override;
Type type() override;
Expression * clone() override;

View File

@@ -6,10 +6,11 @@
class Product : public CommutativeOperation {
using CommutativeOperation::CommutativeOperation;
public:
ExpressionLayout * createLayout(ExpressionLayout * parent) override;
Type type() override;
float operateApproximatevelyOn(float a, float b) override;
Expression * clone() override;
protected:
char operatorChar() override;
};
#endif

View File

@@ -6,7 +6,7 @@
class Subtraction : public BinaryOperation {
using BinaryOperation::BinaryOperation;
public:
ExpressionLayout * createLayout(ExpressionLayout * parent) override;
ExpressionLayout * createLayout() override;
float approximate(Context& context) override;
Type type() override;
Expression * clone() override;

View File

@@ -7,7 +7,7 @@ class Symbol : public LeafExpression {
public:
Symbol(char * name);
~Symbol();
ExpressionLayout * createLayout(ExpressionLayout * parent) override;
ExpressionLayout * createLayout() override;
float approximate(Context& context) override;
Type type() override;
Expression * clone() override;

View File

@@ -13,6 +13,6 @@ float Addition::operateApproximatevelyOn(float a, float b) {
return a + b;
}
ExpressionLayout * Addition::createLayout(ExpressionLayout * parent) {
return new HorizontalLayout(parent, m_operands, m_numberOfOperands, '+');
char Addition::operatorChar() {
return '+';
}

View File

@@ -4,6 +4,9 @@ extern "C" {
#include <stdlib.h>
}
#include "layout/horizontal_layout.h"
#include "layout/string_layout.h"
CommutativeOperation::CommutativeOperation(Expression ** operands, int numberOfOperands, bool cloneOperands) {
assert(numberOfOperands >= 2);
m_numberOfOperands = numberOfOperands;
@@ -42,3 +45,15 @@ float CommutativeOperation::approximate(Context& context) {
}
return result;
}
ExpressionLayout * CommutativeOperation::createLayout() {
int number_of_children = 2*m_numberOfOperands-1;
ExpressionLayout** children_layouts = (ExpressionLayout **)malloc(number_of_children*sizeof(ExpressionLayout *));
char string[2] = {operatorChar(), '\0'};
children_layouts[0] = m_operands[0]->createLayout();
for (int i=1; i<m_numberOfOperands; i++) {
children_layouts[2*i-1] = new StringLayout(string, 1);
children_layouts[2*i] = m_operands[i]->createLayout();
}
return new HorizontalLayout(children_layouts, number_of_children);
}

View File

@@ -21,7 +21,7 @@ Expression::Type Float::type() {
return Expression::Type::Float;
}
ExpressionLayout * Float::createLayout(ExpressionLayout * parent) {
ExpressionLayout * Float::createLayout() {
assert(0); // Should not come here, ever...
return nullptr;
}

View File

@@ -6,8 +6,8 @@ Expression * Fraction::clone() {
return new Fraction(m_operands, true);
}
ExpressionLayout * Fraction::createLayout(ExpressionLayout * parent) {
return new FractionLayout(parent, m_operands[0], m_operands[1]);
ExpressionLayout * Fraction::createLayout() {
return new FractionLayout(m_operands[0]->createLayout(), m_operands[1]->createLayout());
}
float Fraction::approximate(Context& context) {

View File

@@ -2,7 +2,8 @@ extern "C" {
#include <stdlib.h>
}
#include <poincare/function.h>
#include "layout/function_layout.h"
#include "layout/horizontal_layout.h"
#include "layout/string_layout.h"
Function::Function(Expression * arg, char* function_name, bool clone_operands) {
m_arg = (Expression *)malloc(sizeof(Expression));
@@ -18,8 +19,15 @@ Function::~Function() {
delete m_arg;
}
ExpressionLayout * Function::createLayout(ExpressionLayout * parent) {
return new FunctionLayout(parent, m_function_name, m_arg);
ExpressionLayout * Function::createLayout() {
ExpressionLayout** children_layouts = (ExpressionLayout **)malloc(4*sizeof(ExpressionLayout *));
children_layouts[0] = new StringLayout(m_function_name, strlen(m_function_name));
char string[2] = {'-', '\0'};
children_layouts[1] = new StringLayout(string, 1);
children_layouts[2] = m_arg->createLayout();
string[0] = ')';
children_layouts[3] = new StringLayout(string, 1);
return new HorizontalLayout(children_layouts, 4);
}
Expression * Function::operand(int i) {

View File

@@ -268,7 +268,7 @@ Expression * Integer::clone() {
clone->m_negative = m_negative;
free(clone->m_digits);
clone->m_digits = (native_uint_t *)malloc(m_numberOfDigits*sizeof(native_uint_t));
for (int i=0;i<m_numberOfDigits; i++) {
for (unsigned int i=0;i<m_numberOfDigits; i++) {
clone->m_digits[i] = m_digits[i];
}
return clone;
@@ -320,7 +320,7 @@ Expression::Type Integer::type() {
return Expression::Type::Integer;
}
ExpressionLayout * Integer::createLayout(ExpressionLayout * parent) {
ExpressionLayout * Integer::createLayout() {
char buffer[255];
Integer base = Integer(10);
@@ -341,7 +341,7 @@ ExpressionLayout * Integer::createLayout(ExpressionLayout * parent) {
buffer[j] = c;
}
return new StringLayout(parent, buffer, size);
return new StringLayout(buffer, size);
}
bool Integer::valueEquals(Expression * e) {

View File

@@ -5,10 +5,10 @@
// TODO(fraimundo): Find a better name.
#define EXPONENT_HEIGHT 5
ExponentLayout::ExponentLayout(ExpressionLayout * parent, Expression * base, Expression * exponent) :
ExpressionLayout(parent) {
m_base_layout = base->createLayout(this);
m_exponent_layout = exponent->createLayout(this);
ExponentLayout::ExponentLayout(ExpressionLayout * base_layout, ExpressionLayout * exponent_layout) :
ExpressionLayout(), m_base_layout(base_layout), m_exponent_layout(exponent_layout) {
m_base_layout->setParent(this);
m_exponent_layout->setParent(this);
}
ExponentLayout::~ExponentLayout() {

View File

@@ -6,7 +6,7 @@
class ExponentLayout : public ExpressionLayout {
public:
ExponentLayout(ExpressionLayout * parent, Expression * base, Expression * exponent);
ExponentLayout(ExpressionLayout * base_layout, ExpressionLayout * exponent_layout);
~ExponentLayout();
protected:
void render(KDPoint point) override;

View File

@@ -2,8 +2,8 @@
#include <stdlib.h>
#include "string_layout.h"
ExpressionLayout::ExpressionLayout(ExpressionLayout * parent) :
m_parent(parent),
ExpressionLayout::ExpressionLayout() :
m_parent(nullptr),
m_sized(false),
m_positioned(false),
m_frame(KDRectZero) {
@@ -52,3 +52,7 @@ KDSize ExpressionLayout::size() {
}
return m_frame.size;
}
void ExpressionLayout::setParent(ExpressionLayout* parent) {
m_parent = parent;
}

View File

@@ -10,19 +10,19 @@ static inline KDCoordinate max(KDCoordinate a, KDCoordinate b) {
#define FRACTION_LINE_MARGIN 2
#define FRACTION_LINE_HEIGHT 1
FractionLayout::FractionLayout(ExpressionLayout * parent, Expression * numerator, Expression * denominator) :
ExpressionLayout(parent) {
m_numerator = numerator->createLayout(this);
m_denominator = denominator->createLayout(this);
FractionLayout::FractionLayout(ExpressionLayout * numerator_layout, ExpressionLayout * denominator_layout) :
ExpressionLayout(), m_numerator_layout(numerator_layout), m_denominator_layout(denominator_layout) {
m_numerator_layout->setParent(this);
m_denominator_layout->setParent(this);
}
FractionLayout::~FractionLayout() {
delete m_denominator;
delete m_numerator;
delete m_denominator_layout;
delete m_numerator_layout;
}
void FractionLayout::render(KDPoint point) {
KDCoordinate fractionLineY = point.y + m_numerator->size().height + FRACTION_LINE_MARGIN;
KDCoordinate fractionLineY = point.y + m_numerator_layout->size().height + FRACTION_LINE_MARGIN;
KDDrawLine(
KDPointMake(point.x, fractionLineY),
@@ -32,17 +32,18 @@ void FractionLayout::render(KDPoint point) {
KDSize FractionLayout::computeSize() {
KDSize s;
s.width = max(m_numerator->size().width, m_denominator->size().width) + 2*FRACTION_BORDER_LENGTH;
s.height = m_numerator->size().height + FRACTION_LINE_MARGIN + FRACTION_LINE_HEIGHT + FRACTION_LINE_MARGIN + m_denominator->size().height;
s.width = max(m_numerator_layout->size().width, m_denominator_layout->size().width) + 2*FRACTION_BORDER_LENGTH;
s.height = m_numerator_layout->size().height + FRACTION_LINE_MARGIN
+ FRACTION_LINE_HEIGHT + FRACTION_LINE_MARGIN + m_denominator_layout->size().height;
return s;
}
ExpressionLayout * FractionLayout::child(uint16_t index) {
switch (index) {
case 0:
return m_numerator;
return m_numerator_layout;
case 1:
return m_denominator;
return m_denominator_layout;
default:
return nullptr;
}
@@ -50,12 +51,12 @@ ExpressionLayout * FractionLayout::child(uint16_t index) {
KDPoint FractionLayout::positionOfChild(ExpressionLayout * child) {
KDPoint p;
if (child == m_numerator) {
p.x = (KDCoordinate)((size().width - m_numerator->size().width)/2);
if (child == m_numerator_layout) {
p.x = (KDCoordinate)((size().width - m_numerator_layout->size().width)/2);
p.y = 0;
} else if (child == m_denominator) {
p.x = (KDCoordinate)((size().width - m_denominator->size().width)/2);
p.y = (KDCoordinate)(m_numerator->size().height + 2*FRACTION_LINE_MARGIN + FRACTION_LINE_HEIGHT);
} else if (child == m_denominator_layout) {
p.x = (KDCoordinate)((size().width - m_denominator_layout->size().width)/2);
p.y = (KDCoordinate)(m_numerator_layout->size().height + 2*FRACTION_LINE_MARGIN + FRACTION_LINE_HEIGHT);
} else {
assert(false); // Should not happen
}

View File

@@ -6,7 +6,7 @@
class FractionLayout : public ExpressionLayout {
public:
FractionLayout(ExpressionLayout * parent, Expression * numerator, Expression * denominator);
FractionLayout(ExpressionLayout * numerator, ExpressionLayout * denominator);
~FractionLayout();
protected:
void render(KDPoint point) override;
@@ -14,8 +14,8 @@ class FractionLayout : public ExpressionLayout {
ExpressionLayout * child(uint16_t index) override;
KDPoint positionOfChild(ExpressionLayout * child) override;
private:
ExpressionLayout * m_numerator;
ExpressionLayout * m_denominator;
ExpressionLayout * m_numerator_layout;
ExpressionLayout * m_denominator_layout;
};
#endif

View File

@@ -1,73 +0,0 @@
extern "C" {
#include <kandinsky.h>
#include <assert.h>
}
#include "function_layout.h"
#include "string_layout.h"
// This code seems like a duplicate of the horizontal layout but it isn't, indeed the horizontal
// layout is used to print the same operation applied to different expressions such that:
// "expr_1 + epr_2 + expr_3 + expr_4".
// Here we want the pattern
// FUNCTION_NAME(expr).
// Thus the code in horizontal layer is not really reusable.
FunctionLayout::FunctionLayout(ExpressionLayout * parent, char* function_name, Expression * argument) :
ExpressionLayout(parent) {
m_children[0] = new StringLayout(this, function_name, 1);
char string[2] = {'(', '\0'};
m_children[1] = new StringLayout(this, string, 1);
m_children[2] = argument->createLayout(this);
string[0] = ')';
m_children[3] = new StringLayout(this, string, 1);
}
FunctionLayout::~FunctionLayout() {
for (int i(0); i<4; i++) {
delete m_children[i];
}
}
void FunctionLayout::render(KDPoint point) { }
KDSize FunctionLayout::computeSize() {
KDSize size = (KDSize){.width = 0, .height = 0};
int i = 0;
while (ExpressionLayout * c = child(i++)) {
KDSize childSize = c->size();
size.width += childSize.width;
if (childSize.height > size.height) {
size.height = childSize.height;
}
}
return size;
}
ExpressionLayout * FunctionLayout::child(uint16_t index) {
if (index >= 4) {
return nullptr;
}
return m_children[index];
}
KDPoint FunctionLayout::positionOfChild(ExpressionLayout * child) {
KDPoint position = (KDPoint){.x = 0, .y = 0};
uint16_t index = 0;
for (int i=0;i<4;i++) {
if (m_children[i] == child) {
index = i;
break;
}
}
if (index > 0) {
ExpressionLayout * previousChild = m_children[index-1];
assert(previousChild != nullptr);
position.x = previousChild->origin().x + previousChild->size().width;
}
position.y = (size().height - child->size().height)/2;
return position;
}

View File

@@ -1,21 +0,0 @@
#ifndef POINCARE_FUNCTION_LAYOUT_H
#define POINCARE_FUNCTION_LAYOUT_H
#include <poincare/expression.h>
#include <poincare/expression_layout.h>
class FunctionLayout : public ExpressionLayout {
public:
FunctionLayout(ExpressionLayout * parent, char* function_name, Expression * arg);
~FunctionLayout();
protected:
void render(KDPoint point) override;
KDSize computeSize() override;
ExpressionLayout * child(uint16_t index) override;
KDPoint positionOfChild(ExpressionLayout * child) override;
private:
ExpressionLayout * m_children[4];
};
#endif

View File

@@ -6,15 +6,11 @@ extern "C" {
#include "horizontal_layout.h"
#include "string_layout.h"
HorizontalLayout::HorizontalLayout(ExpressionLayout * parent, Expression ** operands,int number_of_operands, char symbol) : ExpressionLayout(parent) {
assert(number_of_operands > 0);
m_number_of_children = 2*number_of_operands-1;
m_children_layouts = (ExpressionLayout **)malloc(m_number_of_children*sizeof(ExpressionLayout *));
char string[2] = {symbol, '\0'};
m_children_layouts[0] = operands[0]->createLayout(this);
for (int i=1; i<number_of_operands; i++) {
m_children_layouts[2*i-1] = new StringLayout(this, string, 1);
m_children_layouts[2*i] = operands[i]->createLayout(this);
HorizontalLayout::HorizontalLayout(ExpressionLayout ** children_layouts, int number_of_children) :
ExpressionLayout(), m_number_of_children(number_of_children), m_children_layouts(children_layouts) {
assert(number_of_children > 0);
for (int i=0; i<m_number_of_children; i++) {
m_children_layouts[i]->setParent(this);
}
}
@@ -41,8 +37,8 @@ KDSize HorizontalLayout::computeSize() {
}
ExpressionLayout * HorizontalLayout::child(uint16_t index) {
assert(index <= m_number_of_children);
if (index < m_number_of_children) {
assert(index <= (unsigned int) m_number_of_children);
if (index < (unsigned int) m_number_of_children) {
return m_children_layouts[index];
} else {
return nullptr;

View File

@@ -6,7 +6,7 @@
class HorizontalLayout : public ExpressionLayout {
public:
HorizontalLayout(ExpressionLayout * parent, Expression ** operands, int number_of_children, char symbol);
HorizontalLayout(ExpressionLayout ** layouts, int number_of_children);
~HorizontalLayout();
protected:
void render(KDPoint point) override;

View File

@@ -2,8 +2,8 @@
#include <stdlib.h>
#include "string_layout.h"
StringLayout::StringLayout(ExpressionLayout * parent, const char * string, size_t length) :
ExpressionLayout(parent) {
StringLayout::StringLayout(const char * string, size_t length) :
ExpressionLayout() {
assert(string[length] == 0); // Assert NULL-termination
m_string = (char *)malloc(sizeof(char)*(length+1));
memcpy(m_string, string, (length+1));

View File

@@ -6,7 +6,7 @@
class StringLayout : public ExpressionLayout {
public:
StringLayout(ExpressionLayout * parent, const char * string, size_t length);
StringLayout(const char * string, size_t length);
~StringLayout();
protected:
void render(KDPoint point) override;

View File

@@ -14,6 +14,6 @@ Expression::Type Power::type() {
return Expression::Type::Power;
}
ExpressionLayout * Power::createLayout(ExpressionLayout * parent) {
return new ExponentLayout(parent, m_operands[0], m_operands[1]);
ExpressionLayout * Power::createLayout() {
return new ExponentLayout(m_operands[0]->createLayout(), m_operands[1]->createLayout());
}

View File

@@ -16,6 +16,6 @@ Expression::Type Product::type() {
return Expression::Type::Product;
}
ExpressionLayout * Product::createLayout(ExpressionLayout * parent) {
return new HorizontalLayout(parent, m_operands, m_numberOfOperands, '*');
char Product::operatorChar() {
return '*';
}

View File

@@ -1,5 +1,9 @@
extern "C" {
#include <stdlib.h>
}
#include <poincare/subtraction.h>
#include "layout/horizontal_layout.h"
#include "layout/string_layout.h"
Expression * Subtraction::clone() {
return new Subtraction(m_operands, true);
@@ -13,6 +17,11 @@ Expression::Type Subtraction::type() {
return Expression::Type::Subtraction;
}
ExpressionLayout * Subtraction::createLayout(ExpressionLayout * parent) {
return new HorizontalLayout(parent, m_operands, 2, '-');
ExpressionLayout * Subtraction::createLayout() {
ExpressionLayout** children_layouts = (ExpressionLayout **)malloc(3*sizeof(ExpressionLayout *));
children_layouts[0] = m_operands[0]->createLayout();
char string[2] = {'-', '\0'};
children_layouts[1] = new StringLayout(string, 1);
children_layouts[2] = m_operands[1]->createLayout();
return new HorizontalLayout(children_layouts, 3);
}

View File

@@ -25,9 +25,9 @@ Expression::Type Symbol::type() {
return Expression::Type::Symbol;
}
ExpressionLayout * Symbol::createLayout(ExpressionLayout * parent) {
ExpressionLayout * Symbol::createLayout() {
size_t length = strlen(m_name);
return new StringLayout(parent, m_name, length);
return new StringLayout(m_name, length);
}
Expression * Symbol::clone() {