diff --git a/addition_node.h b/addition_node.h index 7c7d1cecc..814f65ea3 100644 --- a/addition_node.h +++ b/addition_node.h @@ -40,6 +40,9 @@ public: i++; } + // Step 2: Sort the operands + sortChildren(); + return false; } diff --git a/expression_node.cpp b/expression_node.cpp index ff3194342..e392a95a6 100644 --- a/expression_node.cpp +++ b/expression_node.cpp @@ -5,3 +5,7 @@ TreeNode * ExpressionNode::FailedAllocationStaticNode() { return ExpressionRef::FailedAllocationStaticNode(); } + +void ExpressionNode::sortChildren() { + ExpressionRef(this).sortChildren(); +} diff --git a/expression_node.h b/expression_node.h index d0e45c238..68f3bef32 100644 --- a/expression_node.h +++ b/expression_node.h @@ -46,6 +46,8 @@ public: // Hierarchy ExpressionNode * child(int i) { return static_cast(childTreeAtIndex(i)); } +protected: + void sortChildren(); }; #endif diff --git a/expression_reference.h b/expression_reference.h index 3b2c460b1..0702d4790 100644 --- a/expression_reference.h +++ b/expression_reference.h @@ -38,6 +38,23 @@ public: void shallowReduce() { return this->castedNode()->shallowReduce(); } + + void sortChildren() { + for (int i = this->numberOfChildren()-1; i > 0; i--) { + bool isSorted = true; + for (int j = 0; j < this->numberOfChildren()-1; j++) { + if (this->childAtIndex(j).castedNode()->type() > this->childAtIndex(j+1).castedNode()->type()) { + this->swapChildren(j, j+1); + isSorted = false; + } + } + if (isSorted) { + return; + } + } + } + + }; typedef ExpressionReference ExpressionRef; diff --git a/test.cpp b/test.cpp index cd43a074b..7da9b9b95 100644 --- a/test.cpp +++ b/test.cpp @@ -239,6 +239,28 @@ void testSimplify() { assert(a.numberOfChildren() == 3); } +void testChildSort() { + printf("Child sort test\n"); + + AdditionRef a( + AdditionRef( + FloatRef(1.0f), + FloatRef(2.0f)), + FloatRef(3.0f)); + a.addChild(FloatRef(0.0f)); + + assert(a.childAtIndex(0).castedNode()->type() == ExpressionNode::Type::Float); + assert(a.childAtIndex(1).castedNode()->type() == ExpressionNode::Type::Addition); + assert(a.childAtIndex(2).castedNode()->type() == ExpressionNode::Type::Float); + + a.sortChildren(); + + assert(a.childAtIndex(0).castedNode()->type() == ExpressionNode::Type::Float); + assert(a.childAtIndex(1).castedNode()->type() == ExpressionNode::Type::Float); + assert(a.childAtIndex(2).castedNode()->type() == ExpressionNode::Type::Addition); +} + + void testPoolLayoutAllocationFail() { printf("Pool layout allocation fail test\n"); @@ -279,6 +301,7 @@ int main() { runTest(testPoolExpressionAllocationFailOnImbricatedAdditions); runTest(testStealOperand); runTest(testSimplify); + runTest(testChildSort); printf("\n*******************\nEnd of tests\n*******************\n\n"); return 0; } diff --git a/tree_reference.h b/tree_reference.h index a9c25bde2..c28123e8a 100644 --- a/tree_reference.h +++ b/tree_reference.h @@ -13,7 +13,7 @@ template class TreeReference { friend class TreeNode; friend class AdditionNode; - + friend class ExpressionNode; friend class Cursor; template friend class TreeReference;