Example #1
0
  const std::string NodeBinaryOpEqualShift::methodNameForCodeGen()
  {
    std::ostringstream methodname;
    //methodname << "_Shift";  determined by each op

    UlamType * nut = m_state.getUlamTypeByIndex(getNodeType());

    // common part of name
    ULAMTYPE etyp = nut->getUlamTypeEnum();
    switch(etyp)
      {
      case Int:
      case Unsigned:
      case Bool:
      case Unary:
      case Bits:
	methodname << UlamType::getUlamTypeEnumAsString(etyp);
	break;
      default:
	m_state.abortUndefinedUlamPrimitiveType();
	break;
      };
    methodname << nut->getTotalWordSize();
    return methodname.str();
  } //methodNameForCodeGen
Example #2
0
  FORECAST UlamTypePrimitive::explicitlyCastable(UTI typidx)
  {
    FORECAST scr = UlamType::safeCast(typidx); //default
    if(scr == CAST_CLEAR)
      {
	// primitives must be the same sizes when casting to a reference type
	if(isReference() && !UlamType::checkReferenceCast(typidx))
	  scr = CAST_BAD;

	// strings cannot be cast explicitly to other primitive types, except Void (t3961)
	UlamType * vut = m_state.getUlamTypeByIndex(typidx);
	ULAMTYPE valtypEnum = vut->getUlamTypeEnum();
	if((getUlamTypeEnum() != Void) && ((valtypEnum == String) ^ (getUlamTypeEnum() == String)))
	  scr = CAST_BAD;

	//only quarks may be cast to Ints, explicitly or not; requires toInt method (t3996)
	if(valtypEnum == Class)
	  {
	    ULAMCLASSTYPE vclasstype = vut->getUlamClassType();
	    if(vclasstype != UC_QUARK)
	      scr = CAST_BAD;
	  }
      }
    return scr;
  } //explicitlyCastable
Example #3
0
  void NodeVarRef::printTypeAndName(File * fp)
  {
    UTI vuti = m_varSymbol->getUlamTypeIdx();
    UlamKeyTypeSignature vkey = m_state.getUlamKeyTypeSignatureByIndex(vuti);
    UlamType * vut = m_state.getUlamTypeByIndex(vuti);
    if(m_state.isConstantRefType(vuti))
      fp->write(" constant"); //t41242,3

    fp->write(" ");
    if(vut->getUlamTypeEnum() != Class)
      {
	fp->write(vkey.getUlamKeyTypeSignatureNameAndBitSize(&m_state).c_str());
	fp->write("&"); //<--the only difference!!!
      }
    else
      fp->write(vut->getUlamTypeClassNameBrief(vuti).c_str()); //includes any &

    fp->write(" ");
    fp->write(getName());

    s32 arraysize = m_state.getArraySize(vuti);
    if(arraysize > NONARRAYSIZE)
      {
	fp->write("[");
	fp->write_decimal(arraysize);
	fp->write("]");
      }
    else if(arraysize == UNKNOWNSIZE)
      {
	fp->write("[UNKNOWN]");
      }
  } //printTypeAndName
Example #4
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
Example #5
0
  // replaces NodeTypedef:printPostfix to learn the values of Class' storage in center site
  void SymbolTypedef::printPostfixValuesOfVariableDeclarations(File * fp, s32 slot, u32 startpos, ULAMCLASSTYPE classtype)
  {
    UTI tuti = getUlamTypeIdx();
    UlamKeyTypeSignature tkey = m_state.getUlamKeyTypeSignatureByIndex(tuti);
    UlamType * tut = m_state.getUlamTypeByIndex(tuti);

    fp->write(" typedef");

    fp->write(" ");
    if(tut->getUlamTypeEnum() != Class)
      fp->write(tkey.getUlamKeyTypeSignatureNameAndBitSize(&m_state).c_str());
    else
      fp->write(tut->getUlamTypeNameBrief().c_str());

    fp->write(" ");
    fp->write(m_state.m_pool.getDataAsString(getId()).c_str());

    s32 arraysize = m_state.getArraySize(tuti);
    if(arraysize > NONARRAYSIZE)
      {
	fp->write("[");
	fp->write_decimal(arraysize);
	fp->write("]");
      }
    else if(arraysize == UNKNOWNSIZE)
      {
	fp->write("[UNKNOWN]");
      }

    fp->write("; ");
  } //printPostfixValuesOfVariableDeclarations
Example #6
0
  const std::string NodeBinaryOpEqualArith::methodNameForCodeGen()
  {
    std::ostringstream methodname;
    //methodname << "_BitwiseOr";  determined by each op
    UlamType * nut = m_state.getUlamTypeByIndex(getNodeType());

    // common part of name
    ULAMTYPE etyp = nut->getUlamTypeEnum();
    switch(etyp)
      {
      case Int:
      case Unsigned:
      case Bool:
      case Unary:
	methodname << UlamType::getUlamTypeEnumAsString(etyp);
	break;
      case Bits:
      default:
	assert(0);
	methodname << "NAV";
	break;
      };
    methodname << nut->getTotalWordSize();
    return methodname.str();
  } //methodNameForCodeGen
Example #7
0
  const std::string NodeBinaryOpCompare::methodNameForCodeGen()
  {
    std::ostringstream methodname;
    //methodname << "_BitwiseOr";  determined by each op
    UlamType * lut = m_state.getUlamTypeByIndex(m_nodeLeft->getNodeType());

    // common part of name
    ULAMTYPE etyp = lut->getUlamTypeEnum();
    switch(etyp)
      {
      case Int:
	methodname << "Int";
	break;
      case Unsigned:
	methodname << "Unsigned";
	break;
      case Bits:
	methodname << "Bits";
	break;
      case Bool:
	methodname << "Bool";
	break;
      case String:
	methodname << "String";
	break;
      default:
	m_state.abortUndefinedUlamPrimitiveType();
	methodname << "NAV";
	break;
      };
    methodname << lut->getTotalWordSize();
    return methodname.str();
  } // methodNameForCodeGen
