private bool TryGetConstant(string currentToken, out IExpression constant) { if (currentToken.Equals("true", this.context.ParsingStringComparison)) { constant = new ConstantValueExpression(true); } else if (currentToken.Equals("false", this.context.ParsingStringComparison)) { constant = new ConstantValueExpression(false); } else if (currentToken.Equals("null", this.context.ParsingStringComparison)) { constant = new ConstantValueExpression(null); } else if (currentToken.Equals("pi", this.context.ParsingStringComparison)) { constant = new ConstantValueExpression(Math.PI); } else if (currentToken.Equals("e", this.context.ParsingStringComparison)) { constant = new ConstantValueExpression(Math.E); } else { constant = null; } return(null != constant); }
public void TestUnsupportedValue() { var unsupportedValue = new { Name = "Shaun", Age = 99 }; var constantValueExpression = new ConstantValueExpression(unsupportedValue); Assert.AreEqual(unsupportedValue, constantValueExpression.Evaluate(null)); }
public void DefaultValues() { var sut = new ConstantValueExpression(); Assert.Null(sut.Value); Assert.AreNotEqual(0, sut.GetHashCode()); Assert.AreNotEqual(1, sut.GetHashCode()); }
public void SettingValues() { var sut = new ConstantValueExpression { Value = "a" }; Assert.AreEqual("a", sut.Value); }
public void Equality_Default() { var a = new ConstantValueExpression(); var b = new ConstantValueExpression(); Assert.AreEqual(a, b); Assert.AreEqual(a.GetHashCode(), b.GetHashCode()); }
public void TestDateTimeValue() { var now = DateTime.Now; var constantValueExpression = new ConstantValueExpression(now); Assert.AreEqual(now, constantValueExpression.Evaluate(null)); }
public void Equality_DifferentValue() { var a = new ConstantValueExpression { Value = "a" }; var b = new ConstantValueExpression(); Assert.AreNotEqual(a, b); Assert.AreNotEqual(a.GetHashCode(), b.GetHashCode()); }
public void Equality_ReallyTheSame() { var a = new ConstantValueExpression { Value = "a" }; var b = new ConstantValueExpression { Value = "a" }; Assert.AreEqual(a, b); Assert.AreEqual(a.GetHashCode(), b.GetHashCode()); }
public void Should_parse_AlphaNumeric(string input, ConstantValueExpression expected) { // Arrange _outputHelper.WriteLine($"input : '{input}'"); TokenList <FilterToken> tokens = _tokenizer.Tokenize(input); _outputHelper.WriteLine($"Tokens : ${StringifyTokens(tokens)}"); // Act FilterExpression actual = FilterTokenParser.AlphaNumeric.Parse(tokens); _outputHelper.WriteLine($"actual is '{actual.EscapedParseableString}'"); // Assert AssertThatShould_parse(actual, expected); }
public void TestBooleanValue() { var constantValueExpression = new ConstantValueExpression(true); Assert.AreEqual(true, constantValueExpression.Evaluate(null)); }
public void VisitorWithReturnIsImplemented() { var sut = new ConstantValueExpression(); sut.Accept(23).VerifyWithReturn(v => v.Visit(sut, 23)); }
public void TestDoubleValue() { var constantValueExpression = new ConstantValueExpression(123d); Assert.AreEqual(123d, constantValueExpression.Evaluate(null)); }
public void TestDecimalValue() { var constantValueExpression = new ConstantValueExpression(123M); Assert.AreEqual(123M, constantValueExpression.Evaluate(null)); }
public void TestIntegerValue() { var constantValueExpression = new ConstantValueExpression(123); Assert.AreEqual(123, constantValueExpression.Evaluate(null)); }
public void TestLongValue() { var constantValueExpression = new ConstantValueExpression(123L); Assert.AreEqual(123L, constantValueExpression.Evaluate(null)); }
private IExpression CompileExpression(Queue <Token> tokens, OperatorPrecedence minimumPrecedence, IList <string> variables, bool isWithinFunction) { if (tokens == null) { throw new ArgumentNullException("tokens", "You must call Tokenise before compiling"); } IExpression leftHandSide = null; var currentToken = tokens.PeekOrDefault(); Token previousToken = null; while (currentToken != null) { Func <IExpression[], IDictionary <string, object>, object> function = null; IOperator op = null; if (_registeredOperators.TryGetValue(currentToken.CurrentToken, out op)) // Are we an IOperator? { var precedence = op.GetPrecedence(previousToken); if (precedence > minimumPrecedence) { tokens.Dequeue(); if (!op.CanGetCaptiveTokens(previousToken, currentToken, tokens)) { // Do it anyway to update the list of tokens op.GetCaptiveTokens(previousToken, currentToken, tokens); break; } else { IExpression rightHandSide = null; var captiveTokens = op.GetCaptiveTokens(previousToken, currentToken, tokens); if (captiveTokens.Length > 1) { var innerTokens = op.GetInnerCaptiveTokens(captiveTokens); rightHandSide = CompileExpression(new Queue <Token>(innerTokens), OperatorPrecedence.Minimum, variables, isWithinFunction); currentToken = captiveTokens[captiveTokens.Length - 1]; } else { rightHandSide = CompileExpression(tokens, precedence, variables, isWithinFunction); // We are at the end of an expression so fake it up. currentToken = new Token(")", -1); } leftHandSide = op.BuildExpression(previousToken, new[] { leftHandSide, rightHandSide }, _options); } } else { break; } } else if (_registeredFunctions.TryGetValue(currentToken.CurrentToken, out function)) // or an IFunction? { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); var expressions = new List <IExpression>(); var captiveTokens = new Queue <Token>(); var parenCount = 0; tokens.Dequeue(); // Loop through the list of tokens and split by ParameterSeparator character while (tokens.Count > 0) { var nextToken = tokens.Dequeue(); if (string.Equals(nextToken.CurrentToken, "(", StringComparison.Ordinal)) { parenCount++; } else if (string.Equals(nextToken.CurrentToken, ")", StringComparison.Ordinal)) { parenCount--; } if (!(parenCount == 1 && nextToken.CurrentToken == "(") && !(parenCount == 0 && nextToken.CurrentToken == ")")) { captiveTokens.Enqueue(nextToken); } if (parenCount == 0 && captiveTokens.Any()) { expressions.Add(CompileExpression(captiveTokens, minimumPrecedence: OperatorPrecedence.Minimum, variables: variables, isWithinFunction: true)); captiveTokens.Clear(); } else if (string.Equals(nextToken.CurrentToken, ParameterSeparator.ToString(), StringComparison.Ordinal) && parenCount == 1) { // TODO: Should we expect expressions to be null??? expressions.Add(CompileExpression(captiveTokens, minimumPrecedence: 0, variables: variables, isWithinFunction: true)); captiveTokens.Clear(); } if (parenCount <= 0) { break; } } leftHandSide = new FunctionExpression(currentToken.CurrentToken, function, expressions.ToArray()); } else if (currentToken.CurrentToken.IsNumeric()) // Or a number { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); tokens.Dequeue(); int intValue = 0; decimal decimalValue = 0.0M; double doubleValue = 0.0; float floatValue = 0.0f; long longValue = 0; if (int.TryParse(currentToken.CurrentToken, out intValue)) { leftHandSide = new ConstantValueExpression(ConstantValueExpressionType.Integer, intValue); } else if (decimal.TryParse(currentToken.CurrentToken, out decimalValue)) { leftHandSide = new ConstantValueExpression(ConstantValueExpressionType.Decimal, decimalValue); } else if (double.TryParse(currentToken.CurrentToken, out doubleValue)) { leftHandSide = new ConstantValueExpression(ConstantValueExpressionType.Double, doubleValue); } else if (float.TryParse(currentToken.CurrentToken, out floatValue)) { leftHandSide = new ConstantValueExpression(ConstantValueExpressionType.Float, floatValue); } else if (long.TryParse(currentToken.CurrentToken, out longValue)) { leftHandSide = new ConstantValueExpression(ConstantValueExpressionType.Long, longValue); } } else if (currentToken.CurrentToken.StartsWith("[") && currentToken.CurrentToken.EndsWith("]")) // or a variable? { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); tokens.Dequeue(); string variableName = currentToken.CurrentToken.Replace("[", "").Replace("]", ""); leftHandSide = new VariableExpression(variableName); if (!variables.Contains(variableName, _stringComparer)) { variables.Add(variableName); } } else if (string.Equals(currentToken.CurrentToken, "true", StringComparison.OrdinalIgnoreCase)) // or a boolean? { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); tokens.Dequeue(); leftHandSide = new ConstantValueExpression(ConstantValueExpressionType.Boolean, true); } else if (string.Equals(currentToken.CurrentToken, "false", StringComparison.OrdinalIgnoreCase)) { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); tokens.Dequeue(); leftHandSide = new ConstantValueExpression(ConstantValueExpressionType.Boolean, false); } else if (string.Equals(currentToken.CurrentToken, "null", StringComparison.OrdinalIgnoreCase)) // or a null? { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); tokens.Dequeue(); leftHandSide = new ConstantValueExpression(ConstantValueExpressionType.Null, null); } else if (currentToken.CurrentToken.StartsWith(DateSeparator.ToString()) && currentToken.CurrentToken.EndsWith(DateSeparator.ToString())) // or a date? { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); tokens.Dequeue(); string dateToken = currentToken.CurrentToken.Replace(DateSeparator.ToString(), ""); DateTime date = DateTime.MinValue; // If we can't parse the date let's check for some known tags. if (!DateTime.TryParse(dateToken, out date)) { if (string.Equals("TODAY", dateToken, StringComparison.OrdinalIgnoreCase)) { date = DateTime.Today; } else if (string.Equals("NOW", dateToken, StringComparison.OrdinalIgnoreCase)) { date = DateTime.Now; } else { throw new UnrecognisedTokenException(dateToken); } } leftHandSide = new ConstantValueExpression(ConstantValueExpressionType.DateTime, date); } else if ((currentToken.CurrentToken.StartsWith("'") && currentToken.CurrentToken.EndsWith("'")) || (currentToken.CurrentToken.StartsWith("\"") && currentToken.CurrentToken.EndsWith("\""))) { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); tokens.Dequeue(); leftHandSide = new ConstantValueExpression(ConstantValueExpressionType.String, CleanString(currentToken.CurrentToken.Substring(1, currentToken.Length - 2))); } else if (string.Equals(currentToken.CurrentToken, ParameterSeparator.ToString(), StringComparison.Ordinal)) // Make sure we ignore the parameter separator { // TODO should we throw an exception if we are not within a function? if (!isWithinFunction) { throw new ExpressiveException($"Unexpected token '{currentToken}'"); } tokens.Dequeue(); //throw new InvalidOperationException("Unrecognised token '" + currentToken + "'"); //if (!string.Equals(currentToken, ParameterSeparator.ToString(), StringComparison.Ordinal)) // Make sure we ignore the parameter separator //{ // currentToken = CleanString(currentToken); // leftHandSide = new ConstantValueExpression(ConstantValueExpressionType.Unknown, currentToken); //} } else { tokens.Dequeue(); throw new UnrecognisedTokenException(currentToken.CurrentToken); } previousToken = currentToken; currentToken = tokens.PeekOrDefault(); } return(leftHandSide); }
public void TestStringValue() { var constantValueExpression = new ConstantValueExpression("123"); Assert.AreEqual("123", constantValueExpression.Evaluate(null)); }
private IExpression CompileExpression(Queue <Token> tokens, OperatorPrecedence minimumPrecedence, IList <string> variables, bool isWithinFunction) { if (tokens == null) { throw new ArgumentNullException(nameof(tokens), "You must call Tokenise before compiling"); } IExpression leftHandSide = null; var currentToken = tokens.PeekOrDefault(); Token previousToken = null; while (currentToken != null) { if (this.registeredOperators.TryGetValue(currentToken.CurrentToken, out var op)) // Are we an IOperator? { var precedence = op.GetPrecedence(previousToken); if (precedence > minimumPrecedence) { tokens.Dequeue(); if (!op.CanGetCaptiveTokens(previousToken, currentToken, tokens)) { // Do it anyway to update the list of tokens op.GetCaptiveTokens(previousToken, currentToken, tokens); break; } else { IExpression rightHandSide = null; var captiveTokens = op.GetCaptiveTokens(previousToken, currentToken, tokens); if (captiveTokens.Length > 1) { var innerTokens = op.GetInnerCaptiveTokens(captiveTokens); rightHandSide = this.CompileExpression(new Queue <Token>(innerTokens), OperatorPrecedence.Minimum, variables, isWithinFunction); currentToken = captiveTokens[captiveTokens.Length - 1]; } else { rightHandSide = this.CompileExpression(tokens, precedence, variables, isWithinFunction); // We are at the end of an expression so fake it up. currentToken = new Token(")", -1); } leftHandSide = op.BuildExpression(previousToken, new[] { leftHandSide, rightHandSide }, this.options); } } else { break; } } else if (this.registeredFunctions.TryGetValue(currentToken.CurrentToken, out var function)) // or an IFunction? { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); var expressions = new List <IExpression>(); var captiveTokens = new Queue <Token>(); var parenCount = 0; tokens.Dequeue(); // Loop through the list of tokens and split by ParameterSeparator character while (tokens.Count > 0) { var nextToken = tokens.Dequeue(); if (string.Equals(nextToken.CurrentToken, "(", StringComparison.Ordinal)) { parenCount++; } else if (string.Equals(nextToken.CurrentToken, ")", StringComparison.Ordinal)) { parenCount--; } if (!(parenCount == 1 && nextToken.CurrentToken == "(") && !(parenCount == 0 && nextToken.CurrentToken == ")")) { captiveTokens.Enqueue(nextToken); } if (parenCount == 0 && captiveTokens.Any()) { expressions.Add(this.CompileExpression(captiveTokens, minimumPrecedence: OperatorPrecedence.Minimum, variables: variables, isWithinFunction: true)); captiveTokens.Clear(); } else if (string.Equals(nextToken.CurrentToken, ParameterSeparator.ToString(), StringComparison.Ordinal) && parenCount == 1) { // TODO: Should we expect expressions to be null??? expressions.Add(this.CompileExpression(captiveTokens, minimumPrecedence: 0, variables: variables, isWithinFunction: true)); captiveTokens.Clear(); } if (parenCount <= 0) { break; } } leftHandSide = new FunctionExpression(currentToken.CurrentToken, function, expressions.ToArray()); } else if (currentToken.CurrentToken.IsNumeric(this.currentCulture)) // Or a number { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); tokens.Dequeue(); if (int.TryParse(currentToken.CurrentToken, NumberStyles.Any, this.currentCulture, out var intValue)) { leftHandSide = new ConstantValueExpression(intValue); } else if (decimal.TryParse(currentToken.CurrentToken, NumberStyles.Any, this.currentCulture, out var decimalValue)) { leftHandSide = new ConstantValueExpression(decimalValue); } else if (double.TryParse(currentToken.CurrentToken, NumberStyles.Any, this.currentCulture, out var doubleValue)) { leftHandSide = new ConstantValueExpression(doubleValue); } else if (float.TryParse(currentToken.CurrentToken, NumberStyles.Any, this.currentCulture, out var floatValue)) { leftHandSide = new ConstantValueExpression(floatValue); } else if (long.TryParse(currentToken.CurrentToken, NumberStyles.Any, this.currentCulture, out var longValue)) { leftHandSide = new ConstantValueExpression(longValue); } } else if (currentToken.CurrentToken.StartsWith("[") && currentToken.CurrentToken.EndsWith("]")) // or a variable? { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); tokens.Dequeue(); var variableName = currentToken.CurrentToken.Replace("[", "").Replace("]", ""); leftHandSide = new VariableExpression(variableName); if (!variables.Contains(variableName, this.stringComparer)) { variables.Add(variableName); } } else if (string.Equals(currentToken.CurrentToken, "true", StringComparison.OrdinalIgnoreCase)) // or a boolean? { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); tokens.Dequeue(); leftHandSide = new ConstantValueExpression(true); } else if (string.Equals(currentToken.CurrentToken, "false", StringComparison.OrdinalIgnoreCase)) { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); tokens.Dequeue(); leftHandSide = new ConstantValueExpression(false); } else if (string.Equals(currentToken.CurrentToken, "null", StringComparison.OrdinalIgnoreCase)) // or a null? { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); tokens.Dequeue(); leftHandSide = new ConstantValueExpression(null); } else if (currentToken.CurrentToken.StartsWith(DateSeparator.ToString()) && currentToken.CurrentToken.EndsWith(DateSeparator.ToString())) // or a date? { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); tokens.Dequeue(); var dateToken = currentToken.CurrentToken.Replace(DateSeparator.ToString(), ""); // If we can't parse the date let's check for some known tags. if (!DateTime.TryParse(dateToken, out var date)) { if (string.Equals("TODAY", dateToken, StringComparison.OrdinalIgnoreCase)) { date = DateTime.Today; } else if (string.Equals("NOW", dateToken, StringComparison.OrdinalIgnoreCase)) { date = DateTime.Now; } else { throw new UnrecognisedTokenException(dateToken); } } leftHandSide = new ConstantValueExpression(date); } else if ((currentToken.CurrentToken.StartsWith("'") && currentToken.CurrentToken.EndsWith("'")) || (currentToken.CurrentToken.StartsWith("\"") && currentToken.CurrentToken.EndsWith("\""))) { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); tokens.Dequeue(); leftHandSide = new ConstantValueExpression(CleanString(currentToken.CurrentToken.Substring(1, currentToken.Length - 2))); } else if (string.Equals(currentToken.CurrentToken, ParameterSeparator.ToString(), StringComparison.Ordinal)) // Make sure we ignore the parameter separator { if (!isWithinFunction) { throw new ExpressiveException($"Unexpected token '{currentToken.CurrentToken}' at position {currentToken.StartIndex}"); } tokens.Dequeue(); } else { tokens.Dequeue(); if (options.HasFlag(ExpressiveOptions.UnknownTokensAsVariables)) { this.CheckForExistingParticipant(leftHandSide, currentToken, isWithinFunction); var variableName = currentToken.CurrentToken; leftHandSide = new VariableExpression(variableName); if (!variables.Contains(variableName, this.stringComparer)) { variables.Add(variableName); } } else { throw new UnrecognisedTokenException(currentToken.CurrentToken); } } previousToken = currentToken; currentToken = tokens.PeekOrDefault(); } return(leftHandSide); }
public static IKaVEList <IStatement> CreateCurrentBody() { var anyVarRef = new VariableReference(); var anyStmt = new BreakStatement(); var anyExpr = new ConstantValueExpression(); var anyBody = Lists.NewList <IStatement>(new BreakStatement()); return(Lists.NewList( // new DoLoop { Condition = anyExpr, Body = anyBody }, new ForEachLoop { Declaration = new VariableDeclaration { Reference = anyVarRef, Type = Names.Type("T1,P") }, LoopedReference = anyVarRef, Body = anyBody }, new ForLoop { Init = anyBody, Condition = anyExpr, Step = anyBody, Body = anyBody }, new IfElseBlock { Condition = anyExpr, Then = anyBody, Else = anyBody }, new LockBlock { Reference = anyVarRef, Body = anyBody }, new SwitchBlock { Reference = anyVarRef, Sections = { new CaseBlock { Label = anyExpr, Body = anyBody } }, DefaultSection = anyBody }, new TryBlock { Body = anyBody, CatchBlocks = { new CatchBlock { Parameter = Names.Parameter("[?] p"), Kind = CatchBlockKind.General, Body = anyBody } }, Finally = anyBody }, new UncheckedBlock { Body = anyBody }, new UnsafeBlock(), new UsingBlock { Reference = anyVarRef, Body = anyBody }, new WhileLoop { Condition = anyExpr, Body = anyBody }, // new Assignment { Reference = anyVarRef, Expression = anyExpr }, new BreakStatement(), new ContinueStatement(), new EventSubscriptionStatement { Reference = anyVarRef, Operation = EventSubscriptionOperation.Add, Expression = anyExpr }, new ExpressionStatement { Expression = anyExpr }, new GotoStatement { Label = "l" }, new LabelledStatement { Label = "l", Statement = anyStmt }, new ReturnStatement { Expression = anyExpr, IsVoid = true }, new ThrowStatement { Reference = anyVarRef }, new UnknownStatement(), new VariableDeclaration { Type = Names.Type("T2, P"), Reference = anyVarRef }, // Nested( new BinaryExpression { LeftOperand = anyExpr, Operator = BinaryOperator.BitwiseAnd, RightOperand = anyExpr }), Nested( new CastExpression { Reference = anyVarRef, Operator = CastOperator.SafeCast, TargetType = Names.Type("T3, P") }), Nested( new CompletionExpression { Token = "t", TypeReference = Names.Type("T4, P"), VariableReference = anyVarRef }), Nested(new ComposedExpression { References = { anyVarRef } }), Nested(new IfElseExpression { Condition = anyExpr, ThenExpression = anyExpr, ElseExpression = anyExpr }), Nested(new IndexAccessExpression { Reference = anyVarRef, Indices = { anyExpr } }), Nested( new InvocationExpression { Reference = anyVarRef, MethodName = Names.Method("[?] [?].M()"), Parameters = { anyExpr } }), Nested(new LambdaExpression { Name = Names.Lambda("[?] ()"), Body = anyBody }), Nested(new TypeCheckExpression { Type = Names.Type("T4, P"), Reference = anyVarRef }), Nested(new UnaryExpression { Operator = UnaryOperator.Minus, Operand = anyExpr }), Nested(new LoopHeaderBlockExpression { Body = anyBody }), Nested(new ConstantValueExpression { Value = "v" }), Nested(new NullExpression()), Nested(new ReferenceExpression { Reference = anyVarRef }), Nested(new UnknownExpression()), // Nested(new EventReference { Reference = anyVarRef, EventName = Names.Event("[?] [?].e") }), Nested(new FieldReference { Reference = anyVarRef, FieldName = Names.Field("[?] [?]._f") }), Nested( new IndexAccessReference { Expression = new IndexAccessExpression { Reference = anyVarRef, Indices = { anyExpr } } }), Nested(new MethodReference { Reference = anyVarRef, MethodName = Names.Method("[?] [?].M()") }), Nested(new PropertyReference { Reference = anyVarRef, PropertyName = Names.Property("get [?] [?].P()") }), Nested(new UnknownReference()), Nested(new VariableReference { Identifier = "id" }) // )); }
public void Given_ConstantExpression_equals_left_and_left_equals_right_expression_IsEquivalentTo_should_be_true(ConstantValueExpression filterExpression) => Given_FilterExpression_equals_left_and_right_IsEquivalentTo_should_return_true(filterExpression);