void NodeCast::genCodeCastAtomAndElement(File * fp, UlamValue & uvpass) { UTI nuti = getNodeType(); UlamType * nut = m_state.getUlamTypeByIndex(nuti); UTI vuti = uvpass.getUlamValueTypeIdx(); s32 tmpVarNum = 0; if(vuti == Ptr) { tmpVarNum = uvpass.getPtrSlotIndex(); vuti = uvpass.getPtrTargetType(); //replace } // "downcast" might not be true; compare to be sure the atom is an element "Foo" if(vuti == UAtom) { m_state.indent(fp); fp->write("if(!"); fp->write(nut->getUlamTypeMangledName().c_str()); fp->write("<EC>::THE_INSTANCE."); fp->write(m_state.getIsMangledFunctionName()); fp->write("("); fp->write(m_state.getTmpVarAsString(vuti, tmpVarNum).c_str()); fp->write("))\n"); m_state.m_currentIndentLevel++; m_state.indent(fp); fp->write("FAIL(BAD_CAST);\n"); m_state.m_currentIndentLevel--; } //update the uvpass to have the casted type uvpass = UlamValue::makePtr(tmpVarNum, uvpass.getPtrStorage(), nuti, m_state.determinePackable(nuti), m_state, 0, uvpass.getPtrNameId()); //POS 0 rightjustified; pass along name id return; } //genCodeCastAtomAndElement
void NodeCast::genCodeCastAtomAndQuark(File * fp, UlamValue & uvpass) { UTI nuti = getNodeType(); //quark tobe UlamType * nut = m_state.getUlamTypeByIndex(nuti); UTI vuti = uvpass.getUlamValueTypeIdx(); if(vuti == Ptr) vuti = uvpass.getPtrTargetType(); //replace m_node->genCodeToStoreInto(fp, uvpass); //No need to load lhs into tmp (T); symbol's in COS vector assert(!m_state.m_currentObjSymbolsForCodeGen.empty()); Symbol * stgcos = NULL; stgcos = m_state.m_currentObjSymbolsForCodeGen[0]; s32 tmpVarPos = m_state.getNextTmpVarNumber(); // "downcast" might not be true; compare to be sure the atom has a quark "Foo" // get signed pos if(vuti == UAtom) { m_state.indent(fp); fp->write("const s32 "); fp->write(m_state.getTmpVarAsString(Int, tmpVarPos).c_str());; fp->write(" = "); //internal method, takes uc, u32 and const char*, returns s32 position fp->write(m_state.getHasMangledFunctionName(vuti)); fp->write("("); fp->write("uc, "); Node::genLocalMemberNameOfMethod(fp); //assume atom is a local var (neither dm nor ep) if(stgcos->isSelf()) fp->write("GetType(), "); //no read for self else fp->write("read().GetType(), "); fp->write("\""); fp->write(nut->getUlamTypeMangledName().c_str()); fp->write("\");\n"); //keeping pos in tmp } else { UlamType* vut = m_state.getUlamTypeByIndex(vuti); if(vut->getUlamClass() == UC_ELEMENT) { m_state.indent(fp); fp->write("const s32 "); fp->write(m_state.getTmpVarAsString(Int, tmpVarPos).c_str());; fp->write(" = "); //internal method, takes uc, u32 and const char*, returns s32 position fp->write(vut->getUlamTypeMangledName().c_str()); fp->write("<EC>::"); fp->write(m_state.getHasMangledFunctionName(vuti)); fp->write("(\""); fp->write(nut->getUlamTypeMangledName().c_str()); fp->write("\");\n"); //keeping pos in tmp } else { //e.g. a quark here would be wrong std::ostringstream msg; msg << "Casting 'incomplete' types "; msg << m_state.getUlamTypeNameBriefByIndex(nuti).c_str(); msg << " to be "; msg << m_state.getUlamTypeNameBriefByIndex(vuti).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); assert(0);//return; } } m_state.indent(fp); fp->write("if("); fp->write(m_state.getTmpVarAsString(Int, tmpVarPos).c_str()); fp->write(" < 0)\n"); m_state.m_currentIndentLevel++; m_state.indent(fp); fp->write("FAIL(BAD_CAST);\n\n"); m_state.m_currentIndentLevel--; //informed by genCodedAutoLocal() in NodeVarDecl used for conditional-as // uses stgcos since there's no m_varSymbol in this situation. s32 tmpVarStg = m_state.getNextTmpVarNumber(); UTI stguti = stgcos->getUlamTypeIdx(); UlamType * stgut = m_state.getUlamTypeByIndex(stguti); assert(stguti == UAtom || stgut->getUlamClass() == UC_ELEMENT); // can't let Node::genCodeReadIntoTmpVar do this for us (we need a ref!): assert(m_state.m_currentObjSymbolsForCodeGen.size() == 1); m_state.indent(fp); // no const here fp->write(stgut->getTmpStorageTypeAsString().c_str()); fp->write("& "); fp->write(m_state.getTmpVarAsString(stguti, tmpVarStg, TMPBITVAL).c_str()); fp->write(" = "); fp->write(stgcos->getMangledName().c_str()); if(!stgcos->isSelf()) fp->write(".getRef()"); fp->write("; //ref needed\n"); // now we have our pos in tmpVarPos, and our T in tmpVarStg // time to (like a) "shadow 'self'" with auto local variable: m_state.indent(fp); fp->write(nut->getUlamTypeImmediateAutoMangledName().c_str()); //for C++ local vars, ie non-data members fp->write("<EC> "); s32 tmpIQ = m_state.getNextTmpVarNumber(); //tmp since no variable name fp->write(m_state.getTmpVarAsString(nuti, tmpIQ).c_str()); fp->write("("); fp->write(m_state.getTmpVarAsString(stguti, tmpVarStg, TMPBITVAL).c_str()); //for known quark: fp->write(", "); fp->write(m_state.getTmpVarAsString(Int, tmpVarPos).c_str()); fp->write(");\n"); //like, shadow lhs of as //update the uvpass to have the casted immediate quark uvpass = UlamValue::makePtr(tmpIQ, uvpass.getPtrStorage(), nuti, m_state.determinePackable(nuti), m_state, 0); //POS 0 rightjustified; m_state.m_currentObjSymbolsForCodeGen.clear(); //clear remnant of lhs } //genCodeCastAtomAndQuark
EvalStatus NodeSquareBracket::evalToStoreInto() { assert(m_nodeLeft && m_nodeRight); UTI nuti = getNodeType(); if(nuti == Nav) return ERROR; evalNodeProlog(0); //new current frame pointer makeRoomForSlots(1); //always 1 slot for ptr EvalStatus evs = m_nodeLeft->evalToStoreInto(); if(evs != NORMAL) { evalNodeEpilog(); return evs; } UlamValue pluv = m_state.m_nodeEvalStack.popArg(); makeRoomForNodeType(m_nodeRight->getNodeType()); //offset a constant expression evs = m_nodeRight->eval(); if(evs != NORMAL) { evalNodeEpilog(); return evs; } UlamValue offset = m_state.m_nodeEvalStack.popArg(); // constant expression only required for array declaration u32 offsetdata = offset.getImmediateData(m_state); s32 offsetInt = m_state.getUlamTypeByIndex(offset.getUlamValueTypeIdx())->getDataAsCs32(offsetdata); UTI auti = pluv.getPtrTargetType(); UlamType * aut = m_state.getUlamTypeByIndex(auti); if(aut->isCustomArray()) { UTI caType = ((UlamTypeClass *) aut)->getCustomArrayType(); UlamType * caut = m_state.getUlamTypeByIndex(caType); u32 pos = pluv.getPtrPos(); if(caut->getBitSize() > MAXBITSPERINT) pos = 0; // itemUV = UlamValue::makeAtom(caType); //else // itemUV = UlamValue::makeImmediate(caType, 0, m_state); //quietly skip for now XXX //use CA type, not the left ident's type UlamValue scalarPtr = UlamValue::makePtr(pluv.getPtrSlotIndex(), pluv.getPtrStorage(), caType, m_state.determinePackable(caType), //PACKEDLOADABLE m_state, pos /* base pos of array */ ); //copy result UV to stack, -1 relative to current frame pointer assignReturnValuePtrToStack(scalarPtr); } else { //adjust pos by offset * len, according to its scalar type UlamValue scalarPtr = UlamValue::makeScalarPtr(pluv, m_state); if(scalarPtr.incrementPtr(m_state, offsetInt)) //copy result UV to stack, -1 relative to current frame pointer assignReturnValuePtrToStack(scalarPtr); else { s32 arraysize = m_state.getArraySize(pluv.getPtrTargetType()); Symbol * lsymptr; u32 lid = 0; if(getSymbolPtr(lsymptr)) lid = lsymptr->getId(); std::ostringstream msg; msg << "Array subscript [" << offsetInt << "] exceeds the size (" << arraysize; msg << ") of array '" << m_state.m_pool.getDataAsString(lid).c_str() << "'"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); evs = ERROR; } } evalNodeEpilog(); return evs; } //evalToStoreInto