Example #8
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
Example #9
0
  bool SymbolWithValue::convertValueToANonPrettyString(u64 varg, UTI tuti, std::string& vstr, CompilerState & state)
  {
    std::ostringstream ostr;
    UlamType * tut = state.getUlamTypeByIndex(tuti);
    s32 bs = tut->getBitSize();
    ULAMTYPE etyp = tut->getUlamTypeEnum();
    switch(etyp)
      {
      case Int:
	{
	  if(bs <= MAXBITSPERINT)
	    {
	      s32 sval = _Int32ToInt32((u32) varg, bs, MAXBITSPERINT);
	      ostr << sval;
	    }
	  else if(bs <= MAXBITSPERLONG)
	    {
	      s64 sval = _Int64ToInt64(varg, bs, MAXBITSPERLONG);
	      ostr << sval;
	    }
	  else
	    state.abortGreaterThanMaxBitsPerLong();
	}
	break;
      case Unsigned:
	{
	  if( bs <= MAXBITSPERINT)
	    ostr << (u32) varg << "u";
	  else if( bs <= MAXBITSPERLONG)
	    ostr << varg << "u";
	  else
	    state.abortGreaterThanMaxBitsPerLong();
	}
	break;
      case Unary:
      case Bool:
      case Bits:
      case Class:
	{
	  ostr << "0x" << std::hex << varg;
	}
	break;
      case String:
	{
	  std::string fstr = state.getDataAsUnFormattedUserString((u32) varg);
	  u32 flen = fstr.length() - 1; //exclude null terminator
	  for(u32 i = 0; i < flen; i++)
	    ostr << std::hex << std::setfill('0') << std::setw(2) << (u32) fstr[i];
	}
	break;
      default:
	state.abortUndefinedUlamType();
      };
    vstr = ostr.str();
    return true;
  } //convertValueToANonPrettyString (static helper)
Example #10
0
  UTI NodeControl::checkAndLabelType()
  {
    assert(m_nodeCondition && m_nodeBody);
    UTI newType = Bool;
    ULAMTYPE newEnumTyp = Bool;

    // condition should be a bool, safely cast
    UTI cuti = m_nodeCondition->checkAndLabelType();
    if(m_state.okUTItoContinue(cuti) && m_state.isComplete(cuti))
      {
	assert(m_state.isScalar(cuti));
	UlamType * cut = m_state.getUlamTypeByIndex(cuti);
	ULAMTYPE ctypEnum = cut->getUlamTypeEnum();
	if(ctypEnum != newEnumTyp)
	  {
	    if(checkSafeToCastTo(cuti, newType))
	      {
		if(!Node::makeCastingNode(m_nodeCondition, newType, m_nodeCondition))
		  newType = Nav;
	      }
	    //else not safe, newType changed
	  }
	else
	  {
	    //caution: c&l called multiple times
	    //always cast: Bools are maintained as unsigned in gen code,
	    //until c-bool is needed
	    if(cuti != newType)
	      {
		if(checkSafeToCastTo(cuti, newType))
		  {
		    if(!Node::makeCastingNode(m_nodeCondition, cuti, m_nodeCondition))
		      newType = Nav;
		    else
		      newType = cuti;
		  }
	      }
	  }
      }
    else
      {
	newType = Hzy; //was = cuti;
	m_state.setGoAgain();
      }

    m_nodeBody->checkAndLabelType(); //side-effect

    setNodeType(newType);  //stays the same
    Node::setStoreIntoAble(TBOOL_FALSE);
    return getNodeType();
  } //checkAndLabelType
Example #11
0
  FORECAST UlamTypeInt::safeCast(UTI typidx)
  {
    FORECAST scr = UlamType::safeCast(typidx);
    if(scr != CAST_CLEAR)
      return scr;

    bool brtn = true;
    UlamType * vut = m_state.getUlamTypeByIndex(typidx);
    s32 valbitsize = m_state.getBitSize(typidx);
    s32 bitsize = getBitSize();
    ULAMTYPE valtypEnum = vut->getUlamTypeEnum();
    switch(valtypEnum)
      {
      case Int:
	brtn = (bitsize >= valbitsize);
	break;
      case Unsigned:
	brtn = (bitsize > valbitsize);
	break;
      case Unary:
	brtn = (bitsize > (s32) _getLogBase2(valbitsize) + 1);
	break;
      case Bool:
      case Bits:
      case Void:
      case UAtom:
	brtn = false;
	break;
      case Class:
	{
	  //must be Quark! treat as Int if it has a toInt method
	  if(vut->isNumericType())
	    brtn = (bitsize >= MAXBITSPERINT);
	  else
	    {
	      std::ostringstream msg;
	      msg << "Class: ";
	      msg << m_state.getUlamTypeNameBriefByIndex(typidx).c_str();
	      msg << " is not a numeric type and cannot be safely cast to an Int";
	      MSG(m_state.getFullLocationAsString(m_state.m_locOfNextLineText).c_str(),msg.str().c_str(), ERR);
	      brtn = false;
	    }
	}
	break;
      default:
	assert(0);
	//std::cerr << "UlamTypeInt (cast) error! Value Type was: " << valtypidx << std::endl;
	brtn = false;
      };
    return brtn ? CAST_CLEAR : CAST_BAD;
  } //safeCast
  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
Example #13
0
  FORECAST UlamTypePrimitiveInt::safeCast(UTI typidx)
  {
    FORECAST scr = UlamType::safeCast(typidx);
    if(scr != CAST_CLEAR)
      return scr;

    bool brtn = true;
    UlamType * vut = m_state.getUlamTypeByIndex(typidx);
    s32 valbitsize = m_state.getBitSize(typidx);
    s32 bitsize = getBitSize();

    ULAMTYPE valtypEnum = vut->getUlamTypeEnum();
    switch(valtypEnum)
      {
      case Int:
	brtn = (bitsize >= valbitsize);
	break;
      case Unsigned:
	brtn = (bitsize > valbitsize);
	break;
      case Unary:
	brtn = (bitsize > (s32) _getLogBase2(valbitsize) + 1);
	break;
      case Bool:
      case Bits:
      case Void:
      case UAtom:
	brtn = false;
	break;
      case Class:
	{
	  //must be Quark! treat as Int if it has a toInt method
	  if(vut->isNumericType())
	    brtn = (bitsize >= MAXBITSPERINT);
	  else
	    brtn = false; //t41131 called by matching args (no error msg please)
	}
	break;
      default:
	m_state.abortUndefinedUlamType();
	//std::cerr << "UlamTypePrimitiveInt (cast) error! Value Type was: " << valtypidx << std::endl;
	brtn = false;
      };
    return brtn ? CAST_CLEAR : CAST_BAD;
  } //safeCast
