diff --git a/poincare/src/simplify/expression_builder.cpp b/poincare/src/simplify/expression_builder.cpp index ebe0161c4..e8ebb4359 100644 --- a/poincare/src/simplify/expression_builder.cpp +++ b/poincare/src/simplify/expression_builder.cpp @@ -16,7 +16,7 @@ Expression * ExpressionBuilder::build(ExpressionMatch matches[]) { int numberOfChildrenExpressions = 0; for (int i=0; ichild(i); + ExpressionBuilder * child = (ExpressionBuilder *)this->child(i); if (child->m_action == ExpressionBuilder::Action::BringUpWildcard) { for (int j=0; jm_matchIndex].numberOfExpressions(); j++) { children_expressions[numberOfChildrenExpressions++] = @@ -62,14 +62,3 @@ Expression * ExpressionBuilder::build(ExpressionMatch matches[]) { } return result; } - -// Extrude in a class -ExpressionBuilder * ExpressionBuilder::child(int index) { - assert(index>=0 && indexchild(index-1); - return previousChild+previousChild->m_numberOfChildren+1; // Pointer arithm. - } -} diff --git a/poincare/src/simplify/expression_builder.h b/poincare/src/simplify/expression_builder.h index 77b18ef6e..bb42b92b7 100644 --- a/poincare/src/simplify/expression_builder.h +++ b/poincare/src/simplify/expression_builder.h @@ -2,18 +2,25 @@ #define POINCARE_SIMPLIFY_EXPRESSION_BUILDER_H #include +#include "contiguous_tree.h" #include "expression_match.h" extern "C" { #include } -class ExpressionBuilder { - typedef Expression * (ExternalGenerator)(Expression ** parameters, int numberOfParameters); +class ExpressionBuilder : public ContiguousTree { +public: + static constexpr ExpressionBuilder BuildFromType(Expression::Type type, uint8_t numberOfChildren); + static constexpr ExpressionBuilder BuildFromTypeAndValue(Expression::Type type, int32_t value, uint8_t numberOfChildren); + static constexpr ExpressionBuilder Clone(uint8_t matchIndex, uint8_t numberOfChildren); + static constexpr ExpressionBuilder BringUpWildcard(uint8_t matchIndex, uint8_t numberOfChildren); + typedef Expression * (ExternalGenerator)(Expression ** parameters, int numberOfParameters); + static constexpr ExpressionBuilder CallExternalGenerator(ExternalGenerator * generator, uint8_t numberOfChildren); public: - ExpressionBuilder * child(int i); Expression * build(ExpressionMatch matches[]); +private: enum class Action { BuildFromTypeAndValue, Clone, @@ -21,6 +28,10 @@ public: CallExternalGenerator }; + constexpr ExpressionBuilder(Expression::Type type, int32_t integerValue, uint8_t numberOfChildren); + constexpr ExpressionBuilder(Action action, uint8_t matchIndex, uint8_t numberOfChildren); + constexpr ExpressionBuilder(ExternalGenerator * generator, uint8_t numberOfChildren); + Action m_action; union { @@ -39,8 +50,67 @@ public: // m_action == CallExternalGenerator ExternalGenerator * m_generator; }; - - uint8_t m_numberOfChildren; }; +/* Since they have to be evaluated at compile time, constexpr functions are + * implicitely defined inline. Therefore we have to provide their implementation + * in this header. */ + +constexpr ExpressionBuilder ExpressionBuilder::BuildFromType( + Expression::Type type, + uint8_t numberOfChildren) { + return ExpressionBuilder(type, 0, numberOfChildren); +} +constexpr ExpressionBuilder ExpressionBuilder::BuildFromTypeAndValue( + Expression::Type type, + int32_t value, + uint8_t numberOfChildren) { + return ExpressionBuilder(type, value, numberOfChildren); +} + +constexpr ExpressionBuilder ExpressionBuilder::Clone( + uint8_t matchIndex, + uint8_t numberOfChildren) { + return ExpressionBuilder(ExpressionBuilder::Action::Clone, matchIndex, numberOfChildren); +} + +constexpr ExpressionBuilder ExpressionBuilder::BringUpWildcard( + uint8_t matchIndex, + uint8_t numberOfChildren) { + return ExpressionBuilder(ExpressionBuilder::Action::BringUpWildcard, matchIndex, numberOfChildren); +} + +constexpr ExpressionBuilder ExpressionBuilder::CallExternalGenerator( + ExternalGenerator * generator, + uint8_t numberOfChildren) { + return ExpressionBuilder(generator, numberOfChildren); +} + +constexpr ExpressionBuilder::ExpressionBuilder(Expression::Type type, + int32_t integerValue, + uint8_t numberOfChildren) + : + ContiguousTree(numberOfChildren), + m_action(ExpressionBuilder::Action::BuildFromTypeAndValue), + m_expressionType(type), + m_integerValue(integerValue) { +} + +constexpr ExpressionBuilder::ExpressionBuilder(Action action, + uint8_t matchIndex, + uint8_t numberOfChildren) + : + ContiguousTree(numberOfChildren), + m_action(action), + m_matchIndex(matchIndex) { +} + +constexpr ExpressionBuilder::ExpressionBuilder(ExternalGenerator * generator, + uint8_t numberOfChildren) + : + ContiguousTree(numberOfChildren), + m_action(ExpressionBuilder::Action::CallExternalGenerator), + m_generator(generator) { +} + #endif diff --git a/poincare/src/simplify/expression_selector.h b/poincare/src/simplify/expression_selector.h index 63bfaf38b..bf30f13cd 100644 --- a/poincare/src/simplify/expression_selector.h +++ b/poincare/src/simplify/expression_selector.h @@ -2,21 +2,27 @@ #define POINCARE_SIMPLIFY_EXPRESSION_SELECTOR_H #include +#include "contiguous_tree.h" #include "expression_match.h" extern "C" { #include } -class ExpressionSelector { - /* Everything must be made public otherwise we cannot static-initialize an - * array of ExpressionSelectors. */ +class ExpressionSelector : public ContiguousTree { public: - enum class Match { - Any, - Type, - Wildcard, - TypeAndValue, - }; + static constexpr ExpressionSelector Any(uint8_t numberOfChildren) { + return ExpressionSelector(Match::Any, (Expression::Type)0, 0, numberOfChildren); + } + static constexpr ExpressionSelector Wildcard(uint8_t numberOfChildren) { + return ExpressionSelector(Match::Wildcard, (Expression::Type)0, 0, numberOfChildren); + } + static constexpr ExpressionSelector Type(Expression::Type type, uint8_t numberOfChildren) { + return ExpressionSelector(Match::Type, type, 0, numberOfChildren); + } + static constexpr ExpressionSelector TypeAndValue(Expression::Type type, int32_t value, uint8_t numberOfChildren) { + return ExpressionSelector(Match::TypeAndValue, type, value, numberOfChildren); + } + ExpressionSelector * child(int i); /* The match function is interesting * - It returns 0 if the selector didn't match the expression @@ -25,6 +31,25 @@ public: * value is zero. */ int match(Expression * e, ExpressionMatch * matches); +private: + enum class Match { + Any, + Type, + Wildcard, + TypeAndValue, + }; + + constexpr ExpressionSelector(Match match, + Expression::Type type, + int32_t integerValue, + uint8_t numberOfChildren) + : + ContiguousTree(numberOfChildren), + m_match(match), + m_expressionType(type), + m_integerValue(integerValue) + { + } Match m_match; union { @@ -41,7 +66,6 @@ public: }; }; }; - uint8_t m_numberOfChildren; }; #endif