Ejemplo n.º 1
0
        private static bool TryReadHatPower(string text, ref int pos, out int power)
        {
            if (text[pos] != '^')
            {
                // leaving this even if it is a try method. Getting here means something should have been checked before
                throw new InvalidOperationException("Check that there is a hat power to read before calling this");
            }

            pos++;
            WhiteSpaceReader.TryRead(text, ref pos);

            var ps = OperatorReader.TryReadSign(text, ref pos);

            if (ps == Sign.None)
            {
                ps = Sign.Positive;
            }

            if (OperatorReader.TryReadSign(text, ref pos) != Sign.None)
            {
                // not allowing a^--2 as it is most likely a typo
                power = 0;
                return(false);
            }

            WhiteSpaceReader.TryRead(text, ref pos);
            if (IntReader.TryReadInt32(text, ref pos, out power))
            {
                power *= (int)ps;
                return(true);
            }

            power = 0;
            return(false);
        }
Ejemplo n.º 2
0
        internal static bool TryReadInt32(string text, ref int pos, out int result)
        {
            if (pos == text.Length)
            {
                result = 0;
                return(false);
            }

            var sign = OperatorReader.TryReadSign(text, ref pos);

            var start = pos;
            var end   = Math.Min(text.Length, pos + MaxDigits - 1);

            result = 0;

            while (pos < end)
            {
                var c = text[pos] - '0';
                if (c < 0 || c > 9)
                {
                    break;
                }

                result *= 10;
                result += c;
                pos++;
            }

            if (pos == start)
            {
                if (sign != Sign.None)
                {
                    pos--;
                }

                return(false);
            }

            if (pos < end ||
                !IsDigit(text, pos))
            {
                switch (sign)
                {
                case Sign.Negative:
                    result = -result;
                    return(true);

                case Sign.None:
                case Sign.Positive:
                    return(true);

                default:
                    throw new InvalidEnumArgumentException(nameof(sign), (int)sign, typeof(Sign));
                }
            }

            // getting here means we must handle the last digit and potential overflows.
            long temp = result;

            temp *= 10;
            temp += text[pos] - '0';

            switch (sign)
            {
            case Sign.Negative:
            {
                temp = -temp;
                if (temp >= int.MinValue)
                {
                    result = (int)temp;
                    pos++;
                    return(true);
                }

                pos    = start - 1;
                result = 0;
                return(false);
            }

            case Sign.None:
            case Sign.Positive:
            {
                if (temp <= int.MaxValue)
                {
                    result = (int)temp;
                    pos++;
                    return(true);
                }

                pos = start - sign == Sign.Positive
                            ? 1
                            : 0;
                result = 0;
                return(false);
            }

            default:
                throw new InvalidEnumArgumentException(nameof(sign), (int)sign, typeof(Sign));
            }
        }