Exemplo n.º 1
0
  bool SymbolWithValue::getArrayValueAsString(std::string& vstr)
  {
    BV8K dval;
    bool oktoprint = getValueReadyToPrint(dval);

    if(!oktoprint) return false;

    UTI tuti = getUlamTypeIdx();
    UlamType * tut = m_state.getUlamTypeByIndex(tuti);

    if(tut->getTotalBitSize() == 0)
      {
	vstr = "10"; //empty array
	return true;
      }

    //get the number of bits for this type into u64
    // convert to a lex-number as a string, applying type specifics
    // return the completed string of all the array values in arg vstr.
    std::ostringstream tovstr;
    s32 bs = tut->getBitSize();
    s32 arraysize = tut->getArraySize();
    for(s32 i=0; i < arraysize; i++)
      {
	u64 thisval = dval.ReadLong(i * bs, bs); //pos and len
	std::string str;
	convertValueToALexString(thisval, tuti, str, m_state);
	tovstr << str;
      }
    vstr = tovstr.str();
    return true;
  } //getArrayValueAsString
Exemplo n.º 2
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
Exemplo n.º 3
0
  // replaced by NodeVarDecl:genCode to leverage the declaration order preserved by the parse tree.
  void SymbolVariableDataMember::generateCodedVariableDeclarations(File * fp, ULAMCLASSTYPE classtype)
  {
    assert(classtype == UC_ELEMENT); //really?
    UTI vuti = getUlamTypeIdx();
    UlamType * vut = m_state.getUlamTypeByIndex(vuti);
    ULAMCLASSTYPE vclasstype = vut->getUlamClassType();

    m_state.indentUlamCode(fp);
    fp->write(vut->getUlamTypeMangledName().c_str()); //for C++

    if(vclasstype == UC_QUARK) //called on classtype elements only
      {
	fp->write("<");
	fp->write_decimal(getPosOffset());
	fp->write(">");
      }
    fp->write(" ");
    fp->write(getMangledName().c_str());

#if 0
    s32 arraysize = vut->getArraySize();
    if(arraysize > NONARRAYSIZE)
      {
	fp->write("[");
	fp->write_decimal(arraysize);
	fp->write("]");
      }
    else if(arraysize == UNKNOWNSIZE)
      {
	fp->write("[UNKNOWN]");
      }
#endif
    fp->write(";"); GCNL;
  } //generateCodedVariableDeclarations
Exemplo n.º 4
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
Exemplo n.º 5
0
  //atomic parameter type, not model parameter.
  const std::string Symbol::getMangledNameForParameterType()
  {
    assert(!isModelParameter());

    UlamType * sut = m_state.getUlamTypeByIndex(getUlamTypeIdx());
    ULAMCLASSTYPE classtype = sut->getUlamClass();

    //another way, like this?
    if(isModelParameter())
      {
	std::ostringstream epmangled;
	epmangled << sut->getImmediateModelParameterStorageTypeAsString();
	//if(classtype == UC_QUARK)
	//  epmangled << "::Us";
	assert(classtype == UC_NOTACLASS);
	return epmangled.str();
      }

    // to distinguish btn an atomic parameter typedef and quark typedef;
    // use atomic parameter with array of classes
    bool isaclass = (( classtype == UC_QUARK || classtype == UC_ELEMENT || classtype == UC_UNSEEN) && sut->isScalar());

    std::ostringstream pmangled;
    pmangled << Symbol::getParameterTypePrefix(isaclass).c_str() << getMangledName();
    return pmangled.str();
  } //getMangledNameForParameterType
