private bool IsValueExpression(Expression expression) { if (expression is LiteralExpression) { CsTokenType tokenType = ((LiteralExpression)expression).Token.CsTokenType; return(tokenType == CsTokenType.Number || tokenType == CsTokenType.String || tokenType == CsTokenType.Null || tokenType == CsTokenType.True || tokenType == CsTokenType.False); } if (expression is ParenthesizedExpression) { return(this.IsValueExpression(((ParenthesizedExpression)expression).InnerExpression)); } if (expression is RelationalExpression) { RelationalExpression re = (RelationalExpression)expression; return(this.IsValueExpression(re.LeftHandSide) && this.IsValueExpression(re.RightHandSide)); } if (expression is ArithmeticExpression) { ArithmeticExpression ae = (ArithmeticExpression)expression; return(this.IsValueExpression(ae.LeftHandSide) && this.IsValueExpression(ae.RightHandSide)); } return(false); }
/// <summary> /// Reads a relational expression. /// </summary> /// <param name="leftHandSide"> /// The expression on the left hand side of the operator. /// </param> /// <param name="previousPrecedence"> /// The precedence of the expression just before this one. /// </param> /// <param name="parentReference"> /// The parent code part. /// </param> /// <param name="unsafeCode"> /// Indicates whether the code being parsed resides in an unsafe code block. /// </param> /// <returns> /// Returns the expression. /// </returns> private RelationalExpression GetRelationalExpression( Expression leftHandSide, ExpressionPrecedence previousPrecedence, Reference<ICodePart> parentReference, bool unsafeCode) { Param.AssertNotNull(leftHandSide, "leftHandSide"); Param.Ignore(previousPrecedence); Param.AssertNotNull(parentReference, "parentReference"); Param.Ignore(unsafeCode); RelationalExpression expression = null; Reference<ICodePart> expressionReference = new Reference<ICodePart>(); // Read the details of the expression. OperatorSymbol operatorToken = this.PeekOperatorToken(parentReference, expressionReference); Debug.Assert(operatorToken.Category == OperatorCategory.Relational, "Expected a relational operator"); // Check the precedence of the operators to make sure we can gather this statement now. ExpressionPrecedence precedence = GetOperatorPrecedence(operatorToken.SymbolType); if (CheckPrecedence(previousPrecedence, precedence)) { // Add the operator token to the document and advance the symbol manager up to it. this.symbols.Advance(); this.tokens.Add(operatorToken); // Get the expression on the right-hand side of the operator. Expression rightHandSide = this.GetOperatorRightHandExpression(precedence, expressionReference, unsafeCode); // Create the partial token list for the expression. CsTokenList partialTokens = new CsTokenList(this.tokens, leftHandSide.Tokens.First, this.tokens.Last); // Get the expression operator type. RelationalExpression.Operator type; switch (operatorToken.SymbolType) { case OperatorType.ConditionalEquals: type = RelationalExpression.Operator.EqualTo; break; case OperatorType.NotEquals: type = RelationalExpression.Operator.NotEqualTo; break; case OperatorType.GreaterThan: type = RelationalExpression.Operator.GreaterThan; break; case OperatorType.GreaterThanOrEquals: type = RelationalExpression.Operator.GreaterThanOrEqualTo; break; case OperatorType.LessThan: type = RelationalExpression.Operator.LessThan; break; case OperatorType.LessThanOrEquals: type = RelationalExpression.Operator.LessThanOrEqualTo; break; default: Debug.Fail("Unexpected operator type"); throw new InvalidOperationException(); } // Create and return the expression. expression = new RelationalExpression(partialTokens, type, leftHandSide, rightHandSide); expressionReference.Target = expression; } return expression; }
/// <summary> /// Reads a relational expression. /// </summary> /// <param name="sourceCode"> /// The file containing the expression. /// </param> /// <param name="parentReference"> /// The parent code unit. /// </param> /// <param name="leftHandSide"> /// The expression on the left hand side of the operator. /// </param> /// <param name="previousPrecedence"> /// The precedence of the expression just before this one. /// </param> /// <returns> /// Returns the expression. /// </returns> private RelationalExpression GetConditionalPreprocessorEqualityExpression( SourceCode sourceCode, Reference<ICodePart> parentReference, Expression leftHandSide, ExpressionPrecedence previousPrecedence) { Param.AssertNotNull(sourceCode, "sourceCode"); Param.AssertNotNull(parentReference, "parentReference"); Param.AssertNotNull(leftHandSide, "leftHandSide"); Param.Ignore(previousPrecedence); RelationalExpression expression = null; this.AdvanceToNextConditionalDirectiveCodeSymbol(parentReference); Symbol firstSymbol = this.symbols.Peek(1); if (firstSymbol == null) { throw new SyntaxException(sourceCode, firstSymbol.LineNumber); } Reference<ICodePart> expressionReference = new Reference<ICodePart>(); // Create the operator symbol. OperatorType type; OperatorCategory category; GetOperatorType(firstSymbol, out type, out category); OperatorSymbol operatorToken = new OperatorSymbol(firstSymbol.Text, category, type, firstSymbol.Location, expressionReference, this.symbols.Generated); // Check the precedence of the operators to make sure we can gather this statement now. ExpressionPrecedence precedence = GetOperatorPrecedence(operatorToken.SymbolType); if (CheckPrecedence(previousPrecedence, precedence)) { // Add the operator token to the document and advance the symbol manager up to it. this.symbols.Advance(); this.tokens.Add(operatorToken); // Get the expression on the right-hand side of the operator. Expression rightHandSide = this.GetNextConditionalPreprocessorExpression(sourceCode, precedence); if (rightHandSide == null) { throw new SyntaxException(sourceCode, operatorToken.LineNumber); } // Create the partial token list for the expression. CsTokenList partialTokens = new CsTokenList(this.tokens, leftHandSide.Tokens.First, this.tokens.Last); // Get the expression operator type. RelationalExpression.Operator relationalType; switch (operatorToken.SymbolType) { case OperatorType.ConditionalEquals: relationalType = RelationalExpression.Operator.EqualTo; break; case OperatorType.NotEquals: relationalType = RelationalExpression.Operator.NotEqualTo; break; default: throw new SyntaxException(sourceCode, operatorToken.LineNumber); } // Create and return the expression. expression = new RelationalExpression(partialTokens, relationalType, leftHandSide, rightHandSide); expressionReference.Target = expression; } return expression; }
/// <summary> /// Reads a relational expression. /// </summary> /// <param name="sourceCode"> /// The file containing the expression. /// </param> /// <param name="parentReference"> /// The parent code unit. /// </param> /// <param name="leftHandSide"> /// The expression on the left hand side of the operator. /// </param> /// <param name="previousPrecedence"> /// The precedence of the expression just before this one. /// </param> /// <returns> /// Returns the expression. /// </returns> private RelationalExpression GetConditionalPreprocessorEqualityExpression( SourceCode sourceCode, Reference <ICodePart> parentReference, Expression leftHandSide, ExpressionPrecedence previousPrecedence) { Param.AssertNotNull(sourceCode, "sourceCode"); Param.AssertNotNull(parentReference, "parentReference"); Param.AssertNotNull(leftHandSide, "leftHandSide"); Param.Ignore(previousPrecedence); RelationalExpression expression = null; this.AdvanceToNextConditionalDirectiveCodeSymbol(parentReference); Symbol firstSymbol = this.symbols.Peek(1); if (firstSymbol == null) { throw new SyntaxException(sourceCode, firstSymbol.LineNumber); } Reference <ICodePart> expressionReference = new Reference <ICodePart>(); // Create the operator symbol. OperatorType type; OperatorCategory category; GetOperatorType(firstSymbol, out type, out category); OperatorSymbol operatorToken = new OperatorSymbol(firstSymbol.Text, category, type, firstSymbol.Location, expressionReference, this.symbols.Generated); // Check the precedence of the operators to make sure we can gather this statement now. ExpressionPrecedence precedence = GetOperatorPrecedence(operatorToken.SymbolType); if (CheckPrecedence(previousPrecedence, precedence)) { // Add the operator token to the document and advance the symbol manager up to it. this.symbols.Advance(); this.tokens.Add(operatorToken); // Get the expression on the right-hand side of the operator. Expression rightHandSide = this.GetNextConditionalPreprocessorExpression(sourceCode, precedence); if (rightHandSide == null) { throw new SyntaxException(sourceCode, operatorToken.LineNumber); } // Create the partial token list for the expression. CsTokenList partialTokens = new CsTokenList(this.tokens, leftHandSide.Tokens.First, this.tokens.Last); // Get the expression operator type. RelationalExpression.Operator relationalType; switch (operatorToken.SymbolType) { case OperatorType.ConditionalEquals: relationalType = RelationalExpression.Operator.EqualTo; break; case OperatorType.NotEquals: relationalType = RelationalExpression.Operator.NotEqualTo; break; default: throw new SyntaxException(sourceCode, operatorToken.LineNumber); } // Create and return the expression. expression = new RelationalExpression(partialTokens, relationalType, leftHandSide, rightHandSide); expressionReference.Target = expression; } return(expression); }
/// <summary> /// The save. /// </summary> /// <param name="operator"> /// The operator. /// </param> private void Save(RelationalExpression.Operator @operator) { var operatorString = string.Empty; switch (@operator) { case RelationalExpression.Operator.EqualTo: operatorString = "=="; break; case RelationalExpression.Operator.NotEqualTo: operatorString = "!="; break; case RelationalExpression.Operator.GreaterThan: operatorString = ">"; break; case RelationalExpression.Operator.GreaterThanOrEqualTo: operatorString = ">="; break; case RelationalExpression.Operator.LessThan: operatorString = "<"; break; case RelationalExpression.Operator.LessThanOrEqualTo: operatorString = "<="; break; default: break; } this.cppWriter.Write(' '); this.cppWriter.Write(operatorString); this.cppWriter.Write(' '); }
/// <summary> /// The save. /// </summary> /// <param name="relationalExpression"> /// The relational expression. /// </param> private void Save(RelationalExpression relationalExpression) { @switch(relationalExpression.LeftHandSide); this.Save(relationalExpression.OperatorType); @switch(relationalExpression.RightHandSide); }