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