Example #14
0
  void SymbolWithValue::printPostfixValueArrayStringAsComment(File * fp)
  {
    BV8K dval;
    bool oktoprint = getValueReadyToPrint(dval);

    UTI tuti = getUlamTypeIdx();
    UlamType * tut = m_state.getUlamTypeByIndex(tuti);
    bool isString = (tut->getUlamTypeEnum() == String); //t3953
    assert(isString);

    if(!oktoprint)
      {
	fp->write("// ");
	fp->write(getMangledName().c_str());
	fp->write(": NONREADYCONSTARRAY OF STRINGS"); GCNL;
	return;
      }

    //like the code generated in CS::genCodeClassDefaultConstantArray
    u32 uvals[ARRAY_LEN8K];
    dval.ToArray(uvals);

    u32 nwords = tut->getTotalNumberOfWords();

    //indented comments of string value items (one per line); e.g. t3953,4
    for(u32 w = 0; w < nwords; w++)
      {
	m_state.indent(fp);
	fp->write("// ");
	fp->write("[");
	fp->write_decimal_unsigned(w);
	fp->write("] = ");
	fp->write(m_state.getDataAsFormattedUserString(uvals[w]).c_str());
	fp->write("\n");
      }
    m_state.indent(fp);
    fp->write("// = ");
    fp->write(getMangledName().c_str());
    fp->write("[");
    fp->write_decimal_unsigned(nwords);
    fp->write("]");
    GCNL;
  } //printPostfixValueArrayStringAsComment
Example #15
0
  void NodeVarRef::checkAbstractInstanceErrors()
  {
    //unlike NodeVarDecl, an abstract class can be a reference!
    UTI nuti = getNodeType();
    UlamType * nut = m_state.getUlamTypeByIndex(nuti);
    if(nut->getUlamTypeEnum() == Class)
      {
	SymbolClass * csym = NULL;
	AssertBool isDefined = m_state.alreadyDefinedSymbolClass(nuti, csym);
	assert(isDefined);
	if(csym->isAbstract())
	  {
	    std::ostringstream msg;
	    msg << "Instance of Abstract Class ";
	    msg << m_state.getUlamTypeNameBriefByIndex(nuti).c_str();
	    msg << " used with reference variable symbol name '";
	    msg << getName() << "'";
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), INFO);
	  }
      }
  } //checkAbstractInstanceErrors
Example #16
0
  FORECAST UlamTypePrimitiveUnary::safeCast(UTI typidx)
  {
    FORECAST scr = UlamType::safeCast(typidx);
    if(scr != CAST_CLEAR)
      return scr;

    bool brtn = true;
    UlamType * vut = m_state.getUlamTypeByIndex(typidx);
    s32 valbitsize = vut->getBitSize();
    s32 bitsize = getBitSize();
    ULAMTYPE valtypEnum = vut->getUlamTypeEnum();
    switch(valtypEnum)
      {
      case Unsigned:
	{
	  u32 vwordsize = vut->getTotalWordSize();
	  if(vwordsize <= MAXBITSPERINT)
	    brtn = ((u32) bitsize >= (u32) vut->getMax());
	  else
	    brtn = ((u64) bitsize >= vut->getMax());
	}
	break;
      case Unary:
	brtn = (bitsize >= valbitsize);
	break;
      case Int:
      case Bool:
      case Bits:
      case Void:
      case UAtom:
      case Class:
	brtn = false;
	break;
      default:
	m_state.abortUndefinedUlamType();
	//std::cerr << "UlamTypePrimitiveUnary (cast) error! Value Type was: " << valtypidx << std::endl;
	brtn = false;
      };
    return brtn ? CAST_CLEAR : CAST_BAD;
  } //safeCast
Example #17
0
  void SymbolWithValue::printPostfixValueArray(File * fp)
  {
    BV8K dval;
    bool oktoprint = getValueReadyToPrint(dval);

    if(!oktoprint)
      {
	fp->write("NONREADYCONSTARRAY");
	return;
      }

    UTI tuti = getUlamTypeIdx();
    UlamType * tut = m_state.getUlamTypeByIndex(tuti);
    s32 tbs = tut->getTotalBitSize();
    if(tbs == 0)
      {
	fp->write("{ }");
	return; //nothing to do
      }

    //required as hex for String arrays too (needed for initialization) (t3974)
    //like the code generated in CS::genCodeClassDefaultConstantArray
    std::string dhex;
    bool nonZero = SymbolWithValue::getHexValueAsString(tbs, dval, dhex);

    //short-circuit if all zeros
    if(!nonZero)
      {
	if(tut->getUlamTypeEnum() == String) //t3953
	  m_state.abortShouldntGetHere();

	fp->write("{ 0 }");
	return; //nothing else to do
      }

    fp->write("{ ");
    fp->write(dhex.c_str());
    fp->write(" }");
  } //printPostfixValueArray
Example #18
0
  void NodeTypedef::printPostfix(File * fp)
  {
    assert(m_typedefSymbol);
    if(m_typedefSymbol->getId() == m_state.m_pool.getIndexForDataString("Self")) return;
    if(m_typedefSymbol->getId() == m_state.m_pool.getIndexForDataString("Super")) return;

    UTI tuti = m_typedefSymbol->getUlamTypeIdx();
    UlamKeyTypeSignature tkey = m_state.getUlamKeyTypeSignatureByIndex(tuti);
    UlamType * tut = m_state.getUlamTypeByIndex(tuti);

    fp->write(" typedef");

    fp->write(" ");
    if(tut->getUlamTypeEnum() != Class)
      {
	fp->write(tkey.getUlamKeyTypeSignatureNameAndBitSize(&m_state).c_str());
	if(tut->isReference())
	  fp->write(" &"); //an array of refs as written, should be ref to an array.
      }
    else
      fp->write(tut->getUlamTypeNameBrief().c_str());

    fp->write(" ");
    fp->write(getName());

    s32 arraysize = m_state.getArraySize(tuti);
    if(arraysize > NONARRAYSIZE)
      {
	fp->write("[");
	fp->write_decimal(arraysize);
	fp->write("]");
      }
    else if(arraysize == UNKNOWNSIZE)
      {
	fp->write("[UNKNOWN]");
      }
    fp->write("; ");
  } //printPostfix
