diff --git a/poincare/Makefile b/poincare/Makefile index 8bee4c7ef..d9750e607 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -23,6 +23,7 @@ objs += $(addprefix poincare/src/,\ logarithm.o\ matrix.o\ matrix_data.o\ + n_context.o\ nth_root.o\ opposite.o\ parenthesis.o\ @@ -30,6 +31,7 @@ objs += $(addprefix poincare/src/,\ product.o\ sine.o\ subtraction.o\ + sum.o\ symbol.o\ tangent.o\ x_context.o\ diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index 9d74b0107..f22d001c6 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 76a4878cd..97baff133 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -26,6 +26,7 @@ class Expression { Power, Product, Sine, + Sum, Subtraction, Symbol, Tangent, diff --git a/poincare/include/poincare/n_context.h b/poincare/include/poincare/n_context.h new file mode 100644 index 000000000..d569c4ce1 --- /dev/null +++ b/poincare/include/poincare/n_context.h @@ -0,0 +1,17 @@ +#ifndef POINCARE_N_CONTEXT_H +#define POINCARE_N_CONTEXT_H + +#include +#include + +class NContext : public Context { +public: + NContext(Context * parentContext = nullptr); + void setExpressionForSymbolName(Expression * expression, const Symbol * symbol) override; + const Expression * expressionForSymbol(const Symbol * symbol) override; +private: + Float m_nValue; + Context * m_parentContext; +}; + +#endif \ No newline at end of file diff --git a/poincare/include/poincare/sum.h b/poincare/include/poincare/sum.h new file mode 100644 index 000000000..f9afbcc0e --- /dev/null +++ b/poincare/include/poincare/sum.h @@ -0,0 +1,16 @@ +#ifndef POINCARE_SUM_H +#define POINCARE_SUM_H + +#include +#include + +class Sum : public Function { +public: + Sum(); + 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/x_context.h b/poincare/include/poincare/x_context.h index bee9ac94b..0755bf68e 100644 --- a/poincare/include/poincare/x_context.h +++ b/poincare/include/poincare/x_context.h @@ -1,5 +1,5 @@ -#ifndef POINCARE_LOCAL_CONTEXT_H -#define POINCARE_LOCAL_CONTEXT_H +#ifndef POINCARE_X_CONTEXT_H +#define POINCARE_X_CONTEXT_H #include #include diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l index b98123782..a31ed323c 100644 --- a/poincare/src/expression_lexer.l +++ b/poincare/src/expression_lexer.l @@ -89,6 +89,7 @@ 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; } root { poincare_expression_yylval.expression = new NthRoot(); return FUNCTION; } +sum { poincare_expression_yylval.expression = new Sum(); return FUNCTION; } \+ { return PLUS; } \- { return MINUS; } \* { return MULTIPLY; } diff --git a/poincare/src/n_context.cpp b/poincare/src/n_context.cpp new file mode 100644 index 000000000..985a60489 --- /dev/null +++ b/poincare/src/n_context.cpp @@ -0,0 +1,24 @@ +#include + +NContext::NContext(::Context * parentContext) : + m_nValue(Float(0.0f)), + m_parentContext(parentContext) +{ +} + +void NContext::setExpressionForSymbolName(Expression * expression, const Symbol * symbol) { + if (symbol->name() == 'n') { + m_nValue = Float((int)expression->approximate(*m_parentContext)); + } else { + m_parentContext->setExpressionForSymbolName(expression, symbol); + } +} + +const Expression * NContext::expressionForSymbol(const Symbol * symbol) { + if (symbol->name() == 'n') { + return &m_nValue; + } else { + return m_parentContext->expressionForSymbol(symbol); + } +} + diff --git a/poincare/src/sum.cpp b/poincare/src/sum.cpp new file mode 100644 index 000000000..e5a2785d7 --- /dev/null +++ b/poincare/src/sum.cpp @@ -0,0 +1,39 @@ +#include +#include +#include + +extern "C" { +#include +} + +Sum::Sum() : + Function("sum") +{ +} + +Expression::Type Sum::type() const { + return Type::Sum; +} + +Expression * Sum::cloneWithDifferentOperands(Expression** newOperands, + int numberOfOperands, bool cloneOperands) const { + assert(numberOfOperands == 2); + assert(newOperands != nullptr); + Sum * s = new Sum(); + s->setArgument(newOperands, numberOfOperands, cloneOperands); + return s; +} + +float Sum::approximate(Context& context) const { + NContext nContext = NContext(&context); + Symbol nSymbol = Symbol('n'); + int start = m_args[1]->approximate(context); + int end = m_args[2]->approximate(context); + float result = 0.0f; + for (int i = start; i <= end; i++) { + Float iExpression = Float(i); + nContext.setExpressionForSymbolName(&iExpression, &nSymbol); + result += m_args[0]->approximate(nContext); + } + return result; +}