当前位置: 首页>>代码示例>>C++>>正文


C++ ExprVector::push_back方法代码示例

本文整理汇总了C++中ExprVector::push_back方法的典型用法代码示例。如果您正苦于以下问题:C++ ExprVector::push_back方法的具体用法?C++ ExprVector::push_back怎么用?C++ ExprVector::push_back使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在ExprVector的用法示例。


在下文中一共展示了ExprVector::push_back方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: getSubExprs

/***************************************************************
* Function: RangeExpr::getSubExprs()
* Purpose : Access sub-expressions
* Initial : Maxime Chevalier-Boisvert on January 8, 2009
****************************************************************
Revisions and bug fixes:
*/
Expression::ExprVector RangeExpr::getSubExprs() const
{
	// Create a list to store the sub-expression pointers
	ExprVector list; 
	
	// Add the sub-expressions to the list
	list.push_back(m_pStartExpr); 
	list.push_back(m_pStepExpr);
	list.push_back(m_pEndExpr);
	
	// Return the list
	return list;	
}
开发者ID:Sable,项目名称:mcvm,代码行数:20,代码来源:rangeexpr.cpp

示例2: ParseMicrosoftIfExistsBraceInitializer

// Return true if a comma (or closing brace) is necessary after the
// __if_exists/if_not_exists statement.
bool Parser::ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
                                                    bool &InitExprsOk) {
  bool trailingComma = false;
  IfExistsCondition Result;
  if (ParseMicrosoftIfExistsCondition(Result))
    return false;
  
  BalancedDelimiterTracker Braces(*this, tok::l_brace);
  if (Braces.consumeOpen()) {
    Diag(Tok, diag::err_expected) << tok::l_brace;
    return false;
  }

  switch (Result.Behavior) {
  case IEB_Parse:
    // Parse the declarations below.
    break;
        
  case IEB_Dependent:
    Diag(Result.KeywordLoc, diag::warn_microsoft_dependent_exists)
      << Result.IsIfExists;
    // Fall through to skip.
      
  case IEB_Skip:
    Braces.skipToEnd();
    return false;
  }

  while (!isEofOrEom()) {
    trailingComma = false;
    // If we know that this cannot be a designation, just parse the nested
    // initializer directly.
    ExprResult SubElt;
    if (MayBeDesignationStart())
      SubElt = ParseInitializerWithPotentialDesignator();
    else
      SubElt = ParseInitializer();

    if (Tok.is(tok::ellipsis))
      SubElt = Actions.ActOnPackExpansion(SubElt.get(), ConsumeToken());
    
    // If we couldn't parse the subelement, bail out.
    if (!SubElt.isInvalid())
      InitExprs.push_back(SubElt.release());
    else
      InitExprsOk = false;

    if (Tok.is(tok::comma)) {
      ConsumeToken();
      trailingComma = true;
    }

    if (Tok.is(tok::r_brace))
      break;
  }

  Braces.consumeClose();

  return !trailingComma;
}
开发者ID:Xmister,项目名称:clang-onex,代码行数:62,代码来源:ParseInit.cpp

示例3: Flatten

// Flatten out all expressions with a given head.
void Expression::Flatten(const string head)
{
	ExprVector newLeaves;
	newLeaves.reserve(leaves.size());
	for(ExprVector::const_iterator leaf = leaves.begin(); leaf != leaves.end(); ++leaf)
		if((*leaf)->FunctionName() == head)
		{
			for(ExprVector::const_iterator subLeaf = (*leaf)->Leaves().begin(); subLeaf != (*leaf)->Leaves().end(); ++subLeaf)
				newLeaves.push_back(*subLeaf);
			(*leaf)->Leaves().clear();
			delete *leaf;
		}
		else
			newLeaves.push_back(*leaf);
	leaves = newLeaves;
}
开发者ID:dubrousky,项目名称:Mathador,代码行数:17,代码来源:Expression.cpp

示例4: Apply

