Ejemplo n.º 1
0
  bool NodeUnaryOp::checkSafeToCastTo(UTI unused, UTI& newType)
  {
    bool rtnOK = true;
    FORECAST scr = m_node->safeToCastTo(newType);
    if(scr != CAST_CLEAR)
      {
	ULAMTYPE etyp = m_state.getUlamTypeByIndex(newType)->getUlamTypeEnum();
	std::ostringstream msg;
	if(etyp == Bool)
	  msg << "Use a comparison operation";
	else if(etyp == String)
	  msg << "Invalid";
	else
	  msg << "Use explicit cast";
	msg << " to convert "; // the real converting-message
	msg << m_state.getUlamTypeNameBriefByIndex(m_node->getNodeType()).c_str();
	msg << " to ";
	msg << m_state.getUlamTypeNameBriefByIndex(newType).c_str();
	msg << " for unary " << getName();
	if(scr == CAST_HAZY)
	  {
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT);
	    newType = Hzy;
	  }
	else
	  {
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	    newType = Nav;
	  }
	rtnOK = false;
      } //not safe
    return rtnOK;
  } //checkSafeToCastTo
Ejemplo n.º 2
0
  void NodeTypedef::checkForSymbol()
  {
    //in case of a cloned unknown
    NodeBlock * currBlock = getBlock();
    m_state.pushCurrentBlockAndDontUseMemberBlock(currBlock);

    Symbol * asymptr = NULL;
    bool hazyKin = false;
    if(m_state.alreadyDefinedSymbol(m_tdid, asymptr, hazyKin) && !hazyKin)
      {
	if(asymptr->isTypedef())
	  {
	    m_typedefSymbol = (SymbolTypedef *) asymptr;
	  }
	else
	  {
	    std::ostringstream msg;
	    msg << "(1) <" << m_state.m_pool.getDataAsString(m_tdid).c_str();
	    msg << "> is not a typedef, and cannot be used as one";
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	  }
      }
    else
      {
	std::ostringstream msg;
	msg << "(2) Typedef <" << m_state.m_pool.getDataAsString(m_tdid).c_str();
	msg << "> is not defined, and cannot be used";
	if(!hazyKin)
	  MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	else
	  MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
      }
    m_state.popClassContext(); //restore
  } //toinstantiate
Ejemplo n.º 3
0
  UTI NodeBinaryOpEqualArith::checkAndLabelType()
  {
    UTI nodeType = NodeBinaryOpEqual::checkAndLabelType();
    UlamType * nut = m_state.getUlamTypeByIndex(nodeType);

    // common part of name
    ULAMTYPE enodetyp = nut->getUlamTypeEnum();
    if(enodetyp == Bits)
      {
	// can happen with op-equal operations when both sides are the same type
	MSG(getNodeLocationAsString().c_str(), "Arithmetic Operations are invalid on 'Bits' type", ERR);
	nodeType = Nav;
      }

    if(enodetyp == Bool)
      {
	// can happen with op-equal operations when both sides are the same type
	MSG(getNodeLocationAsString().c_str(), "Arithmetic Operations are invalid on 'Bool' type", ERR);
	nodeType = Nav;
      }

    if((nodeType != Nav) && !nut->isScalar())
      {
	std::ostringstream msg;
	msg << "Non-scalars require a loop for operator" << getName();
	MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	nodeType = Nav;
      }

    setNodeType(nodeType);
    return nodeType;
  } //checkAndLabelType
