bool NodeUnaryOp::checkSafeToCastTo(UTI unused, UTI& newType) { bool rtnOK = true; FORECAST scr = m_node->safeToCastTo(newType); if(scr != CAST_CLEAR) { ULAMTYPE etyp = m_state.getUlamTypeByIndex(newType)->getUlamTypeEnum(); std::ostringstream msg; if(etyp == Bool) msg << "Use a comparison operation"; else if(etyp == String) msg << "Invalid"; else msg << "Use explicit cast"; msg << " to convert "; // the real converting-message msg << m_state.getUlamTypeNameBriefByIndex(m_node->getNodeType()).c_str(); msg << " to "; msg << m_state.getUlamTypeNameBriefByIndex(newType).c_str(); msg << " for unary " << getName(); if(scr == CAST_HAZY) { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT); newType = Hzy; } else { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); newType = Nav; } rtnOK = false; } //not safe return rtnOK; } //checkSafeToCastTo
void NodeTypedef::checkForSymbol() { //in case of a cloned unknown NodeBlock * currBlock = getBlock(); m_state.pushCurrentBlockAndDontUseMemberBlock(currBlock); Symbol * asymptr = NULL; bool hazyKin = false; if(m_state.alreadyDefinedSymbol(m_tdid, asymptr, hazyKin) && !hazyKin) { if(asymptr->isTypedef()) { m_typedefSymbol = (SymbolTypedef *) asymptr; } else { std::ostringstream msg; msg << "(1) <" << m_state.m_pool.getDataAsString(m_tdid).c_str(); msg << "> is not a typedef, and cannot be used as one"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); } } else { std::ostringstream msg; msg << "(2) Typedef <" << m_state.m_pool.getDataAsString(m_tdid).c_str(); msg << "> is not defined, and cannot be used"; if(!hazyKin) MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); else MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); } m_state.popClassContext(); //restore } //toinstantiate
UTI NodeBinaryOpEqualArith::checkAndLabelType() { UTI nodeType = NodeBinaryOpEqual::checkAndLabelType(); UlamType * nut = m_state.getUlamTypeByIndex(nodeType); // common part of name ULAMTYPE enodetyp = nut->getUlamTypeEnum(); if(enodetyp == Bits) { // can happen with op-equal operations when both sides are the same type MSG(getNodeLocationAsString().c_str(), "Arithmetic Operations are invalid on 'Bits' type", ERR); nodeType = Nav; } if(enodetyp == Bool) { // can happen with op-equal operations when both sides are the same type MSG(getNodeLocationAsString().c_str(), "Arithmetic Operations are invalid on 'Bool' type", ERR); nodeType = Nav; } if((nodeType != Nav) && !nut->isScalar()) { std::ostringstream msg; msg << "Non-scalars require a loop for operator" << getName(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); nodeType = Nav; } setNodeType(nodeType); return nodeType; } //checkAndLabelType
UTI NodeBinaryOpEqualShift::calcNodeType(UTI lt, UTI rt) //shift { if(!m_state.neitherNAVokUTItoContinue(lt, rt)) return Nav; if(!m_state.isComplete(lt) || !m_state.isComplete(rt)) return Hzy; //no atoms, elements nor voids as either operand if(!NodeBinaryOp::checkForPrimitiveNotVoidTypes(lt, rt)) return Nav; UTI newType = Nav; //init if(NodeBinaryOp::checkScalarTypesOnly(lt, rt)) { bool bOK = true; //can't cast lhs of equal ULAMTYPE ltypEnum = m_state.getUlamTypeByIndex(lt)->getUlamTypeEnum(); if(ltypEnum != Bits) { std::ostringstream msg; msg << "Bits is the supported type for shift operation "; //equal msg << getName(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); bOK = false; } newType = lt; FORECAST rscr = m_nodeRight->safeToCastTo(Unsigned); if(rscr != CAST_CLEAR) { std::ostringstream msg; msg << "Righthand type "; msg << m_state.getUlamTypeNameBriefByIndex(rt).c_str(); msg << " is not representable as Unsigned"; msg << "; the supported type for rhs of shift operation "; msg << getName(); if(rscr == CAST_BAD) { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); bOK = false; } else //hazy { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT); m_state.setGoAgain(); //for compiler counts newType = Hzy; } } if(!bOK) newType = Nav; } //both scalars return newType; } //calcNodeType
void NodeConstantArray::checkForSymbol() { //in case of a cloned unknown NodeBlock * currBlock = getBlock(); m_state.pushCurrentBlockAndDontUseMemberBlock(currBlock); Symbol * asymptr = NULL; bool hazyKin = false; if(m_state.alreadyDefinedSymbol(m_token.m_dataindex, asymptr, hazyKin)) { if(asymptr->isConstant()) { m_constSymbol = (SymbolConstantValue *) asymptr; } else { std::ostringstream msg; msg << "(1) <" << m_state.getTokenDataAsString(m_token).c_str(); msg << "> is not a constant, and cannot be used as one with class: "; msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); } } else { std::ostringstream msg; msg << "Named Constant Array <" << m_state.getTokenDataAsString(m_token).c_str(); msg << "> is not defined, or was used before declared in a function"; if(!hazyKin) MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); else MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); } m_state.popClassContext(); //restore if(m_constSymbol && !m_constSymbol->isDataMember() && !m_constSymbol->isLocalsFilescopeDef() && !m_constSymbol->isClassArgument() && (m_constSymbol->getDeclNodeNo() > getNodeNo())) { NodeBlock * currBlock = getBlock(); currBlock = currBlock->getPreviousBlockPointer(); std::ostringstream msg; msg << "Named constant array '" << getName(); msg << "' was used before declared in a function"; if(currBlock) { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT); setBlockNo(currBlock->getNodeNo()); m_constSymbol = NULL; return checkForSymbol(); } else { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); m_constSymbol = NULL; } } } //checkForSymbol
UTI NodeBinaryOpLogical::calcNodeType(UTI lt, UTI rt) //logical { if(!m_state.okUTItoContinue(lt, rt)) return Nav; if(!m_state.isComplete(lt) || !m_state.isComplete(rt)) return Hzy; //no atoms, elements nor voids as either operand if(!NodeBinaryOp::checkForPrimitiveTypes(lt, rt)) return Nav; UTI newType = Nav; //init // all logical operations are performed as Bool.BITSPERBOOL.-1 if(NodeBinaryOp::checkScalarTypesOnly(lt, rt)) { s32 maxbs = 1; FORECAST lscr = m_state.getUlamTypeByIndex(Bool)->safeCast(lt); FORECAST rscr = m_state.getUlamTypeByIndex(Bool)->safeCast(rt); //check for Bool, or safe Non-Bool to Bool casting cases: if(lscr != CAST_CLEAR || rscr != CAST_CLEAR) { std::ostringstream msg; msg << "Bool is the supported type for logical operator"; msg << getName() << "; Suggest casting "; msg << m_state.getUlamTypeNameBriefByIndex(lt).c_str() << " and "; msg << m_state.getUlamTypeNameBriefByIndex(rt).c_str(); msg << " to Bool"; if(lscr == CAST_BAD || rscr == CAST_BAD) { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); newType = Nav; } else { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); //hazy m_state.setGoAgain(); newType = Hzy; } } else { s32 lbs = m_state.getBitSize(lt); s32 rbs = m_state.getBitSize(rt); maxbs = (lbs > rbs ? lbs : rbs); //both bool. ok to cast. use larger bool bitsize. UlamKeyTypeSignature newkey(m_state.m_pool.getIndexForDataString("Bool"), maxbs); newType = m_state.makeUlamType(newkey, Bool, UC_NOTACLASS); } } //both scalars return newType; } //calcNodeType
UTI NodeBinaryOpArithRemainder::castThyselfToResultType(UTI rt, UTI lt, UTI newType) { UTI nuti = newType; //because the result bitsize for mod should be the right bitsize // create a cast! combining newType's base type and right resultbitsize. // could be the same, or "unsafe". if(m_state.okUTItoContinue(newType) && m_state.isComplete(newType)) { UlamType * newut = m_state.getUlamTypeByIndex(newType); ULAMTYPE typEnum = newut->getUlamTypeEnum(); u32 convertSize = m_state.getUlamTypeByIndex(rt)->bitsizeToConvertTypeTo(typEnum); u32 enumStrIdx = m_state.m_pool.getIndexForDataString(UlamType::getUlamTypeEnumAsString(typEnum)); UlamKeyTypeSignature tokey(enumStrIdx, convertSize, NONARRAYSIZE); ULAMCLASSTYPE newclasstype = newut->getUlamClassType(); nuti = m_state.makeUlamType(tokey, typEnum, newclasstype); if(UlamType::compareForMakingCastingNode(nuti, newType, m_state) != UTIC_SAME) //not same, or dontknow { NNO pno = Node::getYourParentNo(); //save assert(pno); //not using use makeCastingNode since don't want recursive c&l call Node * castNode = Node::newCastingNode(this, nuti); Node * parentNode = m_state.findNodeNoInThisClass(pno); if(!parentNode) { std::ostringstream msg; msg << "Remainder cast cannot be exchanged at this time while compiling class: "; msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str(); msg << " Parent required"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); assert(0); //parent required } AssertBool swapOk = parentNode->exchangeKids(this, castNode); assert(swapOk); std::ostringstream msg; msg << "Exchanged kids! of parent of binary operator" << getName(); msg << ", with a cast to type: "; msg << m_state.getUlamTypeNameBriefByIndex(nuti).c_str(); msg << " while compiling class: "; msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); castNode->setYourParentNo(pno); //inverts normal update lineage setYourParentNo(castNode->getNodeNo()); } } return nuti; } //castThyselfToResultType
UTI NodeBinaryOpEqualBitwise::calcNodeType(UTI lt, UTI rt) //bitwise { if(!m_state.isComplete(lt) || !m_state.isComplete(rt)) return Nav; //no atoms, elements nor voids as either operand if(!NodeBinaryOp::checkForPrimitiveTypes(lt, rt)) return Nav; UTI newType = Nav; //init if(NodeBinaryOp::checkScalarTypesOnly(lt, rt)) { bool bOK = true; //can't cast lhs of equal ULAMTYPE ltypEnum = m_state.getUlamTypeByIndex(lt)->getUlamTypeEnum(); if(ltypEnum != Bits) { std::ostringstream msg; msg << "Bits is the supported type for bitwise operator"; //equal msg << getName(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); bOK = false; } newType = lt; FORECAST rscr = m_nodeRight->safeToCastTo(newType); if(rscr != CAST_CLEAR) { std::ostringstream msg; msg << "Righthand type "; msg << m_state.getUlamTypeNameBriefByIndex(rt).c_str(); msg << " is not representable as "; msg<< m_state.getUlamTypeNameBriefByIndex(newType).c_str(); msg << ". Bits is the supported type for bitwise operator"; msg << getName(); if(rscr == CAST_BAD) MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); else //hazy MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); bOK = false; } if(!bOK) newType = Nav; } //both scalars return newType; } //calcNodeType
UTI NodeUnaryOpBang::calcNodeType(UTI uti) { if(uti == Nav) return Nav; if(!m_state.isComplete(uti)) return Hzy; ULAMTYPE typEnum = m_state.getUlamTypeByIndex(uti)->getUlamTypeEnum(); if(typEnum == Bits) { std::ostringstream msg; msg << "Incompatible Bits type for unary "; msg << getName() << ". Suggest casting to a Bool first"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); return Nav; } if(!NodeUnaryOp::checkForPrimitiveType(uti)) return Nav; UTI newType = Nav; s32 newbs = (typEnum == Bool ? m_state.getBitSize(uti) : 1); FORECAST scr = m_state.getUlamTypeByIndex(Bool)->safeCast(uti); if(scr != CAST_CLEAR) { std::ostringstream msg; msg << "Bool is the supported type for logical unary "; msg << getName() << "; Suggest casting "; msg << m_state.getUlamTypeNameBriefByIndex(uti).c_str(); msg << " to Bool"; if(scr == CAST_HAZY) { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT); m_state.setGoAgain(); newType = Hzy; } else MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); } else { // safe to cast. use a bool bitsize. UlamKeyTypeSignature newkey(m_state.m_pool.getIndexForDataString("Bool"), newbs); newType = m_state.makeUlamType(newkey, Bool, UC_NOTACLASS); } return newType; } //calcNodeType
UlamValue NodeBinaryOpArithDivide::makeImmediateBinaryOp(UTI type, u32 ldata, u32 rdata, u32 len) { UlamValue rtnUV; if(rdata == 0) { MSG(getNodeLocationAsString().c_str(), "Possible Divide By Zero Attempt", ERR); rtnUV.setUlamValueTypeIdx(Nav); setNodeType(Nav); //compiler counts return rtnUV; } ULAMTYPE typEnum = m_state.getUlamTypeByIndex(type)->getUlamTypeEnum(); switch(typEnum) { case Int: rtnUV = UlamValue::makeImmediate(type, _BinOpDivideInt32(ldata, rdata, len), len); break; case Unsigned: rtnUV = UlamValue::makeImmediate(type, _BinOpDivideUnsigned32(ldata, rdata, len), len); break; case Bool: rtnUV = UlamValue::makeImmediate(type, _BinOpDivideBool32(ldata, rdata, len), len); break; case Unary: rtnUV = UlamValue::makeImmediate(type, _BinOpDivideUnary32(ldata, rdata, len), len); break; case Bits: default: m_state.abortUndefinedUlamPrimitiveType(); break; }; return rtnUV; } //makeImmediateBinaryOp
void NodeBinaryOpArithDivide::appendBinaryOp(UlamValue& refUV, u32 ldata, u32 rdata, u32 pos, u32 len) { if(rdata == 0) { MSG(getNodeLocationAsString().c_str(), "Possible Divide By Zero Attempt", ERR); refUV.setUlamValueTypeIdx(Nav); setNodeType(Nav); //compiler counts return; } UTI type = refUV.getUlamValueTypeIdx(); ULAMTYPE typEnum = m_state.getUlamTypeByIndex(type)->getUlamTypeEnum(); switch(typEnum) { case Int: refUV.putData(pos, len, _BinOpDivideInt32(ldata, rdata, len)); break; case Unsigned: refUV.putData(pos, len, _BinOpDivideUnsigned32(ldata, rdata, len)); break; case Bool: refUV.putData(pos, len, _BinOpDivideBool32(ldata, rdata, len)); break; case Unary: refUV.putData(pos, len, _BinOpDivideUnary32(ldata, rdata, len)); break; case Bits: default: m_state.abortUndefinedUlamPrimitiveType(); break; }; return; } //appendBinaryOp
UlamValue NodeBinaryOpArithRemainder::makeImmediateLongBinaryOp(UTI type, u64 ldata, u64 rdata, u32 len) { UlamValue rtnUV; if(rdata == 0) { MSG(getNodeLocationAsString().c_str(), "Possible Division By Zero Attempt in Modulus", ERR); rtnUV.setUlamValueTypeIdx(Nav); setNodeType(Nav); //compiler counts return rtnUV; } ULAMTYPE typEnum = m_state.getUlamTypeByIndex(type)->getUlamTypeEnum(); switch(typEnum) { case Int: rtnUV = UlamValue::makeImmediateLong(type, _BinOpModInt64(ldata, rdata, len), len); break; case Unsigned: rtnUV = UlamValue::makeImmediateLong(type, _BinOpModUnsigned64(ldata, rdata, len), len); break; case Bool: rtnUV = UlamValue::makeImmediateLong(type, _BinOpModBool64(ldata, rdata, len), len); break; case Unary: rtnUV = UlamValue::makeImmediateLong(type, _BinOpModUnary64(ldata, rdata, len), len); break; case Bits: default: assert(0); break; }; return rtnUV; } //makeImmediateLongBinaryOp
Node * NodeUnaryOp::buildOperatorOverloadFuncCallNode() { Token identTok; TokenType opTokType = Token::getTokenTypeFromString(getName()); assert(opTokType != TOK_LAST_ONE); Token opTok(opTokType, getNodeLocation(), 0); u32 opolId = Token::getOperatorOverloadFullNameId(opTok, &m_state); if(opolId == 0) { std::ostringstream msg; msg << "Overload for operator <" << getName(); msg << "> is not supported as operand for class: "; msg << m_state.getUlamTypeNameBriefByIndex(m_node->getNodeType()).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); return NULL; } identTok.init(TOK_IDENTIFIER, getNodeLocation(), opolId); //fill in func symbol during type labeling; NodeFunctionCall * fcallNode = new NodeFunctionCall(identTok, NULL, m_state); assert(fcallNode); fcallNode->setNodeLocation(identTok.m_locator); //similar to Binary Op's except no argument NodeMemberSelect * mselectNode = new NodeMemberSelect(m_node, fcallNode, m_state); assert(mselectNode); mselectNode->setNodeLocation(identTok.m_locator); //redo check and type labeling done by caller!! return mselectNode; //replace right node with new branch } //buildOperatorOverloadFuncCallNode
bool NodeCast::needsACast() { UTI tobeType = getNodeType(); UTI nodeType = m_node->getNodeType(); ULAMTYPECOMPARERESULTS uticr = UlamType::compare(nodeType, tobeType, m_state); if(uticr == UTIC_DONTKNOW) { std::ostringstream msg; msg << "Casting 'incomplete' types: "; msg << m_state.getUlamTypeNameBriefByIndex(nodeType).c_str(); msg << "(UTI" << nodeType << ") to be "; msg << m_state.getUlamTypeNameBriefByIndex(tobeType).c_str(); msg << "(UTI" << tobeType << ")"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); return false; } if(uticr == UTIC_SAME) return false; //short-circuit if same exact type ULAMTYPE typEnum = m_state.getUlamTypeByIndex(tobeType)->getUlamTypeEnum(); ULAMTYPE nodetypEnum = m_state.getUlamTypeByIndex(nodeType)->getUlamTypeEnum(); if(m_state.getUlamTypeByIndex(nodeType)->getUlamClass() == UC_QUARK) return false; // consider user requested first, then size independent; // even constant may need casting (e.g. narrowing for saturation) // Bool constants require casts to generate "full" true UlamValue (>1-bit). return( isExplicitCast() || typEnum != nodetypEnum || (m_state.getBitSize(tobeType) != m_state.getBitSize(nodeType)) || (nodetypEnum == Bool && m_node->isAConstant() && m_state.getBitSize(tobeType)>1)); } //needsACast
void NodeBinaryOpArithRemainder::appendBinaryOp(UlamValue& refUV, u32 ldata, u32 rdata, u32 pos, u32 len) { if(rdata == 0) { MSG(getNodeLocationAsString().c_str(), "Possible Remainder By Zero Attempt", ERR); return; } UTI type = refUV.getUlamValueTypeIdx(); ULAMTYPE typEnum = m_state.getUlamTypeByIndex(type)->getUlamTypeEnum(); switch(typEnum) { case Int: refUV.putData(pos, len, _BinOpModInt32(ldata, rdata, len)); break; case Unsigned: refUV.putData(pos, len, _BinOpModUnsigned32(ldata, rdata, len)); break; case Bool: refUV.putData(pos, len, _BinOpModBool32(ldata, rdata, len)); break; case Unary: refUV.putData(pos, len, _BinOpModUnary32(ldata, rdata, len)); break; case Bits: default: assert(0); break; }; return; } //appendBinaryOp
//class context set prior to calling us; purpose is to get // the value of this constant from the context before // constant folding happens. bool NodeConstantArray::assignClassArgValueInStubCopy() { // insure current block NNOs match if(m_currBlockNo != m_state.getCurrentBlockNo()) { std::ostringstream msg; msg << "Block NNO " << m_currBlockNo << " for <"; msg << m_state.getTokenDataAsString(m_token).c_str(); msg << "> does not match the current block no "; msg << m_state.getCurrentBlockNo(); msg << "; its value cannot be used in stub copy, with class: "; msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); return false; } if(isReadyConstant()) return true; //nothing to do bool isready = false; Symbol * asymptr = NULL; bool hazyKin = false; if(m_state.alreadyDefinedSymbol(m_token.m_dataindex, asymptr, hazyKin)) { assert(hazyKin); //always hazy, right? if(asymptr->isConstant() && ((SymbolConstantValue *) asymptr)->isReady()) //??? { isready = true; //note: m_constSymbol may be NULL; ok in this circumstance (i.e. stub copy). } } return isready; } //assignClassArgValueInStubCopy
const char * NodeBinaryOpCompare::getInverseOpName() { std::ostringstream msg; msg << "virtual const char * " << prettyNodeName().c_str(); msg << "::getInverseOpName(){} is needed!!"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); return NULL; }
bool NodeSquareBracket::getSymbolPtr(Symbol *& symptrref) { if(m_nodeLeft) return m_nodeLeft->getSymbolPtr(symptrref); MSG(getNodeLocationAsString().c_str(), "No symbol", ERR); return false; }
bool NodeMemberSelect::getSymbolPtr(Symbol *& symptrref) { if(m_nodeRight) return m_nodeRight->getSymbolPtr(symptrref); MSG(getNodeLocationAsString().c_str(), "No symbol", ERR); return false; }
// eval() no longer performed before check and label // returns false if error; UNKNOWNSIZE is not an error! bool NodeSquareBracket::getArraysizeInBracket(s32 & rtnArraySize) { bool noerr = true; // since square brackets determine the constant size for this type, else error s32 newarraysize = NONARRAYSIZE; UTI sizetype = m_nodeRight->checkAndLabelType(); if(sizetype == Nav) { rtnArraySize = UNKNOWNSIZE; return true; } UlamType * sizeut = m_state.getUlamTypeByIndex(sizetype); // expects a constant, numeric type within [] if(sizeut->isNumericType() && m_nodeRight->isAConstant()) { evalNodeProlog(0); //new current frame pointer makeRoomForNodeType(sizetype); //offset a constant expression if(m_nodeRight->eval() == NORMAL) { UlamValue arrayUV = m_state.m_nodeEvalStack.popArg(); u32 arraysizedata = arrayUV.getImmediateData(m_state); newarraysize = sizeut->getDataAsCs32(arraysizedata); if(newarraysize < 0 && newarraysize != UNKNOWNSIZE) //NONARRAY or UNKNOWN { MSG(getNodeLocationAsString().c_str(), "Array size specifier in [] is not a positive number", ERR); noerr = false; } //else unknown is not an error } else //newarraysize = UNKNOWNSIZE; //still true noerr = false; evalNodeEpilog(); } else { MSG(getNodeLocationAsString().c_str(), "Array size specifier in [] is not a constant number", ERR); noerr = false; } rtnArraySize = newarraysize; return noerr; } //getArraysizeInBracket
bool NodeMemberSelect::getStorageSymbolPtr(Symbol *& symptrref) { if(m_nodeLeft) return m_nodeLeft->getSymbolPtr(symptrref); //includes quarks, transients MSG(getNodeLocationAsString().c_str(), "No storage symbol", ERR); return false; }
UTI NodeConstant::checkAndLabelType() { UTI it = Nav; bool stubcopy = m_state.isClassAStub(m_state.getCompileThisIdx()); //instantiate, look up in class block; skip if stub copy and already ready. if(!stubcopy && m_constSymbol == NULL) checkForSymbol(); else { stubcopy = m_state.hasClassAStub(m_state.getCompileThisIdx()); //includes ancestors } if(m_constSymbol) { it = m_constSymbol->getUlamTypeIdx(); } else if(isReadyConstant() && stubcopy) { assert(m_state.okUTItoContinue(m_constType)); setNodeType(m_constType); //t3565, t3640, t3641, t3642, t3652 //stub copy case: still wants uti mapping it = NodeTerminal::checkAndLabelType(); } else if(stubcopy) { // still need its symbol for a value // use the member class (unlike checkForSymbol) } // map incomplete UTI if(!m_state.isComplete(it)) //reloads to recheck { std::ostringstream msg; msg << "Incomplete " << prettyNodeName().c_str() << " for type: "; msg << m_state.getUlamTypeNameBriefByIndex(it).c_str(); msg << ", used with constant symbol name '"; msg << m_state.getTokenDataAsString(m_token).c_str() << "'"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT); //wait until updateConstant tried. } setNodeType(it); Node::setStoreIntoAble(TBOOL_FALSE); //copy m_constant from Symbol into NodeTerminal parent. if(!isReadyConstant()) m_ready = updateConstant(); //sets ready here if(!isReadyConstant()) { it = Hzy; if(!stubcopy) m_constSymbol = NULL; //lookup again too! (e.g. inherited template instances) m_state.setGoAgain(); } return it; } //checkAndLabelType
//see also NodeIdent bool NodeSquareBracket::installSymbolVariable(TypeArgs& args, Symbol *& asymptr) { assert(m_nodeLeft && m_nodeRight); if(!m_nodeLeft) { MSG(getNodeLocationAsString().c_str(), "No Identifier to build array symbol", ERR); return false; } if(args.m_arraysize > NONARRAYSIZE) { MSG(getNodeLocationAsString().c_str(), "Array size specified twice", ERR); return false; } args.m_arraysize = UNKNOWNSIZE; // no eval yet return m_nodeLeft->installSymbolVariable(args, asymptr); } //installSymbolVariable
//no atoms, elements as operand bool NodeUnaryOp::checkForPrimitiveType(UTI uti) { if(!m_state.getUlamTypeByIndex(uti)->isPrimitiveType()) { std::ostringstream msg; msg << "Non-primitive type <"; msg << m_state.getUlamTypeNameBriefByIndex(uti).c_str(); msg << "> is not supported for unary "; msg << getName(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); return false; } return checkNotVoidType(uti); } //checkForPrimitiveType
bool NodeUnaryOp::checkNotVoidType(UTI uti) { bool rtnOK = true; ULAMTYPE typEnum = m_state.getUlamTypeByIndex(uti)->getUlamTypeEnum(); if(typEnum == Void) { std::ostringstream msg; msg << "Void is not a supported type for unary "; msg << getName(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); rtnOK = false; } return rtnOK; } //checkNotVoidTypes
bool NodeVarRef::checkReferenceCompatibility(UTI uti) { assert(m_state.okUTItoContinue(uti)); if((!m_state.getUlamTypeByIndex(uti)->isAltRefType())) { std::ostringstream msg; msg << "Variable reference '"; msg << m_state.m_pool.getDataAsString(m_vid).c_str(); msg << "', is invalid"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); return false; } return true; //ok } //checkReferenceCompatibility
void NodeTypedef::printUnresolvedVariableDataMembers() { assert(m_typedefSymbol); UTI it = m_typedefSymbol->getUlamTypeIdx(); if(!m_state.isComplete(it)) { std::ostringstream msg; msg << "Unresolved type <"; msg << m_state.getUlamTypeNameBriefByIndex(it).c_str(); msg << "> used with typedef symbol name '" << getName() << "'"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); setNodeType(Nav); //compiler counts } //not complete } //printUnresolvedVariableDataMembers
void NodeConstant::checkForSymbol() { //in case of a cloned unknown NodeBlock * currBlock = getBlock(); m_state.pushCurrentBlockAndDontUseMemberBlock(currBlock); Symbol * asymptr = NULL; bool hazyKin = false; if(m_state.alreadyDefinedSymbol(m_token.m_dataindex, asymptr, hazyKin)) { if(asymptr->isConstant()) { m_constSymbol = (SymbolConstantValue *) asymptr; } else { std::ostringstream msg; msg << "(1) <" << m_state.getTokenDataAsString(m_token).c_str(); msg << "> is not a constant, and cannot be used as one with class: "; msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); } } else { std::ostringstream msg; msg << "(2) Named Constant <" << m_state.getTokenDataAsString(m_token).c_str(); msg << "> is not defined, and cannot be used with class: "; msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str(); if(!hazyKin) MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); else MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); } m_state.popClassContext(); //restore } //checkForSymbol
bool NodeUnaryOp::checkForNumericType(UTI uti) { bool rtnOK = true; bool isnum = m_state.getUlamTypeByIndex(uti)->isNumericType(); if(!isnum) { std::ostringstream msg; msg << "Incompatible type for unary "; msg << getName() << " : "; msg << m_state.getUlamTypeNameBriefByIndex(uti).c_str(); msg << "; Suggest casting to a numeric type first"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); rtnOK = false; } return rtnOK; } //checkForNumericType
bool NodeUnaryOp::doUnaryOperation(s32 slot, u32 nslots) { UTI nuti = getNodeType(); if(m_state.isScalar(nuti)) //not an array { return doUnaryOperationImmediate(slot, nslots); } else { //arrays not supported at this time std::ostringstream msg; msg << "Unsupported unary operation " << getName(); msg << ", with an array type <"; msg << m_state.getUlamTypeNameBriefByIndex(nuti).c_str() << ">"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); } return false; } //dobinaryop