void OpReplaceRepeated::Apply(Expression *expression, Calculator *calculator, int32 recursions)
{
	if(expression->LeafCount() != 2)
		throw ArgumentException("ReplaceRepeated expects 2 arguments.");
	if(expression->LeafCount() != 2)
		throw ArgumentException("ReplaceRepeated expects 2 arguments.");
	string leafFunction = expression->Leaf(1)->FunctionName();
	if(leafFunction != "Rule" && leafFunction != "RuleDelayed" && leafFunction != "List")
		throw ArgumentException("ReplaceRepeated expects its second argument to be a rule or a list of rules.");
	ExprVector rules;
	if(leafFunction == "List")
	{
		for(ExprVector::const_iterator item = expression->Leaf(1)->Leaves().begin(); item != expression->Leaf(1)->Leaves().end(); ++ item)
			if((*item)->FunctionName() != "Rule" && (*item)->FunctionName() != "RuleDelayed")
				throw ArgumentException("ReplaceRepeated expects its second argument to be a rule or a list of rules.");
		rules = expression->Leaf(1)->Leaves();
	}
	else
		rules.push_back(expression->Leaf(1));
	int32 iterations(0);
	Expression *result = expression->Leaf(0);
	while(true)
	{
		bool changed(false);
		if(!result->ReplaceAll(rules, calculator, &changed))
			break;
		if(!changed)
			break;
		++iterations;
		if(iterations >= Max_ReplaceRepeated_Iterations)
			throw LimitationException("Maximum number of iterations reached.");
	}
	expression->AssignLeaf(0);
	expression->Evaluate(calculator, recursions);
}
开发者ID:dubrousky,项目名称:Mathador,代码行数:35,代码来源:Rule.cpp

示例5: MakeElementExprs

void TransformVector::MakeElementExprs(DeclVector &DeclVec, 
                                       ExprVector &ExprVec,
                                       ExtVectorElementExpr *E) {
  llvm::SmallVector<unsigned, 4> Indices;
  E->getEncodedElementAccess(Indices);
  Expr *BE = E->getBase();

  // If E is an arrow expression, the base pointer expression needs to be 
  // converted into a vector value expression.
  if (E->isArrow()) {
    QualType BaseTy = BE->getType();
    const PointerType *PTy = BaseTy->getAs<PointerType>();
    assert(PTy && "Not a pointer type");
    BE = new (ASTCtx) UnaryOperator(BE, UO_Deref, PTy->getPointeeType(),
                                    VK_RValue, OK_Ordinary, SourceLocation());
    BE = new (ASTCtx) ParenExpr(SourceLocation(), SourceLocation(), BE);
  }

  if (ExtVectorElementExpr *BP = dyn_cast<ExtVectorElementExpr>(BE)) {
    ExprVector BaseExprVec;
    MakeElementExprs(DeclVec, BaseExprVec, BP);
    for (unsigned i = 0, e = Indices.size(); i < e; i++) {
      ExprVec.push_back(BaseExprVec[Indices[i]]);
    }
  } else if (CompoundLiteralExpr *BP = dyn_cast<CompoundLiteralExpr>(BE)) {
    for (unsigned i = 0, e = Indices.size(); i < e; i++) {
      Expr *ElemE = GetSingleValueOfVecLiteral(DeclVec, BP, Indices[i]);
      ExprVec.push_back(ElemE);
    }
  } else {
    Expr *NewBE = ConvertVecLiteralInExpr(DeclVec, BE);
    const ExtVectorType *VecTy = NewBE->getType()->getAs<ExtVectorType>();
    assert(VecTy && "The type of BaseExpr is not a vector type.");

    QualType ElemTy = VecTy->getElementType();
    SourceLocation loc;

    for (unsigned i = 0, e = Indices.size(); i < e; i++) {
      unsigned Kind = CLExpressions::ZERO + Indices[i];
      ArraySubscriptExpr *ElemE = new (ASTCtx) ArraySubscriptExpr(
          NewBE,
          CLExprs.getExpr((CLExpressions::ExprKind)(Kind)), 
          ElemTy, VK_RValue, OK_Ordinary, loc);
      ExprVec.push_back(ElemE);
    }
  }
}
开发者ID:SiddharthC,项目名称:snucl-1.3.2,代码行数:47,代码来源:TransformVector.cpp

