diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 026c19b36..0c946ee19 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -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(TreeByReference::treeChildAtIndex(i).node())); diff --git a/poincare/include/poincare/expression_node.h b/poincare/include/poincare/expression_node.h index b3910f339..b326de5b7 100644 --- a/poincare/include/poincare/expression_node.h +++ b/poincare/include/poincare/expression_node.h @@ -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; diff --git a/poincare/include/poincare/horizontal_layout_node.h b/poincare/include/poincare/horizontal_layout_node.h index bab78d033..68d568874 100644 --- a/poincare/include/poincare/horizontal_layout_node.h +++ b/poincare/include/poincare/horizontal_layout_node.h @@ -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(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(), true) {} + HorizontalLayoutRef() : LayoutReference(TreePool::sharedPool()->createTreeNode()) {} 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); diff --git a/poincare/include/poincare/layout_engine.h b/poincare/include/poincare/layout_engine.h index 382ac1522..e90d585f2 100644 --- a/poincare/include/poincare/layout_engine.h +++ b/poincare/include/poincare/layout_engine.h @@ -1,19 +1,18 @@ #ifndef POINCARE_LAYOUT_ENGINE_H #define POINCARE_LAYOUT_ENGINE_H -#include +#include #include +#include 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); }; } diff --git a/poincare/include/poincare/tree_by_reference.h b/poincare/include/poincare/tree_by_reference.h index f1df5fff2..a0a622ef4 100644 --- a/poincare/include/poincare/tree_by_reference.h +++ b/poincare/include/poincare/tree_by_reference.h @@ -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 */ diff --git a/poincare/include/poincare/tree_pool.h b/poincare/include/poincare/tree_pool.h index 862e522f5..9dc7c3af1 100644 --- a/poincare/include/poincare/tree_pool.h +++ b/poincare/include/poincare/tree_pool.h @@ -24,7 +24,7 @@ public: TreeNode * last() const { return reinterpret_cast(const_cast(m_cursor)); } template - 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; inumberOfChildren(); 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; } diff --git a/poincare/include/poincare/undefined.h b/poincare/include/poincare/undefined.h index 4a7476126..5d8d0de3c 100644 --- a/poincare/include/poincare/undefined.h +++ b/poincare/include/poincare/undefined.h @@ -7,6 +7,10 @@ namespace Poincare { class UndefinedNode : public NumberNode { public: + static UndefinedNode * FailedAllocationStaticNode() { + return static_cast(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 approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(); } - EvaluationReference approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { + Evaluation approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override { return templatedApproximate(); } @@ -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 EvaluationReference templatedApproximate() const; + template Evaluation templatedApproximate() const; }; -class UndefinedReference : public NumberReference { +class Undefined : public Number { public: - UndefinedReference() : NumberReference(TreePool::sharedPool()->createTreeNode(), true) {} + Undefined() : Number(TreePool::sharedPool()->createTreeNode()) {} }; } diff --git a/poincare/src/expression_node.cpp b/poincare/src/expression_node.cpp index ecbe5c0ed..490374f96 100644 --- a/poincare/src/expression_node.cpp +++ b/poincare/src/expression_node.cpp @@ -4,7 +4,7 @@ namespace Poincare { -TreeNode * ExpressionNode::FailedAllocationStaticNode() { +ExpressionNode * ExpressionNode::FailedAllocationStaticNode() { static AllocationFailedExpressionNode FailureNode; TreePool::sharedPool()->registerStaticNodeIfRequired(&FailureNode); return &FailureNode; diff --git a/poincare/src/tree_by_reference.cpp b/poincare/src/tree_by_reference.cpp index 971618ea8..1db4d6f64 100644 --- a/poincare/src/tree_by_reference.cpp +++ b/poincare/src/tree_by_reference.cpp @@ -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); - } -} - } diff --git a/poincare/src/undefined.cpp b/poincare/src/undefined.cpp index 8fdf9e3ff..7c56e0136 100644 --- a/poincare/src/undefined.cpp +++ b/poincare/src/undefined.cpp @@ -26,8 +26,8 @@ int UndefinedNode::writeTextInBuffer(char * buffer, int bufferSize, Preferences: return PrintFloat::convertFloatToText(NAN, buffer, bufferSize, numberOfSignificantDigits, floatDisplayMode); } -template EvaluationReference UndefinedNode::templatedApproximate() const { - return ComplexReference::Undefined(); +template Evaluation UndefinedNode::templatedApproximate() const { + return Complex::Undefined(); } }