8000 implement switch-case parser · repos-javascript-compilers/JSX@3268348 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3268348

Browse files
committed
implement switch-case parser
1 parent c6870e7 commit 3268348

File tree

3 files changed

+83
-4
lines changed

3 files changed

+83
-4
lines changed

example/fib.jsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,15 @@ class Fib {
2525
}
2626
return value;
2727
}
28+
29+
static function fib4(n : Int) : Int {
30+
switch (n) {
31+
case 1:
32+
return 1;
33+
case 2:
34+
return 1;
35+
default:
36+
return Fib.fib4(n - 1) + Fib.fib4(n - 2);
37+
}
38+
}
2839
}

lib/Parser.js

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ var IfStatement = require("./IfStatement");
2121
var LabelStatement = require("./LabelStatement");
2222
var LogStatement = require("./LogStatement");
2323
var ReturnStatement = require("./ReturnStatement");
24+
var SwitchStatement = require("./SwitchStatement");
2425
var WhileStatement = require("./WhileStatement");
2526
var AdditiveExpression = require("./AdditiveExpression");
2627
var ArrayExpression = require("./ArrayExpression");
@@ -178,6 +179,14 @@ var Parser = module.exports = Class.extend({
178179
return identifier;
179180
},
180181

182+
_expectIsNotEOF: function () {
183+
if (this._isEOF()) {
184+
this._newError("unexpected EOF");
185+
return false;
186+
}
187+
return true;
188+
},
189+
181190
_skipStatement: function () {
182191
var token;
183192
while ((token = this._nextToken()) != null) {
@@ -359,10 +368,8 @@ var Parser = module.exports = Class.extend({
359368

360369
_block: function () {
361370
while (this._expectKeywordOpt("}") == null) {
362-
if (this._isEOF()) {
363-
this._newError("unexpected EOF");
371+
if (! this._expectIsNotEOF())
364372
break;
365-
}
366373
if (! this._statement())
367374
this._skipStatement();
368375
}
@@ -582,7 +589,54 @@ var Parser = module.exports = Class.extend({
582589
},
583590

584591
_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;
586640
},
587641

588642
_throwStatement: function () {

lib/SwitchStatement.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"use strict";
2+
3+
var Statement = require("./Statement");
4+
5+
var SwitchStatement = module.exports = Statement.extend({
6+
7+
initialize: function (expr, caseExpr, defaultStatementIndex, statements) {
8+
this._expr = expr;
9+
this._caseExpr = caseExpr;
10+
this._defaultStatementIndex = defaultStatementIndex;
11+
this._statements = statements;
12+
}
13+
14+
});

0 commit comments

Comments
 (0)
0