示例6: create

/**
* @brief Converts the given LLVM call instruction @a inst into an expression in BIR.
*/
ShPtr<CallExpr> LLVMInstructionConverter::convertCallInstToCallExpr(llvm::CallInst &inst) {
	ExprVector args;
	for (auto &arg: inst.arg_operands()) {
		args.push_back(getConverter()->convertValueToExpression(arg));
	}

	auto calledExpr = getConverter()->convertValueToExpression(inst.getCalledValue());
	return CallExpr::create(calledExpr, args);
}
开发者ID:SchuckBeta,项目名称:retdec,代码行数:12,代码来源:llvm_instruction_converter.cpp

示例7: getSubExprs

/***************************************************************
* Function: ParamExpr::getSubExprs()
* Purpose : Access sub-expressions
* Initial : Maxime Chevalier-Boisvert on January 8, 2009
****************************************************************
Revisions and bug fixes:
*/
Expression::ExprVector ParamExpr::getSubExprs() const
{
	// Create a list to store the sub-expression pointers
	ExprVector list;

	// Add the symbol to the list
	list.push_back(m_pSymbolExpr);

	// For each argument
	for (size_t i = 0; i < m_arguments.size(); ++i)
	{
		// Add the sub-expression to the list
		list.push_back(m_arguments[i]);
	}

	// Return the list
	return list;
}
开发者ID:dcdelia,项目名称:mcvm,代码行数:25,代码来源:paramexpr.cpp

示例8: copy

/***************************************************************
* Function: ParamExpr::copy()
* Purpose : Copy this IIR node recursively
* Initial : Maxime Chevalier-Boisvert on November 8, 2008
****************************************************************
Revisions and bug fixes:
*/
ParamExpr* ParamExpr::copy() const
{
	// Create an argument vector to store the argument copies
	ExprVector arguments;

	// Copy each argument
	for (ExprVector::const_iterator itr = m_arguments.begin(); itr != m_arguments.end(); ++itr)
		arguments.push_back((Expression*)(*itr)->copy());

	// Create and return a copy of this node
	return new ParamExpr(
		m_pSymbolExpr->copy(),
		arguments
	);
}
开发者ID:dcdelia,项目名称:mcvm,代码行数:22,代码来源:paramexpr.cpp

示例9: copy

/***************************************************************
* Function: AssignStmt::copy()
* Purpose : Copy this IIR node recursively
* Initial : Maxime Chevalier-Boisvert on November 6, 2008
****************************************************************
Revisions and bug fixes:
*/
AssignStmt* AssignStmt::copy() const
{
	// Create a vector for the left expression copies
	ExprVector leftExprs;
	
	// Copy each left expression
	for (ExprVector::const_iterator itr = m_leftExprs.begin(); itr != m_leftExprs.end(); ++itr)
		leftExprs.push_back((*itr)->copy());
	
	// Create and return a copy of this node
	return new AssignStmt(
		leftExprs,
		m_pRightExpr->copy(),
		m_suppressOut
	);
}	
开发者ID:Sable,项目名称:mcvm,代码行数:23,代码来源:assignstmt.cpp

示例10: visit