Ejemplo n.º 4
0
  UTI NodeBinaryOpEqualShift::calcNodeType(UTI lt, UTI rt)  //shift
  {
    if(!m_state.neitherNAVokUTItoContinue(lt, rt))
      return Nav;

    if(!m_state.isComplete(lt) || !m_state.isComplete(rt))
	return Hzy;

    //no atoms, elements nor voids as either operand
    if(!NodeBinaryOp::checkForPrimitiveNotVoidTypes(lt, rt))
	return Nav;

    UTI newType = Nav;  //init
    if(NodeBinaryOp::checkScalarTypesOnly(lt, rt))
      {
	bool bOK = true;
	//can't cast lhs of equal
	ULAMTYPE ltypEnum = m_state.getUlamTypeByIndex(lt)->getUlamTypeEnum();
	if(ltypEnum != Bits)
	  {
	    std::ostringstream msg;
	    msg << "Bits is the supported type for shift operation "; //equal
	    msg << getName();
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	    bOK = false;
	  }

	newType = lt;

	FORECAST rscr = m_nodeRight->safeToCastTo(Unsigned);
	if(rscr != CAST_CLEAR)
	  {
	    std::ostringstream msg;
	    msg << "Righthand type ";
	    msg << m_state.getUlamTypeNameBriefByIndex(rt).c_str();
	    msg << " is not representable as Unsigned";
	    msg << "; the supported type for rhs of shift operation ";
	    msg << getName();
	    if(rscr == CAST_BAD)
	      {
		MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
		bOK = false;
	      }
	    else //hazy
	      {
		MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT);
		m_state.setGoAgain(); //for compiler counts
		newType = Hzy;
	      }
	  }

	if(!bOK)
	  newType = Nav;
      } //both scalars
    return newType;
  } //calcNodeType
Ejemplo n.º 5
0
  void NodeConstantArray::checkForSymbol()
  {
    //in case of a cloned unknown
    NodeBlock * currBlock = getBlock();
    m_state.pushCurrentBlockAndDontUseMemberBlock(currBlock);

    Symbol * asymptr = NULL;
    bool hazyKin = false;
    if(m_state.alreadyDefinedSymbol(m_token.m_dataindex, asymptr, hazyKin))
      {
	if(asymptr->isConstant())
	  {
	    m_constSymbol = (SymbolConstantValue *) asymptr;
	  }
	else
	  {
	    std::ostringstream msg;
	    msg << "(1) <" << m_state.getTokenDataAsString(m_token).c_str();
	    msg << "> is not a constant, and cannot be used as one with class: ";
	    msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str();
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	  }
      }
    else
      {
	std::ostringstream msg;
	msg << "Named Constant Array <" << m_state.getTokenDataAsString(m_token).c_str();
	msg << "> is not defined, or was used before declared in a function";
	if(!hazyKin)
	  MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	else
	  MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
      }
    m_state.popClassContext(); //restore

    if(m_constSymbol && !m_constSymbol->isDataMember() && !m_constSymbol->isLocalsFilescopeDef() && !m_constSymbol->isClassArgument() && (m_constSymbol->getDeclNodeNo() > getNodeNo()))
      {
	NodeBlock * currBlock = getBlock();
	currBlock = currBlock->getPreviousBlockPointer();
	std::ostringstream msg;
	msg << "Named constant array '" << getName();
	msg << "' was used before declared in a function";
	if(currBlock)
	  {
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT);
	    setBlockNo(currBlock->getNodeNo());
	    m_constSymbol = NULL;
	    return checkForSymbol();
	  }
	else
	  {
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	    m_constSymbol = NULL;
	  }
      }
  } //checkForSymbol
