Many amenities can be mapped as areas.
[potlatch2.git] / it / sephiroth / expr / Scanner.as
1 package it.sephiroth.expr
2 {
3         public class Scanner
4         {
5                 private var _pos: int;
6                 private var _pool: Array;
7                 private var _source: String;
8                 
9                 public function Scanner( source: String )
10                 {
11                         _pos = 0;
12                         _source = source;
13                         _pool = new Array();
14                 }
15                 
16                 public function nextToken(): Token
17                 {
18                         if( _pool.length > 0 )
19                         {
20                                 return _pool.shift();
21                         }
22                         
23                         skipWhites();
24                         
25                         if( isEOF() )
26                         {
27                                 return new Token( TokenType.EOF );
28                         }
29                         
30                         var c: String = _source.charAt( _pos++ );
31                         
32                         switch( c )
33                         {
34                                 case '+':       return new Token( TokenType.ADD );
35                                 case '-':       return new Token( TokenType.SUB );
36                                 case '*':       return new Token( TokenType.MUL );
37                                 case '/':       return new Token( TokenType.DIV );
38                                 case '(':       return new Token( TokenType.LEFT_PAR );
39                                 case ')':       return new Token( TokenType.RIGHT_PAR );
40                                 case ',':       return new Token( TokenType.COMMA );
41                                 
42                                 default:
43                                         
44                                         var buf: String = "";
45                                         var code: int = c.charCodeAt( 0 );
46                                         
47                                         if( isNumber( code ) )
48                                         {
49                                                 var num: Number;
50                                                 
51                                                 while( isNumber( code ) )
52                                                 {
53                                                         buf += c;
54                                                         
55                                                         if( isEOF() )
56                                                         {
57                                                                 ++_pos;
58                                                                 break;
59                                                         }
60                                                         
61                                                         c  = _source.charAt( _pos++ );
62                                                         code = c.charCodeAt( 0 );
63                                                 }
64                                                 
65                                                 if( c == '.' )
66                                                 {
67                                                         buf += c;
68                                                         c  = _source.charAt( _pos++ );
69                                                         code = c.charCodeAt( 0 );
70                                                         
71                                                         while( isNumber( code ) )
72                                                         {
73                                                                 buf += c;
74                                                                 
75                                                                 if( isEOF() )
76                                                                 {
77                                                                         ++_pos;
78                                                                         break;
79                                                                 }
80                                                                 
81                                                                 c  = _source.charAt( _pos++ );
82                                                                 code = c.charCodeAt( 0 );
83                                                         }
84                                                         
85                                                         num = parseFloat( buf );
86                                                 }else
87                                                 {
88                                                         num = parseInt( buf );
89                                                 }
90                                                 
91                                                 --_pos;
92                                                 return new Token( TokenType.NUM, num );
93                                         }
94                                         
95                                         if( isAlpha( code ) || ( c == '_' ) )
96                                         {
97                                                 
98                                                 while( isAlpha( code ) || ( c == '_' ) || isNumber( code ) )
99                                                 {
100                                                         buf += c;
101                                                         
102                                                         if( isEOF() )
103                                                         {
104                                                                 ++_pos;
105                                                                 break;
106                                                         }
107                                                         
108                                                         c  = _source.charAt( _pos++ );
109                                                         code = c.charCodeAt( 0 );
110                                                 }
111                                                 
112                                                 --_pos;
113                                                 return new Token( TokenType.IDENT, buf );
114                                         }
115                                         
116                                         break;
117                         }
118                         
119                         return new Token( TokenType.NULL, c );
120                 }
121                 
122                 public function pushBack( token: Token ): void
123                 {
124                         _pool.push( token );
125                 }
126                 
127                 protected function isNumber( c: int ): Boolean
128                 {
129                         return ( c >= 48 ) && ( c <= 57 );
130                 }
131                 
132                 protected function isAlpha( c: int ): Boolean
133                 {
134                         return ( ( c >= 97 ) && ( c <= 122 ) ) || ( ( c >= 65 ) && ( c <= 90 ) );
135                 }
136                 
137                 protected function isEOF(): Boolean
138                 {
139                         return ( _pos >= _source.length );
140                 }
141                 
142                 protected function skipWhites(): void
143                 {
144                         while( !isEOF() )
145                         {
146                                 var c: String = _source.charAt( _pos++ );
147                                 if( ( c != " " ) && ( c != "\t" ) )
148                                 {
149                                         --_pos;
150                                         break;
151                                 }
152                         }
153                 }
154         }
155 }