ExpressionNode Multiplication::simplify(ExpressionNode& left, ExpressionNode& right) { // unimplemented ExpressionNode newNode(&MULTIPLICATION); left.setRight(&right); newNode.setFirstChild(&left); return newNode; }
ExpressionNode Addition::simplify(ExpressionNode& left, ExpressionNode& right) { std::clog << "checkpoint addsimplify" << std::endl; //simplest case: at least one side is just 0 if (left.getType() == NUMBER && left.getValue().getInt() == 0) { return right; } else if (right.getType() == NUMBER && right.getValue().getInt() == 0) { return left; } // for each left term: for each right term: try adding std::stack <ExpressionNode*> leftNodeStack; ExpressionNode * currentLeftNode = &left; bool leftFinished = false; std::stack <ExpressionNode*> rightNodeStack; ExpressionNode * currentRightNode = &right; bool rightFinished = false; ExpressionNode * tempNodePtr; ExpressionNode newNode; while (leftFinished == false) { std::clog << "looping left" << std::endl; if (currentLeftNode->getType() == OPERATION && currentLeftNode->getOperation() == &ADDITION) { if (currentLeftNode->getFirstChild() == 0) { throw ExpressionNode::WrongArityError(); } currentLeftNode = currentLeftNode->getFirstChild(); leftNodeStack.push(currentLeftNode); continue; } // leaf term on left tree: traverse right tree while (rightFinished == false) { std::clog << "looping right" << std::endl; if (currentRightNode->getType() == OPERATION && currentRightNode->getOperation() == &ADDITION) { if (currentRightNode->getFirstChild() == 0) { throw ExpressionNode::WrongArityError(); } currentRightNode = currentRightNode->getFirstChild(); rightNodeStack.push(currentRightNode); continue; } std::clog << "checkpoint addsimplify: before isAddable; " << std::endl; // leaf terms on both sides: attempt adding if (isAddable(*currentLeftNode, *currentRightNode)) { std::clog << "checkpoint addsimplify: after isAddable; " << std::endl; std::clog << *currentLeftNode << " " << *currentRightNode << std::endl; std::clog << "add testrun: " << addTerms(*currentLeftNode, *currentRightNode); (*currentLeftNode).replace( addTerms(*currentLeftNode, *currentRightNode) ); std::clog << "checkpoint addsimplify: after addTerms; " << std::endl; if (currentRightNode == &right) { //entire right tree has been assimilated return left; } tempNodePtr = currentRightNode; currentRightNode = right.findParentOf(*currentRightNode); right.remove(*tempNodePtr); } while (true) { if (rightNodeStack.size() == 0) { rightFinished = true; break; } currentRightNode = rightNodeStack.top(); rightNodeStack.pop(); if (currentRightNode->getRight() != 0) { currentRightNode = currentRightNode->getRight(); rightNodeStack.push(currentRightNode); break; } } } while (true) { if (leftNodeStack.size() == 0) { leftFinished = true; break; } currentLeftNode = leftNodeStack.top(); leftNodeStack.pop(); if (currentLeftNode->getRight() != 0) { currentLeftNode = currentLeftNode->getRight(); leftNodeStack.push(currentLeftNode); break; } } } //still some terms left on right left.setRight(&right); newNode.init(&ADDITION, &left); return newNode; }