[poincare] Context::expressionForSymbol takes a boolean notifying that

we want a copy or not
This commit is contained in:
Émilie Feral
2018-11-16 16:57:25 +01:00
parent b44c5e6d05
commit e80512f362
18 changed files with 35 additions and 35 deletions

View File

@@ -9,7 +9,7 @@ using namespace Shared;
namespace Regression {
const Expression RegressionContext::expressionForSymbol(const SymbolAbstract & symbol) {
const Expression RegressionContext::expressionForSymbol(const SymbolAbstract & symbol, bool clone) {
if (symbol.type() == ExpressionNode::Type::Symbol && Symbol::isRegressionSymbol(symbol.name())) {
const char * seriesName = symbol.name();
assert(strlen(seriesName) == 2);
@@ -24,7 +24,7 @@ const Expression RegressionContext::expressionForSymbol(const SymbolAbstract & s
assert(m_seriesPairIndex < m_store->numberOfPairsOfSeries(series));
return Float<double>(m_store->get(series, storeI, m_seriesPairIndex));
} else {
return m_parentContext->expressionForSymbol(symbol);
return m_parentContext->expressionForSymbol(symbol, clone);
}
}

View File

@@ -9,7 +9,7 @@ namespace Regression {
class RegressionContext : public Shared::StoreContext {
public:
using Shared::StoreContext::StoreContext;
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol) override;
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol, bool clone) override;
};
}

View File

@@ -15,7 +15,7 @@ CacheContext<T>::CacheContext(Context * parentContext) :
}
template<typename T>
const Expression CacheContext<T>::expressionForSymbol(const SymbolAbstract & symbol) {
const Expression CacheContext<T>::expressionForSymbol(const SymbolAbstract & symbol, bool clone) {
// [u|v](n(+1)?)
if (symbol.type() == ExpressionNode::Type::Symbol
&& (symbol.name()[0] == SequenceStore::k_sequenceNames[0][0] || symbol.name()[0] == SequenceStore::k_sequenceNames[1][0])
@@ -24,7 +24,7 @@ const Expression CacheContext<T>::expressionForSymbol(const SymbolAbstract & sym
Symbol s = const_cast<Symbol &>(static_cast<const Symbol &>(symbol));
return Float<T>(m_values[nameIndexForSymbol(s)][rankIndexForSymbol(s)]);
}
return VariableContext::expressionForSymbol(symbol);
return VariableContext::expressionForSymbol(symbol, clone);
}
template<typename T>

View File

@@ -13,7 +13,7 @@ template<typename T>
class CacheContext : public Poincare::VariableContext {
public:
CacheContext(Poincare::Context * parentContext);
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol) override;
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol, bool clone) override;
void setValueForSymbol(T value, const Poincare::Symbol & symbol);
private:
int nameIndexForSymbol(const Poincare::Symbol & symbol);

View File

@@ -45,8 +45,8 @@ public:
* context respective methods. Indeed, special chars like n, u(n), u(n+1),
* v(n), v(n+1) are taken into accound only when evaluating sequences which
* is done in another context. */
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol) override {
return m_parentContext->expressionForSymbol(symbol);
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol, bool clone) override {
return m_parentContext->expressionForSymbol(symbol, clone);
}
void setExpressionForSymbol(const Poincare::Expression & expression, const Poincare::SymbolAbstract & symbol, Poincare::Context & context) override {
m_parentContext->setExpressionForSymbol(expression, symbol, context);

View File

@@ -60,7 +60,7 @@ void GlobalContext::DestroyRecordsBaseNamedWithoutExtension(const char * baseNam
}
}
const Expression GlobalContext::expressionForSymbol(const SymbolAbstract & symbol) {
const Expression GlobalContext::expressionForSymbol(const SymbolAbstract & symbol, bool clone) {
Ion::Storage::Record r = SymbolAbstractRecordWithBaseName(symbol.name());
return ExpressionForSymbolAndRecord(symbol, r);
}

View File

@@ -38,7 +38,7 @@ public:
/* Expression for symbol
* The expression recorded in global context is already an expression.
* Otherwise, we would need the context and the angle unit to evaluate it */
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol) override;
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol, bool clone) override;
void setExpressionForSymbol(
const Poincare::Expression & expression,
const Poincare::SymbolAbstract & symbol,

View File

@@ -9,7 +9,7 @@ using namespace Shared;
namespace Statistics {
const Expression StatisticsContext::expressionForSymbol(const SymbolAbstract & symbol) {
const Expression StatisticsContext::expressionForSymbol(const SymbolAbstract & symbol, bool clone) {
if (symbol.type() == ExpressionNode::Type::Symbol && Symbol::isSeriesSymbol(symbol.name())) {
const char * seriesName = symbol.name();
assert(strlen(seriesName) == 2);
@@ -24,7 +24,7 @@ const Expression StatisticsContext::expressionForSymbol(const SymbolAbstract & s
assert(m_seriesPairIndex < m_store->numberOfPairsOfSeries(series));
return Float<double>(m_store->get(series, storeI, m_seriesPairIndex));
} else {
return m_parentContext->expressionForSymbol(symbol);
return m_parentContext->expressionForSymbol(symbol, clone);
}
}

View File

@@ -8,7 +8,7 @@ namespace Statistics {
class StatisticsContext : public Shared::StoreContext {
public:
using Shared::StoreContext::StoreContext;
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol) override;
const Poincare::Expression expressionForSymbol(const Poincare::SymbolAbstract & symbol, bool clone) override;
};
}

View File

@@ -8,7 +8,7 @@ class SymbolAbstract;
class Context {
public:
virtual const Expression expressionForSymbol(const SymbolAbstract & symbol) = 0;
virtual const Expression expressionForSymbol(const SymbolAbstract & symbol, bool clone) = 0;
virtual void setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context & context) = 0;
};

View File

@@ -82,7 +82,7 @@ public:
Expression replaceReplaceableSymbols(Context & context);
private:
SymbolNode * node() const { return static_cast<SymbolNode *>(Expression::node()); }
Expression expand(Context & context) const;
Expression expand(Context & context, bool cloneContextValue) const;
};
}

