diff --git a/poincare/Makefile b/poincare/Makefile index 2d7202235..af90ddb10 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -32,6 +32,7 @@ objs += $(addprefix poincare/src/simplify/,\ simplify_addition_integer.o\ simplify_commutative_merge.o\ simplify_product_zero.o\ + expression_selector.o\ ) tests += $(addprefix poincare/test/,\ addition.cpp\ diff --git a/poincare/src/simplify/expression_selector.cpp b/poincare/src/simplify/expression_selector.cpp new file mode 100644 index 000000000..8198beabe --- /dev/null +++ b/poincare/src/simplify/expression_selector.cpp @@ -0,0 +1,67 @@ +#include "expression_selector.h" +extern "C" { +#include +} + +int ExpressionSelector::match(Expression * e, Expression ** matches) { + int numberOfMatches = 0; + + // Does the current node match? + switch(m_match) { + case ExpressionSelector::Match::Any: + // Yes, it always does! + break; + case ExpressionSelector::Match::TypeAndValue: + if (e->type() != m_expressionType) { + return 0; + } + /* + switch (e->type()) { + case Expression::Type::Integer: + // Test e->equals(Integer(m_integerValue)); + // Maybe return 0 + break; + case Expression::Type::Symbol: + // Test symbol is same name + // Maybe return 0 + break; + default: + // By default we don't check a value equality + } + */ + break; + } + + // The current node does match. Let's add it to our matches + matches[numberOfMatches++] = e; + + // FIXME: For now we'll ignore the commutativity of the Selector + // which is definitely something *very* important + // Checking if "e" is commutative seems like a nice solution + + for (int i=0; ichild(i); + // To account for commutativity, we should have multiple possibilities for childExpression + Expression * childExpression = e->operand(i); + int numberOfChildMatches = childSelector->match(childExpression, &matches[numberOfMatches]); + if (numberOfChildMatches == 0) { + return 0; + } else { + numberOfMatches += numberOfChildMatches; + } + } + + return numberOfMatches; +} + +// Extrude in a class impossible otherwise ExpressionBuilder is not aggregate +// and cannot be initialized statically +ExpressionSelector * ExpressionSelector::child(int index) { + assert(index>=0 && indexchild(index-1); + return previousChild+previousChild->m_numberOfChildren; // Pointer arithm. + } +} diff --git a/poincare/src/simplify/expression_selector.h b/poincare/src/simplify/expression_selector.h new file mode 100644 index 000000000..8b3c055db --- /dev/null +++ b/poincare/src/simplify/expression_selector.h @@ -0,0 +1,53 @@ +#ifndef POINCARE_SIMPLIFY_EXPRESSION_SELECTOR_H +#define POINCARE_SIMPLIFY_EXPRESSION_SELECTOR_H + +#include +extern "C" { +#include +} + +class ExpressionSelector { + /* Everything must be made public otherwise we cannot static-initialize an + * array of ExpressionSelectors. */ +public: + enum class Match { + Any, + TypeAndValue + }; + ExpressionSelector * child(int i); + /* The match function is interesting + * - It returns 0 if the selector didn't match the expression + * - Otherwise, it returns the number of captured matches and sets *matches + * Caution: This function *will* write to *matches even if the returned + * value is zero. + */ + int match(Expression * e, Expression ** matches); // Return the matched expressions + /*Expression ** match(Expression * e);*/ + Match m_match; + union { + // m_match == Any + // nothing! + // m_match == ExpressionType + struct { + Expression::Type m_expressionType; + union { + // m_expressionType == Integer + int32_t m_integerValue; + // m_expressionType == Symbol + char const * m_symbolName; + }; + }; + }; + uint8_t m_numberOfChildren; +}; + +/* +{ + my_tree_selector, my_expression_builder; + if (my_tree_selector->match(my_expression)) { + my_expression_builder->build(my_expression, *matchedData); + } +} +*/ + +#endif