diff --git a/poincare/Makefile b/poincare/Makefile index c7144dd49..b4a1c4f5b 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -4,7 +4,7 @@ objs += $(addprefix poincare/src/,\ binary_operation.o\ commutative_operation.o\ context.o\ - cosinus.o\ + cosine.o\ expression.o\ expression_lexer.o\ expression_parser.o\ @@ -15,7 +15,7 @@ objs += $(addprefix poincare/src/,\ leaf_expression.o\ power.o\ product.o\ - sinus.o\ + sine.o\ subtraction.o\ symbol.o\ tangent.o\ @@ -40,6 +40,7 @@ tests += $(addprefix poincare/test/,\ product.cpp\ simplify.cpp\ simplify_addition_integer.cpp\ + trigo.cpp\ subtraction.cpp\ ) diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index 4b89926c0..21b774e7c 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include #include @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/poincare/include/poincare/cosine.h b/poincare/include/poincare/cosine.h new file mode 100644 index 000000000..31f376375 --- /dev/null +++ b/poincare/include/poincare/cosine.h @@ -0,0 +1,14 @@ +#ifndef POINCARE_COSINE_H +#define POINCARE_COSINE_H + +#include + +class Cosine : public Function { + public: + Cosine(Expression * arg, bool clone_arg=true): Function(arg, (char*) "cos", clone_arg) {} + float approximate(Context& context) override; + Type type() override; + Expression * clone() override; +}; + +#endif diff --git a/poincare/include/poincare/cosinus.h b/poincare/include/poincare/cosinus.h deleted file mode 100644 index f23e66e4c..000000000 --- a/poincare/include/poincare/cosinus.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef POINCARE_COSINUS_H -#define POINCARE_COSINUS_H - -#include - -class Cosinus : public Function { - public: - Cosinus(Expression * arg, bool clone_arg=true): Function(arg, (char*) "cos", clone_arg) {} - float approximate(Context& context) override; - Type type() override; - Expression * clone() override; -}; - -#endif diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 44dcd345f..cedb2ec46 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -10,13 +10,13 @@ class Expression { public: enum class Type : uint8_t { Addition, - Cosinus, + Cosine, Float, Fraction, Integer, Power, Product, - Sinus, + Sine, Subtraction, Symbol, Tangent, diff --git a/poincare/include/poincare/sine.h b/poincare/include/poincare/sine.h new file mode 100644 index 000000000..fe53563a0 --- /dev/null +++ b/poincare/include/poincare/sine.h @@ -0,0 +1,14 @@ +#ifndef POINCARE_SINE_H +#define POINCARE_SINE_H + +#include + +class Sine : public Function { + public: + Sine(Expression * arg, bool clone_arg=true): Function(arg, (char*) "sin", clone_arg) {} + float approximate(Context& context) override; + Type type() override; + Expression * clone() override; +}; + +#endif diff --git a/poincare/include/poincare/sinus.h b/poincare/include/poincare/sinus.h deleted file mode 100644 index a970aac09..000000000 --- a/poincare/include/poincare/sinus.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef POINCARE_SINUS_H -#define POINCARE_SINUS_H - -#include - -class Sinus : public Function { - public: - Sinus(Expression * arg, bool clone_arg=true): Function(arg, (char*) "sin", clone_arg) {} - float approximate(Context& context) override; - Type type() override; - Expression * clone() override; -}; - -#endif diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index cb4080b33..15795ee7b 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -14,6 +14,5 @@ float Addition::operateApproximatevelyOn(float a, float b) { } ExpressionLayout * Addition::createLayout(ExpressionLayout * parent) { - //FIXME: There can be more than two operands now! :-) - return new HorizontalLayout(parent, operand(0), '+', operand(1)); + return new HorizontalLayout(parent, m_operands, m_numberOfOperands, '+'); } diff --git a/poincare/src/commutative_operation.cpp b/poincare/src/commutative_operation.cpp index 929908076..37252e0a0 100644 --- a/poincare/src/commutative_operation.cpp +++ b/poincare/src/commutative_operation.cpp @@ -30,6 +30,7 @@ int CommutativeOperation::numberOfOperands() { } Expression * CommutativeOperation::operand(int i) { + assert(i < m_numberOfOperands); return m_operands[i]; } diff --git a/poincare/src/cosine.cpp b/poincare/src/cosine.cpp new file mode 100644 index 000000000..8fafad923 --- /dev/null +++ b/poincare/src/cosine.cpp @@ -0,0 +1,15 @@ +#include +#include "layout/horizontal_layout.h" + +Expression * Cosine::clone() { + return new Cosine(m_arg, true); +} + +Expression::Type Cosine::type() { + return Expression::Type::Cosine; +} + +float Cosine::approximate(Context& context) { + // FIXME: use cosine obviously. + return m_arg->approximate(context); +} diff --git a/poincare/src/cosinus.cpp b/poincare/src/cosinus.cpp deleted file mode 100644 index 070b82a2a..000000000 --- a/poincare/src/cosinus.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include "layout/horizontal_layout.h" - -Expression * Cosinus::clone() { - return new Cosinus(m_arg, true); -} - -Expression::Type Cosinus::type() { - return Expression::Type::Cosinus; -} - -float Cosinus::approximate(Context& context) { - // FIXME: use cosinus obviously. - return m_arg->approximate(context); -} diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index 008e5fca5..26a2dffdc 100644 --- a/poincare/src/expression_lexer.l +++ b/poincare/src/expression_lexer.l @@ -42,10 +42,10 @@ class Expression; %% [0-9]+ { yylval->string = yytext; return(INTEGER); } -[A-Za-z]+ { yylval->string = yytext; return(SYMBOL); } -sin {return(SINUS);} -cos {return(COSINUS);} +sin {return(SINE);} +cos {return(COSINE);} tan {return(TANGENT);} +[A-Za-z]+ { yylval->string = yytext; return(SYMBOL); } \+ { return(PLUS); } \- { return(MINUS); } \* { return(MULTIPLY); } diff --git a/poincare/src/expression_parser.y b/poincare/src/expression_parser.y index bb3dd2b14..43c501e64 100644 --- a/poincare/src/expression_parser.y +++ b/poincare/src/expression_parser.y @@ -54,8 +54,8 @@ void poincare_expression_yyerror(void * scanner, Expression ** expressionOutput, %token MULTIPLY %token DIVIDE %token POW -%token SINUS -%token COSINUS +%token SINE +%token COSINE %token TANGENT %token LEFT_PARENTHESIS %token RIGHT_PARENTHESIS @@ -88,8 +88,8 @@ exp: | 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; } - | SINUS LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = new Sinus($3); } - | COSINUS LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = new Cosinus($3); } + | SINE LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = new Sine($3); } + | COSINE LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = new Cosine($3); } | TANGENT LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = new Tangent($3); } ; diff --git a/poincare/src/layout/horizontal_layout.cpp b/poincare/src/layout/horizontal_layout.cpp index 0ba763f4b..eebc343b0 100644 --- a/poincare/src/layout/horizontal_layout.cpp +++ b/poincare/src/layout/horizontal_layout.cpp @@ -1,29 +1,28 @@ extern "C" { -#include #include +#include +#include } #include "horizontal_layout.h" #include "string_layout.h" -HorizontalLayout::HorizontalLayout(ExpressionLayout * parent, int number_of_operands, Expression ** operands, char symbol) { - m_number_of_operands = number_of_operands; - // FIXME: This implementation is not optimal as the operator layout is created and stored a lot of times. - // The reason for this is how the layouts are drawn. - m_children_layouts = (ExpressionLayout **)malloc((2*m_number_of_operands-)*sizeof(ExpressionLayout *)); - m_operator_layout = new StringLayout(this, string, 1); +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'}; - for (int i=1; icreateLayout(); + m_children_layouts[0] = operands[0]->createLayout(this); + for (int i=1; icreateLayout(this); } } HorizontalLayout::~HorizontalLayout() { - for (int i(0); i= 2*m_number_of_operands) { + assert(index <= m_number_of_children); + if (index < m_number_of_children) { + return m_children_layouts[index]; + } else { return nullptr; } - return m_children_layouts[index]; } KDPoint HorizontalLayout::positionOfChild(ExpressionLayout * child) { KDPoint position = (KDPoint){.x = 0, .y = 0}; uint16_t index = 0; - for (int i=0;i<3;i++) { - if (m_children[i] == child) { + for (int i=0;i 0) { - ExpressionLayout * previousChild = m_children[index-1]; + ExpressionLayout * previousChild = m_children_layouts[index-1]; assert(previousChild != nullptr); position.x = previousChild->origin().x + previousChild->size().width; } diff --git a/poincare/src/layout/horizontal_layout.h b/poincare/src/layout/horizontal_layout.h index 4482aca87..0ee133f5c 100644 --- a/poincare/src/layout/horizontal_layout.h +++ b/poincare/src/layout/horizontal_layout.h @@ -6,7 +6,7 @@ class HorizontalLayout : public ExpressionLayout { public: - HorizontalLayout(ExpressionLayout * parent, int number_of_operands, Expression ** operands, char symbol); + HorizontalLayout(ExpressionLayout * parent, Expression ** operands, int number_of_children, char symbol); ~HorizontalLayout(); protected: void render(KDPoint point) override; @@ -14,9 +14,8 @@ class HorizontalLayout : public ExpressionLayout { ExpressionLayout * child(uint16_t index) override; KDPoint positionOfChild(ExpressionLayout * child) override; private: - int m_number_of_operands; + int m_number_of_children; ExpressionLayout ** m_children_layouts; - ExpressionLayout * m_operator_layout; }; #endif diff --git a/poincare/src/product.cpp b/poincare/src/product.cpp index fc888bfd8..36c93dcba 100644 --- a/poincare/src/product.cpp +++ b/poincare/src/product.cpp @@ -17,6 +17,5 @@ Expression::Type Product::type() { } ExpressionLayout * Product::createLayout(ExpressionLayout * parent) { - //FIXME: There can be more than two factors now! :-) - return new HorizontalLayout(parent, operand(0), '*', operand(1)); + return new HorizontalLayout(parent, m_operands, m_numberOfOperands, '*'); } diff --git a/poincare/src/sine.cpp b/poincare/src/sine.cpp new file mode 100644 index 000000000..fb3d7003c --- /dev/null +++ b/poincare/src/sine.cpp @@ -0,0 +1,15 @@ +#include +#include "layout/horizontal_layout.h" + +Expression * Sine::clone() { + return new Sine(m_arg, true); +} + +Expression::Type Sine::type() { + return Expression::Type::Sine; +} + +float Sine::approximate(Context& context) { + // FIXME: use sine obviously. + return m_arg->approximate(context); +} diff --git a/poincare/src/sinus.cpp b/poincare/src/sinus.cpp deleted file mode 100644 index 9a73559a3..000000000 --- a/poincare/src/sinus.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include "layout/horizontal_layout.h" - -Expression * Sinus::clone() { - return new Sinus(m_arg, true); -} - -Expression::Type Sinus::type() { - return Expression::Type::Sinus; -} - -float Sinus::approximate(Context& context) { - // FIXME: use sinus obviously. - return m_arg->approximate(context); -} diff --git a/poincare/src/subtraction.cpp b/poincare/src/subtraction.cpp index 7f82f02db..448553f2a 100644 --- a/poincare/src/subtraction.cpp +++ b/poincare/src/subtraction.cpp @@ -14,5 +14,5 @@ Expression::Type Subtraction::type() { } ExpressionLayout * Subtraction::createLayout(ExpressionLayout * parent) { - return new HorizontalLayout(parent, m_operands[0], '-', m_operands[1]); + return new HorizontalLayout(parent, m_operands, 2, '-'); } diff --git a/poincare/test/trigo.cpp b/poincare/test/trigo.cpp new file mode 100644 index 000000000..700ac5b64 --- /dev/null +++ b/poincare/test/trigo.cpp @@ -0,0 +1,21 @@ +#include +#include +#include + +QUIZ_CASE(poincare_parse_trigo) { + { + Expression * e = Expression::parse("sin(0)"); + Expression * e2 = e->simplify(); + assert(e2->type() == Expression::Type::Sine); + } + { + Expression * e = Expression::parse("cos(0)"); + Expression * e2 = e->simplify(); + assert(e2->type() == Expression::Type::Cosine); + } + { + Expression * e = Expression::parse("tan(0)"); + Expression * e2 = e->simplify(); + assert(e2->type() == Expression::Type::Tangent); + } +}