/// <summary> /// Reads the next foreach statement from the file and returns it. /// </summary> /// <param name="parentReference"> /// The parent code unit. /// </param> /// <param name="unsafeCode"> /// Indicates whether the code being parsed resides in an unsafe code block. /// </param> /// <returns> /// Returns the statement. /// </returns> private ForeachStatement ParseForeachStatement(Reference<ICodePart> parentReference, bool unsafeCode) { Param.AssertNotNull(parentReference, "parentReference"); Param.Ignore(unsafeCode); Reference<ICodePart> statementReference = new Reference<ICodePart>(); // Get the foreach keyword. CsToken firstToken = this.GetToken(CsTokenType.Foreach, SymbolType.Foreach, parentReference, statementReference); Node<CsToken> firstTokenNode = this.tokens.InsertLast(firstToken); // Get the opening parenthesis. Bracket openParenthesis = this.GetBracketToken(CsTokenType.OpenParenthesis, SymbolType.OpenParenthesis, statementReference); Node<CsToken> openParenthesisNode = this.tokens.InsertLast(openParenthesis); // Get the variable. VariableDeclarationExpression variable = this.GetNextExpression(ExpressionPrecedence.None, statementReference, unsafeCode, true, false) as VariableDeclarationExpression; if (variable == null) { throw this.CreateSyntaxException(); } // Get the 'in' keyword and add it. this.tokens.Add(this.GetToken(CsTokenType.In, SymbolType.In, statementReference)); // Get the item being iterated over. Expression item = this.GetNextExpression(ExpressionPrecedence.None, statementReference, unsafeCode); if (item == null) { throw this.CreateSyntaxException(); } // Get the closing parenthesis. Bracket closeParenthesis = this.GetBracketToken(CsTokenType.CloseParenthesis, SymbolType.CloseParenthesis, statementReference); Node<CsToken> closeParenthesisNode = this.tokens.InsertLast(closeParenthesis); openParenthesis.MatchingBracketNode = closeParenthesisNode; closeParenthesis.MatchingBracketNode = openParenthesisNode; // Get the embedded statement. Statement childStatement = this.GetNextStatement(statementReference, unsafeCode); if (childStatement == null) { throw this.CreateSyntaxException(); } // Create the token list for the statement. CsTokenList partialTokens = new CsTokenList(this.tokens, firstTokenNode, this.tokens.Last); // Create the foreach-statement. ForeachStatement statement = new ForeachStatement(partialTokens, variable, item); statement.EmbeddedStatement = childStatement; statementReference.Target = statement; // Add the variable. foreach (VariableDeclaratorExpression declarator in variable.Declarators) { Variable localVariable = new Variable( variable.Type, declarator.Identifier.Token.Text, VariableModifiers.None, CodeLocation.Join(variable.Type.Location, declarator.Identifier.Token.Location), statementReference, variable.Type.Generated); // If there is already a variable in this scope with the same name, ignore this one. if (!statement.Variables.Contains(declarator.Identifier.Token.Text)) { statement.Variables.Add(localVariable); } } return statement; }
/// <summary> /// The save. /// </summary> /// <param name="foreachStatement"> /// The foreach statement. /// </param> private void Save(ForeachStatement foreachStatement) { this.cppWriter.Write("for ("); this.saveVariablesMode = SaveVariablesMode.AppendRightReferene; this.Save(foreachStatement.Variable); this.saveVariablesMode = SaveVariablesMode.Default; this.cppWriter.Write(" : "); @switch(foreachStatement.Item); this.cppWriter.Write(")"); this.Save(foreachStatement.EmbeddedStatement); }