Example #19
0
  UTI NodeCast::checkAndLabelType()
  {
    // unlike the other nodes, nodecast knows its type at construction time;
    // this is for checking for errors, before eval happens.
    u32 errorsFound = 0;
    UTI tobeType = getNodeType();
    UTI nodeType = isExplicitCast() ? m_node->checkAndLabelType() : m_node->getNodeType(); //user cast if explicit

    if(m_nodeTypeDesc)
      {
	//might be a mapped uti for instantiated template class
	tobeType = m_nodeTypeDesc->checkAndLabelType();
	setNodeType(tobeType); //overrides type set at parse time
	if(!m_nodeTypeDesc->isReadyType())
	  {
	    std::ostringstream msg;
	    msg << "Cannot cast to nonready type: " ;
	    msg << m_state.getUlamTypeNameBriefByIndex(tobeType).c_str();
	    msg << " (UTI" << tobeType << ")";
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
	    errorsFound++;
	  }
      }

    UlamType * tobe = m_state.getUlamTypeByIndex(tobeType);
    if(!m_state.isComplete(tobeType))
      {
	std::ostringstream msg;
	msg << "Cannot cast to incomplete type: " ;
	msg << m_state.getUlamTypeNameBriefByIndex(tobeType).c_str();
	msg << " (UTI" << tobeType << ")";
	MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
	errorsFound++;
      }
    else if(tobeType == Nav)
      {
	std::ostringstream msg;
	msg << "Cannot cast " << m_state.getUlamTypeNameBriefByIndex(nodeType).c_str();
	msg << " to not-a-valid type";
	MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	errorsFound++;
      }
    else if(tobe->getUlamClass() != UC_NOTACLASS && m_state.getUlamTypeByIndex(nodeType)->getUlamClass() == UC_NOTACLASS)
      {
	if(nodeType != UAtom)
	  {
	    std::ostringstream msg;
	    msg << "Cannot cast ";
	    msg << m_state.getUlamTypeNameBriefByIndex(nodeType).c_str();
	    msg << " to " << m_state.getUlamTypeNameBriefByIndex(tobeType).c_str();
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	    errorsFound++;
	  }
      }
    else if(isExplicitCast())
      {
	FORECAST scr = tobe->explicitlyCastable(nodeType);
	if(scr != CAST_CLEAR)
	  {
	    std::ostringstream msg;
	    msg << "Cannot explicitly cast ";
	    msg << m_state.getUlamTypeNameBriefByIndex(nodeType).c_str();
	    msg << " to type: " << m_state.getUlamTypeNameBriefByIndex(tobeType).c_str();
	    if(tobe->getUlamTypeEnum() == Bool)
	      msg << "; Consider using a comparison operator";
	    if(scr == CAST_HAZY)
	      MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
	    else
	      MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	    errorsFound++;
	  }
      }

    if(errorsFound == 0) //else
      {
	if(!m_state.isScalar(tobeType))
	  {
	    MSG(getNodeLocationAsString().c_str(),
		"Array casts currently not supported", ERR);
	    errorsFound++;

	    if(m_state.isScalar(nodeType))
	      {
		MSG(getNodeLocationAsString().c_str(),
		    "Consider implementing array casts: Cannot cast scalar into array", ERR);
		errorsFound++;
	      }
	    else if(m_state.getArraySize(tobeType) != m_state.getArraySize(nodeType))
	      {
		MSG(getNodeLocationAsString().c_str(),
		    "Consider implementing array casts: Array sizes differ", ERR);
		errorsFound++;
	      }
	  }
	else
	  {
	    //to be scalar type
	    if(!m_state.isScalar(nodeType))
	      {
		MSG(getNodeLocationAsString().c_str(),
		    "Consider implementing array casts: Cannot cast array into scalar", ERR);
		errorsFound++;
	      }
	  } // end not scalar errors

	// needs commandline arg..lots of non-explicit warning.
	// reserve for user requested casts;
	////if(isExplicitCast())
	//Node::warnOfNarrowingCast(nodeType, tobeType);
      }

    // special case: user casting a quark to an Int;
    if(errorsFound == 0)
      {
	ULAMCLASSTYPE nodeClass = m_state.getUlamTypeByIndex(nodeType)->getUlamClass();
	if(nodeClass == UC_QUARK)
	  {
	    if(!makeCastingNode(m_node, tobeType, m_node, isExplicitCast()))
	      errorsFound++;
	  }
	else
	  {
	    //classes are not surprisingly unknown bit sizes at this point
	    if(nodeClass == UC_UNSEEN)
	      {
		std::ostringstream msg;
		msg << "Cannot cast unseen class ";
		msg << m_state.getUlamTypeNameBriefByIndex(nodeType).c_str();
		msg << " to " << m_state.getUlamTypeNameByIndex(tobeType).c_str();
		MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
		errorsFound++;
	      }
	  }
      }

    if(errorsFound)
      return Nav; //inconsistent! but keeps cast type..makeCastingNode returns error

    return getNodeType();
  } //checkAndLabelType
Example #20
0
  void SymbolWithValue::printPostfixValueScalar(File * fp)
  {
    u64 val = 0;
    bool oktoprint = getValueReadyToPrint(val);

    if(oktoprint)
      {
	UTI tuti = getUlamTypeIdx();
	UlamType * tut = m_state.getUlamTypeByIndex(tuti);
	u32 twordsize =  tut->getTotalWordSize(); //must be commplete
	s32 tbs = tut->getBitSize();
	ULAMTYPE etyp = tut->getUlamTypeEnum();

	switch(etyp)
	  {
	  case Int:
	    {
	      if(twordsize <= MAXBITSPERINT)
		{
		  s32 sval = _Int32ToCs32((u32) val, tbs);
		  fp->write_decimal(sval);
		}
	      else if(twordsize <= MAXBITSPERLONG)
		{
		  s64 sval = _Int64ToCs64(val, tbs);
		  fp->write_decimal_long(sval);
		}
	      else
		m_state.abortGreaterThanMaxBitsPerLong();
	    }
	    break;
	  case Bool:
	    {
	      bool bval = _Bool64ToCbool(val, tbs);
	      if(bval)
		fp->write("true");
	      else
		fp->write("false");
	    }
	    break;
	  case Unary:
	  case Unsigned:
	  case Bits:
	    {
	      // NO CASTING NEEDED, assume saved in its ulam-native format
	      if( tbs <= MAXBITSPERINT)
		fp->write_decimal_unsigned(val);
	      else if( tbs <= MAXBITSPERLONG)
		fp->write_decimal_unsignedlong(val);
	      else
		m_state.abortGreaterThanMaxBitsPerLong(); //TBD > 64
	      fp->write("u");
	    }
	    break;
	  case String:
	    // scalar strings generate comments (output value rather than index) e.g. t3951,2
	    fp->write(m_state.getDataAsFormattedUserString(val).c_str());
	    break;
	  default:
	    m_state.abortUndefinedUlamPrimitiveType();
	  };
      }
    else
      fp->write("NONREADYCONST");
  } //printPostfixValueScalar
