Пример #1
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
Пример #2
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
Пример #3
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
Пример #4
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
Пример #5
0
  void NodeAtomof::genCode(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;

	//read into a T
	s32 tmpVarNum2 = m_state.getNextTmpVarNumber(); //tmp for atomref
	m_state.indentUlamCode(fp);
	fp->write("const ");
	fp->write(nut->getTmpStorageTypeAsString().c_str()); //for C++ local vars
	fp->write(" ");
	fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum2, TMPTATOM).c_str());
	fp->write(" = ");
	fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum, TMPBITVAL).c_str());
	fp->write(".read();"); GCNL;

	uvpass = UVPass::makePass(tmpVarNum2, TMPTATOM, nuti, UNPACKED, m_state, 0, uvpass.getPassNameId());
      }
    else
      {
	//get the element in a tmpvar; necessary for array item members selected (at runtime).
	m_nodeOf->genCode(fp, uvpass);
	assert(m_state.m_currentObjSymbolsForCodeGen.empty());

	//e.g. 'return self.atomof;' (e.g. t3408, t3410, t3585, t3631, t3663)
	uvpass = UVPass::makePass(uvpass.getPassVarNum(), TMPTATOM, nuti, UNPACKED, m_state, uvpass.getPassPos(), uvpass.getPassNameId());
      }
  } //genCode
Пример #6
0
  void NodeInstanceof::genCode(File * fp, UVPass& uvpass)
  {
    //generates a new instance of..
    UTI nuti = getNodeType();
    UlamType * nut = m_state.getUlamTypeByIndex(nuti);
    s32 tmpVarNum = m_state.getNextTmpVarNumber(); //tmp for atomref
    Symbol * cos = NULL;
    Symbol * stgcos = NULL;
    //starts out as its default type; references (UAtom) are updated:
    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(";"); GCNL;

    // a reference (including 'self'), returns a UAtom of effective type;
    // SINCE effective self type is known only at runtime.
    if(m_nodeOf)
      {
	m_nodeOf->genCodeToStoreInto(fp, uvpass);
	assert(!m_state.m_currentObjSymbolsForCodeGen.empty());
	cos = m_state.m_currentObjSymbolsForCodeGen.back();
	UTI cosuti = cos->getUlamTypeIdx();
	stgcos = m_state.m_currentObjSymbolsForCodeGen[0];

	bool isself = stgcos->isSelf();
	bool issuper = stgcos->isSuper();
	bool isaref = m_state.isAltRefType(cosuti) || isself || issuper;

	if(isaref)
	  {
	    u32 tmpuclass = m_state.getNextTmpVarNumber(); //only for this case
	    m_state.indentUlamCode(fp);
	    fp->write("const UlamClass<EC> * ");
	    fp->write(m_state.getUlamClassTmpVarAsString(tmpuclass).c_str());
	    fp->write(" = ");
	    fp->write(cos->getMangledName().c_str());
	    fp->write(".GetEffectiveSelf();"); GCNL;

	    //primitive FAILS
	    m_state.indentUlamCode(fp);
	    fp->write("if(");
	    fp->write(m_state.getUlamClassTmpVarAsString(tmpuclass).c_str());
	    fp->write(" == NULL) FAIL(ILLEGAL_ARGUMENT); //non-class"); GCNL;

	    //an immediate default quark FAILS
	    m_state.indentUlamCode(fp);
	    fp->write("if(");
	    fp->write(m_state.getUlamClassTmpVarAsString(tmpuclass).c_str());
	    fp->write("->AsUlamQuark() != NULL) ");
	    fp->write("FAIL(NOT_AN_ELEMENT); //quark"); GCNL;

	    m_state.indentUlamCode(fp);
	    fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum, TMPBITVAL).c_str());
	    fp->write(".WriteAtom(");
	    fp->write("((UlamElement<EC> *) ");
	    fp->write(m_state.getUlamClassTmpVarAsString(tmpuclass).c_str());
	    fp->write(")->GetDefaultAtom()); //instanceof default element"); GCNL;
	  }
	else if(m_state.isAtom(nuti))
	  {
	    u32 tmpuclass = m_state.getNextTmpVarNumber(); //only for this case
	    m_state.indentUlamCode(fp);
	    fp->write("const UlamClass<EC> * ");
	    fp->write(m_state.getUlamClassTmpVarAsString(tmpuclass).c_str());
	    fp->write(" = ");
	    fp->write("uc.LookupUlamElementTypeFromContext(");
	    fp->write(cos->getMangledName().c_str());
	    fp->write(".GetType()");
	    fp->write(");"); GCNL;

	    m_state.indentUlamCode(fp);
	    fp->write("if(");
	    fp->write(m_state.getUlamClassTmpVarAsString(tmpuclass).c_str());
	    fp->write(" == NULL) FAIL(ILLEGAL_ARGUMENT); //non-class"); GCNL;

	    m_state.indentUlamCode(fp);
	    fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum, TMPBITVAL).c_str());
	    fp->write(".WriteAtom(");
	    fp->write("((UlamElement<EC> *) ");
	    fp->write(m_state.getUlamClassTmpVarAsString(tmpuclass).c_str());
	    fp->write(")->GetDefaultAtom()); //instanceof default element"); GCNL;
	  }
      }

    if(m_state.isAtom(nuti))
      {
	// THE READ:
	s32 tmpVarNum2 = m_state.getNextTmpVarNumber(); //tmp to read into
	TMPSTORAGE rstor = nut->getTmpStorageTypeForTmpVar();

	m_state.indentUlamCode(fp);
	fp->write("const ");
	fp->write(nut->getTmpStorageTypeAsString().c_str()); //for C++ local vars
	fp->write(" ");
	fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum2, rstor).c_str());
	fp->write(" = ");
	fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum, TMPBITVAL).c_str());
	fp->write(".");
	fp->write("read();"); GCNL;

	uvpass = UVPass::makePass(tmpVarNum2, rstor, nuti, nut->getPackable(), m_state, 0, cos ? cos->getId() : 0);
      }
    else //element and uvpass stays the same (a default immediate element).
      uvpass = UVPass::makePass(tmpVarNum, TMPBITVAL, nuti, nut->getPackable(), m_state, 0, cos ? cos->getId() : 0); //t3657

    m_state.clearCurrentObjSymbolsForCodeGen(); //clear remnant of rhs ?
  } //genCode
