1- import { FIELD , int , isBlank , BaseException } from 'facade/lang' ;
1+ import { FIELD , int , isBlank , BaseException , StringWrapper } from 'facade/lang' ;
22import { ListWrapper , List } from 'facade/collection' ;
3- import { Lexer , EOF , Token , $PERIOD , $COLON , $SEMICOLON , $LBRACKET , $RBRACKET } from './lexer' ;
3+ import { Lexer , EOF , Token , $PERIOD , $COLON , $SEMICOLON , $LBRACKET , $RBRACKET , $COMMA , $LBRACE , $RBRACE } from './lexer' ;
44import { ClosureMap } from './closure_map' ;
55import {
66 AST ,
@@ -14,7 +14,9 @@ import {
1414 Formatter ,
1515 Assignment ,
1616 Chain ,
17- KeyedAccess
17+ KeyedAccess ,
18+ LiteralArray ,
19+ LiteralMap
1820 } from './ast' ;
1921
2022var _implicitReceiver = new ImplicitReceiver ( ) ;
@@ -80,7 +82,7 @@ class _ParseAST {
8082
8183 expectCharacter ( code :int ) {
8284 if ( this . optionalCharacter ( code ) ) return ;
83- this . error ( `Missing expected ${ code } ` ) ;
85+ this . error ( `Missing expected ${ StringWrapper . fromCharCode ( code ) } ` ) ;
8486 }
8587
8688
@@ -107,6 +109,15 @@ class _ParseAST {
107109 return n . toString ( ) ;
108110 }
109111
112+ expectIdentifierOrKeywordOrString ( ) :string {
113+ var n = this . next ;
114+ if ( ! n . isIdentifier ( ) && ! n . isKeyword ( ) && ! n . isString ( ) ) {
115+ this . error ( `Unexpected token ${ n } , expected identifier, or keyword, or string` )
116+ }
117+ this . advance ( ) ;
118+ return n . toString ( ) ;
119+ }
120+
110121 parseChain ( ) :AST {
111122 var exprs = [ ] ;
112123 while ( this . index < this . tokens . length ) {
@@ -142,11 +153,6 @@ class _ParseAST {
142153 var result = this . parseConditional ( ) ;
143154
144155 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- // }
150156 this . expectOperator ( '=' ) ;
151157 result = new Assignment ( result , this . parseConditional ( ) ) ;
152158 }
@@ -269,6 +275,12 @@ class _ParseAST {
269275 while ( true ) {
270276 if ( this . optionalCharacter ( $PERIOD ) ) {
271277 result = this . parseFieldRead ( result ) ;
278+
279+ } else if ( this . optionalCharacter ( $LBRACKET ) ) {
280+ var key = this . parseExpression ( ) ;
281+ this . expectCharacter ( $RBRACKET ) ;
282+ result = new KeyedAccess ( result , key ) ;
283+
272284 } else {
273285 return result ;
274286 }
@@ -288,6 +300,14 @@ class _ParseAST {
288300 this . advance ( ) ;
289301 return new LiteralPrimitive ( false ) ;
290302
303+ } else if ( this . optionalCharacter ( $LBRACKET ) ) {
304+ var elements = this . parseExpressionList ( $RBRACKET ) ;
305+ this . expectCharacter ( $RBRACKET ) ;
306+ return new LiteralArray ( elements ) ;
307+
308+ } else if ( this . next . isCharacter ( $LBRACE ) ) {
309+ return this . parseLiteralMap ( ) ;
310+
291311 } else if ( this . next . isIdentifier ( ) ) {
292312 return this . parseFieldRead ( _implicitReceiver ) ;
293313
@@ -309,6 +329,32 @@ class _ParseAST {
309329 }
310330 }
311331
332+ parseExpressionList ( terminator :int ) :List {
333+ var result = [ ] ;
334+ if ( ! this . next . isCharacter ( terminator ) ) {
335+ do {
336+ ListWrapper . push ( result , this . parseExpression ( ) ) ;
337+ } while ( this . optionalCharacter ( $COMMA ) ) ;
338+ }
339+ return result ;
340+ }
341+
342+ parseLiteralMap ( ) {
343+ var keys = [ ] ;
344+ var values = [ ] ;
345+ this . expectCharacter ( $LBRACE ) ;
346+ if ( ! this . optionalCharacter ( $RBRACE ) ) {
347+ do {
348+ var key = this . expectIdentifierOrKeywordOrString ( ) ;
349+ ListWrapper . push ( keys , key ) ;
350+ this . expectCharacter ( $COLON ) ;
351+ ListWrapper . push ( values , this . parseExpression ( ) ) ;
352+ } while ( this . optionalCharacter ( $COMMA ) ) ;
353+ this . expectCharacter ( $RBRACE ) ;
354+ }
355+ return new LiteralMap ( keys , values ) ;
356+ }
357+
312358 parseFieldRead ( receiver ) :AST {
313359 var id = this . expectIdentifierOrKeyword ( ) ;
314360 return new FieldRead ( receiver , id , this . closureMap . getter ( id ) , this . closureMap . setter ( id ) ) ;
0 commit comments