UTI NodeTypedef::checkAndLabelType() { UTI it = Nav; // instantiate, look up in current block if(m_typedefSymbol == NULL) checkForSymbol(); if(m_typedefSymbol) { //m_typedefSymbol is the (rhs) type alias it = m_typedefSymbol->getUlamTypeIdx(); //check for UNSEEN Class' ClassType (e.g. array of UC_QUARK) UlamType * tdut = m_state.getUlamTypeByIndex(it); if((tdut->getUlamTypeEnum() == Class) && (tdut->getUlamClassType() == UC_UNSEEN)) { if(!m_state.completeIncompleteClassSymbolForTypedef(it)) { std::ostringstream msg; msg << "Incomplete Typedef for class type: "; msg << m_state.getUlamTypeNameBriefByIndex(it).c_str(); msg << ", used with variable symbol name <" << getName() << ">"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT); } } else if(tdut->isHolder() && !m_state.isThisLocalsFileScope()) { m_state.statusUnknownTypeInThisClassResolver(it); } UTI cuti = m_state.getCompileThisIdx(); if(m_nodeTypeDesc) { UTI duti = m_nodeTypeDesc->checkAndLabelType(); //sets goagain if nav if(m_state.okUTItoContinue(duti) && (duti != it)) { std::ostringstream msg; msg << "REPLACING Symbol UTI" << it; msg << ", " << m_state.getUlamTypeNameBriefByIndex(it).c_str(); msg << " used with typedef symbol name '" << getName(); msg << "' with node type descriptor type: "; msg << m_state.getUlamTypeNameBriefByIndex(duti).c_str(); msg << " UTI" << duti << " while labeling class: "; msg << m_state.getUlamTypeNameBriefByIndex(cuti).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); m_state.mapTypesInCurrentClass(it, duti); m_state.updateUTIAliasForced(it, duti); //t3379 m_typedefSymbol->resetUlamType(duti); //consistent! (must be same ref type) it = duti; } } if(!m_state.okUTItoContinue(it) || !m_state.isComplete(it)) //reloads { std::ostringstream msg; msg << "Incomplete Typedef for type: "; msg << m_state.getUlamTypeNameBriefByIndex(it).c_str(); msg << ", used with typedef symbol name '" << getName() << "'"; if(m_state.okUTItoContinue(it) || (it == Hzy)) { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT); m_state.setGoAgain(); //since not error; unlike vardecl } else MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); } } // got typedef symbol setNodeType(it); return getNodeType(); } //checkAndLabelType
// used to select an array element; not for declaration UTI NodeSquareBracket::checkAndLabelType() { assert(m_nodeLeft && m_nodeRight); u32 errorCount = 0; UTI newType = Nav; //init UTI idxuti = Nav; UTI leftType = m_nodeLeft->checkAndLabelType(); bool isCustomArray = false; //for example, f.chance[i] where i is local, same as f.func(i); NodeBlock * currBlock = m_state.getCurrentBlock(); m_state.pushCurrentBlockAndDontUseMemberBlock(currBlock); //currblock doesn't change UTI rightType = m_nodeRight->checkAndLabelType(); m_state.popClassContext(); if(leftType != Nav) { UlamType * lut = m_state.getUlamTypeByIndex(leftType); isCustomArray = lut->isCustomArray(); if(lut->isScalar()) { if(lut->isHolder()) { std::ostringstream msg; msg << "Incomplete Type: " << m_state.getUlamTypeNameBriefByIndex(leftType).c_str(); msg << " used with " << getName(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); errorCount++; } else if(!isCustomArray) { std::ostringstream msg; msg << "Invalid Type: " << m_state.getUlamTypeNameBriefByIndex(leftType).c_str(); msg << " used with " << getName(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); errorCount++; } else { //must be a custom array; t.f. lhs is a quark! assert(lut->getUlamClass() != UC_NOTACLASS); // can't substitute a function call node for square brackets to leverage // all the overload matching in func call node's c&l, because // we ([]) can't tell which side of = we are on, and whether we should // be a aref or aset. UTI caType = ((UlamTypeClass *) lut)->getCustomArrayType(); if(!m_state.isComplete(caType)) { std::ostringstream msg; msg << "Incomplete Custom Array Type: "; msg << m_state.getUlamTypeNameBriefByIndex(caType).c_str(); msg << " used with class: "; msg << m_state.getUlamTypeNameBriefByIndex(leftType).c_str(); msg << getName(); if(lut->isComplete()) MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); else MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); newType = Nav; //error! errorCount++; } } //set up idxuti..RHS //cant proceed with custom array subscript if lhs is incomplete if(errorCount == 0) { if(isCustomArray) { bool hasHazyArgs = false; u32 camatches = ((UlamTypeClass *) lut)->getCustomArrayIndexTypeFor(m_nodeRight, idxuti, hasHazyArgs); if(camatches == 0) { std::ostringstream msg; msg << "No defined custom array get function with"; msg << " matching argument type "; msg << m_state.getUlamTypeNameBriefByIndex(rightType).c_str(); msg << "; and cannot be called"; if(hasHazyArgs) MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); else MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); idxuti = Nav; //error! errorCount++; } else if(camatches > 1) { std::ostringstream msg; msg << "Ambiguous matches (" << camatches; msg << ") of custom array get function for argument type "; msg << m_state.getUlamTypeNameBriefByIndex(rightType).c_str(); msg << "; Explicit casting required"; if(hasHazyArgs) MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); else MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); idxuti = Nav; //error! errorCount++; } } else { //not custom array //must be some kind of numeric type: Int, Unsigned, or Unary..of any bit size if(rightType != Nav && !m_state.getUlamTypeByIndex(rightType)->isNumericType()) { std::ostringstream msg; msg << "Array item specifier requires numeric type: "; msg << m_state.getUlamTypeNameBriefByIndex(rightType).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); idxuti = Nav; //error! errorCount++; } else idxuti = rightType; //default unless caarray } } //errorcount is zero } //lut is scalar if(idxuti != Nav && UlamType::compare(idxuti, rightType, m_state) == UTIC_NOTSAME) { if(m_nodeRight->safeToCastTo(idxuti) == CAST_CLEAR) { if(!makeCastingNode(m_nodeRight, idxuti, m_nodeRight)) { newType = Nav; //error! errorCount++; } } else { newType = Nav; //error! errorCount++; } } } //lt not nav if(errorCount == 0) { // sq bracket purpose in life is to account for array elements; if(isCustomArray) newType = ((UlamTypeClass *) m_state.getUlamTypeByIndex(leftType))->getCustomArrayType(); else newType = m_state.getUlamTypeAsScalar(leftType); // multi-dimensional possible; MP not ok lhs. setStoreIntoAble(m_nodeLeft->isStoreIntoAble()); } setNodeType(newType); return newType; } //checkAndLabelType