View File

@@ -58,7 +58,7 @@ public:
static size_t TruncateExtension(char * dst, const char * src, size_t len);
static bool ValidInContext(SymbolAbstract & s, Context * context) {
// Retrive from context the expression corresponding to s
Expression f = context ? context->expressionForSymbol(s) : Expression();
Expression f = context ? context->expressionForSymbol(s, false) : Expression();
return f.isUninitialized() || f.type() == s.type();
}
constexpr static size_t k_maxNameSize = 8;

View File

@@ -14,7 +14,7 @@ public:
// Context
void setExpressionForSymbol(const Expression & expression, const SymbolAbstract & symbol, Context & context) override;
const Expression expressionForSymbol(const SymbolAbstract & symbol) override;
const Expression expressionForSymbol(const SymbolAbstract & symbol, bool clone) override;
private:
const char * m_name;

View File

@@ -227,9 +227,9 @@ bool Expression::hasReplaceableSymbols(Context & context) const {
return recursivelyMatches([](const Expression e, Context & context, bool replaceSymbols) {
return (e.type() == ExpressionNode::Type::Symbol
&& !static_cast<const Symbol &>(e).isSystemSymbol()
&& !context.expressionForSymbol(static_cast<const Symbol &>(e)).isUninitialized())
&& !context.expressionForSymbol(static_cast<const Symbol &>(e), false).isUninitialized())
|| (e.type() == ExpressionNode::Type::Function
&& !context.expressionForSymbol(static_cast<const Function &>(e)).isUninitialized());
&& !context.expressionForSymbol(static_cast<const Function &>(e), false).isUninitialized());
}, context, false);
}

View File

