UlamValue NodeInstanceof::makeUlamValuePtr() { // (from NodeVarDecl's makeUlamValuePtr) UlamValue ptr; UlamValue atomuv; UTI auti = getOfType(); UlamType * aut = m_state.getUlamTypeByIndex(auti); ULAMCLASSTYPE aclasstype = aut->getUlamClassType(); u32 atop = 1; atop = m_state.m_funcCallStack.getAbsoluteStackIndexOfSlot(atop); if(m_state.isAtom(auti)) atomuv = UlamValue::makeAtom(auti); else if(aclasstype == UC_ELEMENT) atomuv = UlamValue::makeDefaultAtom(auti, m_state); else if(aclasstype == UC_QUARK) { u32 dq = 0; AssertBool isDefinedQuark = m_state.getDefaultQuark(auti, dq); //returns scalar dq assert(isDefinedQuark); atomuv = UlamValue::makeImmediateClass(auti, dq, aut->getTotalBitSize()); } else if(aclasstype == UC_TRANSIENT) atomuv = UlamValue::makeDefaultAtom(auti, m_state); //size limited to atom for eval else m_state.abortUndefinedUlamClassType(); m_state.m_funcCallStack.storeUlamValueAtStackIndex(atomuv, atop); //stackframeslotindex ? ptr = UlamValue::makePtr(atop, STACK, auti, m_state.determinePackable(auti), m_state, 0); ptr.setUlamValueTypeIdx(PtrAbs); return ptr; } //makeUlamValuePtr
// replaced by NodeVarDecl:genCode to leverage the declaration order preserved by the parse tree. void SymbolVariableDataMember::generateCodedVariableDeclarations(File * fp, ULAMCLASSTYPE classtype) { assert(classtype == UC_ELEMENT); //really? UTI vuti = getUlamTypeIdx(); UlamType * vut = m_state.getUlamTypeByIndex(vuti); ULAMCLASSTYPE vclasstype = vut->getUlamClassType(); m_state.indentUlamCode(fp); fp->write(vut->getUlamTypeMangledName().c_str()); //for C++ if(vclasstype == UC_QUARK) //called on classtype elements only { fp->write("<"); fp->write_decimal(getPosOffset()); fp->write(">"); } fp->write(" "); fp->write(getMangledName().c_str()); #if 0 s32 arraysize = vut->getArraySize(); if(arraysize > NONARRAYSIZE) { fp->write("["); fp->write_decimal(arraysize); fp->write("]"); } else if(arraysize == UNKNOWNSIZE) { fp->write("[UNKNOWN]"); } #endif fp->write(";"); GCNL; } //generateCodedVariableDeclarations
EvalStatus NodeVarRefAs::eval() { assert(m_varSymbol); UTI nuti = getNodeType(); if(nuti == Nav) return ERROR; if(nuti == Hzy) return NOTREADY; assert(m_varSymbol->getUlamTypeIdx() == nuti); assert(!m_state.isAtom(nuti)); //rhs type of conditional as/has can't be an atom UlamValue pluv = m_state.m_currentAutoObjPtr; ((SymbolVariableStack *) m_varSymbol)->setAutoPtrForEval(pluv); //for future ident eval uses UTI luti = pluv.getPtrTargetType(); assert(m_state.okUTItoContinue(luti)); UlamType * lut = m_state.getUlamTypeByIndex(luti); ULAMCLASSTYPE lclasstype = lut->getUlamClassType(); UTI autostgtype = m_state.m_currentAutoStorageType; if((UlamType::compare(autostgtype, UAtom, m_state) == UTIC_SAME) && (lclasstype == UC_ELEMENT)) autostgtype = luti; //e.g. funccall expects a class, not an atom (t3636) ((SymbolVariableStack *) m_varSymbol)->setAutoStorageTypeForEval(autostgtype); //for future virtual function call eval uses //m_state.m_funcCallStack.storeUlamValueInSlot(pluv, ((SymbolVariableStack *) m_varSymbol)->getStackFrameSlotIndex()); //doesn't seem to matter.. return NORMAL; } //eval
FORECAST UlamTypePrimitive::explicitlyCastable(UTI typidx) { FORECAST scr = UlamType::safeCast(typidx); //default if(scr == CAST_CLEAR) { // primitives must be the same sizes when casting to a reference type if(isReference() && !UlamType::checkReferenceCast(typidx)) scr = CAST_BAD; // strings cannot be cast explicitly to other primitive types, except Void (t3961) UlamType * vut = m_state.getUlamTypeByIndex(typidx); ULAMTYPE valtypEnum = vut->getUlamTypeEnum(); if((getUlamTypeEnum() != Void) && ((valtypEnum == String) ^ (getUlamTypeEnum() == String))) scr = CAST_BAD; //only quarks may be cast to Ints, explicitly or not; requires toInt method (t3996) if(valtypEnum == Class) { ULAMCLASSTYPE vclasstype = vut->getUlamClassType(); if(vclasstype != UC_QUARK) scr = CAST_BAD; } } return scr; } //explicitlyCastable
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 NodeAtomof::checkAndLabelType() { assert(m_nodeOf); //Identifier, not a Type; caught at parse time (right?) UTI nuti = NodeStorageof::checkAndLabelType(); if(m_state.okUTItoContinue(nuti)) { UTI vuti = m_nodeOf->getNodeType(); bool isself = m_nodeOf->hasASymbolSelf(); bool isaref = m_state.isReference(vuti); //t3706, t41046 (not isAltRefType) UTI oftype = NodeStorageof::getOfType(); UlamType * ofut = m_state.getUlamTypeByIndex(oftype); assert(isself || UlamType::compare(m_state.getUlamTypeAsDeref(vuti), oftype, m_state) == UTIC_SAME); //sanity (e.g. t3905, t3701) ULAMCLASSTYPE ofclasstype = ofut->getUlamClassType(); //refs checked at runtime; non-refs here: if(!isaref && !isself) { //only an element or atom have real storage (ie. not quarks) if(ofclasstype == UC_QUARK) { //only way to get storage for a quark is if its a DM // of an element; if(!m_nodeOf->hasASymbolDataMember()) { std::ostringstream msg; msg << "<" << m_nodeOf->getName(); msg << "> is a quark and cannot be used with "; msg << getName() << "; try a reference or self"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); setNodeType(Nav); } else { //quark dm, must find an element or ele-ref in m_nodeOf, o.w. error // (can't be an atom dm, and transients are illegal for atomof, !isself) // lose the quark. (t3906) if(!trimToTheElement(NULL, m_nodeOf)) setNodeType(Nav); else setOfType(m_nodeOf->getNodeType()); } } else if(ofclasstype == UC_TRANSIENT) { std::ostringstream msg; msg << "<" << m_nodeOf->getName(); msg << "> is a transient"; msg << "; Transients cannot be used with " << getName(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); setNodeType(Nav); //e.g. error/t3761 } //else element (or atom) ok! } //neither a ref nor isself (done at compile time) else if(ofclasstype == UC_TRANSIENT) { std::ostringstream msg; msg << "<" << m_nodeOf->getName(); msg << "> is a transient reference"; msg << "; Transients cannot be used with " << getName(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); setNodeType(Nav); //e.g. error/t3762 } else if(ofclasstype == UC_QUARK) { //either a quark ref (runtime), or isself; if self, trim to self (t3905) if(isself && trimToTheElement(NULL, m_nodeOf)) setOfType(m_nodeOf->getNodeType()); } //else element (or atom) is clear to go } return getNodeType(); //UAtomRef (storeintoable) } //checkAndLabelType
UlamValue NodeAtomof::makeUlamValuePtr() { // (from NodeVarDecl's makeUlamValuePtr) UlamValue ptr; UlamValue atomuv; UTI auti = getOfType(); assert(m_nodeOf); if(m_nodeOf->hasASymbolSelf()) { //when "self/atom" is a quark, we're inside a func called on a quark (e.g. dm or local) //'atom' gets entire atom/element containing this quark; including its type! //'self' gets type/pos/len of the quark from which 'atom' can be extracted UlamValue selfuvp = m_state.m_currentSelfPtr; UTI ttype = selfuvp.getPtrTargetType(); assert(m_state.okUTItoContinue(ttype)); if((m_state.getUlamTypeByIndex(ttype)->getUlamClassType() == UC_QUARK)) { selfuvp = atomuv; //bail for error } return selfuvp; } //done if(m_state.getReferenceType(auti) == ALT_AS) { assert(0); Symbol * vsym = NULL; m_nodeOf->getSymbolPtr(vsym); return ((SymbolVariableStack *) vsym)->getAutoPtrForEval(); //haha! we're done. } if(m_nodeOf->hasASymbolDataMember()) { UTI cuti = m_state.m_currentObjPtr.getPtrTargetType(); UlamType * cut = m_state.getUlamTypeByIndex(cuti); if(cut->getUlamClassType() == UC_QUARK) ptr = atomuv; //bail else { // return ptr to the m_currentObjPtr that contains this data member within ptr = UlamValue::makePtr(m_state.m_currentObjPtr.getPtrSlotIndex(), m_state.m_currentObjPtr.getPtrStorage(), auti, m_state.determinePackable(getNodeType()), m_state, 0, 0); //id? ptr.checkForAbsolutePtr(m_state.m_currentObjPtr); } } else { UTI vuti = getOfType(); UlamType * vut = m_state.getUlamTypeByIndex(vuti); if(vut->getUlamClassType() == UC_QUARK) ptr = atomuv; //bail else { //local variable on the stack; could be array ptr! Symbol * vsym = NULL; m_nodeOf->getSymbolPtr(vsym); ptr = UlamValue::makePtr(((SymbolVariableStack *) vsym)->getStackFrameSlotIndex(), STACK, auti, m_state.determinePackable(vuti), m_state, 0, vsym->getId()); //id? } } return ptr; } //makeUlamValuePtr
FORECAST NodeVarRef::safeToCastTo(UTI newType) { assert(m_nodeInitExpr); UTI nuti = getNodeType(); //cast RHS if necessary and safe //insure lval is same bitsize/arraysize // if classes, safe to cast a subclass to any of its superclasses FORECAST rscr = CAST_CLEAR; if(UlamType::compare(nuti, newType, m_state) != UTIC_SAME) { UlamType * nut = m_state.getUlamTypeByIndex(nuti); UlamType * newt = m_state.getUlamTypeByIndex(newType); rscr = m_nodeInitExpr->safeToCastTo(nuti); if((nut->getUlamTypeEnum() == Class)) { if(rscr != CAST_CLEAR) { //e.g. error/t3792, error/t3616 std::ostringstream msg; msg << "Incompatible class types "; msg << nut->getUlamTypeClassNameBrief(nuti).c_str(); msg << " and "; msg << m_state.getUlamTypeNameBriefByIndex(newType).c_str(); msg << " used to initialize reference '" << getName() <<"'"; if(rscr == CAST_HAZY) MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); else MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); } } else if(m_state.isAtom(nuti)) { //atoms init from a quark ref could use .atomof // "clear" when complete, not the same as "bad". if(rscr != CAST_CLEAR) { std::ostringstream msg; msg << "Reference atom variable " << getName() << "'s type "; msg << nut->getUlamTypeNameBrief().c_str(); msg << ", and its initial value type "; msg << m_state.getUlamTypeNameBriefByIndex(newType).c_str(); msg << ", are incompatible"; if(newt->isAltRefType() && newt->getUlamClassType() == UC_QUARK) msg << "; .atomof may help"; if(rscr == CAST_HAZY) MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); else MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); } } else { //primitives must be EXACTLY the same size (for initialization); // "clear" when complete, not the same as "bad". (t3614, t3694) if(rscr != CAST_CLEAR) { std::ostringstream msg; msg << "Reference variable " << getName() << "'s type "; msg << m_state.getUlamTypeNameBriefByIndex(nuti).c_str(); msg << ", and its initial value type "; msg << m_state.getUlamTypeNameBriefByIndex(newType).c_str(); msg << ", are incompatible"; if(rscr == CAST_HAZY) MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); else MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); } else if(m_nodeInitExpr->isAConstant() && !m_state.isConstantRefType(nuti)) { std::ostringstream msg; msg << "Initial value of non-constant reference variable: " << getName(); msg << " is constant"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); //error/t41255 rscr = CAST_BAD; } } } //okay to explicitly cast rhs to reference type, e.g. if(a is Foo) QW& qref = (Foo &) a; return rscr; } //safeToCastTo
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
// this is the auto local variable's node, created at parse time, // for Conditional-As case. void NodeVarRefAs::genCode(File * fp, UVPass & uvpass) { assert(!m_state.m_currentObjSymbolsForCodeGen.empty()); // the uvpass comes from NodeControl, and still has the POS obtained // during the condition statement for As..unorthodox, but necessary. // before shadowing the lhs of the h/as-conditional variable with its auto, // let's load its storage from the currentSelfSymbol: Symbol * stgcos = m_state.m_currentObjSymbolsForCodeGen[0]; UTI stgcosuti = stgcos->getUlamTypeIdx(); UlamType * stgcosut = m_state.getUlamTypeByIndex(stgcosuti); ULAMTYPE stgetyp = stgcosut->getUlamTypeEnum(); ULAMCLASSTYPE stgclasstype = stgcosut->getUlamClassType(); assert((stgetyp == UAtom) || (stgetyp == Class)); //lhs if(stgcos->isSelf()) return genCodeRefAsSelf(fp, uvpass); s32 tmpVarStg = m_state.getNextTmpVarNumber(); // can't let Node::genCodeReadIntoTmpVar do this for us: need a ref. assert(m_state.m_currentObjSymbolsForCodeGen.size() == 1); m_state.indentUlamCode(fp); fp->write(stgcosut->getUlamTypeImmediateMangledName().c_str()); fp->write("<EC> & "); //here it is!! brilliant fp->write(m_state.getTmpVarAsString(stgcosuti, tmpVarStg, TMPBITVAL).c_str()); fp->write(" = "); fp->write(stgcos->getMangledName().c_str()); fp->write("; //c++ reference to immediate"); GCNL; // now we have our pos in tmpVarPos, and our T in tmpVarStg // time to shadow 'self' with auto local variable: UTI vuti = m_varSymbol->getUlamTypeIdx(); UlamType * vut = m_state.getUlamTypeByIndex(vuti); ULAMCLASSTYPE vclasstype = vut->getUlamClassType(); m_state.indentUlamCode(fp); fp->write(vut->getLocalStorageTypeAsString().c_str()); //for C++ local vars, ie non-data members fp->write(" "); fp->write(m_varSymbol->getMangledName().c_str()); fp->write("("); fp->write(m_state.getTmpVarAsString(stgcosuti, tmpVarStg, TMPBITVAL).c_str()); if(stgetyp == UAtom) { fp->write(", 0u + T::ATOM_FIRST_STATE_BIT, "); //position as super quark (e.g. t3639, t3709, t3675, t3408, t3336); as element t3249, t3255, t3637; as atom ref t3908 //note: needs effective self of the atom, not simply the RHS type. fp->write(m_state.getHiddenContextArgName()); fp->write(".LookupUlamElementTypeFromContext("); fp->write(m_state.getTmpVarAsString(stgcosuti, tmpVarStg, TMPBITVAL).c_str()); //t3636 fp->write(".GetType())"); if(vclasstype == UC_QUARK) fp->write(", UlamRef<EC>::ELEMENTAL"); //becomes elemental, t3835 } else if((stgclasstype == UC_ELEMENT)) { if(stgcosut->isReference()) { fp->write(", 0u, "); //t3655 fp->write(stgcos->getMangledName().c_str()); //stg fp->write(".GetEffectiveSelf()"); //Sat Jun 18 17:30:20 2016 } else { fp->write(", 0u + T::ATOM_FIRST_STATE_BIT, &"); //t3586, t3589, t3637 //must be same as look up for elements only Sat Jun 18 17:30:17 2016 fp->write(m_state.getTheInstanceMangledNameByIndex(stgcosuti).c_str()); } if(vclasstype == UC_QUARK) fp->write(", UlamRef<EC>::ELEMENTAL"); //stays elemental } else if((stgclasstype == UC_TRANSIENT)) { // transient can be another transient or a quark, not an element fp->write(", 0u, "); if(stgcosut->isReference()) { fp->write(stgcos->getMangledName().c_str()); //stg fp->write(".GetEffectiveSelf()"); //t3824 } else { fp->write("&"); //t3822 fp->write(m_state.getTheInstanceMangledNameByIndex(stgcosuti).c_str()); } if(vclasstype == UC_QUARK) fp->write(", UlamRef<EC>::CLASSIC"); //stays classic } else if((stgclasstype == UC_QUARK)) { // quark can be another quark, not an element, nor transient fp->write(", 0u, "); if(stgcosut->isReference()) { fp->write(stgcos->getMangledName().c_str()); //stg fp->write(".GetEffectiveSelf()"); //tt3829 } else { fp->write("&"); //t3830 fp->write(m_state.getTheInstanceMangledNameByIndex(stgcosuti).c_str()); } assert(vclasstype == UC_QUARK); fp->write(", UlamRef<EC>::CLASSIC"); //stays classic } else m_state.abortUndefinedUlamClassType(); //WHAT THEN??? if(!stgcosut->isReference()) fp->write(", uc"); //t3249 fp->write("); //shadows lhs of 'as'"); GCNL; m_state.clearCurrentObjSymbolsForCodeGen(); //clear remnant of lhs ? } //genCode
// replaces NodeVarDecl:printPostfix to learn the values of Class' storage in center site void SymbolVariableDataMember::printPostfixValuesOfVariableDeclarations(File * fp, s32 slot, u32 startpos, ULAMCLASSTYPE classtype) { UTI vuti = getUlamTypeIdx(); UlamKeyTypeSignature vkey = m_state.getUlamKeyTypeSignatureByIndex(vuti); UlamType * vut = m_state.getUlamTypeByIndex(vuti); ULAMCLASSTYPE vclasstype = vut->getUlamClassType(); ULAMTYPE vetyp = vut->getUlamTypeEnum(); fp->write(" "); if(vclasstype == UC_NOTACLASS) fp->write(vkey.getUlamKeyTypeSignatureNameAndBitSize(&m_state).c_str()); else fp->write(vut->getUlamTypeNameBrief().c_str()); fp->write(" "); fp->write(m_state.m_pool.getDataAsString(getId()).c_str()); s32 arraysize = m_state.getArraySize(vuti); //scalar has 'size=1'; empty array [0] is still '0'. s32 size = (arraysize > NONARRAYSIZE ? arraysize : 1); //output the arraysize (optional), and open paren if(arraysize > NONARRAYSIZE) { fp->write("["); fp->write_decimal(arraysize); fp->write("]"); } else if(arraysize == UNKNOWNSIZE) { fp->write("[UNKNOWN]"); } fp->write("("); if(vclasstype == UC_QUARK) { //outputs the data members, not just the lump value (e.g. SWV::printPostfixValue()) UTI scalarquark = m_state.getUlamTypeAsScalar(vuti); //printPostfixValuesForClass: SymbolClass * csym = NULL; AssertBool isDefined = m_state.alreadyDefinedSymbolClass(scalarquark, csym); assert(isDefined); NodeBlockClass * classNode = csym->getClassBlockNode(); assert(classNode); u32 newstartpos = startpos + getPosOffset(); s32 len = vut->getBitSize(); for(s32 i = 0; i < size; i++) classNode->printPostfixDataMembersSymbols(fp, slot, newstartpos + len * i, vclasstype); } else { PACKFIT packFit = m_state.determinePackable(vuti); assert(WritePacked(packFit)); //has to be to fit in an atom/site; char * valstr = new char[size * 8 + MAXBITSPERLONG]; //was 32 if(size > 0) { //build the string of values (for both scalar and packed array) UlamValue arrayPtr = UlamValue::makePtr(slot, EVENTWINDOW, vuti, packFit, m_state, startpos + getPosOffset(), getId()); UlamValue nextPtr = UlamValue::makeScalarPtr(arrayPtr, m_state); UlamValue atval = m_state.getPtrTarget(nextPtr); s32 len = m_state.getBitSize(vuti); if(len == UNKNOWNSIZE) { sprintf(valstr,"unknown"); for(s32 i = 1; i < size; i++) { strcat(valstr,", unknown"); } } else if(len <= MAXBITSPERINT) { u32 data = atval.getDataFromAtom(nextPtr, m_state); vut->getDataAsString(data, valstr, 'z'); //'z' -> no preceeding ',' if(vetyp == Unsigned || vetyp == Unary) strcat(valstr, "u"); for(s32 i = 1; i < size; i++) { char tmpstr[8]; AssertBool isNext = nextPtr.incrementPtr(m_state); assert(isNext); atval = m_state.getPtrTarget(nextPtr); data = atval.getDataFromAtom(nextPtr, m_state); vut->getDataAsString(data, tmpstr, ','); if(vetyp == Unsigned || vetyp == Unary) strcat(tmpstr, "u"); strcat(valstr,tmpstr); } } else if(len <= MAXBITSPERLONG) { u64 data = atval.getDataLongFromAtom(nextPtr, m_state); vut->getDataLongAsString(data, valstr, 'z'); //'z' -> no preceeding ',' if(vetyp == Unsigned || vetyp == Unary) strcat(valstr, "u"); for(s32 i = 1; i < size; i++) { char tmpstr[8]; AssertBool isNext = nextPtr.incrementPtr(m_state); assert(isNext); atval = m_state.getPtrTarget(nextPtr); data = atval.getDataLongFromAtom(nextPtr, m_state); vut->getDataLongAsString(data, tmpstr, ','); if(vetyp == Unsigned || vetyp == Unary) strcat(tmpstr, "u"); strcat(valstr,tmpstr); } } else assert(0); } //end arrays > 0, and scalar else { sprintf(valstr," "); } fp->write(valstr); //results out here! delete [] valstr; } //not a quark fp->write("); "); } //printPostfixValuesOfVariableDeclarations
UTI NodeMemberSelect::checkAndLabelType() { assert(m_nodeLeft && m_nodeRight); UTI luti = m_nodeLeft->checkAndLabelType(); //side-effect TBOOL lstor = m_nodeLeft->getStoreIntoAble(); if(lstor != TBOOL_TRUE) { //e.g. funcCall is not storeintoable even if its return value is. std::ostringstream msg; msg << "Member selected must be a valid lefthand side: '"; msg << m_nodeLeft->getName(); msg << "' requires a variable; may be a casted function call"; if(lstor == TBOOL_HAZY) { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT); setNodeType(Hzy); m_state.setGoAgain(); return Hzy; } else { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); setNodeType(Nav); return Nav; } } //done if(!m_state.isComplete(luti)) { std::ostringstream msg; msg << "Member selected is incomplete class: "; msg << m_state.getUlamTypeNameBriefByIndex(luti).c_str(); msg << ", check and label fails this time around"; if(luti == Nav) { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); setNodeType(Nav); } else { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT); setNodeType(Hzy); m_state.setGoAgain(); //since no error msg } return getNodeType(); } //done UlamType * lut = m_state.getUlamTypeByIndex(luti); ULAMCLASSTYPE classtype = lut->getUlamClassType(); if(((classtype == UC_NOTACLASS) && (lut->getUlamTypeEnum() != Holder)) || !lut->isScalar()) { // must be a scalar 'Class' type, (e.g. error/t3815) // doesn't complete checkandlabel for rhs (e.g. funccall is NULL, no eval) std::ostringstream msg; msg << "Member selected must be a Class, not type: "; msg << m_state.getUlamTypeNameBriefByIndex(luti).c_str(); if(classtype != UC_NOTACLASS) msg << "[" << lut->getArraySize() << "]"; if(m_state.isAtom(luti)) msg << "; suggest using a Conditional-As"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); setNodeType(Nav); return Nav; } //done std::string className = m_state.getUlamTypeNameBriefByIndex(luti); //help me debug SymbolClass * csym = NULL; AssertBool isDefined = m_state.alreadyDefinedSymbolClass(luti, csym); assert(isDefined); NodeBlockClass * memberClassNode = csym->getClassBlockNode(); assert(memberClassNode); //e.g. forgot the closing brace on quark definition assert(m_state.okUTItoContinue(memberClassNode->getNodeType())); //t41010 //set up compiler state to use the member class block for symbol searches m_state.pushClassContextUsingMemberClassBlock(memberClassNode); UTI rightType = m_nodeRight->checkAndLabelType(); //clear up compiler state to no longer use the member class block for symbol searches m_state.popClassContext(); setNodeType(rightType); //set Nav if error (t3513) if(m_state.okUTItoContinue(rightType)) { //based on righthand side Node::setStoreIntoAble(m_nodeRight->getStoreIntoAble()); //base reference-ability on righthand side (t41085) Node::setReferenceAble(m_nodeRight->getReferenceAble()); } return getNodeType(); } //checkAndLabelType