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::constantFold() { u64 val = U64_MAX; UTI nuti = getNodeType(); if(nuti == Nav) return Nav; //nothing to do yet //if(nuti == Hzy) return Hzy; //nothing to do yet TRY? // if here, must be a constant.. assert(isAConstant()); NNO pno = Node::getYourParentNo(); assert(pno); Node * parentNode = m_state.findNodeNoInThisClassForParent(pno); //t3767 assert(parentNode); evalNodeProlog(0); //new current frame pointer makeRoomForNodeType(nuti); //offset a constant expression EvalStatus evs = eval(); if( evs == NORMAL) { UlamValue cnstUV = m_state.m_nodeEvalStack.popArg(); u32 wordsize = m_state.getTotalWordSize(nuti); if(wordsize <= MAXBITSPERINT) val = cnstUV.getImmediateData(m_state); else if(wordsize <= MAXBITSPERLONG) val = cnstUV.getImmediateDataLong(m_state); else m_state.abortGreaterThanMaxBitsPerLong(); } evalNodeEpilog(); if(evs == ERROR) { std::ostringstream msg; msg << "Constant value expression for unary op" << getName(); msg << " is erroneous while compiling class: "; msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); setNodeType(Nav); return Nav; } if(evs == NOTREADY) { std::ostringstream msg; msg << "Constant value expression for unary op" << getName(); msg << " is not yet ready while compiling class: "; msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT); setNodeType(Hzy); m_state.setGoAgain(); //for compiler counts return Hzy; } //replace ourselves (and kids) with a node terminal; new NNO unlike template's NodeTerminal * newnode = new NodeTerminal(val, nuti, m_state); assert(newnode); newnode->setNodeLocation(getNodeLocation()); AssertBool swapOk = parentNode->exchangeKids(this, newnode); assert(swapOk); std::ostringstream msg; msg << "Exchanged kids! for unary " << getName(); msg << ", with a constant == " << newnode->getName(); msg << " while compiling class: "; msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); newnode->setYourParentNo(pno); newnode->resetNodeNo(getNodeNo()); delete this; //suicide is painless.. return newnode->checkAndLabelType(); } //constantFold
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