void RecursiveCFGBuilder::visit(ShPtr<IfStmt> stmt) {
	ShPtr<CFG::Node> beforeIfNode(currNode);

	// Create a node for the if statement.
	ShPtr<CFG::Node> ifNode(new CFG::Node());
	firstStmtNodeMapping[stmt] = ifNode;
	cfg->stmtNodeMapping[stmt] = ifNode;
	ifNode->stmts.push_back(stmt);
	cfg->addNode(ifNode);
	cfg->addEdge(beforeIfNode, ifNode);

	// Create a node for the bodies of the if statement.
	ExprVector conds;
	for (auto i = stmt->clause_begin(), e = stmt->clause_end(); i != e; ++i) {
		ShPtr<CFG::Node> clauseBody(addNode(i->second));
		cfg->addEdge(ifNode, clauseBody, generateIfCondEdgeLabel(conds, i->first));
		conds.push_back(i->first);
	}

	// Create a node for the else clause/statement's successor. If there is an
	// else clause, then we don't have to generate a node for the statement's
	// successor here. Indeed, if the else clause always ends with a return
	// statement, then the statement's successor is never entered. If the else
	// clause doesn't always ends with a return, the statement's successor will
	// be traversed when adding a node for the else clause.
	if (stmt->hasElseClause()) {
		ShPtr<CFG::Node> clauseBody(addNode(stmt->getElseClause()));
		cfg->addEdge(ifNode, clauseBody, generateIfCondEdgeLabel(conds));
		return;
	}
	ShPtr<Expression> edgeCond(generateIfCondEdgeLabel(conds));
	if (ShPtr<Statement> stmtSucc = stmt->getSuccessor()) {
		ShPtr<CFG::Node> afterIfNode(addNode(stmtSucc));
		cfg->addEdge(ifNode, afterIfNode, edgeCond);
		return;
	}
	currNode = ifNode;
	addForwardOrBackwardEdge(stmt, edgeCond);
}
开发者ID:SchuckBeta,项目名称:retdec,代码行数:39,代码来源:recursive_cfg_builder.cpp

示例11: VisitCompoundLiteralExpr

Stmt *TransformVector::VisitInitListExpr(InitListExpr *Node) {
  // For conventional vector literals such as '{1, 2, 3, 4}'
  QualType ETy = Node->getType();
  if (ETy->isExtVectorType()) {
    CompoundLiteralExpr *CLE = new (ASTCtx) CompoundLiteralExpr(
        SourceLocation(), ASTCtx.getTrivialTypeSourceInfo(ETy),
        ETy, Node->getValueKind(), Node, false);
    return VisitCompoundLiteralExpr(CLE);
  }

  if (NeedFlattening) {
    ExprVector InitExprs;
    ExprVector *PrvInitExprs = CurInitExprs;
    CurInitExprs = &InitExprs;

    for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
      assert(Node->getInit(i) && "NULL InitExpr?");
      Expr *InitExpr = TransformExpr(Node->getInit(i));
      InitExprs.push_back(InitExpr);
    }

    for (unsigned i =0, e = InitExprs.size(); i < e; ++i) {
      Node->updateInit(ASTCtx, i, InitExprs[i]);
    }

    CurInitExprs = PrvInitExprs;

  } else {
    for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
      if (Node->getInit(i)) {
        Node->setInit(i, TransformExpr(Node->getInit(i)));
      }
    }
  }
  
  return Node;
}
开发者ID:SiddharthC,项目名称:snucl-1.3.2,代码行数:37,代码来源:TransformVector.cpp

示例12: ParseBraceInitializer

