public bool TryEvaluate(string expr, out ExpressionValue result)
        {
            List <Token> list = Scanner.TokenizeText(expr, _opts);

            return(TryEvaluate(list, out result));
        }
        /// <summary>
        /// Reference used for this implementation
        ///
        /// https://gcc.gnu.org/onlinedocs/cpp/If.html#If
        ///
        /// In summary calculations done using the widest type known to compiler which is long for
        /// our implementation.
        /// </summary>
        public static ExpressionValue EvaluateBinaryOperation(BinaryOperator op, ExpressionValue left, ExpressionValue right)
        {
            long leftValue;
            bool leftBool;
            long rightValue;
            bool rightBool;

            try
            {
                leftValue  = left.ConvertToLong();
                leftBool   = left.ConvertToBool();
                rightValue = right.ConvertToLong();
                rightBool  = right.ConvertToBool();
            }
            catch (Exception ex)
            {
                throw new Exception($"Unable to convert binary operands: {ex.Message}", ex);
            }

            ExpressionValue result;

            switch (op)
            {
            case BinaryOperator.Divide:
                result = ExpressionValue.Create(leftValue / rightValue);
                break;

            case BinaryOperator.GreaterThan:
                result = ExpressionValue.Create(leftValue > rightValue);
                break;

            case BinaryOperator.GreaterThanOrEqualTo:
                result = ExpressionValue.Create(leftValue >= rightValue);
                break;

            case BinaryOperator.LessThan:
                result = ExpressionValue.Create(leftValue < rightValue);
                break;

            case BinaryOperator.LessThanOrEqualTo:
                result = ExpressionValue.Create(leftValue <= rightValue);
                break;

            case BinaryOperator.Subtract:
                result = ExpressionValue.Create(leftValue - rightValue);
                break;

            case BinaryOperator.Modulus:
                result = ExpressionValue.Create(leftValue % rightValue);
                break;

            case BinaryOperator.ShiftLeft:
                result = ExpressionValue.Create(leftValue << (int)rightValue);
                break;

            case BinaryOperator.ShiftRight:
                result = ExpressionValue.Create(leftValue >> (int)rightValue);
                break;

            case BinaryOperator.Add:
                result = ExpressionValue.Create(leftValue + rightValue);
                break;

            case BinaryOperator.Multiply:
                result = ExpressionValue.Create(leftValue * rightValue);
                break;

            case BinaryOperator.BooleanAnd:
                result = ExpressionValue.Create(leftBool && rightBool);
                break;

            case BinaryOperator.BooleanOr:
                result = ExpressionValue.Create(leftBool || rightBool);
                break;

            case BinaryOperator.BooleanEquals:
                result = ExpressionValue.Create(leftValue == rightValue);
                break;

            case BinaryOperator.BooleanNotEquals:
                result = ExpressionValue.Create(leftValue != rightValue);
                break;

            case BinaryOperator.BitwiseAnd:
                result = ExpressionValue.Create(leftValue & rightValue);
                break;

            case BinaryOperator.BitwiseOr:
                result = ExpressionValue.Create(leftValue | rightValue);
                break;

            case BinaryOperator.Assign:
                result = right;
                break;

            default:
                throw Contract.CreateInvalidEnumValueException(op);
            }

            return(result);
        }
        private ExpressionValue EvaluateNegation(ExpressionNode node)
        {
            var value = EvaluateCore(node.LeftNode);

            return(ExpressionValue.Create(!value.ConvertToBool()));
        }