Ejemplo n.º 6
0
  UTI NodeBinaryOpLogical::calcNodeType(UTI lt, UTI rt)  //logical
  {
    if(!m_state.okUTItoContinue(lt, rt))
      return Nav;

    if(!m_state.isComplete(lt) || !m_state.isComplete(rt))
      return Hzy;

    //no atoms, elements nor voids as either operand
    if(!NodeBinaryOp::checkForPrimitiveTypes(lt, rt))
	return Nav;

    UTI newType = Nav; //init
    // all logical operations are performed as Bool.BITSPERBOOL.-1
    if(NodeBinaryOp::checkScalarTypesOnly(lt, rt))
      {
	s32 maxbs = 1;
	FORECAST lscr = m_state.getUlamTypeByIndex(Bool)->safeCast(lt);
	FORECAST rscr = m_state.getUlamTypeByIndex(Bool)->safeCast(rt);

	//check for Bool, or safe Non-Bool to Bool casting cases:
	if(lscr != CAST_CLEAR || rscr != CAST_CLEAR)
	  {
	    std::ostringstream msg;
	    msg << "Bool is the supported type for logical operator";
	    msg << getName() << "; Suggest casting ";
	    msg << m_state.getUlamTypeNameBriefByIndex(lt).c_str() << " and ";
	    msg << m_state.getUlamTypeNameBriefByIndex(rt).c_str();
	    msg << " to Bool";
	    if(lscr == CAST_BAD || rscr == CAST_BAD)
	      {
		MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
		newType = Nav;
	      }
	    else
	      {
		MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); //hazy
		m_state.setGoAgain();
		newType = Hzy;
	      }
	  }
	else
	  {
	    s32 lbs = m_state.getBitSize(lt);
	    s32 rbs = m_state.getBitSize(rt);
	    maxbs = (lbs > rbs ? lbs : rbs);
	    //both bool. ok to cast. use larger bool bitsize.
	    UlamKeyTypeSignature newkey(m_state.m_pool.getIndexForDataString("Bool"), maxbs);
	    newType = m_state.makeUlamType(newkey, Bool, UC_NOTACLASS);
	  }
      } //both scalars
    return newType;
  } //calcNodeType
