Example #1
0
  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
Example #2
0
  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
Example #3
0
  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
Example #5
0
  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
Example #6
0
  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
Example #7
0
  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