Exemplo n.º 6
0
  UlamValue NodeInstanceof::makeUlamValuePtr()
  {
    // (from NodeVarDecl's makeUlamValuePtr)
    UlamValue ptr;
    UlamValue atomuv;

    UTI auti = getOfType();
    UlamType * aut = m_state.getUlamTypeByIndex(auti);
    ULAMCLASSTYPE aclasstype = aut->getUlamClassType();

    u32 atop = 1;
    atop = m_state.m_funcCallStack.getAbsoluteStackIndexOfSlot(atop);
    if(m_state.isAtom(auti))
      atomuv = UlamValue::makeAtom(auti);
    else if(aclasstype == UC_ELEMENT)
      atomuv = UlamValue::makeDefaultAtom(auti, m_state);
    else if(aclasstype == UC_QUARK)
      {
	u32 dq = 0;
	AssertBool isDefinedQuark = m_state.getDefaultQuark(auti, dq); //returns scalar dq
	assert(isDefinedQuark);
	atomuv = UlamValue::makeImmediateClass(auti, dq, aut->getTotalBitSize());
      }
    else if(aclasstype == UC_TRANSIENT)
      atomuv = UlamValue::makeDefaultAtom(auti, m_state); //size limited to atom for eval
    else
      m_state.abortUndefinedUlamClassType();

    m_state.m_funcCallStack.storeUlamValueAtStackIndex(atomuv, atop); //stackframeslotindex ?

    ptr = UlamValue::makePtr(atop, STACK, auti, m_state.determinePackable(auti), m_state, 0);
    ptr.setUlamValueTypeIdx(PtrAbs);
    return ptr;
  } //makeUlamValuePtr
Exemplo n.º 7
0
  void NodeVarRefAs::genCodeRefAsSelf(File * fp, UVPass& uvpass)
  {
    //no tmpref needed since 'self' (i.e. ur) is already a C++ reference
    //t3821, t3815 (transient), t3828 (quark)
    Symbol * stgcos = m_state.m_currentObjSymbolsForCodeGen[0];

    UTI vuti = m_varSymbol->getUlamTypeIdx();
    UlamType * vut = m_state.getUlamTypeByIndex(vuti);

    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(stgcos->getMangledName().c_str()); //stg
    fp->write(", 0u, ");
    fp->write(stgcos->getMangledName().c_str()); //stg
    fp->write(".GetEffectiveSelf()");
    fp->write("); //shadows lhs of 'as'"); GCNL;

    m_state.indentUlamCode(fp);
    fp->write("UlamRef<EC>& ur = ");
    fp->write(m_varSymbol->getMangledName().c_str());
    fp->write("; //shadows self"); GCNL;

    m_varSymbol->setIsSelf(); //nope

    m_state.clearCurrentObjSymbolsForCodeGen(); //clear remnant of lhs
  } //genCodeRefAsSelf
Exemplo n.º 8
0
  EvalStatus NodeVarRefAs::eval()
  {
    assert(m_varSymbol);

    UTI nuti = getNodeType();
    if(nuti == Nav)
      return ERROR;

    if(nuti == Hzy)
      return NOTREADY;

    assert(m_varSymbol->getUlamTypeIdx() == nuti);
    assert(!m_state.isAtom(nuti)); //rhs type of conditional as/has can't be an atom

    UlamValue pluv = m_state.m_currentAutoObjPtr;
    ((SymbolVariableStack *) m_varSymbol)->setAutoPtrForEval(pluv); //for future ident eval uses

    UTI luti = pluv.getPtrTargetType();
    assert(m_state.okUTItoContinue(luti));
    UlamType * lut = m_state.getUlamTypeByIndex(luti);
    ULAMCLASSTYPE lclasstype = lut->getUlamClassType();
    UTI autostgtype = m_state.m_currentAutoStorageType;
    if((UlamType::compare(autostgtype, UAtom, m_state) == UTIC_SAME) && (lclasstype == UC_ELEMENT))
       autostgtype = luti; //e.g. funccall expects a class, not an atom (t3636)

    ((SymbolVariableStack *) m_varSymbol)->setAutoStorageTypeForEval(autostgtype); //for future virtual function call eval uses

    //m_state.m_funcCallStack.storeUlamValueInSlot(pluv, ((SymbolVariableStack *) m_varSymbol)->getStackFrameSlotIndex()); //doesn't seem to matter..

    return NORMAL;
  } //eval
