[poincare] Move UndefinedReference to Undefined

This commit is contained in:
Romain Goyet
2018-08-07 17:20:57 +02:00
parent 9cb00aa279
commit c29afba2bd
10 changed files with 65 additions and 48 deletions

View File

@@ -111,8 +111,9 @@ public:
double nextRoot(char symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit) const;
Coordinate2D nextIntersection(char symbol, double start, double step, double max, Context & context, Preferences::AngleUnit angleUnit, const Expression expression) const;
private:
protected:
Expression(ExpressionNode * n) : SerializableReference(n), TreeByValue(n) {}
private:
/* Hierarchy */
Expression childAtIndex(int i) const {
return Expression(static_cast<ExpressionNode *>(TreeByReference::treeChildAtIndex(i).node()));

View File

@@ -88,8 +88,8 @@ public:
};
/* Allocation failure */
static TreeNode * FailedAllocationStaticNode();
TreeNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); }
static ExpressionNode * FailedAllocationStaticNode();
ExpressionNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); }
/* Poor man's RTTI */
virtual Type type() const = 0;

View File

@@ -13,6 +13,12 @@ namespace Poincare {
class HorizontalLayoutNode : public LayoutNode {
friend class LayoutReference;
public:
static HorizontalLayoutNode * FailedAllocationStaticNode() {
// TODO: Check this is OK
return static_cast<HorizontalLayoutNode *>(LayoutNode::FailedAllocationStaticNode());
}
HorizontalLayoutNode() :
LayoutNode(),
m_numberOfChildren(0)
@@ -62,26 +68,26 @@ class HorizontalLayoutRef : public LayoutReference {
friend class HorizontalLayoutNode;
public:
HorizontalLayoutRef(HorizontalLayoutNode * n) : LayoutReference(n) {}
HorizontalLayoutRef() : LayoutReference(TreePool::sharedPool()->createTreeNode<HorizontalLayoutNode>(), true) {}
HorizontalLayoutRef() : LayoutReference(TreePool::sharedPool()->createTreeNode<HorizontalLayoutNode>()) {}
HorizontalLayoutRef(LayoutRef l) : HorizontalLayoutRef() {
addChildTreeAtIndex(l, 0, 0);
addChildAtIndexInPlace(l, 0, 0);
}
HorizontalLayoutRef(LayoutRef l1, LayoutRef l2) : HorizontalLayoutRef() {
addChildTreeAtIndex(l1, 0, 0);
addChildTreeAtIndex(l2, 1, 1);
addChildAtIndexInPlace(l1, 0, 0);
addChildAtIndexInPlace(l2, 1, 1);
}
HorizontalLayoutRef(LayoutRef l1, LayoutRef l2, LayoutRef l3) : HorizontalLayoutRef() {
addChildTreeAtIndex(l1, 0, 0);
addChildTreeAtIndex(l2, 1, 1);
addChildTreeAtIndex(l3, 2, 2);
addChildAtIndexInPlace(l1, 0, 0);
addChildAtIndexInPlace(l2, 1, 1);
addChildAtIndexInPlace(l3, 2, 2);
}
HorizontalLayoutRef(LayoutRef l1, LayoutRef l2, LayoutRef l3, LayoutRef l4) : HorizontalLayoutRef() {
addChildTreeAtIndex(l1, 0, 0);
addChildTreeAtIndex(l2, 1, 1);
addChildTreeAtIndex(l3, 2, 2);
addChildTreeAtIndex(l4, 3, 3);
addChildAtIndexInPlace(l1, 0, 0);
addChildAtIndexInPlace(l2, 1, 1);
addChildAtIndexInPlace(l3, 2, 2);
addChildAtIndexInPlace(l4, 3, 3);
}
void addChildAtIndex(LayoutReference l, int index, int currentNumberOfChildren, LayoutCursor * cursor) override {
LayoutReference::addChildAtIndex(l, index, currentNumberOfChildren, cursor);

View File

@@ -1,19 +1,18 @@
#ifndef POINCARE_LAYOUT_ENGINE_H
#define POINCARE_LAYOUT_ENGINE_H
#include <poincare/expression_reference.h>
#include <poincare/expression.h>
#include <poincare/layout_reference.h>
#include <poincare/horizontal_layout_node.h>
namespace Poincare {
class HorizontalLayoutRef;
class LayoutEngine {
public:
/* Expression to Layout */
static LayoutRef createInfixLayout(const ExpressionReference expression, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits, const char * operatorName);
static LayoutRef createPrefixLayout(const ExpressionReference expression, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits, const char * operatorName);
static LayoutRef createInfixLayout(const Expression expression, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits, const char * operatorName);
static LayoutRef createPrefixLayout(const Expression expression, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits, const char * operatorName);
/* Create special layouts */
static LayoutRef createParenthesedLayout(LayoutRef layout, bool cloneLayout);
@@ -22,7 +21,7 @@ public:
/* SerializableReference to Text */
static int writeInfixSerializableRefTextInBuffer(
const SerializableRef serializableRef,
const SerializableReference serializableRef,
char * buffer,
int bufferSize,
Preferences::PrintFloatMode floatDisplayMode,
@@ -32,7 +31,7 @@ public:
int lastChildIndex = -1);
static int writePrefixSerializableRefTextInBuffer(
const SerializableRef serializableRef,
const SerializableReference serializableRef,
char * buffer,
int bufferSize,
Preferences::PrintFloatMode floatDisplayMode,
@@ -44,7 +43,7 @@ public:
static int writeOneCharInBuffer(char * buffer, int bufferSize, char charToWrite);
private:
static void writeChildTreeInBuffer(SerializableRef childRef, SerializableRef parentRef, char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfDigits, int * numberOfChar);
static void writeChildTreeInBuffer(SerializableReference childRef, SerializableReference parentRef, char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfDigits, int * numberOfChar);
};
}

View File

@@ -102,15 +102,12 @@ public:
protected:
/* Constructor */
TreeByReference(const TreeNode * node, bool isCreatingNode = false) {
TreeByReference(const TreeNode * node) {
if (node == nullptr) {
m_identifier = TreePool::NoNodeIdentifier;
return;
}
setIdentifierAndRetain(node->identifier());
if (isCreatingNode) {
buildGhostChildren();
}
}
TreeByReference() : m_identifier(-1) {}
/* Hierarchy operations */

View File

@@ -24,7 +24,7 @@ public:
TreeNode * last() const { return reinterpret_cast<TreeNode *>(const_cast<char *>(m_cursor)); }
template <typename T>
TreeNode * createTreeNode(size_t size = sizeof(T)) {
T * createTreeNode(size_t size = sizeof(T)) {
int nodeIdentifier = generateIdentifier();
if (nodeIdentifier == -1) {
T::FailedAllocationStaticNode()->retain();
@@ -37,6 +37,29 @@ public:
}
T * node = new(ptr) T();
node->rename(nodeIdentifier, false);
// Ensure the pool is syntactially correct by creating ghost children if needed.
// It's needed for children that have a fixed, non-zero number of children.
for (int i=0; i<node->numberOfChildren(); i++) {
assert(false);
// TODO! :-D
#if 0
// It used to be this:
void TreeByReference::buildGhostChildren() {
assert(isDefined());
for (int i = 0; i < numberOfChildren(); i++) {
// Add a ghost child
GhostReference ghost;
if (ghost.isAllocationFailure()) {
replaceWithAllocationFailureInPlace(numberOfChildren());
return;
}
TreePool::sharedPool()->move(node()->next(), ghost.node(), 0);
}
}
#endif
}
return node;
}

View File

@@ -7,6 +7,10 @@ namespace Poincare {
class UndefinedNode : public NumberNode {
public:
static UndefinedNode * FailedAllocationStaticNode() {
return static_cast<UndefinedNode *>(ExpressionNode::FailedAllocationStaticNode());
}
// TreeNode
size_t size() const override { return sizeof(UndefinedNode); }
#if TREE_LOG
@@ -18,10 +22,10 @@ public:
int polynomialDegree(char symbolName) const override;
// Approximation
EvaluationReference<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
Evaluation<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
return templatedApproximate<float>();
}
EvaluationReference<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
Evaluation<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
return templatedApproximate<double>();
}
@@ -29,12 +33,12 @@ public:
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
int writeTextInBuffer(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode = Preferences::PrintFloatMode::Decimal, int numberOfSignificantDigits = 0) const override;
private:
template<typename T> EvaluationReference<T> templatedApproximate() const;
template<typename T> Evaluation<T> templatedApproximate() const;
};
class UndefinedReference : public NumberReference {
class Undefined : public Number {
public:
UndefinedReference() : NumberReference(TreePool::sharedPool()->createTreeNode<UndefinedNode>(), true) {}
Undefined() : Number(TreePool::sharedPool()->createTreeNode<UndefinedNode>()) {}
};
}

View File

@@ -4,7 +4,7 @@
namespace Poincare {
TreeNode * ExpressionNode::FailedAllocationStaticNode() {
ExpressionNode * ExpressionNode::FailedAllocationStaticNode() {
static AllocationFailedExpressionNode FailureNode;
TreePool::sharedPool()->registerStaticNodeIfRequired(&FailureNode);
return &FailureNode;

View File

@@ -225,17 +225,4 @@ void TreeByReference::setTo(const TreeByReference & tr) {
}
}
void TreeByReference::buildGhostChildren() {
assert(isDefined());
for (int i = 0; i < numberOfChildren(); i++) {
// Add a ghost child
GhostReference ghost;
if (ghost.isAllocationFailure()) {
replaceWithAllocationFailureInPlace(numberOfChildren());
return;
}
TreePool::sharedPool()->move(node()->next(), ghost.node(), 0);
}
}
}

View File

@@ -26,8 +26,8 @@ int UndefinedNode::writeTextInBuffer(char * buffer, int bufferSize, Preferences:
return PrintFloat::convertFloatToText<float>(NAN, buffer, bufferSize, numberOfSignificantDigits, floatDisplayMode);
}
template<typename T> EvaluationReference<T> UndefinedNode::templatedApproximate() const {
return ComplexReference<T>::Undefined();
template<typename T> Evaluation<T> UndefinedNode::templatedApproximate() const {
return Complex<T>::Undefined();
}
}