private static ExpressionBase ParseComparison(PositionalTokenizer tokenizer, ExpressionBase left, ComparisonOperation operation, int joinerLine, int joinerColumn) { var right = ParseExpression(tokenizer, OperationPriority.Compare); switch (right.Type) { case ExpressionType.ParseError: return(right); case ExpressionType.BooleanConstant: case ExpressionType.Conditional: // will be rebalanced case ExpressionType.FloatConstant: case ExpressionType.FunctionCall: case ExpressionType.IntegerConstant: case ExpressionType.Mathematic: case ExpressionType.StringConstant: case ExpressionType.Variable: break; default: var expressionTokenizer = tokenizer as ExpressionTokenizer; if (expressionTokenizer != null) { expressionTokenizer.QueueExpression(right); } right = new KeywordExpression(ComparisonExpression.GetOperatorString(operation), joinerLine, joinerColumn); return(ParseError(tokenizer, "Incompatible comparison", right)); } return(new ComparisonExpression(left, operation, right)); }
/// <summary> /// Replaces the variables in the expression with values from <paramref name="scope" />. /// </summary> /// <param name="scope">The scope object containing variable values.</param> /// <param name="result">[out] The new expression containing the replaced variables.</param> /// <returns> /// <c>true</c> if substitution was successful, <c>false</c> if something went wrong, in which case <paramref name="result" /> will likely be a <see cref="ParseErrorExpression" />. /// </returns> public override bool ReplaceVariables(InterpreterScope scope, out ExpressionBase result) { ExpressionBase left; if (!Left.ReplaceVariables(scope, out left)) { result = left; return(false); } ExpressionBase right; if (!Right.ReplaceVariables(scope, out right)) { result = right; return(false); } var comparison = new ComparisonExpression(left, Operation, right); CopyLocation(comparison); result = comparison; return(true); }
internal static ExpressionBase InvertExpression(ExpressionBase expression) { // logical inversion var condition = expression as ConditionalExpression; if (condition != null) { var newConditions = new List <ExpressionBase>(condition._conditions.Count); foreach (var oldCondition in condition._conditions) { newConditions.Add(InvertExpression(oldCondition)); } switch (condition.Operation) { case ConditionalOperation.Not: // !(!A) => A return(newConditions[0]); case ConditionalOperation.And: // !(A && B) => !A || !B return(new ConditionalExpression(ConditionalOperation.Or, newConditions)); case ConditionalOperation.Or: // !(A || B) => !A && !B return(new ConditionalExpression(ConditionalOperation.And, newConditions)); default: throw new NotImplementedException("Unsupported condition operation"); } } // comparative inversion var comparison = expression as ComparisonExpression; if (comparison != null) { // !(A == B) => A != B, !(A < B) => A >= B, ... return(new ComparisonExpression( comparison.Left, ComparisonExpression.GetOppositeComparisonOperation(comparison.Operation), comparison.Right)); } // boolean constant var boolean = expression as BooleanConstantExpression; if (boolean != null) { return(new BooleanConstantExpression(!boolean.Value)); } // special handling for built-in functions var function = expression as FunctionCallExpression; if (function != null && function.Parameters.Count() == 0) { if (function.FunctionName.Name == "always_true") { return(AlwaysFalseFunction.CreateAlwaysFalseFunctionCall()); } if (function.FunctionName.Name == "always_false") { return(AlwaysTrueFunction.CreateAlwaysTrueFunctionCall()); } } // unsupported inversion return(new ParseErrorExpression("! operator cannot be applied to " + expression.Type, expression)); }
private static ExpressionBase ParseComparison(PositionalTokenizer tokenizer, ExpressionBase left, ComparisonOperation operation, int joinerLine, int joinerColumn) { var right = ExpressionBase.Parse(tokenizer); switch (right.Type) { case ExpressionType.ParseError: return(right); case ExpressionType.Conditional: // will be rebalanced case ExpressionType.FunctionCall: case ExpressionType.IntegerConstant: case ExpressionType.Mathematic: case ExpressionType.StringConstant: case ExpressionType.Variable: break; default: ParseError(tokenizer, "incompatible comparison", new KeywordExpression(ComparisonExpression.GetOperatorString(operation), joinerLine, joinerColumn)); break; } return(new ComparisonExpression(left, operation, right)); }