From 61b1b8a09dfe050c5bd2281b13231a4de61a0321 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 24 Oct 2018 15:03:24 +0200 Subject: [PATCH] [poincare] Add Expression::FunctionHelper class That class is meant to contain data about named functions (e.g. sin, tan...) in one place: their name, their number of children and a pointer to a builder. The derived class corresponding to each such function contains a private instance (m_functionHelper) and a getter. The previous parser is removed, along with unecessary constructors (used by the previous parsers). --- apps/regression/model/trigonometric_model.cpp | 2 +- apps/shared/storage_cartesian_function.cpp | 5 +- apps/solver/equation_store.cpp | 4 +- poincare/Makefile | 24 --- poincare/include/poincare/absolute_value.h | 14 +- .../include/poincare/absolute_value_layout.h | 2 +- poincare/include/poincare/addition.h | 1 - poincare/include/poincare/arc_cosine.h | 15 +- poincare/include/poincare/arc_sine.h | 14 +- poincare/include/poincare/arc_tangent.h | 14 +- .../include/poincare/binomial_coefficient.h | 15 +- poincare/include/poincare/ceiling.h | 14 +- poincare/include/poincare/ceiling_layout.h | 2 +- poincare/include/poincare/complex_argument.h | 14 +- .../include/poincare/condensed_sum_layout.h | 2 +- .../include/poincare/confidence_interval.h | 30 +-- poincare/include/poincare/conjugate.h | 14 +- poincare/include/poincare/cosine.h | 14 +- poincare/include/poincare/derivative.h | 18 +- poincare/include/poincare/determinant.h | 14 +- poincare/include/poincare/division.h | 1 - poincare/include/poincare/division_quotient.h | 16 +- .../include/poincare/division_remainder.h | 16 +- poincare/include/poincare/equal.h | 6 +- poincare/include/poincare/expression.h | 19 ++ poincare/include/poincare/factor.h | 14 +- poincare/include/poincare/factorial.h | 4 +- poincare/include/poincare/floor.h | 14 +- poincare/include/poincare/floor_layout.h | 2 +- poincare/include/poincare/frac_part.h | 14 +- poincare/include/poincare/function.h | 4 +- .../include/poincare/great_common_divisor.h | 16 +- .../include/poincare/hyperbolic_arc_cosine.h | 12 +- .../include/poincare/hyperbolic_arc_sine.h | 12 +- .../include/poincare/hyperbolic_arc_tangent.h | 12 +- poincare/include/poincare/hyperbolic_cosine.h | 12 +- poincare/include/poincare/hyperbolic_sine.h | 12 +- .../include/poincare/hyperbolic_tangent.h | 12 +- poincare/include/poincare/imaginary_part.h | 14 +- poincare/include/poincare/integral.h | 20 +- .../include/poincare/least_common_multiple.h | 16 +- poincare/include/poincare/logarithm.h | 27 ++- poincare/include/poincare/matrix_dimension.h | 14 +- poincare/include/poincare/matrix_inverse.h | 14 +- poincare/include/poincare/matrix_trace.h | 14 +- poincare/include/poincare/matrix_transpose.h | 14 +- .../include/poincare/naperian_logarithm.h | 14 +- poincare/include/poincare/nth_root.h | 16 +- poincare/include/poincare/opposite.h | 4 +- .../include/poincare/permute_coefficient.h | 15 +- poincare/include/poincare/power.h | 1 - .../include/poincare/prediction_interval.h | 16 +- poincare/include/poincare/product.h | 18 +- poincare/include/poincare/randint.h | 12 +- poincare/include/poincare/random.h | 8 +- poincare/include/poincare/real_part.h | 14 +- poincare/include/poincare/round.h | 16 +- poincare/include/poincare/sine.h | 14 +- poincare/include/poincare/square_root.h | 18 +- poincare/include/poincare/subtraction.h | 7 +- poincare/include/poincare/sum.h | 18 +- poincare/include/poincare/tangent.h | 14 +- poincare/src/absolute_value.cpp | 7 +- poincare/src/addition.cpp | 4 +- poincare/src/arc_cosine.cpp | 10 +- poincare/src/arc_sine.cpp | 10 +- poincare/src/arc_tangent.cpp | 10 +- poincare/src/binomial_coefficient.cpp | 8 +- poincare/src/binomial_coefficient_layout.cpp | 2 +- poincare/src/ceiling.cpp | 8 +- poincare/src/complex_argument.cpp | 11 +- poincare/src/confidence_interval.cpp | 16 +- poincare/src/conjugate.cpp | 8 +- poincare/src/conjugate_layout.cpp | 2 +- poincare/src/cosine.cpp | 10 +- poincare/src/derivative.cpp | 11 +- poincare/src/determinant.cpp | 10 +- poincare/src/division.cpp | 2 +- poincare/src/division_quotient.cpp | 10 +- poincare/src/division_remainder.cpp | 9 +- poincare/src/expression.cpp | 7 - poincare/src/expression_lexer.l | 188 ------------------ poincare/src/expression_lexer_parser.h | 5 - poincare/src/expression_parser.y | 174 ---------------- poincare/src/factor.cpp | 10 +- poincare/src/floor.cpp | 8 +- poincare/src/frac_part.cpp | 10 +- poincare/src/great_common_divisor.cpp | 10 +- poincare/src/hyperbolic_arc_cosine.cpp | 6 +- poincare/src/hyperbolic_arc_sine.cpp | 6 +- poincare/src/hyperbolic_arc_tangent.cpp | 6 +- poincare/src/hyperbolic_cosine.cpp | 6 +- poincare/src/hyperbolic_sine.cpp | 6 +- poincare/src/hyperbolic_tangent.cpp | 6 +- poincare/src/imaginary_part.cpp | 10 +- poincare/src/integral.cpp | 9 +- poincare/src/least_common_multiple.cpp | 10 +- poincare/src/logarithm.cpp | 18 +- poincare/src/matrix_dimension.cpp | 10 +- poincare/src/matrix_inverse.cpp | 10 +- poincare/src/matrix_trace.cpp | 10 +- poincare/src/matrix_transpose.cpp | 10 +- poincare/src/multiplication.cpp | 2 +- poincare/src/naperian_logarithm.cpp | 12 +- poincare/src/nth_root.cpp | 8 +- poincare/src/nth_root_layout.cpp | 4 +- poincare/src/permute_coefficient.cpp | 10 +- poincare/src/power.cpp | 10 +- poincare/src/prediction_interval.cpp | 10 +- poincare/src/product.cpp | 4 +- poincare/src/randint.cpp | 8 +- poincare/src/random.cpp | 10 +- poincare/src/real_part.cpp | 10 +- poincare/src/round.cpp | 12 +- poincare/src/sine.cpp | 10 +- poincare/src/square_root.cpp | 8 +- poincare/src/subtraction.cpp | 4 +- poincare/src/sum.cpp | 4 +- poincare/src/tangent.cpp | 14 +- poincare/src/trigonometry.cpp | 2 +- 120 files changed, 660 insertions(+), 933 deletions(-) delete mode 100644 poincare/src/expression_lexer.l delete mode 100644 poincare/src/expression_lexer_parser.h delete mode 100644 poincare/src/expression_parser.y diff --git a/apps/regression/model/trigonometric_model.cpp b/apps/regression/model/trigonometric_model.cpp index 252e88f8c..f7e5380ef 100644 --- a/apps/regression/model/trigonometric_model.cpp +++ b/apps/regression/model/trigonometric_model.cpp @@ -51,7 +51,7 @@ Expression TrigonometricModel::simplifiedExpression(double * modelCoefficients, Addition( Multiplication( Number::DecimalNumber(a), - Sine( + Sine::Builder( Addition( Multiplication( Number::DecimalNumber(b), diff --git a/apps/shared/storage_cartesian_function.cpp b/apps/shared/storage_cartesian_function.cpp index 2ce4cdf7d..088930577 100644 --- a/apps/shared/storage_cartesian_function.cpp +++ b/apps/shared/storage_cartesian_function.cpp @@ -85,7 +85,7 @@ void StorageCartesianFunction::setDisplayDerivative(bool display) { } double StorageCartesianFunction::approximateDerivative(double x, Poincare::Context * context) const { - Poincare::Derivative derivative(expression(context).clone(), Symbol(Symbol::SpecialSymbols::UnknownX), Poincare::Float(x)); // derivative takes ownership of Poincare::Float(x) and the clone of expression + Poincare::Derivative derivative = Poincare::Derivative::Builder(expression(context).clone(), Symbol(Symbol::SpecialSymbols::UnknownX), Poincare::Float(x)); // derivative takes ownership of Poincare::Float(x) and the clone of expression /* TODO: when we approximate derivative, we might want to simplify the * derivative here. However, we might want to do it once for all x (to avoid * lagging in the derivative table. */ @@ -93,7 +93,8 @@ double StorageCartesianFunction::approximateDerivative(double x, Poincare::Conte } double StorageCartesianFunction::sumBetweenBounds(double start, double end, Poincare::Context * context) const { - Poincare::Integral integral(expression(context).clone(), Symbol(Symbol::SpecialSymbols::UnknownX), Poincare::Float(start), Poincare::Float(end)); // Integral takes ownership of args + // TODO: this does not work yet because integral does not understand UnknownX + Poincare::Integral integral = Poincare::Integral::Builder(expression(context).clone(), Symbol(Symbol::SpecialSymbols::UnknownX), Poincare::Float(start), Poincare::Float(end)); // Integral takes ownership of args /* TODO: when we approximate integral, we might want to simplify the integral * here. However, we might want to do it once for all x (to avoid lagging in * the derivative table. */ diff --git a/apps/solver/equation_store.cpp b/apps/solver/equation_store.cpp index f6132561f..1347548b1 100644 --- a/apps/solver/equation_store.cpp +++ b/apps/solver/equation_store.cpp @@ -250,9 +250,9 @@ EquationStore::Error EquationStore::oneDimensialPolynomialSolve(Expression exact m_numberOfSolutions = 1; } else { // x0 = (-b-sqrt(delta))/(2a) - exactSolutions[0] = Division(Subtraction(Opposite(coefficients[1].clone()), SquareRoot(delta.clone())), Multiplication(Rational(2), coefficients[2].clone())); + exactSolutions[0] = Division(Subtraction(Opposite(coefficients[1].clone()), SquareRoot::Builder(delta.clone())), Multiplication(Rational(2), coefficients[2].clone())); // x1 = (-b+sqrt(delta))/(2a) - exactSolutions[1] = Division(Addition(Opposite(coefficients[1]), SquareRoot(delta.clone())), Multiplication(Rational(2), coefficients[2])); + exactSolutions[1] = Division(Addition(Opposite(coefficients[1]), SquareRoot::Builder(delta.clone())), Multiplication(Rational(2), coefficients[2])); m_numberOfSolutions = 2; } exactSolutions[m_numberOfSolutions] = delta; diff --git a/poincare/Makefile b/poincare/Makefile index 971a34495..00db1741e 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -63,9 +63,7 @@ objs += $(addprefix poincare/src/,\ equal.o\ evaluation.o\ expression.o\ - expression_lexer.o\ expression_node.o\ - expression_parser.o\ factor.o\ factorial.o\ float.o\ @@ -186,25 +184,3 @@ endif ifdef POINCARE_TREE_LOG SFLAGS += -DPOINCARE_TREE_LOG=1 endif - -# Even though flex and bison will generate both implementation and headers at -# once, we don't declare it in the Makefile. If we did, "make -jN" with N>1 may -# call bison or flex twice. - -lexer_files = $(addprefix poincare/src/, expression_lexer.cpp expression_lexer.hpp) -poincare/src/expression_lexer.hpp: poincare/src/expression_lexer.cpp -poincare/src/expression_lexer.cpp: poincare/src/expression_lexer.l - @echo "FLEX $(lexer_files)" - $(Q) flex -P poincare_expression_yy --header-file=poincare/src/expression_lexer.hpp -o poincare/src/expression_lexer.cpp $< - -poincare/src/expression_lexer.o: CXXFLAGS += -Wno-deprecated-register -Wno-unused-value -Wno-unused-function - -parser_files = $(addprefix poincare/src/, expression_parser.cpp expression_parser.hpp) -poincare/src/expression_parser.hpp: poincare/src/expression_parser.cpp -poincare/src/expression_parser.cpp: poincare/src/expression_parser.y - @echo "BISON $(parser_files)" - $(Q) bison -d -p poincare_expression_yy -o poincare/src/expression_parser.cpp $< - -poincare/src/expression.cpp: $(lexer_files) $(parser_files) - -products += $(lexer_files) $(parser_files) diff --git a/poincare/include/poincare/absolute_value.h b/poincare/include/poincare/absolute_value.h index d1e592f84..b47508ec7 100644 --- a/poincare/include/poincare/absolute_value.h +++ b/poincare/include/poincare/absolute_value.h @@ -44,17 +44,19 @@ public: class AbsoluteValue final : public Expression { friend class AbsoluteValueNode; public: - AbsoluteValue(); AbsoluteValue(const AbsoluteValueNode * n) : Expression(n) {} - explicit AbsoluteValue(Expression operand) : AbsoluteValue() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "abs"; } - static const int NumberOfChildren() { return 1; } + static AbsoluteValue Builder(Expression child) { return AbsoluteValue(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); private: + explicit AbsoluteValue(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } Expression setSign(ExpressionNode::Sign s, Context & context, Preferences::AngleUnit angleUnit); + + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/absolute_value_layout.h b/poincare/include/poincare/absolute_value_layout.h index a1c452b4b..b6edb8b31 100644 --- a/poincare/include/poincare/absolute_value_layout.h +++ b/poincare/include/poincare/absolute_value_layout.h @@ -13,7 +13,7 @@ public: // SerializationHelperInterface int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, AbsoluteValue::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, AbsoluteValue::FunctionHelper()->name()); } // TreeNode diff --git a/poincare/include/poincare/addition.h b/poincare/include/poincare/addition.h index f5e71fd5c..7ff36d659 100644 --- a/poincare/include/poincare/addition.h +++ b/poincare/include/poincare/addition.h @@ -73,7 +73,6 @@ public: addChildAtIndexInPlace(children[i], i, i); } } - static const char * Name() { return "+"; } // Expression Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); Expression shallowBeautify(Context & context, Preferences::AngleUnit angleUnit); diff --git a/poincare/include/poincare/arc_cosine.h b/poincare/include/poincare/arc_cosine.h index 0ef96f9d0..860ba7371 100644 --- a/poincare/include/poincare/arc_cosine.h +++ b/poincare/include/poincare/arc_cosine.h @@ -40,15 +40,18 @@ private: class ArcCosine final : public Expression { public: - ArcCosine(); ArcCosine(const ArcCosineNode * n) : Expression(n) {} - explicit ArcCosine(Expression operand) : ArcCosine() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "acos"; } - static const int NumberOfChildren() { return 1; } + static ArcCosine Builder(Expression child) { return ArcCosine(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit ArcCosine(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/arc_sine.h b/poincare/include/poincare/arc_sine.h index b1b64edd2..5a01a865f 100644 --- a/poincare/include/poincare/arc_sine.h +++ b/poincare/include/poincare/arc_sine.h @@ -39,15 +39,17 @@ private: class ArcSine final : public Expression { public: - ArcSine(); ArcSine(const ArcSineNode * n) : Expression(n) {} - explicit ArcSine(Expression operand) : ArcSine() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "asin"; } - static const int NumberOfChildren() { return 1; } + static ArcSine Builder(Expression child) { return ArcSine(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit ArcSine(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/arc_tangent.h b/poincare/include/poincare/arc_tangent.h index e7d9ac4e1..01ad81583 100644 --- a/poincare/include/poincare/arc_tangent.h +++ b/poincare/include/poincare/arc_tangent.h @@ -39,15 +39,17 @@ private: class ArcTangent final : public Expression { public: - ArcTangent(); ArcTangent(const ArcTangentNode * n) : Expression(n) {} - explicit ArcTangent(Expression operand) : ArcTangent() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "atan"; } - static const int NumberOfChildren() { return 1; } + static ArcTangent Builder(Expression child) { return ArcTangent(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit ArcTangent(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/binomial_coefficient.h b/poincare/include/poincare/binomial_coefficient.h index 5caed992d..68285dcfb 100644 --- a/poincare/include/poincare/binomial_coefficient.h +++ b/poincare/include/poincare/binomial_coefficient.h @@ -37,18 +37,19 @@ private: class BinomialCoefficient final : public Expression { public: - BinomialCoefficient(); BinomialCoefficient(const BinomialCoefficientNode * n) : Expression(n) {} - BinomialCoefficient(Expression child1, Expression child2) : BinomialCoefficient() { - replaceChildAtIndexInPlace(0, child1); - replaceChildAtIndexInPlace(1, child2); - } - static const char * Name() { return "binomial"; } - static const int NumberOfChildren() { return 2; } + static BinomialCoefficient Builder(Expression child0, Expression child1) { return BinomialCoefficient(child0, child1); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } // Expression Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); private: + BinomialCoefficient(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + } + static const Expression::FunctionHelper m_functionHelper; constexpr static int k_maxNValue = 300; }; diff --git a/poincare/include/poincare/ceiling.h b/poincare/include/poincare/ceiling.h index 6fe7887c4..924607adc 100644 --- a/poincare/include/poincare/ceiling.h +++ b/poincare/include/poincare/ceiling.h @@ -38,15 +38,17 @@ private: class Ceiling final : public Expression { public: - Ceiling(); Ceiling(const CeilingNode * n) : Expression(n) {} - explicit Ceiling(Expression operand) : Ceiling() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "ceil"; } - static const int NumberOfChildren() { return 1; } + static Ceiling Builder(Expression child) { return Ceiling(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit Ceiling(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/ceiling_layout.h b/poincare/include/poincare/ceiling_layout.h index 0b41a6392..996208fd8 100644 --- a/poincare/include/poincare/ceiling_layout.h +++ b/poincare/include/poincare/ceiling_layout.h @@ -13,7 +13,7 @@ public: using BracketPairLayoutNode::BracketPairLayoutNode; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Ceiling::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Ceiling::FunctionHelper()->name()); } // TreeNode diff --git a/poincare/include/poincare/complex_argument.h b/poincare/include/poincare/complex_argument.h index ac7473f13..65300c7d6 100644 --- a/poincare/include/poincare/complex_argument.h +++ b/poincare/include/poincare/complex_argument.h @@ -38,15 +38,17 @@ private: class ComplexArgument final : public Expression { public: - ComplexArgument(); ComplexArgument(const ComplexArgumentNode * n) : Expression(n) {} - explicit ComplexArgument(Expression operand) : ComplexArgument() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "arg"; } - static const int NumberOfChildren() { return 1; } + static ComplexArgument Builder(Expression child) { return ComplexArgument(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit ComplexArgument(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/condensed_sum_layout.h b/poincare/include/poincare/condensed_sum_layout.h index 3490e90e0..fb83a5b27 100644 --- a/poincare/include/poincare/condensed_sum_layout.h +++ b/poincare/include/poincare/condensed_sum_layout.h @@ -20,7 +20,7 @@ public: void moveCursorUp(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override { assert(false); } void moveCursorDown(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override { assert(false); } int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Sum::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Sum::FunctionHelper()->name()); } LayoutNode * layoutToPointWhenInserting() override { diff --git a/poincare/include/poincare/confidence_interval.h b/poincare/include/poincare/confidence_interval.h index fa3485193..5624282ef 100644 --- a/poincare/include/poincare/confidence_interval.h +++ b/poincare/include/poincare/confidence_interval.h @@ -42,32 +42,36 @@ private: }; class ConfidenceInterval : public Expression { + friend class SimplePredictionInterval; public: - ConfidenceInterval(); ConfidenceInterval(const ConfidenceIntervalNode * n) : Expression(n) {} - ConfidenceInterval(Expression child1, Expression child2) : ConfidenceInterval() { - replaceChildAtIndexInPlace(0, child1); - replaceChildAtIndexInPlace(1, child2); - } - static const char * Name() { return "confidence"; } - static const int NumberOfChildren() { return 2; } + static ConfidenceInterval Builder(Expression child0, Expression child1) { return ConfidenceInterval(child0, child1); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } // Expression Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); private: + ConfidenceInterval(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + } + static const Expression::FunctionHelper m_functionHelper; constexpr static int k_maxNValue = 300; }; class SimplePredictionInterval final : public ConfidenceInterval { public: - SimplePredictionInterval() : ConfidenceInterval(static_cast(TreePool::sharedPool()->createTreeNode())) {} SimplePredictionInterval(const SimplePredictionIntervalNode * n) : ConfidenceInterval(n) {} - SimplePredictionInterval(Expression child1, Expression child2) : SimplePredictionInterval() { - replaceChildAtIndexInPlace(0, child1); - replaceChildAtIndexInPlace(1, child2); + static SimplePredictionInterval Builder(Expression child0, Expression child1) { return SimplePredictionInterval(child0, child1); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } +private: + SimplePredictionInterval(Expression child0, Expression child1) : ConfidenceInterval(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); } - static const char * Name() { return "prediction"; } - static const int NumberOfChildren() { return 2; } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/conjugate.h b/poincare/include/poincare/conjugate.h index 192254914..c2a906b58 100644 --- a/poincare/include/poincare/conjugate.h +++ b/poincare/include/poincare/conjugate.h @@ -38,15 +38,17 @@ private: class Conjugate final : public Expression { public: - Conjugate(); Conjugate(const ConjugateNode * n) : Expression(n) {} - explicit Conjugate(Expression operand) : Conjugate() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "conj"; } - static const int NumberOfChildren() { return 1; } + static Conjugate Builder(Expression child) { return Conjugate(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit Conjugate(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/cosine.h b/poincare/include/poincare/cosine.h index 85b2ad842..f3229a072 100644 --- a/poincare/include/poincare/cosine.h +++ b/poincare/include/poincare/cosine.h @@ -42,15 +42,17 @@ private: class Cosine final : public Expression { public: - Cosine(); Cosine(const CosineNode * n) : Expression(n) {} - explicit Cosine(Expression operand) : Cosine() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "cos"; } - static const int NumberOfChildren() { return 1; } + static Cosine Builder(Expression child) { return Cosine(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit Cosine(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/derivative.h b/poincare/include/poincare/derivative.h index 583244039..afdae0527 100644 --- a/poincare/include/poincare/derivative.h +++ b/poincare/include/poincare/derivative.h @@ -45,17 +45,19 @@ private: class Derivative final : public Expression { public: - Derivative(); Derivative(const DerivativeNode * n) : Expression(n) {} - Derivative(Expression child1, Expression child2, Expression child3) : Derivative() { - replaceChildAtIndexInPlace(0, child1); - replaceChildAtIndexInPlace(1, child2); - replaceChildAtIndexInPlace(2, child3); - } - static const char * Name() { return "diff"; } - static const int NumberOfChildren() { return 3; } + static Derivative Builder(Expression child0, Expression child1, Expression child2) { return Derivative(child0, child1, child2); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1), children.childAtIndex(2)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + Derivative(Expression child0, Expression child1, Expression child2) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + replaceChildAtIndexInPlace(2, child2); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/determinant.h b/poincare/include/poincare/determinant.h index 4bd485984..0e4fc1efc 100644 --- a/poincare/include/poincare/determinant.h +++ b/poincare/include/poincare/determinant.h @@ -34,15 +34,17 @@ private: class Determinant final : public Expression { public: - Determinant(); Determinant(const DeterminantNode * n) : Expression(n) {} - explicit Determinant(Expression operand) : Determinant() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "det"; } - static const int NumberOfChildren() { return 1; } + static Determinant Builder(Expression child) { return Determinant(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit Determinant(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/division.h b/poincare/include/poincare/division.h index d99ff7cbc..5b2ea25ae 100644 --- a/poincare/include/poincare/division.h +++ b/poincare/include/poincare/division.h @@ -65,7 +65,6 @@ public: replaceChildAtIndexInPlace(1, denominator); } Division(const DivisionNode * n) : Expression(n) {} - static const char * Name() { return "/"; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); }; diff --git a/poincare/include/poincare/division_quotient.h b/poincare/include/poincare/division_quotient.h index 953ec511f..c3aa82697 100644 --- a/poincare/include/poincare/division_quotient.h +++ b/poincare/include/poincare/division_quotient.h @@ -33,17 +33,19 @@ private: class DivisionQuotient final : public Expression { public: - DivisionQuotient(); DivisionQuotient(const DivisionQuotientNode * n) : Expression(n) {} - DivisionQuotient(Expression child1, Expression child2) : DivisionQuotient() { - replaceChildAtIndexInPlace(0, child1); - replaceChildAtIndexInPlace(1, child2); - } - static const char * Name() { return "quo"; } - static const int NumberOfChildren() { return 2; } + static DivisionQuotient Builder(Expression child0, Expression child1) { return DivisionQuotient(child0, child1); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } // Expression Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + DivisionQuotient(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/division_remainder.h b/poincare/include/poincare/division_remainder.h index f99b44974..6d253f45c 100644 --- a/poincare/include/poincare/division_remainder.h +++ b/poincare/include/poincare/division_remainder.h @@ -34,17 +34,19 @@ private: class DivisionRemainder final : public Expression { public: - DivisionRemainder(); DivisionRemainder(const DivisionRemainderNode * n) : Expression(n) {} - DivisionRemainder(Expression child1, Expression child2) : DivisionRemainder() { - replaceChildAtIndexInPlace(0, child1); - replaceChildAtIndexInPlace(1, child2); - } - static const char * Name() { return "rem"; } - static const int NumberOfChildren() { return 2; } + static DivisionRemainder Builder(Expression child0, Expression child1) { return DivisionRemainder(child0, child1); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } // Expression Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + DivisionRemainder(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/equal.h b/poincare/include/poincare/equal.h index 54e67248e..ab6171a1a 100644 --- a/poincare/include/poincare/equal.h +++ b/poincare/include/poincare/equal.h @@ -35,9 +35,9 @@ private: class Equal final : public Expression { public: Equal(const EqualNode * n) : Expression(n) {} - Equal(Expression child1, Expression child2) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child1); - replaceChildAtIndexInPlace(1, child2); + Equal(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); } // For the equation A = B, create the reduced expression A-B diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 1a68a88aa..aeafa1d87 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -186,6 +186,24 @@ public: double nextRoot(const char * symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit) const; Coordinate2D nextIntersection(const char * symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const; + /* This class is meant to contain data about named functions (e.g. sin, tan...) + * in one place: their name, their number of children and a pointer to a builder. + * It is used in particular by the parser. */ + class FunctionHelper { + public: + constexpr FunctionHelper(const char * name, const int numberOfChildren, Expression (* const builder)(Expression)) : + m_name(name), + m_numberOfChildren(numberOfChildren), + m_untypedBuilder(builder) {} + const char * name() const { return m_name; } + const int numberOfChildren() const { return m_numberOfChildren; } + Expression build(Expression children) const { return (*m_untypedBuilder)(children); } + private: + const char * m_name; + const int m_numberOfChildren; + Expression (* const m_untypedBuilder)(Expression children); + }; + protected: Expression(const ExpressionNode * n) : TreeHandle(n) {} @@ -230,6 +248,7 @@ protected: Expression shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) { return node()->shallowBeautify(context, angleUnit); } Expression deepBeautify(Context & context, Preferences::AngleUnit angleUnit); Expression setSign(ExpressionNode::Sign s, Context & context, Preferences::AngleUnit angleUnit); + private: /* Simplification */ void defaultReduceChildren(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols); diff --git a/poincare/include/poincare/factor.h b/poincare/include/poincare/factor.h index 319d619bc..fab714cbe 100644 --- a/poincare/include/poincare/factor.h +++ b/poincare/include/poincare/factor.h @@ -36,16 +36,18 @@ private: class Factor final : public Expression { public: - Factor(); Factor(const FactorNode * n) : Expression(n) {} - explicit Factor(Expression operand) : Factor() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "factor"; } - static const int NumberOfChildren() { return 1; } + static Factor Builder(Expression child) { return Factor(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowBeautify(Context & context, Preferences::AngleUnit angleUnit); Multiplication createMultiplicationOfIntegerPrimeDecomposition(Integer i, Context & context, Preferences::AngleUnit angleUnit) const; +private: + explicit Factor(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/factorial.h b/poincare/include/poincare/factorial.h index cec3131f9..0a456004c 100644 --- a/poincare/include/poincare/factorial.h +++ b/poincare/include/poincare/factorial.h @@ -48,8 +48,8 @@ class Factorial final : public Expression { public: Factorial(); Factorial(const FactorialNode * n) : Expression(n) {} - explicit Factorial(Expression operand) : Factorial() { - replaceChildAtIndexInPlace(0, operand); + explicit Factorial(Expression child) : Factorial() { + replaceChildAtIndexInPlace(0, child); } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); diff --git a/poincare/include/poincare/floor.h b/poincare/include/poincare/floor.h index fa9b3c879..4289f8b5c 100644 --- a/poincare/include/poincare/floor.h +++ b/poincare/include/poincare/floor.h @@ -38,15 +38,17 @@ private: class Floor final : public Expression { public: - Floor(); Floor(const FloorNode * n) : Expression(n) {} - explicit Floor(Expression operand) : Floor() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "floor"; } - static const int NumberOfChildren() { return 1; } + static Floor Builder(Expression child) { return Floor(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit Floor(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/floor_layout.h b/poincare/include/poincare/floor_layout.h index d78fcedb4..0240cac6c 100644 --- a/poincare/include/poincare/floor_layout.h +++ b/poincare/include/poincare/floor_layout.h @@ -12,7 +12,7 @@ class FloorLayoutNode final : public BracketPairLayoutNode { public: using BracketPairLayoutNode::BracketPairLayoutNode; int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Floor::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Floor::FunctionHelper()->name()); } // TreeNode diff --git a/poincare/include/poincare/frac_part.h b/poincare/include/poincare/frac_part.h index c094ba8bd..588ca2266 100644 --- a/poincare/include/poincare/frac_part.h +++ b/poincare/include/poincare/frac_part.h @@ -38,15 +38,17 @@ private: class FracPart final : public Expression { public: - FracPart(); FracPart(const FracPartNode * n) : Expression(n) {} - explicit FracPart(Expression operand) : FracPart() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "frac"; } - static const int NumberOfChildren() { return 1; } + static FracPart Builder(Expression child) { return FracPart(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit FracPart(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/function.h b/poincare/include/poincare/function.h index 1fff8a28b..5944e2ae0 100644 --- a/poincare/include/poincare/function.h +++ b/poincare/include/poincare/function.h @@ -48,8 +48,8 @@ class Function : public SymbolAbstract { public: explicit Function(const char * name); Function(const FunctionNode * n) : SymbolAbstract(n) {} - explicit Function(const char * name, Expression operand) : Function(name) { - replaceChildAtIndexInPlace(0, operand); + explicit Function(const char * name, Expression child) : Function(name) { + replaceChildAtIndexInPlace(0, child); } Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression); diff --git a/poincare/include/poincare/great_common_divisor.h b/poincare/include/poincare/great_common_divisor.h index 3bc68963d..1e2cd8231 100644 --- a/poincare/include/poincare/great_common_divisor.h +++ b/poincare/include/poincare/great_common_divisor.h @@ -33,17 +33,19 @@ private: class GreatCommonDivisor final : public Expression { public: - GreatCommonDivisor(); GreatCommonDivisor(const GreatCommonDivisorNode * n) : Expression(n) {} - GreatCommonDivisor(Expression child1, Expression child2) : GreatCommonDivisor() { - replaceChildAtIndexInPlace(0, child1); - replaceChildAtIndexInPlace(1, child2); - } - static const char * Name() { return "gcd"; } - static const int NumberOfChildren() { return 2; } + static GreatCommonDivisor Builder(Expression child0, Expression child1) { return GreatCommonDivisor(child0, child1); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } // Expression Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + GreatCommonDivisor(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/hyperbolic_arc_cosine.h b/poincare/include/poincare/hyperbolic_arc_cosine.h index a0e1d3260..22404e1bb 100644 --- a/poincare/include/poincare/hyperbolic_arc_cosine.h +++ b/poincare/include/poincare/hyperbolic_arc_cosine.h @@ -35,13 +35,15 @@ private: class HyperbolicArcCosine final : public HyperbolicTrigonometricFunction { public: - HyperbolicArcCosine() : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) {} HyperbolicArcCosine(const HyperbolicArcCosineNode * n) : HyperbolicTrigonometricFunction(n) {} - explicit HyperbolicArcCosine(Expression operand) : HyperbolicArcCosine() { - replaceChildAtIndexInPlace(0, operand); + static HyperbolicArcCosine Builder(Expression child) { return HyperbolicArcCosine(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } +private: + explicit HyperbolicArcCosine(Expression child) : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); } - static const char * Name() { return "acosh"; } - static const int NumberOfChildren() { return 1; } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/hyperbolic_arc_sine.h b/poincare/include/poincare/hyperbolic_arc_sine.h index d267deb3f..77f32ab91 100644 --- a/poincare/include/poincare/hyperbolic_arc_sine.h +++ b/poincare/include/poincare/hyperbolic_arc_sine.h @@ -35,13 +35,15 @@ private: class HyperbolicArcSine final : public HyperbolicTrigonometricFunction { public: - HyperbolicArcSine() : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) {} HyperbolicArcSine(const HyperbolicArcSineNode * n) : HyperbolicTrigonometricFunction(n) {} - explicit HyperbolicArcSine(Expression operand) : HyperbolicArcSine() { - replaceChildAtIndexInPlace(0, operand); + static HyperbolicArcSine Builder(Expression child) { return HyperbolicArcSine(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } +private: + explicit HyperbolicArcSine(Expression child) : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); } - static const char * Name() { return "asinh"; } - static const int NumberOfChildren() { return 1; } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/hyperbolic_arc_tangent.h b/poincare/include/poincare/hyperbolic_arc_tangent.h index 87d3de642..b752822da 100644 --- a/poincare/include/poincare/hyperbolic_arc_tangent.h +++ b/poincare/include/poincare/hyperbolic_arc_tangent.h @@ -35,13 +35,15 @@ private: class HyperbolicArcTangent final : public HyperbolicTrigonometricFunction { public: - HyperbolicArcTangent() : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) {} HyperbolicArcTangent(const HyperbolicArcTangentNode * n) : HyperbolicTrigonometricFunction(n) {} - explicit HyperbolicArcTangent(Expression operand) : HyperbolicArcTangent() { - replaceChildAtIndexInPlace(0, operand); + static HyperbolicArcTangent Builder(Expression child) { return HyperbolicArcTangent(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } +private: + explicit HyperbolicArcTangent(Expression child) : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); } - static const char * Name() { return "atanh"; } - static const int NumberOfChildren() { return 1; } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/hyperbolic_cosine.h b/poincare/include/poincare/hyperbolic_cosine.h index 4c93632b2..c3e1d2a62 100644 --- a/poincare/include/poincare/hyperbolic_cosine.h +++ b/poincare/include/poincare/hyperbolic_cosine.h @@ -35,13 +35,15 @@ private: class HyperbolicCosine final : public HyperbolicTrigonometricFunction { public: - HyperbolicCosine() : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) {} HyperbolicCosine(const HyperbolicCosineNode * n) : HyperbolicTrigonometricFunction(n) {} - explicit HyperbolicCosine(Expression operand) : HyperbolicCosine() { - replaceChildAtIndexInPlace(0, operand); + static HyperbolicCosine Builder(Expression child) { return HyperbolicCosine(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } +private: + explicit HyperbolicCosine(Expression child) : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); } - static const char * Name() { return "cosh"; } - static const int NumberOfChildren() { return 1; } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/hyperbolic_sine.h b/poincare/include/poincare/hyperbolic_sine.h index adf99190a..d4b052de8 100644 --- a/poincare/include/poincare/hyperbolic_sine.h +++ b/poincare/include/poincare/hyperbolic_sine.h @@ -35,13 +35,15 @@ private: class HyperbolicSine final : public HyperbolicTrigonometricFunction { public: - HyperbolicSine() : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) {} HyperbolicSine(const HyperbolicSineNode * n) : HyperbolicTrigonometricFunction(n) {} - explicit HyperbolicSine(Expression operand) : HyperbolicSine() { - replaceChildAtIndexInPlace(0, operand); + static HyperbolicSine Builder(Expression child) { return HyperbolicSine(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } +private: + explicit HyperbolicSine(Expression child) : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); } - static const char * Name() { return "sinh"; } - static const int NumberOfChildren() { return 1; } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/hyperbolic_tangent.h b/poincare/include/poincare/hyperbolic_tangent.h index 5306f17fd..b03dff01f 100644 --- a/poincare/include/poincare/hyperbolic_tangent.h +++ b/poincare/include/poincare/hyperbolic_tangent.h @@ -35,13 +35,15 @@ private: class HyperbolicTangent final : public HyperbolicTrigonometricFunction { public: - HyperbolicTangent() : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) {} HyperbolicTangent(const HyperbolicTangentNode * n) : HyperbolicTrigonometricFunction(n) {} - explicit HyperbolicTangent(Expression operand) : HyperbolicTangent() { - replaceChildAtIndexInPlace(0, operand); + static HyperbolicTangent Builder(Expression child) { return HyperbolicTangent(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } +private: + explicit HyperbolicTangent(Expression child) : HyperbolicTrigonometricFunction(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); } - static const char * Name() { return "tanh"; } - static const int NumberOfChildren() { return 1; } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/imaginary_part.h b/poincare/include/poincare/imaginary_part.h index ac6b8e036..3fe02435a 100644 --- a/poincare/include/poincare/imaginary_part.h +++ b/poincare/include/poincare/imaginary_part.h @@ -40,15 +40,17 @@ private: class ImaginaryPart final : public Expression { public: - ImaginaryPart(); ImaginaryPart(const ImaginaryPartNode * n) : Expression(n) {} - explicit ImaginaryPart(Expression operand) : ImaginaryPart() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "im"; } - static const int NumberOfChildren() { return 1; } + static ImaginaryPart Builder(Expression child) { return ImaginaryPart(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit ImaginaryPart(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/integral.h b/poincare/include/poincare/integral.h index 5b888422d..1c7d2c80f 100644 --- a/poincare/include/poincare/integral.h +++ b/poincare/include/poincare/integral.h @@ -48,19 +48,21 @@ private: class Integral final : public Expression { public: - Integral(); Integral(const IntegralNode * n) : Expression(n) {} - Integral(Expression child1, Expression child2, Expression child3, Expression child4) : Integral() { - replaceChildAtIndexInPlace(0, child1); - replaceChildAtIndexInPlace(1, child2); - replaceChildAtIndexInPlace(2, child3); - replaceChildAtIndexInPlace(3, child4); - } - static const char * Name() { return "int"; } - static const int NumberOfChildren() { return 4; } + static Integral Builder(Expression child0, Expression child1, Expression child2, Expression child3) { return Integral(child0, child1, child2, child3); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1), children.childAtIndex(2), children.childAtIndex(3)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } // Expression Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + Integral(Expression child0, Expression child1, Expression child2, Expression child3) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + replaceChildAtIndexInPlace(2, child2); + replaceChildAtIndexInPlace(3, child3); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/least_common_multiple.h b/poincare/include/poincare/least_common_multiple.h index 9114c01c6..263eef204 100644 --- a/poincare/include/poincare/least_common_multiple.h +++ b/poincare/include/poincare/least_common_multiple.h @@ -32,17 +32,19 @@ private: class LeastCommonMultiple final : public Expression { public: - LeastCommonMultiple(); LeastCommonMultiple(const LeastCommonMultipleNode * n) : Expression(n) {} - LeastCommonMultiple(Expression child1, Expression child2) : LeastCommonMultiple() { - replaceChildAtIndexInPlace(0, child1); - replaceChildAtIndexInPlace(1, child2); - } - static const char * Name() { return "lcm"; } - static const int NumberOfChildren() { return 2; } + static LeastCommonMultiple Builder(Expression child0, Expression child1) { return LeastCommonMultiple(child0, child1); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } // Expression Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + LeastCommonMultiple(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/logarithm.h b/poincare/include/poincare/logarithm.h index 4ed58f0b4..6f70543f0 100644 --- a/poincare/include/poincare/logarithm.h +++ b/poincare/include/poincare/logarithm.h @@ -44,33 +44,38 @@ public: class Logarithm final : public Expression { public: Logarithm(const LogarithmNode<2> * n) : Expression(n) {} - Logarithm(Expression child1, Expression child2) : Expression(TreePool::sharedPool()->createTreeNode >()) { - replaceChildAtIndexInPlace(0, child1); - replaceChildAtIndexInPlace(1, child2); - } - static const char * Name() { return "log"; } - static const int NumberOfChildren() { return 2; } + static Logarithm Builder(Expression child0, Expression child1) { return Logarithm(child0, child1); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); Expression shallowBeautify(Context & context, Preferences::AngleUnit angleUnit); private: + Logarithm(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode >()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + } Expression simpleShallowReduce(Context & context, Preferences::AngleUnit angleUnit); Integer simplifyLogarithmIntegerBaseInteger(Integer i, Integer & base, Addition & a, bool isDenominator); Expression splitLogarithmInteger(Integer i, bool isDenominator, Context & context, Preferences::AngleUnit angleUnit); bool parentIsAPowerOfSameBase() const; + static const Expression::FunctionHelper m_functionHelper; }; class CommonLogarithm : public Expression { public: CommonLogarithm(const LogarithmNode<1> * n) : Expression(n) {} - explicit CommonLogarithm(Expression operand) : Expression(TreePool::sharedPool()->createTreeNode >()) { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "log"; } - static const int NumberOfChildren() { return 1; } + static CommonLogarithm Builder(Expression child) { return CommonLogarithm(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit CommonLogarithm(Expression child) : Expression(TreePool::sharedPool()->createTreeNode >()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/matrix_dimension.h b/poincare/include/poincare/matrix_dimension.h index 5d1ddaead..cf7d78b98 100644 --- a/poincare/include/poincare/matrix_dimension.h +++ b/poincare/include/poincare/matrix_dimension.h @@ -33,15 +33,17 @@ private: class MatrixDimension final : public Expression { public: - MatrixDimension(); MatrixDimension(const MatrixDimensionNode * n) : Expression(n) {} - explicit MatrixDimension(Expression operand) : MatrixDimension() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "dim"; } - static const int NumberOfChildren() { return 1; } + static MatrixDimension Builder(Expression child) { return MatrixDimension(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit MatrixDimension(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/matrix_inverse.h b/poincare/include/poincare/matrix_inverse.h index 20acc420a..fece63113 100644 --- a/poincare/include/poincare/matrix_inverse.h +++ b/poincare/include/poincare/matrix_inverse.h @@ -33,15 +33,17 @@ private: class MatrixInverse final : public Expression { public: - MatrixInverse(); MatrixInverse(const MatrixInverseNode * n) : Expression(n) {} - explicit MatrixInverse(Expression operand) : MatrixInverse() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "inverse"; } - static const int NumberOfChildren() { return 1; } + static MatrixInverse Builder(Expression child) { return MatrixInverse(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit MatrixInverse(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/matrix_trace.h b/poincare/include/poincare/matrix_trace.h index a838f5d48..e1f424b5f 100644 --- a/poincare/include/poincare/matrix_trace.h +++ b/poincare/include/poincare/matrix_trace.h @@ -33,15 +33,17 @@ private: class MatrixTrace final : public Expression { public: - MatrixTrace(); MatrixTrace(const MatrixTraceNode * n) : Expression(n) {} - explicit MatrixTrace(Expression operand) : MatrixTrace() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "trace"; } - static const int NumberOfChildren() { return 1; } + static MatrixTrace Builder(Expression child) { return MatrixTrace(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit MatrixTrace(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/matrix_transpose.h b/poincare/include/poincare/matrix_transpose.h index 20d8fe4f6..5946484b6 100644 --- a/poincare/include/poincare/matrix_transpose.h +++ b/poincare/include/poincare/matrix_transpose.h @@ -33,15 +33,17 @@ private: class MatrixTranspose final : public Expression { public: - MatrixTranspose(); MatrixTranspose(const MatrixTransposeNode * n) : Expression(n) {} - explicit MatrixTranspose(Expression operand) : MatrixTranspose() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "transpose"; } - static const int NumberOfChildren() { return 1; } + static MatrixTranspose Builder(Expression child) { return MatrixTranspose(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit MatrixTranspose(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/naperian_logarithm.h b/poincare/include/poincare/naperian_logarithm.h index dd60e0511..a27297314 100644 --- a/poincare/include/poincare/naperian_logarithm.h +++ b/poincare/include/poincare/naperian_logarithm.h @@ -43,15 +43,17 @@ private: class NaperianLogarithm final : public Expression { public: - NaperianLogarithm(); NaperianLogarithm(const NaperianLogarithmNode * n) : Expression(n) {} - explicit NaperianLogarithm(Expression operand) : NaperianLogarithm() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "ln"; } - static const int NumberOfChildren() { return 1; } + static NaperianLogarithm Builder(Expression child) { return NaperianLogarithm(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit NaperianLogarithm(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/nth_root.h b/poincare/include/poincare/nth_root.h index 246ca9664..035c4154f 100644 --- a/poincare/include/poincare/nth_root.h +++ b/poincare/include/poincare/nth_root.h @@ -34,16 +34,18 @@ private: class NthRoot final : public Expression { public: - NthRoot(); NthRoot(const NthRootNode * n) : Expression(n) {} - NthRoot(Expression child1, Expression child2) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, child1); - replaceChildAtIndexInPlace(1, child2); - } - static const char * Name() { return "root"; } - static const int NumberOfChildren() { return 2; } + static NthRoot Builder(Expression child0, Expression child1) { return NthRoot(child0, child1); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + NthRoot(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/opposite.h b/poincare/include/poincare/opposite.h index 160d3abc3..32a2b9224 100644 --- a/poincare/include/poincare/opposite.h +++ b/poincare/include/poincare/opposite.h @@ -48,8 +48,8 @@ class Opposite final : public Expression { public: Opposite(); Opposite(const OppositeNode * n) : Expression(n) {} - explicit Opposite(Expression operand) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, operand); + explicit Opposite(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); diff --git a/poincare/include/poincare/permute_coefficient.h b/poincare/include/poincare/permute_coefficient.h index 429eb162e..32bd12a8d 100644 --- a/poincare/include/poincare/permute_coefficient.h +++ b/poincare/include/poincare/permute_coefficient.h @@ -36,18 +36,19 @@ private: class PermuteCoefficient final : public Expression { public: - PermuteCoefficient(); PermuteCoefficient(const PermuteCoefficientNode * n) : Expression(n) {} - PermuteCoefficient(Expression child1, Expression child2) : PermuteCoefficient() { - replaceChildAtIndexInPlace(0, child1); - replaceChildAtIndexInPlace(1, child2); - } - static const char * Name() { return "permute"; } - static const int NumberOfChildren() { return 2; } + static PermuteCoefficient Builder(Expression child0, Expression child1) { return PermuteCoefficient(child0, child1); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } // Expression Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); private: + PermuteCoefficient(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + } + static const Expression::FunctionHelper m_functionHelper; constexpr static int k_maxNValue = 100; }; diff --git a/poincare/include/poincare/power.h b/poincare/include/poincare/power.h index 223ce5cf7..f50a9959b 100644 --- a/poincare/include/poincare/power.h +++ b/poincare/include/poincare/power.h @@ -65,7 +65,6 @@ class Power final : public Expression { public: Power(Expression base, Expression exponent); Power(const PowerNode * n) : Expression(n) {} - static const char * Name() { return "^"; } Expression setSign(ExpressionNode::Sign s, Context & context, Preferences::AngleUnit angleUnit); int getPolynomialCoefficients(Context & context, const char * symbolName, Expression coefficients[]) const; Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); diff --git a/poincare/include/poincare/prediction_interval.h b/poincare/include/poincare/prediction_interval.h index 5c47e307d..6899ba400 100644 --- a/poincare/include/poincare/prediction_interval.h +++ b/poincare/include/poincare/prediction_interval.h @@ -36,17 +36,19 @@ private: class PredictionInterval final : public Expression { public: - PredictionInterval(); PredictionInterval(const PredictionIntervalNode * n) : Expression(n) {} - PredictionInterval(Expression child1, Expression child2) : PredictionInterval() { - replaceChildAtIndexInPlace(0, child1); - replaceChildAtIndexInPlace(1, child2); - } - static const char * Name() { return "prediction95"; } - static const int NumberOfChildren() { return 2; } + static PredictionInterval Builder(Expression child0, Expression child1) { return PredictionInterval(child0, child1); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } // Expression Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + PredictionInterval(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/product.h b/poincare/include/poincare/product.h index 68bc1c6e8..10826b67a 100644 --- a/poincare/include/poincare/product.h +++ b/poincare/include/poincare/product.h @@ -32,16 +32,18 @@ private: class Product final : public Expression { friend class ProductNode; public: - Product(); Product(const ProductNode * n) : Expression(n) {} - Product(Expression operand0, Expression operand1, Expression operand2, Expression operand3) : Product() { - replaceChildAtIndexInPlace(0, operand0); - replaceChildAtIndexInPlace(1, operand1); - replaceChildAtIndexInPlace(2, operand2); - replaceChildAtIndexInPlace(3, operand3); + static Product Builder(Expression child0, Expression child1, Expression child2, Expression child3) { return Product(child0, child1, child2, child3); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1), children.childAtIndex(2), children.childAtIndex(3)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } +private: + Product(Expression child0, Expression child1, Expression child2, Expression child3) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + replaceChildAtIndexInPlace(2, child2); + replaceChildAtIndexInPlace(3, child3); } - static const char * Name() { return "product"; } - static const int NumberOfChildren() { return 3; } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/randint.h b/poincare/include/poincare/randint.h index 20db8ec23..cbdc10327 100644 --- a/poincare/include/poincare/randint.h +++ b/poincare/include/poincare/randint.h @@ -36,10 +36,16 @@ private: class Randint final : public Expression { friend class RandintNode; public: - Randint(); Randint(const RandintNode * n) : Expression(n) {} - static const char * Name() { return "randint"; } - static const int NumberOfChildren() { return 2; } + static Randint Builder(Expression child0, Expression child1) { return Randint(child0, child1); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } +private: + Randint(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/random.h b/poincare/include/poincare/random.h index c6a60c54f..7f1a1876a 100644 --- a/poincare/include/poincare/random.h +++ b/poincare/include/poincare/random.h @@ -39,14 +39,16 @@ private: class Random final : public Expression { friend class RandomNode; public: - Random(); Random(const RandomNode * n) : Expression(n) {} - static const char * Name() { return "random"; } - static const int NumberOfChildren() { return 0; } + static Random Builder() { return Random(); } + static Expression UntypedBuilder(Expression children) { return Builder(); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } template static T random(); private: + Random() : Expression(TreePool::sharedPool()->createTreeNode()) {} Expression setSign(ExpressionNode::Sign s, Context & context, Preferences::AngleUnit angleUnit); + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/real_part.h b/poincare/include/poincare/real_part.h index 74bee8175..a9a3827a3 100644 --- a/poincare/include/poincare/real_part.h +++ b/poincare/include/poincare/real_part.h @@ -40,15 +40,17 @@ private: class RealPart final : public Expression { public: - RealPart(); RealPart(const RealPartNode * n) : Expression(n) {} - explicit RealPart(Expression operand) : RealPart() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "re"; } - static const int NumberOfChildren() { return 1; } + static RealPart Builder(Expression child) { return RealPart(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit RealPart(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/round.h b/poincare/include/poincare/round.h index 4a1369da3..8d7ea357f 100644 --- a/poincare/include/poincare/round.h +++ b/poincare/include/poincare/round.h @@ -34,16 +34,18 @@ private: class Round final : public Expression { public: - Round(); Round(const RoundNode * n) : Expression(n) {} - Round(Expression operand0, Expression operand1) : Round() { - replaceChildAtIndexInPlace(0, operand0); - replaceChildAtIndexInPlace(1, operand1); - } - static const char * Name() { return "round"; } - static const int NumberOfChildren() { return 2; } + static Round Builder(Expression child0, Expression child1) { return Round(child0, child1); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + Round(Expression child0, Expression child1) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/sine.h b/poincare/include/poincare/sine.h index b9b97db7c..2de0a1bb1 100644 --- a/poincare/include/poincare/sine.h +++ b/poincare/include/poincare/sine.h @@ -44,15 +44,17 @@ private: class Sine final : public Expression { public: - Sine(); Sine(const SineNode * n) : Expression(n) {} - explicit Sine(Expression operand) : Sine() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "sin"; } - static const int NumberOfChildren() { return 1; } + static Sine Builder(Expression child) { return Sine(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit Sine(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/square_root.h b/poincare/include/poincare/square_root.h index 6869b7878..68f70c7dc 100644 --- a/poincare/include/poincare/square_root.h +++ b/poincare/include/poincare/square_root.h @@ -40,18 +40,18 @@ private: class SquareRoot final : public Expression { public: - SquareRoot(); SquareRoot(const SquareRootNode * n) : Expression(n) {} - explicit SquareRoot(Expression operand) : Expression(TreePool::sharedPool()->createTreeNode()) { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { - constexpr static char k_name[2] = {Ion::Charset::Root, 0}; - return k_name; - } - static const int NumberOfChildren() { return 1; } + static SquareRoot Builder(Expression child) { return SquareRoot(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit SquareRoot(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const char k_name[2]; + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/subtraction.h b/poincare/include/poincare/subtraction.h index dca380399..8ae2a86bb 100644 --- a/poincare/include/poincare/subtraction.h +++ b/poincare/include/poincare/subtraction.h @@ -56,11 +56,10 @@ class Subtraction final : public Expression { public: Subtraction(); Subtraction(const SubtractionNode * n) : Expression(n) {} - Subtraction(Expression child1, Expression child2) : Subtraction() { - replaceChildAtIndexInPlace(0, child1); - replaceChildAtIndexInPlace(1, child2); + Subtraction(Expression child0, Expression child1) : Subtraction() { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); } - static const char * Name() { return "-"; } // Expression Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); diff --git a/poincare/include/poincare/sum.h b/poincare/include/poincare/sum.h index cfbc317b5..37872a252 100644 --- a/poincare/include/poincare/sum.h +++ b/poincare/include/poincare/sum.h @@ -32,16 +32,18 @@ private: class Sum final : public Expression { friend class SumNode; public: - Sum(); Sum(const SumNode * n) : Expression(n) {} - Sum(Expression operand0, Expression operand1, Expression operand2, Expression operand3) : Sum() { - replaceChildAtIndexInPlace(0, operand0); - replaceChildAtIndexInPlace(1, operand1); - replaceChildAtIndexInPlace(2, operand2); - replaceChildAtIndexInPlace(3, operand3); + static Sum Builder(Expression child0, Expression child1, Expression child2, Expression child3) { return Sum(child0, child1, child2, child3); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0), children.childAtIndex(1), children.childAtIndex(2), children.childAtIndex(3)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } +private: + Sum(Expression child0, Expression child1, Expression child2, Expression child3) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child0); + replaceChildAtIndexInPlace(1, child1); + replaceChildAtIndexInPlace(2, child2); + replaceChildAtIndexInPlace(3, child3); } - static const char * Name() { return "sum"; } - static const int NumberOfChildren() { return 3; } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/include/poincare/tangent.h b/poincare/include/poincare/tangent.h index 66f012fa4..ee097f947 100644 --- a/poincare/include/poincare/tangent.h +++ b/poincare/include/poincare/tangent.h @@ -42,15 +42,17 @@ private: class Tangent final : public Expression { public: - Tangent(); Tangent(const TangentNode * n) : Expression(n) {} - explicit Tangent(Expression operand) : Tangent() { - replaceChildAtIndexInPlace(0, operand); - } - static const char * Name() { return "tan"; } - static const int NumberOfChildren() { return 1; } + static Tangent Builder(Expression child) { return Tangent(child); } + static Expression UntypedBuilder(Expression children) { return Builder(children.childAtIndex(0)); } + static const Expression::FunctionHelper * FunctionHelper() { return &m_functionHelper; } Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols = true); +private: + explicit Tangent(Expression child) : Expression(TreePool::sharedPool()->createTreeNode()) { + replaceChildAtIndexInPlace(0, child); + } + static const Expression::FunctionHelper m_functionHelper; }; } diff --git a/poincare/src/absolute_value.cpp b/poincare/src/absolute_value.cpp index 8150886cd..78b199bb7 100644 --- a/poincare/src/absolute_value.cpp +++ b/poincare/src/absolute_value.cpp @@ -8,7 +8,7 @@ namespace Poincare { -int AbsoluteValueNode::numberOfChildren() const { return AbsoluteValue::NumberOfChildren(); } +int AbsoluteValueNode::numberOfChildren() const { return AbsoluteValue::FunctionHelper()->numberOfChildren(); } Expression AbsoluteValueNode::setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) { return AbsoluteValue(this).setSign(s, context, angleUnit); @@ -19,7 +19,7 @@ Layout AbsoluteValueNode::createLayout(Preferences::PrintFloatMode floatDisplayM } int AbsoluteValueNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, AbsoluteValue::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, AbsoluteValue::FunctionHelper()->name()); } Expression AbsoluteValueNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { @@ -31,8 +31,6 @@ Expression AbsoluteValue::setSign(ExpressionNode::Sign s, Context & context, Pre return *this; } -AbsoluteValue::AbsoluteValue() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression AbsoluteValue::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { Expression e = Expression::defaultShallowReduce(context, angleUnit); if (e.isUndefined()) { @@ -58,5 +56,6 @@ Expression AbsoluteValue::shallowReduce(Context & context, Preferences::AngleUni return *this; } +constexpr Expression::FunctionHelper AbsoluteValue::m_functionHelper = Expression::FunctionHelper("abs", 1, &AbsoluteValue::UntypedBuilder); } diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index c6b7f8ae2..28844a674 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -38,11 +38,11 @@ bool AdditionNode::childNeedsParenthesis(const TreeNode * child) const { } Layout AdditionNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Infix(Addition(this), floatDisplayMode, numberOfSignificantDigits, Addition::Name()); + return LayoutHelper::Infix(Addition(this), floatDisplayMode, numberOfSignificantDigits, "+"); } int AdditionNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Infix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Addition::Name()); + return SerializationHelper::Infix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "+"); } // Simplication diff --git a/poincare/src/arc_cosine.cpp b/poincare/src/arc_cosine.cpp index 4aa3add95..1f75031f5 100644 --- a/poincare/src/arc_cosine.cpp +++ b/poincare/src/arc_cosine.cpp @@ -7,14 +7,14 @@ namespace Poincare { -int ArcCosineNode::numberOfChildren() const { return ArcCosine::NumberOfChildren(); } +int ArcCosineNode::numberOfChildren() const { return ArcCosine::FunctionHelper()->numberOfChildren(); } Layout ArcCosineNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(ArcCosine(this), floatDisplayMode, numberOfSignificantDigits, ArcCosine::Name()); + return LayoutHelper::Prefix(ArcCosine(this), floatDisplayMode, numberOfSignificantDigits, ArcCosine::FunctionHelper()->name()); } int ArcCosineNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ArcCosine::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ArcCosine::FunctionHelper()->name()); } Expression ArcCosineNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { @@ -36,8 +36,6 @@ Complex ArcCosineNode::computeOnComplex(const std::complex c, Preferences: return Complex(Trigonometry::ConvertRadianToAngleUnit(result, angleUnit)); } -ArcCosine::ArcCosine() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression ArcCosine::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -53,4 +51,6 @@ Expression ArcCosine::shallowReduce(Context & context, Preferences::AngleUnit an return Trigonometry::shallowReduceInverseFunction(*this, context, angleUnit); } +constexpr Expression::FunctionHelper ArcCosine::m_functionHelper = Expression::FunctionHelper("acos", 1, &ArcCosine::UntypedBuilder); + } diff --git a/poincare/src/arc_sine.cpp b/poincare/src/arc_sine.cpp index f6b214152..9134490ba 100644 --- a/poincare/src/arc_sine.cpp +++ b/poincare/src/arc_sine.cpp @@ -7,14 +7,14 @@ namespace Poincare { -int ArcSineNode::numberOfChildren() const { return ArcSine::NumberOfChildren(); } +int ArcSineNode::numberOfChildren() const { return ArcSine::FunctionHelper()->numberOfChildren(); } Layout ArcSineNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(ArcSine(this), floatDisplayMode, numberOfSignificantDigits, ArcSine::Name()); + return LayoutHelper::Prefix(ArcSine(this), floatDisplayMode, numberOfSignificantDigits, ArcSine::FunctionHelper()->name()); } int ArcSineNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ArcSine::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ArcSine::FunctionHelper()->name()); } Expression ArcSineNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { @@ -36,8 +36,6 @@ Complex ArcSineNode::computeOnComplex(const std::complex c, Preferences::A return Complex(Trigonometry::ConvertRadianToAngleUnit(result, angleUnit)); } -ArcSine::ArcSine() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression ArcSine::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -53,4 +51,6 @@ Expression ArcSine::shallowReduce(Context & context, Preferences::AngleUnit angl return Trigonometry::shallowReduceInverseFunction(*this, context, angleUnit); } +constexpr Expression::FunctionHelper ArcSine::m_functionHelper = Expression::FunctionHelper("asin", 1, &ArcSine::UntypedBuilder); + } diff --git a/poincare/src/arc_tangent.cpp b/poincare/src/arc_tangent.cpp index 6fe794144..50290d817 100644 --- a/poincare/src/arc_tangent.cpp +++ b/poincare/src/arc_tangent.cpp @@ -7,14 +7,14 @@ namespace Poincare { -int ArcTangentNode::numberOfChildren() const { return ArcTangent::NumberOfChildren(); } +int ArcTangentNode::numberOfChildren() const { return ArcTangent::FunctionHelper()->numberOfChildren(); } Layout ArcTangentNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(ArcTangent(this), floatDisplayMode, numberOfSignificantDigits, ArcTangent::Name()); + return LayoutHelper::Prefix(ArcTangent(this), floatDisplayMode, numberOfSignificantDigits, ArcTangent::FunctionHelper()->name()); } int ArcTangentNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ArcTangent::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ArcTangent::FunctionHelper()->name()); } template @@ -36,8 +36,6 @@ Expression ArcTangentNode::shallowReduce(Context & context, Preferences::AngleUn return ArcTangent(this).shallowReduce(context, angleUnit, replaceSymbols); } -ArcTangent::ArcTangent() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression ArcTangent::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -53,4 +51,6 @@ Expression ArcTangent::shallowReduce(Context & context, Preferences::AngleUnit a return Trigonometry::shallowReduceInverseFunction(*this, context, angleUnit); } +constexpr Expression::FunctionHelper ArcTangent::m_functionHelper = Expression::FunctionHelper("atan", 1, &ArcTangent::UntypedBuilder); + } diff --git a/poincare/src/binomial_coefficient.cpp b/poincare/src/binomial_coefficient.cpp index 59d00decd..1c653ade6 100644 --- a/poincare/src/binomial_coefficient.cpp +++ b/poincare/src/binomial_coefficient.cpp @@ -10,7 +10,7 @@ namespace Poincare { -int BinomialCoefficientNode::numberOfChildren() const { return BinomialCoefficient::NumberOfChildren(); } +int BinomialCoefficientNode::numberOfChildren() const { return BinomialCoefficient::FunctionHelper()->numberOfChildren(); } Expression BinomialCoefficientNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { return BinomialCoefficient(this).shallowReduce(context, angleUnit, replaceSymbols); @@ -23,7 +23,7 @@ Layout BinomialCoefficientNode::createLayout(Preferences::PrintFloatMode floatDi } int BinomialCoefficientNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, BinomialCoefficient::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, BinomialCoefficient::FunctionHelper()->name()); } template @@ -51,8 +51,6 @@ T BinomialCoefficientNode::compute(T k, T n) { return std::round(result); } -BinomialCoefficient::BinomialCoefficient() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression BinomialCoefficient::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -121,4 +119,6 @@ Expression BinomialCoefficient::shallowReduce(Context & context, Preferences::An template double BinomialCoefficientNode::compute(double k, double n); template float BinomialCoefficientNode::compute(float k, float n); +constexpr Expression::FunctionHelper BinomialCoefficient::m_functionHelper = Expression::FunctionHelper("binomial", 2, &BinomialCoefficient::UntypedBuilder); + } diff --git a/poincare/src/binomial_coefficient_layout.cpp b/poincare/src/binomial_coefficient_layout.cpp index b1f169677..26fd1e81f 100644 --- a/poincare/src/binomial_coefficient_layout.cpp +++ b/poincare/src/binomial_coefficient_layout.cpp @@ -74,7 +74,7 @@ void BinomialCoefficientLayoutNode::moveCursorDown(LayoutCursor * cursor, bool * } int BinomialCoefficientLayoutNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, BinomialCoefficient::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, BinomialCoefficient::FunctionHelper()->name()); } KDSize BinomialCoefficientLayoutNode::computeSize() { diff --git a/poincare/src/ceiling.cpp b/poincare/src/ceiling.cpp index a4ddca09e..86bced597 100644 --- a/poincare/src/ceiling.cpp +++ b/poincare/src/ceiling.cpp @@ -11,14 +11,14 @@ namespace Poincare { -int CeilingNode::numberOfChildren() const { return Ceiling::NumberOfChildren(); } +int CeilingNode::numberOfChildren() const { return Ceiling::FunctionHelper()->numberOfChildren(); } Layout CeilingNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { return CeilingLayout(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits)); } int CeilingNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Ceiling::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Ceiling::FunctionHelper()->name()); } template @@ -33,8 +33,6 @@ Expression CeilingNode::shallowReduce(Context & context, Preferences::AngleUnit return Ceiling(this).shallowReduce(context, angleUnit, replaceSymbols); } -Ceiling::Ceiling() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression Ceiling::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -83,4 +81,6 @@ Expression Ceiling::shallowReduce(Context & context, Preferences::AngleUnit angl return rationalResult; } +constexpr Expression::FunctionHelper Ceiling::m_functionHelper = Expression::FunctionHelper("ceil", 1, &Ceiling::UntypedBuilder); + } diff --git a/poincare/src/complex_argument.cpp b/poincare/src/complex_argument.cpp index 38cd5eee3..917543186 100644 --- a/poincare/src/complex_argument.cpp +++ b/poincare/src/complex_argument.cpp @@ -9,14 +9,14 @@ extern "C" { namespace Poincare { -int ComplexArgumentNode::numberOfChildren() const { return ComplexArgument::NumberOfChildren(); } +int ComplexArgumentNode::numberOfChildren() const { return ComplexArgument::FunctionHelper()->numberOfChildren(); } Layout ComplexArgumentNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(ComplexArgument(this), floatDisplayMode, numberOfSignificantDigits, ComplexArgument::Name()); + return LayoutHelper::Prefix(ComplexArgument(this), floatDisplayMode, numberOfSignificantDigits, ComplexArgument::FunctionHelper()->name()); } int ComplexArgumentNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ComplexArgument::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ComplexArgument::FunctionHelper()->name()); } Expression ComplexArgumentNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { @@ -28,8 +28,6 @@ Complex ComplexArgumentNode::computeOnComplex(const std::complex c, Prefer return Complex(std::arg(c)); } -ComplexArgument::ComplexArgument() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression ComplexArgument::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -46,5 +44,6 @@ Expression ComplexArgument::shallowReduce(Context & context, Preferences::AngleU return *this; } -} +constexpr Expression::FunctionHelper ComplexArgument::m_functionHelper = Expression::FunctionHelper("arg", 1, &ComplexArgument::UntypedBuilder); +} diff --git a/poincare/src/confidence_interval.cpp b/poincare/src/confidence_interval.cpp index fc4c807f2..cd344d077 100644 --- a/poincare/src/confidence_interval.cpp +++ b/poincare/src/confidence_interval.cpp @@ -11,14 +11,14 @@ namespace Poincare { -int ConfidenceIntervalNode::numberOfChildren() const { return ConfidenceInterval::NumberOfChildren(); } +int ConfidenceIntervalNode::numberOfChildren() const { return ConfidenceInterval::FunctionHelper()->numberOfChildren(); } Layout ConfidenceIntervalNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(ConfidenceInterval(this), floatDisplayMode, numberOfSignificantDigits, ConfidenceInterval::Name()); + return LayoutHelper::Prefix(ConfidenceInterval(this), floatDisplayMode, numberOfSignificantDigits, ConfidenceInterval::FunctionHelper()->name()); } int ConfidenceIntervalNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ConfidenceInterval::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ConfidenceInterval::FunctionHelper()->name()); } Expression ConfidenceIntervalNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { @@ -41,15 +41,13 @@ Evaluation ConfidenceIntervalNode::templatedApproximate(Context& context, Pre } Layout SimplePredictionIntervalNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(SimplePredictionInterval(this), floatDisplayMode, numberOfSignificantDigits, SimplePredictionInterval::Name()); + return LayoutHelper::Prefix(SimplePredictionInterval(this), floatDisplayMode, numberOfSignificantDigits, SimplePredictionInterval::FunctionHelper()->name()); } int SimplePredictionIntervalNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, SimplePredictionInterval::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, SimplePredictionInterval::FunctionHelper()->name()); } -ConfidenceInterval::ConfidenceInterval() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression ConfidenceInterval::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -96,4 +94,8 @@ Expression ConfidenceInterval::shallowReduce(Context & context, Preferences::Ang return matrix; } +constexpr Expression::FunctionHelper ConfidenceInterval::m_functionHelper = Expression::FunctionHelper("confidence", 2, &ConfidenceInterval::UntypedBuilder); + +constexpr Expression::FunctionHelper SimplePredictionInterval::m_functionHelper = Expression::FunctionHelper("prediction", 2, &SimplePredictionInterval::UntypedBuilder); + } diff --git a/poincare/src/conjugate.cpp b/poincare/src/conjugate.cpp index 9860aedc2..635a1f188 100644 --- a/poincare/src/conjugate.cpp +++ b/poincare/src/conjugate.cpp @@ -7,14 +7,14 @@ namespace Poincare { -int ConjugateNode::numberOfChildren() const { return Conjugate::NumberOfChildren(); } +int ConjugateNode::numberOfChildren() const { return Conjugate::FunctionHelper()->numberOfChildren(); } Layout ConjugateNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { return ConjugateLayout(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits)); } int ConjugateNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Conjugate::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Conjugate::FunctionHelper()->name()); } Expression ConjugateNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { @@ -26,8 +26,6 @@ Complex ConjugateNode::computeOnComplex(const std::complex c, Preferences: return Complex(std::conj(c)); } -Conjugate::Conjugate() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression Conjugate::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -48,4 +46,6 @@ Expression Conjugate::shallowReduce(Context & context, Preferences::AngleUnit an return *this; } +constexpr Expression::FunctionHelper Conjugate::m_functionHelper = Expression::FunctionHelper("conj", 1, &Conjugate::UntypedBuilder); + } diff --git a/poincare/src/conjugate_layout.cpp b/poincare/src/conjugate_layout.cpp index c7f022daf..b636995e8 100644 --- a/poincare/src/conjugate_layout.cpp +++ b/poincare/src/conjugate_layout.cpp @@ -52,7 +52,7 @@ void ConjugateLayoutNode::moveCursorRight(LayoutCursor * cursor, bool * shouldRe } int ConjugateLayoutNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Conjugate::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Conjugate::FunctionHelper()->name()); } KDSize ConjugateLayoutNode::computeSize() { diff --git a/poincare/src/cosine.cpp b/poincare/src/cosine.cpp index 32c2d2e13..c9a7ad1b4 100644 --- a/poincare/src/cosine.cpp +++ b/poincare/src/cosine.cpp @@ -7,7 +7,7 @@ namespace Poincare { -int CosineNode::numberOfChildren() const { return Cosine::NumberOfChildren(); } +int CosineNode::numberOfChildren() const { return Cosine::FunctionHelper()->numberOfChildren(); } float CosineNode::characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const { return Trigonometry::characteristicXRange(Cosine(this), context, angleUnit); @@ -21,19 +21,17 @@ Complex CosineNode::computeOnComplex(const std::complex c, Preferences::An } Layout CosineNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(Cosine(this), floatDisplayMode, numberOfSignificantDigits, Cosine::Name()); + return LayoutHelper::Prefix(Cosine(this), floatDisplayMode, numberOfSignificantDigits, Cosine::FunctionHelper()->name()); } int CosineNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Cosine::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Cosine::FunctionHelper()->name()); } Expression CosineNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { return Cosine(this).shallowReduce(context, angleUnit, replaceSymbols); } -Cosine::Cosine() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression Cosine::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -50,4 +48,6 @@ Expression Cosine::shallowReduce(Context & context, Preferences::AngleUnit angle return Trigonometry::shallowReduceDirectFunction(*this, context, angleUnit); } +constexpr Expression::FunctionHelper Cosine::m_functionHelper = Expression::FunctionHelper("cos", 1, &Cosine::UntypedBuilder); + } diff --git a/poincare/src/derivative.cpp b/poincare/src/derivative.cpp index d95f5bcf6..15567829d 100644 --- a/poincare/src/derivative.cpp +++ b/poincare/src/derivative.cpp @@ -10,7 +10,7 @@ namespace Poincare { -int DerivativeNode::numberOfChildren() const { return Derivative::NumberOfChildren(); } +int DerivativeNode::numberOfChildren() const { return Derivative::FunctionHelper()->numberOfChildren(); } int DerivativeNode::polynomialDegree(Context & context, const char * symbolName) const { if (childAtIndex(0)->polynomialDegree(context, symbolName) == 0 @@ -25,11 +25,11 @@ int DerivativeNode::polynomialDegree(Context & context, const char * symbolName) } Layout DerivativeNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, Derivative::Name()); + return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, Derivative::FunctionHelper()->name()); } int DerivativeNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Derivative::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Derivative::FunctionHelper()->name()); } Expression DerivativeNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { @@ -130,8 +130,6 @@ T DerivativeNode::riddersApproximation(Context & context, Preferences::AngleUnit return ans; } -Derivative::Derivative() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression Derivative::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -148,5 +146,6 @@ Expression Derivative::shallowReduce(Context & context, Preferences::AngleUnit a return *this; } -} +constexpr Expression::FunctionHelper Derivative::m_functionHelper = Expression::FunctionHelper("diff", 3, &Derivative::UntypedBuilder); +} diff --git a/poincare/src/determinant.cpp b/poincare/src/determinant.cpp index 778940ad0..981b022cb 100644 --- a/poincare/src/determinant.cpp +++ b/poincare/src/determinant.cpp @@ -9,14 +9,14 @@ extern "C" { namespace Poincare { -int DeterminantNode::numberOfChildren() const { return Determinant::NumberOfChildren(); } +int DeterminantNode::numberOfChildren() const { return Determinant::FunctionHelper()->numberOfChildren(); } Layout DeterminantNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(Determinant(this), floatDisplayMode, numberOfSignificantDigits, Determinant::Name()); + return LayoutHelper::Prefix(Determinant(this), floatDisplayMode, numberOfSignificantDigits, Determinant::FunctionHelper()->name()); } int DeterminantNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Determinant::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Determinant::FunctionHelper()->name()); } // TODO: handle this exactly in shallowReduce for small dimensions. @@ -30,8 +30,6 @@ Expression DeterminantNode::shallowReduce(Context & context, Preferences::AngleU return Determinant(this).shallowReduce(context, angleUnit, replaceSymbols); } -Determinant::Determinant() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression Determinant::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -56,4 +54,6 @@ Expression Determinant::shallowReduce(Context & context, Preferences::AngleUnit return *this; } +constexpr Expression::FunctionHelper Determinant::m_functionHelper = Expression::FunctionHelper("det", 1, &Determinant::UntypedBuilder); + } diff --git a/poincare/src/division.cpp b/poincare/src/division.cpp index 5c977df8f..7a3fdbc0e 100644 --- a/poincare/src/division.cpp +++ b/poincare/src/division.cpp @@ -37,7 +37,7 @@ Layout DivisionNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, } int DivisionNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Infix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Division::Name()); + return SerializationHelper::Infix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "/"); } Expression DivisionNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { diff --git a/poincare/src/division_quotient.cpp b/poincare/src/division_quotient.cpp index 08d4e8cf9..68b8c1a29 100644 --- a/poincare/src/division_quotient.cpp +++ b/poincare/src/division_quotient.cpp @@ -8,17 +8,17 @@ namespace Poincare { -int DivisionQuotientNode::numberOfChildren() const { return DivisionQuotient::NumberOfChildren(); } +int DivisionQuotientNode::numberOfChildren() const { return DivisionQuotient::FunctionHelper()->numberOfChildren(); } Expression DivisionQuotientNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { return DivisionQuotient(this).shallowReduce(context, angleUnit, replaceSymbols); } Layout DivisionQuotientNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(DivisionQuotient(this), floatDisplayMode, numberOfSignificantDigits, DivisionQuotient::Name()); + return LayoutHelper::Prefix(DivisionQuotient(this), floatDisplayMode, numberOfSignificantDigits, DivisionQuotient::FunctionHelper()->name()); } int DivisionQuotientNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, DivisionQuotient::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, DivisionQuotient::FunctionHelper()->name()); } template @@ -33,8 +33,6 @@ Evaluation DivisionQuotientNode::templatedApproximate(Context& context, Prefe return Complex(std::floor(f1/f2)); } -DivisionQuotient::DivisionQuotient() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression DivisionQuotient::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -87,4 +85,6 @@ Expression DivisionQuotient::shallowReduce(Context & context, Preferences::Angle return rationalResult; } +constexpr Expression::FunctionHelper DivisionQuotient::m_functionHelper = Expression::FunctionHelper("quo", 2, &DivisionQuotient::UntypedBuilder); + } diff --git a/poincare/src/division_remainder.cpp b/poincare/src/division_remainder.cpp index 219dc6bcb..42dc0a6ba 100644 --- a/poincare/src/division_remainder.cpp +++ b/poincare/src/division_remainder.cpp @@ -8,14 +8,14 @@ namespace Poincare { -int DivisionRemainderNode::numberOfChildren() const { return DivisionRemainder::NumberOfChildren(); } +int DivisionRemainderNode::numberOfChildren() const { return DivisionRemainder::FunctionHelper()->numberOfChildren(); } Layout DivisionRemainderNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(DivisionRemainder(this), floatDisplayMode, numberOfSignificantDigits, DivisionRemainder::Name()); + return LayoutHelper::Prefix(DivisionRemainder(this), floatDisplayMode, numberOfSignificantDigits, DivisionRemainder::FunctionHelper()->name()); } int DivisionRemainderNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, DivisionRemainder::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, DivisionRemainder::FunctionHelper()->name()); } Expression DivisionRemainderNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { @@ -33,7 +33,6 @@ Evaluation DivisionRemainderNode::templatedApproximate(Context& context, Pref } return Complex(std::round(f1-f2*std::floor(f1/f2))); } -DivisionRemainder::DivisionRemainder() : Expression(TreePool::sharedPool()->createTreeNode()) {} Expression DivisionRemainder::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { @@ -85,4 +84,6 @@ Expression DivisionRemainder::shallowReduce(Context & context, Preferences::Angl return rationalResult; } +constexpr Expression::FunctionHelper DivisionRemainder::m_functionHelper = Expression::FunctionHelper("rem", 2, &DivisionRemainder::UntypedBuilder); + } diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index cc86aa005..c2089d717 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -3,21 +3,14 @@ #include #include #include -#include #include #include #include #include #include -#include "expression_lexer_parser.h" -#include "expression_parser.hpp" -#include "expression_lexer.hpp" - #include "parsing/parser.h" -int poincare_expression_yyparse(Poincare::Expression * expressionOutput); - namespace Poincare { #include diff --git a/poincare/src/expression_lexer.l b/poincare/src/expression_lexer.l deleted file mode 100644 index 4c8230cf5..000000000 --- a/poincare/src/expression_lexer.l +++ /dev/null @@ -1,188 +0,0 @@ -/* Normally, Flex will call yywrap when reaching an end-of-file. We don't want - * to deal with files anyway, so let's just disable this. */ -%option noyywrap - -/* We're using the bison-bridge option because the bison parser is reentrant, - * as specified by the "pure-parser" option. Using the bison-bridge option - * prevents Flex from using global variables such as yylval. Instead, those - * become local pointers that are passed by Bison to Flex. - * In practice, when using bison-bridge, you shall simply use yylval as a - * pointer. - */ -%option bison-bridge - -/* Normally, on each new input file the scanner calls isatty() in an attempt to - * determine whether the scanner's input source is interactive and thus should - * be read a character at a time. - * We obviously do *not* provide isatty(), and we know we're never going to use - * an interactive input source. */ -%option never-interactive - -%{ -/* Flex generate a lexer, a function that outputs tokens. - * Those tokens (and the optional value that they can be attached) are defined - * in the Bison grammar. To use those token definitions, we need to include the - * header generated by Bison. - * Also, since some tokens can have an "Expression" value attached, we'll - * need "Expression" to be defined before including that header. - * We could use the '%code requires{}' directive to make sure that Expression is - * well defined in the parser header, but this directive only comes in bison 3, - * which is not installed by default on MacOS, we thus made the choice to prefer - * compatibility with MacOS's default version (2.3) instead of using the code - * requires feature. */ -#include - -/* YYSTYPE has to be defined in expression_parser.y, expression.cpp and here - * because the genereated code is included in expression_parser.cpp, not .hpp - * so we cannot use expression_parser.hpp here. We use an additional header - * which only define YYSTYPE. This should be discarded with Bison 3. */ -#include "expression_lexer_parser.h" - -#include -#include "expression_parser.hpp" -using namespace Poincare; - -/* Flex has provision for reading files. We'll never use this, so we're defining - * YY_INPUT which effectively disables taking input from a file. */ -#define YY_INPUT - -/* Flex can print to stdout what token it matches by calling the ECHO function. - * We don't want that feature : we don't even have printf ! */ -#define ECHO - -/* This defines the size of the flex buffer size. - * By default this buffer is of 16k, but we don't have the luxury to use so much - * memory on a microcontroller. - * The choice of 256 Bytes is the size of the input buffer given to flex in the - * current implementation (the app takes a maximum of 256). - */ -#undef YY_BUF_SIZE -#define YY_BUF_SIZE 256 - -#define fprintf(...) ((void)0) -#define exit(...) abort() - -%} - -%% - - /* If two patterns can match the same input, flex resolves the ambiguity: - * - By matching the longest possible string - * - In a tie, by using the pattern that appears first - * - * Also note that yytext is guaranteed to be null-terminated when the token is - * being built, (i.e. when flex calls our code snippet), but this is achieved - * by flex temporarily swapping the last character. Afterwards the pointer is - * still valid but the string isn't null-terminated anymore. - */ - /* We designed our own extended-ASCII to include required symbols in less - * than 255 glyphs. The file ion/include/ion/charset.h lists all added - * non-ASCII symbols with their char associated. For example, the char \x89 - * refered to Pi symbols. This artefact leads to the following lexer rules - * starting with \x. */ - -(([0-9]*[.]?[0-9]+)|([0-9]+[.]?[0-9]*))(\x8d\-?[0-9]+)? { *yylval = Poincare::Number::ParseDigits(yytext, yyleng); return DIGITS; } - /* For now, we decided not to parse u(0), because it seems a little complex. */ -u\(n\) { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -u\(n\+1\) { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -v\(n\) { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -v\(n\+1\) { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -u\_\{n\} { yytext[1] = '('; yytext[2] = 'n'; yytext[3] = ')'; yytext[4] = 0; *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -u\_\{n\+1\} { yytext[1] = '('; yytext[2] = 'n'; yytext[3] = '+'; yytext[4] = '1'; yytext[5] = ')'; yytext[6] = 0; *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -v\_\{n\} { yytext[1] = '('; yytext[2] = 'n'; yytext[3] = ')'; yytext[4] = 0; *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -v\_\{n\+1\} { yytext[1] = '('; yytext[2] = 'n'; yytext[3] = '+'; yytext[4] = '1'; yytext[5] = ')'; yytext[6] = 0; *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -V1 { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -N1 { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -V2 { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -N2 { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -V3 { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -N3 { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -X1 { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -Y1 { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -X2 { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -Y2 { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -X3 { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -Y3 { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -acos { *yylval = ArcCosine(); return FUNCTION; } -acosh { *yylval = HyperbolicArcCosine(); return FUNCTION; } -abs { *yylval = AbsoluteValue(); return FUNCTION; } -ans { *yylval = Poincare::Symbol(yytext, yyleng); return FINAL_SYMBOL; } -arg { *yylval = ComplexArgument(); return FUNCTION; } -asin { *yylval = ArcSine(); return FUNCTION; } -asinh { *yylval = HyperbolicArcSine(); return FUNCTION; } -atan { *yylval = ArcTangent(); return FUNCTION; } -atanh { *yylval = HyperbolicArcTangent(); return FUNCTION; } -binomial { *yylval = BinomialCoefficient(); return FUNCTION; } -ceil { *yylval = Ceiling(); return FUNCTION; } -confidence { *yylval = ConfidenceInterval(); return FUNCTION; } -diff { *yylval = Derivative(); return VARIABLE_DEPENDENT_FUNCTION; } -dim { *yylval = MatrixDimension(); return FUNCTION; } -conj { *yylval = Conjugate(); return FUNCTION; } -det { *yylval = Determinant(); return FUNCTION; } -cos { *yylval = Cosine(); return FUNCTION; } -cosh { *yylval = HyperbolicCosine(); return FUNCTION; } -factor { *yylval = Factor(); return FUNCTION; } -floor { *yylval = Floor(); return FUNCTION; } -frac { *yylval = FracPart(); return FUNCTION; } -gcd { *yylval = GreatCommonDivisor(); return FUNCTION; } -im { *yylval = ImaginaryPart(); return FUNCTION; } -int { *yylval = Integral(); return VARIABLE_DEPENDENT_FUNCTION; } -inverse { *yylval = MatrixInverse(); return FUNCTION; } -lcm { *yylval = LeastCommonMultiple(); return FUNCTION; } -ln { *yylval = NaperianLogarithm(); return FUNCTION; } -log\( { return LOG_FUNCTION; } -log\_\{ { return LOG_FUNCTION_TWO_ARGUMENTS; } -permute { *yylval = PermuteCoefficient(); return FUNCTION; } -prediction95 { *yylval = PredictionInterval(); return FUNCTION; } -prediction { *yylval = SimplePredictionInterval(); return FUNCTION; } -product { *yylval = Product(); return VARIABLE_DEPENDENT_FUNCTION; } -quo { *yylval = DivisionQuotient(); return FUNCTION; } -random { *yylval = Random(); return FUNCTION; } -randint { *yylval = Randint(); return FUNCTION; } -re { *yylval = RealPart(); return FUNCTION; } -rem { *yylval = DivisionRemainder(); return FUNCTION; } -root { *yylval = NthRoot(); return FUNCTION; } -round { *yylval = Round(); return FUNCTION; } -sin { *yylval = Sine(); return FUNCTION; } -sinh { *yylval = HyperbolicSine(); return FUNCTION; } -sum { *yylval = Sum(); return VARIABLE_DEPENDENT_FUNCTION; } -tan { *yylval = Tangent(); return FUNCTION; } -tanh { *yylval = HyperbolicTangent(); return FUNCTION; } -trace { *yylval = MatrixTrace(); return FUNCTION; } -transpose { *yylval = MatrixTranspose(); return FUNCTION; } -undef { *yylval = Undefined(); return TERM; } -inf { *yylval = Infinity(false); return TERM; } -\x1 { *yylval = Poincare::Symbol(yytext[0]); return FINAL_SYMBOL; } /* UnknownX */ -\x8a { *yylval = Poincare::Constant(yytext[0]); return FINAL_SYMBOL; } /* Pi */ -\x8c { *yylval = Poincare::Constant(yytext[0]); return FINAL_SYMBOL; } /* I complex */ -\x8f { *yylval = Poincare::Constant(yytext[0]); return FINAL_SYMBOL; } /* Exponential */ -\x90 { return STO; } -\x91 { *yylval = SquareRoot(); return FUNCTION; } -= { return EQUAL; } -\+ { return PLUS; } -\- { return MINUS; } -\x94 { return MULTIPLY; } -\x95 { return MULTIPLY; } -\* { return MULTIPLY; } -\/ { return DIVIDE; } -\^ { return POW; } -\! { return BANG; } -\( { return LEFT_PARENTHESIS; } -\) { return RIGHT_PARENTHESIS; } -\{ { return LEFT_BRACE; } -\} { return RIGHT_BRACE; } -\[ { return LEFT_BRACKET; } -\] { return RIGHT_BRACKET; } -\, { return COMMA; } -\_ { return UNDERSCORE; } -\x98 { *yylval = EmptyExpression(); return TERM; } -[ ]+ /* Ignore whitespaces */ - /* The rule to lex any symbol is defined after all other rules so that, for instance, sin is lexed as a Sinus and not as sin symbol */ -u { return UNDEFINED_SYMBOL; } -v { return UNDEFINED_SYMBOL; } -w { return UNDEFINED_SYMBOL; } - /*TODO prevent u,v or w symbol with something like ((?![uvw])[A-Za-z\_][A-Za-z\_0-9]*) ? */ -([A-Za-z\_][A-Za-z\_0-9]*) { *yylval = Poincare::Symbol(yytext, yyleng); return SYMBOL; } -. { return UNDEFINED_SYMBOL; } - -%% diff --git a/poincare/src/expression_lexer_parser.h b/poincare/src/expression_lexer_parser.h deleted file mode 100644 index 6453d7fbe..000000000 --- a/poincare/src/expression_lexer_parser.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Usually, YYSTYPE is defined as the union of the objects it might be. Here, - * Expression is non-trivial (specific copy-constructors and destructors), so - * it cannot be part of a union. */ - -#define YYSTYPE Poincare::Expression diff --git a/poincare/src/expression_parser.y b/poincare/src/expression_parser.y deleted file mode 100644 index 69ed98e9f..000000000 --- a/poincare/src/expression_parser.y +++ /dev/null @@ -1,174 +0,0 @@ -/* This file should be built with Bison 3.0.4. It might work with other Bison - * version, but those haven't been tested. */ - -/* When calling the parser, we will provide yyparse with an extra parameter : a - * backpointer to the resulting expression. */ -%parse-param { Poincare::Expression * expressionOutput } - -/* The value stored in each token is an Expresssion, which is a complex C++ - * object. If we use a global variable to keep track of yylval, this object will - * be long-lived AND will need to be initialized at startup. - * Both those behaviors are annoying: the first one because you need to delete - * the object if an exception happens, the second one because of the static init - * order fiasco. - * Using a pure parser (i.e. one without any global variable) fixes this. */ -%pure-parser - -%{ -#include - -/* YYSTYPE has to be defined in expression_lexer.y, expression.cpp and here - * because the genereated code is included in expression_parser.cpp, not .hpp - * so we use an additional header which only define YYSTYPE. This should be - * discarded with Bison 3. */ -#include "expression_lexer_parser.h" - -/* The lexer manipulates tokens defined by the parser, so we need the following - * inclusion order. */ -#include "expression_parser.hpp" -#include "expression_lexer.hpp" - -/* Declare our error-handling function. Since we're making a re-entrant parser, - * it takes a context parameter as its first input. */ -void poincare_expression_yyerror(Poincare::Expression * expressionOutput, char const *msg); - -/* Bison expects to use __builtin_memcpy. We don't want to provide this, but - * instead we do provide regular memcpy. Let's instruct Bison to use it. */ -#define YYCOPY(To, From, Count) memcpy(To, From, (Count)*sizeof(*(From))) - -using namespace Poincare; - -%} - -/* The INTEGER token uses the "string" part of the union to store its value */ - - -/* Make the operators left associative. - * This makes 1 - 2 - 5’ be ‘(1 - 2) - 5’ instead of ‘1 - (2 - 5)’. - * This makes 1 / 2 / 5’ be ‘(1 / 2) / 5’ instead of ‘1 / (2 / 5)’. - * - * This also puts the precedence of the operators, here DIVIDE has a bigger - * precedence than PLUS for example. - * - * Note that specifying the precedence of reduces is usually a very bad practice - * expect in the case of operator precedence and of IF/THE/ELSE structure which - * are the only two exceptions. - * If you need to define precedence in order to avoid shift/redice conflicts for - * other situations your grammar is most likely ambiguous. - */ - -/* Note that in bison, precedence of parsing depend on the order they are defined in here, the last - * one has the highest precedence. */ - -%nonassoc EQUAL STO -%left PLUS -%left MINUS -%left MULTIPLY -%left DIVIDE -%left IMPLICIT_MULTIPLY -%nonassoc UNARY_MINUS -%right POW -%left BANG -%nonassoc LEFT_BRACKET -%nonassoc RIGHT_BRACKET -%nonassoc LEFT_BRACE -%nonassoc RIGHT_BRACE -%nonassoc FUNCTION LOG_FUNCTION LOG_FUNCTION_TWO_ARGUMENTS VARIABLE_DEPENDENT_FUNCTION -%left COMMA -%nonassoc UNDERSCORE -%nonassoc DIGITS -%nonassoc TERM -%nonassoc SYMBOL FINAL_SYMBOL -%nonassoc SYMBOL_TO_FUNCTION -%nonassoc LEFT_PARENTHESIS -%nonassoc RIGHT_PARENTHESIS -%nonassoc UNDEFINED_SYMBOL - -/* During error recovery, some symbols need to be discarded. No destructor need - * to be specified to Bison because all symbols are Poincare::Expression that - * are garbage collected. */ - -%% - -Root: final_exp { *expressionOutput = $1; } - ; - -lstData: exp { $$ = Matrix($1); } - | lstData COMMA exp { $$ = $1; static_cast($$).addChildAtIndexInPlace($3, $$.numberOfChildren(), $$.numberOfChildren()); } - ; - -/* MATRICES_ARE_DEFINED */ -mtxData: LEFT_BRACKET lstData RIGHT_BRACKET { $$ = Matrix::EmptyMatrix(); static_cast($$).addChildrenAsRowInPlace($2, 0); } - | mtxData LEFT_BRACKET lstData RIGHT_BRACKET { if ($3.numberOfChildren() != static_cast($1).numberOfColumns()) { YYERROR; } ; $$ = $1; static_cast($$).addChildrenAsRowInPlace($3, $$.numberOfChildren()); } - ; - -/* When approximating expressions to double, results are bounded by 1E308 (and - * 1E-308 for small numbers). We thus accept decimals whose exponents are in - * {-1000, 1000}. However, we have to compute the exponent first to decide - * whether to accept the decimal. The exponent of a Decimal is stored as an - * int32_t. We thus have to throw an error when the exponent computation might - * overflow. Finally, we escape computation by throwing an error when the length - * of the exponent digits is above 4 (0.00...-256 times-...01E1256=1E1000 is - * accepted and 1000-...256times...-0E10000 = 1E10256, 10256 does not overflow - * an int32_t). */ -number : DIGITS { $$ = $1; } - | DIGITS DIGITS { YYERROR; } - ; - -short_symb : SYMBOL { if (strlen(static_cast($1).name()) +1 > SymbolAbstract::k_maxNameSize) { YYERROR; } ; $$ = $1; } - ; - -func : short_symb LEFT_PARENTHESIS lstData RIGHT_PARENTHESIS %prec SYMBOL_TO_FUNCTION { if ($3.numberOfChildren() != 1) { YYERROR; } ; $$ = Function(static_cast($1).name(), $3.childAtIndex(0)); } - ; - -symb : short_symb { $$ = $1; } - ; - -term : TERM { $$ = $1; } - | func { $$ = $1; } - | symb { $$ = $1; } - | FINAL_SYMBOL { $$ = $1; } - | number { $$ = $1; } - | FUNCTION LEFT_PARENTHESIS RIGHT_PARENTHESIS { if ($1.numberOfChildren() != 0) { YYERROR; } $$ = $1; } - | FUNCTION LEFT_PARENTHESIS lstData RIGHT_PARENTHESIS { $$ = $1; if ($$.numberOfChildren() != ($3.numberOfChildren())) { YYERROR; } ; $$.setChildrenInPlace($3); } -/* Special case for logarithm, as we do not at first if it needs 1 or 2 children */ - | LOG_FUNCTION lstData RIGHT_PARENTHESIS { if ($2.numberOfChildren() == 1) { $$ = Logarithm($2.childAtIndex(0)); } else if ($2.numberOfChildren() == 2) { $$ = Logarithm($2.childAtIndex(0), $2.childAtIndex(1));} else { YYERROR; } ; } - | LOG_FUNCTION_TWO_ARGUMENTS exp RIGHT_BRACE LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = Logarithm($5, $2); } - | VARIABLE_DEPENDENT_FUNCTION LEFT_PARENTHESIS lstData RIGHT_PARENTHESIS { if ($$.numberOfChildren() != ($3.numberOfChildren())) { YYERROR; } ; if ($3.childAtIndex(1).type() != ExpressionNode::Type::Symbol && $3.childAtIndex(1).type() != ExpressionNode::Type::EmptyExpression ) { YYERROR; } ; $$ = $1; $$.setChildrenInPlace($3); } - | LEFT_PARENTHESIS exp RIGHT_PARENTHESIS { $$ = Parenthesis($2); } -/* MATRICES_ARE_DEFINED */ - | LEFT_BRACKET mtxData RIGHT_BRACKET { $$ = $2; } - ; - -bang : term { $$ = $1; } - | term BANG { $$ = Factorial($1); } - ; - -factor : bang { $$ = $1; } - | bang pow %prec IMPLICIT_MULTIPLY { $$ = Multiplication($1, $2); } - ; - -pow : factor { $$ = $1; } - | bang POW pow { $$ = Power($1,$3); } - | bang POW MINUS pow { $$ = Power($1,Opposite($4)); } - ; - -exp : pow { $$ = $1; } - | exp DIVIDE exp { $$ = Division($1,$3); } - | exp MULTIPLY exp { $$ = Multiplication($1,$3); } - | exp MINUS exp { $$ = Subtraction($1,$3); } - | MINUS exp %prec UNARY_MINUS { $$ = Opposite($2); } - | exp PLUS exp { $$ = Addition($1,$3); } - ; - -final_exp : exp { $$ = $1; } - | exp STO symb { $$ = Store($1, static_cast($3)); } - | exp STO func { if ($3.childAtIndex(0).type() != ExpressionNode::Type::Symbol) { YYERROR; } ; $$ = Store($1, static_cast($3)); } - | exp EQUAL exp { $$ = Equal($1, $3); } - ; -%% - -void poincare_expression_yyerror(Expression * expressionOutput, const char * msg) { - // Handle the error! - // TODO: handle explicitely different type of errors (division by 0, missing parenthesis). This should call back the container to display a pop up with a message corresponding to the error? -} diff --git a/poincare/src/factor.cpp b/poincare/src/factor.cpp index 640df12d0..398e868ca 100644 --- a/poincare/src/factor.cpp +++ b/poincare/src/factor.cpp @@ -14,18 +14,16 @@ extern "C" { namespace Poincare { -int FactorNode::numberOfChildren() const { return Factor::NumberOfChildren(); } +int FactorNode::numberOfChildren() const { return Factor::FunctionHelper()->numberOfChildren(); } Layout FactorNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(Factor(this), floatDisplayMode, numberOfSignificantDigits, Factor::Name()); + return LayoutHelper::Prefix(Factor(this), floatDisplayMode, numberOfSignificantDigits, Factor::FunctionHelper()->name()); } int FactorNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Factor::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Factor::FunctionHelper()->name()); } -Factor::Factor() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression FactorNode::shallowBeautify(Context & context, Preferences::AngleUnit angleUnit) { return Factor(this).shallowBeautify(context, angleUnit); } @@ -90,4 +88,6 @@ Multiplication Factor::createMultiplicationOfIntegerPrimeDecomposition(Integer i return m; } +constexpr Expression::FunctionHelper Factor::m_functionHelper = Expression::FunctionHelper("factor", 1, &Factor::UntypedBuilder); + } diff --git a/poincare/src/floor.cpp b/poincare/src/floor.cpp index c86089813..1c4b0c60e 100644 --- a/poincare/src/floor.cpp +++ b/poincare/src/floor.cpp @@ -11,14 +11,14 @@ namespace Poincare { -int FloorNode::numberOfChildren() const { return Floor::NumberOfChildren(); } +int FloorNode::numberOfChildren() const { return Floor::FunctionHelper()->numberOfChildren(); } Layout FloorNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { return FloorLayout(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits)); } int FloorNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Floor::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Floor::FunctionHelper()->name()); } template @@ -33,8 +33,6 @@ Expression FloorNode::shallowReduce(Context & context, Preferences::AngleUnit an return Floor(this).shallowReduce(context, angleUnit, replaceSymbols); } -Floor::Floor() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression Floor::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -74,4 +72,6 @@ Expression Floor::shallowReduce(Context & context, Preferences::AngleUnit angleU return result; } +constexpr Expression::FunctionHelper Floor::m_functionHelper = Expression::FunctionHelper("floor", 1, &Floor::UntypedBuilder); + } diff --git a/poincare/src/frac_part.cpp b/poincare/src/frac_part.cpp index 7e7a89284..9915bc739 100644 --- a/poincare/src/frac_part.cpp +++ b/poincare/src/frac_part.cpp @@ -7,14 +7,14 @@ namespace Poincare { -int FracPartNode::numberOfChildren() const { return FracPart::NumberOfChildren(); } +int FracPartNode::numberOfChildren() const { return FracPart::FunctionHelper()->numberOfChildren(); } Layout FracPartNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(FracPart(this), floatDisplayMode, numberOfSignificantDigits, FracPart::Name()); + return LayoutHelper::Prefix(FracPart(this), floatDisplayMode, numberOfSignificantDigits, FracPart::FunctionHelper()->name()); } int FracPartNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, FracPart::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, FracPart::FunctionHelper()->name()); } Expression FracPartNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { @@ -29,8 +29,6 @@ Complex FracPartNode::computeOnComplex(const std::complex c, Preferences:: return Complex(c.real()-std::floor(c.real())); } -FracPart::FracPart() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression FracPart::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -56,4 +54,6 @@ Expression FracPart::shallowReduce(Context & context, Preferences::AngleUnit ang return result; } +constexpr Expression::FunctionHelper FracPart::m_functionHelper = Expression::FunctionHelper("frac", 1, &FracPart::UntypedBuilder); + } diff --git a/poincare/src/great_common_divisor.cpp b/poincare/src/great_common_divisor.cpp index 77305b173..686f1c71e 100644 --- a/poincare/src/great_common_divisor.cpp +++ b/poincare/src/great_common_divisor.cpp @@ -8,14 +8,14 @@ namespace Poincare { -int GreatCommonDivisorNode::numberOfChildren() const { return GreatCommonDivisor::NumberOfChildren(); } +int GreatCommonDivisorNode::numberOfChildren() const { return GreatCommonDivisor::FunctionHelper()->numberOfChildren(); } Layout GreatCommonDivisorNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(GreatCommonDivisor(this), floatDisplayMode, numberOfSignificantDigits, GreatCommonDivisor::Name()); + return LayoutHelper::Prefix(GreatCommonDivisor(this), floatDisplayMode, numberOfSignificantDigits, GreatCommonDivisor::FunctionHelper()->name()); } int GreatCommonDivisorNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, GreatCommonDivisor::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, GreatCommonDivisor::FunctionHelper()->name()); } Expression GreatCommonDivisorNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { @@ -46,8 +46,6 @@ Evaluation GreatCommonDivisorNode::templatedApproximate(Context& context, Pre return Complex(std::round((T)a)); } -GreatCommonDivisor::GreatCommonDivisor() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression GreatCommonDivisor::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -93,4 +91,6 @@ Expression GreatCommonDivisor::shallowReduce(Context & context, Preferences::Ang return result; } +constexpr Expression::FunctionHelper GreatCommonDivisor::m_functionHelper = Expression::FunctionHelper("gcd", 2, &GreatCommonDivisor::UntypedBuilder); + } diff --git a/poincare/src/hyperbolic_arc_cosine.cpp b/poincare/src/hyperbolic_arc_cosine.cpp index 2cefdc6a2..19aa3bbdf 100644 --- a/poincare/src/hyperbolic_arc_cosine.cpp +++ b/poincare/src/hyperbolic_arc_cosine.cpp @@ -7,11 +7,11 @@ namespace Poincare { Layout HyperbolicArcCosineNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(HyperbolicArcCosine(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicArcCosine::Name()); + return LayoutHelper::Prefix(HyperbolicArcCosine(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicArcCosine::FunctionHelper()->name()); } int HyperbolicArcCosineNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicArcCosine::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicArcCosine::FunctionHelper()->name()); } template @@ -27,4 +27,6 @@ Complex HyperbolicArcCosineNode::computeOnComplex(const std::complex c, Pr template Complex Poincare::HyperbolicArcCosineNode::computeOnComplex(std::complex, Preferences::AngleUnit); template Complex Poincare::HyperbolicArcCosineNode::computeOnComplex(std::complex, Preferences::AngleUnit); +constexpr Expression::FunctionHelper HyperbolicArcCosine::m_functionHelper = Expression::FunctionHelper("acosh", 1, &HyperbolicArcCosine::UntypedBuilder); + } diff --git a/poincare/src/hyperbolic_arc_sine.cpp b/poincare/src/hyperbolic_arc_sine.cpp index 191108232..21515df76 100644 --- a/poincare/src/hyperbolic_arc_sine.cpp +++ b/poincare/src/hyperbolic_arc_sine.cpp @@ -7,10 +7,10 @@ namespace Poincare { Layout HyperbolicArcSineNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(HyperbolicArcSine(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicArcSine::Name()); + return LayoutHelper::Prefix(HyperbolicArcSine(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicArcSine::FunctionHelper()->name()); } int HyperbolicArcSineNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicArcSine::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicArcSine::FunctionHelper()->name()); } template @@ -30,4 +30,6 @@ Complex HyperbolicArcSineNode::computeOnComplex(const std::complex c, Pref template Complex Poincare::HyperbolicArcSineNode::computeOnComplex(std::complex, Preferences::AngleUnit); template Complex Poincare::HyperbolicArcSineNode::computeOnComplex(std::complex, Preferences::AngleUnit); +constexpr Expression::FunctionHelper HyperbolicArcSine::m_functionHelper = Expression::FunctionHelper("asinh", 1, &HyperbolicArcSine::UntypedBuilder); + } diff --git a/poincare/src/hyperbolic_arc_tangent.cpp b/poincare/src/hyperbolic_arc_tangent.cpp index 46dab4595..8dde2d5fd 100644 --- a/poincare/src/hyperbolic_arc_tangent.cpp +++ b/poincare/src/hyperbolic_arc_tangent.cpp @@ -7,11 +7,11 @@ namespace Poincare { Layout HyperbolicArcTangentNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(HyperbolicArcTangent(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicArcTangent::Name()); + return LayoutHelper::Prefix(HyperbolicArcTangent(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicArcTangent::FunctionHelper()->name()); } int HyperbolicArcTangentNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicArcTangent::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicArcTangent::FunctionHelper()->name()); } template @@ -31,4 +31,6 @@ Complex HyperbolicArcTangentNode::computeOnComplex(const std::complex c, P template Complex Poincare::HyperbolicArcTangentNode::computeOnComplex(std::complex, Preferences::AngleUnit); template Complex Poincare::HyperbolicArcTangentNode::computeOnComplex(std::complex, Preferences::AngleUnit); +constexpr Expression::FunctionHelper HyperbolicArcTangent::m_functionHelper = Expression::FunctionHelper("atanh", 1, &HyperbolicArcTangent::UntypedBuilder); + } diff --git a/poincare/src/hyperbolic_cosine.cpp b/poincare/src/hyperbolic_cosine.cpp index a34b6013a..68f12fa76 100644 --- a/poincare/src/hyperbolic_cosine.cpp +++ b/poincare/src/hyperbolic_cosine.cpp @@ -5,10 +5,10 @@ namespace Poincare { Layout HyperbolicCosineNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(HyperbolicCosine(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicCosine::Name()); + return LayoutHelper::Prefix(HyperbolicCosine(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicCosine::FunctionHelper()->name()); } int HyperbolicCosineNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicCosine::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicCosine::FunctionHelper()->name()); } template @@ -19,4 +19,6 @@ Complex HyperbolicCosineNode::computeOnComplex(const std::complex c, Prefe template Complex Poincare::HyperbolicCosineNode::computeOnComplex(std::complex, Preferences::AngleUnit); template Complex Poincare::HyperbolicCosineNode::computeOnComplex(std::complex, Preferences::AngleUnit); +constexpr Expression::FunctionHelper HyperbolicCosine::m_functionHelper = Expression::FunctionHelper("cosh", 1, &HyperbolicCosine::UntypedBuilder); + } diff --git a/poincare/src/hyperbolic_sine.cpp b/poincare/src/hyperbolic_sine.cpp index ae84f7a7f..803b6284d 100644 --- a/poincare/src/hyperbolic_sine.cpp +++ b/poincare/src/hyperbolic_sine.cpp @@ -5,10 +5,10 @@ namespace Poincare { Layout HyperbolicSineNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(HyperbolicSine(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicSine::Name()); + return LayoutHelper::Prefix(HyperbolicSine(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicSine::FunctionHelper()->name()); } int HyperbolicSineNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicSine::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicSine::FunctionHelper()->name()); } template @@ -19,4 +19,6 @@ Complex HyperbolicSineNode::computeOnComplex(const std::complex c, Prefere template Complex Poincare::HyperbolicSineNode::computeOnComplex(std::complex, Preferences::AngleUnit); template Complex Poincare::HyperbolicSineNode::computeOnComplex(std::complex, Preferences::AngleUnit); +constexpr Expression::FunctionHelper HyperbolicSine::m_functionHelper = Expression::FunctionHelper("sinh", 1, &HyperbolicSine::UntypedBuilder); + } diff --git a/poincare/src/hyperbolic_tangent.cpp b/poincare/src/hyperbolic_tangent.cpp index 47aadd4cc..1e53a87e8 100644 --- a/poincare/src/hyperbolic_tangent.cpp +++ b/poincare/src/hyperbolic_tangent.cpp @@ -5,10 +5,10 @@ namespace Poincare { Layout HyperbolicTangentNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(HyperbolicTangent(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicTangent::Name()); + return LayoutHelper::Prefix(HyperbolicTangent(this), floatDisplayMode, numberOfSignificantDigits, HyperbolicTangent::FunctionHelper()->name()); } int HyperbolicTangentNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicTangent::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, HyperbolicTangent::FunctionHelper()->name()); } template @@ -19,4 +19,6 @@ Complex HyperbolicTangentNode::computeOnComplex(const std::complex c, Pref template Complex Poincare::HyperbolicTangentNode::computeOnComplex(std::complex, Preferences::AngleUnit); template Complex Poincare::HyperbolicTangentNode::computeOnComplex(std::complex, Preferences::AngleUnit); +constexpr Expression::FunctionHelper HyperbolicTangent::m_functionHelper = Expression::FunctionHelper("tanh", 1, &HyperbolicTangent::UntypedBuilder); + } diff --git a/poincare/src/imaginary_part.cpp b/poincare/src/imaginary_part.cpp index a7887c05c..2ab1ebf89 100644 --- a/poincare/src/imaginary_part.cpp +++ b/poincare/src/imaginary_part.cpp @@ -7,22 +7,20 @@ namespace Poincare { -int ImaginaryPartNode::numberOfChildren() const { return ImaginaryPart::NumberOfChildren(); } +int ImaginaryPartNode::numberOfChildren() const { return ImaginaryPart::FunctionHelper()->numberOfChildren(); } Layout ImaginaryPartNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(ImaginaryPart(this), floatDisplayMode, numberOfSignificantDigits, ImaginaryPart::Name()); + return LayoutHelper::Prefix(ImaginaryPart(this), floatDisplayMode, numberOfSignificantDigits, ImaginaryPart::FunctionHelper()->name()); } int ImaginaryPartNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ImaginaryPart::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, ImaginaryPart::FunctionHelper()->name()); } Expression ImaginaryPartNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { return ImaginaryPart(this).shallowReduce(context, angleUnit, replaceSymbols); } -ImaginaryPart::ImaginaryPart() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression ImaginaryPart::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -44,4 +42,6 @@ Expression ImaginaryPart::shallowReduce(Context & context, Preferences::AngleUni return *this; } +constexpr Expression::FunctionHelper ImaginaryPart::m_functionHelper = Expression::FunctionHelper("im", 1, &ImaginaryPart::UntypedBuilder); + } diff --git a/poincare/src/integral.cpp b/poincare/src/integral.cpp index cf20c5524..77d5ac394 100644 --- a/poincare/src/integral.cpp +++ b/poincare/src/integral.cpp @@ -10,7 +10,7 @@ namespace Poincare { -int IntegralNode::numberOfChildren() const { return Integral::NumberOfChildren(); } +int IntegralNode::numberOfChildren() const { return Integral::FunctionHelper()->numberOfChildren(); } int IntegralNode::polynomialDegree(Context & context, const char * symbolName) const { if (childAtIndex(0)->polynomialDegree(context, symbolName) == 0 @@ -33,7 +33,7 @@ Layout IntegralNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, } int IntegralNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Integral::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Integral::FunctionHelper()->name()); } Expression IntegralNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { @@ -188,9 +188,6 @@ T IntegralNode::adaptiveQuadrature(T a, T b, T eps, int numberOfIterations, Cont } #endif - -Integral::Integral() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression Integral::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -210,4 +207,6 @@ Expression Integral::shallowReduce(Context & context, Preferences::AngleUnit ang return *this; } +constexpr Expression::FunctionHelper Integral::m_functionHelper = Expression::FunctionHelper("int", 4, &Integral::UntypedBuilder); + } diff --git a/poincare/src/least_common_multiple.cpp b/poincare/src/least_common_multiple.cpp index 7a0909714..480b26519 100644 --- a/poincare/src/least_common_multiple.cpp +++ b/poincare/src/least_common_multiple.cpp @@ -9,14 +9,14 @@ namespace Poincare { -int LeastCommonMultipleNode::numberOfChildren() const { return LeastCommonMultiple::NumberOfChildren(); } +int LeastCommonMultipleNode::numberOfChildren() const { return LeastCommonMultiple::FunctionHelper()->numberOfChildren(); } Layout LeastCommonMultipleNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(LeastCommonMultiple(this), floatDisplayMode, numberOfSignificantDigits, LeastCommonMultiple::Name()); + return LayoutHelper::Prefix(LeastCommonMultiple(this), floatDisplayMode, numberOfSignificantDigits, LeastCommonMultiple::FunctionHelper()->name()); } int LeastCommonMultipleNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, LeastCommonMultiple::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, LeastCommonMultiple::FunctionHelper()->name()); } Expression LeastCommonMultipleNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { @@ -51,8 +51,6 @@ Evaluation LeastCommonMultipleNode::templatedApproximate(Context& context, Pr return Complex(product/a); } -LeastCommonMultiple::LeastCommonMultiple() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression LeastCommonMultiple::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -100,4 +98,6 @@ Expression LeastCommonMultiple::shallowReduce(Context & context, Preferences::An return result; } +constexpr Expression::FunctionHelper LeastCommonMultiple::m_functionHelper = Expression::FunctionHelper("lcm", 2, &LeastCommonMultiple::UntypedBuilder); + } diff --git a/poincare/src/logarithm.cpp b/poincare/src/logarithm.cpp index 6ea2c4416..2d8272435 100644 --- a/poincare/src/logarithm.cpp +++ b/poincare/src/logarithm.cpp @@ -21,14 +21,14 @@ namespace Poincare { template<> -int LogarithmNode<1>::numberOfChildren() const { return CommonLogarithm::NumberOfChildren(); } +int LogarithmNode<1>::numberOfChildren() const { return CommonLogarithm::FunctionHelper()->numberOfChildren(); } template<> -int LogarithmNode<2>::numberOfChildren() const { return Logarithm::NumberOfChildren(); } +int LogarithmNode<2>::numberOfChildren() const { return Logarithm::FunctionHelper()->numberOfChildren(); } template<> Layout LogarithmNode<1>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, CommonLogarithm::Name()); + return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, CommonLogarithm::FunctionHelper()->name()); } template<> @@ -40,7 +40,7 @@ Layout LogarithmNode<2>::createLayout(Preferences::PrintFloatMode floatDisplayMo template int LogarithmNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, T == 1 ? CommonLogarithm::Name() : Logarithm::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, T == 1 ? CommonLogarithm::FunctionHelper()->name() : Logarithm::FunctionHelper()->name()); } template<> @@ -96,7 +96,7 @@ Expression CommonLogarithm::shallowReduce(Context & context, Preferences::AngleU } #endif #endif - Logarithm log(childAtIndex(0), Rational(10)); + Logarithm log = Logarithm::Builder(childAtIndex(0), Rational(10)); replaceWithInPlace(log); return log.shallowReduce(context, angleUnit, replaceSymbols); } @@ -305,19 +305,23 @@ Expression Logarithm::shallowBeautify(Context & context, Preferences::AngleUnit assert(numberOfChildren() == 2); Constant e = Constant(Ion::Charset::Exponential); if (childAtIndex(1).isIdenticalTo(e)) { - NaperianLogarithm np(childAtIndex(0)); + NaperianLogarithm np = NaperianLogarithm::Builder(childAtIndex(0)); replaceWithInPlace(np); return np; } Rational ten(10); if (childAtIndex(1).isIdenticalTo(ten)) { - CommonLogarithm l(childAtIndex(0)); + CommonLogarithm l = CommonLogarithm::Builder(childAtIndex(0)); replaceWithInPlace(l); return l; } return *this; } +constexpr Expression::FunctionHelper Logarithm::m_functionHelper = Expression::FunctionHelper("log", 2, &Logarithm::UntypedBuilder); + +constexpr Expression::FunctionHelper CommonLogarithm::m_functionHelper = Expression::FunctionHelper("log", 1, &CommonLogarithm::UntypedBuilder); + template Evaluation LogarithmNode<1>::templatedApproximate(Poincare::Context&, Poincare::Preferences::AngleUnit) const; template Evaluation LogarithmNode<1>::templatedApproximate(Poincare::Context&, Poincare::Preferences::AngleUnit) const; template Evaluation LogarithmNode<2>::templatedApproximate(Poincare::Context&, Poincare::Preferences::AngleUnit) const; diff --git a/poincare/src/matrix_dimension.cpp b/poincare/src/matrix_dimension.cpp index 1fdd154b0..da660f5e5 100644 --- a/poincare/src/matrix_dimension.cpp +++ b/poincare/src/matrix_dimension.cpp @@ -7,18 +7,18 @@ namespace Poincare { -int MatrixDimensionNode::numberOfChildren() const { return MatrixDimension::NumberOfChildren(); } +int MatrixDimensionNode::numberOfChildren() const { return MatrixDimension::FunctionHelper()->numberOfChildren(); } Expression MatrixDimensionNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { return MatrixDimension(this).shallowReduce(context, angleUnit, replaceSymbols); } Layout MatrixDimensionNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(MatrixDimension(this), floatDisplayMode, numberOfSignificantDigits, MatrixDimension::Name()); + return LayoutHelper::Prefix(MatrixDimension(this), floatDisplayMode, numberOfSignificantDigits, MatrixDimension::FunctionHelper()->name()); } int MatrixDimensionNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, MatrixDimension::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, MatrixDimension::FunctionHelper()->name()); } template @@ -35,8 +35,6 @@ Evaluation MatrixDimensionNode::templatedApproximate(Context& context, Prefer return MatrixComplex(operands, 1, 2); } -MatrixDimension::MatrixDimension() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression MatrixDimension::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -75,4 +73,6 @@ Expression MatrixDimension::shallowReduce(Context & context, Preferences::AngleU #endif } +constexpr Expression::FunctionHelper MatrixDimension::m_functionHelper = Expression::FunctionHelper("dim", 1, &MatrixDimension::UntypedBuilder); + } diff --git a/poincare/src/matrix_inverse.cpp b/poincare/src/matrix_inverse.cpp index 79ab4ceca..41b7a590f 100644 --- a/poincare/src/matrix_inverse.cpp +++ b/poincare/src/matrix_inverse.cpp @@ -10,18 +10,18 @@ namespace Poincare { -int MatrixInverseNode::numberOfChildren() const { return MatrixInverse::NumberOfChildren(); } +int MatrixInverseNode::numberOfChildren() const { return MatrixInverse::FunctionHelper()->numberOfChildren(); } Expression MatrixInverseNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { return MatrixInverse(this).shallowReduce(context, angleUnit, replaceSymbols); } Layout MatrixInverseNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(MatrixInverse(this), floatDisplayMode, numberOfSignificantDigits, MatrixInverse::Name()); + return LayoutHelper::Prefix(MatrixInverse(this), floatDisplayMode, numberOfSignificantDigits, MatrixInverse::FunctionHelper()->name()); } int MatrixInverseNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, MatrixInverse::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, MatrixInverse::FunctionHelper()->name()); } // TODO: handle this exactly in shallowReduce for small dimensions. @@ -40,8 +40,6 @@ Evaluation MatrixInverseNode::templatedApproximate(Context& context, Preferen return inverse; } -MatrixInverse::MatrixInverse() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression MatrixInverse::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -74,4 +72,6 @@ Expression MatrixInverse::shallowReduce(Context & context, Preferences::AngleUni #endif } +constexpr Expression::FunctionHelper MatrixInverse::m_functionHelper = Expression::FunctionHelper("inverse", 1, &MatrixInverse::UntypedBuilder); + } diff --git a/poincare/src/matrix_trace.cpp b/poincare/src/matrix_trace.cpp index 3f25c406c..44d1d69c5 100644 --- a/poincare/src/matrix_trace.cpp +++ b/poincare/src/matrix_trace.cpp @@ -9,18 +9,18 @@ namespace Poincare { -int MatrixTraceNode::numberOfChildren() const { return MatrixTrace::NumberOfChildren(); } +int MatrixTraceNode::numberOfChildren() const { return MatrixTrace::FunctionHelper()->numberOfChildren(); } Expression MatrixTraceNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { return MatrixTrace(this).shallowReduce(context, angleUnit, replaceSymbols); } Layout MatrixTraceNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(MatrixTrace(this), floatDisplayMode, numberOfSignificantDigits, MatrixTrace::Name()); + return LayoutHelper::Prefix(MatrixTrace(this), floatDisplayMode, numberOfSignificantDigits, MatrixTrace::FunctionHelper()->name()); } int MatrixTraceNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, MatrixTrace::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, MatrixTrace::FunctionHelper()->name()); } template @@ -30,8 +30,6 @@ Evaluation MatrixTraceNode::templatedApproximate(Context& context, Preference return result; } -MatrixTrace::MatrixTrace() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression MatrixTrace::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -68,4 +66,6 @@ Expression MatrixTrace::shallowReduce(Context & context, Preferences::AngleUnit #endif } +constexpr Expression::FunctionHelper MatrixTrace::m_functionHelper = Expression::FunctionHelper("trace", 1, &MatrixTrace::UntypedBuilder); + } diff --git a/poincare/src/matrix_transpose.cpp b/poincare/src/matrix_transpose.cpp index 6cdb2775b..72cc9129c 100644 --- a/poincare/src/matrix_transpose.cpp +++ b/poincare/src/matrix_transpose.cpp @@ -8,18 +8,18 @@ namespace Poincare { -int MatrixTransposeNode::numberOfChildren() const { return MatrixTranspose::NumberOfChildren(); } +int MatrixTransposeNode::numberOfChildren() const { return MatrixTranspose::FunctionHelper()->numberOfChildren(); } Expression MatrixTransposeNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { return MatrixTranspose(this).shallowReduce(context, angleUnit, replaceSymbols); } Layout MatrixTransposeNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(MatrixTranspose(this), floatDisplayMode, numberOfSignificantDigits, MatrixTranspose::Name()); + return LayoutHelper::Prefix(MatrixTranspose(this), floatDisplayMode, numberOfSignificantDigits, MatrixTranspose::FunctionHelper()->name()); } int MatrixTransposeNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, MatrixTranspose::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, MatrixTranspose::FunctionHelper()->name()); } template @@ -35,8 +35,6 @@ Evaluation MatrixTransposeNode::templatedApproximate(Context& context, Prefer return transpose; } -MatrixTranspose::MatrixTranspose() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression MatrixTranspose::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -63,4 +61,6 @@ Expression MatrixTranspose::shallowReduce(Context & context, Preferences::AngleU #endif } +constexpr Expression::FunctionHelper MatrixTranspose::m_functionHelper = Expression::FunctionHelper("transpose", 1, &MatrixTranspose::UntypedBuilder); + } diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index 0db70283e..79dcdca70 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -610,7 +610,7 @@ void Multiplication::factorizeSineAndCosine(int i, int j, Context & context, Pre Number sumPQ = Number::Addition(p, q); Number absP = p.clone().convert().setSign(ExpressionNode::Sign::Positive, context, angleUnit); Number absQ = q.clone().convert().setSign(ExpressionNode::Sign::Positive, context, angleUnit); - Expression tan = Tangent(x.clone()); + Expression tan = Tangent::Builder(x.clone()); if (Number::NaturalOrder(absP, absQ) < 0) { // Replace sin(x) by tan(x) or sin(x)^p by tan(x)^p if (p.isRationalOne()) { diff --git a/poincare/src/naperian_logarithm.cpp b/poincare/src/naperian_logarithm.cpp index f5d1dd07b..d3d8bf82f 100644 --- a/poincare/src/naperian_logarithm.cpp +++ b/poincare/src/naperian_logarithm.cpp @@ -7,21 +7,19 @@ namespace Poincare { -int NaperianLogarithmNode::numberOfChildren() const { return NaperianLogarithm::NumberOfChildren(); } +int NaperianLogarithmNode::numberOfChildren() const { return NaperianLogarithm::FunctionHelper()->numberOfChildren(); } Layout NaperianLogarithmNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, NaperianLogarithm::Name()); + return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, NaperianLogarithm::FunctionHelper()->name()); } int NaperianLogarithmNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, NaperianLogarithm::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, NaperianLogarithm::FunctionHelper()->name()); } Expression NaperianLogarithmNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { return NaperianLogarithm(this).shallowReduce(context, angleUnit, replaceSymbols); } -NaperianLogarithm::NaperianLogarithm() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression NaperianLogarithm::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -34,9 +32,11 @@ Expression NaperianLogarithm::shallowReduce(Context & context, Preferences::Angl return SimplificationHelper::Map(*this, context, angleUnit); } #endif - Logarithm l = Logarithm(childAtIndex(0), Constant(Ion::Charset::Exponential)); + Logarithm l = Logarithm::Builder(childAtIndex(0), Constant(Ion::Charset::Exponential)); replaceWithInPlace(l); return l.shallowReduce(context, angleUnit); } +constexpr Expression::FunctionHelper NaperianLogarithm::m_functionHelper = Expression::FunctionHelper("ln", 1, &NaperianLogarithm::UntypedBuilder); + } diff --git a/poincare/src/nth_root.cpp b/poincare/src/nth_root.cpp index 58ee716b0..af199380b 100644 --- a/poincare/src/nth_root.cpp +++ b/poincare/src/nth_root.cpp @@ -10,7 +10,7 @@ namespace Poincare { -int NthRootNode::numberOfChildren() const { return NthRoot::NumberOfChildren(); } +int NthRootNode::numberOfChildren() const { return NthRoot::FunctionHelper()->numberOfChildren(); } Layout NthRootNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { return NthRootLayout( @@ -19,7 +19,7 @@ Layout NthRootNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, i } int NthRootNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, NthRoot::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, NthRoot::FunctionHelper()->name()); } Expression NthRootNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { @@ -41,8 +41,6 @@ Evaluation NthRootNode::templatedApproximate(Context& context, Preferences::A return result; } -NthRoot::NthRoot() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression NthRoot::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -62,4 +60,6 @@ Expression NthRoot::shallowReduce(Context & context, Preferences::AngleUnit angl return p.shallowReduce(context, angleUnit); } +constexpr Expression::FunctionHelper NthRoot::m_functionHelper = Expression::FunctionHelper("root", 2, &NthRoot::UntypedBuilder); + } diff --git a/poincare/src/nth_root_layout.cpp b/poincare/src/nth_root_layout.cpp index e77b7df35..4e008880e 100644 --- a/poincare/src/nth_root_layout.cpp +++ b/poincare/src/nth_root_layout.cpp @@ -154,11 +154,11 @@ int NthRootLayoutNode::serialize(char * buffer, int bufferSize, Preferences::Pri && (const_cast(this))->indexLayout() && !(const_cast(this))->indexLayout()->isEmpty()) { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, NthRoot::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, NthRoot::FunctionHelper()->name()); } // Case: squareRoot(x) if (!m_hasIndex) { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, SquareRoot::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, SquareRoot::FunctionHelper()->name()); } // Case: root(x,empty) // Write "'SquareRootSymbol'('radicandLayout')". diff --git a/poincare/src/permute_coefficient.cpp b/poincare/src/permute_coefficient.cpp index 29562e65a..f2878de06 100644 --- a/poincare/src/permute_coefficient.cpp +++ b/poincare/src/permute_coefficient.cpp @@ -11,14 +11,14 @@ extern "C" { namespace Poincare { -int PermuteCoefficientNode::numberOfChildren() const { return PermuteCoefficient::NumberOfChildren(); } +int PermuteCoefficientNode::numberOfChildren() const { return PermuteCoefficient::FunctionHelper()->numberOfChildren(); } Layout PermuteCoefficientNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(PermuteCoefficient(this), floatDisplayMode, numberOfSignificantDigits, PermuteCoefficient::Name()); + return LayoutHelper::Prefix(PermuteCoefficient(this), floatDisplayMode, numberOfSignificantDigits, PermuteCoefficient::FunctionHelper()->name()); } int PermuteCoefficientNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, PermuteCoefficient::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, PermuteCoefficient::FunctionHelper()->name()); } Expression PermuteCoefficientNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { @@ -47,8 +47,6 @@ Evaluation PermuteCoefficientNode::templatedApproximate(Context& context, Pre return Complex(std::round(result)); } -PermuteCoefficient::PermuteCoefficient() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression PermuteCoefficient::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -110,4 +108,6 @@ Expression PermuteCoefficient::shallowReduce(Context & context, Preferences::Ang } +constexpr Expression::FunctionHelper PermuteCoefficient::m_functionHelper = Expression::FunctionHelper("permute", 2, &PermuteCoefficient::UntypedBuilder); + } diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index c80a449ac..2a00e5b9a 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -124,7 +124,7 @@ bool PowerNode::childNeedsParenthesis(const TreeNode * child) const { } int PowerNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Infix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Power::Name()); + return SerializationHelper::Infix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "^"); } @@ -415,9 +415,9 @@ Expression Power::shallowReduce(Context & context, Preferences::AngleUnit angleU if (angleUnit == Preferences::AngleUnit::Degree) { m.replaceChildAtIndexInPlace(m.numberOfChildren()-1, Rational(180)); } - Expression cos = Cosine(m); + Expression cos = Cosine::Builder(m); m = m.shallowReduce(context, angleUnit); - Expression sin = Sine(m.clone()); + Expression sin = Sine::Builder(m.clone()); Expression complexPart = Multiplication(sin, i); sin.shallowReduce(context, angleUnit); Expression a = Addition(cos, complexPart); @@ -632,11 +632,11 @@ Expression Power::shallowBeautify(Context & context, Preferences::AngleUnit angl if (childAtIndex(1).type() == ExpressionNode::Type::Rational && childAtIndex(1).convert().signedIntegerNumerator().isOne()) { Integer index = childAtIndex(1).convert().integerDenominator(); if (index.isEqualTo(Integer(2))) { - Expression result = SquareRoot(childAtIndex(0)); + Expression result = SquareRoot::Builder(childAtIndex(0)); replaceWithInPlace(result); return result; } - Expression result = NthRoot(childAtIndex(0), Rational(index)); + Expression result = NthRoot::Builder(childAtIndex(0), Rational(index)); replaceWithInPlace(result); return result; } diff --git a/poincare/src/prediction_interval.cpp b/poincare/src/prediction_interval.cpp index bb9a930aa..eb184bfc8 100644 --- a/poincare/src/prediction_interval.cpp +++ b/poincare/src/prediction_interval.cpp @@ -14,14 +14,14 @@ extern "C" { namespace Poincare { -int PredictionIntervalNode::numberOfChildren() const { return PredictionInterval::NumberOfChildren(); } +int PredictionIntervalNode::numberOfChildren() const { return PredictionInterval::FunctionHelper()->numberOfChildren(); } Layout PredictionIntervalNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(PredictionInterval(this), floatDisplayMode, numberOfSignificantDigits, PredictionInterval::Name()); + return LayoutHelper::Prefix(PredictionInterval(this), floatDisplayMode, numberOfSignificantDigits, PredictionInterval::FunctionHelper()->name()); } int PredictionIntervalNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, PredictionInterval::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, PredictionInterval::FunctionHelper()->name()); } @@ -44,8 +44,6 @@ Evaluation PredictionIntervalNode::templatedApproximate(Context& context, Pre return MatrixComplex(operands, 1, 2); } -PredictionInterval::PredictionInterval() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression PredictionInterval::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -106,4 +104,6 @@ Expression PredictionInterval::shallowReduce(Context & context, Preferences::Ang return matrix; } +constexpr Expression::FunctionHelper PredictionInterval::m_functionHelper = Expression::FunctionHelper("prediction95", 2, &PredictionInterval::UntypedBuilder); + } diff --git a/poincare/src/product.cpp b/poincare/src/product.cpp index b18bdd30a..1449fdc9e 100644 --- a/poincare/src/product.cpp +++ b/poincare/src/product.cpp @@ -16,7 +16,7 @@ Layout ProductNode::createSequenceLayout(Layout argumentLayout, Layout symbolLay } int ProductNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Product::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Product::FunctionHelper()->name()); } template @@ -39,6 +39,6 @@ Evaluation ProductNode::templatedApproximateWithNextTerm(Evaluation a, Eva return MultiplicationNode::computeOnMatrices(m, n); } -Product::Product() : Expression(TreePool::sharedPool()->createTreeNode()) {} +constexpr Expression::FunctionHelper Product::m_functionHelper = Expression::FunctionHelper("product", 4, &Product::UntypedBuilder); } diff --git a/poincare/src/randint.cpp b/poincare/src/randint.cpp index 00ffb0a03..8e5cf2a17 100644 --- a/poincare/src/randint.cpp +++ b/poincare/src/randint.cpp @@ -12,14 +12,14 @@ extern "C" { namespace Poincare { -int RandintNode::numberOfChildren() const { return Randint::NumberOfChildren(); } +int RandintNode::numberOfChildren() const { return Randint::FunctionHelper()->numberOfChildren(); } Layout RandintNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(Randint(this), floatDisplayMode, numberOfSignificantDigits, Randint::Name()); + return LayoutHelper::Prefix(Randint(this), floatDisplayMode, numberOfSignificantDigits, Randint::FunctionHelper()->name()); } int RandintNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Randint::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Randint::FunctionHelper()->name()); } template Evaluation RandintNode::templateApproximate(Context & context, Preferences::AngleUnit angleUnit) const { @@ -35,6 +35,6 @@ template Evaluation RandintNode::templateApproximate(Context & c return Complex(result); } -Randint::Randint() : Expression(TreePool::sharedPool()->createTreeNode()) {} +constexpr Expression::FunctionHelper Randint::m_functionHelper = Expression::FunctionHelper("randint", 2, &Randint::UntypedBuilder); } diff --git a/poincare/src/random.cpp b/poincare/src/random.cpp index 053c92c79..96ba9489f 100644 --- a/poincare/src/random.cpp +++ b/poincare/src/random.cpp @@ -8,26 +8,24 @@ namespace Poincare { -int RandomNode::numberOfChildren() const { return Random::NumberOfChildren(); } +int RandomNode::numberOfChildren() const { return Random::FunctionHelper()->numberOfChildren(); } Expression RandomNode::setSign(Sign s, Context & context, Preferences::AngleUnit angleUnit) { return Random(this).setSign(s, context, angleUnit); } Layout RandomNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(Random(this), floatDisplayMode, numberOfSignificantDigits, Random::Name()); + return LayoutHelper::Prefix(Random(this), floatDisplayMode, numberOfSignificantDigits, Random::FunctionHelper()->name()); } int RandomNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Random::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Random::FunctionHelper()->name()); } template Evaluation RandomNode::templateApproximate() const { return Complex(Random::random()); } -Random::Random() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression Random::setSign(ExpressionNode::Sign s, Context & context, Preferences::AngleUnit angleUnit) { assert(s == ExpressionNode::Sign::Positive); return *this; @@ -52,4 +50,6 @@ template Evaluation RandomNode::templateApproximate() const; template float Random::random(); template double Random::random(); +constexpr Expression::FunctionHelper Random::m_functionHelper = Expression::FunctionHelper("random", 0, &Random::UntypedBuilder); + } diff --git a/poincare/src/real_part.cpp b/poincare/src/real_part.cpp index dad368088..75e922005 100644 --- a/poincare/src/real_part.cpp +++ b/poincare/src/real_part.cpp @@ -7,22 +7,20 @@ namespace Poincare { -int RealPartNode::numberOfChildren() const { return RealPart::NumberOfChildren(); } +int RealPartNode::numberOfChildren() const { return RealPart::FunctionHelper()->numberOfChildren(); } Layout RealPartNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(RealPart(this), floatDisplayMode, numberOfSignificantDigits, RealPart::Name()); + return LayoutHelper::Prefix(RealPart(this), floatDisplayMode, numberOfSignificantDigits, RealPart::FunctionHelper()->name()); } int RealPartNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, RealPart::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, RealPart::FunctionHelper()->name()); } Expression RealPartNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { return RealPart(this).shallowReduce(context, angleUnit, replaceSymbols); } -RealPart::RealPart() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression RealPart::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -43,4 +41,6 @@ Expression RealPart::shallowReduce(Context & context, Preferences::AngleUnit ang return *this; } +constexpr Expression::FunctionHelper RealPart::m_functionHelper = Expression::FunctionHelper("re", 1, &RealPart::UntypedBuilder); + } diff --git a/poincare/src/round.cpp b/poincare/src/round.cpp index ae1901ec6..20a63f538 100644 --- a/poincare/src/round.cpp +++ b/poincare/src/round.cpp @@ -9,14 +9,14 @@ namespace Poincare { -int RoundNode::numberOfChildren() const { return Round::NumberOfChildren(); } +int RoundNode::numberOfChildren() const { return Round::FunctionHelper()->numberOfChildren(); } Layout RoundNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(Round(this), floatDisplayMode, numberOfSignificantDigits, Round::Name()); + return LayoutHelper::Prefix(Round(this), floatDisplayMode, numberOfSignificantDigits, Round::FunctionHelper()->name()); } int RoundNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Round::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Round::FunctionHelper()->name()); } Expression RoundNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { @@ -36,8 +36,6 @@ Evaluation RoundNode::templatedApproximate(Context& context, Preferences::Ang return Complex(std::round(f1*err)/err); } -Round::Round() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression Round::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -82,6 +80,6 @@ Expression Round::shallowReduce(Context & context, Preferences::AngleUnit angleU return *this; } +constexpr Expression::FunctionHelper Round::m_functionHelper = Expression::FunctionHelper("round", 2, &Round::UntypedBuilder); + } - - diff --git a/poincare/src/sine.cpp b/poincare/src/sine.cpp index 0c689c49a..a880ee4ad 100644 --- a/poincare/src/sine.cpp +++ b/poincare/src/sine.cpp @@ -7,7 +7,7 @@ namespace Poincare { -int SineNode::numberOfChildren() const { return Sine::NumberOfChildren(); } +int SineNode::numberOfChildren() const { return Sine::FunctionHelper()->numberOfChildren(); } float SineNode::characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const { return Trigonometry::characteristicXRange(Sine(this), context, angleUnit); @@ -21,19 +21,17 @@ Complex SineNode::computeOnComplex(const std::complex c, Preferences::Angl } Layout SineNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(Sine(this), floatDisplayMode, numberOfSignificantDigits, Sine::Name()); + return LayoutHelper::Prefix(Sine(this), floatDisplayMode, numberOfSignificantDigits, Sine::FunctionHelper()->name()); } int SineNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Sine::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Sine::FunctionHelper()->name()); } Expression SineNode::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { return Sine(this).shallowReduce(context, angleUnit, replaceSymbols); } -Sine::Sine() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression Sine::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -50,4 +48,6 @@ Expression Sine::shallowReduce(Context & context, Preferences::AngleUnit angleUn return Trigonometry::shallowReduceDirectFunction(*this, context, angleUnit); } +constexpr Expression::FunctionHelper Sine::m_functionHelper = Expression::FunctionHelper("sin", 1, &Sine::UntypedBuilder); + } diff --git a/poincare/src/square_root.cpp b/poincare/src/square_root.cpp index b8cba4325..9603f506b 100644 --- a/poincare/src/square_root.cpp +++ b/poincare/src/square_root.cpp @@ -10,14 +10,14 @@ namespace Poincare { -int SquareRootNode::numberOfChildren() const { return SquareRoot::NumberOfChildren(); } +int SquareRootNode::numberOfChildren() const { return SquareRoot::FunctionHelper()->numberOfChildren(); } Layout SquareRootNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { return NthRootLayout(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits)); } int SquareRootNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, SquareRoot::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, SquareRoot::FunctionHelper()->name()); } template @@ -36,8 +36,6 @@ Expression SquareRootNode::shallowReduce(Context & context, Preferences::AngleUn return SquareRoot(this).shallowReduce(context, angleUnit, replaceSymbols); } -SquareRoot::SquareRoot() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression SquareRoot::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -55,4 +53,6 @@ Expression SquareRoot::shallowReduce(Context & context, Preferences::AngleUnit a return p.shallowReduce(context, angleUnit); } +constexpr char SquareRoot::k_name[2] = {Ion::Charset::Root, 0}; +constexpr Expression::FunctionHelper SquareRoot::m_functionHelper = Expression::FunctionHelper(SquareRoot::k_name, 1, &SquareRoot::UntypedBuilder); } diff --git a/poincare/src/subtraction.cpp b/poincare/src/subtraction.cpp index aebed1741..0078caf44 100644 --- a/poincare/src/subtraction.cpp +++ b/poincare/src/subtraction.cpp @@ -32,11 +32,11 @@ bool SubtractionNode::childNeedsParenthesis(const TreeNode * child) const { } Layout SubtractionNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Infix(Subtraction(this), floatDisplayMode, numberOfSignificantDigits, Subtraction::Name()); + return LayoutHelper::Infix(Subtraction(this), floatDisplayMode, numberOfSignificantDigits, "-"); } int SubtractionNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Infix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Subtraction::Name()); + return SerializationHelper::Infix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, "-"); } template MatrixComplex SubtractionNode::computeOnComplexAndMatrix(const std::complex c, const MatrixComplex m) { diff --git a/poincare/src/sum.cpp b/poincare/src/sum.cpp index e2aad351a..0e72161d0 100644 --- a/poincare/src/sum.cpp +++ b/poincare/src/sum.cpp @@ -16,7 +16,7 @@ Layout SumNode::createSequenceLayout(Layout argumentLayout, Layout symbolLayout, } int SumNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Sum::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Sum::FunctionHelper()->name()); } template @@ -39,6 +39,6 @@ Evaluation SumNode::templatedApproximateWithNextTerm(Evaluation a, Evaluat return AdditionNode::computeOnMatrices(m, n); } -Sum::Sum() : Expression(TreePool::sharedPool()->createTreeNode()) {} +constexpr Expression::FunctionHelper Sum::m_functionHelper = Expression::FunctionHelper("sum", 4, &Sum::UntypedBuilder); } diff --git a/poincare/src/tangent.cpp b/poincare/src/tangent.cpp index f9b13001a..dca43e158 100644 --- a/poincare/src/tangent.cpp +++ b/poincare/src/tangent.cpp @@ -10,18 +10,18 @@ namespace Poincare { -int TangentNode::numberOfChildren() const { return Tangent::NumberOfChildren(); } +int TangentNode::numberOfChildren() const { return Tangent::FunctionHelper()->numberOfChildren(); } float TangentNode::characteristicXRange(Context & context, Preferences::AngleUnit angleUnit) const { return Trigonometry::characteristicXRange(Tangent(this), context, angleUnit); } Layout TangentNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return LayoutHelper::Prefix(Tangent(this), floatDisplayMode, numberOfSignificantDigits, Tangent::Name()); + return LayoutHelper::Prefix(Tangent(this), floatDisplayMode, numberOfSignificantDigits, Tangent::FunctionHelper()->name()); } int TangentNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Tangent::Name()); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, Tangent::FunctionHelper()->name()); } template @@ -35,8 +35,6 @@ Expression TangentNode::shallowReduce(Context & context, Preferences::AngleUnit return Tangent(this).shallowReduce(context, angleUnit, replaceSymbols); } -Tangent::Tangent() : Expression(TreePool::sharedPool()->createTreeNode()) {} - Expression Tangent::shallowReduce(Context & context, Preferences::AngleUnit angleUnit, bool replaceSymbols) { { Expression e = Expression::defaultShallowReduce(context, angleUnit); @@ -52,8 +50,8 @@ Expression Tangent::shallowReduce(Context & context, Preferences::AngleUnit angl #endif Expression newExpression = Trigonometry::shallowReduceDirectFunction(*this, context, angleUnit); if (newExpression.type() == ExpressionNode::Type::Tangent) { - Sine s = Sine(newExpression.childAtIndex(0).clone()); - Cosine c = Cosine(newExpression.childAtIndex(0)); + Sine s = Sine::Builder(newExpression.childAtIndex(0).clone()); + Cosine c = Cosine::Builder(newExpression.childAtIndex(0)); Division d = Division(s, c); newExpression.replaceWithInPlace(d); return d.shallowReduce(context, angleUnit); @@ -61,4 +59,6 @@ Expression Tangent::shallowReduce(Context & context, Preferences::AngleUnit angl return newExpression; } +constexpr Expression::FunctionHelper Tangent::m_functionHelper = Expression::FunctionHelper("tan", 1, &Tangent::UntypedBuilder); + } diff --git a/poincare/src/trigonometry.cpp b/poincare/src/trigonometry.cpp index 989365833..00ae1c984 100644 --- a/poincare/src/trigonometry.cpp +++ b/poincare/src/trigonometry.cpp @@ -32,7 +32,7 @@ float Trigonometry::characteristicXRange(const Expression & e, Context & context assert(d == 1); /* To compute a, the slope of the expression child(0), we compute the * derivative of child(0) for any x value. */ - Poincare::Derivative derivative(e.childAtIndex(0).clone(), Symbol(x, 1), Float(1.0f)); + Poincare::Derivative derivative = Poincare::Derivative::Builder(e.childAtIndex(0).clone(), Symbol(x, 1), Float(1.0f)); float a = derivative.approximateToScalar(context, angleUnit); float pi = angleUnit == Preferences::AngleUnit::Radian ? M_PI : 180.0f; return 2.0f*pi/std::fabs(a);