diff options
author | Ethan Nicholas <ethannicholas@google.com> | 2017-02-27 13:26:45 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-02-27 19:01:55 +0000 |
commit | af19769831f1c4c3b90c85aa9f8851cd8bbf86d5 (patch) | |
tree | 5dd063830d41aff45eefcb524c868ac210016467 /src/sksl/SkSLParser.cpp | |
parent | 578f064a60b63ddfb00831e9e59a47060bfcefe0 (diff) |
Re-land of skslc switch support
This reverts commit 7d975fc200bbbea991ec4c04c08f3a5ea7b847af.
BUG=skia:
Change-Id: I57521f7a291a35cfed58d623ea4f8da29582d2c5
Reviewed-on: https://skia-review.googlesource.com/8993
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Diffstat (limited to 'src/sksl/SkSLParser.cpp')
-rw-r--r-- | src/sksl/SkSLParser.cpp | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp index cc47577e93..478d6fd673 100644 --- a/src/sksl/SkSLParser.cpp +++ b/src/sksl/SkSLParser.cpp @@ -63,6 +63,8 @@ #include "ast/SkSLASTReturnStatement.h" #include "ast/SkSLASTStatement.h" #include "ast/SkSLASTSuffixExpression.h" +#include "ast/SkSLASTSwitchCase.h" +#include "ast/SkSLASTSwitchStatement.h" #include "ast/SkSLASTTernaryExpression.h" #include "ast/SkSLASTType.h" #include "ast/SkSLASTVarDeclaration.h" @@ -770,6 +772,8 @@ std::unique_ptr<ASTStatement> Parser::statement() { return this->doStatement(); case Token::WHILE: return this->whileStatement(); + case Token::SWITCH: + return this->switchStatement(); case Token::RETURN: return this->returnStatement(); case Token::BREAK: @@ -975,6 +979,86 @@ std::unique_ptr<ASTWhileStatement> Parser::whileStatement() { std::move(statement))); } +/* CASE expression COLON statement* */ +std::unique_ptr<ASTSwitchCase> Parser::switchCase() { + Token start; + if (!this->expect(Token::CASE, "'case'", &start)) { + return nullptr; + } + std::unique_ptr<ASTExpression> value = this->expression(); + if (!value) { + return nullptr; + } + if (!this->expect(Token::COLON, "':'")) { + return nullptr; + } + std::vector<std::unique_ptr<ASTStatement>> statements; + while (this->peek().fKind != Token::RBRACE && this->peek().fKind != Token::CASE && + this->peek().fKind != Token::DEFAULT) { + std::unique_ptr<ASTStatement> s = this->statement(); + if (!s) { + return nullptr; + } + statements.push_back(std::move(s)); + } + return std::unique_ptr<ASTSwitchCase>(new ASTSwitchCase(start.fPosition, std::move(value), + std::move(statements))); +} + +/* SWITCH LPAREN expression RPAREN LBRACE switchCase* (DEFAULT COLON statement*)? RBRACE */ +std::unique_ptr<ASTStatement> Parser::switchStatement() { + Token start; + if (!this->expect(Token::SWITCH, "'switch'", &start)) { + return nullptr; + } + if (!this->expect(Token::LPAREN, "'('")) { + return nullptr; + } + std::unique_ptr<ASTExpression> value(this->expression()); + if (!value) { + return nullptr; + } + if (!this->expect(Token::RPAREN, "')'")) { + return nullptr; + } + if (!this->expect(Token::LBRACE, "'{'")) { + return nullptr; + } + std::vector<std::unique_ptr<ASTSwitchCase>> cases; + while (this->peek().fKind == Token::CASE) { + std::unique_ptr<ASTSwitchCase> c = this->switchCase(); + if (!c) { + return nullptr; + } + cases.push_back(std::move(c)); + } + // Requiring default: to be last (in defiance of C and GLSL) was a deliberate decision. Other + // parts of the compiler may rely upon this assumption. + if (this->peek().fKind == Token::DEFAULT) { + Token defaultStart; + SkAssertResult(this->expect(Token::DEFAULT, "'default'", &defaultStart)); + if (!this->expect(Token::COLON, "':'")) { + return nullptr; + } + std::vector<std::unique_ptr<ASTStatement>> statements; + while (this->peek().fKind != Token::RBRACE) { + std::unique_ptr<ASTStatement> s = this->statement(); + if (!s) { + return nullptr; + } + statements.push_back(std::move(s)); + } + cases.emplace_back(new ASTSwitchCase(defaultStart.fPosition, nullptr, + std::move(statements))); + } + if (!this->expect(Token::RBRACE, "'}'")) { + return nullptr; + } + return std::unique_ptr<ASTStatement>(new ASTSwitchStatement(start.fPosition, + std::move(value), + std::move(cases))); +} + /* FOR LPAREN (declaration | expression)? SEMICOLON expression? SEMICOLON expression? RPAREN STATEMENT */ std::unique_ptr<ASTForStatement> Parser::forStatement() { |