2 // Author: Sergey Chaban (serge@wildwestsoftware.com)
\r
6 using System.Globalization;
\r
8 namespace Mono.ILASM {
\r
12 internal class NumberHelper : StringHelperBase {
\r
14 private ILToken result;
\r
18 /// <param name="host"></param>
\r
19 public NumberHelper (ILTokenizer host) : base (host)
\r
25 private void Reset ()
\r
27 result = ILToken.Invalid.Clone() as ILToken;
\r
32 /// <returns></returns>
\r
33 public override bool Start (char ch)
\r
35 bool res = (Char.IsDigit (ch) || ch == '-' || (ch == '.' && Char.IsDigit ((char) host.Reader.Peek ())));
\r
42 return (e >= '0' && e <= '9') || (e >= 'A' && e <= 'F') || (e >= 'a' && e <= 'f');
\r
45 bool is_sign (int ch)
\r
47 return ((ch == '+') || (ch == '-'));
\r
52 return ((ch == 'e') || (ch == 'E'));
\r
57 /// <returns></returns>
\r
58 public override string Build ()
\r
60 ILReader reader = host.Reader;
\r
61 reader.MarkLocation ();
\r
62 StringBuilder num_builder = new StringBuilder ();
\r
66 bool is_real = false;
\r
67 bool dec_found = false;
\r
69 NumberStyles nstyles = NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint |
\r
70 NumberStyles.AllowLeadingSign;
\r
72 ch = reader.Read ();
\r
73 peek = reader.Peek ();
\r
76 if (ch == '0' && (peek == 'x' || peek == 'X'))
\r
79 if (is_sign (reader.Peek ()))
\r
80 num_builder.Append ((char) reader.Read ());
\r
83 ch = reader.Read ();
\r
84 peek = reader.Peek ();
\r
85 num_builder.Append ((char) ch);
\r
89 throw new ILTokenizingException (reader.Location, num_builder.ToString ());
\r
95 if (!is_hex(peek) &&
\r
96 !(peek == '.' && !dec_found) && !is_e (peek) &&
\r
97 !(is_sign (peek) && is_real)) {
\r
100 } while (ch != -1);
\r
102 num = num_builder.ToString ();
\r
104 // Check for hexbytes
\r
105 if (num.Length == 2) {
\r
106 if (Char.IsLetter (num[0]) || Char.IsLetter (num[1])) {
\r
107 result.token = Token.HEXBYTE;
\r
108 result.val = Byte.Parse (num, NumberStyles.HexNumber);
\r
113 if (ch == '.' && peek == '.') {
\r
114 num = num.Substring (0, num.Length-1);
\r
115 reader.Unread ('.');
\r
117 } else if (ch == '.') {
\r
121 if (!dec_found && !is_real) {
\r
123 long i = Int64.Parse (num, nstyles);
\r
124 result.token = Token.INT64;
\r
132 long i = (long) UInt64.Parse (num, nstyles);
\r
133 result.token = Token.INT64;
\r
142 double d = Double.Parse (num, nstyles, NumberFormatInfo.InvariantInfo);
\r
143 result.token = Token.FLOAT64;
\r
146 reader.Unread (num.ToCharArray ());
\r
147 reader.RestoreLocation ();
\r
148 num = String.Empty;
\r
150 throw new ILTokenizingException (reader.Location, num_builder.ToString ());
\r
155 public string BuildHex ()
\r
157 ILReader reader = host.Reader;
\r
158 reader.MarkLocation ();
\r
159 StringBuilder num_builder = new StringBuilder ();
\r
160 NumberStyles nstyles = NumberStyles.HexNumber;
\r
166 ch = reader.Read ();
\r
168 throw new ILTokenizingException (reader.Location, ((char) ch).ToString ());
\r
170 ch = reader.Read ();
\r
172 if (ch != 'x' && ch != 'X')
\r
173 throw new ILTokenizingException (reader.Location, "0" + (char) ch);
\r
176 ch = reader.Read ();
\r
177 peek = reader.Peek ();
\r
178 num_builder.Append ((char) ch);
\r
180 if (!is_hex ((char) peek))
\r
183 if (num_builder.Length == 32)
\r
184 throw new ILTokenizingException (reader.Location, num_builder.ToString ());
\r
186 } while (ch != -1);
\r
188 num = num_builder.ToString ();
\r
191 long i = (long) UInt64.Parse (num, nstyles);
\r
192 //if (i < Int32.MinValue || i > Int32.MaxValue) {
\r
193 result.token = Token.INT64;
\r
196 // result.token = Token.INT32;
\r
197 // result.val = (int) i;
\r
201 reader.Unread (num.ToCharArray ());
\r
202 reader.RestoreLocation ();
\r
203 num = String.Empty;
\r
205 throw new ILTokenizingException (reader.Location, tnum);
\r
212 public ILToken ResultToken {
\r