@@ -21,6 +21,7 @@ var IfStatement = require("./IfStatement");
21
21
var LabelStatement = require ( "./LabelStatement" ) ;
22
22
var LogStatement = require ( "./LogStatement" ) ;
23
23
var ReturnStatement = require ( "./ReturnStatement" ) ;
24
+ var SwitchStatement = require ( "./SwitchStatement" ) ;
24
25
var WhileStatement = require ( "./WhileStatement" ) ;
25
26
var AdditiveExpression = require ( "./AdditiveExpression" ) ;
26
27
var ArrayExpression = require ( "./ArrayExpression" ) ;
@@ -178,6 +179,14 @@ var Parser = module.exports = Class.extend({
178
179
return identifier ;
179
180
} ,
180
181
182
+ _expectIsNotEOF : function ( ) {
183
+ if ( this . _isEOF ( ) ) {
184
+ this . _newError ( "unexpected EOF" ) ;
185
+ return false ;
186
+ }
187
+ return true ;
188
+ } ,
189
+
181
190
_skipStatement : function ( ) {
182
191
var token ;
183
192
while ( ( token = this . _nextToken ( ) ) != null ) {
@@ -359,10 +368,8 @@ var Parser = module.exports = Class.extend({
359
368
360
369
_block : function ( ) {
361
370
while ( this . _expectKeywordOpt ( "}" ) == null ) {
362
- if ( this . _isEOF ( ) ) {
363
- this . _newError ( "unexpected EOF" ) ;
371
+ if ( ! this . _expectIsNotEOF ( ) )
364
372
break ;
365
- }
366
373
if ( ! this . _statement ( ) )
367
374
this . _skipStatement ( ) ;
368
375
}
@@ -582,7 +589,54 @@ var Parser = module.exports = Class.extend({
582
589
} ,
583
590
584
591
_switchStatement : function ( ) {
585
- return false ; // FIXME
592
+ var expr = this . _expr ( false ) ;
593
+ if ( expr == null )
594
+ return false ;
595
+ if ( this . _expectKeyword ( "{" ) == null )
596
+ return null ;
597
+ var caseExprs = [ ] ; // array of [ label, statementIndex ]
598
+ var defaultStatementIndex = - 1 ;
599
+ // caseblock
600
+ var statementBase = this . _statements . length ;
601
+ while ( this . _expectKeywordOpt ( "}" ) == null ) {
602
+ if ( ! this . _expectIsNotEOF ( ) )
603
+ return false ;
604
+ var caseOrDefault ;
605
+ if ( caseExprs . length == 0 && defaultStatementIndex == 1 ) {
606
+ // first statement within the block should start with a label
607
+ if ( ( caseOrDefault = this . _expectKeyword ( [ "case" , "default" ] ) ) == null )
608
+ return false ;
609
+ } else {
610
+ caseOrDefault = this . _expectKeywordOpt ( [ "case" , "default" ] ) ;
611
+ }
612
+ switch ( caseOrDefault ) {
613
+ case "case" :
614
+ var labelExpr = this . _expr ( ) ;
615
+ if ( labelExpr == null )
616
+ return false ;
617
+ if ( this . _expectKeyword ( ":" ) == null )
618
+ return false ;
619
+ caseExprs . push ( [ labelExpr , this . _statements . length - statementBase ] ) ;
620
+ break ;
621
+ case "default" :
622
+ if ( this . _expectKeyword ( ":" ) == null )
623
+ return false ;
624
+ if ( defaultStatementIndex != - 1 ) {
625
+ this . _newError ( "cannot have more than one default statement within one switch block" ) ;
626
+ return false ;
627
+ }
628
+ defaultStatementIndex = this . _statements . length - statementBase ;
629
+ break ;
630
+ default :
631
+ if ( ! this . _statement ( ) )
632
+ this . _skipStatement ( ) ;
633
+ break ;
634
+ }
635
+ }
636
+ // done
637
+ var subStatements = this . _statements . splice ( statementBase ) ;
638
+ this . _statements . push ( new SwitchStatement ( expr , caseExprs , defaultStatementIndex , subStatements ) ) ;
639
+ return true ;
586
640
} ,
587
641
588
642
_throwStatement : function ( ) {
0 commit comments