Example #21
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
Example #22
0
  UTI NodeMemberSelect::checkAndLabelType()
  {
    assert(m_nodeLeft && m_nodeRight);

    UTI luti = m_nodeLeft->checkAndLabelType(); //side-effect
    TBOOL lstor = m_nodeLeft->getStoreIntoAble();
    if(lstor != TBOOL_TRUE)
      {
	//e.g. funcCall is not storeintoable even if its return value is.
	std::ostringstream msg;
	msg << "Member selected must be a valid lefthand side: '";
	msg << m_nodeLeft->getName();
	msg << "' requires a variable; may be a casted function call";
	if(lstor == TBOOL_HAZY)
	  {
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT);
	    setNodeType(Hzy);
	    m_state.setGoAgain();
	    return Hzy;
	  }
	else
	  {
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	    setNodeType(Nav);
	    return Nav;
	  }
      } //done

    if(!m_state.isComplete(luti))
      {
	std::ostringstream msg;
	msg << "Member selected is incomplete class: ";
	msg << m_state.getUlamTypeNameBriefByIndex(luti).c_str();
	msg << ", check and label fails this time around";
	if(luti == Nav)
	  {
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	    setNodeType(Nav);
	  }
	else
	  {
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT);
	    setNodeType(Hzy);
	    m_state.setGoAgain(); //since no error msg
	  }
	return getNodeType();
      } //done

    UlamType * lut = m_state.getUlamTypeByIndex(luti);
    ULAMCLASSTYPE classtype = lut->getUlamClassType();
    if(((classtype == UC_NOTACLASS) && (lut->getUlamTypeEnum() != Holder)) || !lut->isScalar())
      {
	// must be a scalar 'Class' type, (e.g. error/t3815)
	// doesn't complete checkandlabel for rhs (e.g. funccall is NULL, no eval)
	std::ostringstream msg;
	msg << "Member selected must be a Class, not type: ";
	msg << m_state.getUlamTypeNameBriefByIndex(luti).c_str();
	if(classtype != UC_NOTACLASS)
	  msg << "[" << lut->getArraySize() << "]";
	if(m_state.isAtom(luti))
	  msg << "; suggest using a Conditional-As";
	MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	setNodeType(Nav);
	return Nav;
      } //done

    std::string className = m_state.getUlamTypeNameBriefByIndex(luti); //help me debug

    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())); //t41010

   //set up compiler state to use the member class block for symbol searches
    m_state.pushClassContextUsingMemberClassBlock(memberClassNode);

    UTI rightType = m_nodeRight->checkAndLabelType();

    //clear up compiler state to no longer use the member class block for symbol searches
    m_state.popClassContext();

    setNodeType(rightType); //set Nav if error (t3513)

    if(m_state.okUTItoContinue(rightType))
      {
	//based on righthand side
	Node::setStoreIntoAble(m_nodeRight->getStoreIntoAble());

	//base reference-ability on righthand side (t41085)
	Node::setReferenceAble(m_nodeRight->getReferenceAble());
      }
    return getNodeType();
  } //checkAndLabelType
Example #23
0
  FORECAST NodeVarRef::safeToCastTo(UTI newType)
  {
    assert(m_nodeInitExpr);
    UTI nuti = getNodeType();

    //cast RHS if necessary and safe
    //insure lval is same bitsize/arraysize
    // if classes, safe to cast a subclass to any of its superclasses
    FORECAST rscr = CAST_CLEAR;
    if(UlamType::compare(nuti, newType, m_state) != UTIC_SAME)
      {
	UlamType * nut = m_state.getUlamTypeByIndex(nuti);
	UlamType * newt = m_state.getUlamTypeByIndex(newType);
	rscr = m_nodeInitExpr->safeToCastTo(nuti);

	if((nut->getUlamTypeEnum() == Class))
	  {
	    if(rscr != CAST_CLEAR)
	      {
		//e.g. error/t3792, error/t3616
		std::ostringstream msg;
		msg << "Incompatible class types ";
		msg << nut->getUlamTypeClassNameBrief(nuti).c_str();
		msg << " and ";
		msg << m_state.getUlamTypeNameBriefByIndex(newType).c_str();
		msg << " used to initialize reference '" << getName() <<"'";
		if(rscr == CAST_HAZY)
		  MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
		else
		  MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	      }
	  }
	else if(m_state.isAtom(nuti))
	  {
	    //atoms init from a quark ref could use .atomof
	    // "clear" when complete, not the same as "bad".
	    if(rscr != CAST_CLEAR)
	      {
		std::ostringstream msg;
		msg << "Reference atom variable " << getName() << "'s type ";
		msg << nut->getUlamTypeNameBrief().c_str();
		msg << ", and its initial value type ";
		msg << m_state.getUlamTypeNameBriefByIndex(newType).c_str();
		msg << ", are incompatible";
		if(newt->isAltRefType() && newt->getUlamClassType() == UC_QUARK)
		  msg << "; .atomof may help";
		if(rscr == CAST_HAZY)
		  MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
		else
		  MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	      }
	  }
	else
	  {
	    //primitives must be EXACTLY the same size (for initialization);
	    // "clear" when complete, not the same as "bad". (t3614, t3694)
	    if(rscr != CAST_CLEAR)
	      {
		std::ostringstream msg;
		msg << "Reference variable " << getName() << "'s type ";
		msg << m_state.getUlamTypeNameBriefByIndex(nuti).c_str();
		msg << ", and its initial value type ";
		msg << m_state.getUlamTypeNameBriefByIndex(newType).c_str();
		msg << ", are incompatible";
		if(rscr == CAST_HAZY)
		  MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
		else
		  MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	      }
	    else if(m_nodeInitExpr->isAConstant() && !m_state.isConstantRefType(nuti))
	      {
		std::ostringstream msg;
		msg << "Initial value of non-constant reference variable: " << getName();
		msg << " is constant";
		MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); //error/t41255
		rscr = CAST_BAD;
	      }
	  }
      }
    //okay to explicitly cast rhs to reference type, e.g. if(a is Foo) QW& qref = (Foo &) a;
    return rscr;
  } //safeToCastTo
