Add case_selectors update
This CL adds the missing case_selectors option from the grammar updates. Change-Id: Ia6c110e917dd574711d396fb34ad53a2a67cf1fe Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/22306 Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
59fc026bcf
commit
1aadbd4e47
|
@ -19,15 +19,14 @@ namespace ast {
|
||||||
|
|
||||||
CaseStatement::CaseStatement() : Statement() {}
|
CaseStatement::CaseStatement() : Statement() {}
|
||||||
|
|
||||||
CaseStatement::CaseStatement(std::unique_ptr<Literal> condition,
|
CaseStatement::CaseStatement(CaseSelectorList conditions, StatementList body)
|
||||||
StatementList body)
|
: Statement(), conditions_(std::move(conditions)), body_(std::move(body)) {}
|
||||||
: Statement(), condition_(std::move(condition)), body_(std::move(body)) {}
|
|
||||||
|
|
||||||
CaseStatement::CaseStatement(const Source& source,
|
CaseStatement::CaseStatement(const Source& source,
|
||||||
std::unique_ptr<Literal> condition,
|
CaseSelectorList conditions,
|
||||||
StatementList body)
|
StatementList body)
|
||||||
: Statement(source),
|
: Statement(source),
|
||||||
condition_(std::move(condition)),
|
conditions_(std::move(conditions)),
|
||||||
body_(std::move(body)) {}
|
body_(std::move(body)) {}
|
||||||
|
|
||||||
CaseStatement::CaseStatement(CaseStatement&&) = default;
|
CaseStatement::CaseStatement(CaseStatement&&) = default;
|
||||||
|
@ -52,7 +51,16 @@ void CaseStatement::to_str(std::ostream& out, size_t indent) const {
|
||||||
if (IsDefault()) {
|
if (IsDefault()) {
|
||||||
out << "Default{" << std::endl;
|
out << "Default{" << std::endl;
|
||||||
} else {
|
} else {
|
||||||
out << "Case " << condition_->to_str() << "{" << std::endl;
|
out << "Case ";
|
||||||
|
bool first = true;
|
||||||
|
for (const auto& lit : conditions_) {
|
||||||
|
if (!first)
|
||||||
|
out << ", ";
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
out << lit->to_str();
|
||||||
|
}
|
||||||
|
out << "{" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& stmt : body_)
|
for (const auto& stmt : body_)
|
||||||
|
|
|
@ -27,35 +27,38 @@
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
|
||||||
|
/// A list of case literals
|
||||||
|
using CaseSelectorList = std::vector<std::unique_ptr<ast::Literal>>;
|
||||||
|
|
||||||
/// A case statement
|
/// A case statement
|
||||||
class CaseStatement : public Statement {
|
class CaseStatement : public Statement {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
CaseStatement();
|
CaseStatement();
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param condition the case condition
|
/// @param conditions the case conditions
|
||||||
/// @param body the case body
|
/// @param body the case body
|
||||||
CaseStatement(std::unique_ptr<Literal> condition, StatementList body);
|
CaseStatement(CaseSelectorList conditions, StatementList body);
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// @param source the source information
|
/// @param source the source information
|
||||||
/// @param condition the case condition
|
/// @param conditions the case conditions
|
||||||
/// @param body the case body
|
/// @param body the case body
|
||||||
CaseStatement(const Source& source,
|
CaseStatement(const Source& source,
|
||||||
std::unique_ptr<Literal> condition,
|
CaseSelectorList conditions,
|
||||||
StatementList body);
|
StatementList body);
|
||||||
/// Move constructor
|
/// Move constructor
|
||||||
CaseStatement(CaseStatement&&);
|
CaseStatement(CaseStatement&&);
|
||||||
~CaseStatement() override;
|
~CaseStatement() override;
|
||||||
|
|
||||||
/// Sets the condition for the case statement
|
/// Sets the conditions for the case statement
|
||||||
/// @param condition the condition to set
|
/// @param conditions the conditions to set
|
||||||
void set_condition(std::unique_ptr<Literal> condition) {
|
void set_conditions(CaseSelectorList conditions) {
|
||||||
condition_ = std::move(condition);
|
conditions_ = std::move(conditions);
|
||||||
}
|
}
|
||||||
/// @returns the case condition or nullptr if none set
|
/// @returns the case condition, empty if none set
|
||||||
Literal* condition() const { return condition_.get(); }
|
const CaseSelectorList& conditions() const { return conditions_; }
|
||||||
/// @returns true if this is a default statement
|
/// @returns true if this is a default statement
|
||||||
bool IsDefault() const { return condition_ == nullptr; }
|
bool IsDefault() const { return conditions_.empty(); }
|
||||||
|
|
||||||
/// Sets the case body
|
/// Sets the case body
|
||||||
/// @param body the case body
|
/// @param body the case body
|
||||||
|
@ -77,7 +80,7 @@ class CaseStatement : public Statement {
|
||||||
private:
|
private:
|
||||||
CaseStatement(const CaseStatement&) = delete;
|
CaseStatement(const CaseStatement&) = delete;
|
||||||
|
|
||||||
std::unique_ptr<Literal> condition_;
|
CaseSelectorList conditions_;
|
||||||
StatementList body_;
|
StatementList body_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,10 @@
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "src/ast/bool_literal.h"
|
#include "src/ast/bool_literal.h"
|
||||||
#include "src/ast/if_statement.h"
|
#include "src/ast/if_statement.h"
|
||||||
|
#include "src/ast/int_literal.h"
|
||||||
#include "src/ast/kill_statement.h"
|
#include "src/ast/kill_statement.h"
|
||||||
#include "src/ast/type/bool_type.h"
|
#include "src/ast/type/bool_type.h"
|
||||||
|
#include "src/ast/type/i32_type.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace ast {
|
namespace ast {
|
||||||
|
@ -28,22 +30,28 @@ using CaseStatementTest = testing::Test;
|
||||||
|
|
||||||
TEST_F(CaseStatementTest, Creation) {
|
TEST_F(CaseStatementTest, Creation) {
|
||||||
ast::type::BoolType bool_type;
|
ast::type::BoolType bool_type;
|
||||||
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
|
|
||||||
|
CaseSelectorList b;
|
||||||
|
b.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||||
|
|
||||||
StatementList stmts;
|
StatementList stmts;
|
||||||
stmts.push_back(std::make_unique<KillStatement>());
|
stmts.push_back(std::make_unique<KillStatement>());
|
||||||
|
|
||||||
auto* bool_ptr = b.get();
|
auto* bool_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));
|
||||||
EXPECT_EQ(c.condition(), bool_ptr);
|
ASSERT_EQ(c.conditions().size(), 1);
|
||||||
|
EXPECT_EQ(c.conditions()[0].get(), bool_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::BoolType bool_type;
|
||||||
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
|
CaseSelectorList b;
|
||||||
|
b.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||||
|
|
||||||
StatementList stmts;
|
StatementList stmts;
|
||||||
stmts.push_back(std::make_unique<KillStatement>());
|
stmts.push_back(std::make_unique<KillStatement>());
|
||||||
|
|
||||||
|
@ -64,9 +72,11 @@ TEST_F(CaseStatementTest, IsDefault_WithoutCondition) {
|
||||||
|
|
||||||
TEST_F(CaseStatementTest, IsDefault_WithCondition) {
|
TEST_F(CaseStatementTest, IsDefault_WithCondition) {
|
||||||
ast::type::BoolType bool_type;
|
ast::type::BoolType bool_type;
|
||||||
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
|
CaseSelectorList b;
|
||||||
|
b.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||||
|
|
||||||
CaseStatement c;
|
CaseStatement c;
|
||||||
c.set_condition(std::move(b));
|
c.set_conditions(std::move(b));
|
||||||
EXPECT_FALSE(c.IsDefault());
|
EXPECT_FALSE(c.IsDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +92,9 @@ TEST_F(CaseStatementTest, IsValid) {
|
||||||
|
|
||||||
TEST_F(CaseStatementTest, IsValid_NullBodyStatement) {
|
TEST_F(CaseStatementTest, IsValid_NullBodyStatement) {
|
||||||
ast::type::BoolType bool_type;
|
ast::type::BoolType bool_type;
|
||||||
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
|
CaseSelectorList b;
|
||||||
|
b.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||||
|
|
||||||
StatementList stmts;
|
StatementList stmts;
|
||||||
stmts.push_back(std::make_unique<KillStatement>());
|
stmts.push_back(std::make_unique<KillStatement>());
|
||||||
stmts.push_back(nullptr);
|
stmts.push_back(nullptr);
|
||||||
|
@ -93,20 +105,24 @@ TEST_F(CaseStatementTest, IsValid_NullBodyStatement) {
|
||||||
|
|
||||||
TEST_F(CaseStatementTest, IsValid_InvalidBodyStatement) {
|
TEST_F(CaseStatementTest, IsValid_InvalidBodyStatement) {
|
||||||
ast::type::BoolType bool_type;
|
ast::type::BoolType bool_type;
|
||||||
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
|
CaseSelectorList b;
|
||||||
|
b.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||||
|
|
||||||
StatementList stmts;
|
StatementList stmts;
|
||||||
stmts.push_back(std::make_unique<IfStatement>());
|
stmts.push_back(std::make_unique<IfStatement>());
|
||||||
|
|
||||||
CaseStatement c(std::move(b), std::move(stmts));
|
CaseStatement c({std::move(b)}, std::move(stmts));
|
||||||
EXPECT_FALSE(c.IsValid());
|
EXPECT_FALSE(c.IsValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CaseStatementTest, ToStr_WithCondition) {
|
TEST_F(CaseStatementTest, ToStr_WithCondition) {
|
||||||
ast::type::BoolType bool_type;
|
ast::type::BoolType bool_type;
|
||||||
auto b = std::make_unique<BoolLiteral>(&bool_type, true);
|
CaseSelectorList b;
|
||||||
|
b.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||||
|
|
||||||
StatementList stmts;
|
StatementList stmts;
|
||||||
stmts.push_back(std::make_unique<KillStatement>());
|
stmts.push_back(std::make_unique<KillStatement>());
|
||||||
CaseStatement c(std::move(b), std::move(stmts));
|
CaseStatement c({std::move(b)}, std::move(stmts));
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
c.to_str(out, 2);
|
c.to_str(out, 2);
|
||||||
|
@ -116,10 +132,28 @@ TEST_F(CaseStatementTest, ToStr_WithCondition) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CaseStatementTest, ToStr_WithMultipleConditions) {
|
||||||
|
ast::type::I32Type i32;
|
||||||
|
|
||||||
|
CaseSelectorList b;
|
||||||
|
b.push_back(std::make_unique<IntLiteral>(&i32, 1));
|
||||||
|
b.push_back(std::make_unique<IntLiteral>(&i32, 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 1, 2{
|
||||||
|
Kill{}
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(CaseStatementTest, ToStr_WithoutCondition) {
|
TEST_F(CaseStatementTest, ToStr_WithoutCondition) {
|
||||||
StatementList stmts;
|
StatementList stmts;
|
||||||
stmts.push_back(std::make_unique<KillStatement>());
|
stmts.push_back(std::make_unique<KillStatement>());
|
||||||
CaseStatement c(nullptr, std::move(stmts));
|
CaseStatement c(CaseSelectorList{}, std::move(stmts));
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
c.to_str(out, 2);
|
c.to_str(out, 2);
|
||||||
|
|
|
@ -30,7 +30,8 @@ using SwitchStatementTest = testing::Test;
|
||||||
|
|
||||||
TEST_F(SwitchStatementTest, Creation) {
|
TEST_F(SwitchStatementTest, Creation) {
|
||||||
ast::type::BoolType bool_type;
|
ast::type::BoolType bool_type;
|
||||||
auto lit = std::make_unique<BoolLiteral>(&bool_type, true);
|
CaseSelectorList lit;
|
||||||
|
lit.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||||
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,7 +62,8 @@ TEST_F(SwitchStatementTest, IsSwitch) {
|
||||||
|
|
||||||
TEST_F(SwitchStatementTest, IsValid) {
|
TEST_F(SwitchStatementTest, IsValid) {
|
||||||
ast::type::BoolType bool_type;
|
ast::type::BoolType bool_type;
|
||||||
auto lit = std::make_unique<BoolLiteral>(&bool_type, true);
|
CaseSelectorList lit;
|
||||||
|
lit.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||||
auto ident = std::make_unique<IdentifierExpression>("ident");
|
auto ident = std::make_unique<IdentifierExpression>("ident");
|
||||||
CaseStatementList body;
|
CaseStatementList body;
|
||||||
body.push_back(
|
body.push_back(
|
||||||
|
@ -73,7 +75,8 @@ TEST_F(SwitchStatementTest, IsValid) {
|
||||||
|
|
||||||
TEST_F(SwitchStatementTest, IsValid_Null_Condition) {
|
TEST_F(SwitchStatementTest, IsValid_Null_Condition) {
|
||||||
ast::type::BoolType bool_type;
|
ast::type::BoolType bool_type;
|
||||||
auto lit = std::make_unique<BoolLiteral>(&bool_type, true);
|
CaseSelectorList lit;
|
||||||
|
lit.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||||
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()));
|
||||||
|
@ -85,7 +88,8 @@ 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::BoolType bool_type;
|
||||||
auto lit = std::make_unique<BoolLiteral>(&bool_type, true);
|
CaseSelectorList lit;
|
||||||
|
lit.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||||
auto ident = std::make_unique<IdentifierExpression>("");
|
auto ident = std::make_unique<IdentifierExpression>("");
|
||||||
CaseStatementList body;
|
CaseStatementList body;
|
||||||
body.push_back(
|
body.push_back(
|
||||||
|
@ -97,7 +101,8 @@ 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::BoolType bool_type;
|
||||||
auto lit = std::make_unique<BoolLiteral>(&bool_type, true);
|
CaseSelectorList lit;
|
||||||
|
lit.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||||
auto ident = std::make_unique<IdentifierExpression>("ident");
|
auto ident = std::make_unique<IdentifierExpression>("ident");
|
||||||
CaseStatementList body;
|
CaseStatementList body;
|
||||||
body.push_back(
|
body.push_back(
|
||||||
|
@ -115,8 +120,8 @@ TEST_F(SwitchStatementTest, IsValid_Invalid_BodyStatement) {
|
||||||
case_body.push_back(nullptr);
|
case_body.push_back(nullptr);
|
||||||
|
|
||||||
CaseStatementList body;
|
CaseStatementList body;
|
||||||
body.push_back(
|
body.push_back(std::make_unique<CaseStatement>(CaseSelectorList{},
|
||||||
std::make_unique<CaseStatement>(nullptr, std::move(case_body)));
|
std::move(case_body)));
|
||||||
|
|
||||||
SwitchStatement stmt(std::move(ident), std::move(body));
|
SwitchStatement stmt(std::move(ident), std::move(body));
|
||||||
EXPECT_FALSE(stmt.IsValid());
|
EXPECT_FALSE(stmt.IsValid());
|
||||||
|
@ -138,7 +143,8 @@ TEST_F(SwitchStatementTest, ToStr_Empty) {
|
||||||
|
|
||||||
TEST_F(SwitchStatementTest, ToStr) {
|
TEST_F(SwitchStatementTest, ToStr) {
|
||||||
ast::type::BoolType bool_type;
|
ast::type::BoolType bool_type;
|
||||||
auto lit = std::make_unique<BoolLiteral>(&bool_type, true);
|
CaseSelectorList lit;
|
||||||
|
lit.push_back(std::make_unique<BoolLiteral>(&bool_type, true));
|
||||||
auto ident = std::make_unique<IdentifierExpression>("ident");
|
auto ident = std::make_unique<IdentifierExpression>("ident");
|
||||||
CaseStatementList body;
|
CaseStatementList body;
|
||||||
body.push_back(
|
body.push_back(
|
||||||
|
|
|
@ -1800,7 +1800,7 @@ std::unique_ptr<ast::SwitchStatement> ParserImpl::switch_stmt() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// switch_body
|
// switch_body
|
||||||
// : CASE const_literal COLON BRACKET_LEFT case_body BRACKET_RIGHT
|
// : CASE case_selectors COLON BRACKET_LEFT case_body BRACKET_RIGHT
|
||||||
// | DEFAULT COLON BRACKET_LEFT case_body BRACKET_RIGHT
|
// | DEFAULT COLON BRACKET_LEFT case_body BRACKET_RIGHT
|
||||||
std::unique_ptr<ast::CaseStatement> ParserImpl::switch_body() {
|
std::unique_ptr<ast::CaseStatement> ParserImpl::switch_body() {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
|
@ -1813,14 +1813,14 @@ std::unique_ptr<ast::CaseStatement> ParserImpl::switch_body() {
|
||||||
auto stmt = std::make_unique<ast::CaseStatement>();
|
auto stmt = std::make_unique<ast::CaseStatement>();
|
||||||
stmt->set_source(source);
|
stmt->set_source(source);
|
||||||
if (t.IsCase()) {
|
if (t.IsCase()) {
|
||||||
auto cond = const_literal();
|
auto cond = case_selectors();
|
||||||
if (has_error())
|
if (has_error())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (cond == nullptr) {
|
if (cond.empty()) {
|
||||||
set_error(peek(), "unable to parse case conditional");
|
set_error(peek(), "unable to parse case conditional");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
stmt->set_condition(std::move(cond));
|
stmt->set_conditions(std::move(cond));
|
||||||
}
|
}
|
||||||
|
|
||||||
t = next();
|
t = next();
|
||||||
|
@ -1850,6 +1850,24 @@ std::unique_ptr<ast::CaseStatement> ParserImpl::switch_body() {
|
||||||
return stmt;
|
return stmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// case_selectors
|
||||||
|
// : const_literal (COMMA const_literal)*
|
||||||
|
ast::CaseSelectorList ParserImpl::case_selectors() {
|
||||||
|
ast::CaseSelectorList selectors;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
auto cond = const_literal();
|
||||||
|
if (has_error())
|
||||||
|
return {};
|
||||||
|
if (cond == nullptr)
|
||||||
|
break;
|
||||||
|
|
||||||
|
selectors.push_back(std::move(cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
return selectors;
|
||||||
|
}
|
||||||
|
|
||||||
// case_body
|
// case_body
|
||||||
// :
|
// :
|
||||||
// | statement case_body
|
// | statement case_body
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "src/ast/assignment_statement.h"
|
#include "src/ast/assignment_statement.h"
|
||||||
#include "src/ast/builtin.h"
|
#include "src/ast/builtin.h"
|
||||||
|
#include "src/ast/case_statement.h"
|
||||||
#include "src/ast/constructor_expression.h"
|
#include "src/ast/constructor_expression.h"
|
||||||
#include "src/ast/else_statement.h"
|
#include "src/ast/else_statement.h"
|
||||||
#include "src/ast/entry_point.h"
|
#include "src/ast/entry_point.h"
|
||||||
|
@ -216,6 +217,9 @@ class ParserImpl {
|
||||||
/// Parses a `switch_body` grammar element
|
/// Parses a `switch_body` grammar element
|
||||||
/// @returns the parsed statement or nullptr
|
/// @returns the parsed statement or nullptr
|
||||||
std::unique_ptr<ast::CaseStatement> switch_body();
|
std::unique_ptr<ast::CaseStatement> switch_body();
|
||||||
|
/// Parses a `case_selectors` grammar element
|
||||||
|
/// @returns the list of literals
|
||||||
|
ast::CaseSelectorList case_selectors();
|
||||||
/// Parses a `case_body` grammar element
|
/// Parses a `case_body` grammar element
|
||||||
/// @returns the parsed statements
|
/// @returns the parsed statements
|
||||||
ast::StatementList case_body();
|
ast::StatementList case_body();
|
||||||
|
|
|
@ -165,8 +165,9 @@ TEST_F(TypeDeterminerTest, Stmt_Case) {
|
||||||
body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
|
body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
|
||||||
std::move(rhs)));
|
std::move(rhs)));
|
||||||
|
|
||||||
ast::CaseStatement cse(std::make_unique<ast::IntLiteral>(&i32, 3),
|
ast::CaseSelectorList lit;
|
||||||
std::move(body));
|
lit.push_back(std::make_unique<ast::IntLiteral>(&i32, 3));
|
||||||
|
ast::CaseStatement cse(std::move(lit), std::move(body));
|
||||||
|
|
||||||
EXPECT_TRUE(td()->DetermineResultType(&cse));
|
EXPECT_TRUE(td()->DetermineResultType(&cse));
|
||||||
ASSERT_NE(lhs_ptr->result_type(), nullptr);
|
ASSERT_NE(lhs_ptr->result_type(), nullptr);
|
||||||
|
@ -355,9 +356,12 @@ TEST_F(TypeDeterminerTest, Stmt_Switch) {
|
||||||
body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
|
body.push_back(std::make_unique<ast::AssignmentStatement>(std::move(lhs),
|
||||||
std::move(rhs)));
|
std::move(rhs)));
|
||||||
|
|
||||||
|
ast::CaseSelectorList lit;
|
||||||
|
lit.push_back(std::make_unique<ast::IntLiteral>(&i32, 3));
|
||||||
|
|
||||||
ast::CaseStatementList cases;
|
ast::CaseStatementList cases;
|
||||||
cases.push_back(std::make_unique<ast::CaseStatement>(
|
cases.push_back(
|
||||||
std::make_unique<ast::IntLiteral>(&i32, 3), std::move(body)));
|
std::make_unique<ast::CaseStatement>(std::move(lit), std::move(body)));
|
||||||
|
|
||||||
ast::SwitchStatement stmt(std::make_unique<ast::ScalarConstructorExpression>(
|
ast::SwitchStatement stmt(std::make_unique<ast::ScalarConstructorExpression>(
|
||||||
std::make_unique<ast::IntLiteral>(&i32, 2)),
|
std::make_unique<ast::IntLiteral>(&i32, 2)),
|
||||||
|
|
|
@ -724,9 +724,18 @@ bool GeneratorImpl::EmitCase(ast::CaseStatement* stmt) {
|
||||||
} else {
|
} else {
|
||||||
out_ << "case ";
|
out_ << "case ";
|
||||||
|
|
||||||
if (!EmitLiteral(stmt->condition())) {
|
bool first = true;
|
||||||
|
for (const auto& lit : stmt->conditions()) {
|
||||||
|
if (!first) {
|
||||||
|
out_ << ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
if (!EmitLiteral(lit.get())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out_ << ":";
|
out_ << ":";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,12 +31,13 @@ using GeneratorImplTest = testing::Test;
|
||||||
|
|
||||||
TEST_F(GeneratorImplTest, Emit_Case) {
|
TEST_F(GeneratorImplTest, Emit_Case) {
|
||||||
ast::type::I32Type i32;
|
ast::type::I32Type i32;
|
||||||
auto cond = std::make_unique<ast::IntLiteral>(&i32, 5);
|
|
||||||
|
|
||||||
ast::StatementList body;
|
ast::StatementList body;
|
||||||
body.push_back(std::make_unique<ast::BreakStatement>());
|
body.push_back(std::make_unique<ast::BreakStatement>());
|
||||||
|
|
||||||
ast::CaseStatement c(std::move(cond), std::move(body));
|
ast::CaseSelectorList lit;
|
||||||
|
lit.push_back(std::make_unique<ast::IntLiteral>(&i32, 5));
|
||||||
|
ast::CaseStatement c(std::move(lit), std::move(body));
|
||||||
|
|
||||||
GeneratorImpl g;
|
GeneratorImpl g;
|
||||||
g.increment_indent();
|
g.increment_indent();
|
||||||
|
@ -48,6 +49,27 @@ TEST_F(GeneratorImplTest, Emit_Case) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(GeneratorImplTest, Emit_Case_MultipleSelectors) {
|
||||||
|
ast::type::I32Type i32;
|
||||||
|
|
||||||
|
ast::StatementList body;
|
||||||
|
body.push_back(std::make_unique<ast::BreakStatement>());
|
||||||
|
|
||||||
|
ast::CaseSelectorList lit;
|
||||||
|
lit.push_back(std::make_unique<ast::IntLiteral>(&i32, 5));
|
||||||
|
lit.push_back(std::make_unique<ast::IntLiteral>(&i32, 6));
|
||||||
|
ast::CaseStatement c(std::move(lit), std::move(body));
|
||||||
|
|
||||||
|
GeneratorImpl g;
|
||||||
|
g.increment_indent();
|
||||||
|
|
||||||
|
ASSERT_TRUE(g.EmitCase(&c)) << g.error();
|
||||||
|
EXPECT_EQ(g.result(), R"( case 5, 6: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(GeneratorImplTest, Emit_Case_Default) {
|
TEST_F(GeneratorImplTest, Emit_Case_Default) {
|
||||||
ast::CaseStatement c;
|
ast::CaseStatement c;
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,9 @@ TEST_F(GeneratorImplTest, Emit_Switch) {
|
||||||
def->set_body(std::move(def_body));
|
def->set_body(std::move(def_body));
|
||||||
|
|
||||||
ast::type::I32Type i32;
|
ast::type::I32Type i32;
|
||||||
auto case_val = std::make_unique<ast::IntLiteral>(&i32, 5);
|
ast::CaseSelectorList case_val;
|
||||||
|
case_val.push_back(std::make_unique<ast::IntLiteral>(&i32, 5));
|
||||||
|
|
||||||
ast::StatementList case_body;
|
ast::StatementList case_body;
|
||||||
case_body.push_back(std::make_unique<ast::BreakStatement>());
|
case_body.push_back(std::make_unique<ast::BreakStatement>());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue