[poincare] Avoid returning partial simplification when the

simplification process has been interrupted
This commit is contained in:
Émilie Feral
2018-01-24 10:34:23 +01:00
committed by EmilieNumworks
parent e4c6636b08
commit 59fdcde548
5 changed files with 32 additions and 24 deletions

View File

@@ -71,8 +71,7 @@ void Calculation::setContent(const char * c, Context * context, CalculationStore
/* We do not store directly the text enter by the user but its serialization
* to be able to compare it to the exact ouput text. */
m_input->writeTextInBuffer(m_inputText, sizeof(m_inputText));
m_exactOutput = input()->clone();
Expression::Simplify(&m_exactOutput, *context);
m_exactOutput = Expression::ParseAndSimplify(m_inputText, *context);
m_exactOutput->writeTextInBuffer(m_exactOutputText, sizeof(m_exactOutputText));
m_approximateOutput = m_exactOutput->approximate<double>(*context);
m_approximateOutput->writeTextInBuffer(m_approximateOutputText, sizeof(m_approximateOutputText));
@@ -148,13 +147,8 @@ void Calculation::tidy() {
Expression * Calculation::exactOutput(Context * context) {
if (m_exactOutput == nullptr) {
/* To ensure that the expression 'm_exactOutput' is a simplified, we
* call 'simplifyAndBeautify'. */
m_exactOutput = Expression::parse(m_exactOutputText);
if (m_exactOutput != nullptr) {
Expression::Simplify(&m_exactOutput, *context);
} else {
m_exactOutput = new Undefined();
}
* call 'ParseAndSimplify'. */
m_exactOutput = Expression::ParseAndSimplify(m_exactOutputText, *context);
}
return m_exactOutput;
}

View File

@@ -149,20 +149,14 @@ void Sequence::setInitialRank(int rank) {
Poincare::Expression * Sequence::firstInitialConditionExpression(Context * context) const {
if (m_firstInitialConditionExpression == nullptr) {
m_firstInitialConditionExpression = Poincare::Expression::parse(m_firstInitialConditionText);
if (m_firstInitialConditionExpression) {
Expression::Simplify(&m_firstInitialConditionExpression, *context);
}
m_firstInitialConditionExpression = Poincare::Expression::ParseAndSimplify(m_firstInitialConditionText, *context);
}
return m_firstInitialConditionExpression;
}
Poincare::Expression * Sequence::secondInitialConditionExpression(Context * context) const {
if (m_secondInitialConditionExpression == nullptr) {
m_secondInitialConditionExpression = Poincare::Expression::parse(m_secondInitialConditionText);
if (m_secondInitialConditionExpression) {
Expression::Simplify(&m_secondInitialConditionExpression, *context);
}
m_secondInitialConditionExpression = Poincare::Expression::ParseAndSimplify(m_secondInitialConditionText, *context);
}
return m_secondInitialConditionExpression;
}

View File

@@ -71,10 +71,7 @@ const char * Function::name() const {
Poincare::Expression * Function::expression(Poincare::Context * context) const {
if (m_expression == nullptr) {
m_expression = Expression::parse(m_text);
if (m_expression) {
Expression::Simplify(&m_expression, *context);
}
m_expression = Expression::ParseAndSimplify(m_text, *context);
}
return m_expression;
}

View File

@@ -217,6 +217,7 @@ public:
virtual int writeTextInBuffer(char * buffer, int bufferSize) const = 0;
/* Simplification */
static Expression * ParseAndSimplify(const char * text, Context & context, AngleUnit angleUnit = AngleUnit::Default);
static void Simplify(Expression ** expressionAddress, Context & context, AngleUnit angleUnit = AngleUnit::Default);
/* Evaluation Engine

View File

@@ -56,6 +56,7 @@ Expression * Expression::replaceSymbolWithExpression(char symbol, Expression * e
/* Circuit breaker */
static Expression::CircuitBreaker sCircuitBreaker = nullptr;
static bool sSimplificationHasBeenInterrupted = false;
void Expression::setCircuitBreaker(CircuitBreaker cb) {
sCircuitBreaker = cb;
@@ -65,7 +66,11 @@ bool Expression::shouldStopProcessing() {
if (sCircuitBreaker == nullptr) {
return false;
}
return sCircuitBreaker();
if (sCircuitBreaker()) {
sSimplificationHasBeenInterrupted = true;
return true;
}
return false;
}
/* Hierarchy */
@@ -229,7 +234,20 @@ ExpressionLayout * Expression::createLayout(FloatDisplayMode floatDisplayMode, C
/* Simplification */
Expression * Expression::ParseAndSimplify(const char * text, Context & context, AngleUnit angleUnit) {
Expression * exp = parse(text);
if (exp == nullptr) {
return new Undefined();
}
Simplify(&exp, context, angleUnit);
if (exp == nullptr) {
return parse(text);
}
return exp;
}
void Expression::Simplify(Expression ** expressionAddress, Context & context, AngleUnit angleUnit) {
sSimplificationHasBeenInterrupted = false;
if (angleUnit == AngleUnit::Default) {
angleUnit = Preferences::sharedPreferences()->angleUnit();
}
@@ -243,6 +261,11 @@ void Expression::Simplify(Expression ** expressionAddress, Context & context, An
root.editableOperand(0)->deepReduce(context, angleUnit);
root.editableOperand(0)->deepBeautify(context, angleUnit);
*expressionAddress = root.editableOperand(0);
if (sSimplificationHasBeenInterrupted) {
root.detachOperands();
delete *expressionAddress;
*expressionAddress = nullptr;
}
}
@@ -310,8 +333,7 @@ template<typename T> T Expression::approximateToScalar(Context& context, AngleUn
}
template<typename T> T Expression::approximateToScalar(const char * text, Context& context, AngleUnit angleUnit) {
Expression * exp = parse(text);
Simplify(&exp, context, angleUnit);
Expression * exp = ParseAndSimplify(text, context, angleUnit);
T result = exp->approximateToScalar<T>(context, angleUnit);
delete exp;
return result;