Exemplo n.º 9
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
Exemplo n.º 10
0
  const std::string UlamType::castMethodForCodeGen(UTI nodetype)
  {
    std::ostringstream rtnMethod;
    UlamType * nut = m_state.getUlamTypeByIndex(nodetype);
    //base types e.g. Int, Bool, Unary, Foo, Bar..
    u32 sizeByIntBitsToBe = getTotalWordSize();
    u32 sizeByIntBits = nut->getTotalWordSize();

    if(sizeByIntBitsToBe != sizeByIntBits)
      {
	std::ostringstream msg;
	msg << "Casting different word sizes; " << sizeByIntBits;
	msg << ", Value Type and size was: " << nut->getUlamTypeName().c_str();
	msg << ", to be: " << sizeByIntBitsToBe << " for type: ";
	msg << getUlamTypeName().c_str();
	MSG(m_state.getFullLocationAsString(m_state.m_locOfNextLineText).c_str(), msg.str().c_str(), DEBUG);

	//use the larger word size
	if(sizeByIntBitsToBe < sizeByIntBits) //downcast using larger
	  sizeByIntBitsToBe = sizeByIntBits;
	else
	  sizeByIntBits = sizeByIntBitsToBe;
      }
    rtnMethod << "_" << nut->getUlamTypeNameOnly().c_str() << sizeByIntBits << "To";
    rtnMethod << getUlamTypeNameOnly().c_str() << sizeByIntBitsToBe;
    return rtnMethod.str();
  } //castMethodForCodeGen
Exemplo n.º 11
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
Exemplo n.º 12
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
Exemplo n.º 13
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
Exemplo n.º 14
0
  void NodeUnaryOp::genCode(File * fp, UVPass& uvpass)
  {
    assert(m_node);
    m_node->genCode(fp, uvpass);

    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(" = ");

    fp->write(methodNameForCodeGen().c_str());
    fp->write("(");
    fp->write(uvpass.getTmpVarAsString(m_state).c_str());
    fp->write(", ");
    fp->write_decimal(nut->getBitSize());
    fp->write(");"); GCNL;

    uvpass = UVPass::makePass(tmpVarNum, TMPREGISTER, nuti, m_state.determinePackable(nuti), m_state, 0, 0); //POS 0 rightjustified.
  } //genCode
Exemplo n.º 15
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
Exemplo n.º 16
0
  FORECAST NodeConstantArray::safeToCastTo(UTI newType)
  {
    if(isReadyConstant())
      {
	UlamType * newut = m_state.getUlamTypeByIndex(newType);
	return newut->safeCast(getNodeType());
      }
    return CAST_HAZY;
  } //safeToCastTo
Exemplo n.º 17
0
  void NodeConstantArray::makeUVPassForCodeGen(UVPass& uvpass)
  {
    assert(m_constSymbol);
    s32 tmpnum = m_state.getNextTmpVarNumber();
    UTI nuti = getNodeType();
    UlamType * nut = m_state.getUlamTypeByIndex(nuti);

    uvpass = UVPass::makePass(tmpnum, nut->getTmpStorageTypeForTmpVar(), nuti, m_state.determinePackable(nuti), m_state, 0, m_constSymbol->getId());
  }