/// ParseBraceInitializer - Called when parsing an initializer that has a
/// leading open brace.
///
///       initializer: [C99 6.7.8]
///         '{' initializer-list '}'
///         '{' initializer-list ',' '}'
/// [GNU]   '{' '}'
///
///       initializer-list:
///         designation[opt] initializer ...[opt]
///         initializer-list ',' designation[opt] initializer ...[opt]
///
ExprResult Parser::ParseBraceInitializer() {
  InMessageExpressionRAIIObject InMessage(*this, false);
  
  BalancedDelimiterTracker T(*this, tok::l_brace);
  T.consumeOpen();
  SourceLocation LBraceLoc = T.getOpenLocation();

  /// InitExprs - This is the actual list of expressions contained in the
  /// initializer.
  ExprVector InitExprs;

  if (Tok.is(tok::r_brace)) {
    // Empty initializers are a C++ feature and a GNU extension to C.
    if (!getLangOpts().CPlusPlus)
      Diag(LBraceLoc, diag::ext_gnu_empty_initializer);
    // Match the '}'.
    return Actions.ActOnInitList(LBraceLoc, None, ConsumeBrace());
  }

  bool InitExprsOk = true;

  while (1) {
    // Handle Microsoft __if_exists/if_not_exists if necessary.
    if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
        Tok.is(tok::kw___if_not_exists))) {
      if (ParseMicrosoftIfExistsBraceInitializer(InitExprs, InitExprsOk)) {
        if (Tok.isNot(tok::comma)) break;
        ConsumeToken();
      }
      if (Tok.is(tok::r_brace)) break;
      continue;
    }

    // Parse: designation[opt] initializer

    // If we know that this cannot be a designation, just parse the nested
    // initializer directly.
    ExprResult SubElt;
    if (MayBeDesignationStart())
      SubElt = ParseInitializerWithPotentialDesignator();
    else
      SubElt = ParseInitializer();

    if (Tok.is(tok::ellipsis))
      SubElt = Actions.ActOnPackExpansion(SubElt.get(), ConsumeToken());
    
    // If we couldn't parse the subelement, bail out.
    if (!SubElt.isInvalid()) {
      InitExprs.push_back(SubElt.release());
    } else {
      InitExprsOk = false;

      // We have two ways to try to recover from this error: if the code looks
      // grammatically ok (i.e. we have a comma coming up) try to continue
      // parsing the rest of the initializer.  This allows us to emit
      // diagnostics for later elements that we find.  If we don't see a comma,
      // assume there is a parse error, and just skip to recover.
      // FIXME: This comment doesn't sound right. If there is a r_brace
      // immediately, it can't be an error, since there is no other way of
      // leaving this loop except through this if.
      if (Tok.isNot(tok::comma)) {
        SkipUntil(tok::r_brace, StopBeforeMatch);
        break;
      }
    }

    // If we don't have a comma continued list, we're done.
    if (Tok.isNot(tok::comma)) break;

    // TODO: save comma locations if some client cares.
    ConsumeToken();

    // Handle trailing comma.
    if (Tok.is(tok::r_brace)) break;
  }

  bool closed = !T.consumeClose();

  if (InitExprsOk && closed)
    return Actions.ActOnInitList(LBraceLoc, InitExprs,
                                 T.getCloseLocation());

  return ExprError(); // an error occurred.
}
开发者ID:Xmister,项目名称:clang-onex,代码行数:96,代码来源:ParseInit.cpp

示例13: getInitExprs

void RemoveUnusedStructField::getInitExprs(const Type *Ty, 
                                           const Expr *E,
                                           const IndexVector *IdxVec,
                                           ExprVector &InitExprs)
{
  const ArrayType *ArrayTy = dyn_cast<ArrayType>(Ty);
  if (ArrayTy) {
    const InitListExpr *ILE = dyn_cast<InitListExpr>(E);
    TransAssert(ILE && "Invalid array initializer!");
    unsigned int NumInits = ILE->getNumInits();
    Ty = ArrayTy->getElementType().getTypePtr();
    
    for (unsigned I = 0; I < NumInits; ++I) {
      const Expr *Init = ILE->getInit(I);
      getInitExprs(Ty, Init, IdxVec, InitExprs);
    }
    return;
  }
 
  const InitListExpr *ILE = dyn_cast<InitListExpr>(E);
  if (!ILE)
    return;

  const RecordType *RT = NULL;
  if (Ty->isUnionType()) {
    RT = Ty->getAsUnionType();
  }
  else if (Ty->isStructureType()) {
    RT = Ty->getAsStructureType();
  }
  else {
    TransAssert(0 && "Bad RecordType!");
  }

  const RecordDecl *RD = RT->getDecl();
  unsigned int VecSz = IdxVec->size();
  for (IndexVector::const_iterator FI = IdxVec->begin(),
       FE = IdxVec->end(); FI != FE; ++FI)
  {
    const FieldDecl *FD = getFieldDeclByIdx(RD, (*FI));
    TransAssert(FD && "NULL FieldDecl!");
    IndexVector *FieldIdxVec = FieldToIdxVector[FD];
    TransAssert(FieldIdxVec && "Cannot find FieldIdxVec!");

    Ty = FD->getType().getTypePtr();
    const Expr *Init;
    unsigned int InitListIdx;
    if (RD->isUnion())
      InitListIdx = 0;
    else
      InitListIdx = (*FI);

    if (InitListIdx >= ILE->getNumInits())
      return;

    Init = ILE->getInit(InitListIdx);

    if (FD == TheFieldDecl) {
      InitExprs.push_back(Init);
      TransAssert((VecSz == 1) && "Bad IndexVector size!"); (void)VecSz;
    }
    else {
      getInitExprs(Ty, Init, FieldIdxVec, InitExprs);
    }
  }
}
开发者ID:annulen,项目名称:creduce,代码行数:66,代码来源:RemoveUnusedStructField.cpp

