wgsl-reader: support multiple case selectors
Bug: tint:454
Change-Id: I5a046e19f66b5807723e96593ea6ba107ef69e6c
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/38261
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index 2175a46..264f23f 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -1856,13 +1856,26 @@
for (;;) {
auto t = peek();
+ auto matched_comma = match(Token::Type::kComma);
+
+ if (selectors.empty() && matched_comma)
+ return add_error(t, "a selector is expected before the comma");
+ if (matched_comma)
+ t = peek();
+
auto cond = const_literal();
if (cond.errored)
return Failure::kErrored;
- if (!cond.matched)
+ if (!cond.matched) {
+ if (matched_comma) {
+ return add_error(t, "a selector is expected after the comma");
+ }
break;
+ }
if (!cond->Is<ast::IntLiteral>())
return add_error(t, "invalid case selector must be an integer value");
+ if (!selectors.empty() && !matched_comma)
+ return add_error(t, "expected a comma after the previous selector");
selectors.push_back(cond.value->As<ast::IntLiteral>());
}
diff --git a/src/reader/wgsl/parser_impl_switch_body_test.cc b/src/reader/wgsl/parser_impl_switch_body_test.cc
index 73ab068..ba98d01 100644
--- a/src/reader/wgsl/parser_impl_switch_body_test.cc
+++ b/src/reader/wgsl/parser_impl_switch_body_test.cc
@@ -105,6 +105,61 @@
EXPECT_EQ(p->error(), "1:11: expected '}' for case statement");
}
+TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectors) {
+ auto p = parser("case 1, 2: { }");
+ auto e = p->switch_body();
+ EXPECT_FALSE(p->has_error()) << p->error();
+ EXPECT_TRUE(e.matched);
+ EXPECT_FALSE(e.errored);
+ ASSERT_NE(e.value, nullptr);
+ ASSERT_TRUE(e->Is<ast::CaseStatement>());
+ EXPECT_FALSE(e->IsDefault());
+ ASSERT_EQ(e->body()->size(), 0u);
+ ASSERT_EQ(e->selectors().size(), 2u);
+ ASSERT_EQ(e->selectors()[0]->to_str(), "1");
+ ASSERT_EQ(e->selectors()[1]->to_str(), "2");
+}
+
+TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsMissingColon) {
+ auto p = parser("case 1, 2 { }");
+ auto e = p->switch_body();
+ EXPECT_TRUE(p->has_error());
+ EXPECT_TRUE(e.errored);
+ EXPECT_FALSE(e.matched);
+ EXPECT_EQ(e.value, nullptr);
+ EXPECT_EQ(p->error(), "1:11: expected ':' for case statement");
+}
+
+TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsMissingComma) {
+ auto p = parser("case 1 2: { }");
+ auto e = p->switch_body();
+ EXPECT_TRUE(p->has_error());
+ EXPECT_TRUE(e.errored);
+ EXPECT_FALSE(e.matched);
+ EXPECT_EQ(e.value, nullptr);
+ EXPECT_EQ(p->error(), "1:8: expected a comma after the previous selector");
+}
+
+TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsEndsWithComma) {
+ auto p = parser("case 1, 2,: { }");
+ auto e = p->switch_body();
+ EXPECT_TRUE(p->has_error());
+ EXPECT_TRUE(e.errored);
+ EXPECT_FALSE(e.matched);
+ EXPECT_EQ(e.value, nullptr);
+ EXPECT_EQ(p->error(), "1:11: a selector is expected after the comma");
+}
+
+TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsStartsWithComma) {
+ auto p = parser("case , 1, 2: { }");
+ auto e = p->switch_body();
+ EXPECT_TRUE(p->has_error());
+ EXPECT_TRUE(e.errored);
+ EXPECT_FALSE(e.matched);
+ EXPECT_EQ(e.value, nullptr);
+ EXPECT_EQ(p->error(), "1:6: a selector is expected before the comma");
+}
+
TEST_F(ParserImplTest, SwitchBody_Default) {
auto p = parser("default: { a = 4; }");
auto e = p->switch_body();