Ejemplo n.º 7
0
  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(m_state.okUTItoContinue(newType) && 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);
	ULAMCLASSTYPE newclasstype = newut->getUlamClassType();
	nuti = m_state.makeUlamType(tokey, typEnum, newclasstype);

	if(UlamType::compareForMakingCastingNode(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 = Node::newCastingNode(this, nuti);

	    Node * parentNode = m_state.findNodeNoInThisClass(pno);
	    if(!parentNode)
	      {
		std::ostringstream msg;
		msg << "Remainder cast cannot be exchanged at this time while compiling class: ";
		msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str();
		msg << " Parent required";
		MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
		assert(0); //parent required
	      }

	    AssertBool swapOk = parentNode->exchangeKids(this, castNode);
	    assert(swapOk);

	    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
  UTI NodeBinaryOpEqualBitwise::calcNodeType(UTI lt, UTI rt)  //bitwise
  {
    if(!m_state.isComplete(lt) || !m_state.isComplete(rt))
	return Nav;

    //no atoms, elements nor voids as either operand
    if(!NodeBinaryOp::checkForPrimitiveTypes(lt, rt))
	return Nav;

    UTI newType = Nav;  //init
    if(NodeBinaryOp::checkScalarTypesOnly(lt, rt))
      {
	bool bOK = true;
	//can't cast lhs of equal
	ULAMTYPE ltypEnum = m_state.getUlamTypeByIndex(lt)->getUlamTypeEnum();
	if(ltypEnum != Bits)
	  {
	    std::ostringstream msg;
	    msg << "Bits is the supported type for bitwise operator"; //equal
	    msg << getName();
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	    bOK = false;
	  }

	newType = lt;

	FORECAST rscr = m_nodeRight->safeToCastTo(newType);
	if(rscr != CAST_CLEAR)
	  {
	    std::ostringstream msg;
	    msg << "Righthand type ";
	    msg << m_state.getUlamTypeNameBriefByIndex(rt).c_str();
	    msg << " is not representable as ";
	    msg<< m_state.getUlamTypeNameBriefByIndex(newType).c_str();
	    msg << ". Bits is the supported type for bitwise operator";
	    msg << getName();
	    if(rscr == CAST_BAD)
	      MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	    else //hazy
	      MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
	    bOK = false;
	  }

	if(!bOK)
	  newType = Nav;
      } //both scalars
    return newType;
  } //calcNodeType
Ejemplo n.º 9
0
  UTI NodeUnaryOpBang::calcNodeType(UTI uti)
  {
    if(uti == Nav)
      return Nav;

    if(!m_state.isComplete(uti))
      return Hzy;

    ULAMTYPE typEnum = m_state.getUlamTypeByIndex(uti)->getUlamTypeEnum();
    if(typEnum == Bits)
      {
	std::ostringstream msg;
	msg << "Incompatible Bits type for unary ";
	msg << getName() << ". Suggest casting to a Bool first";
	MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	return Nav;
      }

    if(!NodeUnaryOp::checkForPrimitiveType(uti))
      return Nav;

    UTI newType = Nav;
    s32 newbs = (typEnum == Bool ? m_state.getBitSize(uti) : 1);
    FORECAST scr = m_state.getUlamTypeByIndex(Bool)->safeCast(uti);
    if(scr != CAST_CLEAR)
      {
	std::ostringstream msg;
	msg << "Bool is the supported type for logical unary ";
	msg << getName() << "; Suggest casting ";
	msg << m_state.getUlamTypeNameBriefByIndex(uti).c_str();
	msg << " to Bool";
	if(scr == CAST_HAZY)
	  {
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT);
	    m_state.setGoAgain();
	    newType = Hzy;
	  }
	else
	  MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
      }
    else
      {
	// safe to cast. use a bool bitsize.
	UlamKeyTypeSignature newkey(m_state.m_pool.getIndexForDataString("Bool"), newbs);
	newType = m_state.makeUlamType(newkey, Bool, UC_NOTACLASS);
      }
    return newType;
  } //calcNodeType
Ejemplo n.º 10
0
  UlamValue NodeBinaryOpArithDivide::makeImmediateBinaryOp(UTI type, u32 ldata, u32 rdata, u32 len)
  {
    UlamValue rtnUV;

    if(rdata == 0)
      {
	MSG(getNodeLocationAsString().c_str(), "Possible Divide By Zero Attempt", ERR);
	rtnUV.setUlamValueTypeIdx(Nav);
	setNodeType(Nav); //compiler counts
	return rtnUV;
      }

    ULAMTYPE typEnum = m_state.getUlamTypeByIndex(type)->getUlamTypeEnum();
    switch(typEnum)
      {
      case Int:
	rtnUV = UlamValue::makeImmediate(type, _BinOpDivideInt32(ldata, rdata, len), len);
	break;
      case Unsigned:
	rtnUV = UlamValue::makeImmediate(type, _BinOpDivideUnsigned32(ldata, rdata, len), len);
	break;
      case Bool:
	rtnUV = UlamValue::makeImmediate(type, _BinOpDivideBool32(ldata, rdata, len), len);
	break;
      case Unary:
	rtnUV = UlamValue::makeImmediate(type, _BinOpDivideUnary32(ldata, rdata, len), len);
	break;
      case Bits:
      default:
	m_state.abortUndefinedUlamPrimitiveType();
	break;
      };
    return rtnUV;
  } //makeImmediateBinaryOp
Ejemplo n.º 11
0
  void NodeBinaryOpArithDivide::appendBinaryOp(UlamValue& refUV, u32 ldata, u32 rdata, u32 pos, u32 len)
  {
    if(rdata == 0)
      {
	MSG(getNodeLocationAsString().c_str(), "Possible Divide By Zero Attempt", ERR);
	refUV.setUlamValueTypeIdx(Nav);
	setNodeType(Nav); //compiler counts
	return;
      }

    UTI type = refUV.getUlamValueTypeIdx();
    ULAMTYPE typEnum = m_state.getUlamTypeByIndex(type)->getUlamTypeEnum();
    switch(typEnum)
      {
      case Int:
	refUV.putData(pos, len, _BinOpDivideInt32(ldata, rdata, len));
	break;
      case Unsigned:
	refUV.putData(pos, len, _BinOpDivideUnsigned32(ldata, rdata, len));
	break;
      case Bool:
	refUV.putData(pos, len, _BinOpDivideBool32(ldata, rdata, len));
	break;
      case Unary:
	refUV.putData(pos, len, _BinOpDivideUnary32(ldata, rdata, len));
	break;
      case Bits:
      default:
	m_state.abortUndefinedUlamPrimitiveType();
	break;
      };
    return;
  } //appendBinaryOp
Ejemplo n.º 12
0
  UlamValue NodeBinaryOpArithRemainder::makeImmediateLongBinaryOp(UTI type, u64 ldata, u64 rdata, u32 len)
  {
    UlamValue rtnUV;

    if(rdata == 0)
      {
	MSG(getNodeLocationAsString().c_str(), "Possible Division By Zero Attempt in Modulus", ERR);
	rtnUV.setUlamValueTypeIdx(Nav);
	setNodeType(Nav); //compiler counts
	return rtnUV;
      }

    ULAMTYPE typEnum = m_state.getUlamTypeByIndex(type)->getUlamTypeEnum();
    switch(typEnum)
      {
      case Int:
	rtnUV = UlamValue::makeImmediateLong(type, _BinOpModInt64(ldata, rdata, len), len);
	break;
      case Unsigned:
	rtnUV = UlamValue::makeImmediateLong(type, _BinOpModUnsigned64(ldata, rdata, len), len);
	break;
      case Bool:
	rtnUV = UlamValue::makeImmediateLong(type, _BinOpModBool64(ldata, rdata, len), len);
	break;
      case Unary:
	rtnUV = UlamValue::makeImmediateLong(type, _BinOpModUnary64(ldata, rdata, len), len);
	break;
      case Bits:
      default:
	assert(0);
	break;
      };
    return rtnUV;
  } //makeImmediateLongBinaryOp
Ejemplo n.º 13
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
Ejemplo n.º 14
0
  bool NodeCast::needsACast()
  {
    UTI tobeType = getNodeType();
    UTI nodeType = m_node->getNodeType();

    ULAMTYPECOMPARERESULTS uticr = UlamType::compare(nodeType, tobeType, m_state);
    if(uticr == UTIC_DONTKNOW)
      {
	std::ostringstream msg;
	msg << "Casting 'incomplete' types: ";
	msg << m_state.getUlamTypeNameBriefByIndex(nodeType).c_str();
	msg << "(UTI" << nodeType << ") to be ";
	msg << m_state.getUlamTypeNameBriefByIndex(tobeType).c_str();
	msg << "(UTI" << tobeType << ")";
	MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
	return false;
      }

    if(uticr == UTIC_SAME)
      return false; //short-circuit if same exact type

    ULAMTYPE typEnum = m_state.getUlamTypeByIndex(tobeType)->getUlamTypeEnum();
    ULAMTYPE nodetypEnum = m_state.getUlamTypeByIndex(nodeType)->getUlamTypeEnum();

    if(m_state.getUlamTypeByIndex(nodeType)->getUlamClass() == UC_QUARK)
      return false;

    // consider user requested first, then size independent;
    // even constant may need casting (e.g. narrowing for saturation)
    // Bool constants require casts to generate "full" true UlamValue (>1-bit).
    return( isExplicitCast() || typEnum != nodetypEnum  || (m_state.getBitSize(tobeType) != m_state.getBitSize(nodeType)) || (nodetypEnum == Bool && m_node->isAConstant() && m_state.getBitSize(tobeType)>1));
  } //needsACast
  void NodeBinaryOpArithRemainder::appendBinaryOp(UlamValue& refUV, u32 ldata, u32 rdata, u32 pos, u32 len)
  {
    if(rdata == 0)
      {
	MSG(getNodeLocationAsString().c_str(), "Possible Remainder By Zero Attempt", ERR);
	return;
      }

    UTI type = refUV.getUlamValueTypeIdx();
    ULAMTYPE typEnum = m_state.getUlamTypeByIndex(type)->getUlamTypeEnum();
    switch(typEnum)
      {
      case Int:
	refUV.putData(pos, len, _BinOpModInt32(ldata, rdata, len));
	break;
      case Unsigned:
	refUV.putData(pos, len, _BinOpModUnsigned32(ldata, rdata, len));
	break;
      case Bool:
	refUV.putData(pos, len, _BinOpModBool32(ldata, rdata, len));
	break;
      case Unary:
	refUV.putData(pos, len, _BinOpModUnary32(ldata, rdata, len));
	break;
      case Bits:
      default:
	assert(0);
	break;
      };
    return;
  } //appendBinaryOp
Ejemplo n.º 16
0
  //class context set prior to calling us; purpose is to get
  // the value of this constant from the context before
  // constant folding happens.
  bool NodeConstantArray::assignClassArgValueInStubCopy()
  {
    // insure current block NNOs match
    if(m_currBlockNo != m_state.getCurrentBlockNo())
      {
	std::ostringstream msg;
	msg << "Block NNO " << m_currBlockNo << " for <";
	msg << m_state.getTokenDataAsString(m_token).c_str();
	msg << "> does not match the current block no ";
	msg << m_state.getCurrentBlockNo();
	msg << "; its value cannot be used in stub copy, with class: ";
	msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str();
	MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
	return false;
      }

    if(isReadyConstant())
      return true; //nothing to do

    bool isready = false;
    Symbol * asymptr = NULL;
    bool hazyKin = false;
    if(m_state.alreadyDefinedSymbol(m_token.m_dataindex, asymptr, hazyKin))
      {
	assert(hazyKin); //always hazy, right?
	if(asymptr->isConstant() && ((SymbolConstantValue *) asymptr)->isReady()) //???
	  {
	    isready = true;
	    //note: m_constSymbol may be NULL; ok in this circumstance (i.e. stub copy).
	  }
      }
    return isready;
  } //assignClassArgValueInStubCopy
Ejemplo n.º 17
0
 const char * NodeBinaryOpCompare::getInverseOpName()
 {
   std::ostringstream msg;
   msg << "virtual const char * " << prettyNodeName().c_str();
   msg << "::getInverseOpName(){} is needed!!";
   MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
   return NULL;
 }
Ejemplo n.º 18
0
  bool NodeSquareBracket::getSymbolPtr(Symbol *& symptrref)
  {
    if(m_nodeLeft)
      return m_nodeLeft->getSymbolPtr(symptrref);

    MSG(getNodeLocationAsString().c_str(), "No symbol", ERR);
    return false;
  }
Ejemplo n.º 19
0
  bool NodeMemberSelect::getSymbolPtr(Symbol *& symptrref)
  {
    if(m_nodeRight)
      return m_nodeRight->getSymbolPtr(symptrref);

    MSG(getNodeLocationAsString().c_str(), "No symbol", ERR);
    return false;
  }
Ejemplo n.º 20
0
  // eval() no longer performed before check and label
  // returns false if error; UNKNOWNSIZE is not an error!
  bool NodeSquareBracket::getArraysizeInBracket(s32 & rtnArraySize)
  {
    bool noerr = true;
    // since square brackets determine the constant size for this type, else error
    s32 newarraysize = NONARRAYSIZE;
    UTI sizetype = m_nodeRight->checkAndLabelType();
    if(sizetype == Nav)
      {
	rtnArraySize = UNKNOWNSIZE;
	return true;
      }

    UlamType * sizeut = m_state.getUlamTypeByIndex(sizetype);

    // expects a constant, numeric type within []
    if(sizeut->isNumericType() && m_nodeRight->isAConstant())
      {
	evalNodeProlog(0); //new current frame pointer
	makeRoomForNodeType(sizetype); //offset a constant expression
	if(m_nodeRight->eval() == NORMAL)
	  {
	    UlamValue arrayUV = m_state.m_nodeEvalStack.popArg();
	    u32 arraysizedata = arrayUV.getImmediateData(m_state);
	    newarraysize = sizeut->getDataAsCs32(arraysizedata);
	    if(newarraysize < 0 && newarraysize != UNKNOWNSIZE) //NONARRAY or UNKNOWN
	      {
		MSG(getNodeLocationAsString().c_str(),
		    "Array size specifier in [] is not a positive number", ERR);
		noerr = false;
	      }
	    //else unknown is not an error
	  }
	else //newarraysize = UNKNOWNSIZE; //still true
	  noerr = false;

	evalNodeEpilog();
      }
    else
      {
	MSG(getNodeLocationAsString().c_str(),
	    "Array size specifier in [] is not a constant number", ERR);
	noerr = false;
      }
    rtnArraySize = newarraysize;
    return noerr;
  } //getArraysizeInBracket
Ejemplo n.º 21
0
  bool NodeMemberSelect::getStorageSymbolPtr(Symbol *& symptrref)
  {
    if(m_nodeLeft)
      return m_nodeLeft->getSymbolPtr(symptrref); //includes quarks, transients

    MSG(getNodeLocationAsString().c_str(), "No storage symbol", ERR);
    return false;
  }
Ejemplo n.º 22
0
  UTI NodeConstant::checkAndLabelType()
  {
    UTI it = Nav;

    bool stubcopy = m_state.isClassAStub(m_state.getCompileThisIdx());

    //instantiate, look up in class block; skip if stub copy and already ready.
    if(!stubcopy && m_constSymbol == NULL)
	checkForSymbol();
    else
      {
	stubcopy = m_state.hasClassAStub(m_state.getCompileThisIdx()); //includes ancestors
      }

    if(m_constSymbol)
      {
	it = m_constSymbol->getUlamTypeIdx();
      }
    else if(isReadyConstant() && stubcopy)
      {
	assert(m_state.okUTItoContinue(m_constType));
	setNodeType(m_constType); //t3565, t3640, t3641, t3642, t3652
	//stub copy case: still wants uti mapping
	it = NodeTerminal::checkAndLabelType();
      }
    else if(stubcopy)
      {
	// still need its symbol for a value
	// use the member class (unlike checkForSymbol)
      }

    // map incomplete UTI
    if(!m_state.isComplete(it)) //reloads to recheck
      {
	std::ostringstream msg;
	msg << "Incomplete " << prettyNodeName().c_str() << " for type: ";
	msg << m_state.getUlamTypeNameBriefByIndex(it).c_str();
	msg << ", used with constant symbol name '";
	msg << m_state.getTokenDataAsString(m_token).c_str() << "'";
	MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT);
	//wait until updateConstant tried.
      }

    setNodeType(it);
    Node::setStoreIntoAble(TBOOL_FALSE);

    //copy m_constant from Symbol into NodeTerminal parent.
    if(!isReadyConstant())
      m_ready = updateConstant(); //sets ready here
    if(!isReadyConstant())
      {
	it = Hzy;
	if(!stubcopy)
	  m_constSymbol = NULL; //lookup again too! (e.g. inherited template instances)
	m_state.setGoAgain();
      }
    return it;
  } //checkAndLabelType
