OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library polymer_expressions.parser; | 5 library polymer_expressions.parser; |
6 | 6 |
7 import 'tokenizer.dart'; | 7 import 'tokenizer.dart'; |
8 import 'expression.dart'; | 8 import 'expression.dart'; |
9 | 9 |
10 const _UNARY_OPERATORS = const ['+', '-', '!']; | 10 const _UNARY_OPERATORS = const ['+', '-', '!']; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 } else if (_token.value == '[') { | 57 } else if (_token.value == '[') { |
58 var indexExpr = _parseIndex(); | 58 var indexExpr = _parseIndex(); |
59 left = _astFactory.index(left, indexExpr); | 59 left = _astFactory.index(left, indexExpr); |
60 } else { | 60 } else { |
61 break; | 61 break; |
62 } | 62 } |
63 } else if (_token.kind == DOT_TOKEN) { | 63 } else if (_token.kind == DOT_TOKEN) { |
64 _advance(); | 64 _advance(); |
65 var right = _parseUnary(); | 65 var right = _parseUnary(); |
66 left = _makeInvokeOrGetter(left, right); | 66 left = _makeInvokeOrGetter(left, right); |
67 } else if (_token.kind == KEYWORD_TOKEN && _token.value == 'in') { | 67 } else if (_token.kind == KEYWORD_TOKEN) { |
68 left = _parseComprehension(left); | 68 if (_token.value == 'in') { |
69 } else if (_token.kind == OPERATOR_TOKEN && _token.value == '?') { | 69 left = _parseInExpression(left); |
70 left = _parseTernary(left); | 70 } else if (_token.value == 'as') { |
71 } else if (_token.kind == OPERATOR_TOKEN | 71 left = _parseAsExpression(left); |
72 && _token.precedence >= precedence) { | 72 } else { |
73 left = _parseBinary(left); | 73 break; |
| 74 } |
| 75 } else if (_token.kind == OPERATOR_TOKEN) { |
| 76 if (_token.value == '?') { |
| 77 left = _parseTernary(left); |
| 78 } else if (_token.precedence >= precedence) { |
| 79 left = _parseBinary(left); |
| 80 } |
74 } else { | 81 } else { |
75 break; | 82 break; |
76 } | 83 } |
77 } | 84 } |
78 return left; | 85 return left; |
79 } | 86 } |
80 | 87 |
81 // invoke or getter | 88 // invoke or getter |
82 Expression _makeInvokeOrGetter(left, right) { | 89 Expression _makeInvokeOrGetter(left, right) { |
83 if (right is Identifier) { | 90 if (right is Identifier) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 | 143 |
137 Expression _parsePrimary() { | 144 Expression _parsePrimary() { |
138 var kind = _token.kind; | 145 var kind = _token.kind; |
139 switch (kind) { | 146 switch (kind) { |
140 case KEYWORD_TOKEN: | 147 case KEYWORD_TOKEN: |
141 var keyword = _token.value; | 148 var keyword = _token.value; |
142 if (keyword == 'this') { | 149 if (keyword == 'this') { |
143 _advance(); | 150 _advance(); |
144 // TODO(justin): return keyword node | 151 // TODO(justin): return keyword node |
145 return _astFactory.identifier('this'); | 152 return _astFactory.identifier('this'); |
146 } else if (keyword == 'in') { | 153 } else if (KEYWORDS.contains(keyword)) { |
147 return null; | 154 throw new ParseException('invalid keyword: $keyword'); |
148 } | 155 } |
149 throw new ArgumentError('unrecognized keyword: $keyword'); | 156 throw new ArgumentError('unrecognized keyword: $keyword'); |
150 case IDENTIFIER_TOKEN: | 157 case IDENTIFIER_TOKEN: |
151 return _parseInvokeOrIdentifier(); | 158 return _parseInvokeOrIdentifier(); |
152 case STRING_TOKEN: | 159 case STRING_TOKEN: |
153 return _parseString(); | 160 return _parseString(); |
154 case INTEGER_TOKEN: | 161 case INTEGER_TOKEN: |
155 return _parseInteger(); | 162 return _parseInteger(); |
156 case DECIMAL_TOKEN: | 163 case DECIMAL_TOKEN: |
157 return _parseDecimal(); | 164 return _parseDecimal(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 return new MapLiteral(entries); | 206 return new MapLiteral(entries); |
200 } | 207 } |
201 | 208 |
202 MapLiteralEntry _parseMapLiteralEntry() { | 209 MapLiteralEntry _parseMapLiteralEntry() { |
203 var key = _parseString(); | 210 var key = _parseString(); |
204 _advance(COLON_TOKEN, ':'); | 211 _advance(COLON_TOKEN, ':'); |
205 var value = _parseExpression(); | 212 var value = _parseExpression(); |
206 return _astFactory.mapLiteralEntry(key, value); | 213 return _astFactory.mapLiteralEntry(key, value); |
207 } | 214 } |
208 | 215 |
209 InExpression _parseComprehension(Expression left) { | 216 InExpression _parseInExpression(Expression left) { |
210 assert(_token.value == 'in'); | 217 assert(_token.value == 'in'); |
211 if (left is! Identifier) { | 218 if (left is! Identifier) { |
212 throw new ParseException( | 219 throw new ParseException( |
213 "in... statements must start with an identifier"); | 220 "in... statements must start with an identifier"); |
214 } | 221 } |
215 _advance(); | 222 _advance(); |
216 var right = _parseExpression(); | 223 var right = _parseExpression(); |
217 return _astFactory.inExpr(left, right); | 224 return _astFactory.inExpr(left, right); |
218 } | 225 } |
219 | 226 |
| 227 AsExpression _parseAsExpression(Expression left) { |
| 228 assert(_token.value == 'as'); |
| 229 _advance(); |
| 230 var right = _parseExpression(); |
| 231 if (right is! Identifier) { |
| 232 throw new ParseException( |
| 233 "as... statements must end with an identifier"); |
| 234 } |
| 235 return _astFactory.asExpr(left, right); |
| 236 } |
| 237 |
220 Expression _parseInvokeOrIdentifier() { | 238 Expression _parseInvokeOrIdentifier() { |
221 if (_token.value == 'true') { | 239 if (_token.value == 'true') { |
222 _advance(); | 240 _advance(); |
223 return _astFactory.literal(true); | 241 return _astFactory.literal(true); |
224 } | 242 } |
225 if (_token.value == 'false') { | 243 if (_token.value == 'false') { |
226 _advance(); | 244 _advance(); |
227 return _astFactory.literal(false); | 245 return _astFactory.literal(false); |
228 } | 246 } |
229 if (_token.value == 'null') { | 247 if (_token.value == 'null') { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 return value; | 312 return value; |
295 } | 313 } |
296 | 314 |
297 Literal<double> _parseDecimal([String prefix = '']) { | 315 Literal<double> _parseDecimal([String prefix = '']) { |
298 var value = _astFactory.literal(double.parse('$prefix${_token.value}')); | 316 var value = _astFactory.literal(double.parse('$prefix${_token.value}')); |
299 _advance(); | 317 _advance(); |
300 return value; | 318 return value; |
301 } | 319 } |
302 | 320 |
303 } | 321 } |
OLD | NEW |