• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/ast/unary_op_expression.h"
16 #include "src/reader/wgsl/parser_impl_test_helper.h"
17 
18 namespace tint {
19 namespace reader {
20 namespace wgsl {
21 namespace {
22 
TEST_F(ParserImplTest,UnaryExpression_Postix)23 TEST_F(ParserImplTest, UnaryExpression_Postix) {
24   auto p = parser("a[2]");
25   auto e = p->unary_expression();
26   EXPECT_TRUE(e.matched);
27   EXPECT_FALSE(e.errored);
28   EXPECT_FALSE(p->has_error()) << p->error();
29   ASSERT_NE(e.value, nullptr);
30 
31   ASSERT_TRUE(e->Is<ast::IndexAccessorExpression>());
32   auto* idx = e->As<ast::IndexAccessorExpression>();
33   ASSERT_TRUE(idx->object->Is<ast::IdentifierExpression>());
34   auto* ident = idx->object->As<ast::IdentifierExpression>();
35   EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
36 
37   ASSERT_TRUE(idx->index->Is<ast::SintLiteralExpression>());
38   ASSERT_EQ(idx->index->As<ast::SintLiteralExpression>()->value, 2);
39 }
40 
TEST_F(ParserImplTest,UnaryExpression_Minus)41 TEST_F(ParserImplTest, UnaryExpression_Minus) {
42   auto p = parser("- 1");
43   auto e = p->unary_expression();
44   EXPECT_TRUE(e.matched);
45   EXPECT_FALSE(e.errored);
46   EXPECT_FALSE(p->has_error()) << p->error();
47   ASSERT_NE(e.value, nullptr);
48   ASSERT_TRUE(e->Is<ast::UnaryOpExpression>());
49 
50   auto* u = e->As<ast::UnaryOpExpression>();
51   ASSERT_EQ(u->op, ast::UnaryOp::kNegation);
52 
53   ASSERT_TRUE(u->expr->Is<ast::SintLiteralExpression>());
54   EXPECT_EQ(u->expr->As<ast::SintLiteralExpression>()->value, 1);
55 }
56 
TEST_F(ParserImplTest,UnaryExpression_AddressOf)57 TEST_F(ParserImplTest, UnaryExpression_AddressOf) {
58   auto p = parser("&x");
59   auto e = p->unary_expression();
60   EXPECT_TRUE(e.matched);
61   EXPECT_FALSE(e.errored);
62   EXPECT_FALSE(p->has_error()) << p->error();
63   ASSERT_NE(e.value, nullptr);
64   ASSERT_TRUE(e->Is<ast::UnaryOpExpression>());
65 
66   auto* u = e->As<ast::UnaryOpExpression>();
67   EXPECT_EQ(u->op, ast::UnaryOp::kAddressOf);
68   EXPECT_TRUE(u->expr->Is<ast::IdentifierExpression>());
69 }
70 
TEST_F(ParserImplTest,UnaryExpression_Dereference)71 TEST_F(ParserImplTest, UnaryExpression_Dereference) {
72   auto p = parser("*x");
73   auto e = p->unary_expression();
74   EXPECT_TRUE(e.matched);
75   EXPECT_FALSE(e.errored);
76   EXPECT_FALSE(p->has_error()) << p->error();
77   ASSERT_NE(e.value, nullptr);
78   ASSERT_TRUE(e->Is<ast::UnaryOpExpression>());
79 
80   auto* u = e->As<ast::UnaryOpExpression>();
81   EXPECT_EQ(u->op, ast::UnaryOp::kIndirection);
82   EXPECT_TRUE(u->expr->Is<ast::IdentifierExpression>());
83 }
84 
TEST_F(ParserImplTest,UnaryExpression_AddressOf_Precedence)85 TEST_F(ParserImplTest, UnaryExpression_AddressOf_Precedence) {
86   auto p = parser("&x.y");
87   auto e = p->logical_or_expression();
88   EXPECT_TRUE(e.matched);
89   EXPECT_FALSE(e.errored);
90   EXPECT_FALSE(p->has_error()) << p->error();
91   ASSERT_NE(e.value, nullptr);
92   ASSERT_TRUE(e->Is<ast::UnaryOpExpression>());
93 
94   auto* u = e->As<ast::UnaryOpExpression>();
95   EXPECT_EQ(u->op, ast::UnaryOp::kAddressOf);
96   EXPECT_TRUE(u->expr->Is<ast::MemberAccessorExpression>());
97 }
98 
TEST_F(ParserImplTest,UnaryExpression_Dereference_Precedence)99 TEST_F(ParserImplTest, UnaryExpression_Dereference_Precedence) {
100   auto p = parser("*x.y");
101   auto e = p->logical_or_expression();
102   EXPECT_TRUE(e.matched);
103   EXPECT_FALSE(e.errored);
104   EXPECT_FALSE(p->has_error()) << p->error();
105   ASSERT_NE(e.value, nullptr);
106   ASSERT_TRUE(e->Is<ast::UnaryOpExpression>());
107 
108   auto* u = e->As<ast::UnaryOpExpression>();
109   EXPECT_EQ(u->op, ast::UnaryOp::kIndirection);
110   EXPECT_TRUE(u->expr->Is<ast::MemberAccessorExpression>());
111 }
112 
TEST_F(ParserImplTest,UnaryExpression_Minus_InvalidRHS)113 TEST_F(ParserImplTest, UnaryExpression_Minus_InvalidRHS) {
114   auto p = parser("-if(a) {}");
115   auto e = p->unary_expression();
116   EXPECT_FALSE(e.matched);
117   EXPECT_TRUE(e.errored);
118   EXPECT_EQ(e.value, nullptr);
119   EXPECT_TRUE(p->has_error());
120   EXPECT_EQ(p->error(), "1:2: unable to parse right side of - expression");
121 }
122 
TEST_F(ParserImplTest,UnaryExpression_Bang)123 TEST_F(ParserImplTest, UnaryExpression_Bang) {
124   auto p = parser("!1");
125   auto e = p->unary_expression();
126   EXPECT_TRUE(e.matched);
127   EXPECT_FALSE(e.errored);
128   EXPECT_FALSE(p->has_error()) << p->error();
129   ASSERT_NE(e.value, nullptr);
130   ASSERT_TRUE(e->Is<ast::UnaryOpExpression>());
131 
132   auto* u = e->As<ast::UnaryOpExpression>();
133   ASSERT_EQ(u->op, ast::UnaryOp::kNot);
134 
135   ASSERT_TRUE(u->expr->Is<ast::SintLiteralExpression>());
136   EXPECT_EQ(u->expr->As<ast::SintLiteralExpression>()->value, 1);
137 }
138 
TEST_F(ParserImplTest,UnaryExpression_Bang_InvalidRHS)139 TEST_F(ParserImplTest, UnaryExpression_Bang_InvalidRHS) {
140   auto p = parser("!if (a) {}");
141   auto e = p->unary_expression();
142   EXPECT_FALSE(e.matched);
143   EXPECT_TRUE(e.errored);
144   EXPECT_EQ(e.value, nullptr);
145   EXPECT_TRUE(p->has_error());
146   EXPECT_EQ(p->error(), "1:2: unable to parse right side of ! expression");
147 }
148 
TEST_F(ParserImplTest,UnaryExpression_Tilde)149 TEST_F(ParserImplTest, UnaryExpression_Tilde) {
150   auto p = parser("~1");
151   auto e = p->unary_expression();
152   EXPECT_TRUE(e.matched);
153   EXPECT_FALSE(e.errored);
154   EXPECT_FALSE(p->has_error()) << p->error();
155   ASSERT_NE(e.value, nullptr);
156   ASSERT_TRUE(e->Is<ast::UnaryOpExpression>());
157 
158   auto* u = e->As<ast::UnaryOpExpression>();
159   ASSERT_EQ(u->op, ast::UnaryOp::kComplement);
160 
161   ASSERT_TRUE(u->expr->Is<ast::SintLiteralExpression>());
162   EXPECT_EQ(u->expr->As<ast::SintLiteralExpression>()->value, 1);
163 }
164 
TEST_F(ParserImplTest,UnaryExpression_PrefixPlusPlus)165 TEST_F(ParserImplTest, UnaryExpression_PrefixPlusPlus) {
166   auto p = parser("++a");
167   auto e = p->unary_expression();
168   EXPECT_FALSE(e.matched);
169   EXPECT_TRUE(e.errored);
170   EXPECT_EQ(e.value, nullptr);
171   EXPECT_TRUE(p->has_error());
172   EXPECT_EQ(p->error(),
173             "1:1: prefix increment and decrement operators are reserved for a "
174             "future WGSL version");
175 }
176 
TEST_F(ParserImplTest,UnaryExpression_PrefixMinusMinus)177 TEST_F(ParserImplTest, UnaryExpression_PrefixMinusMinus) {
178   auto p = parser("--a");
179   auto e = p->unary_expression();
180   EXPECT_FALSE(e.matched);
181   EXPECT_TRUE(e.errored);
182   EXPECT_EQ(e.value, nullptr);
183   EXPECT_TRUE(p->has_error());
184   EXPECT_EQ(p->error(),
185             "1:1: prefix increment and decrement operators are reserved for a "
186             "future WGSL version");
187 }
188 
189 }  // namespace
190 }  // namespace wgsl
191 }  // namespace reader
192 }  // namespace tint
193