reader/wgsl: Parse '&' and '*'
Bug: tint:727 Change-Id: I1a2c93017b934fd0884570412f5ed25bf15991bb Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/50820 Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
2ef8033212
commit
09587e1d86
|
@ -2315,28 +2315,34 @@ Expect<ast::ExpressionList> ParserImpl::expect_argument_expression_list(
|
|||
// : singular_expression
|
||||
// | MINUS unary_expression
|
||||
// | BANG unary_expression
|
||||
// | STAR unary_expression
|
||||
// | AND unary_expression
|
||||
Maybe<ast::Expression*> ParserImpl::unary_expression() {
|
||||
auto t = peek();
|
||||
auto source = t.source();
|
||||
if (t.IsMinus() || t.IsBang()) {
|
||||
auto name = t.to_name();
|
||||
|
||||
next(); // Consume the peek
|
||||
|
||||
auto op = ast::UnaryOp::kNegation;
|
||||
if (t.IsBang())
|
||||
op = ast::UnaryOp::kNot;
|
||||
|
||||
auto expr = unary_expression();
|
||||
if (expr.errored)
|
||||
return Failure::kErrored;
|
||||
if (!expr.matched)
|
||||
return add_error(peek(),
|
||||
"unable to parse right side of " + name + " expression");
|
||||
|
||||
return create<ast::UnaryOpExpression>(source, op, expr.value);
|
||||
ast::UnaryOp op;
|
||||
if (match(Token::Type::kMinus)) {
|
||||
op = ast::UnaryOp::kNegation;
|
||||
} else if (match(Token::Type::kBang)) {
|
||||
op = ast::UnaryOp::kNot;
|
||||
} else if (match(Token::Type::kStar)) {
|
||||
op = ast::UnaryOp::kDereference;
|
||||
} else if (match(Token::Type::kAnd)) {
|
||||
op = ast::UnaryOp::kAddressOf;
|
||||
} else {
|
||||
return singular_expression();
|
||||
}
|
||||
return singular_expression();
|
||||
|
||||
auto expr = unary_expression();
|
||||
if (expr.errored) {
|
||||
return Failure::kErrored;
|
||||
}
|
||||
if (!expr.matched) {
|
||||
return add_error(
|
||||
peek(), "unable to parse right side of " + t.to_name() + " expression");
|
||||
}
|
||||
|
||||
return create<ast::UnaryOpExpression>(t.source(), op, expr.value);
|
||||
}
|
||||
|
||||
// multiplicative_expr
|
||||
|
|
|
@ -61,6 +61,62 @@ TEST_F(ParserImplTest, UnaryExpression_Minus) {
|
|||
EXPECT_EQ(init->literal()->As<ast::SintLiteral>()->value(), 1);
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, UnaryExpression_AddressOf) {
|
||||
auto p = parser("&x");
|
||||
auto e = p->unary_expression();
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
ASSERT_TRUE(e->Is<ast::UnaryOpExpression>());
|
||||
|
||||
auto* u = e->As<ast::UnaryOpExpression>();
|
||||
EXPECT_EQ(u->op(), ast::UnaryOp::kAddressOf);
|
||||
EXPECT_TRUE(u->expr()->Is<ast::IdentifierExpression>());
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, UnaryExpression_Dereference) {
|
||||
auto p = parser("*x");
|
||||
auto e = p->unary_expression();
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
ASSERT_TRUE(e->Is<ast::UnaryOpExpression>());
|
||||
|
||||
auto* u = e->As<ast::UnaryOpExpression>();
|
||||
EXPECT_EQ(u->op(), ast::UnaryOp::kDereference);
|
||||
EXPECT_TRUE(u->expr()->Is<ast::IdentifierExpression>());
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, UnaryExpression_AddressOf_Precedence) {
|
||||
auto p = parser("&x.y");
|
||||
auto e = p->logical_or_expression();
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
ASSERT_TRUE(e->Is<ast::UnaryOpExpression>());
|
||||
|
||||
auto* u = e->As<ast::UnaryOpExpression>();
|
||||
EXPECT_EQ(u->op(), ast::UnaryOp::kAddressOf);
|
||||
EXPECT_TRUE(u->expr()->Is<ast::MemberAccessorExpression>());
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, UnaryExpression_Dereference_Precedence) {
|
||||
auto p = parser("*x.y");
|
||||
auto e = p->logical_or_expression();
|
||||
EXPECT_TRUE(e.matched);
|
||||
EXPECT_FALSE(e.errored);
|
||||
EXPECT_FALSE(p->has_error()) << p->error();
|
||||
ASSERT_NE(e.value, nullptr);
|
||||
ASSERT_TRUE(e->Is<ast::UnaryOpExpression>());
|
||||
|
||||
auto* u = e->As<ast::UnaryOpExpression>();
|
||||
EXPECT_EQ(u->op(), ast::UnaryOp::kDereference);
|
||||
EXPECT_TRUE(u->expr()->Is<ast::MemberAccessorExpression>());
|
||||
}
|
||||
|
||||
TEST_F(ParserImplTest, UnaryExpression_Minus_InvalidRHS) {
|
||||
auto p = parser("-if(a) {}");
|
||||
auto e = p->unary_expression();
|
||||
|
|
Loading…
Reference in New Issue