Example #24
0
  UTI NodeBinaryOpEqualShift::checkAndLabelType()
  {
    //UTI nodeType = NodeBinaryOp::checkAndLabelType(); //dup Shift calcNodeType

    assert(m_nodeLeft && m_nodeRight);

    UTI leftType = m_nodeLeft->checkAndLabelType();
    UTI rightType = m_nodeRight->checkAndLabelType();

    if(!m_state.okUTItoContinue(leftType))
      {
	//left type possibly a class w overload operator; no need to check right type here;
	setNodeType(leftType);
	return getNodeType();
      }

    // efficiency bites! no sooner, need left and right side-effects
    // (e.g. NodeControl condition is Bool at start; stubs need Symbol ptrs)
    if(m_state.isComplete(getNodeType()))
      return getNodeType();

    //replace node with func call to matching function overload operator for class
    // of left, with argument of right;
    UlamType * lut = m_state.getUlamTypeByIndex(leftType);
    if((lut->getUlamTypeEnum() == Class))
      {
	Node * newnode = buildOperatorOverloadFuncCallNode(); //virtual
	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();
	  }
	//else should fail again as non-primitive;
      } //done

    UTI newType = calcNodeType(leftType, rightType); //does safety check

    setNodeType(newType);

    if(m_state.okUTItoContinue(newType))
      {
	TBOOL stor = NodeBinaryOpEqual::checkStoreIntoAble();
	if(stor == TBOOL_FALSE)
	  {
	    setNodeType(Nav);
	    return Nav; //newType
	  }
	else if(stor == TBOOL_HAZY)
	  {
	    setNodeType(Hzy);
	    m_state.setGoAgain();
	  }

	if(!NodeBinaryOpEqual::checkNotUnpackedArray())
	  {
	    setNodeType(Nav);
	    return Nav;
	  }
      }

    if(m_state.isComplete(newType))
      {
	//lhs must be Bits; can't cast lhs of equal.

	//shift by unsigned type; cast if need be. safety checked by calcNodeType.
	if(m_state.getUlamTypeByIndex(rightType)->getUlamTypeEnum() != Unsigned)
	  {
	    if(!Node::makeCastingNode(m_nodeRight, Unsigned, m_nodeRight))
	      {
		newType = Nav;
		setNodeType(Nav);
	      }
	  }
      } //complete

    return getNodeType();
  } //checkandlabeltype
Example #25
0
  // 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
Example #26
0
  bool SymbolWithValue::convertValueToALexString(u64 varg, UTI tuti, std::string& vstr, CompilerState & state)
  {
    //UTI tuti = getUlamTypeIdx();
    UlamType * tut = state.getUlamTypeByIndex(tuti);
    s32 bs = tut->getBitSize();
    ULAMTYPE etyp = tut->getUlamTypeEnum();
    switch(etyp)
      {
      case Int:
	{
	  if(bs <= MAXBITSPERINT)
	    {
	      s32 sval = _Int32ToInt32((u32) varg, bs, MAXBITSPERINT);
	      vstr = ToLeximitedNumber(sval);
	    }
	  else if(bs <= MAXBITSPERLONG)
	    {
	      s64 sval = _Int64ToInt64(varg, bs, MAXBITSPERLONG);
	      vstr = ToLeximitedNumber64(sval);
	    }
	  else
	    state.abortGreaterThanMaxBitsPerLong();
	}
	break;
      case Bool:
	{
	  bool bval = _Bool64ToCbool(varg, bs);
	  if(bval)
	    vstr = ToLeximitedNumber(1); //true
	  else
	    vstr = ToLeximitedNumber(0); //false
	}
	break;
      case Unary:
	{
	  s32 pval = _Unary64ToInt64(varg, bs, MAXBITSPERINT);
	  vstr = ToLeximitedNumber(pval);
	}
	break;
      case Unsigned:
      case Bits:
	{
	  if( bs <= MAXBITSPERINT)
	    vstr = ToLeximitedNumber((u32) varg);
	  else if( bs <= MAXBITSPERLONG)
	    vstr = ToLeximitedNumber64(varg);
	  else
	    state.abortGreaterThanMaxBitsPerLong();
	}
	break;
      case String:
	{
	  std::ostringstream fhex;
	  std::string fstr = state.getDataAsUnFormattedUserString((u32) varg);
	  u32 flen = fstr.length() - 1; //exclude null terminator
	  for(u32 i = 0; i < flen; i++)
	    fhex << std::hex << std::setfill('0') << std::setw(2) << (u32) fstr[i];
	  vstr = fhex.str();
	}
	break;
      default:
	state.abortUndefinedUlamPrimitiveType();
      };
    return true;
  } //convertValueToLexString (static helper)
Example #27
0
  UTI NodeTypedef::checkAndLabelType()
  {
    UTI it = Nav;

    // instantiate, look up in current block
    if(m_typedefSymbol == NULL)
      checkForSymbol();

    if(m_typedefSymbol)
      {
	//m_typedefSymbol is the (rhs) type alias
	it = m_typedefSymbol->getUlamTypeIdx();

	//check for UNSEEN Class' ClassType (e.g. array of UC_QUARK)
	UlamType * tdut = m_state.getUlamTypeByIndex(it);
	if((tdut->getUlamTypeEnum() == Class) && (tdut->getUlamClassType() == UC_UNSEEN))
	  {
	    if(!m_state.completeIncompleteClassSymbolForTypedef(it))
	      {
		std::ostringstream msg;
		msg << "Incomplete Typedef for class type: ";
		msg << m_state.getUlamTypeNameBriefByIndex(it).c_str();
		msg << ", used with variable symbol name <" << getName() << ">";
		MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT);
	      }
	  }
	else if(tdut->isHolder() && !m_state.isThisLocalsFileScope())
	  {
	    m_state.statusUnknownTypeInThisClassResolver(it);
	  }

	UTI cuti = m_state.getCompileThisIdx();
	if(m_nodeTypeDesc)
	  {
	    UTI duti = m_nodeTypeDesc->checkAndLabelType(); //sets goagain if nav
	    if(m_state.okUTItoContinue(duti) && (duti != it))
	      {
		std::ostringstream msg;
		msg << "REPLACING Symbol UTI" << it;
		msg << ", " << m_state.getUlamTypeNameBriefByIndex(it).c_str();
		msg << " used with typedef symbol name '" << getName();
		msg << "' with node type descriptor type: ";
		msg << m_state.getUlamTypeNameBriefByIndex(duti).c_str();
		msg << " UTI" << duti << " while labeling class: ";
		msg << m_state.getUlamTypeNameBriefByIndex(cuti).c_str();
		MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
		m_state.mapTypesInCurrentClass(it, duti);
		m_state.updateUTIAliasForced(it, duti); //t3379
		m_typedefSymbol->resetUlamType(duti); //consistent! (must be same ref type)
		it = duti;
	      }
	  }

	if(!m_state.okUTItoContinue(it) || !m_state.isComplete(it)) //reloads
	  {
	    std::ostringstream msg;
	    msg << "Incomplete Typedef for type: ";
	    msg << m_state.getUlamTypeNameBriefByIndex(it).c_str();
	    msg << ", used with typedef symbol name '" << getName() << "'";
	    if(m_state.okUTItoContinue(it) || (it == Hzy))
	      {
		MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT);
		m_state.setGoAgain(); //since not error; unlike vardecl
	      }
	    else
	      MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	  }
      } // got typedef symbol

    setNodeType(it);
    return getNodeType();
  } //checkAndLabelType
