예제 #1
0
  UTI NodeBinaryOpCompare::checkAndLabelType()
  {
    assert(m_nodeLeft && m_nodeRight);
    UTI leftType = m_nodeLeft->checkAndLabelType();
    UTI rightType = m_nodeRight->checkAndLabelType();

    UlamType * lut = m_state.getUlamTypeByIndex(leftType);
    if((lut->getUlamTypeEnum() == Class))
      {
	Node * newnode = buildOperatorOverloadFuncCallNode();
	if(newnode)
	  {
	    AssertBool swapOk = Node::exchangeNodeWithParent(newnode);
	    assert(swapOk);

	    m_nodeLeft = NULL; //recycle as memberselect
	    m_nodeRight = NULL; //recycle as func call arg

	    delete this; //suicide is painless..

	    return newnode->checkAndLabelType(); //t41109
	  }
	//else should fail again as non-primitive;
      } //done

    UTI newType = calcNodeType(leftType, rightType); //for casting
    if(m_state.isComplete(newType))
      {
	u32 errCnt = 0;
	if(UlamType::compareForMakingCastingNode(rightType, newType, m_state) != UTIC_SAME)
	  {
	    if(!Node::makeCastingNode(m_nodeRight, newType, m_nodeRight))
	      errCnt++;
	  }

	if(UlamType::compareForMakingCastingNode(leftType, newType, m_state) != UTIC_SAME)
	  {
	    if(!Node::makeCastingNode(m_nodeLeft, newType, m_nodeLeft))
	      errCnt++;
	  }

	if(errCnt)
	  newType = Nav;
	else
	  newType = Bool; //always Bool (default size) for node; after castings!
      }
    setNodeType(newType);
    if(newType == Hzy) m_state.setGoAgain(); //nolonger needed in calcnodetypes
    Node::setStoreIntoAble(TBOOL_FALSE);

    //still may need casting (e.g. unary compared to an int) before constantfolding
    if((newType != Nav) && isAConstant() && m_nodeLeft->isReadyConstant() && m_nodeRight->isReadyConstant())
      return NodeBinaryOp::constantFold();

    return newType;
  } //checkAndLabelType
예제 #2
0
  UTI NodeBinaryOpCompare::checkAndLabelType()
  {
    assert(m_nodeLeft && m_nodeRight);
    UTI leftType = m_nodeLeft->checkAndLabelType();
    UTI rightType = m_nodeRight->checkAndLabelType();

    UTI newType = calcNodeType(leftType, rightType); //for casting
    if(newType != Nav && m_state.isComplete(newType))
      {
	u32 errCnt = 0;
	if(UlamType::compare(rightType, newType, m_state) != UTIC_SAME)
	  {
	    if(!makeCastingNode(m_nodeRight, newType, m_nodeRight))
	      errCnt++;
	  }

	if(UlamType::compare(leftType, newType, m_state) != UTIC_SAME)
	  {
	    if(!makeCastingNode(m_nodeLeft, newType, m_nodeLeft))
	      errCnt++;
	  }

	if(errCnt)
	  newType = Nav;
	else
	  newType = Bool; //always Bool (default size) for node; after castings!
      }
    setNodeType(newType);
    setStoreIntoAble(false);

    //still may need casting (e.g. unary compared to an int) before constantfolding
    if(newType != Nav && isAConstant() && m_nodeLeft->isReadyConstant() && m_nodeRight->isReadyConstant())
      return NodeBinaryOp::constantFold();

    return newType;
  } //checkAndLabelType
예제 #3
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
예제 #4
0
  UTI NodeUnaryOp::checkAndLabelType()
  {
    assert(m_node);
    UTI uti = m_node->checkAndLabelType();

    if(m_state.isComplete(uti) && !m_state.isScalar(uti)) //array unsupported at this time
      {
	std::ostringstream msg;
	msg << "Incompatible (nonscalar) type: ";
	msg << m_state.getUlamTypeNameBriefByIndex(uti).c_str();
	msg << ", for unary " << getName();
	MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	setNodeType(Nav);
	return Nav;
      }

    //replace node with func call to matching function overload operator for class
    // of left, with no arguments for unary (t41???);
    // quark toInt must be used on rhs of operators (t3191, t3200, t3513, t3648,9)
    UlamType * ut = m_state.getUlamTypeByIndex(uti);
    if((ut->getUlamTypeEnum() == Class))
      {
	Node * newnode = buildOperatorOverloadFuncCallNode();
	if(newnode)
	  {
	    AssertBool swapOk = Node::exchangeNodeWithParent(newnode);
	    assert(swapOk);

	    m_node = NULL; //recycle as memberselect

	    delete this; //suicide is painless..

	    return newnode->checkAndLabelType();
	  }
	//else should fail again as non-primitive;
      } //done

    UTI newType = Nav;
    if(uti != Nav)
      newType = calcNodeType(uti); //does safety check

    if(m_state.isComplete(newType))
      {
	if(UlamType::compareForMakingCastingNode(newType, uti, m_state) != UTIC_SAME) //not same|dontknow
	  {
	    if(!Node::makeCastingNode(m_node, newType, m_node))
	      newType = Nav;
	  }
      }
    else
      newType = Hzy;

    setNodeType(newType);
    if(newType == Hzy) m_state.setGoAgain(); //since not error
    Node::setStoreIntoAble(TBOOL_FALSE);

    if((newType != Nav) && isAConstant() && m_node->isReadyConstant())
      return constantFold();

    return newType;
  } //checkAndLabelType