/// <inheritdoc /> public Expression Operate(BinaryExpression e, Block block, IArithmeticOpMetadata operationParameters) { if (e == null) { throw new ArgumentNullException(nameof(e)); } if (block == null) { throw new ArgumentNullException(nameof(block)); } return(BinaryOperate(e, block, operationParameters)); }
protected override Expression BinaryOperate( BinaryExpression bin, Block block, IArithmeticOpMetadata operationParameters) { if (bin.LeftHandSide.IsConst) { var left = (ConstantBoolExpression)bin.LeftHandSide; left.Value = !(bool)left.Value; return(left); } return(bin); // expression remains the same }
private static bool HandleBoolRelop( IArithmeticOpMetadata operationParameters, ConstantExpression left, ConstantExpression right) { if (operationParameters.Operation == OberonGrammarLexer.EQUAL) { return(left.ToBool() == right.ToBool()); } if (operationParameters.Operation == OberonGrammarLexer.NOTEQUAL) { return(left.ToBool() != right.ToBool()); } return(false); }
private static bool HandleStandardRelop( IArithmeticOpMetadata operationParameters, ConstantExpression left, ConstantExpression right) { bool res = operationParameters.Operation switch { OberonGrammarLexer.GT => left.ToDouble() > right.ToDouble(), OberonGrammarLexer.GE => left.ToDouble() >= right.ToDouble(), OberonGrammarLexer.LT => left.ToDouble() < right.ToDouble(), OberonGrammarLexer.LE => left.ToDouble() <= right.ToDouble(), OberonGrammarLexer.NOTEQUAL => Math.Abs(left.ToDouble() - right.ToDouble()) > double.Epsilon, OberonGrammarLexer.EQUAL => Math.Abs(left.ToDouble() - right.ToDouble()) < double.Epsilon, _ => throw new InvalidOperationException("Unknown comparison") }; return(res); } }
protected override Expression BinaryOperate( BinaryExpression bin, Block block, IArithmeticOpMetadata operationParameters) { if (bin.LeftHandSide.IsConst && bin.RightHandSide.IsConst) { var left = (ConstantExpression)bin.LeftHandSide; var right = (ConstantExpression)bin.RightHandSide; if (bin.LeftHandSide.TargetType.Type == BaseTypes.Int && bin.RightHandSide.TargetType.Type == BaseTypes.Int) { return(new ConstantIntExpression(left.ToInt32() - right.ToInt32())); } return(new ConstantDoubleExpression(left.ToDouble() - right.ToDouble())); } return(bin); // expression remains the same }
protected override Expression BinaryOperate(BinaryExpression bin, Block block, IArithmeticOpMetadata operationParameters) { if (bin.LeftHandSide.IsConst && bin.RightHandSide.IsConst) { var left = (ConstantExpression)bin.LeftHandSide; var right = (ConstantExpression)bin.RightHandSide; bool res = false; switch (operationParameters.Operation) { case OberonGrammarLexer.AND: res = left.ToBool() && right.ToBool(); break; case OberonGrammarLexer.OR: res = left.ToBool() || right.ToBool(); break; } return(new ConstantBoolExpression(res)); } return(bin); // expression remains the same }
protected override Expression BinaryOperate( BinaryExpression bin, Block block, IArithmeticOpMetadata operationParameters) { if (bin.LeftHandSide.IsConst) { if (bin.LeftHandSide.TargetType.Type == BaseTypes.Int) { var leftInt = (ConstantIntExpression)bin.LeftHandSide; leftInt.Value = -(int)leftInt.Value; return(leftInt); } if (bin.LeftHandSide.TargetType.Type == BaseTypes.Real) { var leftDouble = (ConstantDoubleExpression)bin.LeftHandSide; leftDouble.Value = -(double)leftDouble.Value; return(leftDouble); } } return(bin); // expression remains the same }
protected override Expression BinaryOperate( BinaryExpression bin, Block block, IArithmeticOpMetadata operationParameters) { if (bin.LeftHandSide.IsConst && bin.RightHandSide.IsConst) { var left = (ConstantExpression)bin.LeftHandSide; var right = (ConstantExpression)bin.RightHandSide; bool res; if (left.TargetType.Type == BaseTypes.Bool && right.TargetType.Type == BaseTypes.Bool) { res = HandleBoolRelop(operationParameters, left, right); } else { res = HandleStandardRelop(operationParameters, left, right); } return(new ConstantBoolExpression(res)); } return(bin); // expression remains the same }
public ArithmeticOperation(IArithmeticOperation operation, IArithmeticOpMetadata metadata) { Operation = operation; Metadata = metadata; }
/// <summary> /// Run the binary operation /// </summary> /// <param name="bin"> /// The bin. /// </param> /// <param name="block"> /// The block. /// </param> /// <param name="operationParameters"> /// The operation parameters. /// </param> /// <returns> /// The <see cref="Expression" />. /// </returns> protected abstract Expression BinaryOperate( BinaryExpression bin, [UsedImplicitly] Block block, IArithmeticOpMetadata operationParameters);