示例14: ParseAsmStatement


//.........这里部分代码省略.........
    Diag(Loc, diag::w_asm_qualifier_ignored) << "_Atomic";

  // Remember if this was a volatile asm.
  bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile;
  if (Tok.isNot(tok::l_paren)) {
    Diag(Tok, diag::err_expected_lparen_after) << "asm";
    SkipUntil(tok::r_paren, StopAtSemi);
    return StmtError();
  }
  BalancedDelimiterTracker T(*this, tok::l_paren);
  T.consumeOpen();

  ExprResult AsmString(ParseAsmStringLiteral());

  // Check if GNU-style InlineAsm is disabled.
  // Error on anything other than empty string.
  if (!(getLangOpts().GNUAsm || AsmString.isInvalid())) {
    const auto *SL = cast<StringLiteral>(AsmString.get());
    if (!SL->getString().trim().empty())
      Diag(Loc, diag::err_gnu_inline_asm_disabled);
  }

  if (AsmString.isInvalid()) {
    // Consume up to and including the closing paren.
    T.skipToEnd();
    return StmtError();
  }

  SmallVector<IdentifierInfo *, 4> Names;
  ExprVector Constraints;
  ExprVector Exprs;
  ExprVector Clobbers;

  if (Tok.is(tok::r_paren)) {
    // We have a simple asm expression like 'asm("foo")'.
    T.consumeClose();
    return Actions.ActOnGCCAsmStmt(AsmLoc, /*isSimple*/ true, isVolatile,
                                   /*NumOutputs*/ 0, /*NumInputs*/ 0, nullptr,
                                   Constraints, Exprs, AsmString.get(),
                                   Clobbers, T.getCloseLocation());
  }

  // Parse Outputs, if present.
  bool AteExtraColon = false;
  if (Tok.is(tok::colon) || Tok.is(tok::coloncolon)) {
    // In C++ mode, parse "::" like ": :".
    AteExtraColon = Tok.is(tok::coloncolon);
    ConsumeToken();

    if (!AteExtraColon && ParseAsmOperandsOpt(Names, Constraints, Exprs))
      return StmtError();
  }

  unsigned NumOutputs = Names.size();

  // Parse Inputs, if present.
  if (AteExtraColon || Tok.is(tok::colon) || Tok.is(tok::coloncolon)) {
    // In C++ mode, parse "::" like ": :".
    if (AteExtraColon)
      AteExtraColon = false;
    else {
      AteExtraColon = Tok.is(tok::coloncolon);
      ConsumeToken();
    }

    if (!AteExtraColon && ParseAsmOperandsOpt(Names, Constraints, Exprs))
      return StmtError();
  }

  assert(Names.size() == Constraints.size() &&
         Constraints.size() == Exprs.size() && "Input operand size mismatch!");

  unsigned NumInputs = Names.size() - NumOutputs;

  // Parse the clobbers, if present.
  if (AteExtraColon || Tok.is(tok::colon)) {
    if (!AteExtraColon)
      ConsumeToken();

    // Parse the asm-string list for clobbers if present.
    if (Tok.isNot(tok::r_paren)) {
      while (1) {
        ExprResult Clobber(ParseAsmStringLiteral());

        if (Clobber.isInvalid())
          break;

        Clobbers.push_back(Clobber.get());

        if (!TryConsumeToken(tok::comma))
          break;
      }
    }
  }

  T.consumeClose();
  return Actions.ActOnGCCAsmStmt(
      AsmLoc, false, isVolatile, NumOutputs, NumInputs, Names.data(),
      Constraints, Exprs, AsmString.get(), Clobbers, T.getCloseLocation());
}
开发者ID:2asoft,项目名称:freebsd,代码行数:101,代码来源:ParseStmtAsm.cpp

