UTI NodeControl::checkAndLabelType() { assert(m_nodeCondition && m_nodeBody); UTI newType = Bool; ULAMTYPE newEnumTyp = Bool; // condition should be a bool, safely cast UTI cuti = m_nodeCondition->checkAndLabelType(); if(m_state.okUTItoContinue(cuti) && m_state.isComplete(cuti)) { assert(m_state.isScalar(cuti)); UlamType * cut = m_state.getUlamTypeByIndex(cuti); ULAMTYPE ctypEnum = cut->getUlamTypeEnum(); if(ctypEnum != newEnumTyp) { if(checkSafeToCastTo(cuti, newType)) { if(!Node::makeCastingNode(m_nodeCondition, newType, m_nodeCondition)) newType = Nav; } //else not safe, newType changed } else { //caution: c&l called multiple times //always cast: Bools are maintained as unsigned in gen code, //until c-bool is needed if(cuti != newType) { if(checkSafeToCastTo(cuti, newType)) { if(!Node::makeCastingNode(m_nodeCondition, cuti, m_nodeCondition)) newType = Nav; else newType = cuti; } } } } else { newType = Hzy; //was = cuti; m_state.setGoAgain(); } m_nodeBody->checkAndLabelType(); //side-effect setNodeType(newType); //stays the same Node::setStoreIntoAble(TBOOL_FALSE); return getNodeType(); } //checkAndLabelType
//same as arith rules for relative comparisons. UTI NodeBinaryOpCompare::calcNodeType(UTI lt, UTI rt) { if(!m_state.neitherNAVokUTItoContinue(lt, rt)) return Nav; if(!m_state.isComplete(lt) || !m_state.isComplete(rt)) return Hzy; //no atoms, elements nor void as either operand if(!NodeBinaryOp::checkForPrimitiveNotVoidTypes(lt, rt)) return Nav; // only int, unsigned, unary types; not bool, bits, etc.. if(!NodeBinaryOp::checkForNumericTypes(lt, rt)) return Nav; //err output UTI newType = Nav; //init // all operations are performed as Int(32) or Unsigned(32) in CastOps.h // if one is unsigned, and the other isn't -> output error if unsafe; // Signed Int wins, unless its a constant. // Class (i.e. quark) + anything goes to Int(32) if(checkScalarTypesOnly(lt, rt)) { s32 newbs = NodeBinaryOp::resultBitsize(lt, rt); ULAMTYPE ltypEnum = m_state.getUlamTypeByIndex(lt)->getUlamTypeEnum(); ULAMTYPE rtypEnum = m_state.getUlamTypeByIndex(rt)->getUlamTypeEnum(); // treat Unary using Unsigned rules if(ltypEnum == Unary) ltypEnum = Unsigned; if(rtypEnum == Unary) rtypEnum = Unsigned; if(ltypEnum == Unsigned && rtypEnum == Unsigned) { UlamKeyTypeSignature newkey(m_state.m_pool.getIndexForDataString("Unsigned"), newbs); newType = m_state.makeUlamType(newkey, Unsigned, UC_NOTACLASS); } else { UlamKeyTypeSignature newkey(m_state.m_pool.getIndexForDataString("Int"), newbs); newType = m_state.makeUlamType(newkey, Int, UC_NOTACLASS); } checkSafeToCastTo(getNodeType(), newType); ////Nav, Hzy or no change; outputs error msg } //both scalars return newType; } //calcNodeType