Пример #7
0
  void NodeCast::genCodeCastAtomAndQuark(File * fp, UlamValue & uvpass)
  {
    UTI nuti = getNodeType(); //quark tobe
    UlamType * nut = m_state.getUlamTypeByIndex(nuti);

    UTI vuti = uvpass.getUlamValueTypeIdx();
    if(vuti == Ptr)
      vuti = uvpass.getPtrTargetType(); //replace

    m_node->genCodeToStoreInto(fp, uvpass); //No need to load lhs into tmp (T); symbol's in COS vector

    assert(!m_state.m_currentObjSymbolsForCodeGen.empty());
    Symbol * stgcos = NULL;
    stgcos = m_state.m_currentObjSymbolsForCodeGen[0];

    s32 tmpVarPos = m_state.getNextTmpVarNumber();
    // "downcast" might not be true; compare to be sure the atom has a quark "Foo"
    // get signed pos
    if(vuti == UAtom)
      {
	m_state.indent(fp);
	fp->write("const s32 ");
	fp->write(m_state.getTmpVarAsString(Int, tmpVarPos).c_str());;
	fp->write(" = ");
	//internal method, takes uc, u32 and const char*, returns s32 position
	fp->write(m_state.getHasMangledFunctionName(vuti));
	fp->write("(");
	fp->write("uc, ");
	Node::genLocalMemberNameOfMethod(fp); //assume atom is a local var (neither dm nor ep)
	if(stgcos->isSelf())
	  fp->write("GetType(), "); //no read for self
	else
	  fp->write("read().GetType(), ");

	fp->write("\"");
	fp->write(nut->getUlamTypeMangledName().c_str());
	fp->write("\");\n"); //keeping pos in tmp
      }
    else
      {
	UlamType* vut = m_state.getUlamTypeByIndex(vuti);
	if(vut->getUlamClass() == UC_ELEMENT)
	  {
	    m_state.indent(fp);
	    fp->write("const s32 ");
	    fp->write(m_state.getTmpVarAsString(Int, tmpVarPos).c_str());;
	    fp->write(" = ");
	    //internal method, takes uc, u32 and const char*, returns s32 position

	    fp->write(vut->getUlamTypeMangledName().c_str());
	    fp->write("<EC>::");

	    fp->write(m_state.getHasMangledFunctionName(vuti));
	    fp->write("(\"");
	    fp->write(nut->getUlamTypeMangledName().c_str());
	    fp->write("\");\n"); //keeping pos in tmp
	  }
        else
	  {
	    //e.g. a quark here would be wrong
	    std::ostringstream msg;
	    msg << "Casting 'incomplete' types ";
	    msg << m_state.getUlamTypeNameBriefByIndex(nuti).c_str();
	    msg << " to be ";
	    msg << m_state.getUlamTypeNameBriefByIndex(vuti).c_str();
	    MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR);
	    assert(0);//return;
	  }
      }

    m_state.indent(fp);
    fp->write("if(");
    fp->write(m_state.getTmpVarAsString(Int, tmpVarPos).c_str());
    fp->write(" < 0)\n");

    m_state.m_currentIndentLevel++;
    m_state.indent(fp);
    fp->write("FAIL(BAD_CAST);\n\n");
    m_state.m_currentIndentLevel--;

    //informed by genCodedAutoLocal() in NodeVarDecl used for conditional-as
    // uses stgcos since there's no m_varSymbol in this situation.
    s32 tmpVarStg = m_state.getNextTmpVarNumber();
    UTI stguti = stgcos->getUlamTypeIdx();
    UlamType * stgut = m_state.getUlamTypeByIndex(stguti);
    assert(stguti == UAtom || stgut->getUlamClass() == UC_ELEMENT);

    // can't let Node::genCodeReadIntoTmpVar do this for us (we need a ref!):
    assert(m_state.m_currentObjSymbolsForCodeGen.size() == 1);
    m_state.indent(fp);
    // no const here
    fp->write(stgut->getTmpStorageTypeAsString().c_str());
    fp->write("& ");
    fp->write(m_state.getTmpVarAsString(stguti, tmpVarStg, TMPBITVAL).c_str());
    fp->write(" = ");
    fp->write(stgcos->getMangledName().c_str());

    if(!stgcos->isSelf())
      fp->write(".getRef()");
    fp->write("; //ref needed\n");

    // now we have our pos in tmpVarPos, and our T in tmpVarStg
    // time to (like a) "shadow 'self'" with auto local variable:
    m_state.indent(fp);
    fp->write(nut->getUlamTypeImmediateAutoMangledName().c_str()); //for C++ local vars, ie non-data members

    fp->write("<EC> ");
    s32 tmpIQ = m_state.getNextTmpVarNumber(); //tmp since no variable name
    fp->write(m_state.getTmpVarAsString(nuti, tmpIQ).c_str());
    fp->write("(");
    fp->write(m_state.getTmpVarAsString(stguti, tmpVarStg, TMPBITVAL).c_str());

    //for known quark:
    fp->write(", ");
    fp->write(m_state.getTmpVarAsString(Int, tmpVarPos).c_str());

    fp->write(");\n"); //like, shadow lhs of as

    //update the uvpass to have the casted immediate quark
    uvpass = UlamValue::makePtr(tmpIQ, uvpass.getPtrStorage(), nuti, m_state.determinePackable(nuti), m_state, 0); //POS 0 rightjustified;

    m_state.m_currentObjSymbolsForCodeGen.clear(); //clear remnant of lhs
  } //genCodeCastAtomAndQuark
