CiSwitch ParseSwitch()
{
Expect(CiToken.LeftParenthesis);
CiSwitch result = new CiSwitch();
result.Value = ParseExpr();
Expect(CiToken.RightParenthesis);
Expect(CiToken.LeftBrace);
List<CiCase> cases = new List<CiCase>();
while (Eat(CiToken.Case)) {
List<object> values = new List<object>();
do {
values.Add(ParseExpr());
Expect(CiToken.Colon);
} while (Eat(CiToken.Case));
if (See(CiToken.Default))
throw new ParseException("Please remove case before default");
CiCase kase = new CiCase { Values = values.ToArray() };
List<ICiStatement> statements = new List<ICiStatement>();
do
statements.Add(ParseStatement());
while (!See(CiToken.Case) && !See(CiToken.Default) && !See(CiToken.Goto) && !See(CiToken.RightBrace));
kase.Body = statements.ToArray();
if (Eat(CiToken.Goto)) {
if (Eat(CiToken.Case))
kase.FallthroughTo = ParseExpr();
else if (Eat(CiToken.Default))
kase.FallthroughTo = null;
else
throw new ParseException("Expected goto case or goto default");
Expect(CiToken.Semicolon);
kase.Fallthrough = true;
}
cases.Add(kase);
}
if (cases.Count == 0)
throw new ParseException("Switch with no cases");
result.Cases = cases.ToArray();
if (Eat(CiToken.Default)) {
Expect(CiToken.Colon);
List<ICiStatement> statements = new List<ICiStatement>();
do
statements.Add(ParseStatement());
while (!See(CiToken.RightBrace));
result.DefaultBody = statements.ToArray();
}
Expect(CiToken.RightBrace);
return result;
}