Exemplo n.º 18
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)
Exemplo n.º 19
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
Exemplo n.º 20
0
  void NodeBinaryOpEqualShift::genCode(File * fp, UVPass& uvpass)
  {
    assert(m_nodeLeft && m_nodeRight);
    assert(m_state.m_currentObjSymbolsForCodeGen.empty());

    // generate rhs first; may update current object globals (e.g. function call)
    UVPass ruvpass;
    m_nodeRight->genCode(fp, ruvpass);

    // restore current object globals
    assert(m_state.m_currentObjSymbolsForCodeGen.empty());

    // lhs should be the new current object: node member select updates them,
    // but a plain NodeIdent does not!!!  because genCodeToStoreInto has been repurposed
    // to mean "don't read into a TmpVar" (e.g. by NodeCast).
    UVPass luvpass;
    m_nodeLeft->genCodeToStoreInto(fp, luvpass); //may update m_currentObjSymbol

    //wiped out by left read; need to write back into left
    std::vector<Symbol *> saveCOSVector = m_state.m_currentObjSymbolsForCodeGen;
    uvpass = luvpass; //keep luvpass slot untouched
    Node::genCodeReadIntoATmpVar(fp, uvpass);
    m_state.m_currentObjSymbolsForCodeGen = saveCOSVector; //restore vector after lhs read*************

    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(" = ");

    fp->write(methodNameForCodeGen().c_str());
    fp->write("(");
    fp->write(uvpass.getTmpVarAsString(m_state).c_str());
    fp->write(", ");
    fp->write(ruvpass.getTmpVarAsString(m_state).c_str());
    fp->write(", ");
    fp->write_decimal(nut->getBitSize());
    fp->write(");"); GCNL;

    uvpass = UVPass::makePass(tmpVarNum, TMPREGISTER, nuti, m_state.determinePackable(nuti), m_state, uvpass.getPassPos(), uvpass.getPassNameId()); //P

    // current object globals should pertain to lhs for the write
    genCodeWriteFromATmpVar(fp, luvpass, uvpass); //uses rhs' tmpvar; orig lhs

    assert(m_state.m_currentObjSymbolsForCodeGen.empty());
  } //genCode
Exemplo n.º 21
0
  bool NodeMemberSelect::passalongUVPass()
  {
    bool rtnb = false; //don't pass along
    if(!m_state.m_currentObjSymbolsForCodeGen.empty())
      {
	Symbol * cossym = m_state.m_currentObjSymbolsForCodeGen.back();
	UTI cosuti = cossym->getUlamTypeIdx();
	UlamType * cosut = m_state.getUlamTypeByIndex(cosuti);
	//t3913, t3915 tmpref may not be a ref, but may need adjusting (i.e. anonymous element returned)
	rtnb = (!cosut->isReference() && (!cossym->isTmpVarSymbol() || Node::needAdjustToStateBits(cosuti)));
      }
    return rtnb;
  }
Exemplo n.º 22
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
Exemplo n.º 23
0
  void NodeAtomof::genCodeToStoreInto(File * fp, UVPass& uvpass)
  {
    //lhs, no longer allowed with packed elements
    assert(getStoreIntoAble() == TBOOL_TRUE);

    UTI nuti = getNodeType(); //UAtomRef

    if(m_nodeOf->hasASymbolReference() && (m_state.getUlamTypeByIndex(getOfType())->getUlamClassType() == UC_QUARK))
      {
	Symbol * stgcos = NULL;
	AssertBool gotstg = m_nodeOf->getStorageSymbolPtr(stgcos);
	assert(gotstg);

	m_state.indentUlamCode(fp);
	fp->write("if(");
	fp->write(stgcos->getMangledName().c_str());
	fp->write(".GetType() == T::ATOM_UNDEFINED_TYPE)"); GCNL;

	m_state.m_currentIndentLevel++;
	m_state.indentUlamCode(fp);
	fp->write("FAIL(NOT_AN_ELEMENT);"); GCNL;
	m_state.m_currentIndentLevel--;

	UlamType * nut = m_state.getUlamTypeByIndex(nuti);
	s32 tmpVarNum = m_state.getNextTmpVarNumber(); //tmp for atomref

	m_state.indentUlamCode(fp); //non-const
	fp->write(nut->getLocalStorageTypeAsString().c_str()); //for C++ local vars
	fp->write(" ");
	fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum, TMPBITVAL).c_str());
	fp->write("(");

	fp->write(stgcos->getMangledName().c_str()); //ur for self
	fp->write(", "); //is storage! can't be const (error/t3659)

	fp->write(" - T::ATOM_FIRST_STATE_BIT"); //must be an effective element ref (e.g.t3684, t3663)
	fp->write("); //atomof"); GCNL;

	uvpass = UVPass::makePass(tmpVarNum, TMPBITVAL, nuti, UNPACKED, m_state, uvpass.getPassPos(), uvpass.getPassNameId());
      }
    else
      {
	//lhs
	assert(getStoreIntoAble() == TBOOL_TRUE);
	assert(m_nodeOf);
	m_nodeOf->genCodeToStoreInto(fp, uvpass); //does it handle array item members selected?
	assert(!m_state.m_currentObjSymbolsForCodeGen.empty());

	uvpass = UVPass::makePass(uvpass.getPassVarNum(), TMPTATOM, getNodeType(), UNPACKED, m_state, uvpass.getPassPos(), uvpass.getPassNameId());
      }
  } //genCodeToStoreInto