示例15: Evaluate


//.........这里部分代码省略.........
					Evaluate(calculator, recursions + 1);
					return;
				}
			}
		}
		// Apply Flat attribute
		if(attributes.Contains(atFlat))
		{
			Flatten(FunctionName());
		}
		// Apply OneIdentity attribute
		if(attributes.Contains(atOneIdentity))
		{
			if(ApplyOneIdentity())
				return;
		}
		// Apply Listable attribute
		if(attributes.Contains(atListable))
		{
			// Determine resulting list length, check if there are lists with different lengths
			bool listFound(false);
			ExprVector::size_type listSize(0);
			for(ExprVector::const_iterator leaf = leaves.begin(); leaf != leaves.end(); ++leaf)
				if((*leaf)->FunctionName() == "List")
					if(!listFound)
					{
						listSize = (*leaf)->LeafCount();
						listFound = true;
					}
					else
						if(listSize != (*leaf)->LeafCount())
							throw EvaluateException("Listable operation requires lists of the same length.");
			// Construct resulting list
			if(listFound)
			{
				ExprVector items;
				// Number of resulting list items = items in operand list
				items.reserve(listSize);
				// Loop through list items
				for(ExprVector::size_type position = 0; position < listSize; ++position)
				{
					// List item = function call, number of operands = number of original operands
					Expression *item = new Expression(FunctionName(), leaves.size());
					for(ExprVector::iterator itemLeaf = leaves.begin(); itemLeaf != leaves.end(); ++itemLeaf)
					{
						if((*itemLeaf)->FunctionName() == "List")
						{
							// Add corresponding list item
							item->AppendLeaf(*((*itemLeaf)->leaves.begin() + position));
						}
						else
						{
							// Add "whole" item (clone if necessary)
							if(position == 0)
								item->AppendLeaf(*itemLeaf);
							else
								item->AppendLeaf((*itemLeaf)->Clone());
						}
					}
					items.push_back(item);
				}
				// Delete lists (elements are now in resulting list)
				for(ExprVector::iterator itemLeaf = leaves.begin(); itemLeaf != leaves.end(); ++itemLeaf)
					if((*itemLeaf)->FunctionName() == "List")
					{
						(*itemLeaf)->leaves.clear();
						delete *itemLeaf;
					}
				delete head;
				head = new Expression("List");
				leaves = items;
				// Evaluate the list for itself
				Evaluate(calculator, recursions);
				return;
			}
		}
		// Apply Orderless attribute
		if(attributes.Contains(atOrderless))
		{
			std::sort(leaves.begin(), leaves.end(), &Compare);
		}
		// Apply down value rules
		bool changed(false);
		if(def->ApplyDownValues(this, calculator, &changed))
		{
			if(changed)
				Evaluate(calculator, recursions + 1);
			return;
		}
		// Execute linked operator, if specified
		if(def->Predef())
			def->Predef()->Apply(this, calculator, recursions);
	}
	else
	{
		// Otherwise simply evaluate the leaves
		for(ExprVector::const_iterator leaf = leaves.begin(); leaf != leaves.end(); ++leaf)
			(*leaf)->Evaluate(calculator, recursions);
	}
}
开发者ID:dubrousky,项目名称:Mathador,代码行数:101,代码来源:Expression.cpp


注:本文中的ExprVector::push_back方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。