UTI NodeBinaryOpCompare::checkAndLabelType() { assert(m_nodeLeft && m_nodeRight); UTI leftType = m_nodeLeft->checkAndLabelType(); UTI rightType = m_nodeRight->checkAndLabelType(); UlamType * lut = m_state.getUlamTypeByIndex(leftType); if((lut->getUlamTypeEnum() == Class)) { Node * newnode = buildOperatorOverloadFuncCallNode(); if(newnode) { AssertBool swapOk = Node::exchangeNodeWithParent(newnode); assert(swapOk); m_nodeLeft = NULL; //recycle as memberselect m_nodeRight = NULL; //recycle as func call arg delete this; //suicide is painless.. return newnode->checkAndLabelType(); //t41109 } //else should fail again as non-primitive; } //done UTI newType = calcNodeType(leftType, rightType); //for casting if(m_state.isComplete(newType)) { u32 errCnt = 0; if(UlamType::compareForMakingCastingNode(rightType, newType, m_state) != UTIC_SAME) { if(!Node::makeCastingNode(m_nodeRight, newType, m_nodeRight)) errCnt++; } if(UlamType::compareForMakingCastingNode(leftType, newType, m_state) != UTIC_SAME) { if(!Node::makeCastingNode(m_nodeLeft, newType, m_nodeLeft)) errCnt++; } if(errCnt) newType = Nav; else newType = Bool; //always Bool (default size) for node; after castings! } setNodeType(newType); if(newType == Hzy) m_state.setGoAgain(); //nolonger needed in calcnodetypes Node::setStoreIntoAble(TBOOL_FALSE); //still may need casting (e.g. unary compared to an int) before constantfolding if((newType != Nav) && isAConstant() && m_nodeLeft->isReadyConstant() && m_nodeRight->isReadyConstant()) return NodeBinaryOp::constantFold(); return newType; } //checkAndLabelType
UTI NodeBinaryOpCompare::checkAndLabelType() { assert(m_nodeLeft && m_nodeRight); UTI leftType = m_nodeLeft->checkAndLabelType(); UTI rightType = m_nodeRight->checkAndLabelType(); UTI newType = calcNodeType(leftType, rightType); //for casting if(newType != Nav && m_state.isComplete(newType)) { u32 errCnt = 0; if(UlamType::compare(rightType, newType, m_state) != UTIC_SAME) { if(!makeCastingNode(m_nodeRight, newType, m_nodeRight)) errCnt++; } if(UlamType::compare(leftType, newType, m_state) != UTIC_SAME) { if(!makeCastingNode(m_nodeLeft, newType, m_nodeLeft)) errCnt++; } if(errCnt) newType = Nav; else newType = Bool; //always Bool (default size) for node; after castings! } setNodeType(newType); setStoreIntoAble(false); //still may need casting (e.g. unary compared to an int) before constantfolding if(newType != Nav && isAConstant() && m_nodeLeft->isReadyConstant() && m_nodeRight->isReadyConstant()) return NodeBinaryOp::constantFold(); return newType; } //checkAndLabelType
UTI NodeUnaryOp::checkAndLabelType() { assert(m_node); UTI uti = m_node->checkAndLabelType(); if(m_state.isComplete(uti) && !m_state.isScalar(uti)) //array unsupported at this time { std::ostringstream msg; msg << "Incompatible (nonscalar) type: "; msg << m_state.getUlamTypeNameBriefByIndex(uti).c_str(); msg << ", for unary " << getName(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); setNodeType(Nav); return Nav; } //replace node with func call to matching function overload operator for class // of left, with no arguments for unary (t41???); // quark toInt must be used on rhs of operators (t3191, t3200, t3513, t3648,9) UlamType * ut = m_state.getUlamTypeByIndex(uti); if((ut->getUlamTypeEnum() == Class)) { Node * newnode = buildOperatorOverloadFuncCallNode(); if(newnode) { AssertBool swapOk = Node::exchangeNodeWithParent(newnode); assert(swapOk); m_node = NULL; //recycle as memberselect delete this; //suicide is painless.. return newnode->checkAndLabelType(); } //else should fail again as non-primitive; } //done UTI newType = Nav; if(uti != Nav) newType = calcNodeType(uti); //does safety check if(m_state.isComplete(newType)) { if(UlamType::compareForMakingCastingNode(newType, uti, m_state) != UTIC_SAME) //not same|dontknow { if(!Node::makeCastingNode(m_node, newType, m_node)) newType = Nav; } } else newType = Hzy; setNodeType(newType); if(newType == Hzy) m_state.setGoAgain(); //since not error Node::setStoreIntoAble(TBOOL_FALSE); if((newType != Nav) && isAConstant() && m_node->isReadyConstant()) return constantFold(); return newType; } //checkAndLabelType
UTI NodeBinaryOpEqualShift::checkAndLabelType() { //UTI nodeType = NodeBinaryOp::checkAndLabelType(); //dup Shift calcNodeType assert(m_nodeLeft && m_nodeRight); UTI leftType = m_nodeLeft->checkAndLabelType(); UTI rightType = m_nodeRight->checkAndLabelType(); if(!m_state.okUTItoContinue(leftType)) { //left type possibly a class w overload operator; no need to check right type here; setNodeType(leftType); return getNodeType(); } // efficiency bites! no sooner, need left and right side-effects // (e.g. NodeControl condition is Bool at start; stubs need Symbol ptrs) if(m_state.isComplete(getNodeType())) return getNodeType(); //replace node with func call to matching function overload operator for class // of left, with argument of right; UlamType * lut = m_state.getUlamTypeByIndex(leftType); if((lut->getUlamTypeEnum() == Class)) { Node * newnode = buildOperatorOverloadFuncCallNode(); //virtual if(newnode) { AssertBool swapOk = Node::exchangeNodeWithParent(newnode); assert(swapOk); m_nodeLeft = NULL; //recycle as memberselect m_nodeRight = NULL; //recycle as func call arg delete this; //suicide is painless.. return newnode->checkAndLabelType(); } //else should fail again as non-primitive; } //done UTI newType = calcNodeType(leftType, rightType); //does safety check setNodeType(newType); if(m_state.okUTItoContinue(newType)) { TBOOL stor = NodeBinaryOpEqual::checkStoreIntoAble(); if(stor == TBOOL_FALSE) { setNodeType(Nav); return Nav; //newType } else if(stor == TBOOL_HAZY) { setNodeType(Hzy); m_state.setGoAgain(); } if(!NodeBinaryOpEqual::checkNotUnpackedArray()) { setNodeType(Nav); return Nav; } } if(m_state.isComplete(newType)) { //lhs must be Bits; can't cast lhs of equal. //shift by unsigned type; cast if need be. safety checked by calcNodeType. if(m_state.getUlamTypeByIndex(rightType)->getUlamTypeEnum() != Unsigned) { if(!Node::makeCastingNode(m_nodeRight, Unsigned, m_nodeRight)) { newType = Nav; setNodeType(Nav); } } } //complete return getNodeType(); } //checkandlabeltype