Ejemplo n.º 23
0
  //see also NodeIdent
  bool NodeSquareBracket::installSymbolVariable(TypeArgs& args,  Symbol *& asymptr)
  {
    assert(m_nodeLeft && m_nodeRight);

    if(!m_nodeLeft)
      {
	MSG(getNodeLocationAsString().c_str(), "No Identifier to build array symbol", ERR);
	return false;
      }

    if(args.m_arraysize > NONARRAYSIZE)
      {
	MSG(getNodeLocationAsString().c_str(), "Array size specified twice", ERR);
	return false;
      }

    args.m_arraysize = UNKNOWNSIZE; // no eval yet
    return m_nodeLeft->installSymbolVariable(args, asymptr);
  } //installSymbolVariable
Ejemplo n.º 24
0
  //no atoms, elements as operand
  bool NodeUnaryOp::checkForPrimitiveType(UTI uti)
  {
    if(!m_state.getUlamTypeByIndex(uti)->isPrimitiveType())
      {
	std::ostringstream msg;
	msg << "Non-primitive type <";
	msg << m_state.getUlamTypeNameBriefByIndex(uti).c_str();
	msg << "> is not supported for unary ";
	msg << getName();
	MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	return false;
      }
    return checkNotVoidType(uti);
  } //checkForPrimitiveType
