private ASTStatementBase ParseSwitch() { Require(TokenType.SWITCH); if (_switchLevel > 0) { throw new ParserException("Nested switch statements are currently not supported.", _lexer.Line, _lexer.Character); } Require(TokenType.LEFT_PARENTHESIS); ASTExpressionBase check = ParseExpression(); Require(TokenType.RIGHT_PARENTHESIS); Require(TokenType.LEFT_BRACE); ASTSwitch switchStatement = new ASTSwitch(check); while (!Match(TokenType.RIGHT_BRACE)) { if (Match(TokenType.END_OF_FILE)) { throw new ParserException("'}' expected!", _lexer.Line, _lexer.Character); } if (Match(TokenType.DEFAULT)) { Require(TokenType.DEFAULT); Require(TokenType.COLON); _switchLevel++; switchStatement.AddCase(null, ParseStatement()); _switchLevel--; if (!Match(TokenType.RIGHT_BRACE)) { throw new ParserException("A default case must be the final case of a switch statement.", _lexer.Line, _lexer.Character); } break; } Require(TokenType.CASE); ASTExpressionBase _case = ParseExpression(); if (_case == null) { throw new ParserException("Identifier expected.", _lexer.Line, _lexer.Character); } Require(TokenType.COLON); if (Match(TokenType.CASE) || Match(TokenType.DEFAULT)) { switchStatement.AddCase(_case, null); } else { _switchLevel++; switchStatement.AddCase(_case, ParseStatement()); _switchLevel--; } /* for now, I don't think forcing the scripter to use braces to have a "break;" after a case is necessary, eg. in the situation of * case 5: * { * print("hello"); * break; * } * * you might as well just type * case 5: * print("hello"); * break; */ if (Match(TokenType.BREAK)) // so let's allow that { Consume(); // consume 'break' Require(TokenType.SEMICOLON); // require ';' var currentCase = switchStatement.Cases[switchStatement.Cases.Count - 1]; // get statement of current case // and add the 'break' to the end of it switchStatement.Cases[switchStatement.Cases.Count - 1] = (currentCase.expression, new ASTBlock(new List <ASTStatementBase> { currentCase.statement, new ASTBreak() })); } } Require(TokenType.RIGHT_BRACE); if (switchStatement.Cases.Count == 0) { throw new ParserException("Empty switch statements are not allowed.", _lexer.Line, _lexer.Character); } return(switchStatement); }
public bool Visit(ASTSwitch node) { throw new NotImplementedException(); }