public string ReadDecimal()
        {
            var hasExpotent = false;
            var hasDecimal  = false;
            var kill        = false;

            var builder = new StringBuilder();

            while (true)
            {
                var current = Read();
                if (current == -1)
                {
                    break;
                }

                var currentChar = char.ToUpper((char)current);
                if ("\x1c\x1d\x1f".Contains(currentChar))
                {
                    // ASCII separator chars invariably lead to zero result
                    kill = true;
                }
                else if (currentChar == '.' && !hasDecimal && !hasExpotent)
                {
                    hasDecimal = true;
                    builder.Append(currentChar);
                }
                else if ((currentChar == 'E' || currentChar == 'D') && !hasExpotent)
                {
                    // there's a special exception for number followed by EL or EQ
                    // presumably meant to protect ELSE and maybe EQV ?
                    if (currentChar == 'E' && "LQ".Contains(char.ToUpper((char)Peek())))
                    {
                        BaseStream.Seek(-1, SeekOrigin.Current);
                        break;
                    }

                    hasExpotent = true;
                    builder.Append(currentChar);
                }
                else if ((currentChar == '-' || currentChar == '+') &&
                         (builder.Length > 0 && "ED".Contains(builder[builder.Length - 1])))
                {
                    // must be first token or in exponent
                    builder.Append(currentChar);
                }
                else if (Constants.DecimalDigits.Contains(currentChar))
                {
                    builder.Append(currentChar);
                }
                else if (Constants.Whitepsace.Contains(currentChar))
                {
                    // we'll remove this later but need to keep it for now
                    // so we can reposition the stream on removing trailing whitespace
                    builder.Append(currentChar);
                }
                else if ((currentChar == '!' || currentChar == '#') && !hasExpotent)
                {
                    builder.Append(currentChar);
                    break;
                }
                else if (currentChar == '%') // swallow a %, but break parsing
                {
                    break;
                }
                else
                {
                    BaseStream.Seek(-1, SeekOrigin.Current);
                    break;
                }
            }

            var word = kill ? "0" : builder.ToString();

            // don't claim trailing whitespace
            while (word.Length > 0 && Constants.Whitepsace.Contains(word[word.Length - 1]))
            {
                word = word.Substring(0, word.Length - 1);
                BaseStream.Seek(-1, SeekOrigin.Current);
            }

            // remove all internal whitespace
            builder.Clear();
            foreach (var c in word.Where(c => !Constants.Whitepsace.Contains(c)))
            {
                builder.Append(c);
            }

            word = builder.ToString();
            var intValue = word.TryParseInt32();

            builder.Clear();

            if (word.Length == 1 && Constants.DecimalDigits.Contains(word[0]))
            {
                builder.Append((char)(0x11 + intValue));
            }
            else if (!(hasExpotent || hasDecimal || "!#".Contains(word[word.Length - 1])) &&
                     intValue <= 0x7fff && intValue >= -0x8000)
            {
                if (intValue <= 0xff && intValue >= 0) // one-byte constant
                {
                    builder.Append((char)Token.ByteConstant);
                    builder.Append((char)intValue);
                }
                else // two-byte constant
                {
                    builder.Append((char)Token.IntegerConstant);

                    var number = intValue.ToBasicSignedInteger();
                    builder.Append(number);
                }
            }
            else
            {
                var mbf = MbfFloat.Parse(word).ToBytes();
                builder.Append((char)(mbf.Length == 4 ? Token.FloatConstant : Token.DoubleConstant));
                builder.Append(new string(mbf.Select(f => (char)f).ToArray()));
            }

            return(builder.ToString());
        }
Beispiel #2
0
 public static void AreEqual(MbfFloat value, ulong mantisa, byte exponent, bool isNegitive)
 {
     Assert.AreEqual(value.Mantissa, mantisa);
     Assert.AreEqual(value.Exponent, exponent);
     Assert.AreEqual(value.IsNegitive, isNegitive);
 }