Poincare: Add an ExpressionBuilder class

Change-Id: I5865b712cfe1f8e1cd2e29d0d2b50be8182985b8
This commit is contained in:
Romain Goyet
2016-03-26 18:47:08 +01:00
parent f81239fdb8
commit e8b7a9bd83
3 changed files with 105 additions and 0 deletions

View File

@@ -33,6 +33,7 @@ objs += $(addprefix poincare/src/simplify/,\
simplify_commutative_merge.o\
simplify_product_zero.o\
expression_selector.o\
expression_builder.o\
)
tests += $(addprefix poincare/test/,\
addition.cpp\

View File

@@ -0,0 +1,60 @@
#include "expression_builder.h"
#include <poincare/addition.h>
#include <poincare/integer.h>
extern "C" {
#include <assert.h>
}
/* Our compiler defines two things:
* - First, a list of ExpressionBuilder
* - Second, a children_expression_buffer[] of the proper size.
*/
Expression * children_expression_buffer[4]; // This will be defined by our compiler
Expression * ExpressionBuilder::build(Expression * matches[]) {
Expression * children_expressions[255]; // FIXME: <- The sized can be given by the compiler
//Expression * children_expressions = malloc;
// That malloc can be avoided: we can give an upper bound
// Afer we've finished processing the rules
// That upper bound is likely to be very small (3, currently)
for (int i=0; i<m_numberOfChildren; i++) {
ExpressionBuilder * child = this->child(i);
children_expressions[i] = child->build(matches);
}
Expression * result = nullptr;
switch(m_action) {
case ExpressionBuilder::Action::Build:
switch(m_expressionType) {
case Expression::Type::Addition:
result = new Addition(children_expressions, m_numberOfChildren, true);
break;
case Expression::Type::Integer:
result = new Integer(m_integerValue);
break;
default:
assert(false);
break;
}
break;
case ExpressionBuilder::Action::Clone:
result = matches[m_matchIndex]->clone();
break;
case ExpressionBuilder::Action::FunctionCall:
// result = m_functionPointer(children_expressions);
break;
}
return result;
}
// Extrude in a class
ExpressionBuilder * ExpressionBuilder::child(int index) {
assert(index>=0 && index<m_numberOfChildren);
if (index == 0) {
return (this+1); // Pointer arithmetics
} else {
ExpressionBuilder * previousChild = this->child(index-1);
return previousChild+previousChild->m_numberOfChildren; // Pointer arithm.
}
}

View File

@@ -0,0 +1,44 @@
#ifndef POINCARE_SIMPLIFY_EXPRESSION_BUILDER_H
#define POINCARE_SIMPLIFY_EXPRESSION_BUILDER_H
#include <poincare/expression.h>
extern "C" {
#include <stdint.h>
}
class ExpressionBuilder {
public:
ExpressionBuilder * child(int i);
Expression * build(Expression * matches[]);
/*Expression ** match(Expression * e);*/
enum class Action {
Build,
Clone,
FunctionCall
};
Action m_action;
union {
// m_action == Build
struct {
Expression::Type m_expressionType;
union {
// m_expressionType == Integer
int32_t m_integerValue;
// m_expressionType == Symbol
char const * m_symbolName;
};
};
// m_action == Clone
uint8_t m_matchIndex;
// m_action == FunctionCall
void * m_functionPointer;
};
uint8_t m_numberOfChildren;
};
#endif