示例#1
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
示例#2
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
示例#3
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
示例#4
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
示例#5
0
  // presumably called by e.g. a binary op equal (lhs); caller saves
  // currentObjPass/Symbol, unlike genCode (rhs)
  void NodeMemberSelect::genCodeToStoreInto(File * fp, UVPass& uvpass)
  {
    assert(m_nodeLeft && m_nodeRight);

    UVPass luvpass;
    if(passalongUVPass())
      {
	luvpass = uvpass; //t3584
	Node::adjustUVPassForElements(luvpass); //t3803 ?
      }

    // if parent is another MS, we might need to adjust pos first
    // elements can be data members of transients, etc.

    m_nodeLeft->genCodeToStoreInto(fp, luvpass);

    //NodeIdent can't do it, because it doesn't know it's not a stand-alone element.
    // here, we know there's rhs of member select, which needs to adjust to state bits.
    //process multiple member selections (e.g. t3817)
    UVPass ruvpass;
    if(passalongUVPass())
      {
	ruvpass = luvpass;  //t3615 ?
	Node::adjustUVPassForElements(ruvpass); //t3803
      }

    m_nodeRight->genCodeToStoreInto(fp, ruvpass); //uvpass contains the member selected, or cos obj symbol?

    uvpass = ruvpass;

    //tmp variable needed for any function call not returning a ref (t41006), including 'aref'(t41005); func calls returning a ref already made tmpvar.
    // uvpass not necessarily returning a reference type (t3913,4,5,7);
    // t41035 returns a primitive ref; t3946, t3948
    if(m_nodeRight->isFunctionCall() && !m_state.isReference(uvpass.getPassTargetType()))
      {
	m_tmpvarSymbol = Node::makeTmpVarSymbolForCodeGen(uvpass, NULL); //dm to avoid leaks
	m_state.m_currentObjSymbolsForCodeGen.push_back(m_tmpvarSymbol);
      }
  } //genCodeToStoreInto
示例#6
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
示例#7
0
  void NodeControl::genCode(File * fp, UVPass& uvpass)
  {
    assert(m_nodeCondition && m_nodeBody);

    //bracket for overall tmpvars (e.g. condition and body) is
    // generated by the specific control; e.g. final bracket depends
    // on presence of 'else'.

    m_nodeCondition->genCode(fp, uvpass);

    bool isTerminal = (uvpass.getPassStorage() == TERMINAL);
    UTI cuti = uvpass.getPassTargetType();
    UlamType * cut = m_state.getUlamTypeByIndex(cuti);

    m_state.indentUlamCode(fp);
    fp->write(getName());  //if, while
    fp->write("(");

    if(isTerminal)
      {
	fp->write(m_state.m_pool.getDataAsString(uvpass.getPassNameId()).c_str());
      }
    else
      {
	if(m_state.m_genCodingConditionalHas)
	  {
	    assert(cut->getUlamTypeEnum() == Bool);
	    fp->write(((UlamTypePrimitiveBool *) cut)->getConvertToCboolMethod().c_str());
	    fp->write("((");
	    fp->write(uvpass.getTmpVarAsString(m_state).c_str());
	    fp->write(" >= 0 ? 1 : 0), "); //test for 'has' pos
	    fp->write_decimal(cut->getBitSize());
	    fp->write(")");
	  }
	else
	  {
	    //regular condition
	    assert(cut->getUlamTypeEnum() == Bool);
	    fp->write(((UlamTypePrimitiveBool *) cut)->getConvertToCboolMethod().c_str());
	    fp->write("(");
	    fp->write(uvpass.getTmpVarAsString(m_state).c_str());
	    fp->write(", ");
	    fp->write_decimal(cut->getBitSize());
	    fp->write(")");
	  }
      }
    fp->write(")"); GCNL;

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

    //note: in case of has-conditional, uvpass still has the tmpvariable containing the pos!
    m_nodeBody->genCode(fp, uvpass);

    //probably should have been done within the body, to avoid any
    //subsequent if/whiles from misinterpretting it as theirs; if so, again, moot.
    assert(!m_state.m_genCodingConditionalHas);

    m_state.m_currentIndentLevel--;
    m_state.indentUlamCode(fp);
    fp->write("} // end ");
    fp->write(getName()); //end
    fp->write("\n");
  } //genCode