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
void NodeStatements::genCode(File * fp, UVPass& uvpass) { Locator nodeloc = getNodeLocation(); m_state.outputTextAsCommentWithLocationUpdate(fp, nodeloc); m_node->genCode(fp, uvpass); if(m_nodeNext) m_nodeNext->genCode(fp, uvpass); } //genCode
void NodeBlockLocals::addTargetDescriptionToInfoMap(TargetMap& classtargets, u32 scid) { UTI cuti = getNodeType(); u32 classNameId = m_state.getClassNameIdForUlamLocalsFilescope(cuti); //cut->getUlamTypeNameOnly(); std::string className = m_state.m_pool.getDataAsString(classNameId); u32 mangledNameId = m_state.getMangledClassNameIdForUlamLocalsFilescope(cuti); //cut->getUlamTypeMangledName(); std::string mangledName = m_state.m_pool.getDataAsString(mangledNameId); struct TargetDesc desc; desc.m_hasTest = false; desc.m_classType = UC_LOCALSFILESCOPE; desc.m_bitsize = 0; desc.m_loc = getNodeLocation(); desc.m_className = className; desc.m_structuredComment = "NONE"; classtargets.insert(std::pair<std::string, struct TargetDesc>(mangledName, desc)); } //addTargetDescriptionToInfoMap
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(newType != Nav && 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); nuti = m_state.makeUlamType(tokey, typEnum); if(UlamType::compare(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 = new NodeCast(this, nuti, NULL, m_state); assert(castNode); castNode->setNodeLocation(getNodeLocation()); Node * parentNode = m_state.findNodeNoInThisClass(pno); assert(parentNode); assert(parentNode->exchangeKids(this, castNode)); 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
void NodeStatements::genCode(File * fp, UlamValue& uvpass) { Locator nodeloc = getNodeLocation(); m_state.outputTextAsComment(fp, nodeloc); m_state.m_locOfNextLineText = nodeloc; //during gen code here #ifdef TMPVARBRACES m_state.indent(fp); fp->write("{\n"); //open for tmpvar arg's m_state.m_currentIndentLevel++; #endif m_node->genCode(fp, uvpass); #ifdef TMPVARBRACES m_state.m_currentIndentLevel--; m_state.indent(fp); fp->write("}\n"); //close for tmpVar #endif if(m_nodeNext) m_nodeNext->genCode(fp, uvpass); } //genCode
UTI NodeUnaryOp::constantFold() { u64 val = U64_MAX; UTI nuti = getNodeType(); if(nuti == Nav) return Nav; //nothing to do yet //if(nuti == Hzy) return Hzy; //nothing to do yet TRY? // if here, must be a constant.. assert(isAConstant()); NNO pno = Node::getYourParentNo(); assert(pno); Node * parentNode = m_state.findNodeNoInThisClassForParent(pno); //t3767 assert(parentNode); evalNodeProlog(0); //new current frame pointer makeRoomForNodeType(nuti); //offset a constant expression EvalStatus evs = eval(); if( evs == NORMAL) { UlamValue cnstUV = m_state.m_nodeEvalStack.popArg(); u32 wordsize = m_state.getTotalWordSize(nuti); if(wordsize <= MAXBITSPERINT) val = cnstUV.getImmediateData(m_state); else if(wordsize <= MAXBITSPERLONG) val = cnstUV.getImmediateDataLong(m_state); else m_state.abortGreaterThanMaxBitsPerLong(); } evalNodeEpilog(); if(evs == ERROR) { std::ostringstream msg; msg << "Constant value expression for unary op" << getName(); msg << " is erroneous while compiling class: "; msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); setNodeType(Nav); return Nav; } if(evs == NOTREADY) { std::ostringstream msg; msg << "Constant value expression for unary op" << getName(); msg << " is not yet ready while compiling class: "; msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT); setNodeType(Hzy); m_state.setGoAgain(); //for compiler counts return Hzy; } //replace ourselves (and kids) with a node terminal; new NNO unlike template's NodeTerminal * newnode = new NodeTerminal(val, nuti, m_state); assert(newnode); newnode->setNodeLocation(getNodeLocation()); AssertBool swapOk = parentNode->exchangeKids(this, newnode); assert(swapOk); std::ostringstream msg; msg << "Exchanged kids! for unary " << getName(); msg << ", with a constant == " << newnode->getName(); msg << " while compiling class: "; msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); newnode->setYourParentNo(pno); newnode->resetNodeNo(getNodeNo()); delete this; //suicide is painless.. return newnode->checkAndLabelType(); } //constantFold
Node * NodeBinaryOpCompare::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_nodeLeft->getNodeType()).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); return NULL; } identTok.init(TOK_IDENTIFIER, getNodeLocation(), opolId); //may need to negate the opposite comparison, if this one isn't defined (t41109) UTI luti = m_nodeLeft->getNodeType(); 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())); //set up compiler state to use the member class block for symbol searches m_state.pushClassContextUsingMemberClassBlock(memberClassNode); Symbol * fnsymptr = NULL; bool hazyKin = false; //unused bool useInverseOp = false; if(!m_state.isFuncIdInClassScope(opolId, fnsymptr, hazyKin)) { //try inverse! const char * invopname = getInverseOpName(); if(!invopname) return NULL; //built-in error msg opTokType = Token::getTokenTypeFromString(invopname); assert(opTokType != TOK_LAST_ONE); opTok.init(opTokType, getNodeLocation(), 0); opolId = Token::getOperatorOverloadFullNameId(opTok, &m_state); assert(opolId != 0); if(!m_state.isFuncIdInClassScope(opolId, fnsymptr, hazyKin)) { std::ostringstream msg; msg << "Overload for operator <" << getName(); msg << "> and its inverse <" << invopname; msg << "> are not supported as operand for class: "; msg << m_state.getUlamTypeNameBriefByIndex(luti).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); return NULL; } else //continue with a bang { std::ostringstream msg; msg << "Using overload operator <" << getName(); msg << ">'s negated inverse <" << invopname; msg << "> operator for class: "; msg << m_state.getUlamTypeNameBriefByIndex(luti).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); useInverseOp = true; } } //else continue without a bang //clear up compiler state to no longer use the member class block for symbol searches m_state.popClassContext(); 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); fcallNode->addArgument(m_nodeRight); Node * rnode = fcallNode; if(useInverseOp) { rnode = new NodeUnaryOpBang(fcallNode, m_state); rnode->setNodeLocation(identTok.m_locator); } NodeMemberSelect * mselectNode = new NodeMemberSelect(m_nodeLeft, rnode, 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