Ejemplo n.º 25
0
  bool NodeUnaryOp::checkNotVoidType(UTI uti)
  {
    bool rtnOK = true;
    ULAMTYPE typEnum = m_state.getUlamTypeByIndex(uti)->getUlamTypeEnum();
    if(typEnum == Void)
      {
	std::ostringstream msg;
	msg << "Void is not a supported type for unary ";
	msg << getName();
	MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	rtnOK = false;
      }
    return rtnOK;
  } //checkNotVoidTypes
Ejemplo n.º 26
0
  bool NodeVarRef::checkReferenceCompatibility(UTI uti)
  {
    assert(m_state.okUTItoContinue(uti));
    if((!m_state.getUlamTypeByIndex(uti)->isAltRefType()))
      {
	std::ostringstream msg;
	msg << "Variable reference '";
	msg << m_state.m_pool.getDataAsString(m_vid).c_str();
	msg << "', is invalid";
	MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	return false;
      }
    return true; //ok
  } //checkReferenceCompatibility
Ejemplo n.º 27
0
  void NodeTypedef::printUnresolvedVariableDataMembers()
  {
    assert(m_typedefSymbol);
    UTI it = m_typedefSymbol->getUlamTypeIdx();
    if(!m_state.isComplete(it))
      {
	std::ostringstream msg;
	msg << "Unresolved type <";
	msg << m_state.getUlamTypeNameBriefByIndex(it).c_str();
	msg << "> used with typedef symbol name '" << getName() << "'";
	MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	setNodeType(Nav); //compiler counts
      } //not complete
  } //printUnresolvedVariableDataMembers
