public override object Eval(TemplateContext context) { // evaluate both parts object lv = LeftExpression.Eval(context); object rv = RightExpression.Eval(context); // equality/not-equality if (op == TokenType.Equal) { if (lv == null && rv == null) { return(true); } else if (lv != null) { return(lv.Equals(rv)); } } else if (op == TokenType.NotEqual) { if (lv == null && rv == null) { return(false); } else if (lv != null) { return(!lv.Equals(rv)); } } // arithmetic operation else if (op == TokenType.Mult || op == TokenType.Div || op == TokenType.Mod || op == TokenType.Plus || op == TokenType.Minus || op == TokenType.Less || op == TokenType.LessOrEqual || op == TokenType.Greater || op == TokenType.GreaterOrEqual) { if (!((lv is Decimal || lv is Int32) && (rv is Decimal || rv is Int32))) { throw new ParserException("Arithmetic and logical operations can be applied to operands or integer and decimal types only.", Line, Column); } bool dec = lv is Decimal || rv is Decimal; object val = null; if (op == TokenType.Mult) { val = dec ? (Decimal)lv * (Decimal)rv : (Int32)lv * (Int32)rv; } else if (op == TokenType.Div) { val = dec ? (Decimal)lv / (Decimal)rv : (Int32)lv / (Int32)rv; } else if (op == TokenType.Mod) { val = dec ? (Decimal)lv % (Decimal)rv : (Int32)lv % (Int32)rv; } else if (op == TokenType.Plus) { val = dec ? (Decimal)lv + (Decimal)rv : (Int32)lv + (Int32)rv; } else if (op == TokenType.Minus) { val = dec ? (Decimal)lv - (Decimal)rv : (Int32)lv - (Int32)rv; } else if (op == TokenType.Less) { val = dec ? (Decimal)lv < (Decimal)rv : (Int32)lv < (Int32)rv; } else if (op == TokenType.LessOrEqual) { val = dec ? (Decimal)lv <= (Decimal)rv : (Int32)lv <= (Int32)rv; } else if (op == TokenType.Greater) { val = dec ? (Decimal)lv > (Decimal)rv : (Int32)lv > (Int32)rv; } else if (op == TokenType.GreaterOrEqual) { val = dec ? (Decimal)lv >= (Decimal)rv : (Int32)lv >= (Int32)rv; } if (val is Boolean) { bool ret = Convert.ToBoolean(val); return(ret); } else if (dec) { decimal ret = Convert.ToDecimal(val); return(ret); } else { int ret = Convert.ToInt32(val); return(ret); } } else if (op == TokenType.Or || op == TokenType.And) { if (!(lv is Boolean && rv is Boolean)) { throw new ParserException("Logical operation can be applied to operands of boolean type only", Line, Column); } if (op == TokenType.Or) { return((Boolean)lv || (Boolean)rv); } else if (op == TokenType.And) { return((Boolean)lv && (Boolean)rv); } } return(0); }
decimal IExpression.Interpret() { return(LeftExpression.Interpret() + RightExpression.Interpret()); }
public Expression Generate(Parameter parameter, LeftExpression left, RightExpression right, FilterAttribute filterAttribute, object value) { return(Expression.Call(left.GetExpression(), typeof(string).GetMethod(CONTAINS_METHOD_NAME, new[] { typeof(string) }), right.GetExpression())); }
public override string Template() { return($"{RightExpression.Template()}\nmovq\t%rax,%rbx\n{LeftExpression.Template()}\n{AssignmentTemplate}\n{LeftExpression.Save()}"); // var retrieve = $"\nmovq\t{varIndex}(%rbp),%rax"; // const string div = "\nidiv\t%rbx"; // var assign = $"\nmovq\t%rax,{varIndex}(%rbp)"; // // return $"{Expression.Template()}" + // "\nmovq\t%rax,%rbx" + // retrieve + // "\ncqo" + // div + // assign; }
public override int Evaluate() { return(LeftExpression.Evaluate() - RightExpression.Evaluate()); }
/// <inheritdoc /> protected override EvaluationResult DoEval(Context context, ModuleLiteral env, EvaluationStackFrame frame) { var leftCandidate = LeftExpression.Eval(context, env, frame); if (leftCandidate.IsErrorValue) { return(EvaluationResult.Error); } EvaluationResult left = leftCandidate; EvaluationResult right = default(EvaluationResult); if (OperatorKind != BinaryOperator.And && OperatorKind != BinaryOperator.Or) { // Don't eval right expression for And and Or operators due to possible short circuit. var rightCandidate = RightExpression.Eval(context, env, frame); if (rightCandidate.IsErrorValue) { return(EvaluationResult.Error); } right = rightCandidate; } try { checked { int leftNumber; int rightNumber; switch (OperatorKind) { case BinaryOperator.Addition: // Different cases: // 1. If left OR right is a string result is a string // 2. If left AND right are numbers - result is a number string leftString = left.Value as string; string rightString = right.Value as string; // First case: if any of the frame is string if (leftString != null) { if (rightString != null) { return(EvaluationResult.Create(leftString + rightString)); } return(EvaluationResult.Create(leftString + ToStringConverter.ObjectToString(context, right))); } if (rightString != null) { return(EvaluationResult.Create(ToStringConverter.ObjectToString(context, left) + rightString)); } // Expecting numbers, but can't report type mismatch error, because in this case string or number are allowed. if (TryGetNumbers(left, right, out leftNumber, out rightNumber)) { return(EvaluationResult.Create(leftNumber + rightNumber)); } context.Errors.ReportUnexpectedValueType(env, LeftExpression, left, typeof(int), typeof(string)); return(EvaluationResult.Error); // Math operators case BinaryOperator.Remainder: return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) % Converter.ExpectNumber(right, position: 1))); case BinaryOperator.Multiplication: return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) * Converter.ExpectNumber(right, position: 1))); case BinaryOperator.Subtraction: return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) - Converter.ExpectNumber(right, position: 1))); case BinaryOperator.Exponentiation: return(NumberOperations.Power(context, Converter.ExpectNumber(left), Converter.ExpectNumber(right), LocationForLogging(context, env))); // Equality + Comparison case BinaryOperator.Equal: return(EvaluationResult.Create(left.Equals(right))); case BinaryOperator.NotEqual: return(EvaluationResult.Create(!left.Equals(right))); case BinaryOperator.GreaterThanOrEqual: return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) >= Converter.ExpectNumber(right, position: 1))); case BinaryOperator.GreaterThan: return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) > Converter.ExpectNumber(right, position: 1))); case BinaryOperator.LessThanOrEqual: return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) <= Converter.ExpectNumber(right, position: 1))); case BinaryOperator.LessThan: return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) < Converter.ExpectNumber(right, position: 1))); // Conditionals case BinaryOperator.Or: return(EvalOr(context, env, frame, left)); case BinaryOperator.And: return(EvalAnd(context, env, frame, left)); // Bitwise operations // For all bitwise operations call to ToEnumValueIfNeeded is required to convert // numeric representation to enum value if left hand side is enum // (ExpectNumberOrEnums will make sure that left and right operands have the same type). case BinaryOperator.BitWiseOr: if (ExpectNumbersOrEnums(context, env, left, right, out leftNumber, out rightNumber)) { return(Converter.ToEnumValueIfNeeded(left.GetType(), leftNumber | rightNumber)); } return(EvaluationResult.Error); case BinaryOperator.BitWiseAnd: if (ExpectNumbersOrEnums(context, env, left, right, out leftNumber, out rightNumber)) { return(Converter.ToEnumValueIfNeeded(left.GetType(), leftNumber & rightNumber)); } return(EvaluationResult.Error); case BinaryOperator.BitWiseXor: if (ExpectNumbersOrEnums(context, env, left, right, out leftNumber, out rightNumber)) { return(Converter.ToEnumValueIfNeeded(left.GetType(), leftNumber ^ rightNumber)); } break; case BinaryOperator.LeftShift: return(EvaluationResult.Create(Converter.ExpectNumber(left, position: 0) << Converter.ExpectNumber(right, position: 1))); case BinaryOperator.SignPropagatingRightShift: return(EvaluationResult.Create(NumberOperations.SignPropagatingRightShift( Converter.ExpectNumber(left, position: 0), Converter.ExpectNumber(right, position: 1)).Value)); case BinaryOperator.ZeroFillingRightShift: return(EvaluationResult.Create(NumberOperations.ZeroFillingRightShift( Converter.ExpectNumber(left, position: 0), Converter.ExpectNumber(right, position: 1)).Value)); default: // And and Or operator should have been replaced by the ite expression. // case BinaryOperator.And: // case BinaryOperator.Or: // return (bool)l && (bool)RightExpression.Eval(context, env, frame); // return (bool) l || (bool) RightExpression.Eval(context, env, frame); Contract.Assert(false); break; } } } catch (OverflowException) { context.Logger.ReportArithmeticOverflow( context.LoggingContext, LocationForLogging(context, env), this.ToDisplayString(context)); } catch (ConvertException convertException) { context.Errors.ReportUnexpectedValueType( env, convertException.ErrorContext.Pos == 0 ? LeftExpression : RightExpression, convertException.Value, convertException.ExpectedTypesToString(context)); } catch (DivideByZeroException) { context.Errors.ReportDivideByZeroException(env, this, Location); } return(EvaluationResult.Error); }
public override bool Interpret(Context context) { return(LeftExpression.Interpret(context) && RightExpression.Interpret(context)); }
public override object Clone() { return(new SCIMLogicalExpression(LogicalOperator, (SCIMExpression)LeftExpression.Clone(), (SCIMExpression)RightExpression.Clone())); }
public override string ToString() => $"{LeftExpression.ToString()} {Op.ToString()} {RightExpression.ToString()}";
public override double Interpret(Context context) { return(LeftExpression.Interpret(context) / RightExpression.Interpret(context)); }
public override Type EvaluateType() { var leftType = LeftExpression.EvaluateType(); var rightType = RightExpression.EvaluateType(); var leftTypeUnboxed = TypeHelper.GetUnderlyingTypeIfNullable(leftType); var rightTypeUnboxed = TypeHelper.GetUnderlyingTypeIfNullable(rightType); var anyNullable = TypeHelper.IsSystemNullableType(leftType) || TypeHelper.IsSystemNullableType(rightType); Type resultedTypeRaw; switch (Operator.Type) { case BinaryOperatorType.Logical: // For logical comparison, we ensure that all operands' type are logical already // The return type is always boolean (logical) if ((leftType != typeof(bool) && leftType != typeof(bool?)) || (rightType != typeof(bool) && rightType != typeof(bool?))) { throw new TranspilerNotSupportedException($"Logical binary operator {Operator} operating must operate on bool types. Actual types: {leftType}, {rightType}"); } return(anyNullable ? TypeHelper.MakeNullableIfNotAlready(typeof(bool)) : typeof(bool)); case BinaryOperatorType.Value: // For value type operator, use the value type coercion table if (!TypeCoersionTables.CoersionTableForValueType.TryGetValue((Operator.Name, leftTypeUnboxed, rightTypeUnboxed), out resultedTypeRaw)) { throw new TranspilerInternalErrorException($"Unexpected use of binary operator {Operator.Name} operating between types {leftTypeUnboxed} and {rightTypeUnboxed}"); } if (resultedTypeRaw == default(Type)) { throw new TranspilerNotSupportedException($"Binary operator {Operator.Name} operating between types {leftTypeUnboxed} and {rightTypeUnboxed}"); } return(anyNullable ? TypeHelper.MakeNullableIfNotAlready(resultedTypeRaw) : resultedTypeRaw); case BinaryOperatorType.Comparison: // For comparison operators, use the equality/inequality type coercion table if (Operator.Name == BinaryOperator.EQ || Operator.Name == BinaryOperator.NEQ) { if (!TypeCoersionTables.CoersionTableEqualityComparison.TryGetValue((leftTypeUnboxed, rightTypeUnboxed), out resultedTypeRaw)) { throw new TranspilerInternalErrorException($"Unexpected use of (un)equality operator {Operator.Name} operating between types {leftTypeUnboxed} and {rightTypeUnboxed}"); } } else if (Operator.Name == BinaryOperator.IN) { // IN need special handling as right operand is a list var innerTypes = rightTypeUnboxed.GetGenericArguments(); if (innerTypes == null || innerTypes.Length != 1) { throw new TranspilerInternalErrorException($"Unexpected use of IN operator, the right type {rightTypeUnboxed} is not a list of value type"); } resultedTypeRaw = typeof(bool); } else { if (!TypeCoersionTables.CoersionTableDefaultComparison.TryGetValue((leftTypeUnboxed, rightTypeUnboxed), out resultedTypeRaw)) { throw new TranspilerInternalErrorException($"Unexpected use of binary operator {Operator.Name} operating between types {leftTypeUnboxed} and {rightTypeUnboxed}"); } } if (resultedTypeRaw == default(Type)) { throw new TranspilerNotSupportedException($"Binary operator {Operator.Name} operating between types {leftTypeUnboxed} and {rightTypeUnboxed}"); } return(anyNullable ? TypeHelper.MakeNullableIfNotAlready(resultedTypeRaw) : resultedTypeRaw); case BinaryOperatorType.Invalid: default: throw new TranspilerInternalErrorException($"Unexpected operator type: {Operator.Type}"); } }
public override object Clone() { return(new SCIMComparisonExpression(ComparisonOperator, (SCIMAttributeExpression)LeftExpression.Clone(), Value)); }
public override bool Eval(PCBObject Obj) { return(LeftExpression.Eval(Obj) ^ RightExpression.Eval(Obj)); }
public override string Template() { return($"{LeftExpression.Template()}\n{AssignmentTemplate}\n{LeftExpression.Save()}"); }
/// <inheritdoc /> protected override void DoSerialize(BuildXLWriter writer) { LeftExpression.Serialize(writer); writer.Write((byte)OperatorKind); RightExpression.Serialize(writer); }
public Expression Generate(Parameter parameter, LeftExpression left, RightExpression right, FilterAttribute filterAttribute, object value) { return(Expression.NotEqual(left.GetExpression(), right.GetExpression())); }
/// <inheritdoc /> public override string ToDebugString() { return(I($"{LeftExpression.ToDebugString()} {OperatorKind.ToDisplayString()} {RightExpression.ToDebugString()}")); }
public override int AbsoluteValue() { return(LeftExpression.AbsoluteValue() + RightExpression.AbsoluteValue()); }
public override bool Eval(IPrincipal principal) { return(LeftExpression.Eval(principal) || RightExpression.Eval(principal)); }
public override string Template() { return($"{LeftExpression.Template()}\nmovq\t%rax,%rcx\n{RightExpression.Template()}\n{AssignmentTemplate}\n{LeftExpression.Save()}"); }
public override QValue Evaluate() { return(((IntValue)LeftExpression.Evaluate()).GrTh((IntValue)RightExpression.Evaluate())); }
public override double Evaluate() { return(Math.Atan2(LeftExpression.Evaluate(), RightExpression.Evaluate())); }
public override QValue Evaluate() { return(((BoolValue)LeftExpression.Evaluate()).And((BoolValue)RightExpression.Evaluate())); }
public override double Evaluate() { return(LeftExpression.Evaluate() + RightExpression.Evaluate()); }
public override Expression Clone() { return(new SpatialAnalysisGeometricExpression((GeometryExpression)LeftExpression.Clone(), SpatialAnalysisOperator, (GeometryExpression)RightExpression.Clone())); }
public override Expression Clone() { return(new SpatialAnalysisDistanceExpression((GeometryExpression)LeftExpression.Clone(), (GeometryExpression)RightExpression.Clone())); }
public override object Evaluate() { return((Complex)Combinatorics.Permutations(LeftExpression.EvaluateAsInt32(), RightExpression.EvaluateAsInt32())); }
/// <summary> /// Evaluates filter expression agains message context /// </summary> /// <param name="messageContext">Key value pair store with message context</param> /// <returns>Evaluation result task</returns> public async Task <IComparable> EvaluateAsync(IReadOnlyDictionary <string, object> messageContext) { // When no actual filter was created as expression we think that evaluation passed successfully, because there were nothing to compare to if (Operation == 0 && (LeftExpression == null || RightExpression == null)) { return(true); } var left = LeftExpression.EvaluateAsync(messageContext); var right = RightExpression.EvaluateAsync(messageContext); await Task.WhenAll(left, right); if (object.ReferenceEquals(left.Result, NullEvaluationResult.Value)) { return(false); } //actual operation between left and right switch (Operation) { case FilterOperator.And: { return((bool)left.Result && (bool)right.Result); } case FilterOperator.Or: { return((bool)left.Result || (bool)right.Result); } case FilterOperator.EqualTo: { return(left.Result.Equals(right.Result)); } case FilterOperator.NotEqualTo: { return(!left.Result.Equals(right.Result)); } case FilterOperator.GreaterThan: { return(left.Result.CompareTo(right.Result) == 1); } case FilterOperator.GreaterThanOrEqualTo: { return(left.Result.CompareTo(right.Result) >= 0); } case FilterOperator.LessThanOrEqualTo: { return(left.Result.CompareTo(right.Result) <= 0); } case FilterOperator.LessThan: { return(left.Result.CompareTo(right.Result) == -1); } } return(false); }