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