1 using System;
 2 
 3 namespace Calculator
 4 {
 5     public inline bool IsNumberChar(uchar c)
 6     {
 7         return IsAsciiDigit(c) || c == '.';
 8     }
 9     
10     public class Scanner
11     {
12         public nothrow Scanner(const ustring& input_) : input(input_)
13         {
14         }
15         public inline nothrow Token* CurrentToken() const
16         {
17             return token.Get();
18         }
19         public void NextToken()
20         {
21             SkipWhiteSpace();
22             if (pos < input.Length())
23             {
24                 if (IsNumberChar(input[pos]))
25                 {
26                     int start = pos;
27                     ++pos;
28                     while (pos < input.Length() && IsNumberChar(input[pos]))
29                     {
30                         ++pos;
31                     }
32                     double number = ParseDouble(ToUtf8(input.Substring(startpos - start)));
33                     token.Reset(new NumberToken(number));
34                 }
35                 else if (IsIdStart(input[pos]))
36                 {
37                     int start = pos;
38                     ++pos;
39                     while (pos < input.Length() && IsIdCont(input[pos]))
40                     {
41                         ++pos;
42                     }
43                     ustring variableName = input.Substring(startpos - start);
44                     if (ToLower(variableName) == u"print")
45                     {
46                         token.Reset(new PrintToken());
47                     }
48                     else
49                     {
50                         token.Reset(new VariableNameToken(variableName));
51                     }
52                 }
53                 else
54                 {
55                     token.Reset(new OperatorToken(input[pos]));
56                     ++pos;
57                 }
58             }
59             else
60             {
61                 token.Reset(new EndToken());
62             }
63         }
64         public void Rewind()
65         {
66             pos = 0;
67         }
68         private void SkipWhiteSpace()
69         {
70             while (pos < input.Length() && (input[pos] == ' ' || input[pos] == '\t'))
71             {
72                 ++pos;
73             }
74         }
75         private UniquePtr<Token> token;
76         private ustring input;
77         private int pos;
78     }
79 }