@@ -121,7 +121,7 @@ Expression Function::shallowReduce(Context & context, Preferences::AngleUnit ang
}
Expression Function::replaceReplaceableSymbols(Context & context) {
Expression e = context.expressionForSymbol(*this);
Expression e = context.expressionForSymbol(*this, true);
if (e.isUninitialized()) {
return *this;
}
@@ -131,7 +131,7 @@ Expression Function::replaceReplaceableSymbols(Context & context) {
}
Expression Function::expand(Context & context) const {
Expression e = context.expressionForSymbol(*this);
Expression e = context.expressionForSymbol(*this, true);
e = ExpressionWithoutSymbols(e, context);
if (!e.isUninitialized()) {
e = e.replaceSymbolWithExpression(Symbol(Symbol::SpecialSymbols::UnknownX), childAtIndex(0));
@@ -155,7 +155,7 @@ VariableContext Function::unknownXContext(Context & parentContext) const {
/* If the parentContext already has an expression for UnknownX, we have to
* replace in childAtIndex(0) any occurence of UnknownX by its value in
* parentContext. That way, we handle: evaluatin f(x-1) with x = 2 & f:x->x^2 */
Expression unknownXValue = parentContext.expressionForSymbol(unknownXSymbol);
Expression unknownXValue = parentContext.expressionForSymbol(unknownXSymbol, true);
if (!unknownXValue.isUninitialized()) {
xContext = static_cast<VariableContext &>(parentContext); // copy the parentContext
child.replaceSymbolWithExpression(unknownXSymbol, unknownXValue);

View File

@@ -47,7 +47,7 @@ Evaluation<T> StoreNode::templatedApproximate(Context& context, Preferences::Ang
Store s(this);
assert(!s.value().isUninitialized());
context.setExpressionForSymbol(s.value(), s.symbol(), context);
Expression e = context.expressionForSymbol(s.symbol());
Expression e = context.expressionForSymbol(s.symbol(), false);
if (e.isUninitialized()) {
return Complex<T>::Undefined();
}
@@ -68,7 +68,7 @@ Expression Store::shallowReduce(Context & context, Preferences::AngleUnit angleU
}
assert(!finalValue.isUninitialized());
context.setExpressionForSymbol(finalValue, symbol(), context);
Expression e = context.expressionForSymbol(symbol());
Expression e = context.expressionForSymbol(symbol(), true);
if (e.isUninitialized()) {
return Undefined();
}

View File

@@ -17,8 +17,8 @@ constexpr char Symbol::k_ans[];
/*ExpressionNode::Sign SymbolNode::sign() const {
TODO: Maybe, we will want to know that from a context given in parameter:
if (context.expressionForSymbol(this) != nullptr) {
return context.expressionForSymbol(this)->sign(context);
if (context.expressionForSymbol(this, false) != nullptr) {
return context.expressionForSymbol(this, false)->sign(context);
}
}
*/
@@ -126,7 +126,7 @@ Expression SymbolNode::replaceReplaceableSymbols(Context & context) {
template<typename T>
Evaluation<T> SymbolNode::templatedApproximate(Context& context, Preferences::AngleUnit angleUnit) const {
Expression e = Symbol(this).expand(context);
Expression e = Symbol(this).expand(context, false);
if (e.isUninitialized()) {
return Complex<T>::Undefined();
}
@@ -156,7 +156,7 @@ bool Symbol::isRegressionSymbol(const char * c) {
}
bool Symbol::matches(ExpressionTest test, Context & context) const {
Expression e = expand(context);
Expression e = expand(context, false);
return !e.isUninitialized() && test(e, context, true);
}
@@ -164,7 +164,7 @@ Expression Symbol::shallowReduce(Context & context, Preferences::AngleUnit angle
if (!replaceSymbols) {
return *this;
}
Expression result = expand(context);
Expression result = expand(context, true);
if (result.isUninitialized()) {
return *this;
}
@@ -200,7 +200,7 @@ Expression Symbol::replaceReplaceableSymbols(Context & context) {
if (isSystemSymbol()) {
return *this;
}
Expression e = context.expressionForSymbol(*this);
Expression e = context.expressionForSymbol(*this, true);
if (e.isUninitialized()) {
return *this;
}
@@ -208,10 +208,10 @@ Expression Symbol::replaceReplaceableSymbols(Context & context) {
return e;
}
Expression Symbol::expand(Context & context) const {
Expression Symbol::expand(Context & context, bool clone) const {
/* Replace all the symbols iteratively. This prevents a memory failure when
* symbols are defined circularly. */
Expression e = context.expressionForSymbol(*this);
Expression e = context.expressionForSymbol(*this, clone);
return ExpressionWithoutSymbols(e, context);
}

View File

@@ -29,11 +29,11 @@ void VariableContext::setExpressionForSymbol(const Expression & expression, cons
}
}
const Expression VariableContext::expressionForSymbol(const SymbolAbstract & symbol) {
const Expression VariableContext::expressionForSymbol(const SymbolAbstract & symbol, bool clone) {
if (strcmp(symbol.name(), m_name) == 0) {
return m_value.clone();
return clone ? m_value.clone() : m_value;
} else {
return m_parentContext->expressionForSymbol(symbol);
return m_parentContext->expressionForSymbol(symbol, clone);
}
}