mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-19 05:40:38 +01:00
Poincare: Add an ExpressionSelector
Change-Id: I1ed0e2f3042f948d81d79b7b8ada00a3e838322b
This commit is contained in:
@@ -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\
|
||||
|
||||
67
poincare/src/simplify/expression_selector.cpp
Normal file
67
poincare/src/simplify/expression_selector.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "expression_selector.h"
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
}
|
||||
|
||||
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; i<m_numberOfChildren; i++) {
|
||||
ExpressionSelector * childSelector = this->child(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 && index<m_numberOfChildren);
|
||||
if (index == 0) {
|
||||
return (this+1); // Pointer arithmetics
|
||||
} else {
|
||||
ExpressionSelector * previousChild = this->child(index-1);
|
||||
return previousChild+previousChild->m_numberOfChildren; // Pointer arithm.
|
||||
}
|
||||
}
|
||||
53
poincare/src/simplify/expression_selector.h
Normal file
53
poincare/src/simplify/expression_selector.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef POINCARE_SIMPLIFY_EXPRESSION_SELECTOR_H
|
||||
#define POINCARE_SIMPLIFY_EXPRESSION_SELECTOR_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
extern "C" {
|
||||
#include <stdint.h>
|
||||
}
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user