From 7e1f3f45962ec1ddf8683bea778c82fbfa9c4470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Fri, 10 Mar 2017 09:49:38 +0100 Subject: [PATCH 1/4] [poincare] Add tests on symbols Change-Id: I44329fb76dd84c1ef6b731d552c80615fc29d01d --- poincare/Makefile | 1 + poincare/test/symbol.cpp | 54 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 poincare/test/symbol.cpp diff --git a/poincare/Makefile b/poincare/Makefile index 77ee68a96..97ee442f8 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -98,6 +98,7 @@ tests += $(addprefix poincare/test/,\ power.cpp\ simplify_utils.cpp\ subtraction.cpp\ + symbol.cpp\ trigo.cpp\ ) diff --git a/poincare/test/symbol.cpp b/poincare/test/symbol.cpp new file mode 100644 index 000000000..6d0aea0f9 --- /dev/null +++ b/poincare/test/symbol.cpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include + +using namespace Poincare; + +QUIZ_CASE(poincare_parse_symbol) { + char piText[2] = {Ion::Charset::SmallPi, 0}; + Expression * e = Expression::parse(piText); + assert(e->type() == Expression::Type::Symbol); + delete e; + + char eText[2] = {Ion::Charset::Exponential, 0}; + e = Expression::parse(eText); + assert(e->type() == Expression::Type::Symbol); + delete e; + + char iText[10] = {Ion::Charset::IComplex, 0}; + e = Expression::parse(iText); + assert(e->type() == Expression::Type::Complex); + delete e; + + char floatText[10] = {'1', '.', '2', Ion::Charset::Exponent, '3', 0}; + e = Expression::parse(floatText); + assert(e->type() == Expression::Type::Complex); + delete e; + + e = Expression::parse("ans"); + assert(e->type() == Expression::Type::Symbol); + delete e; +} + + +QUIZ_CASE(poincare_symbol_approximate) { + GlobalContext globalContext; + char piText[2] = {Ion::Charset::SmallPi, 0}; + Expression * e = Expression::parse(piText); + assert(fabsf(e->approximate(globalContext)-M_PI) <= 0.0001f); + delete e; + + char eText[2] = {Ion::Charset::Exponential, 0}; + e = Expression::parse(eText); + assert(fabsf(e->approximate(globalContext)-M_E) <= 0.0001f); + + delete e; + + char floatText[10] = {'1', '.', '2', Ion::Charset::Exponent, '3', 0}; + e = Expression::parse(floatText); + assert(fabsf(e->approximate(globalContext)-1200.0f) <= 0.0001f); + delete e; +} + From 6b98af52874b47a61f96dc191537f75fe60bfaaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Fri, 10 Mar 2017 10:26:01 +0100 Subject: [PATCH 2/4] [apps][poincare] Add a submenu to toolbox about fluctuation intervals Change-Id: Iae352e67abe4e70a75a4083bc669ea2541618457 --- apps/math_toolbox.cpp | 8 ++-- poincare/Makefile | 2 + poincare/include/poincare.h | 2 + .../include/poincare/confidence_interval.h | 22 ++++++++++ poincare/include/poincare/expression.h | 2 + .../include/poincare/prediction_interval.h | 22 ++++++++++ poincare/src/confidence_interval.cpp | 44 +++++++++++++++++++ poincare/src/expression_lexer.l | 3 ++ poincare/src/prediction_interval.cpp | 44 +++++++++++++++++++ 9 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 poincare/include/poincare/confidence_interval.h create mode 100644 poincare/include/poincare/prediction_interval.h create mode 100644 poincare/src/confidence_interval.cpp create mode 100644 poincare/src/prediction_interval.cpp diff --git a/apps/math_toolbox.cpp b/apps/math_toolbox.cpp index abafdd85b..fc33c6b6b 100644 --- a/apps/math_toolbox.cpp +++ b/apps/math_toolbox.cpp @@ -15,13 +15,15 @@ const ToolboxNode matricesChildren[5] = {ToolboxNode("inverse()", "Inverse"), To const ToolboxNode listesChildren[5] = {ToolboxNode("sort<()", "Tri croissant"), ToolboxNode("sort>()", "Tri decroissant"), ToolboxNode("max()", "Maximum"), ToolboxNode("min()", "Minimum"), ToolboxNode("dim()", "Taille")}; const ToolboxNode approximationChildren[4] = {ToolboxNode("floor()", "Partie entiere"), ToolboxNode("frac()", "Partie fractionnaire"), ToolboxNode("ceil()", "Plafond"), ToolboxNode("round(,)", "Arrondi")}; const ToolboxNode trigonometryChildren[6] = {ToolboxNode("cosh()", "cosh"), ToolboxNode("sinh()", "sinh"), ToolboxNode("tanh()", "tanh"), ToolboxNode("acosh()", "acosh"), ToolboxNode("asinh()", "asinh"), ToolboxNode("atanh()", "atanh")}; +const ToolboxNode predictionChildren[3] = {ToolboxNode("prediction95(,)", "Intervalle fluctuation 95%"), ToolboxNode("prediction(,)", "Intervalle fluctuation simple"), ToolboxNode("confidence(,)", "Intervalle de confiance")}; -const ToolboxNode menu[11] = {ToolboxNode("abs()", "Valeur absolue"), ToolboxNode("root(,)", "Racine k-ieme"), ToolboxNode("log(,)", "Logarithme base a"), +const ToolboxNode menu[12] = {ToolboxNode("abs()", "Valeur absolue"), ToolboxNode("root(,)", "Racine k-ieme"), ToolboxNode("log(,)", "Logarithme base a"), ToolboxNode("Calcul", nullptr, calculChildren, 4), ToolboxNode("Nombre complexe", nullptr, complexChildren, 5), ToolboxNode("Probabilite", nullptr, probabilityChildren, 2), ToolboxNode("Arithmetique", nullptr, arithmeticChildren, 4), ToolboxNode("Matrice", nullptr, matricesChildren, 5), ToolboxNode("Liste", nullptr, listesChildren, 5), - ToolboxNode("Approximation", nullptr, approximationChildren, 4), ToolboxNode("Trigonometrie hyperbolique", nullptr, trigonometryChildren, 6)}; -const ToolboxNode toolboxModel = ToolboxNode("Toolbox", nullptr, menu, 11); + ToolboxNode("Approximation", nullptr, approximationChildren, 4), ToolboxNode("Trigonometrie hyperbolique", nullptr, trigonometryChildren, 6), + ToolboxNode("Intervalle fluctuation", nullptr, predictionChildren, 3)}; +const ToolboxNode toolboxModel = ToolboxNode("Toolbox", nullptr, menu, 12); /* State */ diff --git a/poincare/Makefile b/poincare/Makefile index 97ee442f8..0a27ddf0a 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -13,6 +13,7 @@ objs += $(addprefix poincare/src/,\ ceiling.o\ complex.o\ complex_argument.o\ + confidence_interval.o\ conjugate.o\ cosine.o\ derivative.o\ @@ -54,6 +55,7 @@ objs += $(addprefix poincare/src/,\ parenthesis.o\ permute_coefficient.o\ power.o\ + prediction_interval.o\ preferences.o\ product.o\ reel_part.o\ diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index 0ff3fd55e..138dc9d32 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,7 @@ #include #include #include +#include #include #include #include diff --git a/poincare/include/poincare/confidence_interval.h b/poincare/include/poincare/confidence_interval.h new file mode 100644 index 000000000..7ef0214c9 --- /dev/null +++ b/poincare/include/poincare/confidence_interval.h @@ -0,0 +1,22 @@ +#ifndef POINCARE_CONFIDENCE_INTERVAL_H +#define POINCARE_CONFIDENCE_INTERVAL_H + +#include + +namespace Poincare { + +class ConfidenceInterval : public Function { +public: + ConfidenceInterval(); + Type type() const override; + Expression * cloneWithDifferentOperands(Expression ** newOperands, + int numberOfOperands, bool cloneOperands = true) const override; +private: + float privateApproximate(Context & context, AngleUnit angleUnit) const override; + Expression * privateEvaluate(Context& context, AngleUnit angleUnit) const override; +}; + +} + +#endif + diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 6765e26a3..3b720eab0 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -20,6 +20,7 @@ public: Ceiling, Complex, ComplexArgument, + ConfidenceInterval, Conjugate, Cosine, Derivative, @@ -50,6 +51,7 @@ public: NaperianLogarithm, NthRoot, Opposite, + PredictionInterval, Fraction, Parenthesis, PermuteCoefficient, diff --git a/poincare/include/poincare/prediction_interval.h b/poincare/include/poincare/prediction_interval.h new file mode 100644 index 000000000..5044945a6 --- /dev/null +++ b/poincare/include/poincare/prediction_interval.h @@ -0,0 +1,22 @@ +#ifndef POINCARE_PREDICTION_INTERVAL_H +#define POINCARE_PREDICTION_INTERVAL_H + +#include + +namespace Poincare { + +class PredictionInterval : public Function { +public: + PredictionInterval(); + Type type() const override; + Expression * cloneWithDifferentOperands(Expression ** newOperands, + int numberOfOperands, bool cloneOperands = true) const override; +private: + float privateApproximate(Context & context, AngleUnit angleUnit) const override; + Expression * privateEvaluate(Context& context, AngleUnit angleUnit) const override; +}; + +} + +#endif + diff --git a/poincare/src/confidence_interval.cpp b/poincare/src/confidence_interval.cpp new file mode 100644 index 000000000..d3b179eb2 --- /dev/null +++ b/poincare/src/confidence_interval.cpp @@ -0,0 +1,44 @@ +#include +#include +extern "C" { +#include +#include +} + +namespace Poincare { + +ConfidenceInterval::ConfidenceInterval() : + Function("confidence") +{ +} + +Expression::Type ConfidenceInterval::type() const { + return Type::ConfidenceInterval; +} + +Expression * ConfidenceInterval::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 1); + assert(newOperands != nullptr); + ConfidenceInterval * ci = new ConfidenceInterval(); + ci->setArgument(newOperands, numberOfOperands, cloneOperands); + return ci; +} + +float ConfidenceInterval::privateApproximate(Context& context, AngleUnit angleUnit) const { + assert(angleUnit != AngleUnit::Default); + return NAN; +} + +Expression * ConfidenceInterval::privateEvaluate(Context& context, AngleUnit angleUnit) const { + assert(angleUnit != AngleUnit::Default); + float f = m_args[0]->approximate(context, angleUnit); + float n = m_args[1]->approximate(context, angleUnit); + Expression * operands[2]; + operands[0] = new Complex(Complex::Float(f - 1.0f/sqrtf(n))); + operands[1] = new Complex(Complex::Float(f + 1.0f/sqrtf(n))); + return new Matrix(new MatrixData(operands, 2, 2, 1, false)); +} + +} + diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index 9aba18c22..da42fda71 100644 --- a/poincare/src/expression_lexer.l +++ b/poincare/src/expression_lexer.l @@ -100,6 +100,7 @@ atan { poincare_expression_yylval.expression = new ArcTangent(); return FUNCTION atanh { poincare_expression_yylval.expression = new HyperbolicArcTangent(); return FUNCTION; } binomial { poincare_expression_yylval.expression = new BinomialCoefficient(); return FUNCTION; } ceil { poincare_expression_yylval.expression = new Ceiling(); return FUNCTION; } +confidence { poincare_expression_yylval.expression = new ConfidenceInterval(); return FUNCTION; } diff { poincare_expression_yylval.expression = new Derivative(); return FUNCTION; } dim { poincare_expression_yylval.expression = new MatrixDimension(); return FUNCTION; } det { poincare_expression_yylval.expression = new Determinant(); return FUNCTION; } @@ -116,6 +117,8 @@ lcm { poincare_expression_yylval.expression = new LeastCommonMultiple(); return ln { poincare_expression_yylval.expression = new NaperianLogarithm(); return FUNCTION; } log { poincare_expression_yylval.expression = new Logarithm(); return FUNCTION; } permute { poincare_expression_yylval.expression = new PermuteCoefficient(); return FUNCTION; } +prediction95 { poincare_expression_yylval.expression = new PredictionInterval(); return FUNCTION; } +prediction { poincare_expression_yylval.expression = new ConfidenceInterval(); return FUNCTION; } product { poincare_expression_yylval.expression = new Product(); return FUNCTION; } quo { poincare_expression_yylval.expression = new DivisionQuotient(); return FUNCTION; } re { poincare_expression_yylval.expression = new ReelPart(); return FUNCTION; } diff --git a/poincare/src/prediction_interval.cpp b/poincare/src/prediction_interval.cpp new file mode 100644 index 000000000..bec1f79fa --- /dev/null +++ b/poincare/src/prediction_interval.cpp @@ -0,0 +1,44 @@ +#include +#include +extern "C" { +#include +#include +} + +namespace Poincare { + +PredictionInterval::PredictionInterval() : + Function("prediction95") +{ +} + +Expression::Type PredictionInterval::type() const { + return Type::PredictionInterval; +} + +Expression * PredictionInterval::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 1); + assert(newOperands != nullptr); + PredictionInterval * pi = new PredictionInterval(); + pi->setArgument(newOperands, numberOfOperands, cloneOperands); + return pi; +} + +float PredictionInterval::privateApproximate(Context& context, AngleUnit angleUnit) const { + assert(angleUnit != AngleUnit::Default); + return NAN; +} + +Expression * PredictionInterval::privateEvaluate(Context& context, AngleUnit angleUnit) const { + assert(angleUnit != AngleUnit::Default); + float p = m_args[0]->approximate(context, angleUnit); + float n = m_args[1]->approximate(context, angleUnit); + Expression * operands[2]; + operands[0] = new Complex(Complex::Float(p - 1.96f*sqrtf(p*(1-p))/sqrtf(n))); + operands[1] = new Complex(Complex::Float(p + 1.96f*sqrtf(p*(1-p))/sqrtf(n))); + return new Matrix(new MatrixData(operands, 2, 2, 1, false)); +} + +} + From 91385765d89b48d71ef74e3570fec3b67227e87a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Fri, 10 Mar 2017 13:32:08 +0100 Subject: [PATCH 3/4] [poincare] Parse "3->A" (sto) Change-Id: Idd8545cfcb91cebc7f95e2425db795e8105da14b --- ion/src/shared/events.cpp | 3 +- poincare/Makefile | 1 + poincare/include/poincare.h | 1 + poincare/include/poincare/expression.h | 1 + poincare/include/poincare/global_context.h | 1 + poincare/include/poincare/store.h | 29 ++++++++ poincare/src/expression.cpp | 1 + poincare/src/expression_lexer.l | 1 + poincare/src/expression_parser.y | 14 +++- poincare/src/global_context.cpp | 15 +++- poincare/src/store.cpp | 82 ++++++++++++++++++++++ 11 files changed, 144 insertions(+), 5 deletions(-) create mode 100644 poincare/include/poincare/store.h create mode 100644 poincare/src/store.cpp diff --git a/ion/src/shared/events.cpp b/ion/src/shared/events.cpp index 0a5504569..fd643aa36 100644 --- a/ion/src/shared/events.cpp +++ b/ion/src/shared/events.cpp @@ -28,6 +28,7 @@ static constexpr const char k_pi[2] = {Ion::Charset::SmallPi, 0}; static constexpr const char k_root[4] = {Ion::Charset::Root, '(', ')', 0}; static constexpr const char k_complexI[2] = {Ion::Charset::IComplex, 0}; static constexpr const char k_exponential[5] = {Ion::Charset::Exponential, '^', '(', ')', 0}; +static constexpr const char k_sto[2] = {Ion::Charset::Sto, 0}; static constexpr EventData s_dataForEvent[] = { // Plain @@ -44,7 +45,7 @@ static constexpr EventData s_dataForEvent[] = { U(), U(), U(), U(), U(), U(), U(), U(), U(), U(), U(), U(), U(), U(), TL(), TL(), TL(), TL(), - T("["), T("]"), T("{"), T("}"), T("_"), T("sto"), + T("["), T("]"), T("{"), T("}"), T("_"), T(k_sto), T("asin()"), T("acos()"), T("atan()"), T("="), T("<"), T(">"), U(), U(), TL(), TL(), TL(), TL(), U(), U(), TL(), TL(), TL(), TL(), diff --git a/poincare/Makefile b/poincare/Makefile index 0a27ddf0a..937f3e2a9 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -62,6 +62,7 @@ objs += $(addprefix poincare/src/,\ round.o\ sine.o\ square_root.o\ + store.o\ subtraction.o\ sum.o\ symbol.o\ diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index 138dc9d32..651983e25 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 3b720eab0..f89f70300 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -61,6 +61,7 @@ public: Round, Sine, SquareRoot, + Store, Sum, Subtraction, Symbol, diff --git a/poincare/include/poincare/global_context.h b/poincare/include/poincare/global_context.h index dcc2930ab..3e102cda2 100644 --- a/poincare/include/poincare/global_context.h +++ b/poincare/include/poincare/global_context.h @@ -13,6 +13,7 @@ class Integer; class GlobalContext : public Context { public: GlobalContext(); + ~GlobalContext(); /* The expression recorded in global context is already a final expression. * Otherwise, we would need the context and the angle unit to evaluate it */ const Expression * expressionForSymbol(const Symbol * symbol) override; diff --git a/poincare/include/poincare/store.h b/poincare/include/poincare/store.h new file mode 100644 index 000000000..e8928ca54 --- /dev/null +++ b/poincare/include/poincare/store.h @@ -0,0 +1,29 @@ +#ifndef POINCARE_STORE_H +#define POINCARE_STORE_H + +#include +#include + +namespace Poincare { + +class Store : public Expression { +public: + Store(Symbol * symbol, Expression * value, bool clone = true); + ~Store(); + Type type() const override; + const Expression * operand(int i) const override; + int numberOfOperands() const override; + Expression * clone() const override; + Expression * cloneWithDifferentOperands(Expression ** newOperands, + int numberOfOperands, bool cloneOperands = true) const override; +private: + ExpressionLayout * privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const override; + Expression * privateEvaluate(Context& context, AngleUnit angleUnit) const override; + float privateApproximate(Context& context, AngleUnit angleUnit) const override; + Symbol * m_symbol; + Expression * m_value; +}; + +} + +#endif diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index 440f92623..9d7df1df8 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include "expression_parser.hpp" diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index da42fda71..f5d1742fb 100644 --- a/poincare/src/expression_lexer.l +++ b/poincare/src/expression_lexer.l @@ -137,6 +137,7 @@ transpose { poincare_expression_yylval.expression = new MatrixTranspose(); retur \x90 { poincare_expression_yylval.expression = new SquareRoot(); return FUNCTION; } \x8b { return ICOMPLEX; } \x8e { poincare_expression_yylval.character = yytext[0]; return SYMBOL; } +\x8f { return STO; } \+ { return PLUS; } \- { return MINUS; } \* { return MULTIPLY; } diff --git a/poincare/src/expression_parser.y b/poincare/src/expression_parser.y index d595a1dd8..09715dede 100644 --- a/poincare/src/expression_parser.y +++ b/poincare/src/expression_parser.y @@ -29,6 +29,7 @@ void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char * be useful to retrieve the value of Integers for example). */ %union { Poincare::Expression * expression; + Poincare::Symbol * symbol; Poincare::ListData * listData; Poincare::MatrixData * matrixData; Poincare::Function * function; @@ -49,7 +50,6 @@ void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char %token DIGITS %token SYMBOL %token FUNCTION -%token ICOMPLEX /* Operator tokens */ %token PLUS @@ -66,6 +66,8 @@ void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char %token COMMA %token DOT %token EE +%token ICOMPLEX +%token STO /* Make the operators left associative. * This makes 1 - 2 - 5’ be ‘(1 - 2) - 5’ instead of ‘1 - (2 - 5)’. @@ -80,6 +82,7 @@ void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char * If you need to define precedence in order to avoid shift/redice conflicts for * other situations your grammar is most likely ambiguous. */ +%left STO %left PLUS %left MINUS %left MULTIPLY @@ -89,6 +92,7 @@ void poincare_expression_yyerror(Poincare::Expression ** expressionOutput, char /* The "exp" symbol uses the "expression" part of the union. */ %type exp; %type number; +%type symb; %type lstData; %type mtxData; @@ -119,10 +123,14 @@ number: | DOT DIGITS EE MINUS DIGITS { $$ = new Poincare::Complex(nullptr, 0, false, $2.address, $2.length, $5.address, $5.length, true); } | DIGITS DOT DIGITS EE MINUS DIGITS { $$ = new Poincare::Complex($1.address, $1.length, false, $3.address, $3.length, $6.address, $6.length, true); } +symb: + SYMBOL { $$ = new Poincare::Symbol($1); } + exp: - number { $$ = $1; } + exp STO symb {$$ = new Poincare::Store($3, $1, false); } + | number { $$ = $1; } | ICOMPLEX { $$ = new Poincare::Complex(Poincare::Complex::Cartesian(0.0f, 1.0f)); } - | SYMBOL { $$ = new Poincare::Symbol($1); } + | symb { $$ = $1; } | exp PLUS exp { Poincare::Expression * terms[2] = {$1,$3}; $$ = new Poincare::Addition(terms, false); } | exp MINUS exp { Poincare::Expression * terms[2] = {$1,$3}; $$ = new Poincare::Subtraction(terms, false); } | exp MULTIPLY exp { Poincare::Expression * terms[2] = {$1,$3}; $$ = new Poincare::Multiplication(terms, false); } diff --git a/poincare/src/global_context.cpp b/poincare/src/global_context.cpp index 0f4b4f331..51819d9bc 100644 --- a/poincare/src/global_context.cpp +++ b/poincare/src/global_context.cpp @@ -14,6 +14,15 @@ GlobalContext::GlobalContext() : } } +GlobalContext::~GlobalContext() { + for (int i = 0; i < k_maxNumberOfScalarExpressions; i++) { + if (m_expressions[i] != nullptr) { + delete m_expressions[i]; + } + m_expressions[i] = nullptr; + } +} + Complex * GlobalContext::defaultExpression() { static Complex * defaultExpression = new Complex(Complex::Float(0.0f)); return defaultExpression; @@ -44,7 +53,11 @@ const Expression * GlobalContext::expressionForSymbol(const Symbol * symbol) { void GlobalContext::setExpressionForSymbolName(Expression * expression, const Symbol * symbol) { int index = symbolIndex(symbol); assert(expression->type() == Expression::Type::Complex); - m_expressions[index] = expression; + if (m_expressions[index] != nullptr) { + delete m_expressions[index]; + m_expressions[index] = nullptr; + } + m_expressions[index] = expression->clone(); } } diff --git a/poincare/src/store.cpp b/poincare/src/store.cpp new file mode 100644 index 000000000..bfbc19048 --- /dev/null +++ b/poincare/src/store.cpp @@ -0,0 +1,82 @@ +extern "C" { +#include +#include +} +#include +#include +#include +#include +#include "layout/horizontal_layout.h" +#include "layout/string_layout.h" + +namespace Poincare { + +Store::Store(Symbol * symbol, Expression * value, bool clone) : + m_symbol(symbol), + m_value(value) +{ + if (clone) { + m_symbol = (Symbol *)symbol->clone(); + m_value = value->clone(); + } +} + +Store::~Store() { + delete m_symbol; + delete m_value; +} + +Expression::Type Store::type() const { + return Type::Store; +} + +const Expression * Store::operand(int i) const { + if (i == 0) { + return m_symbol; + } + return m_value; +} + +int Store::numberOfOperands() const { + return 2; +} + +Expression * Store::clone() const { + Expression * newOperands[2]; + newOperands[0] = m_symbol; + newOperands[1] = m_value; + return this->cloneWithDifferentOperands(newOperands, 2, true); +} + +Expression * Store::cloneWithDifferentOperands(Expression ** newOperands, int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 2); + assert(newOperands != nullptr); + assert(newOperands[0]->type() == Type::Symbol); + return new Store((Symbol *)newOperands[0], newOperands[1], cloneOperands); +} + +ExpressionLayout * Store::privateCreateLayout(FloatDisplayMode floatDisplayMode, ComplexFormat complexFormat) const { + assert(floatDisplayMode != FloatDisplayMode::Default); + assert(complexFormat != ComplexFormat::Default); + ExpressionLayout * childrenLayouts[3]; + childrenLayouts[0] = m_value->createLayout(floatDisplayMode, complexFormat); + const char stoSymbol[2] = {Ion::Charset::Sto, 0}; + childrenLayouts[1] = new StringLayout(stoSymbol, 1); + childrenLayouts[2] = m_symbol->createLayout(floatDisplayMode, complexFormat); + return new HorizontalLayout(childrenLayouts, 3); +} + + +Expression * Store::privateEvaluate(Context& context, AngleUnit angleUnit) const { + assert(angleUnit != AngleUnit::Default); + Expression * valueEvaluation = m_value->evaluate(context, angleUnit); + context.setExpressionForSymbolName(valueEvaluation, m_symbol); + return valueEvaluation; +} + +float Store::privateApproximate(Context& context, AngleUnit angleUnit) const { + assert(angleUnit != AngleUnit::Default); + return NAN; +} + +} From 7c59498bffa7e060aeb12fbb4bbe81c402cdf46c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Fri, 10 Mar 2017 13:43:41 +0100 Subject: [PATCH 4/4] [ion] Correct event text in events Change-Id: If0640ecd9917c18001aa0c52821bace5e4025462 --- ion/src/shared/events.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ion/src/shared/events.cpp b/ion/src/shared/events.cpp index fd643aa36..c40cd093b 100644 --- a/ion/src/shared/events.cpp +++ b/ion/src/shared/events.cpp @@ -29,6 +29,7 @@ static constexpr const char k_root[4] = {Ion::Charset::Root, '(', ')', 0}; static constexpr const char k_complexI[2] = {Ion::Charset::IComplex, 0}; static constexpr const char k_exponential[5] = {Ion::Charset::Exponential, '^', '(', ')', 0}; static constexpr const char k_sto[2] = {Ion::Charset::Sto, 0}; +static constexpr const char k_exponent[2] = {Ion::Charset::Exponent, 0}; static constexpr EventData s_dataForEvent[] = { // Plain @@ -40,7 +41,7 @@ static constexpr EventData s_dataForEvent[] = { T("7"), T("8"), T("9"), T("("), T(")"), U(), T("4"), T("5"), T("6"), T("*"), T("/"), U(), T("1"), T("2"), T("3"), T("+"), T("-"), U(), - T("0"), T("."), T("E"), TL(), TL(), U(), + T("0"), T("."), T(k_exponent), TL(), TL(), U(), // Shift U(), U(), U(), U(), U(), U(), U(), U(), U(), U(), U(), U(),