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()); }
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); }