mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-19 05:40:38 +01:00
Poincare: ExpressionBuilder and ExpressionSelector are not PODs anymore
This means we cannot initialize them by using C99-style static init. C++11 to the rescue: we're using constexpr constructor to build them statically, without any runtime cost. This allows us to have private member variables, and a base class. Change-Id: I0617d196e87f946b48375f42b600eb73e366d87d
This commit is contained in:
@@ -16,7 +16,7 @@ Expression * ExpressionBuilder::build(ExpressionMatch matches[]) {
|
||||
int numberOfChildrenExpressions = 0;
|
||||
|
||||
for (int i=0; i<m_numberOfChildren; i++) {
|
||||
ExpressionBuilder * child = this->child(i);
|
||||
ExpressionBuilder * child = (ExpressionBuilder *)this->child(i);
|
||||
if (child->m_action == ExpressionBuilder::Action::BringUpWildcard) {
|
||||
for (int j=0; j<matches[child->m_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 && index<m_numberOfChildren);
|
||||
if (index == 0) {
|
||||
return (this+1); // Pointer arithmetics
|
||||
} else {
|
||||
ExpressionBuilder * previousChild = this->child(index-1);
|
||||
return previousChild+previousChild->m_numberOfChildren+1; // Pointer arithm.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,25 @@
|
||||
#define POINCARE_SIMPLIFY_EXPRESSION_BUILDER_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include "contiguous_tree.h"
|
||||
#include "expression_match.h"
|
||||
extern "C" {
|
||||
#include <stdint.h>
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -2,21 +2,27 @@
|
||||
#define POINCARE_SIMPLIFY_EXPRESSION_SELECTOR_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include "contiguous_tree.h"
|
||||
#include "expression_match.h"
|
||||
extern "C" {
|
||||
#include <stdint.h>
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user