Exemplo n.º 24
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
Exemplo n.º 25
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
Exemplo n.º 26
0
  bool SymbolWithValue::getArrayItemValue(u32 item, u64& rtnitem)
  {
    if(isReady())
      {
	UTI suti = getUlamTypeIdx();
	UlamType * sut = m_state.getUlamTypeByIndex(suti);
	u32 bs = sut->getBitSize();
	s32 arrsize = sut->getArraySize();
	assert(bs <= MAXBITSPERLONG);
	assert((arrsize >= 0) && (item < (u32) arrsize));
	//no casting!
	rtnitem = m_constantValue.ReadLong(item * bs, bs);
	return true;
      }
    return false;
  }
Exemplo n.º 27
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
Exemplo n.º 28
0
  bool SymbolWithValue::getArrayItemInitValue(u32 item, u32& rtnitem)
  {
    assert(hasInitValue());
    if(isInitValueReady())
      {
	UTI suti = getUlamTypeIdx();
	UlamType * sut = m_state.getUlamTypeByIndex(suti);
	u32 bs = sut->getBitSize();
	s32 arrsize = sut->getArraySize();
	assert(bs <= MAXBITSPERINT);
	assert((arrsize >= 0) && (item < (u32) arrsize));
	//no casting!
	rtnitem = m_initialValue.Read(item * bs, bs);
	return true;
      }
    return false;
  }
Exemplo n.º 29
0
  void NodeBinaryOpCompare::genCode(File * fp, UVPass& uvpass)
  {
    assert(m_nodeLeft && m_nodeRight);
    assert(m_state.m_currentObjSymbolsForCodeGen.empty()); //*************

    // generate rhs first; may update current object globals (e.g. function call)
    UVPass ruvpass;
    m_nodeRight->genCode(fp, ruvpass);

    // restore current object globals
    assert(m_state.m_currentObjSymbolsForCodeGen.empty()); //*************

    UVPass luvpass;
    m_nodeLeft->genCode(fp, luvpass); //updates m_currentObjSymbol

    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(" = ");

    fp->write(methodNameForCodeGen().c_str());
    fp->write("(");

    UTI luti = luvpass.getPassTargetType(); //reset
    fp->write(luvpass.getTmpVarAsString(m_state).c_str());

    fp->write(", ");
    fp->write(ruvpass.getTmpVarAsString(m_state).c_str());
    fp->write(", ");

    //compare needs size of left/right nodes (only difference!)
    fp->write_decimal(m_state.getUlamTypeByIndex(luti)->getTotalBitSize());

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

    uvpass = UVPass::makePass(tmpVarNum, TMPREGISTER, nuti, m_state.determinePackable(nuti), m_state, 0, 0);  //P
    assert(m_state.m_currentObjSymbolsForCodeGen.empty()); //*************
  } //genCode
Exemplo n.º 30
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