Пример #8
0
  void NodeCast::genCodeReadIntoATmpVar(File * fp, UlamValue& uvpass)
  {
    // e.g. called by NodeFunctionCall on a NodeTerminal..
    if(!needsACast())
      {
	return m_node->genCodeReadIntoATmpVar(fp, uvpass);
      }

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

    UTI vuti = uvpass.getUlamValueTypeIdx();

    bool isTerminal = false;
    s32 tmpVarNum = 0;

   if(vuti == Ptr)
      {
	tmpVarNum = uvpass.getPtrSlotIndex();
	vuti = uvpass.getPtrTargetType(); //replace
      }
    else
      {
	// an immediate terminal value
	isTerminal = true;
      }

   if(nuti == vuti)
     return; //nothing to do!

   UlamType * vut = m_state.getUlamTypeByIndex(vuti); //after vuti replacement
   ULAMCLASSTYPE nclasstype = nut->getUlamClass();
   ULAMCLASSTYPE vclasstype = vut->getUlamClass();

   //handle element-atom and atom-element casting differently:
   // handle element->quark, atom->quark, not quark->element or quark->atom
   if(nuti == UAtom || vuti == UAtom || vclasstype == UC_ELEMENT || vclasstype == UC_QUARK)
     {
       //only to be nclasstype quark makes sense!!! check first, one might be element
       if(nclasstype == UC_QUARK || vclasstype == UC_QUARK)
	 return genCodeCastAtomAndQuark(fp, uvpass);

       if(nclasstype == UC_ELEMENT || vclasstype == UC_ELEMENT)
	 return genCodeCastAtomAndElement(fp, uvpass);

       {
	 std::ostringstream msg;
	 msg << "Casting 'incomplete' types: ";
	 msg << m_state.getUlamTypeNameByIndex(nuti).c_str();
	 msg << "(UTI" << nuti << ") to be " << m_state.getUlamTypeNameByIndex(vuti).c_str();
	 msg << "(UTI" << vuti << ")";
	 MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG);
	 return;
       }
     }

   s32 tmpVarCastNum = m_state.getNextTmpVarNumber();

   m_state.indent(fp);
   fp->write("const ");
   fp->write(nut->getTmpStorageTypeAsString().c_str()); //e.g. u32, s32, u64, etc.
   fp->write(" ");
   fp->write(m_state.getTmpVarAsString(nuti, tmpVarCastNum).c_str());
   fp->write(" = ");

   // write the cast method (e.g. _Unsigned32ToInt32, _Int32ToUnary32, etc..)
   fp->write(nut->castMethodForCodeGen(vuti).c_str());
   fp->write("(");

   if(isTerminal)
     {
       s32 len = m_state.getBitSize(vuti);
       assert(len != UNKNOWNSIZE);
       if(len <= MAXBITSPERINT)
	 {
	   u32 data = uvpass.getImmediateData(m_state);
	   char dstr[40];
	   vut->getDataAsString(data, dstr, 'z');
	   fp->write(dstr);
	 }
       else if(len <= MAXBITSPERLONG)
	 {
	   u64 data = uvpass.getImmediateDataLong(m_state);
	   char dstr[70];
	   vut->getDataLongAsString(data, dstr, 'z');
	   fp->write(dstr);
	 }
       else
	 assert(0);
     }
   else
     {
       fp->write(m_state.getTmpVarAsString(nuti, tmpVarNum).c_str());
     }

   fp->write(", ");

   assert(!(nuti == UAtom || vuti == UAtom));
   //LENGTH of node being casted (Uh_AP_mi::LENGTH ?)
   //fp->write(m_state.getBitVectorLengthAsStringForCodeGen(nodetype).c_str());
   fp->write_decimal(m_state.getTotalBitSize(vuti)); //src length

   fp->write(", ");
   fp->write_decimal(m_state.getTotalBitSize(nuti)); //tobe length

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

   //PROBLEM is that funccall checks for 0 nameid to use the tmp var!
   // but then if we don't pass it along Node::genMemberNameForMethod fails..
   if(isTerminal)
     uvpass = UlamValue::makePtr(tmpVarCastNum, TMPREGISTER, nuti, m_state.determinePackable(nuti), m_state, 0); //POS 0 rightjustified.
   else
     uvpass = UlamValue::makePtr(tmpVarCastNum, TMPREGISTER, nuti, m_state.determinePackable(nuti), m_state, 0, uvpass.getPtrNameId()); //POS 0 rightjustified; pass along name id
  } //genCodeReadIntoTmp
