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
|
// : singular_expression
|
||||||
// | MINUS unary_expression
|
// | MINUS unary_expression
|
||||||
// | BANG unary_expression
|
// | BANG unary_expression
|
||||||
|
// | STAR unary_expression
|
||||||
|
// | AND unary_expression
|
||||||
Maybe<ast::Expression*> ParserImpl::unary_expression() {
|
Maybe<ast::Expression*> ParserImpl::unary_expression() {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
auto source = t.source();
|
|
||||||
if (t.IsMinus() || t.IsBang()) {
|
|
||||||
auto name = t.to_name();
|
|
||||||
|
|
||||||
next(); // Consume the peek
|
ast::UnaryOp op;
|
||||||
|
if (match(Token::Type::kMinus)) {
|
||||||
auto op = ast::UnaryOp::kNegation;
|
op = ast::UnaryOp::kNegation;
|
||||||
if (t.IsBang())
|
} else if (match(Token::Type::kBang)) {
|
||||||
op = ast::UnaryOp::kNot;
|
op = ast::UnaryOp::kNot;
|
||||||
|
} else if (match(Token::Type::kStar)) {
|
||||||
auto expr = unary_expression();
|
op = ast::UnaryOp::kDereference;
|
||||||
if (expr.errored)
|
} else if (match(Token::Type::kAnd)) {
|
||||||
return Failure::kErrored;
|
op = ast::UnaryOp::kAddressOf;
|
||||||
if (!expr.matched)
|
} else {
|
||||||
return add_error(peek(),
|
return singular_expression();
|
||||||
"unable to parse right side of " + name + " expression");
|
|
||||||
|
|
||||||
return create<ast::UnaryOpExpression>(source, op, expr.value);
|
|
||||||
}
|
}
|
||||||
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
|
// multiplicative_expr
|
||||||
|
|
|
@ -61,6 +61,62 @@ TEST_F(ParserImplTest, UnaryExpression_Minus) {
|
||||||
EXPECT_EQ(init->literal()->As<ast::SintLiteral>()->value(), 1);
|
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) {
|
TEST_F(ParserImplTest, UnaryExpression_Minus_InvalidRHS) {
|
||||||
auto p = parser("-if(a) {}");
|
auto p = parser("-if(a) {}");
|
||||||
auto e = p->unary_expression();
|
auto e = p->unary_expression();
|
||||||
|
|
Loading…
Reference in New Issue