Example #28
0
  // replaces NodeVarDecl:printPostfix to learn the values of Class' storage in center site
  void SymbolVariableDataMember::printPostfixValuesOfVariableDeclarations(File * fp, s32 slot, u32 startpos, ULAMCLASSTYPE classtype)
  {
    UTI vuti = getUlamTypeIdx();
    UlamKeyTypeSignature vkey = m_state.getUlamKeyTypeSignatureByIndex(vuti);
    UlamType * vut = m_state.getUlamTypeByIndex(vuti);
    ULAMCLASSTYPE vclasstype = vut->getUlamClassType();
    ULAMTYPE vetyp = vut->getUlamTypeEnum();

    fp->write(" ");
    if(vclasstype == UC_NOTACLASS)
      fp->write(vkey.getUlamKeyTypeSignatureNameAndBitSize(&m_state).c_str());
    else
      fp->write(vut->getUlamTypeNameBrief().c_str());

    fp->write(" ");
    fp->write(m_state.m_pool.getDataAsString(getId()).c_str());

    s32 arraysize = m_state.getArraySize(vuti);
    //scalar has 'size=1'; empty array [0] is still '0'.
    s32 size = (arraysize > NONARRAYSIZE ? arraysize : 1);

    //output the arraysize (optional), and open paren
    if(arraysize > NONARRAYSIZE)
      {
	fp->write("[");
	fp->write_decimal(arraysize);
	fp->write("]");
      }
    else if(arraysize == UNKNOWNSIZE)
      {
	fp->write("[UNKNOWN]");
      }

    fp->write("(");

    if(vclasstype == UC_QUARK)
      {
	//outputs the data members, not just the lump value (e.g. SWV::printPostfixValue())
	UTI scalarquark = m_state.getUlamTypeAsScalar(vuti);
	//printPostfixValuesForClass:
	SymbolClass * csym = NULL;
	AssertBool isDefined = m_state.alreadyDefinedSymbolClass(scalarquark, csym);
	assert(isDefined);

	NodeBlockClass * classNode = csym->getClassBlockNode();
	assert(classNode);
	u32 newstartpos = startpos + getPosOffset();
	s32 len = vut->getBitSize();
	for(s32 i = 0; i < size; i++)
	  classNode->printPostfixDataMembersSymbols(fp, slot, newstartpos + len * i, vclasstype);
      }
    else
      {
	PACKFIT packFit = m_state.determinePackable(vuti);
	assert(WritePacked(packFit)); //has to be to fit in an atom/site;

	char * valstr = new char[size * 8 + MAXBITSPERLONG]; //was 32

	if(size > 0)
	  {
	    //build the string of values (for both scalar and packed array)
	    UlamValue arrayPtr = UlamValue::makePtr(slot, EVENTWINDOW, vuti, packFit, m_state, startpos + getPosOffset(), getId());
	    UlamValue nextPtr = UlamValue::makeScalarPtr(arrayPtr, m_state);

	    UlamValue atval = m_state.getPtrTarget(nextPtr);
	    s32 len = m_state.getBitSize(vuti);
	    if(len == UNKNOWNSIZE)
	      {
		sprintf(valstr,"unknown");
		for(s32 i = 1; i < size; i++)
		  {
		    strcat(valstr,", unknown");
		  }
	      }
	    else if(len <= MAXBITSPERINT)
	      {
		u32 data = atval.getDataFromAtom(nextPtr, m_state);
		vut->getDataAsString(data, valstr, 'z'); //'z' -> no preceeding ','
		if(vetyp == Unsigned || vetyp == Unary)
		  strcat(valstr, "u");

		for(s32 i = 1; i < size; i++)
		  {
		    char tmpstr[8];
		    AssertBool isNext = nextPtr.incrementPtr(m_state);
		    assert(isNext);
		    atval = m_state.getPtrTarget(nextPtr);
		    data = atval.getDataFromAtom(nextPtr, m_state);
		    vut->getDataAsString(data, tmpstr, ',');
		    if(vetyp == Unsigned || vetyp == Unary)
		      strcat(tmpstr, "u");
		    strcat(valstr,tmpstr);
		  }
	      }
	    else if(len <= MAXBITSPERLONG)
	      {
		u64 data = atval.getDataLongFromAtom(nextPtr, m_state);
		vut->getDataLongAsString(data, valstr, 'z'); //'z' -> no preceeding ','
		if(vetyp == Unsigned || vetyp == Unary)
		  strcat(valstr, "u");

		for(s32 i = 1; i < size; i++)
		  {
		    char tmpstr[8];
		    AssertBool isNext = nextPtr.incrementPtr(m_state);
		    assert(isNext);
		    atval = m_state.getPtrTarget(nextPtr);
		    data = atval.getDataLongFromAtom(nextPtr, m_state);
		    vut->getDataLongAsString(data, tmpstr, ',');
		    if(vetyp == Unsigned || vetyp == Unary)
		      strcat(tmpstr, "u");
		    strcat(valstr,tmpstr);
		  }
	      }
	    else
	      assert(0);

	  } //end arrays > 0, and scalar
	else
	  {
	    sprintf(valstr," ");
	  }

	fp->write(valstr); //results out here!
	delete [] valstr;
      } //not a quark
    fp->write("); ");
  } //printPostfixValuesOfVariableDeclarations
