[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'