void NodeVarRefAs::genCodeRefAsSelf(File * fp, UVPass& uvpass) { //no tmpref needed since 'self' (i.e. ur) is already a C++ reference //t3821, t3815 (transient), t3828 (quark) Symbol * stgcos = m_state.m_currentObjSymbolsForCodeGen[0]; UTI vuti = m_varSymbol->getUlamTypeIdx(); UlamType * vut = m_state.getUlamTypeByIndex(vuti); 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(stgcos->getMangledName().c_str()); //stg fp->write(", 0u, "); fp->write(stgcos->getMangledName().c_str()); //stg fp->write(".GetEffectiveSelf()"); fp->write("); //shadows lhs of 'as'"); GCNL; m_state.indentUlamCode(fp); fp->write("UlamRef<EC>& ur = "); fp->write(m_varSymbol->getMangledName().c_str()); fp->write("; //shadows self"); GCNL; m_varSymbol->setIsSelf(); //nope m_state.clearCurrentObjSymbolsForCodeGen(); //clear remnant of lhs } //genCodeRefAsSelf
void NodeAtomof::genCodeToStoreInto(File * fp, UVPass& uvpass) { //lhs, no longer allowed with packed elements assert(getStoreIntoAble() == TBOOL_TRUE); UTI nuti = getNodeType(); //UAtomRef if(m_nodeOf->hasASymbolReference() && (m_state.getUlamTypeByIndex(getOfType())->getUlamClassType() == UC_QUARK)) { Symbol * stgcos = NULL; AssertBool gotstg = m_nodeOf->getStorageSymbolPtr(stgcos); assert(gotstg); m_state.indentUlamCode(fp); fp->write("if("); fp->write(stgcos->getMangledName().c_str()); fp->write(".GetType() == T::ATOM_UNDEFINED_TYPE)"); GCNL; m_state.m_currentIndentLevel++; m_state.indentUlamCode(fp); fp->write("FAIL(NOT_AN_ELEMENT);"); GCNL; m_state.m_currentIndentLevel--; UlamType * nut = m_state.getUlamTypeByIndex(nuti); s32 tmpVarNum = m_state.getNextTmpVarNumber(); //tmp for atomref m_state.indentUlamCode(fp); //non-const fp->write(nut->getLocalStorageTypeAsString().c_str()); //for C++ local vars fp->write(" "); fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum, TMPBITVAL).c_str()); fp->write("("); fp->write(stgcos->getMangledName().c_str()); //ur for self fp->write(", "); //is storage! can't be const (error/t3659) fp->write(" - T::ATOM_FIRST_STATE_BIT"); //must be an effective element ref (e.g.t3684, t3663) fp->write("); //atomof"); GCNL; uvpass = UVPass::makePass(tmpVarNum, TMPBITVAL, nuti, UNPACKED, m_state, uvpass.getPassPos(), uvpass.getPassNameId()); } else { //lhs assert(getStoreIntoAble() == TBOOL_TRUE); assert(m_nodeOf); m_nodeOf->genCodeToStoreInto(fp, uvpass); //does it handle array item members selected? assert(!m_state.m_currentObjSymbolsForCodeGen.empty()); uvpass = UVPass::makePass(uvpass.getPassVarNum(), TMPTATOM, getNodeType(), UNPACKED, m_state, uvpass.getPassPos(), uvpass.getPassNameId()); } } //genCodeToStoreInto
void NodeInstanceof::genCode(File * fp, UVPass& uvpass) { //generates a new instance of.. UTI nuti = getNodeType(); UlamType * nut = m_state.getUlamTypeByIndex(nuti); s32 tmpVarNum = m_state.getNextTmpVarNumber(); //tmp for atomref Symbol * cos = NULL; Symbol * stgcos = NULL; //starts out as its default type; references (UAtom) are updated: m_state.indentUlamCode(fp); //non-const fp->write(nut->getLocalStorageTypeAsString().c_str()); //for C++ local vars fp->write(" "); fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum, TMPBITVAL).c_str()); fp->write(";"); GCNL; // a reference (including 'self'), returns a UAtom of effective type; // SINCE effective self type is known only at runtime. if(m_nodeOf) { m_nodeOf->genCodeToStoreInto(fp, uvpass); assert(!m_state.m_currentObjSymbolsForCodeGen.empty()); cos = m_state.m_currentObjSymbolsForCodeGen.back(); UTI cosuti = cos->getUlamTypeIdx(); stgcos = m_state.m_currentObjSymbolsForCodeGen[0]; bool isself = stgcos->isSelf(); bool issuper = stgcos->isSuper(); bool isaref = m_state.isAltRefType(cosuti) || isself || issuper; if(isaref) { u32 tmpuclass = m_state.getNextTmpVarNumber(); //only for this case m_state.indentUlamCode(fp); fp->write("const UlamClass<EC> * "); fp->write(m_state.getUlamClassTmpVarAsString(tmpuclass).c_str()); fp->write(" = "); fp->write(cos->getMangledName().c_str()); fp->write(".GetEffectiveSelf();"); GCNL; //primitive FAILS m_state.indentUlamCode(fp); fp->write("if("); fp->write(m_state.getUlamClassTmpVarAsString(tmpuclass).c_str()); fp->write(" == NULL) FAIL(ILLEGAL_ARGUMENT); //non-class"); GCNL; //an immediate default quark FAILS m_state.indentUlamCode(fp); fp->write("if("); fp->write(m_state.getUlamClassTmpVarAsString(tmpuclass).c_str()); fp->write("->AsUlamQuark() != NULL) "); fp->write("FAIL(NOT_AN_ELEMENT); //quark"); GCNL; m_state.indentUlamCode(fp); fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum, TMPBITVAL).c_str()); fp->write(".WriteAtom("); fp->write("((UlamElement<EC> *) "); fp->write(m_state.getUlamClassTmpVarAsString(tmpuclass).c_str()); fp->write(")->GetDefaultAtom()); //instanceof default element"); GCNL; } else if(m_state.isAtom(nuti)) { u32 tmpuclass = m_state.getNextTmpVarNumber(); //only for this case m_state.indentUlamCode(fp); fp->write("const UlamClass<EC> * "); fp->write(m_state.getUlamClassTmpVarAsString(tmpuclass).c_str()); fp->write(" = "); fp->write("uc.LookupUlamElementTypeFromContext("); fp->write(cos->getMangledName().c_str()); fp->write(".GetType()"); fp->write(");"); GCNL; m_state.indentUlamCode(fp); fp->write("if("); fp->write(m_state.getUlamClassTmpVarAsString(tmpuclass).c_str()); fp->write(" == NULL) FAIL(ILLEGAL_ARGUMENT); //non-class"); GCNL; m_state.indentUlamCode(fp); fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum, TMPBITVAL).c_str()); fp->write(".WriteAtom("); fp->write("((UlamElement<EC> *) "); fp->write(m_state.getUlamClassTmpVarAsString(tmpuclass).c_str()); fp->write(")->GetDefaultAtom()); //instanceof default element"); GCNL; } } if(m_state.isAtom(nuti)) { // THE READ: s32 tmpVarNum2 = m_state.getNextTmpVarNumber(); //tmp to read into TMPSTORAGE rstor = nut->getTmpStorageTypeForTmpVar(); m_state.indentUlamCode(fp); fp->write("const "); fp->write(nut->getTmpStorageTypeAsString().c_str()); //for C++ local vars fp->write(" "); fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum2, rstor).c_str()); fp->write(" = "); fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum, TMPBITVAL).c_str()); fp->write("."); fp->write("read();"); GCNL; uvpass = UVPass::makePass(tmpVarNum2, rstor, nuti, nut->getPackable(), m_state, 0, cos ? cos->getId() : 0); } else //element and uvpass stays the same (a default immediate element). uvpass = UVPass::makePass(tmpVarNum, TMPBITVAL, nuti, nut->getPackable(), m_state, 0, cos ? cos->getId() : 0); //t3657 m_state.clearCurrentObjSymbolsForCodeGen(); //clear remnant of rhs ? } //genCode
// 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