Ejemplo n.º 28
0
  void NodeConstant::checkForSymbol()
  {
    //in case of a cloned unknown
    NodeBlock * currBlock = getBlock();
    m_state.pushCurrentBlockAndDontUseMemberBlock(currBlock);

    Symbol * asymptr = NULL;
    bool hazyKin = false;
    if(m_state.alreadyDefinedSymbol(m_token.m_dataindex, asymptr, hazyKin))
      {
	if(asymptr->isConstant())
	  {
	    m_constSymbol = (SymbolConstantValue *) asymptr;
	  }
	else
	  {
	    std::ostringstream msg;
	    msg << "(1) <" << m_state.getTokenDataAsString(m_token).c_str();
	    msg << "> is not a constant, and cannot be used as one with class: ";
	    msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str();
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	  }
      }
    else
      {
	std::ostringstream msg;
	msg << "(2) Named Constant <" << m_state.getTokenDataAsString(m_token).c_str();
	msg << "> is not defined, and cannot be used with class: ";
	msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str();
	if(!hazyKin)
	  MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	else
	  MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
      }
    m_state.popClassContext(); //restore
  } //checkForSymbol
Ejemplo n.º 29
0
  bool NodeUnaryOp::checkForNumericType(UTI uti)
  {
    bool rtnOK = true;
    bool isnum = m_state.getUlamTypeByIndex(uti)->isNumericType();
    if(!isnum)
      {
	std::ostringstream msg;
	msg << "Incompatible type for unary ";
	msg << getName() << " : ";
	msg << m_state.getUlamTypeNameBriefByIndex(uti).c_str();
	msg << "; Suggest casting to a numeric type first";
	MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	rtnOK = false;
      }
    return rtnOK;
  } //checkForNumericType
Ejemplo n.º 30
0
  bool NodeUnaryOp::doUnaryOperation(s32 slot, u32 nslots)
  {
    UTI nuti = getNodeType();
    if(m_state.isScalar(nuti))  //not an array
      {
	return doUnaryOperationImmediate(slot, nslots);
      }
    else
      {
	//arrays not supported at this time
	std::ostringstream msg;
	msg << "Unsupported unary operation " << getName();
	msg << ", with an array type <";
	msg << m_state.getUlamTypeNameBriefByIndex(nuti).c_str() << ">";
	MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
      }
    return false;
  } //dobinaryop