[wgsl-reader] Add `discard` parsing.

This CL adds parsing of the `discard` keyword to the WGSL reader.

Bug: tint:167
Change-Id: Iff91076a65715131f5f0f9bd1c8b6bf3a37cd3c7
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/25604
Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
dan sinclair 2020-07-25 14:33:13 +00:00 committed by dan sinclair
parent d81bebcfcc
commit f75f2cd22e
6 changed files with 39 additions and 0 deletions

View File

@ -495,6 +495,8 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) {
return {Token::Type::kContinue, source, "continue"}; return {Token::Type::kContinue, source, "continue"};
if (str == "continuing") if (str == "continuing")
return {Token::Type::kContinuing, source, "continuing"}; return {Token::Type::kContinuing, source, "continuing"};
if (str == "discard")
return {Token::Type::kDiscard, source, "discard"};
if (str == "default") if (str == "default")
return {Token::Type::kDefault, source, "default"}; return {Token::Type::kDefault, source, "default"};
if (str == "else") if (str == "else")

View File

@ -425,6 +425,7 @@ INSTANTIATE_TEST_SUITE_P(
TokenData{"continue", Token::Type::kContinue}, TokenData{"continue", Token::Type::kContinue},
TokenData{"continuing", Token::Type::kContinuing}, TokenData{"continuing", Token::Type::kContinuing},
TokenData{"default", Token::Type::kDefault}, TokenData{"default", Token::Type::kDefault},
TokenData{"discard", Token::Type::kDiscard},
TokenData{"else", Token::Type::kElse}, TokenData{"else", Token::Type::kElse},
TokenData{"elseif", Token::Type::kElseIf}, TokenData{"elseif", Token::Type::kElseIf},
TokenData{"entry_point", Token::Type::kEntryPoint}, TokenData{"entry_point", Token::Type::kEntryPoint},

View File

@ -29,6 +29,7 @@
#include "src/ast/cast_expression.h" #include "src/ast/cast_expression.h"
#include "src/ast/continue_statement.h" #include "src/ast/continue_statement.h"
#include "src/ast/decorated_variable.h" #include "src/ast/decorated_variable.h"
#include "src/ast/discard_statement.h"
#include "src/ast/else_statement.h" #include "src/ast/else_statement.h"
#include "src/ast/fallthrough_statement.h" #include "src/ast/fallthrough_statement.h"
#include "src/ast/float_literal.h" #include "src/ast/float_literal.h"
@ -1426,6 +1427,7 @@ ast::StatementList ParserImpl::statements() {
// | variable_stmt SEMICOLON // | variable_stmt SEMICOLON
// | break_stmt SEMICOLON // | break_stmt SEMICOLON
// | continue_stmt SEMICOLON // | continue_stmt SEMICOLON
// | DISCARD SEMICOLON
// | KILL SEMICOLON // | KILL SEMICOLON
// | assignment_stmt SEMICOLON // | assignment_stmt SEMICOLON
std::unique_ptr<ast::Statement> ParserImpl::statement() { std::unique_ptr<ast::Statement> ParserImpl::statement() {
@ -1513,6 +1515,18 @@ std::unique_ptr<ast::Statement> ParserImpl::statement() {
return cont; return cont;
} }
if (t.IsDiscard()) {
auto source = t.source();
next(); // Consume the peek
t = next();
if (!t.IsSemicolon()) {
set_error(t, "missing ;");
return nullptr;
}
return std::make_unique<ast::DiscardStatement>(source);
}
if (t.IsKill()) { if (t.IsKill()) {
auto source = t.source(); auto source = t.source();
next(); // Consume the peek next(); // Consume the peek

View File

@ -221,6 +221,22 @@ TEST_F(ParserImplTest, Statement_Kill_MissingSemicolon) {
EXPECT_EQ(p->error(), "1:5: missing ;"); EXPECT_EQ(p->error(), "1:5: missing ;");
} }
TEST_F(ParserImplTest, Statement_Discard) {
auto* p = parser("discard;");
auto e = p->statement();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_NE(e, nullptr);
ASSERT_TRUE(e->IsDiscard());
}
TEST_F(ParserImplTest, Statement_Discard_MissingSemicolon) {
auto* p = parser("discard");
auto e = p->statement();
ASSERT_TRUE(p->has_error());
EXPECT_EQ(e, nullptr);
EXPECT_EQ(p->error(), "1:8: missing ;");
}
} // namespace } // namespace
} // namespace wgsl } // namespace wgsl
} // namespace reader } // namespace reader

View File

@ -131,6 +131,8 @@ std::string Token::TypeToName(Type type) {
return "continue"; return "continue";
case Token::Type::kContinuing: case Token::Type::kContinuing:
return "continuing"; return "continuing";
case Token::Type::kDiscard:
return "discard";
case Token::Type::kDefault: case Token::Type::kDefault:
return "default"; return "default";
case Token::Type::kElse: case Token::Type::kElse:

View File

@ -142,6 +142,8 @@ class Token {
kContinue, kContinue,
/// A 'continuing' /// A 'continuing'
kContinuing, kContinuing,
/// A 'discard'
kDiscard,
/// A 'default' /// A 'default'
kDefault, kDefault,
/// A 'else' /// A 'else'
@ -395,6 +397,8 @@ class Token {
bool IsContinue() const { return type_ == Type::kContinue; } bool IsContinue() const { return type_ == Type::kContinue; }
/// @returns true if token is a 'continuing' /// @returns true if token is a 'continuing'
bool IsContinuing() const { return type_ == Type::kContinuing; } bool IsContinuing() const { return type_ == Type::kContinuing; }
/// @returns true if token is a 'discard'
bool IsDiscard() const { return type_ == Type::kDiscard; }
/// @returns true if token is a 'default' /// @returns true if token is a 'default'
bool IsDefault() const { return type_ == Type::kDefault; } bool IsDefault() const { return type_ == Type::kDefault; }
/// @returns true if token is a 'else' /// @returns true if token is a 'else'