Example #29
0
  //short-circuit when lhs is true
  void NodeBinaryOpLogicalOr::genCode(File * fp, UVPass& uvpass)
  {
    assert(m_nodeLeft && m_nodeRight);
    assert(m_state.m_currentObjSymbolsForCodeGen.empty()); //*************

    //initialize node result to false
    UTI nuti = getNodeType();
    UlamType * nut = m_state.getUlamTypeByIndex(nuti);
    s32 tmpVarNum = m_state.getNextTmpVarNumber();

    m_state.indentUlamCode(fp);
    //fp->write("const ");
    fp->write(nut->getTmpStorageTypeAsString().c_str()); //e.g. u32, s32, u64..
    fp->write(" ");
    fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum, TMPREGISTER).c_str());
    fp->write(" = false;"); GCNL;

    //process lhs first
    UVPass luvpass;
    m_nodeLeft->genCode(fp, luvpass); //updates m_currentObjSymbol
    UTI luti = luvpass.getPassTargetType();
    UlamType * lut = m_state.getUlamTypeByIndex(luti);
    assert(lut->getUlamTypeEnum() == Bool);

    //fp->write("\n");

    m_state.indentUlamCode(fp);
    fp->write("if(!"); //lhs is false
    fp->write(((UlamTypePrimitiveBool *) lut)->getConvertToCboolMethod().c_str());
    fp->write("(");
    fp->write(luvpass.getTmpVarAsString(m_state).c_str());
    fp->write(", ");
    fp->write_decimal(lut->getBitSize());
    fp->write(")");
    fp->write(")"); GCNL;

    m_state.indentUlamCode(fp);
    fp->write("{\n");
    m_state.m_currentIndentLevel++;

    UVPass ruvpass;
    m_nodeRight->genCode(fp, ruvpass);

    //set node's tmp var to whatever rhs value
    m_state.indentUlamCode(fp);
    fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum, TMPREGISTER).c_str());
    fp->write(" = ");
    fp->write(ruvpass.getTmpVarAsString(m_state).c_str());
    fp->write(";"); GCNL;

    m_state.m_currentIndentLevel--;
    m_state.indentUlamCode(fp);
    fp->write("}\n");

    m_state.indentUlamCode(fp);
    fp->write("else\n");
    m_state.indentUlamCode(fp);
    fp->write("{\n");
    m_state.m_currentIndentLevel++;

    //set node's tmp var to lhs value (true)
    m_state.indentUlamCode(fp);
    fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum, TMPREGISTER).c_str());
    fp->write(" = ");
    fp->write(luvpass.getTmpVarAsString(m_state).c_str());
    fp->write(";"); GCNL;

    m_state.m_currentIndentLevel--;
    m_state.indentUlamCode(fp);
    fp->write("}\n");

    uvpass = UVPass::makePass(tmpVarNum, TMPREGISTER, nuti, m_state.determinePackable(nuti), m_state, 0, 0); //P
    assert(m_state.m_currentObjSymbolsForCodeGen.empty()); //*************
  } //genCode
  bool NodeTypeDescriptorSelect::resolveType(UTI& rtnuti)
  {
    bool rtnb = false;
    if(isReadyType())
      {
	rtnuti = getNodeType();
	return true;
      }

    // we are in a "chain" of type selects..
    assert(m_nodeSelect);

    UTI seluti = m_nodeSelect->checkAndLabelType();
    if(m_nodeSelect->isReadyType())
      {
	UlamType * selut = m_state.getUlamTypeByIndex(seluti);
	ULAMTYPE seletype = selut->getUlamTypeEnum();
	if(seletype == Class)
	  {
	    SymbolClass * csym = NULL;
	    assert(m_state.alreadyDefinedSymbolClass(seluti, csym));

	    m_state.pushClassContext(seluti, csym->getClassBlockNode(), csym->getClassBlockNode(), false, NULL);
	    // find our id in the "selected" class, must be a typedef at top level
	    Symbol * asymptr = NULL;
	    if(m_state.alreadyDefinedSymbol(m_typeTok.m_dataindex, asymptr))
	      {
		if(asymptr->isTypedef())
		  {
		    UTI auti = asymptr->getUlamTypeIdx();
		    if(m_state.isComplete(auti))
		      {
			rtnuti = auti; //should be mapped already, if necessary
			rtnb = true;
		      }
		    else if(m_state.isHolder(auti))
		      {
			UTI mappedUTI;
			if(m_state.mappedIncompleteUTI(seluti, auti, mappedUTI))
			  {
			    std::ostringstream msg;
			    msg << "Substituting Mapped UTI" << mappedUTI << ", ";
			    msg << m_state.getUlamTypeNameBriefByIndex(mappedUTI).c_str();
			    msg << " for incomplete descriptor type: ";
			    msg << m_state.getUlamTypeNameBriefByIndex(auti).c_str();
			    msg << "' UTI" << auti << " while labeling class: ";
			    msg << m_state.getUlamTypeNameBriefByIndex(seluti).c_str();
			    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
			    auti = mappedUTI;
			  }
		      }
		  }
		else
		  {
		    //error id is not a typedef
		    std::ostringstream msg;
		    msg << "Not a typedef <" << m_state.getTokenDataAsString(&m_typeTok).c_str();
		    msg << "> in another class, " ;;
		    msg << m_state.getUlamTypeNameBriefByIndex(seluti).c_str();
		    msg <<" while compiling: ";
		    msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str();
		    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WARN);
		  }
	      }
	    else
	      {
		//error! id not found
		std::ostringstream msg;
		msg << "Undefined Typedef <" << m_state.getTokenDataAsString(&m_typeTok).c_str();
		msg << "> in another class, " ;;
		msg << m_state.getUlamTypeNameBriefByIndex(seluti).c_str();
		msg <<" while compiling: ";
		msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str();
		MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
	      }

	    m_state.popClassContext();
	  }
	else
	  {
	    //error has to be a class
	    std::ostringstream msg;
	    msg << "Type selected by <" << m_state.getTokenDataAsString(&m_typeTok).c_str();
	    msg << "> is NOT another class, " ;
	    msg << m_state.getUlamTypeNameBriefByIndex(seluti).c_str();
	    msg << ", rather a " << UlamType::getUlamTypeEnumAsString(seletype) << " type,";
	    msg <<" while compiling: ";
	    msg << m_state.getUlamTypeNameBriefByIndex(m_state.getCompileThisIdx()).c_str();
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	  }
      } //else select not ready, so neither are we!!
    return rtnb;
  } //resolveType