[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>
diff --git a/src/reader/wgsl/lexer.cc b/src/reader/wgsl/lexer.cc index 5fd1ef4..c1263b7 100644 --- a/src/reader/wgsl/lexer.cc +++ b/src/reader/wgsl/lexer.cc
@@ -495,6 +495,8 @@ return {Token::Type::kContinue, source, "continue"}; if (str == "continuing") return {Token::Type::kContinuing, source, "continuing"}; + if (str == "discard") + return {Token::Type::kDiscard, source, "discard"}; if (str == "default") return {Token::Type::kDefault, source, "default"}; if (str == "else")
diff --git a/src/reader/wgsl/lexer_test.cc b/src/reader/wgsl/lexer_test.cc index de64e6f..aa731af 100644 --- a/src/reader/wgsl/lexer_test.cc +++ b/src/reader/wgsl/lexer_test.cc
@@ -425,6 +425,7 @@ TokenData{"continue", Token::Type::kContinue}, TokenData{"continuing", Token::Type::kContinuing}, TokenData{"default", Token::Type::kDefault}, + TokenData{"discard", Token::Type::kDiscard}, TokenData{"else", Token::Type::kElse}, TokenData{"elseif", Token::Type::kElseIf}, TokenData{"entry_point", Token::Type::kEntryPoint},
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc index c3e7318..dd4a625 100644 --- a/src/reader/wgsl/parser_impl.cc +++ b/src/reader/wgsl/parser_impl.cc
@@ -29,6 +29,7 @@ #include "src/ast/cast_expression.h" #include "src/ast/continue_statement.h" #include "src/ast/decorated_variable.h" +#include "src/ast/discard_statement.h" #include "src/ast/else_statement.h" #include "src/ast/fallthrough_statement.h" #include "src/ast/float_literal.h" @@ -1426,6 +1427,7 @@ // | variable_stmt SEMICOLON // | break_stmt SEMICOLON // | continue_stmt SEMICOLON +// | DISCARD SEMICOLON // | KILL SEMICOLON // | assignment_stmt SEMICOLON std::unique_ptr<ast::Statement> ParserImpl::statement() { @@ -1513,6 +1515,18 @@ 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()) { auto source = t.source(); next(); // Consume the peek
diff --git a/src/reader/wgsl/parser_impl_statement_test.cc b/src/reader/wgsl/parser_impl_statement_test.cc index 9df6b49..f5f06f0 100644 --- a/src/reader/wgsl/parser_impl_statement_test.cc +++ b/src/reader/wgsl/parser_impl_statement_test.cc
@@ -221,6 +221,22 @@ 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 wgsl } // namespace reader
diff --git a/src/reader/wgsl/token.cc b/src/reader/wgsl/token.cc index 0a91ca6..91c489a 100644 --- a/src/reader/wgsl/token.cc +++ b/src/reader/wgsl/token.cc
@@ -131,6 +131,8 @@ return "continue"; case Token::Type::kContinuing: return "continuing"; + case Token::Type::kDiscard: + return "discard"; case Token::Type::kDefault: return "default"; case Token::Type::kElse:
diff --git a/src/reader/wgsl/token.h b/src/reader/wgsl/token.h index 8545cfa..8e2ffec 100644 --- a/src/reader/wgsl/token.h +++ b/src/reader/wgsl/token.h
@@ -142,6 +142,8 @@ kContinue, /// A 'continuing' kContinuing, + /// A 'discard' + kDiscard, /// A 'default' kDefault, /// A 'else' @@ -395,6 +397,8 @@ bool IsContinue() const { return type_ == Type::kContinue; } /// @returns true if token is a 'continuing' 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' bool IsDefault() const { return type_ == Type::kDefault; } /// @returns true if token is a 'else'