#include "cache_context.h" #include "sequence.h" #include "sequence_store.h" #include "../shared/poincare_helpers.h" #include #include using namespace Poincare; namespace Sequence { template CacheContext::CacheContext(Context * parentContext) : ContextWithParent(parentContext), m_values{{NAN, NAN},{NAN, NAN},{NAN,NAN}} { } template const Expression CacheContext::expressionForSymbolAbstract(const SymbolAbstract & symbol, bool clone) { // [u|v|w](n(+1)?) if (symbol.type() == ExpressionNode::Type::Sequence) { Symbol s = const_cast(static_cast(symbol)); if (s.childAtIndex(0).type() == ExpressionNode::Type::Symbol) { return Float::Builder(m_values[nameIndexForSymbol(s)][0]); } else if (s.childAtIndex(0).type() == ExpressionNode::Type::Addition) { return Float::Builder(m_values[nameIndexForSymbol(s)][1]); } else { Sequence seq = m_sequenceContext->sequenceStore()->sequenceAtIndex(nameIndexForSymbol(s)); // In case the sequence referenced is not defined, return NAN if (seq.fullName() == nullptr) { return Float::Builder(NAN); } Expression rank = symbol.childAtIndex(0); if (rank.isNumber()) { return Float::Builder(seq.valueAtRank(rank.approximateToScalar(this, Poincare::Preferences::ComplexFormat::Cartesian, Poincare::Preferences::AngleUnit::Radian), m_sequenceContext)); } else { return Float::Builder(NAN); } } } return ContextWithParent::expressionForSymbolAbstract(symbol, clone); } template void CacheContext::setValueForSymbol(T value, const Poincare::Symbol & symbol) { m_values[nameIndexForSymbol(symbol)][rankIndexForSymbol(symbol)] = value; } template int CacheContext::nameIndexForSymbol(const Poincare::Symbol & symbol) { assert(symbol.name()[0] >= 'u' && symbol.name()[0] <= 'w'); // [u|v|w] char name = symbol.name()[0]; assert(name >= SequenceStore::k_sequenceNames[0][0] && name <= SequenceStore::k_sequenceNames[MaxNumberOfSequences-1][0]); // u, v or w return name - 'u'; } template int CacheContext::rankIndexForSymbol(const Poincare::Symbol & symbol) { assert(strcmp(symbol.name()+1, "(n)") == 0 || strcmp(symbol.name()+1, "(n+1)") == 0); // u(n) or u(n+1) if (symbol.name()[3] == ')') { // (n) return 0; } // (n+1) return 1; } template class CacheContext; template class CacheContext; }