Make case selectors an integer value
Change-Id: I819983701ed6cca4eba1a05b4edc5fdff10fa88d Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/22542 Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
e009c2058d
commit
579d33c528
|
@ -20,14 +20,14 @@
|
|||
#include <vector>
|
||||
|
||||
#include "src/ast/expression.h"
|
||||
#include "src/ast/literal.h"
|
||||
#include "src/ast/int_literal.h"
|
||||
#include "src/ast/statement.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
||||
/// A list of case literals
|
||||
using CaseSelectorList = std::vector<std::unique_ptr<ast::Literal>>;
|
||||
using CaseSelectorList = std::vector<std::unique_ptr<ast::IntLiteral>>;
|
||||
|
||||
/// A case statement
|
||||
class CaseStatement : public Statement {
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
#include "src/ast/case_statement.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "src/ast/bool_literal.h"
|
||||
#include "src/ast/if_statement.h"
|
||||
#include "src/ast/kill_statement.h"
|
||||
#include "src/ast/sint_literal.h"
|
||||
#include "src/ast/type/bool_type.h"
|
||||
#include "src/ast/type/i32_type.h"
|
||||
#include "src/ast/type/u32_type.h"
|
||||
#include "src/ast/uint_literal.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
@ -28,29 +28,48 @@ namespace {
|
|||
|
||||
using CaseStatementTest = testing::Test;
|
||||
|
||||
TEST_F(CaseStatementTest, Creation) {
|
||||
ast::type::BoolType bool_type;
|
||||
TEST_F(CaseStatementTest, Creation_i32) {
|
||||
ast::type::I32Type i32;
|
||||
|
||||
CaseSelectorList b;
|
||||
b.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||
b.push_back(std::make_unique<SintLiteral>(&i32, 2));
|
||||
|
||||
StatementList stmts;
|
||||
stmts.push_back(std::make_unique<KillStatement>());
|
||||
|
||||
auto* bool_ptr = b.back().get();
|
||||
auto* int_ptr = b.back().get();
|
||||
auto* kill_ptr = stmts[0].get();
|
||||
|
||||
CaseStatement c(std::move(b), std::move(stmts));
|
||||
ASSERT_EQ(c.selectors().size(), 1);
|
||||
EXPECT_EQ(c.selectors()[0].get(), bool_ptr);
|
||||
EXPECT_EQ(c.selectors()[0].get(), int_ptr);
|
||||
ASSERT_EQ(c.body().size(), 1u);
|
||||
EXPECT_EQ(c.body()[0].get(), kill_ptr);
|
||||
}
|
||||
|
||||
TEST_F(CaseStatementTest, Creation_u32) {
|
||||
ast::type::U32Type u32;
|
||||
|
||||
CaseSelectorList b;
|
||||
b.push_back(std::make_unique<UintLiteral>(&u32, 2));
|
||||
|
||||
StatementList stmts;
|
||||
stmts.push_back(std::make_unique<KillStatement>());
|
||||
|
||||
auto* int_ptr = b.back().get();
|
||||
auto* kill_ptr = stmts[0].get();
|
||||
|
||||
CaseStatement c(std::move(b), std::move(stmts));
|
||||
ASSERT_EQ(c.selectors().size(), 1);
|
||||
EXPECT_EQ(c.selectors()[0].get(), int_ptr);
|
||||
ASSERT_EQ(c.body().size(), 1u);
|
||||
EXPECT_EQ(c.body()[0].get(), kill_ptr);
|
||||
}
|
||||
|
||||
TEST_F(CaseStatementTest, Creation_WithSource) {
|
||||
ast::type::BoolType bool_type;
|
||||
ast::type::I32Type i32;
|
||||
CaseSelectorList b;
|
||||
b.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||
b.push_back(std::make_unique<SintLiteral>(&i32, 2));
|
||||
|
||||
StatementList stmts;
|
||||
stmts.push_back(std::make_unique<KillStatement>());
|
||||
|
@ -71,9 +90,9 @@ TEST_F(CaseStatementTest, IsDefault_WithoutSelectors) {
|
|||
}
|
||||
|
||||
TEST_F(CaseStatementTest, IsDefault_WithSelectors) {
|
||||
ast::type::BoolType bool_type;
|
||||
ast::type::I32Type i32;
|
||||
CaseSelectorList b;
|
||||
b.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||
b.push_back(std::make_unique<SintLiteral>(&i32, 2));
|
||||
|
||||
CaseStatement c;
|
||||
c.set_selectors(std::move(b));
|
||||
|
@ -91,9 +110,9 @@ TEST_F(CaseStatementTest, IsValid) {
|
|||
}
|
||||
|
||||
TEST_F(CaseStatementTest, IsValid_NullBodyStatement) {
|
||||
ast::type::BoolType bool_type;
|
||||
ast::type::I32Type i32;
|
||||
CaseSelectorList b;
|
||||
b.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||
b.push_back(std::make_unique<SintLiteral>(&i32, 2));
|
||||
|
||||
StatementList stmts;
|
||||
stmts.push_back(std::make_unique<KillStatement>());
|
||||
|
@ -104,9 +123,9 @@ TEST_F(CaseStatementTest, IsValid_NullBodyStatement) {
|
|||
}
|
||||
|
||||
TEST_F(CaseStatementTest, IsValid_InvalidBodyStatement) {
|
||||
ast::type::BoolType bool_type;
|
||||
ast::type::I32Type i32;
|
||||
CaseSelectorList b;
|
||||
b.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||
b.push_back(std::make_unique<SintLiteral>(&i32, 2));
|
||||
|
||||
StatementList stmts;
|
||||
stmts.push_back(std::make_unique<IfStatement>());
|
||||
|
@ -115,10 +134,10 @@ TEST_F(CaseStatementTest, IsValid_InvalidBodyStatement) {
|
|||
EXPECT_FALSE(c.IsValid());
|
||||
}
|
||||
|
||||
TEST_F(CaseStatementTest, ToStr_WithSelectors) {
|
||||
ast::type::BoolType bool_type;
|
||||
TEST_F(CaseStatementTest, ToStr_WithSelectors_i32) {
|
||||
ast::type::I32Type i32;
|
||||
CaseSelectorList b;
|
||||
b.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||
b.push_back(std::make_unique<SintLiteral>(&i32, -2));
|
||||
|
||||
StatementList stmts;
|
||||
stmts.push_back(std::make_unique<KillStatement>());
|
||||
|
@ -126,7 +145,24 @@ TEST_F(CaseStatementTest, ToStr_WithSelectors) {
|
|||
|
||||
std::ostringstream out;
|
||||
c.to_str(out, 2);
|
||||
EXPECT_EQ(out.str(), R"( Case true{
|
||||
EXPECT_EQ(out.str(), R"( Case -2{
|
||||
Kill{}
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(CaseStatementTest, ToStr_WithSelectors_u32) {
|
||||
ast::type::U32Type u32;
|
||||
CaseSelectorList b;
|
||||
b.push_back(std::make_unique<UintLiteral>(&u32, 2));
|
||||
|
||||
StatementList stmts;
|
||||
stmts.push_back(std::make_unique<KillStatement>());
|
||||
CaseStatement c({std::move(b)}, std::move(stmts));
|
||||
|
||||
std::ostringstream out;
|
||||
c.to_str(out, 2);
|
||||
EXPECT_EQ(out.str(), R"( Case 2{
|
||||
Kill{}
|
||||
}
|
||||
)");
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
#include "src/ast/int_literal.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "src/ast/sint_literal.h"
|
||||
#include "src/ast/type/i32_type.h"
|
||||
#include "src/ast/type/u32_type.h"
|
||||
#include "src/ast/sint_literal.h"
|
||||
#include "src/ast/uint_literal.h"
|
||||
|
||||
namespace tint {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "src/ast/bool_literal.h"
|
||||
#include "src/ast/float_literal.h"
|
||||
#include "src/ast/int_literal.h"
|
||||
#include "src/ast/null_literal.h"
|
||||
#include "src/ast/sint_literal.h"
|
||||
#include "src/ast/uint_literal.h"
|
||||
|
@ -63,6 +64,11 @@ FloatLiteral* Literal::AsFloat() {
|
|||
return static_cast<FloatLiteral*>(this);
|
||||
}
|
||||
|
||||
IntLiteral* Literal::AsInt() {
|
||||
assert(IsInt());
|
||||
return static_cast<IntLiteral*>(this);
|
||||
}
|
||||
|
||||
SintLiteral* Literal::AsSint() {
|
||||
assert(IsSint());
|
||||
return static_cast<SintLiteral*>(this);
|
||||
|
|
|
@ -26,6 +26,7 @@ class BoolLiteral;
|
|||
class FloatLiteral;
|
||||
class NullLiteral;
|
||||
class SintLiteral;
|
||||
class IntLiteral;
|
||||
class UintLiteral;
|
||||
|
||||
/// Base class for a literal value
|
||||
|
@ -50,6 +51,8 @@ class Literal {
|
|||
BoolLiteral* AsBool();
|
||||
/// @returns the literal as a float literal
|
||||
FloatLiteral* AsFloat();
|
||||
/// @returns the literal as an int literal
|
||||
IntLiteral* AsInt();
|
||||
/// @returns the literal as a signed int literal
|
||||
SintLiteral* AsSint();
|
||||
/// @returns the literal as a null literal
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
#include <sstream>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "src/ast/bool_literal.h"
|
||||
#include "src/ast/case_statement.h"
|
||||
#include "src/ast/identifier_expression.h"
|
||||
#include "src/ast/type/bool_type.h"
|
||||
#include "src/ast/sint_literal.h"
|
||||
#include "src/ast/type/i32_type.h"
|
||||
|
||||
namespace tint {
|
||||
namespace ast {
|
||||
|
@ -29,9 +29,11 @@ namespace {
|
|||
using SwitchStatementTest = testing::Test;
|
||||
|
||||
TEST_F(SwitchStatementTest, Creation) {
|
||||
ast::type::BoolType bool_type;
|
||||
ast::type::I32Type i32;
|
||||
|
||||
CaseSelectorList lit;
|
||||
lit.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||
lit.push_back(std::make_unique<SintLiteral>(&i32, 1));
|
||||
|
||||
auto ident = std::make_unique<IdentifierExpression>("ident");
|
||||
CaseStatementList body;
|
||||
body.push_back(
|
||||
|
@ -61,9 +63,11 @@ TEST_F(SwitchStatementTest, IsSwitch) {
|
|||
}
|
||||
|
||||
TEST_F(SwitchStatementTest, IsValid) {
|
||||
ast::type::BoolType bool_type;
|
||||
ast::type::I32Type i32;
|
||||
|
||||
CaseSelectorList lit;
|
||||
lit.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||
lit.push_back(std::make_unique<SintLiteral>(&i32, 2));
|
||||
|
||||
auto ident = std::make_unique<IdentifierExpression>("ident");
|
||||
CaseStatementList body;
|
||||
body.push_back(
|
||||
|
@ -74,9 +78,11 @@ TEST_F(SwitchStatementTest, IsValid) {
|
|||
}
|
||||
|
||||
TEST_F(SwitchStatementTest, IsValid_Null_Condition) {
|
||||
ast::type::BoolType bool_type;
|
||||
ast::type::I32Type i32;
|
||||
|
||||
CaseSelectorList lit;
|
||||
lit.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||
lit.push_back(std::make_unique<SintLiteral>(&i32, 2));
|
||||
|
||||
CaseStatementList body;
|
||||
body.push_back(
|
||||
std::make_unique<CaseStatement>(std::move(lit), StatementList()));
|
||||
|
@ -87,9 +93,11 @@ TEST_F(SwitchStatementTest, IsValid_Null_Condition) {
|
|||
}
|
||||
|
||||
TEST_F(SwitchStatementTest, IsValid_Invalid_Condition) {
|
||||
ast::type::BoolType bool_type;
|
||||
ast::type::I32Type i32;
|
||||
|
||||
CaseSelectorList lit;
|
||||
lit.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||
lit.push_back(std::make_unique<SintLiteral>(&i32, 2));
|
||||
|
||||
auto ident = std::make_unique<IdentifierExpression>("");
|
||||
CaseStatementList body;
|
||||
body.push_back(
|
||||
|
@ -100,9 +108,11 @@ TEST_F(SwitchStatementTest, IsValid_Invalid_Condition) {
|
|||
}
|
||||
|
||||
TEST_F(SwitchStatementTest, IsValid_Null_BodyStatement) {
|
||||
ast::type::BoolType bool_type;
|
||||
ast::type::I32Type i32;
|
||||
|
||||
CaseSelectorList lit;
|
||||
lit.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||
lit.push_back(std::make_unique<SintLiteral>(&i32, 2));
|
||||
|
||||
auto ident = std::make_unique<IdentifierExpression>("ident");
|
||||
CaseStatementList body;
|
||||
body.push_back(
|
||||
|
@ -142,9 +152,11 @@ TEST_F(SwitchStatementTest, ToStr_Empty) {
|
|||
}
|
||||
|
||||
TEST_F(SwitchStatementTest, ToStr) {
|
||||
ast::type::BoolType bool_type;
|
||||
ast::type::I32Type i32;
|
||||
|
||||
CaseSelectorList lit;
|
||||
lit.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||
lit.push_back(std::make_unique<SintLiteral>(&i32, 2));
|
||||
|
||||
auto ident = std::make_unique<IdentifierExpression>("ident");
|
||||
CaseStatementList body;
|
||||
body.push_back(
|
||||
|
@ -156,7 +168,7 @@ TEST_F(SwitchStatementTest, ToStr) {
|
|||
EXPECT_EQ(out.str(), R"( Switch{
|
||||
Identifier{ident}
|
||||
{
|
||||
Case true{
|
||||
Case 2{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1856,13 +1856,19 @@ ast::CaseSelectorList ParserImpl::case_selectors() {
|
|||
ast::CaseSelectorList selectors;
|
||||
|
||||
for (;;) {
|
||||
auto t = peek();
|
||||
auto cond = const_literal();
|
||||
if (has_error())
|
||||
return {};
|
||||
if (cond == nullptr)
|
||||
break;
|
||||
if (!cond->IsInt()) {
|
||||
set_error(t, "invalid case selector must be an integer value");
|
||||
return {};
|
||||
}
|
||||
|
||||
selectors.push_back(std::move(cond));
|
||||
std::unique_ptr<ast::IntLiteral> selector(cond.release()->AsInt());
|
||||
selectors.push_back(std::move(selector));
|
||||
}
|
||||
|
||||
return selectors;
|
||||
|
|
|
@ -41,6 +41,14 @@ TEST_F(ParserImplTest, SwitchBody_Case_InvalidConstLiteral) {
|
|||
EXPECT_EQ(p->error(), "1:6: unable to parse case selectors");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, SwitchBody_Case_InvalidSelector_bool) {
|
||||
auto* p = parser("case true: { a = 4; }");
|
||||
auto e = p->switch_body();
|
||||
ASSERT_TRUE(p->has_error());
|
||||
ASSERT_EQ(e, nullptr);
|
||||
EXPECT_EQ(p->error(), "1:6: invalid case selector must be an integer value");
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, SwitchBody_Case_MissingConstLiteral) {
|
||||
auto* p = parser("case: { a = 4; }");
|
||||
auto e = p->switch_body();
|
||||
|
|
Loading…
Reference in New Issue