1- import { FIELD , int , isBlank } from 'facade/lang' ;
1+ import { FIELD , int , isBlank , BaseException } from 'facade/lang' ;
22import { ListWrapper , List } from 'facade/collection' ;
3- import { Lexer , EOF , Token , $PERIOD , $COLON , $SEMICOLON } from './lexer' ;
3+ import { Lexer , EOF , Token , $PERIOD , $COLON , $SEMICOLON , $LBRACKET , $RBRACKET } from './lexer' ;
44import { ClosureMap } from './closure_map' ;
55import {
66 AST ,
@@ -11,7 +11,10 @@ import {
1111 Binary ,
1212 PrefixNot ,
1313 Conditional ,
14- Formatter
14+ Formatter ,
15+ Assignment ,
16+ Chain ,
17+ KeyedAccess
1518 } from './ast' ;
1619
1720var _implicitReceiver = new ImplicitReceiver ( ) ;
@@ -75,6 +78,12 @@ class _ParseAST {
7578 }
7679 }
7780
81+ expectCharacter ( code :int ) {
82+ if ( this . optionalCharacter ( code ) ) return ;
83+ this . error ( `Missing expected ${ code } ` ) ;
84+ }
85+
86+
7887 optionalOperator ( op :string ) :boolean {
7988 if ( this . next . isOperator ( op ) ) {
8089 this . advance ( ) ;
@@ -84,6 +93,20 @@ class _ParseAST {
8493 }
8594 }
8695
96+ expectOperator ( operator :string ) {
97+ if ( this . optionalOperator ( operator ) ) return ;
98+ this . error ( `Missing expected operator ${ operator } ` ) ;
99+ }
100+
101+ expectIdentifierOrKeyword ( ) :string {
102+ var n = this . next ;
103+ if ( ! n . isIdentifier ( ) && ! n . isKeyword ( ) ) {
104+ this . error ( `Unexpected token ${ n } , expected identifier or keyword` )
105+ }
106+ this . advance ( ) ;
107+ return n . toString ( ) ;
108+ }
109+
87110 parseChain ( ) :AST {
88111 var exprs = [ ] ;
89112 while ( this . index < this . tokens . length ) {
@@ -96,7 +119,7 @@ class _ParseAST {
96119 }
97120 }
98121 }
99- return ListWrapper . first ( exprs ) ;
122+ return exprs . length == 1 ? exprs [ 0 ] : new Chain ( exprs ) ;
100123 }
101124
102125 parseFormatter ( ) {
@@ -105,7 +128,7 @@ class _ParseAST {
105128 if ( this . parseAction ) {
106129 this . error ( "Cannot have a formatter in an action expression" ) ;
107130 }
108- var name = this . parseIdentifier ( ) ;
131+ var name = this . expectIdentifierOrKeyword ( ) ;
109132 var args = ListWrapper . create ( ) ;
110133 while ( this . optionalCharacter ( $COLON ) ) {
111134 ListWrapper . push ( args , this . parseExpression ( ) ) ;
@@ -116,7 +139,19 @@ class _ParseAST {
116139 }
117140
118141 parseExpression ( ) {
119- return this . parseConditional ( ) ;
142+ var result = this . parseConditional ( ) ;
143+
144+ while ( this . next . isOperator ( '=' ) ) {
145+ //if (!backend.isAssignable(result)) {
146+ // int end = (index < tokens.length) ? next.index : input.length;
147+ // String expression = input.substring(start, end);
148+ // error('Expression $expression is not assignable');
149+ // }
150+ this . expectOperator ( '=' ) ;
151+ result = new Assignment ( result , this . parseConditional ( ) ) ;
152+ }
153+
154+ return result ;
120155 }
121156
122157 parseConditional ( ) {
@@ -202,7 +237,7 @@ class _ParseAST {
202237 }
203238
204239 parseMultiplicative ( ) {
205- // '*', '%', '/', '~/'
240+ // '*', '%', '/'
206241 var result = this . parsePrefix ( ) ;
207242 while ( true ) {
208243 if ( this . optionalOperator ( '*' ) ) {
@@ -211,9 +246,6 @@ class _ParseAST {
211246 result = new Binary ( '%' , result , this . parsePrefix ( ) ) ;
212247 } else if ( this . optionalOperator ( '/' ) ) {
213248 result = new Binary ( '/' , result , this . parsePrefix ( ) ) ;
214- // TODO(rado): This exists only in Dart, figure out whether to support it.
215- // } else if (this.optionalOperator('~/')) {
216- // result = new BinaryTruncatingDivide(result, this.parsePrefix());
217249 } else {
218250 return result ;
219251 }
@@ -232,59 +264,54 @@ class _ParseAST {
232264 }
233265 }
234266
235- parseAccessOrCallMember ( ) {
267+ parseAccessOrCallMember ( ) : AST {
236268 var result = this . parsePrimary ( ) ;
237- // TODO: add missing cases.
238- return result ;
269+ while ( true ) {
270+ if ( this . optionalCharacter ( $PERIOD ) ) {
271+ result = this . parseFieldRead ( result ) ;
272+ } else {
273+ return result ;
274+ }
275+ }
239276 }
240277
241278 parsePrimary ( ) {
242279 if ( this . next . isKeywordNull ( ) || this . next . isKeywordUndefined ( ) ) {
243280 this . advance ( ) ;
244281 return new LiteralPrimitive ( null ) ;
282+
245283 } else if ( this . next . isKeywordTrue ( ) ) {
246284 this . advance ( ) ;
247285 return new LiteralPrimitive ( true ) ;
286+
248287 } else if ( this . next . isKeywordFalse ( ) ) {
249288 this . advance ( ) ;
250289 return new LiteralPrimitive ( false ) ;
290+
251291 } else if ( this . next . isIdentifier ( ) ) {
252- return this . parseAccess ( ) ;
292+ return this . parseFieldRead ( _implicitReceiver ) ;
293+
253294 } else if ( this . next . isNumber ( ) ) {
254295 var value = this . next . toNumber ( ) ;
255296 this . advance ( ) ;
256297 return new LiteralPrimitive ( value ) ;
298+
257299 } else if ( this . next . isString ( ) ) {
258300 var value = this . next . toString ( ) ;
259301 this . advance ( ) ;
260302 return new LiteralPrimitive ( value ) ;
303+
261304 } else if ( this . index >= this . tokens . length ) {
262- throw `Unexpected end of expression: ${ this . input } ` ;
263- } else {
264- throw `Unexpected token ${ this . next } ` ;
265- }
266- }
305+ this . error ( `Unexpected end of expression: ${ this . input } ` ) ;
267306
268- parseAccess ( ) :AST {
269- var result = this . parseFieldRead ( _implicitReceiver ) ;
270- while ( this . optionalCharacter ( $PERIOD ) ) {
271- result = this . parseFieldRead ( result ) ;
307+ } else {
308+ this . error ( `Unexpected token ${ this . next } ` ) ;
272309 }
273- return result ;
274310 }
275311
276312 parseFieldRead ( receiver ) :AST {
277- var id = this . parseIdentifier ( ) ;
278- return new FieldRead ( receiver , id , this . closureMap . getter ( id ) ) ;
279- }
280-
281- parseIdentifier ( ) :string {
282- var n = this . next ;
283- if ( ! n . isIdentifier ( ) && ! n . isKeyword ( ) ) {
284- this . error ( `Unexpected token ${ n } , expected identifier or keyword` )
285- }
286- this . advance ( ) ;
287- return n . toString ( ) ;
313+ var id = this . expectIdentifierOrKeyword ( ) ;
314+ return new FieldRead ( receiver , id , this . closureMap . getter ( id ) , this . closureMap . setter ( id ) ) ;
288315 }
289316
290317 error ( message :string , index :int = null ) {
@@ -294,16 +321,6 @@ class _ParseAST {
294321 ? `at column ${ this . tokens [ index ] . index + 1 } in`
295322 : `at the end of the expression` ;
296323
297- throw new ParserError ( `Parser Error: ${ message } ${ location } [${ this . input } ]` ) ;
298- }
299- }
300-
301- class ParserError extends Error {
302- constructor ( message ) {
303- this . message = message ;
304- }
305-
306- toString ( ) {
307- return this . message ;
324+ throw new BaseException ( `Parser Error: ${ message } ${ location } [${ this . input } ]` ) ;
308325 }
309326}
0 commit comments