public override bool Eval(PCBObject Obj) { if (LeftExpression.Eval(Obj) == true) { return(true); } return(RightExpression.Eval(Obj)); }
public override bool Eval(IPrincipal principal) { return(LeftExpression.Eval(principal) && RightExpression.Eval(principal)); }
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); }
/// <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 Eval(PCBObject Obj) { return(LeftExpression.Eval(Obj) ^ RightExpression.Eval(Obj)); }