Пример #9
0
  void NodeBinaryOpCompare::genCode(File * fp, UlamValue& uvpass)
  {
    assert(m_nodeLeft && m_nodeRight);
    assert(m_state.m_currentObjSymbolsForCodeGen.empty()); //*************

#ifdef TMPVARBRACES
    m_state.indent(fp);
    fp->write("{\n");
    m_state.m_currentIndentLevel++;
#endif

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

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

    UlamValue 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.indent(fp);
    fp->write("const ");
    fp->write(nut->getTmpStorageTypeAsString().c_str()); //e.g. u32, s32, u64..
    fp->write(" ");

    fp->write(m_state.getTmpVarAsString(nuti,tmpVarNum).c_str());
    fp->write(" = ");

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

    UTI luti = luvpass.getUlamValueTypeIdx();
    assert(luti == Ptr);
    luti = luvpass.getPtrTargetType(); //reset
    fp->write(m_state.getTmpVarAsString(luti, luvpass.getPtrSlotIndex()).c_str());

    fp->write(", ");

    UTI ruti = ruvpass.getUlamValueTypeIdx();
    assert(ruti == Ptr);
    fp->write(m_state.getTmpVarAsString(ruvpass.getPtrTargetType(), ruvpass.getPtrSlotIndex()).c_str());

    fp->write(", ");

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

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

    uvpass = UlamValue::makePtr(tmpVarNum, TMPREGISTER, nuti, m_state.determinePackable(nuti), m_state, 0);  //P

#ifdef TMPVARBRACES
    m_state.m_currentIndentLevel--;
    m_state.indent(fp);
    fp->write("}\n"); //close for tmpVar
#endif
    assert(m_state.m_currentObjSymbolsForCodeGen.empty()); //*************
  } //genCode