diff --git a/ion/src/shared/events.cpp b/ion/src/shared/events.cpp index 51cbb733d..0ce13fbdd 100644 --- a/ion/src/shared/events.cpp +++ b/ion/src/shared/events.cpp @@ -30,7 +30,7 @@ static constexpr EventData s_dataForEvent[] = { TL(), TL(), U(), U(), U(), U(), TL(), TL(), TL(), TL(), TL(), TL(), T("exp()"), T("ln()"), T("log()"), T("i"), T(","), T("^"), - T("sin()"), T("cos()"), T("tan()"), T("p"), T("sqrt()"), T("^2"), + T("sin()"), T("cos()"), T("tan()"), T("Pi"), T("v()"), T("^2"), 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(), diff --git a/poincare/Makefile b/poincare/Makefile index 759e538ad..25aa347aa 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -24,6 +24,7 @@ objs += $(addprefix poincare/src/,\ matrix.o\ matrix_data.o\ multiplication.o\ + naperian_logarithm.o\ n_context.o\ nth_root.o\ opposite.o\ @@ -31,6 +32,7 @@ objs += $(addprefix poincare/src/,\ power.o\ product.o\ sine.o\ + square_root.o\ subtraction.o\ sum.o\ symbol.o\ diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index 5ee726d56..39eaa3586 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 190400e78..3d18919d9 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -20,6 +20,7 @@ class Expression { Logarithm, Matrix, Multiplication, + NaperianLogarithm, NthRoot, Opposite, Fraction, @@ -27,6 +28,7 @@ class Expression { Power, Product, Sine, + SquareRoot, Sum, Subtraction, Symbol, diff --git a/poincare/include/poincare/global_context.h b/poincare/include/poincare/global_context.h index c4285216b..43bb17950 100644 --- a/poincare/include/poincare/global_context.h +++ b/poincare/include/poincare/global_context.h @@ -20,6 +20,7 @@ public: private: int symbolIndex(const Symbol * symbol) const; Expression * m_expressions[k_maxNumberOfScalarExpressions]; + Float m_pi; }; #endif diff --git a/poincare/include/poincare/naperian_logarithm.h b/poincare/include/poincare/naperian_logarithm.h new file mode 100644 index 000000000..34bb9bef2 --- /dev/null +++ b/poincare/include/poincare/naperian_logarithm.h @@ -0,0 +1,15 @@ +#ifndef POINCARE_NAPERIAN_LOGARITHM_H +#define POINCARE_NAPERIAN_LOGARITHM_H + +#include + +class NaperianLogarithm : public Function { +public: + NaperianLogarithm(); + float approximate(Context & context) const override; + Type type() const override; + Expression * cloneWithDifferentOperands(Expression ** newOperands, + int numberOfOperands, bool cloneOperands = true) const override; +}; + +#endif diff --git a/poincare/include/poincare/square_root.h b/poincare/include/poincare/square_root.h new file mode 100644 index 000000000..766d7d753 --- /dev/null +++ b/poincare/include/poincare/square_root.h @@ -0,0 +1,16 @@ +#ifndef POINCARE_SQUARE_ROOT_H +#define POINCARE_SQUARE_ROOT_H + +#include + +class SquareRoot : public Function { +public: + SquareRoot(); + float approximate(Context & context) const override; + Type type() const override; + Expression * cloneWithDifferentOperands(Expression ** newOperands, + int numberOfOperands, bool cloneOperands = true) const override; + ExpressionLayout * createLayout() const override; +}; + +#endif diff --git a/poincare/include/poincare/symbol.h b/poincare/include/poincare/symbol.h index 6b80bfdd3..694397b09 100644 --- a/poincare/include/poincare/symbol.h +++ b/poincare/include/poincare/symbol.h @@ -6,7 +6,8 @@ class Symbol : public LeafExpression { public: enum SpecialSymbols : char { - Ans = '^' + Ans = '^', + Pi = '*' }; Symbol(char name); ExpressionLayout * createLayout() const override; diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index 2586d2132..90b1a9838 100644 --- a/poincare/src/expression_lexer.l +++ b/poincare/src/expression_lexer.l @@ -81,16 +81,19 @@ E { return EE; } [A-Zxnt] { poincare_expression_yylval.character = yytext[0]; return SYMBOL; } abs { poincare_expression_yylval.expression = new AbsoluteValue(); return FUNCTION; } diff { poincare_expression_yylval.expression = new Derivative(); return FUNCTION; } -ans { poincare_expression_yylval.character = Symbol::Ans; return SYMBOL; } +ans { poincare_expression_yylval.character = Symbol::SpecialSymbols::Ans; return SYMBOL; } exp { poincare_expression_yylval.expression = new Exponential(); return FUNCTION; } sin { poincare_expression_yylval.expression = new Sine(); return FUNCTION; } cos { poincare_expression_yylval.expression = new Cosine(); return FUNCTION; } int { poincare_expression_yylval.expression = new Integral(); return FUNCTION; } tan { poincare_expression_yylval.expression = new Tangent(); return FUNCTION; } log { poincare_expression_yylval.expression = new Logarithm(); return FUNCTION; } +ln { poincare_expression_yylval.expression = new NaperianLogarithm(); return FUNCTION; } root { poincare_expression_yylval.expression = new NthRoot(); return FUNCTION; } sum { poincare_expression_yylval.expression = new Sum(); return FUNCTION; } product { poincare_expression_yylval.expression = new Product(); return FUNCTION; } +Pi { poincare_expression_yylval.character = Symbol::SpecialSymbols::Pi; return SYMBOL; } +v { poincare_expression_yylval.expression = new SquareRoot(); return FUNCTION; } \+ { return PLUS; } \- { return MINUS; } \* { return MULTIPLY; } diff --git a/poincare/src/global_context.cpp b/poincare/src/global_context.cpp index 0eefdcac7..baee54faf 100644 --- a/poincare/src/global_context.cpp +++ b/poincare/src/global_context.cpp @@ -1,7 +1,9 @@ #include #include +#include -GlobalContext::GlobalContext() +GlobalContext::GlobalContext() : + m_pi(Float(M_PI)) { for (int i = 0; i < k_maxNumberOfScalarExpressions; i++) { m_expressions[i] = nullptr; @@ -19,6 +21,9 @@ int GlobalContext::symbolIndex(const Symbol * symbol) const { } const Expression * GlobalContext::expressionForSymbol(const Symbol * symbol) { + if (symbol->name() == Symbol::SpecialSymbols::Pi) { + return &m_pi; + } int index = symbolIndex(symbol); if (index < 0 || index >= k_maxNumberOfScalarExpressions) { return nullptr; diff --git a/poincare/src/layout/nth_root_layout.cpp b/poincare/src/layout/nth_root_layout.cpp index 4e0664763..a178ca196 100644 --- a/poincare/src/layout/nth_root_layout.cpp +++ b/poincare/src/layout/nth_root_layout.cpp @@ -19,25 +19,31 @@ NthRootLayout::NthRootLayout(ExpressionLayout * radicandLayout, ExpressionLayout m_indexLayout(indexLayout) { m_radicandLayout->setParent(this); - m_indexLayout->setParent(this); - m_baseline = max(m_radicandLayout->baseline() + k_radixLineThickness + k_heightMargin, - m_indexLayout->size().height() + k_indexHeight); + if (m_indexLayout != nullptr) { + m_indexLayout->setParent(this); + m_baseline = max(m_radicandLayout->baseline() + k_radixLineThickness + k_heightMargin, + m_indexLayout->size().height() + k_indexHeight); + } else { + m_baseline = m_radicandLayout->baseline() + k_radixLineThickness + k_heightMargin; + } } NthRootLayout::~NthRootLayout() { delete m_radicandLayout; - delete m_indexLayout; + if (m_indexLayout != nullptr) { + delete m_indexLayout; + } } void NthRootLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) { KDSize radicandSize = m_radicandLayout->size(); - KDSize indexSize = m_indexLayout->size(); + KDSize indexSize = m_indexLayout != nullptr ? m_indexLayout->size() : KDSize(k_leftRadixWidth,0); KDColor workingBuffer[k_leftRadixWidth*k_leftRadixHeight]; KDRect leftRadixFrame(p.x() + indexSize.width() + k_widthMargin - k_leftRadixWidth, p.y() + m_baseline + radicandSize.height() - m_radicandLayout->baseline() + k_heightMargin - k_leftRadixHeight, k_leftRadixWidth, k_leftRadixHeight); ctx->blendRectWithMask(leftRadixFrame, expressionColor, (const uint8_t *)radixPixel, (KDColor *)workingBuffer); - if (m_indexLayout->size().height() + k_indexHeight > m_radicandLayout->baseline() + k_radixLineThickness + k_heightMargin) { + if (indexSize.height() + k_indexHeight > m_radicandLayout->baseline() + k_radixLineThickness + k_heightMargin) { ctx->fillRect(KDRect(p.x() + indexSize.width() + k_widthMargin, p.y() + indexSize.height() + k_indexHeight - m_radicandLayout->baseline() - k_radixLineThickness - k_heightMargin, k_radixLineThickness, @@ -69,7 +75,7 @@ void NthRootLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDSize NthRootLayout::computeSize() { KDSize radicandSize = m_radicandLayout->size(); - KDSize indexSize = m_indexLayout->size(); + KDSize indexSize = m_indexLayout != nullptr ? m_indexLayout->size() : KDSize(k_leftRadixWidth,0); return KDSize( indexSize.width() + 3*k_widthMargin + 2*k_radixLineThickness + radicandSize.width(), m_baseline + radicandSize.height() - m_radicandLayout->baseline() + k_heightMargin @@ -79,9 +85,9 @@ KDSize NthRootLayout::computeSize() { ExpressionLayout * NthRootLayout::child(uint16_t index) { switch (index) { case 0: - return m_indexLayout; - case 1: return m_radicandLayout; + case 1: + return m_indexLayout; default: return nullptr; } @@ -90,7 +96,7 @@ ExpressionLayout * NthRootLayout::child(uint16_t index) { KDPoint NthRootLayout::positionOfChild(ExpressionLayout * child) { KDCoordinate x = 0; KDCoordinate y = 0; - KDSize indexSize = m_indexLayout->size(); + KDSize indexSize = m_indexLayout != nullptr ? m_indexLayout->size() : KDSize(k_leftRadixWidth,0); if (child == m_indexLayout) { x = 0; y = m_baseline - indexSize.height() - k_indexHeight; diff --git a/poincare/src/naperian_logarithm.cpp b/poincare/src/naperian_logarithm.cpp new file mode 100644 index 000000000..632df69c4 --- /dev/null +++ b/poincare/src/naperian_logarithm.cpp @@ -0,0 +1,31 @@ +#include +extern "C" { +#include +#include +#include +} +#include "layout/horizontal_layout.h" +#include "layout/parenthesis_layout.h" +#include "layout/string_layout.h" + +NaperianLogarithm::NaperianLogarithm() : + Function("ln") +{ +} + +Expression::Type NaperianLogarithm::type() const { + return Type::NaperianLogarithm; +} + +Expression * NaperianLogarithm::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 1 || numberOfOperands == 2); + assert(newOperands != nullptr); + NaperianLogarithm * l = new NaperianLogarithm(); + l->setArgument(newOperands, numberOfOperands, cloneOperands); + return l; +} + +float NaperianLogarithm::approximate(Context& context) const { + return log10f(m_args[0]->approximate(context))/log10f(M_E); +} diff --git a/poincare/src/square_root.cpp b/poincare/src/square_root.cpp new file mode 100644 index 000000000..2456de922 --- /dev/null +++ b/poincare/src/square_root.cpp @@ -0,0 +1,33 @@ +#include +#include "layout/nth_root_layout.h" + +extern "C" { +#include +#include +} + +SquareRoot::SquareRoot() : + Function("v") +{ +} + +Expression::Type SquareRoot::type() const { + return Type::SquareRoot; +} + +Expression * SquareRoot::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 1); + assert(newOperands != nullptr); + SquareRoot * sr = new SquareRoot(); + sr->setArgument(newOperands, numberOfOperands, cloneOperands); + return sr; +} + +float SquareRoot::approximate(Context& context) const { + return powf(m_args[0]->approximate(context), 1.0f/2.0f); +} + +ExpressionLayout * SquareRoot::createLayout() const { + return new NthRootLayout(m_args[0]->createLayout(),nullptr); +} \ No newline at end of file diff --git a/poincare/src/symbol.cpp b/poincare/src/symbol.cpp index 33aefd4c1..720040800 100644 --- a/poincare/src/symbol.cpp +++ b/poincare/src/symbol.cpp @@ -35,6 +35,9 @@ ExpressionLayout * Symbol::createLayout() const { if (m_name == SpecialSymbols::Ans) { return new StringLayout("ans", 4); } + if (m_name == SpecialSymbols::Pi) { + return new StringLayout("Pi", 4); + } return new StringLayout(&m_name, 1); }