diff --git a/BUILD.gn b/BUILD.gn index 698068f074..7c08d053b9 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -230,8 +230,6 @@ source_set("libtint_core_src") { "src/ast/continue_statement.h", "src/ast/decorated_variable.cc", "src/ast/decorated_variable.h", - "src/ast/derivative_modifier.cc", - "src/ast/derivative_modifier.h", "src/ast/else_statement.cc", "src/ast/else_statement.h", "src/ast/entry_point.cc", @@ -322,14 +320,6 @@ source_set("libtint_core_src") { "src/ast/type_constructor_expression.h", "src/ast/uint_literal.cc", "src/ast/uint_literal.h", - "src/ast/unary_derivative.cc", - "src/ast/unary_derivative.h", - "src/ast/unary_derivative_expression.cc", - "src/ast/unary_derivative_expression.h", - "src/ast/unary_method.cc", - "src/ast/unary_method.h", - "src/ast/unary_method_expression.cc", - "src/ast/unary_method_expression.h", "src/ast/unary_op.cc", "src/ast/unary_op.h", "src/ast/unary_op_expression.cc", @@ -623,8 +613,6 @@ source_set("tint_unittests_core_src") { "src/ast/type/vector_type_test.cc", "src/ast/type_constructor_expression_test.cc", "src/ast/uint_literal_test.cc", - "src/ast/unary_derivative_expression_test.cc", - "src/ast/unary_method_expression_test.cc", "src/ast/unary_op_expression_test.cc", "src/ast/unless_statement_test.cc", "src/ast/variable_decl_statement_test.cc", @@ -737,7 +725,6 @@ source_set("tint_unittests_wgsl_reader_src") { "src/reader/wgsl/parser_impl_const_literal_test.cc", "src/reader/wgsl/parser_impl_continue_stmt_test.cc", "src/reader/wgsl/parser_impl_continuing_stmt_test.cc", - "src/reader/wgsl/parser_impl_derivative_modifier_test.cc", "src/reader/wgsl/parser_impl_else_stmt_test.cc", "src/reader/wgsl/parser_impl_elseif_stmt_test.cc", "src/reader/wgsl/parser_impl_entry_point_decl_test.cc", @@ -830,7 +817,6 @@ source_set("tint_unittests_wgsl_writer_src") { "src/writer/wgsl/generator_impl_switch_test.cc", "src/writer/wgsl/generator_impl_test.cc", "src/writer/wgsl/generator_impl_type_test.cc", - "src/writer/wgsl/generator_impl_unary_derivative_test.cc", "src/writer/wgsl/generator_impl_unary_method_test.cc", "src/writer/wgsl/generator_impl_unary_op_test.cc", "src/writer/wgsl/generator_impl_unless_test.cc", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 22fdd35016..117063b0a3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,8 +67,6 @@ set(TINT_LIB_SRCS ast/continue_statement.h ast/decorated_variable.cc ast/decorated_variable.h - ast/derivative_modifier.cc - ast/derivative_modifier.h ast/else_statement.cc ast/else_statement.h ast/entry_point.cc @@ -159,14 +157,6 @@ set(TINT_LIB_SRCS ast/type/void_type.h ast/uint_literal.cc ast/uint_literal.h - ast/unary_derivative.cc - ast/unary_derivative.h - ast/unary_derivative_expression.cc - ast/unary_derivative_expression.h - ast/unary_method.cc - ast/unary_method.h - ast/unary_method_expression.cc - ast/unary_method_expression.h ast/unary_op.cc ast/unary_op.h ast/unary_op_expression.cc @@ -303,8 +293,6 @@ set(TINT_TEST_SRCS ast/type/vector_type_test.cc ast/type_constructor_expression_test.cc ast/uint_literal_test.cc - ast/unary_derivative_expression_test.cc - ast/unary_method_expression_test.cc ast/unary_op_expression_test.cc ast/unless_statement_test.cc ast/variable_decl_statement_test.cc @@ -368,7 +356,6 @@ if(${TINT_BUILD_WGSL_READER}) reader/wgsl/parser_impl_const_literal_test.cc reader/wgsl/parser_impl_continue_stmt_test.cc reader/wgsl/parser_impl_continuing_stmt_test.cc - reader/wgsl/parser_impl_derivative_modifier_test.cc reader/wgsl/parser_impl_else_stmt_test.cc reader/wgsl/parser_impl_elseif_stmt_test.cc reader/wgsl/parser_impl_entry_point_decl_test.cc @@ -478,8 +465,6 @@ if(${TINT_BUILD_WGSL_WRITER}) writer/wgsl/generator_impl_return_test.cc writer/wgsl/generator_impl_switch_test.cc writer/wgsl/generator_impl_type_test.cc - writer/wgsl/generator_impl_unary_derivative_test.cc - writer/wgsl/generator_impl_unary_method_test.cc writer/wgsl/generator_impl_unary_op_test.cc writer/wgsl/generator_impl_unless_test.cc writer/wgsl/generator_impl_variable_decl_statement_test.cc diff --git a/src/ast/derivative_modifier.cc b/src/ast/derivative_modifier.cc deleted file mode 100644 index 66a7f35515..0000000000 --- a/src/ast/derivative_modifier.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/ast/derivative_modifier.h" - -namespace tint { -namespace ast { - -std::ostream& operator<<(std::ostream& out, DerivativeModifier mod) { - switch (mod) { - case DerivativeModifier::kNone: { - out << "none"; - break; - } - case DerivativeModifier::kFine: { - out << "fine"; - break; - } - case DerivativeModifier::kCoarse: { - out << "coarse"; - break; - } - } - return out; -} - -} // namespace ast -} // namespace tint diff --git a/src/ast/derivative_modifier.h b/src/ast/derivative_modifier.h deleted file mode 100644 index 83789e426f..0000000000 --- a/src/ast/derivative_modifier.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SRC_AST_DERIVATIVE_MODIFIER_H_ -#define SRC_AST_DERIVATIVE_MODIFIER_H_ - -#include - -namespace tint { -namespace ast { - -/// The derivative modifier -enum class DerivativeModifier { kNone = -1, kFine, kCoarse }; - -std::ostream& operator<<(std::ostream& out, DerivativeModifier mod); - -} // namespace ast -} // namespace tint - -#endif // SRC_AST_DERIVATIVE_MODIFIER_H_ diff --git a/src/ast/expression.cc b/src/ast/expression.cc index 71074e64fb..bbbc7ad124 100644 --- a/src/ast/expression.cc +++ b/src/ast/expression.cc @@ -25,8 +25,6 @@ #include "src/ast/identifier_expression.h" #include "src/ast/member_accessor_expression.h" #include "src/ast/type/alias_type.h" -#include "src/ast/unary_derivative_expression.h" -#include "src/ast/unary_method_expression.h" #include "src/ast/unary_op_expression.h" namespace tint { @@ -78,14 +76,6 @@ bool Expression::IsBinary() const { return false; } -bool Expression::IsUnaryDerivative() const { - return false; -} - -bool Expression::IsUnaryMethod() const { - return false; -} - bool Expression::IsUnaryOp() const { return false; } @@ -129,16 +119,6 @@ const MemberAccessorExpression* Expression::AsMemberAccessor() const { return static_cast(this); } -const UnaryDerivativeExpression* Expression::AsUnaryDerivative() const { - assert(IsUnaryDerivative()); - return static_cast(this); -} - -const UnaryMethodExpression* Expression::AsUnaryMethod() const { - assert(IsUnaryMethod()); - return static_cast(this); -} - const UnaryOpExpression* Expression::AsUnaryOp() const { assert(IsUnaryOp()); return static_cast(this); @@ -184,16 +164,6 @@ MemberAccessorExpression* Expression::AsMemberAccessor() { return static_cast(this); } -UnaryDerivativeExpression* Expression::AsUnaryDerivative() { - assert(IsUnaryDerivative()); - return static_cast(this); -} - -UnaryMethodExpression* Expression::AsUnaryMethod() { - assert(IsUnaryMethod()); - return static_cast(this); -} - UnaryOpExpression* Expression::AsUnaryOp() { assert(IsUnaryOp()); return static_cast(this); diff --git a/src/ast/expression.h b/src/ast/expression.h index f82fe9be93..43c4c40884 100644 --- a/src/ast/expression.h +++ b/src/ast/expression.h @@ -32,8 +32,6 @@ class CastExpression; class IdentifierExpression; class ConstructorExpression; class MemberAccessorExpression; -class UnaryDerivativeExpression; -class UnaryMethodExpression; class UnaryOpExpression; /// Base expression class @@ -63,10 +61,6 @@ class Expression : public Node { virtual bool IsMemberAccessor() const; /// @returns true if this is a binary expression virtual bool IsBinary() const; - /// @returns true if this is a unary derivative expression - virtual bool IsUnaryDerivative() const; - /// @returns true if this is a unary method expression - virtual bool IsUnaryMethod() const; /// @returns true if this is a unary op expression virtual bool IsUnaryOp() const; @@ -86,10 +80,6 @@ class Expression : public Node { const MemberAccessorExpression* AsMemberAccessor() const; /// @returns the expression as a binary expression const BinaryExpression* AsBinary() const; - /// @returns the expression as a unary derivative expression - const UnaryDerivativeExpression* AsUnaryDerivative() const; - /// @returns the expression as a unary method expression - const UnaryMethodExpression* AsUnaryMethod() const; /// @returns the expression as a unary op expression const UnaryOpExpression* AsUnaryOp() const; @@ -109,10 +99,6 @@ class Expression : public Node { MemberAccessorExpression* AsMemberAccessor(); /// @returns the expression as a binary expression BinaryExpression* AsBinary(); - /// @returns the expression as a unary derivative expression - UnaryDerivativeExpression* AsUnaryDerivative(); - /// @returns the expression as a unary method expression - UnaryMethodExpression* AsUnaryMethod(); /// @returns the expression as a unary op expression UnaryOpExpression* AsUnaryOp(); diff --git a/src/ast/unary_derivative.cc b/src/ast/unary_derivative.cc deleted file mode 100644 index 82ae23c205..0000000000 --- a/src/ast/unary_derivative.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/ast/unary_derivative.h" - -namespace tint { -namespace ast { - -std::ostream& operator<<(std::ostream& out, UnaryDerivative mod) { - switch (mod) { - case UnaryDerivative::kDpdx: { - out << "dpdx"; - break; - } - case UnaryDerivative::kDpdy: { - out << "dpdy"; - break; - } - case UnaryDerivative::kFwidth: { - out << "fwidth"; - break; - } - } - return out; -} - -} // namespace ast -} // namespace tint diff --git a/src/ast/unary_derivative.h b/src/ast/unary_derivative.h deleted file mode 100644 index 741834c746..0000000000 --- a/src/ast/unary_derivative.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SRC_AST_UNARY_DERIVATIVE_H_ -#define SRC_AST_UNARY_DERIVATIVE_H_ - -#include - -namespace tint { -namespace ast { - -/// The unary derivative -enum class UnaryDerivative { kDpdx = 0, kDpdy, kFwidth }; - -std::ostream& operator<<(std::ostream& out, UnaryDerivative mod); - -} // namespace ast -} // namespace tint - -#endif // SRC_AST_UNARY_DERIVATIVE_H_ diff --git a/src/ast/unary_derivative_expression.cc b/src/ast/unary_derivative_expression.cc deleted file mode 100644 index 23c13d58e8..0000000000 --- a/src/ast/unary_derivative_expression.cc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/ast/unary_derivative_expression.h" - -namespace tint { -namespace ast { - -UnaryDerivativeExpression::UnaryDerivativeExpression() : Expression() {} - -UnaryDerivativeExpression::UnaryDerivativeExpression( - UnaryDerivative op, - DerivativeModifier mod, - std::unique_ptr param) - : Expression(), op_(op), modifier_(mod), param_(std::move(param)) {} - -UnaryDerivativeExpression::UnaryDerivativeExpression( - const Source& source, - UnaryDerivative op, - DerivativeModifier mod, - std::unique_ptr param) - : Expression(source), op_(op), modifier_(mod), param_(std::move(param)) {} - -UnaryDerivativeExpression::UnaryDerivativeExpression( - UnaryDerivativeExpression&&) = default; - -UnaryDerivativeExpression::~UnaryDerivativeExpression() = default; - -bool UnaryDerivativeExpression::IsUnaryDerivative() const { - return true; -} - -bool UnaryDerivativeExpression::IsValid() const { - if (param_ == nullptr || !param_->IsValid()) { - return false; - } - return true; -} - -void UnaryDerivativeExpression::to_str(std::ostream& out, size_t indent) const { - make_indent(out, indent); - out << "UnaryDerivative{" << std::endl; - make_indent(out, indent + 2); - out << op_ << std::endl; - make_indent(out, indent + 2); - out << modifier_ << std::endl; - param_->to_str(out, indent + 2); - make_indent(out, indent); - out << "}" << std::endl; -} - -} // namespace ast -} // namespace tint diff --git a/src/ast/unary_derivative_expression.h b/src/ast/unary_derivative_expression.h deleted file mode 100644 index 2076eaf14c..0000000000 --- a/src/ast/unary_derivative_expression.h +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SRC_AST_UNARY_DERIVATIVE_EXPRESSION_H_ -#define SRC_AST_UNARY_DERIVATIVE_EXPRESSION_H_ - -#include -#include - -#include "src/ast/derivative_modifier.h" -#include "src/ast/expression.h" -#include "src/ast/literal.h" -#include "src/ast/unary_derivative.h" - -namespace tint { -namespace ast { - -/// A unary derivative expression -class UnaryDerivativeExpression : public Expression { - public: - /// Constructor - UnaryDerivativeExpression(); - /// Constructor - /// @param op the op - /// @param mod the derivative modifier - /// @param param the param - UnaryDerivativeExpression(UnaryDerivative op, - DerivativeModifier mod, - std::unique_ptr param); - /// Constructor - /// @param source the unary derivative expression source - /// @param op the op - /// @param mod the derivative modifier - /// @param param the param - UnaryDerivativeExpression(const Source& source, - UnaryDerivative op, - DerivativeModifier mod, - std::unique_ptr param); - /// Move constructor - UnaryDerivativeExpression(UnaryDerivativeExpression&&); - ~UnaryDerivativeExpression() override; - - /// Sets the op - /// @param op the op - void set_op(UnaryDerivative op) { op_ = op; } - /// @returns the op - UnaryDerivative op() const { return op_; } - - /// Sets the derivative modifier - /// @param mod the modifier - void set_modifier(DerivativeModifier mod) { modifier_ = mod; } - /// @returns the derivative modifier - DerivativeModifier modifier() const { return modifier_; } - - /// Sets the param - /// @param param the param - void set_param(std::unique_ptr param) { - param_ = std::move(param); - } - /// @returns the param - Expression* param() const { return param_.get(); } - - /// @returns true if this is an as expression - bool IsUnaryDerivative() const override; - - /// @returns true if the node is valid - bool IsValid() const override; - - /// Writes a representation of the node to the output stream - /// @param out the stream to write to - /// @param indent number of spaces to indent the node when writing - void to_str(std::ostream& out, size_t indent) const override; - - private: - UnaryDerivativeExpression(const UnaryDerivativeExpression&) = delete; - - UnaryDerivative op_ = UnaryDerivative::kDpdx; - DerivativeModifier modifier_ = DerivativeModifier::kNone; - std::unique_ptr param_; -}; - -} // namespace ast -} // namespace tint - -#endif // SRC_AST_UNARY_DERIVATIVE_EXPRESSION_H_ diff --git a/src/ast/unary_derivative_expression_test.cc b/src/ast/unary_derivative_expression_test.cc deleted file mode 100644 index 96d1e46d16..0000000000 --- a/src/ast/unary_derivative_expression_test.cc +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/ast/unary_derivative_expression.h" - -#include - -#include "gtest/gtest.h" -#include "src/ast/identifier_expression.h" - -namespace tint { -namespace ast { -namespace { - -using UnaryDerivativeExpressionTest = testing::Test; - -TEST_F(UnaryDerivativeExpressionTest, Creation) { - auto ident = std::make_unique("ident"); - auto* ident_ptr = ident.get(); - - UnaryDerivativeExpression d(UnaryDerivative::kDpdy, - DerivativeModifier::kCoarse, std::move(ident)); - EXPECT_EQ(d.param(), ident_ptr); - EXPECT_EQ(d.modifier(), DerivativeModifier::kCoarse); - EXPECT_EQ(d.op(), UnaryDerivative::kDpdy); -} - -TEST_F(UnaryDerivativeExpressionTest, Creation_WithSource) { - auto ident = std::make_unique("ident"); - - UnaryDerivativeExpression d(Source{20, 2}, UnaryDerivative::kDpdy, - DerivativeModifier::kCoarse, std::move(ident)); - auto src = d.source(); - EXPECT_EQ(src.line, 20u); - EXPECT_EQ(src.column, 2u); -} - -TEST_F(UnaryDerivativeExpressionTest, IsUnaryDerivative) { - UnaryDerivativeExpression d; - EXPECT_TRUE(d.IsUnaryDerivative()); -} - -TEST_F(UnaryDerivativeExpressionTest, IsValid) { - auto ident = std::make_unique("ident"); - UnaryDerivativeExpression d(UnaryDerivative::kDpdy, - DerivativeModifier::kCoarse, std::move(ident)); - EXPECT_TRUE(d.IsValid()); -} - -TEST_F(UnaryDerivativeExpressionTest, IsValid_NullParam) { - UnaryDerivativeExpression d(UnaryDerivative::kDpdy, - DerivativeModifier::kCoarse, nullptr); - EXPECT_FALSE(d.IsValid()); -} - -TEST_F(UnaryDerivativeExpressionTest, IsValid_InvalidParam) { - auto ident = std::make_unique(""); - UnaryDerivativeExpression d(UnaryDerivative::kDpdy, - DerivativeModifier::kCoarse, std::move(ident)); - EXPECT_FALSE(d.IsValid()); -} - -TEST_F(UnaryDerivativeExpressionTest, ToStr) { - auto ident = std::make_unique("ident"); - UnaryDerivativeExpression d(UnaryDerivative::kDpdy, - DerivativeModifier::kCoarse, std::move(ident)); - std::ostringstream out; - d.to_str(out, 2); - EXPECT_EQ(out.str(), R"( UnaryDerivative{ - dpdy - coarse - Identifier{ident} - } -)"); -} - -} // namespace -} // namespace ast -} // namespace tint diff --git a/src/ast/unary_method.cc b/src/ast/unary_method.cc deleted file mode 100644 index 7ff4653e64..0000000000 --- a/src/ast/unary_method.cc +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/ast/unary_method.h" - -namespace tint { -namespace ast { - -std::ostream& operator<<(std::ostream& out, UnaryMethod mod) { - switch (mod) { - case UnaryMethod::kAny: { - out << "any"; - break; - } - case UnaryMethod::kAll: { - out << "all"; - break; - } - case UnaryMethod::kIsNan: { - out << "is_nan"; - break; - } - case UnaryMethod::kIsInf: { - out << "is_inf"; - break; - } - case UnaryMethod::kIsFinite: { - out << "is_finite"; - break; - } - case UnaryMethod::kIsNormal: { - out << "is_normal"; - break; - } - case UnaryMethod::kDot: { - out << "dot"; - break; - } - case UnaryMethod::kOuterProduct: { - out << "outer_product"; - break; - } - } - return out; -} - -} // namespace ast -} // namespace tint diff --git a/src/ast/unary_method.h b/src/ast/unary_method.h deleted file mode 100644 index 3f719ef497..0000000000 --- a/src/ast/unary_method.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SRC_AST_UNARY_METHOD_H_ -#define SRC_AST_UNARY_METHOD_H_ - -#include - -namespace tint { -namespace ast { - -/// The unary methods -enum class UnaryMethod { - kAny = 0, - kAll, - kIsNan, - kIsInf, - kIsFinite, - kIsNormal, - kDot, - kOuterProduct -}; - -std::ostream& operator<<(std::ostream& out, UnaryMethod mod); - -} // namespace ast -} // namespace tint - -#endif // SRC_AST_UNARY_METHOD_H_ diff --git a/src/ast/unary_method_expression.cc b/src/ast/unary_method_expression.cc deleted file mode 100644 index 034a8e4d9b..0000000000 --- a/src/ast/unary_method_expression.cc +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/ast/unary_method_expression.h" - -namespace tint { -namespace ast { - -UnaryMethodExpression::UnaryMethodExpression() : Expression() {} - -UnaryMethodExpression::UnaryMethodExpression(UnaryMethod op, - ExpressionList params) - : Expression(), op_(op), params_(std::move(params)) {} - -UnaryMethodExpression::UnaryMethodExpression(const Source& source, - UnaryMethod op, - ExpressionList params) - : Expression(source), op_(op), params_(std::move(params)) {} - -UnaryMethodExpression::UnaryMethodExpression(UnaryMethodExpression&&) = default; - -UnaryMethodExpression::~UnaryMethodExpression() = default; - -bool UnaryMethodExpression::IsUnaryMethod() const { - return true; -} - -bool UnaryMethodExpression::IsValid() const { - if (params_.empty()) { - return false; - } - for (const auto& p : params_) { - if (p == nullptr || !p->IsValid()) { - return false; - } - } - return true; -} - -void UnaryMethodExpression::to_str(std::ostream& out, size_t indent) const { - make_indent(out, indent); - - out << "UnaryMethod{" << std::endl; - make_indent(out, indent + 2); - out << op_ << std::endl; - for (const auto& param : params_) { - param->to_str(out, indent + 2); - } - make_indent(out, indent); - out << "}" << std::endl; -} - -} // namespace ast -} // namespace tint diff --git a/src/ast/unary_method_expression.h b/src/ast/unary_method_expression.h deleted file mode 100644 index 4c63325819..0000000000 --- a/src/ast/unary_method_expression.h +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SRC_AST_UNARY_METHOD_EXPRESSION_H_ -#define SRC_AST_UNARY_METHOD_EXPRESSION_H_ - -#include - -#include "src/ast/expression.h" -#include "src/ast/literal.h" -#include "src/ast/unary_method.h" - -namespace tint { -namespace ast { - -/// A unary method expression -class UnaryMethodExpression : public Expression { - public: - /// Constructor - UnaryMethodExpression(); - /// Constructor - /// @param op the op - /// @param params the params - UnaryMethodExpression(UnaryMethod op, ExpressionList params); - /// Constructor - /// @param source the unary method source - /// @param op the op - /// @param params the params - UnaryMethodExpression(const Source& source, - UnaryMethod op, - ExpressionList params); - /// Move constructor - UnaryMethodExpression(UnaryMethodExpression&&); - ~UnaryMethodExpression() override; - - /// Sets the op - /// @param op the op - void set_op(UnaryMethod op) { op_ = op; } - /// @returns the op - UnaryMethod op() const { return op_; } - - /// Sets the params - /// @param params the parameters - void set_params(ExpressionList params) { params_ = std::move(params); } - /// @returns the params - const ExpressionList& params() const { return params_; } - - /// @returns true if this is an as expression - bool IsUnaryMethod() const override; - - /// @returns true if the node is valid - bool IsValid() const override; - - /// Writes a representation of the node to the output stream - /// @param out the stream to write to - /// @param indent number of spaces to indent the node when writing - void to_str(std::ostream& out, size_t indent) const override; - - private: - UnaryMethodExpression(const UnaryMethodExpression&) = delete; - - UnaryMethod op_ = UnaryMethod::kAny; - ExpressionList params_; -}; - -} // namespace ast -} // namespace tint - -#endif // SRC_AST_UNARY_METHOD_EXPRESSION_H_ diff --git a/src/ast/unary_method_expression_test.cc b/src/ast/unary_method_expression_test.cc deleted file mode 100644 index 1a2d9ed608..0000000000 --- a/src/ast/unary_method_expression_test.cc +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/ast/unary_method_expression.h" - -#include -#include - -#include "gtest/gtest.h" -#include "src/ast/identifier_expression.h" - -namespace tint { -namespace ast { -namespace { - -using UnaryMethodExpressionTest = testing::Test; - -TEST_F(UnaryMethodExpressionTest, Creation) { - ExpressionList params; - params.push_back(std::make_unique("ident")); - - auto* ident_ptr = params[0].get(); - - UnaryMethodExpression u(UnaryMethod::kAll, std::move(params)); - EXPECT_EQ(u.op(), UnaryMethod::kAll); - ASSERT_EQ(u.params().size(), 1u); - EXPECT_EQ(u.params()[0].get(), ident_ptr); -} - -TEST_F(UnaryMethodExpressionTest, Creation_WithSource) { - ExpressionList params; - params.push_back(std::make_unique("ident")); - - UnaryMethodExpression u(Source{20, 2}, UnaryMethod::kAll, std::move(params)); - auto src = u.source(); - EXPECT_EQ(src.line, 20u); - EXPECT_EQ(src.column, 2u); -} - -TEST_F(UnaryMethodExpressionTest, IsUnaryMethod) { - UnaryMethodExpression u; - EXPECT_TRUE(u.IsUnaryMethod()); -} - -TEST_F(UnaryMethodExpressionTest, IsValid) { - ExpressionList params; - params.push_back(std::make_unique("ident")); - - UnaryMethodExpression u(UnaryMethod::kAll, std::move(params)); - EXPECT_TRUE(u.IsValid()); -} - -TEST_F(UnaryMethodExpressionTest, IsValid_NullParam) { - ExpressionList params; - params.push_back(std::make_unique("ident")); - params.push_back(nullptr); - - UnaryMethodExpression u(UnaryMethod::kAll, std::move(params)); - EXPECT_FALSE(u.IsValid()); -} - -TEST_F(UnaryMethodExpressionTest, IsValid_InvalidParam) { - ExpressionList params; - params.push_back(std::make_unique("")); - - UnaryMethodExpression u(UnaryMethod::kAll, std::move(params)); - EXPECT_FALSE(u.IsValid()); -} - -TEST_F(UnaryMethodExpressionTest, IsValid_EmptyParams) { - UnaryMethodExpression u; - u.set_op(UnaryMethod::kAll); - EXPECT_FALSE(u.IsValid()); -} - -TEST_F(UnaryMethodExpressionTest, ToStr) { - ExpressionList params; - params.push_back(std::make_unique("ident")); - - UnaryMethodExpression u(UnaryMethod::kAll, std::move(params)); - std::ostringstream out; - u.to_str(out, 2); - EXPECT_EQ(out.str(), R"( UnaryMethod{ - all - Identifier{ident} - } -)"); -} - -} // namespace -} // namespace ast -} // namespace tint diff --git a/src/reader/wgsl/lexer.cc b/src/reader/wgsl/lexer.cc index 5d11237e3d..ae3e67ff38 100644 --- a/src/reader/wgsl/lexer.cc +++ b/src/reader/wgsl/lexer.cc @@ -468,10 +468,6 @@ Token Lexer::try_punctuation() { } Token Lexer::check_keyword(const Source& source, const std::string& str) { - if (str == "all") - return {Token::Type::kAll, source, "all"}; - if (str == "any") - return {Token::Type::kAny, source, "any"}; if (str == "array") return {Token::Type::kArray, source, "array"}; if (str == "as") @@ -498,16 +494,8 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) { return {Token::Type::kContinue, source, "continue"}; if (str == "continuing") return {Token::Type::kContinuing, source, "continuing"}; - if (str == "coarse") - return {Token::Type::kCoarse, source, "coarse"}; if (str == "default") return {Token::Type::kDefault, source, "default"}; - if (str == "dot") - return {Token::Type::kDot, source, "dot"}; - if (str == "dpdx") - return {Token::Type::kDpdx, source, "dpdx"}; - if (str == "dpdy") - return {Token::Type::kDpdy, source, "dpdy"}; if (str == "else") return {Token::Type::kElse, source, "else"}; if (str == "elseif") @@ -520,16 +508,12 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) { return {Token::Type::kFallthrough, source, "fallthrough"}; if (str == "false") return {Token::Type::kFalse, source, "false"}; - if (str == "fine") - return {Token::Type::kFine, source, "fine"}; if (str == "fn") return {Token::Type::kFn, source, "fn"}; if (str == "fragment") return {Token::Type::kFragment, source, "fragment"}; if (str == "function") return {Token::Type::kFunction, source, "function"}; - if (str == "fwidth") - return {Token::Type::kFwidth, source, "fwidth"}; if (str == "i32") return {Token::Type::kI32, source, "i32"}; if (str == "if") @@ -540,14 +524,6 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) { return {Token::Type::kImport, source, "import"}; if (str == "in") return {Token::Type::kIn, source, "in"}; - if (str == "is_nan") - return {Token::Type::kIsNan, source, "is_nan"}; - if (str == "is_inf") - return {Token::Type::kIsInf, source, "is_inf"}; - if (str == "is_finite") - return {Token::Type::kIsFinite, source, "is_finite"}; - if (str == "is_normal") - return {Token::Type::kIsNormal, source, "is_normal"}; if (str == "kill") return {Token::Type::kKill, source, "kill"}; if (str == "location") @@ -576,8 +552,6 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) { return {Token::Type::kOffset, source, "offset"}; if (str == "out") return {Token::Type::kOut, source, "out"}; - if (str == "outer_product") - return {Token::Type::kOuterProduct, source, "outer_product"}; if (str == "private") return {Token::Type::kPrivate, source, "private"}; if (str == "ptr") diff --git a/src/reader/wgsl/lexer_test.cc b/src/reader/wgsl/lexer_test.cc index 0b514f97b5..12170dce7b 100644 --- a/src/reader/wgsl/lexer_test.cc +++ b/src/reader/wgsl/lexer_test.cc @@ -408,82 +408,69 @@ TEST_P(KeywordTest, Parses) { INSTANTIATE_TEST_SUITE_P( LexerTest, KeywordTest, - testing::Values( - TokenData{"all", Token::Type::kAll}, - TokenData{"any", Token::Type::kAny}, - TokenData{"array", Token::Type::kArray}, - TokenData{"as", Token::Type::kAs}, - TokenData{"binding", Token::Type::kBinding}, - TokenData{"block", Token::Type::kBlock}, - TokenData{"bool", Token::Type::kBool}, - TokenData{"break", Token::Type::kBreak}, - TokenData{"builtin", Token::Type::kBuiltin}, - TokenData{"case", Token::Type::kCase}, - TokenData{"cast", Token::Type::kCast}, - TokenData{"compute", Token::Type::kCompute}, - TokenData{"const", Token::Type::kConst}, - TokenData{"continue", Token::Type::kContinue}, - TokenData{"continuing", Token::Type::kContinuing}, - TokenData{"coarse", Token::Type::kCoarse}, - TokenData{"default", Token::Type::kDefault}, - TokenData{"dot", Token::Type::kDot}, - TokenData{"dpdx", Token::Type::kDpdx}, - TokenData{"dpdy", Token::Type::kDpdy}, - TokenData{"else", Token::Type::kElse}, - TokenData{"elseif", Token::Type::kElseIf}, - TokenData{"entry_point", Token::Type::kEntryPoint}, - TokenData{"f32", Token::Type::kF32}, - TokenData{"fallthrough", Token::Type::kFallthrough}, - TokenData{"false", Token::Type::kFalse}, - TokenData{"fine", Token::Type::kFine}, - TokenData{"fn", Token::Type::kFn}, - TokenData{"fragment", Token::Type::kFragment}, - TokenData{"function", Token::Type::kFunction}, - TokenData{"fwidth", Token::Type::kFwidth}, - TokenData{"i32", Token::Type::kI32}, - TokenData{"if", Token::Type::kIf}, - TokenData{"image", Token::Type::kImage}, - TokenData{"import", Token::Type::kImport}, - TokenData{"in", Token::Type::kIn}, - TokenData{"is_nan", Token::Type::kIsNan}, - TokenData{"is_inf", Token::Type::kIsInf}, - TokenData{"is_finite", Token::Type::kIsFinite}, - TokenData{"is_normal", Token::Type::kIsNormal}, - TokenData{"kill", Token::Type::kKill}, - TokenData{"location", Token::Type::kLocation}, - TokenData{"loop", Token::Type::kLoop}, - TokenData{"mat2x2", Token::Type::kMat2x2}, - TokenData{"mat2x3", Token::Type::kMat2x3}, - TokenData{"mat2x4", Token::Type::kMat2x4}, - TokenData{"mat3x2", Token::Type::kMat3x2}, - TokenData{"mat3x3", Token::Type::kMat3x3}, - TokenData{"mat3x4", Token::Type::kMat3x4}, - TokenData{"mat4x2", Token::Type::kMat4x2}, - TokenData{"mat4x3", Token::Type::kMat4x3}, - TokenData{"mat4x4", Token::Type::kMat4x4}, - TokenData{"offset", Token::Type::kOffset}, - TokenData{"out", Token::Type::kOut}, - TokenData{"outer_product", Token::Type::kOuterProduct}, - TokenData{"private", Token::Type::kPrivate}, - TokenData{"ptr", Token::Type::kPtr}, - TokenData{"return", Token::Type::kReturn}, - TokenData{"set", Token::Type::kSet}, - TokenData{"storage_buffer", Token::Type::kStorageBuffer}, - TokenData{"struct", Token::Type::kStruct}, - TokenData{"switch", Token::Type::kSwitch}, - TokenData{"true", Token::Type::kTrue}, - TokenData{"type", Token::Type::kType}, - TokenData{"u32", Token::Type::kU32}, - TokenData{"uniform", Token::Type::kUniform}, - TokenData{"uniform_constant", Token::Type::kUniformConstant}, - TokenData{"unless", Token::Type::kUnless}, - TokenData{"var", Token::Type::kVar}, - TokenData{"vec2", Token::Type::kVec2}, - TokenData{"vec3", Token::Type::kVec3}, - TokenData{"vec4", Token::Type::kVec4}, - TokenData{"vertex", Token::Type::kVertex}, - TokenData{"void", Token::Type::kVoid}, - TokenData{"workgroup", Token::Type::kWorkgroup})); + testing::Values(TokenData{"array", Token::Type::kArray}, + TokenData{"as", Token::Type::kAs}, + TokenData{"binding", Token::Type::kBinding}, + TokenData{"block", Token::Type::kBlock}, + TokenData{"bool", Token::Type::kBool}, + TokenData{"break", Token::Type::kBreak}, + TokenData{"builtin", Token::Type::kBuiltin}, + TokenData{"case", Token::Type::kCase}, + TokenData{"cast", Token::Type::kCast}, + TokenData{"compute", Token::Type::kCompute}, + TokenData{"const", Token::Type::kConst}, + TokenData{"continue", Token::Type::kContinue}, + TokenData{"continuing", Token::Type::kContinuing}, + TokenData{"default", Token::Type::kDefault}, + TokenData{"else", Token::Type::kElse}, + TokenData{"elseif", Token::Type::kElseIf}, + TokenData{"entry_point", Token::Type::kEntryPoint}, + TokenData{"f32", Token::Type::kF32}, + TokenData{"fallthrough", Token::Type::kFallthrough}, + TokenData{"false", Token::Type::kFalse}, + TokenData{"fn", Token::Type::kFn}, + TokenData{"fragment", Token::Type::kFragment}, + TokenData{"function", Token::Type::kFunction}, + TokenData{"i32", Token::Type::kI32}, + TokenData{"if", Token::Type::kIf}, + TokenData{"image", Token::Type::kImage}, + TokenData{"import", Token::Type::kImport}, + TokenData{"in", Token::Type::kIn}, + TokenData{"kill", Token::Type::kKill}, + TokenData{"location", Token::Type::kLocation}, + TokenData{"loop", Token::Type::kLoop}, + TokenData{"mat2x2", Token::Type::kMat2x2}, + TokenData{"mat2x3", Token::Type::kMat2x3}, + TokenData{"mat2x4", Token::Type::kMat2x4}, + TokenData{"mat3x2", Token::Type::kMat3x2}, + TokenData{"mat3x3", Token::Type::kMat3x3}, + TokenData{"mat3x4", Token::Type::kMat3x4}, + TokenData{"mat4x2", Token::Type::kMat4x2}, + TokenData{"mat4x3", Token::Type::kMat4x3}, + TokenData{"mat4x4", Token::Type::kMat4x4}, + TokenData{"offset", Token::Type::kOffset}, + TokenData{"out", Token::Type::kOut}, + TokenData{"private", Token::Type::kPrivate}, + TokenData{"ptr", Token::Type::kPtr}, + TokenData{"return", Token::Type::kReturn}, + TokenData{"set", Token::Type::kSet}, + TokenData{"storage_buffer", Token::Type::kStorageBuffer}, + TokenData{"struct", Token::Type::kStruct}, + TokenData{"switch", Token::Type::kSwitch}, + TokenData{"true", Token::Type::kTrue}, + TokenData{"type", Token::Type::kType}, + TokenData{"u32", Token::Type::kU32}, + TokenData{"uniform", Token::Type::kUniform}, + TokenData{"uniform_constant", + Token::Type::kUniformConstant}, + TokenData{"unless", Token::Type::kUnless}, + TokenData{"var", Token::Type::kVar}, + TokenData{"vec2", Token::Type::kVec2}, + TokenData{"vec3", Token::Type::kVec3}, + TokenData{"vec4", Token::Type::kVec4}, + TokenData{"vertex", Token::Type::kVertex}, + TokenData{"void", Token::Type::kVoid}, + TokenData{"workgroup", Token::Type::kWorkgroup})); using KeywordTest_Reserved = testing::TestWithParam; TEST_P(KeywordTest_Reserved, Parses) { diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc index 0cfd6e5b85..589e4f7a7e 100644 --- a/src/reader/wgsl/parser_impl.cc +++ b/src/reader/wgsl/parser_impl.cc @@ -57,10 +57,6 @@ #include "src/ast/type/void_type.h" #include "src/ast/type_constructor_expression.h" #include "src/ast/uint_literal.h" -#include "src/ast/unary_derivative.h" -#include "src/ast/unary_derivative_expression.h" -#include "src/ast/unary_method.h" -#include "src/ast/unary_method_expression.h" #include "src/ast/unary_op.h" #include "src/ast/unary_op_expression.h" #include "src/ast/variable_decl_statement.h" @@ -2338,30 +2334,6 @@ std::unique_ptr ParserImpl::postfix_expression() { // : postfix_expression // | MINUS unary_expression // | BANG unary_expression -// | ANY PAREN_LEFT IDENT PAREN_RIGHT -// | ALL PAREN_LEFT IDENT PAREN_RIGHT -// | IS_NAN PAREN_LEFT IDENT PAREN_RIGHT -// | IS_INF PAREN_LEFT IDENT PAREN_RIGHT -// | IS_FINITE PAREN_LEFT IDENT PAREN_RIGHT -// | IS_NORMAL PAREN_LEFT IDENT PAREN_RIGHT -// | DOT PAREN_LEFT IDENT COMMA IDENT PAREN_RIGHT -// | OUTER_PRODUCT PAREN_LEFT IDENT COMMA IDENT PAREN_RIGHT -// | DPDX (LESS_THAN derivative_modifier GREATER_THAN)? -// PAREN_LEFT IDENT PAREN_RIGHT -// | DPDY (LESS_THAN derivative_modifier GREATER_THAN)? -// PAREN_LEFT IDENT PAREN_RIGHT -// | FWIDTH (LESS_THAN derivative_modifier GREATER_THAN)? -// PAREN_LEFT IDENT PAREN_RIGHT -// # | unord_greater_than_equal(a, b) -// # | unord_greater_than(a, b) -// # | unord_less_than_equal(a, b) -// # | unord_less_than(a, b) -// # | unord_not_equal(a, b) -// # | unord_equal(a, b) -// # | signed_greater_than_equal(a, b) -// # | signed_greater_than(a, b) -// # | signed_less_than_equal(a, b) -// # | signed_less_than(a, b) std::unique_ptr ParserImpl::unary_expression() { auto t = peek(); auto source = t.source(); @@ -2385,158 +2357,9 @@ std::unique_ptr ParserImpl::unary_expression() { return std::make_unique(source, op, std::move(expr)); } - if (t.IsAny() || t.IsAll() || t.IsIsNan() || t.IsIsInf() || t.IsIsFinite() || - t.IsIsNormal()) { - next(); // Consume the peek - - auto op = ast::UnaryMethod::kAny; - if (t.IsAll()) - op = ast::UnaryMethod::kAll; - else if (t.IsIsNan()) - op = ast::UnaryMethod::kIsNan; - else if (t.IsIsInf()) - op = ast::UnaryMethod::kIsInf; - else if (t.IsIsFinite()) - op = ast::UnaryMethod::kIsFinite; - else if (t.IsIsNormal()) - op = ast::UnaryMethod::kIsNormal; - - t = next(); - if (!t.IsParenLeft()) { - set_error(t, "missing ( for method call"); - return nullptr; - } - - t = next(); - if (!t.IsIdentifier()) { - set_error(t, "missing identifier for method call"); - return nullptr; - } - ast::ExpressionList ident; - ident.push_back( - std::make_unique(source, t.to_str())); - - t = next(); - if (!t.IsParenRight()) { - set_error(t, "missing ) for method call"); - return nullptr; - } - return std::make_unique(source, op, - std::move(ident)); - } - if (t.IsDot() || t.IsOuterProduct()) { - next(); // Consume the peek - - auto op = ast::UnaryMethod::kDot; - if (t.IsOuterProduct()) - op = ast::UnaryMethod::kOuterProduct; - - t = next(); - if (!t.IsParenLeft()) { - set_error(t, "missing ( for method call"); - return nullptr; - } - - t = next(); - if (!t.IsIdentifier()) { - set_error(t, "missing identifier for method call"); - return nullptr; - } - ast::ExpressionList ident; - ident.push_back( - std::make_unique(source, t.to_str())); - - t = next(); - if (!t.IsComma()) { - set_error(t, "missing , for method call"); - return nullptr; - } - - t = next(); - if (!t.IsIdentifier()) { - set_error(t, "missing identifier for method call"); - return nullptr; - } - ident.push_back( - std::make_unique(source, t.to_str())); - - t = next(); - if (!t.IsParenRight()) { - set_error(t, "missing ) for method call"); - return nullptr; - } - - return std::make_unique(source, op, - std::move(ident)); - } - if (t.IsDpdx() || t.IsDpdy() || t.IsFwidth()) { - next(); // Consume the peek - - auto op = ast::UnaryDerivative::kDpdx; - if (t.IsDpdy()) - op = ast::UnaryDerivative::kDpdy; - else if (t.IsFwidth()) - op = ast::UnaryDerivative::kFwidth; - - t = next(); - auto mod = ast::DerivativeModifier::kNone; - if (t.IsLessThan()) { - mod = derivative_modifier(); - if (has_error()) - return nullptr; - if (mod == ast::DerivativeModifier::kNone) { - set_error(peek(), "unable to parse derivative modifier"); - return nullptr; - } - - t = next(); - if (!t.IsGreaterThan()) { - set_error(t, "missing > for derivative modifier"); - return nullptr; - } - t = next(); - } - if (!t.IsParenLeft()) { - set_error(t, "missing ( for derivative method"); - return nullptr; - } - - t = next(); - if (!t.IsIdentifier()) { - set_error(t, "missing identifier for derivative method"); - return nullptr; - } - auto ident = - std::make_unique(source, t.to_str()); - - t = next(); - if (!t.IsParenRight()) { - set_error(t, "missing ) for derivative method"); - return nullptr; - } - - return std::make_unique(source, op, mod, - std::move(ident)); - } return postfix_expression(); } -// derivative_modifier -// : FINE -// | COARSE -ast::DerivativeModifier ParserImpl::derivative_modifier() { - auto t = peek(); - if (t.IsFine()) { - next(); // Consume the peek - return ast::DerivativeModifier::kFine; - } - if (t.IsCoarse()) { - next(); // Consume the peek - return ast::DerivativeModifier::kCoarse; - } - return ast::DerivativeModifier::kNone; -} - // multiplicative_expr // : // | STAR unary_expression multiplicative_expr diff --git a/src/reader/wgsl/parser_impl.h b/src/reader/wgsl/parser_impl.h index 3767686d0d..fc88037860 100644 --- a/src/reader/wgsl/parser_impl.h +++ b/src/reader/wgsl/parser_impl.h @@ -24,7 +24,6 @@ #include "src/ast/assignment_statement.h" #include "src/ast/builtin.h" #include "src/ast/constructor_expression.h" -#include "src/ast/derivative_modifier.h" #include "src/ast/else_statement.h" #include "src/ast/entry_point.h" #include "src/ast/function.h" @@ -246,9 +245,6 @@ class ParserImpl { /// Parses a `unary_expression` grammar element /// @returns the parsed expression or nullptr std::unique_ptr unary_expression(); - /// Parses a `derivative_modifier` grammar element - /// @returns the modifier or DerivativeModifier::kNone if none matched - ast::DerivativeModifier derivative_modifier(); /// Parses the recursive part of the `multiplicative_expression` /// @param lhs the left side of the expression /// @returns the parsed expression or nullptr diff --git a/src/reader/wgsl/parser_impl_argument_expression_list_test.cc b/src/reader/wgsl/parser_impl_argument_expression_list_test.cc index 4061b1168a..efbd7313b0 100644 --- a/src/reader/wgsl/parser_impl_argument_expression_list_test.cc +++ b/src/reader/wgsl/parser_impl_argument_expression_list_test.cc @@ -17,8 +17,6 @@ #include "src/ast/identifier_expression.h" #include "src/ast/int_literal.h" #include "src/ast/scalar_constructor_expression.h" -#include "src/ast/unary_derivative_expression.h" -#include "src/ast/unary_method_expression.h" #include "src/ast/unary_op_expression.h" #include "src/reader/wgsl/parser_impl.h" #include "src/reader/wgsl/parser_impl_test_helper.h" diff --git a/src/reader/wgsl/parser_impl_derivative_modifier_test.cc b/src/reader/wgsl/parser_impl_derivative_modifier_test.cc deleted file mode 100644 index 29b5785e0a..0000000000 --- a/src/reader/wgsl/parser_impl_derivative_modifier_test.cc +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "gtest/gtest.h" -#include "src/ast/derivative_modifier.h" -#include "src/reader/wgsl/parser_impl.h" -#include "src/reader/wgsl/parser_impl_test_helper.h" - -namespace tint { -namespace reader { -namespace wgsl { -namespace { - -struct DerivativeModifierData { - const char* input; - ast::DerivativeModifier result; -}; -inline std::ostream& operator<<(std::ostream& out, - DerivativeModifierData data) { - out << std::string(data.input); - return out; -} - -class DerivativeModifierTest - : public testing::TestWithParam { - public: - DerivativeModifierTest() = default; - ~DerivativeModifierTest() override = default; - - void SetUp() override { ctx_.Reset(); } - - void TearDown() override { impl_ = nullptr; } - - ParserImpl* parser(const std::string& str) { - impl_ = std::make_unique(&ctx_, str); - return impl_.get(); - } - - private: - std::unique_ptr impl_; - Context ctx_; -}; - -TEST_P(DerivativeModifierTest, Parses) { - auto params = GetParam(); - auto* p = parser(params.input); - - auto mod = p->derivative_modifier(); - ASSERT_FALSE(p->has_error()); - EXPECT_EQ(mod, params.result); - - auto t = p->next(); - EXPECT_TRUE(t.IsEof()); -} -INSTANTIATE_TEST_SUITE_P( - ParserImplTest, - DerivativeModifierTest, - testing::Values( - DerivativeModifierData{"fine", ast::DerivativeModifier::kFine}, - DerivativeModifierData{"coarse", ast::DerivativeModifier::kCoarse})); - -TEST_F(ParserImplTest, DerivativeModifier_NoMatch) { - auto* p = parser("not-a-modifier"); - auto stage = p->derivative_modifier(); - ASSERT_EQ(stage, ast::DerivativeModifier::kNone); - - auto t = p->next(); - EXPECT_TRUE(t.IsIdentifier()); - EXPECT_EQ(t.to_str(), "not"); -} - -} // namespace -} // namespace wgsl -} // namespace reader -} // namespace tint diff --git a/src/reader/wgsl/parser_impl_postfix_expression_test.cc b/src/reader/wgsl/parser_impl_postfix_expression_test.cc index 6f9ff514e3..960bdf33f4 100644 --- a/src/reader/wgsl/parser_impl_postfix_expression_test.cc +++ b/src/reader/wgsl/parser_impl_postfix_expression_test.cc @@ -19,8 +19,6 @@ #include "src/ast/int_literal.h" #include "src/ast/member_accessor_expression.h" #include "src/ast/scalar_constructor_expression.h" -#include "src/ast/unary_derivative_expression.h" -#include "src/ast/unary_method_expression.h" #include "src/ast/unary_op_expression.h" #include "src/reader/wgsl/parser_impl.h" #include "src/reader/wgsl/parser_impl_test_helper.h" diff --git a/src/reader/wgsl/parser_impl_primary_expression_test.cc b/src/reader/wgsl/parser_impl_primary_expression_test.cc index 80f294050d..1be32d7f45 100644 --- a/src/reader/wgsl/parser_impl_primary_expression_test.cc +++ b/src/reader/wgsl/parser_impl_primary_expression_test.cc @@ -23,8 +23,6 @@ #include "src/ast/type/f32_type.h" #include "src/ast/type/i32_type.h" #include "src/ast/type_constructor_expression.h" -#include "src/ast/unary_derivative_expression.h" -#include "src/ast/unary_method_expression.h" #include "src/ast/unary_op_expression.h" #include "src/reader/wgsl/parser_impl.h" #include "src/reader/wgsl/parser_impl_test_helper.h" diff --git a/src/reader/wgsl/parser_impl_unary_expression_test.cc b/src/reader/wgsl/parser_impl_unary_expression_test.cc index a11bc78327..fad15fc34c 100644 --- a/src/reader/wgsl/parser_impl_unary_expression_test.cc +++ b/src/reader/wgsl/parser_impl_unary_expression_test.cc @@ -17,8 +17,6 @@ #include "src/ast/identifier_expression.h" #include "src/ast/int_literal.h" #include "src/ast/scalar_constructor_expression.h" -#include "src/ast/unary_derivative_expression.h" -#include "src/ast/unary_method_expression.h" #include "src/ast/unary_op_expression.h" #include "src/reader/wgsl/parser_impl.h" #include "src/reader/wgsl/parser_impl_test_helper.h" @@ -99,732 +97,6 @@ TEST_F(ParserImplTest, UnaryExpression_Bang_InvalidRHS) { EXPECT_EQ(p->error(), "1:2: unable to parse right side of ! expression"); } -TEST_F(ParserImplTest, UnaryExpression_Any) { - auto* p = parser("any(a)"); - auto e = p->unary_expression(); - ASSERT_FALSE(p->has_error()) << p->error(); - ASSERT_NE(e, nullptr); - ASSERT_TRUE(e->IsUnaryMethod()); - - auto* u = e->AsUnaryMethod(); - ASSERT_EQ(u->op(), ast::UnaryMethod::kAny); - ASSERT_EQ(u->params().size(), 1u); - ASSERT_TRUE(u->params()[0]->IsIdentifier()); - auto* ident = u->params()[0]->AsIdentifier(); - EXPECT_EQ(ident->name(), "a"); -} - -TEST_F(ParserImplTest, UnaryExpression_Any_MissingParenLeft) { - auto* p = parser("any a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:5: missing ( for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_Any_MissingParenRight) { - auto* p = parser("any(a"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:6: missing ) for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_Any_MissingIdentifier) { - auto* p = parser("any()"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:5: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_Any_InvalidIdentifier) { - auto* p = parser("any(123)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:5: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_All) { - auto* p = parser("all(a)"); - auto e = p->unary_expression(); - ASSERT_FALSE(p->has_error()) << p->error(); - ASSERT_NE(e, nullptr); - ASSERT_TRUE(e->IsUnaryMethod()); - - auto* u = e->AsUnaryMethod(); - ASSERT_EQ(u->op(), ast::UnaryMethod::kAll); - ASSERT_EQ(u->params().size(), 1u); - ASSERT_TRUE(u->params()[0]->IsIdentifier()); - auto* ident = u->params()[0]->AsIdentifier(); - EXPECT_EQ(ident->name(), "a"); -} - -TEST_F(ParserImplTest, UnaryExpression_All_MissingParenLeft) { - auto* p = parser("all a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:5: missing ( for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_All_MissingParenRight) { - auto* p = parser("all(a"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:6: missing ) for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_All_MissingIdentifier) { - auto* p = parser("all()"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:5: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_All_InvalidIdentifier) { - auto* p = parser("all(123)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:5: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsNan) { - auto* p = parser("is_nan(a)"); - auto e = p->unary_expression(); - ASSERT_FALSE(p->has_error()) << p->error(); - ASSERT_NE(e, nullptr); - ASSERT_TRUE(e->IsUnaryMethod()); - - auto* u = e->AsUnaryMethod(); - ASSERT_EQ(u->op(), ast::UnaryMethod::kIsNan); - ASSERT_EQ(u->params().size(), 1u); - ASSERT_TRUE(u->params()[0]->IsIdentifier()); - auto* ident = u->params()[0]->AsIdentifier(); - EXPECT_EQ(ident->name(), "a"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsNan_MissingParenLeft) { - auto* p = parser("is_nan a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:8: missing ( for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsNan_MissingParenRight) { - auto* p = parser("is_nan(a"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:9: missing ) for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsNan_MissingIdentifier) { - auto* p = parser("is_nan()"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:8: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsNan_InvalidIdentifier) { - auto* p = parser("is_nan(123)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:8: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsInf) { - auto* p = parser("is_inf(a)"); - auto e = p->unary_expression(); - ASSERT_FALSE(p->has_error()) << p->error(); - ASSERT_NE(e, nullptr); - ASSERT_TRUE(e->IsUnaryMethod()); - - auto* u = e->AsUnaryMethod(); - ASSERT_EQ(u->op(), ast::UnaryMethod::kIsInf); - ASSERT_EQ(u->params().size(), 1u); - ASSERT_TRUE(u->params()[0]->IsIdentifier()); - auto* ident = u->params()[0]->AsIdentifier(); - EXPECT_EQ(ident->name(), "a"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsInf_MissingParenLeft) { - auto* p = parser("is_inf a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:8: missing ( for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsInf_MissingParenRight) { - auto* p = parser("is_inf(a"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:9: missing ) for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsInf_MissingIdentifier) { - auto* p = parser("is_inf()"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:8: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsInf_InvalidIdentifier) { - auto* p = parser("is_inf(123)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:8: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsFinite) { - auto* p = parser("is_finite(a)"); - auto e = p->unary_expression(); - ASSERT_FALSE(p->has_error()) << p->error(); - ASSERT_NE(e, nullptr); - ASSERT_TRUE(e->IsUnaryMethod()); - - auto* u = e->AsUnaryMethod(); - ASSERT_EQ(u->op(), ast::UnaryMethod::kIsFinite); - ASSERT_EQ(u->params().size(), 1u); - ASSERT_TRUE(u->params()[0]->IsIdentifier()); - auto* ident = u->params()[0]->AsIdentifier(); - EXPECT_EQ(ident->name(), "a"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsFinite_MissingParenLeft) { - auto* p = parser("is_finite a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:11: missing ( for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsFinite_MissingParenRight) { - auto* p = parser("is_finite(a"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:12: missing ) for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsFinite_MissingIdentifier) { - auto* p = parser("is_finite()"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:11: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsFinite_InvalidIdentifier) { - auto* p = parser("is_finite(123)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:11: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsNormal) { - auto* p = parser("is_normal(a)"); - auto e = p->unary_expression(); - ASSERT_FALSE(p->has_error()) << p->error(); - ASSERT_NE(e, nullptr); - ASSERT_TRUE(e->IsUnaryMethod()); - - auto* u = e->AsUnaryMethod(); - ASSERT_EQ(u->op(), ast::UnaryMethod::kIsNormal); - ASSERT_EQ(u->params().size(), 1u); - ASSERT_TRUE(u->params()[0]->IsIdentifier()); - auto* ident = u->params()[0]->AsIdentifier(); - EXPECT_EQ(ident->name(), "a"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsNormal_MissingParenLeft) { - auto* p = parser("is_normal a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:11: missing ( for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsNormal_MissingParenRight) { - auto* p = parser("is_normal(a"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:12: missing ) for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsNormal_MissingIdentifier) { - auto* p = parser("is_normal()"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:11: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_IsNormal_InvalidIdentifier) { - auto* p = parser("is_normal(123)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:11: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dot) { - auto* p = parser("dot(a, b)"); - auto e = p->unary_expression(); - ASSERT_FALSE(p->has_error()) << p->error(); - ASSERT_NE(e, nullptr); - ASSERT_TRUE(e->IsUnaryMethod()); - - auto* u = e->AsUnaryMethod(); - ASSERT_EQ(u->op(), ast::UnaryMethod::kDot); - ASSERT_EQ(u->params().size(), 2u); - ASSERT_TRUE(u->params()[0]->IsIdentifier()); - auto* ident = u->params()[0]->AsIdentifier(); - EXPECT_EQ(ident->name(), "a"); - - ASSERT_TRUE(u->params()[1]->IsIdentifier()); - ident = u->params()[1]->AsIdentifier(); - EXPECT_EQ(ident->name(), "b"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dot_MissingParenLeft) { - auto* p = parser("dot a, b)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:5: missing ( for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dot_MissingParenRight) { - auto* p = parser("dot(a, b"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:9: missing ) for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dot_MissingFirstIdentifier) { - auto* p = parser("dot(, a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:5: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dot_MissingSecondIdentifier) { - auto* p = parser("dot(a, )"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:8: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dot_MissingComma) { - auto* p = parser("dot(a b)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:7: missing , for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dot_InvalidFirstIdentifier) { - auto* p = parser("dot(123, b)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:5: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dot_InvalidSecondIdentifier) { - auto* p = parser("dot(a, 123)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:8: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_OuterProduct) { - auto* p = parser("outer_product(a, b)"); - auto e = p->unary_expression(); - ASSERT_FALSE(p->has_error()) << p->error(); - ASSERT_NE(e, nullptr); - ASSERT_TRUE(e->IsUnaryMethod()); - - auto* u = e->AsUnaryMethod(); - ASSERT_EQ(u->op(), ast::UnaryMethod::kOuterProduct); - ASSERT_EQ(u->params().size(), 2u); - ASSERT_TRUE(u->params()[0]->IsIdentifier()); - auto* ident = u->params()[0]->AsIdentifier(); - EXPECT_EQ(ident->name(), "a"); - - ASSERT_TRUE(u->params()[1]->IsIdentifier()); - ident = u->params()[1]->AsIdentifier(); - EXPECT_EQ(ident->name(), "b"); -} - -TEST_F(ParserImplTest, UnaryExpression_OuterProduct_MissingParenLeft) { - auto* p = parser("outer_product a, b)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:15: missing ( for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_OuterProduct_MissingParenRight) { - auto* p = parser("outer_product(a, b"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:19: missing ) for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_OuterProduct_MissingFirstIdentifier) { - auto* p = parser("outer_product(, b)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:15: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_OuterProduct_MissingSecondIdentifier) { - auto* p = parser("outer_product(a, )"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:18: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_OuterProduct_MissingComma) { - auto* p = parser("outer_product(a b)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:17: missing , for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_OuterProduct_InvalidFirstIdentifier) { - auto* p = parser("outer_product(123, b)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:15: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_OuterProduct_InvalidSecondIdentifier) { - auto* p = parser("outer_product(a, 123)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:18: missing identifier for method call"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdx_NoModifier) { - auto* p = parser("dpdx(a)"); - auto e = p->unary_expression(); - ASSERT_FALSE(p->has_error()) << p->error(); - ASSERT_NE(e, nullptr); - ASSERT_TRUE(e->IsUnaryDerivative()); - - auto* deriv = e->AsUnaryDerivative(); - EXPECT_EQ(deriv->op(), ast::UnaryDerivative::kDpdx); - EXPECT_EQ(deriv->modifier(), ast::DerivativeModifier::kNone); - - ASSERT_NE(deriv->param(), nullptr); - ASSERT_TRUE(deriv->param()->IsIdentifier()); - auto* ident = deriv->param()->AsIdentifier(); - EXPECT_EQ(ident->name(), "a"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdx_WithModifier) { - auto* p = parser("dpdx(a)"); - auto e = p->unary_expression(); - ASSERT_FALSE(p->has_error()) << p->error(); - ASSERT_NE(e, nullptr); - ASSERT_TRUE(e->IsUnaryDerivative()); - - auto* deriv = e->AsUnaryDerivative(); - EXPECT_EQ(deriv->op(), ast::UnaryDerivative::kDpdx); - EXPECT_EQ(deriv->modifier(), ast::DerivativeModifier::kCoarse); - - ASSERT_NE(deriv->param(), nullptr); - ASSERT_TRUE(deriv->param()->IsIdentifier()); - auto* ident = deriv->param()->AsIdentifier(); - EXPECT_EQ(ident->name(), "a"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdx_MissingLessThan) { - auto* p = parser("dpdx coarse>(a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:6: missing ( for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdx_InvalidModifier) { - auto* p = parser("dpdx(a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:6: unable to parse derivative modifier"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdx_EmptyModifer) { - auto* p = parser("dpdx coarse>(a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:6: missing ( for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdx_MissingGreaterThan) { - auto* p = parser("dpdxunary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:13: missing > for derivative modifier"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdx_MisisngLeftParen) { - auto* p = parser("dpdxa)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:13: missing ( for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdx_MissingRightParen) { - auto* p = parser("dpdx(a"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:15: missing ) for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdx_MissingIdentifier) { - auto* p = parser("dpdx()"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:14: missing identifier for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdx_InvalidIdentifeir) { - auto* p = parser("dpdx(12345)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:14: missing identifier for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdy_NoModifier) { - auto* p = parser("dpdy(a)"); - auto e = p->unary_expression(); - ASSERT_FALSE(p->has_error()) << p->error(); - ASSERT_NE(e, nullptr); - ASSERT_TRUE(e->IsUnaryDerivative()); - - auto* deriv = e->AsUnaryDerivative(); - EXPECT_EQ(deriv->op(), ast::UnaryDerivative::kDpdy); - EXPECT_EQ(deriv->modifier(), ast::DerivativeModifier::kNone); - - ASSERT_NE(deriv->param(), nullptr); - ASSERT_TRUE(deriv->param()->IsIdentifier()); - auto* ident = deriv->param()->AsIdentifier(); - EXPECT_EQ(ident->name(), "a"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdy_WithModifier) { - auto* p = parser("dpdy(a)"); - auto e = p->unary_expression(); - ASSERT_FALSE(p->has_error()) << p->error(); - ASSERT_NE(e, nullptr); - ASSERT_TRUE(e->IsUnaryDerivative()); - - auto* deriv = e->AsUnaryDerivative(); - EXPECT_EQ(deriv->op(), ast::UnaryDerivative::kDpdy); - EXPECT_EQ(deriv->modifier(), ast::DerivativeModifier::kFine); - - ASSERT_NE(deriv->param(), nullptr); - ASSERT_TRUE(deriv->param()->IsIdentifier()); - auto* ident = deriv->param()->AsIdentifier(); - EXPECT_EQ(ident->name(), "a"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdy_MissingLessThan) { - auto* p = parser("dpdy coarse>(a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:6: missing ( for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdy_InvalidModifier) { - auto* p = parser("dpdy(a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:6: unable to parse derivative modifier"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdy_EmptyModifer) { - auto* p = parser("dpdy coarse>(a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:6: missing ( for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdy_MissingGreaterThan) { - auto* p = parser("dpdyunary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:13: missing > for derivative modifier"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdy_MisisngLeftParen) { - auto* p = parser("dpdya)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:13: missing ( for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdy_MissingRightParen) { - auto* p = parser("dpdy(a"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:15: missing ) for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdy_MissingIdentifier) { - auto* p = parser("dpdy()"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:14: missing identifier for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Dpdy_InvalidIdentifeir) { - auto* p = parser("dpdy(12345)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:14: missing identifier for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Fwidth_NoModifier) { - auto* p = parser("fwidth(a)"); - auto e = p->unary_expression(); - ASSERT_FALSE(p->has_error()) << p->error(); - ASSERT_NE(e, nullptr); - ASSERT_TRUE(e->IsUnaryDerivative()); - - auto* deriv = e->AsUnaryDerivative(); - EXPECT_EQ(deriv->op(), ast::UnaryDerivative::kFwidth); - EXPECT_EQ(deriv->modifier(), ast::DerivativeModifier::kNone); - - ASSERT_NE(deriv->param(), nullptr); - ASSERT_TRUE(deriv->param()->IsIdentifier()); - auto* ident = deriv->param()->AsIdentifier(); - EXPECT_EQ(ident->name(), "a"); -} - -TEST_F(ParserImplTest, UnaryExpression_Fwidth_WithModifier) { - auto* p = parser("fwidth(a)"); - auto e = p->unary_expression(); - ASSERT_FALSE(p->has_error()) << p->error(); - ASSERT_NE(e, nullptr); - ASSERT_TRUE(e->IsUnaryDerivative()); - - auto* deriv = e->AsUnaryDerivative(); - EXPECT_EQ(deriv->op(), ast::UnaryDerivative::kFwidth); - EXPECT_EQ(deriv->modifier(), ast::DerivativeModifier::kCoarse); - - ASSERT_NE(deriv->param(), nullptr); - ASSERT_TRUE(deriv->param()->IsIdentifier()); - auto* ident = deriv->param()->AsIdentifier(); - EXPECT_EQ(ident->name(), "a"); -} - -TEST_F(ParserImplTest, UnaryExpression_Fwidth_MissingLessThan) { - auto* p = parser("fwidth coarse>(a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:8: missing ( for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Fwidth_InvalidModifier) { - auto* p = parser("fwidth(a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:8: unable to parse derivative modifier"); -} - -TEST_F(ParserImplTest, UnaryExpression_Fwidth_EmptyModifer) { - auto* p = parser("fwidth coarse>(a)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:8: missing ( for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Fwidth_MissingGreaterThan) { - auto* p = parser("fwidthunary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:15: missing > for derivative modifier"); -} - -TEST_F(ParserImplTest, UnaryExpression_Fwidth_MisisngLeftParen) { - auto* p = parser("fwidtha)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:15: missing ( for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Fwidth_MissingRightParen) { - auto* p = parser("fwidth(a"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:17: missing ) for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Fwidth_MissingIdentifier) { - auto* p = parser("fwidth()"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:16: missing identifier for derivative method"); -} - -TEST_F(ParserImplTest, UnaryExpression_Fwidht_InvalidIdentifeir) { - auto* p = parser("fwidth(12345)"); - auto e = p->unary_expression(); - ASSERT_TRUE(p->has_error()); - ASSERT_EQ(e, nullptr); - EXPECT_EQ(p->error(), "1:16: missing identifier for derivative method"); -} - } // namespace } // namespace wgsl } // namespace reader diff --git a/src/reader/wgsl/parser_impl_variable_decoration_test.cc b/src/reader/wgsl/parser_impl_variable_decoration_test.cc index 4fc9e5cdb4..dc1a5b0903 100644 --- a/src/reader/wgsl/parser_impl_variable_decoration_test.cc +++ b/src/reader/wgsl/parser_impl_variable_decoration_test.cc @@ -116,7 +116,6 @@ TEST_F(ParserImplTest, VariableDecoration_Builtin_MissingValue) { EXPECT_EQ(p->error(), "1:8: expected identifier for builtin"); } - TEST_F(ParserImplTest, VariableDecoration_Builtin_InvalidValue) { auto* p = parser("builtin other_thingy"); auto deco = p->variable_decoration(); diff --git a/src/reader/wgsl/token.cc b/src/reader/wgsl/token.cc index 300fbe4459..2976a95fe8 100644 --- a/src/reader/wgsl/token.cc +++ b/src/reader/wgsl/token.cc @@ -105,10 +105,6 @@ std::string Token::TypeToName(Type type) { case Token::Type::kXor: return "^"; - case Token::Type::kAll: - return "all"; - case Token::Type::kAny: - return "any"; case Token::Type::kArray: return "array"; case Token::Type::kAs: @@ -135,16 +131,8 @@ std::string Token::TypeToName(Type type) { return "continue"; case Token::Type::kContinuing: return "continuing"; - case Token::Type::kCoarse: - return "coarse"; case Token::Type::kDefault: return "default"; - case Token::Type::kDot: - return "dot"; - case Token::Type::kDpdx: - return "dpdx"; - case Token::Type::kDpdy: - return "dpdy"; case Token::Type::kElse: return "else"; case Token::Type::kElseIf: @@ -157,16 +145,12 @@ std::string Token::TypeToName(Type type) { return "fallthrough"; case Token::Type::kFalse: return "false"; - case Token::Type::kFine: - return "fine"; case Token::Type::kFn: return "fn"; case Token::Type::kFragment: return "fragment"; case Token::Type::kFunction: return "function"; - case Token::Type::kFwidth: - return "fwidth"; case Token::Type::kI32: return "i32"; case Token::Type::kIf: @@ -177,14 +161,6 @@ std::string Token::TypeToName(Type type) { return "import"; case Token::Type::kIn: return "in"; - case Token::Type::kIsNan: - return "is_nan"; - case Token::Type::kIsInf: - return "is_inf"; - case Token::Type::kIsFinite: - return "is_finite"; - case Token::Type::kIsNormal: - return "is_normal"; case Token::Type::kKill: return "kill"; case Token::Type::kLocation: @@ -213,8 +189,6 @@ std::string Token::TypeToName(Type type) { return "offset"; case Token::Type::kOut: return "out"; - case Token::Type::kOuterProduct: - return "outer_product"; case Token::Type::kPremerge: return "premerge"; case Token::Type::kPrivate: diff --git a/src/reader/wgsl/token.h b/src/reader/wgsl/token.h index 53a37cd365..f5a2c5f3ce 100644 --- a/src/reader/wgsl/token.h +++ b/src/reader/wgsl/token.h @@ -116,10 +116,6 @@ class Token { /// A '^' kXor, - /// A 'all' - kAll, - /// A 'any' - kAny, /// A 'array' kArray, /// A 'as' @@ -146,16 +142,8 @@ class Token { kContinue, /// A 'continuing' kContinuing, - /// A 'coarse' - kCoarse, /// A 'default' kDefault, - /// A 'dot' - kDot, - /// A 'dpdx' - kDpdx, - /// A 'dpdy' - kDpdy, /// A 'else' kElse, /// A 'elseif' @@ -168,16 +156,12 @@ class Token { kFallthrough, /// A 'false' kFalse, - /// A 'fine' - kFine, /// A 'fn' kFn, /// A 'fragment' kFragment, /// A 'function' kFunction, - /// A 'fwidth' - kFwidth, /// A 'i32' kI32, /// A 'if' @@ -188,14 +172,6 @@ class Token { kImport, /// A 'in' kIn, - /// A 'is_nan' - kIsNan, - /// A 'is_inf' - kIsInf, - /// A 'is_finite' - kIsFinite, - /// A 'is_normal' - kIsNormal, /// A 'kill' kKill, /// A 'location' @@ -224,8 +200,6 @@ class Token { kOffset, /// A 'out' kOut, - /// A 'outer_product' - kOuterProduct, /// A 'premerge' kPremerge, /// A 'private' @@ -401,10 +375,6 @@ class Token { /// @returns true if token is a '^' bool IsXor() const { return type_ == Type::kXor; } - /// @returns true if token is a 'all' - bool IsAll() const { return type_ == Type::kAll; } - /// @returns true if token is a 'any' - bool IsAny() const { return type_ == Type::kAny; } /// @returns true if token is a 'array' bool IsArray() const { return type_ == Type::kArray; } /// @returns true if token is a 'as' @@ -423,8 +393,6 @@ class Token { bool IsCase() const { return type_ == Type::kCase; } /// @returns true if token is a 'cast' bool IsCast() const { return type_ == Type::kCast; } - /// @returns true if token is 'coarse' - bool IsCoarse() const { return type_ == Type::kCoarse; } /// @returns true if token is a 'compute' bool IsCompute() const { return type_ == Type::kCompute; } /// @returns true if token is a 'const' @@ -435,12 +403,6 @@ class Token { bool IsContinuing() const { return type_ == Type::kContinuing; } /// @returns true if token is a 'default' bool IsDefault() const { return type_ == Type::kDefault; } - /// @returns true if token is a 'dot' - bool IsDot() const { return type_ == Type::kDot; } - /// @returns true if token is a 'dpdx' - bool IsDpdx() const { return type_ == Type::kDpdx; } - /// @returns true if token is a 'dpdy' - bool IsDpdy() const { return type_ == Type::kDpdy; } /// @returns true if token is a 'else' bool IsElse() const { return type_ == Type::kElse; } /// @returns true if token is a 'elseif' @@ -453,16 +415,12 @@ class Token { bool IsFallthrough() const { return type_ == Type::kFallthrough; } /// @returns true if token is a 'false' bool IsFalse() const { return type_ == Type::kFalse; } - /// @returns true if token is a 'fine' - bool IsFine() const { return type_ == Type::kFine; } /// @returns true if token is a 'fn' bool IsFn() const { return type_ == Type::kFn; } /// @returns true if token is a 'fragment' bool IsFragment() const { return type_ == Type::kFragment; } /// @returns true if token is a 'function' bool IsFunction() const { return type_ == Type::kFunction; } - /// @returns true if token is a 'fwidth' - bool IsFwidth() const { return type_ == Type::kFwidth; } /// @returns true if token is a 'i32' bool IsI32() const { return type_ == Type::kI32; } /// @returns true if token is a 'if' @@ -473,14 +431,6 @@ class Token { bool IsImport() const { return type_ == Type::kImport; } /// @returns true if token is a 'in' bool IsIn() const { return type_ == Type::kIn; } - /// @returns true if token is a 'is_nan' - bool IsIsNan() const { return type_ == Type::kIsNan; } - /// @returns true if token is a 'is_inf' - bool IsIsInf() const { return type_ == Type::kIsInf; } - /// @returns true if token is a 'is_finite' - bool IsIsFinite() const { return type_ == Type::kIsFinite; } - /// @returns true if token is a 'is_normal' - bool IsIsNormal() const { return type_ == Type::kIsNormal; } /// @returns true if token is a 'kill' bool IsKill() const { return type_ == Type::kKill; } /// @returns true if token is a 'location' @@ -509,8 +459,6 @@ class Token { bool IsOffset() const { return type_ == Type::kOffset; } /// @returns true if token is a 'out' bool IsOut() const { return type_ == Type::kOut; } - /// @returns true if token is a 'outer_product' - bool IsOuterProduct() const { return type_ == Type::kOuterProduct; } /// @returns true if token is a 'private' bool IsPrivate() const { return type_ == Type::kPrivate; } /// @returns true if token is a 'ptr' diff --git a/src/type_determiner.cc b/src/type_determiner.cc index 0def87071a..beddba4283 100644 --- a/src/type_determiner.cc +++ b/src/type_determiner.cc @@ -42,13 +42,30 @@ #include "src/ast/type/struct_type.h" #include "src/ast/type/vector_type.h" #include "src/ast/type_constructor_expression.h" -#include "src/ast/unary_derivative_expression.h" -#include "src/ast/unary_method_expression.h" #include "src/ast/unary_op_expression.h" #include "src/ast/unless_statement.h" #include "src/ast/variable_decl_statement.h" namespace tint { +namespace { + +bool IsDerivative(const std::string& name) { + return name == "dpdx" || name == "dpdx_fine" || name == "dpdx_coarse" || + name == "dpdy" || name == "dpdy_fine" || name == "dpdy_coarse" || + name == "fwidth" || name == "fwidth_fine" || name == "fwidth_coarse"; +} + +bool IsFloatIntrinsic(const std::string& name) { + return name == "is_finite" || name == "is_inf" || name == "is_nan" || + name == "is_normal"; +} + +bool IsIntrinsic(const std::string& name) { + return IsDerivative(name) || name == "all" || name == "any" || + IsFloatIntrinsic(name) || name == "dot" || name == "outer_product"; +} + +} // namespace TypeDeterminer::TypeDeterminer(Context* ctx, ast::Module* mod) : ctx_(*ctx), mod_(mod) {} @@ -253,12 +270,6 @@ bool TypeDeterminer::DetermineResultType(ast::Expression* expr) { if (expr->IsMemberAccessor()) { return DetermineMemberAccessor(expr->AsMemberAccessor()); } - if (expr->IsUnaryDerivative()) { - return DetermineUnaryDerivative(expr->AsUnaryDerivative()); - } - if (expr->IsUnaryMethod()) { - return DetermineUnaryMethod(expr->AsUnaryMethod()); - } if (expr->IsUnaryOp()) { return DetermineUnaryOp(expr->AsUnaryOp()); } @@ -318,7 +329,11 @@ bool TypeDeterminer::DetermineCall(ast::CallExpression* expr) { if (expr->func()->IsIdentifier()) { auto* ident = expr->func()->AsIdentifier(); - if (ident->has_path()) { + if (IsIntrinsic(ident->name())) { + if (!DetermineIntrinsic(ident->name(), expr)) + return false; + + } else if (ident->has_path()) { auto* imp = mod_->FindImportByName(ident->path()); if (imp == nullptr) { set_error(expr->source(), "Unable to find import for " + ident->name()); @@ -355,6 +370,75 @@ bool TypeDeterminer::DetermineCall(ast::CallExpression* expr) { return true; } +bool TypeDeterminer::DetermineIntrinsic(const std::string& name, + ast::CallExpression* expr) { + if (IsDerivative(name)) { + if (expr->params().size() != 1) { + set_error(expr->source(), "incorrect number of parameters for " + name); + return false; + } + + // The result type must be the same as the type of the parameter. + auto& param = expr->params()[0]; + if (!DetermineResultType(param.get())) { + return false; + } + expr->func()->set_result_type(param->result_type()->UnwrapPtrIfNeeded()); + return true; + } + if (name == "any" || name == "all") { + expr->func()->set_result_type( + ctx_.type_mgr().Get(std::make_unique())); + return true; + } + if (IsFloatIntrinsic(name)) { + if (expr->params().size() != 1) { + set_error(expr->source(), "incorrect number of parameters for " + name); + return false; + } + + auto* bool_type = + ctx_.type_mgr().Get(std::make_unique()); + + auto* param_type = expr->params()[0]->result_type()->UnwrapPtrIfNeeded(); + if (param_type->IsVector()) { + expr->func()->set_result_type( + ctx_.type_mgr().Get(std::make_unique( + bool_type, param_type->AsVector()->size()))); + } else { + expr->func()->set_result_type(bool_type); + } + return true; + } + if (name == "dot") { + expr->func()->set_result_type( + ctx_.type_mgr().Get(std::make_unique())); + return true; + } + if (name == "outer_product") { + if (expr->params().size() != 2) { + set_error(expr->source(), + "incorrect number of parameters for outer_product"); + return false; + } + + auto* param0_type = expr->params()[0]->result_type()->UnwrapPtrIfNeeded(); + auto* param1_type = expr->params()[1]->result_type()->UnwrapPtrIfNeeded(); + if (!param0_type->IsVector() || !param1_type->IsVector()) { + set_error(expr->source(), "invalid parameter type for outer_product"); + return false; + } + + expr->func()->set_result_type( + ctx_.type_mgr().Get(std::make_unique( + ctx_.type_mgr().Get(std::make_unique()), + param0_type->AsVector()->size(), param1_type->AsVector()->size()))); + return true; + } + + return false; +} + bool TypeDeterminer::DetermineCast(ast::CastExpression* expr) { if (!DetermineResultType(expr->expr())) { return false; @@ -550,77 +634,6 @@ bool TypeDeterminer::DetermineBinary(ast::BinaryExpression* expr) { return false; } -bool TypeDeterminer::DetermineUnaryDerivative( - ast::UnaryDerivativeExpression* expr) { - // The result type must be the same as the type of the parameter. - if (!DetermineResultType(expr->param())) { - return false; - } - expr->set_result_type(expr->param()->result_type()->UnwrapPtrIfNeeded()); - return true; -} - -bool TypeDeterminer::DetermineUnaryMethod(ast::UnaryMethodExpression* expr) { - if (!DetermineResultType(expr->params())) { - return false; - } - - switch (expr->op()) { - case ast::UnaryMethod::kAny: - case ast::UnaryMethod::kAll: { - expr->set_result_type( - ctx_.type_mgr().Get(std::make_unique())); - break; - } - case ast::UnaryMethod::kIsNan: - case ast::UnaryMethod::kIsInf: - case ast::UnaryMethod::kIsFinite: - case ast::UnaryMethod::kIsNormal: { - if (expr->params().empty()) { - set_error(expr->source(), "incorrect number of parameters"); - return false; - } - - auto* bool_type = - ctx_.type_mgr().Get(std::make_unique()); - auto* param_type = expr->params()[0]->result_type()->UnwrapPtrIfNeeded(); - if (param_type->IsVector()) { - expr->set_result_type( - ctx_.type_mgr().Get(std::make_unique( - bool_type, param_type->AsVector()->size()))); - } else { - expr->set_result_type(bool_type); - } - break; - } - case ast::UnaryMethod::kDot: { - expr->set_result_type( - ctx_.type_mgr().Get(std::make_unique())); - break; - } - case ast::UnaryMethod::kOuterProduct: { - if (expr->params().size() != 2) { - set_error(expr->source(), - "incorrect number of parameters for outer product"); - return false; - } - auto* param0_type = expr->params()[0]->result_type()->UnwrapPtrIfNeeded(); - auto* param1_type = expr->params()[1]->result_type()->UnwrapPtrIfNeeded(); - if (!param0_type->IsVector() || !param1_type->IsVector()) { - set_error(expr->source(), "invalid parameter type for outer product"); - return false; - } - expr->set_result_type( - ctx_.type_mgr().Get(std::make_unique( - ctx_.type_mgr().Get(std::make_unique()), - param0_type->AsVector()->size(), - param1_type->AsVector()->size()))); - break; - } - } - return true; -} - bool TypeDeterminer::DetermineUnaryOp(ast::UnaryOpExpression* expr) { // Result type matches the parameter type. if (!DetermineResultType(expr->expr())) { diff --git a/src/type_determiner.h b/src/type_determiner.h index 770e00bb75..7f62a57c51 100644 --- a/src/type_determiner.h +++ b/src/type_determiner.h @@ -34,8 +34,6 @@ class ConstructorExpression; class Function; class IdentifierExpression; class MemberAccessorExpression; -class UnaryDerivativeExpression; -class UnaryMethodExpression; class UnaryOpExpression; class Variable; @@ -114,9 +112,8 @@ class TypeDeterminer { bool DetermineCast(ast::CastExpression* expr); bool DetermineConstructor(ast::ConstructorExpression* expr); bool DetermineIdentifier(ast::IdentifierExpression* expr); + bool DetermineIntrinsic(const std::string& name, ast::CallExpression* expr); bool DetermineMemberAccessor(ast::MemberAccessorExpression* expr); - bool DetermineUnaryDerivative(ast::UnaryDerivativeExpression* expr); - bool DetermineUnaryMethod(ast::UnaryMethodExpression* expr); bool DetermineUnaryOp(ast::UnaryOpExpression* expr); Context& ctx_; diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc index bb44112c89..5104709932 100644 --- a/src/type_determiner_test.cc +++ b/src/type_determiner_test.cc @@ -51,8 +51,6 @@ #include "src/ast/type/struct_type.h" #include "src/ast/type/vector_type.h" #include "src/ast/type_constructor_expression.h" -#include "src/ast/unary_derivative_expression.h" -#include "src/ast/unary_method_expression.h" #include "src/ast/unary_op_expression.h" #include "src/ast/unless_statement.h" #include "src/ast/variable_decl_statement.h" @@ -1369,13 +1367,34 @@ TEST_F(TypeDeterminerTest, Expr_Binary_Multiply_Matrix_Matrix) { EXPECT_EQ(mat->columns(), 4u); } -using UnaryDerivativeExpressionTest = - TypeDeterminerTestWithParam; -TEST_P(UnaryDerivativeExpressionTest, Expr_UnaryDerivative) { - auto derivative = GetParam(); +using IntrinsicDerivativeTest = TypeDeterminerTestWithParam; +TEST_P(IntrinsicDerivativeTest, Scalar) { + auto name = GetParam(); ast::type::F32Type f32; + auto var = + std::make_unique("ident", ast::StorageClass::kNone, &f32); + mod()->AddGlobalVariable(std::move(var)); + + // Register the global + EXPECT_TRUE(td()->Determine()); + + ast::ExpressionList call_params; + call_params.push_back(std::make_unique("ident")); + + ast::CallExpression expr(std::make_unique(name), + std::move(call_params)); + EXPECT_TRUE(td()->DetermineResultType(&expr)); + + ASSERT_NE(expr.result_type(), nullptr); + ASSERT_TRUE(expr.result_type()->IsF32()); +} + +TEST_P(IntrinsicDerivativeTest, Vector) { + auto name = GetParam(); + + ast::type::F32Type f32; ast::type::VectorType vec4(&f32, 4); auto var = @@ -1385,25 +1404,75 @@ TEST_P(UnaryDerivativeExpressionTest, Expr_UnaryDerivative) { // Register the global EXPECT_TRUE(td()->Determine()); - ast::UnaryDerivativeExpression der( - derivative, ast::DerivativeModifier::kNone, - std::make_unique("ident")); - EXPECT_TRUE(td()->DetermineResultType(&der)); - ASSERT_NE(der.result_type(), nullptr); - ASSERT_TRUE(der.result_type()->IsVector()); - EXPECT_TRUE(der.result_type()->AsVector()->type()->IsF32()); - EXPECT_EQ(der.result_type()->AsVector()->size(), 4u); + ast::ExpressionList call_params; + call_params.push_back(std::make_unique("ident")); + + ast::CallExpression expr(std::make_unique(name), + std::move(call_params)); + EXPECT_TRUE(td()->DetermineResultType(&expr)); + + ASSERT_NE(expr.result_type(), nullptr); + ASSERT_TRUE(expr.result_type()->IsVector()); + EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsF32()); + EXPECT_EQ(expr.result_type()->AsVector()->size(), 4u); +} + +TEST_P(IntrinsicDerivativeTest, MissingParam) { + auto name = GetParam(); + + ast::type::F32Type f32; + ast::type::VectorType vec4(&f32, 4); + + // Register the global + EXPECT_TRUE(td()->Determine()); + + ast::ExpressionList call_params; + ast::CallExpression expr(std::make_unique(name), + std::move(call_params)); + EXPECT_FALSE(td()->DetermineResultType(&expr)); + EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name); +} + +TEST_P(IntrinsicDerivativeTest, ToomManyParams) { + auto name = GetParam(); + + ast::type::F32Type f32; + ast::type::VectorType vec4(&f32, 4); + + auto var1 = std::make_unique("ident1", + ast::StorageClass::kNone, &vec4); + auto var2 = std::make_unique("ident2", + ast::StorageClass::kNone, &vec4); + mod()->AddGlobalVariable(std::move(var1)); + mod()->AddGlobalVariable(std::move(var2)); + + // Register the global + EXPECT_TRUE(td()->Determine()); + + ast::ExpressionList call_params; + call_params.push_back(std::make_unique("ident1")); + call_params.push_back(std::make_unique("ident2")); + + ast::CallExpression expr(std::make_unique(name), + std::move(call_params)); + EXPECT_FALSE(td()->DetermineResultType(&expr)); + EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name); } INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest, - UnaryDerivativeExpressionTest, - testing::Values(ast::UnaryDerivative::kDpdx, - ast::UnaryDerivative::kDpdy, - ast::UnaryDerivative::kFwidth)); + IntrinsicDerivativeTest, + testing::Values("dpdx", + "dpdx_coarse", + "dpdx_fine", + "dpdy", + "dpdy_coarse", + "dpdy_fine", + "fwidth", + "fwidth_coarse", + "fwidth_fine")); -using UnaryMethodExpressionBoolTest = - TypeDeterminerTestWithParam; -TEST_P(UnaryMethodExpressionBoolTest, Expr_UnaryMethod_Any) { - auto op = GetParam(); +using Intrinsic = TypeDeterminerTestWithParam; +TEST_P(Intrinsic, Test) { + auto name = GetParam(); ast::type::BoolType bool_type; ast::type::VectorType vec3(&bool_type, 3); @@ -1412,27 +1481,26 @@ TEST_P(UnaryMethodExpressionBoolTest, Expr_UnaryMethod_Any) { &vec3); mod()->AddGlobalVariable(std::move(var)); - ast::ExpressionList params; - params.push_back(std::make_unique("my_var")); + ast::ExpressionList call_params; + call_params.push_back(std::make_unique("my_var")); - ast::UnaryMethodExpression exp(op, std::move(params)); + ast::CallExpression expr(std::make_unique(name), + std::move(call_params)); // Register the variable EXPECT_TRUE(td()->Determine()); - EXPECT_TRUE(td()->DetermineResultType(&exp)); - ASSERT_NE(exp.result_type(), nullptr); - EXPECT_TRUE(exp.result_type()->IsBool()); + EXPECT_TRUE(td()->DetermineResultType(&expr)); + ASSERT_NE(expr.result_type(), nullptr); + EXPECT_TRUE(expr.result_type()->IsBool()); } INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest, - UnaryMethodExpressionBoolTest, - testing::Values(ast::UnaryMethod::kAny, - ast::UnaryMethod::kAll)); + Intrinsic, + testing::Values("any", "all")); -using UnaryMethodExpressionVecTest = - TypeDeterminerTestWithParam; -TEST_P(UnaryMethodExpressionVecTest, Expr_UnaryMethod_Bool) { - auto op = GetParam(); +using Intrinsic_FloatMethod = TypeDeterminerTestWithParam; +TEST_P(Intrinsic_FloatMethod, Vector) { + auto name = GetParam(); ast::type::F32Type f32; ast::type::VectorType vec3(&f32, 3); @@ -1441,22 +1509,24 @@ TEST_P(UnaryMethodExpressionVecTest, Expr_UnaryMethod_Bool) { &vec3); mod()->AddGlobalVariable(std::move(var)); - ast::ExpressionList params; - params.push_back(std::make_unique("my_var")); + ast::ExpressionList call_params; + call_params.push_back(std::make_unique("my_var")); - ast::UnaryMethodExpression exp(op, std::move(params)); + ast::CallExpression expr(std::make_unique(name), + std::move(call_params)); // Register the variable EXPECT_TRUE(td()->Determine()); + EXPECT_TRUE(td()->DetermineResultType(&expr)); - EXPECT_TRUE(td()->DetermineResultType(&exp)); - ASSERT_NE(exp.result_type(), nullptr); - ASSERT_TRUE(exp.result_type()->IsVector()); - EXPECT_TRUE(exp.result_type()->AsVector()->type()->IsBool()); - EXPECT_EQ(exp.result_type()->AsVector()->size(), 3u); + ASSERT_NE(expr.result_type(), nullptr); + ASSERT_TRUE(expr.result_type()->IsVector()); + EXPECT_TRUE(expr.result_type()->AsVector()->type()->IsBool()); + EXPECT_EQ(expr.result_type()->AsVector()->size(), 3u); } -TEST_P(UnaryMethodExpressionVecTest, Expr_UnaryMethod_Vec) { - auto op = GetParam(); + +TEST_P(Intrinsic_FloatMethod, Scalar) { + auto name = GetParam(); ast::type::F32Type f32; @@ -1464,26 +1534,65 @@ TEST_P(UnaryMethodExpressionVecTest, Expr_UnaryMethod_Vec) { std::make_unique("my_var", ast::StorageClass::kNone, &f32); mod()->AddGlobalVariable(std::move(var)); - ast::ExpressionList params; - params.push_back(std::make_unique("my_var")); + ast::ExpressionList call_params; + call_params.push_back(std::make_unique("my_var")); - ast::UnaryMethodExpression exp(op, std::move(params)); + ast::CallExpression expr(std::make_unique(name), + std::move(call_params)); // Register the variable EXPECT_TRUE(td()->Determine()); - - EXPECT_TRUE(td()->DetermineResultType(&exp)); - ASSERT_NE(exp.result_type(), nullptr); - EXPECT_TRUE(exp.result_type()->IsBool()); + EXPECT_TRUE(td()->DetermineResultType(&expr)); + ASSERT_NE(expr.result_type(), nullptr); + EXPECT_TRUE(expr.result_type()->IsBool()); } -INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest, - UnaryMethodExpressionVecTest, - testing::Values(ast::UnaryMethod::kIsInf, - ast::UnaryMethod::kIsNan, - ast::UnaryMethod::kIsFinite, - ast::UnaryMethod::kIsNormal)); -TEST_F(TypeDeterminerTest, Expr_UnaryMethod_Dot) { +TEST_P(Intrinsic_FloatMethod, MissingParam) { + auto name = GetParam(); + + ast::type::F32Type f32; + + auto var = + std::make_unique("my_var", ast::StorageClass::kNone, &f32); + mod()->AddGlobalVariable(std::move(var)); + + ast::ExpressionList call_params; + ast::CallExpression expr(std::make_unique(name), + std::move(call_params)); + + // Register the variable + EXPECT_TRUE(td()->Determine()); + EXPECT_FALSE(td()->DetermineResultType(&expr)); + EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name); +} + +TEST_P(Intrinsic_FloatMethod, TooManyParams) { + auto name = GetParam(); + + ast::type::F32Type f32; + + auto var = + std::make_unique("my_var", ast::StorageClass::kNone, &f32); + mod()->AddGlobalVariable(std::move(var)); + + ast::ExpressionList call_params; + call_params.push_back(std::make_unique("my_var")); + call_params.push_back(std::make_unique("my_var")); + + ast::CallExpression expr(std::make_unique(name), + std::move(call_params)); + + // Register the variable + EXPECT_TRUE(td()->Determine()); + EXPECT_FALSE(td()->DetermineResultType(&expr)); + EXPECT_EQ(td()->error(), "incorrect number of parameters for " + name); +} +INSTANTIATE_TEST_SUITE_P( + TypeDeterminerTest, + Intrinsic_FloatMethod, + testing::Values("is_inf", "is_nan", "is_finite", "is_normal")); + +TEST_F(TypeDeterminerTest, Intrinsic_Dot) { ast::type::F32Type f32; ast::type::VectorType vec3(&f32, 3); @@ -1491,21 +1600,21 @@ TEST_F(TypeDeterminerTest, Expr_UnaryMethod_Dot) { &vec3); mod()->AddGlobalVariable(std::move(var)); - ast::ExpressionList params; - params.push_back(std::make_unique("my_var")); - params.push_back(std::make_unique("my_var")); + ast::ExpressionList call_params; + call_params.push_back(std::make_unique("my_var")); + call_params.push_back(std::make_unique("my_var")); - ast::UnaryMethodExpression exp(ast::UnaryMethod::kDot, std::move(params)); + ast::CallExpression expr(std::make_unique("dot"), + std::move(call_params)); // Register the variable EXPECT_TRUE(td()->Determine()); - - EXPECT_TRUE(td()->DetermineResultType(&exp)); - ASSERT_NE(exp.result_type(), nullptr); - EXPECT_TRUE(exp.result_type()->IsF32()); + EXPECT_TRUE(td()->DetermineResultType(&expr)); + ASSERT_NE(expr.result_type(), nullptr); + EXPECT_TRUE(expr.result_type()->IsF32()); } -TEST_F(TypeDeterminerTest, Expr_UnaryMethod_OuterProduct) { +TEST_F(TypeDeterminerTest, Intrinsic_OuterProduct) { ast::type::F32Type f32; ast::type::VectorType vec3(&f32, 3); ast::type::VectorType vec2(&f32, 2); @@ -1517,25 +1626,73 @@ TEST_F(TypeDeterminerTest, Expr_UnaryMethod_OuterProduct) { mod()->AddGlobalVariable(std::move(var1)); mod()->AddGlobalVariable(std::move(var2)); - ast::ExpressionList params; - params.push_back(std::make_unique("v3")); - params.push_back(std::make_unique("v2")); + ast::ExpressionList call_params; + call_params.push_back(std::make_unique("v3")); + call_params.push_back(std::make_unique("v2")); - ast::UnaryMethodExpression exp(ast::UnaryMethod::kOuterProduct, - std::move(params)); + ast::CallExpression expr( + std::make_unique("outer_product"), + std::move(call_params)); // Register the variable EXPECT_TRUE(td()->Determine()); + EXPECT_TRUE(td()->DetermineResultType(&expr)); - EXPECT_TRUE(td()->DetermineResultType(&exp)); - ASSERT_NE(exp.result_type(), nullptr); - ASSERT_TRUE(exp.result_type()->IsMatrix()); - auto* mat = exp.result_type()->AsMatrix(); + ASSERT_NE(expr.result_type(), nullptr); + ASSERT_TRUE(expr.result_type()->IsMatrix()); + + auto* mat = expr.result_type()->AsMatrix(); EXPECT_TRUE(mat->type()->IsF32()); EXPECT_EQ(mat->rows(), 3u); EXPECT_EQ(mat->columns(), 2u); } +TEST_F(TypeDeterminerTest, Intrinsic_OuterProduct_TooFewParams) { + ast::type::F32Type f32; + ast::type::VectorType vec3(&f32, 3); + ast::type::VectorType vec2(&f32, 2); + + auto var2 = + std::make_unique("v2", ast::StorageClass::kNone, &vec2); + mod()->AddGlobalVariable(std::move(var2)); + + ast::ExpressionList call_params; + call_params.push_back(std::make_unique("v2")); + + ast::CallExpression expr( + std::make_unique("outer_product"), + std::move(call_params)); + + // Register the variable + EXPECT_TRUE(td()->Determine()); + EXPECT_FALSE(td()->DetermineResultType(&expr)); + EXPECT_EQ(td()->error(), "incorrect number of parameters for outer_product"); +} + +TEST_F(TypeDeterminerTest, Intrinsic_OuterProduct_TooManyParams) { + ast::type::F32Type f32; + ast::type::VectorType vec3(&f32, 3); + ast::type::VectorType vec2(&f32, 2); + + auto var2 = + std::make_unique("v2", ast::StorageClass::kNone, &vec2); + mod()->AddGlobalVariable(std::move(var2)); + + ast::ExpressionList call_params; + call_params.push_back(std::make_unique("v2")); + call_params.push_back(std::make_unique("v2")); + call_params.push_back(std::make_unique("v2")); + + ast::CallExpression expr( + std::make_unique("outer_product"), + std::move(call_params)); + + // Register the variable + EXPECT_TRUE(td()->Determine()); + EXPECT_FALSE(td()->DetermineResultType(&expr)); + EXPECT_EQ(td()->error(), "incorrect number of parameters for outer_product"); +} + using UnaryOpExpressionTest = TypeDeterminerTestWithParam; TEST_P(UnaryOpExpressionTest, Expr_UnaryOp) { auto op = GetParam(); diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc index e3ddcebcd5..c83759e5c0 100644 --- a/src/writer/wgsl/generator_impl.cc +++ b/src/writer/wgsl/generator_impl.cc @@ -54,8 +54,6 @@ #include "src/ast/type/vector_type.h" #include "src/ast/type_constructor_expression.h" #include "src/ast/uint_literal.h" -#include "src/ast/unary_derivative_expression.h" -#include "src/ast/unary_method_expression.h" #include "src/ast/unary_op_expression.h" #include "src/ast/unless_statement.h" #include "src/ast/variable_decl_statement.h" @@ -166,12 +164,6 @@ bool GeneratorImpl::EmitExpression(ast::Expression* expr) { if (expr->IsMemberAccessor()) { return EmitMemberAccessor(expr->AsMemberAccessor()); } - if (expr->IsUnaryDerivative()) { - return EmitUnaryDerivative(expr->AsUnaryDerivative()); - } - if (expr->IsUnaryMethod()) { - return EmitUnaryMethod(expr->AsUnaryMethod()); - } if (expr->IsUnaryOp()) { return EmitUnaryOp(expr->AsUnaryOp()); } @@ -595,78 +587,6 @@ bool GeneratorImpl::EmitBinary(ast::BinaryExpression* expr) { return true; } -bool GeneratorImpl::EmitUnaryDerivative(ast::UnaryDerivativeExpression* expr) { - switch (expr->op()) { - case ast::UnaryDerivative::kDpdx: - out_ << "dpdx"; - break; - case ast::UnaryDerivative::kDpdy: - out_ << "dpdy"; - break; - case ast::UnaryDerivative::kFwidth: - out_ << "fwidth"; - break; - } - - if (expr->modifier() != ast::DerivativeModifier::kNone) { - out_ << "<" << expr->modifier() << ">"; - } - - out_ << "("; - - if (!EmitExpression(expr->param())) { - return false; - } - - out_ << ")"; - return true; -} - -bool GeneratorImpl::EmitUnaryMethod(ast::UnaryMethodExpression* expr) { - switch (expr->op()) { - case ast::UnaryMethod::kAny: - out_ << "any"; - break; - case ast::UnaryMethod::kAll: - out_ << "all"; - break; - case ast::UnaryMethod::kIsNan: - out_ << "is_nan"; - break; - case ast::UnaryMethod::kIsInf: - out_ << "is_inf"; - break; - case ast::UnaryMethod::kIsFinite: - out_ << "is_finite"; - break; - case ast::UnaryMethod::kIsNormal: - out_ << "is_normal"; - break; - case ast::UnaryMethod::kDot: - out_ << "dot"; - break; - case ast::UnaryMethod::kOuterProduct: - out_ << "outer_product"; - break; - } - out_ << "("; - - bool first = true; - for (const auto& param : expr->params()) { - if (!first) { - out_ << ", "; - } - first = false; - - if (!EmitExpression(param.get())) { - return false; - } - } - out_ << ")"; - - return true; -} - bool GeneratorImpl::EmitUnaryOp(ast::UnaryOpExpression* expr) { switch (expr->op()) { case ast::UnaryOp::kNot: diff --git a/src/writer/wgsl/generator_impl.h b/src/writer/wgsl/generator_impl.h index d9282bd14d..b262a6d4cd 100644 --- a/src/writer/wgsl/generator_impl.h +++ b/src/writer/wgsl/generator_impl.h @@ -190,14 +190,6 @@ class GeneratorImpl { /// @param expr the type constructor expression /// @returns true if the constructor is emitted bool EmitTypeConstructor(ast::TypeConstructorExpression* expr); - /// Handles a unary derivative expression - /// @param expr the expression to emit - /// @returns true if the expression was emitted - bool EmitUnaryDerivative(ast::UnaryDerivativeExpression* expr); - /// Handles a unary method expression - /// @param expr the expression to emit - /// @returns true if the expression was emitted - bool EmitUnaryMethod(ast::UnaryMethodExpression* expr); /// Handles a unary op expression /// @param expr the expression to emit /// @returns true if the expression was emitted diff --git a/src/writer/wgsl/generator_impl_unary_derivative_test.cc b/src/writer/wgsl/generator_impl_unary_derivative_test.cc deleted file mode 100644 index b7af8dc1eb..0000000000 --- a/src/writer/wgsl/generator_impl_unary_derivative_test.cc +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include "gtest/gtest.h" -#include "src/ast/identifier_expression.h" -#include "src/ast/unary_derivative_expression.h" -#include "src/writer/wgsl/generator_impl.h" - -namespace tint { -namespace writer { -namespace wgsl { -namespace { - -struct UnaryDerivativeData { - const char* name; - ast::UnaryDerivative derivative; -}; -inline std::ostream& operator<<(std::ostream& out, UnaryDerivativeData data) { - out << data.derivative; - return out; -} -using UnaryDerivativeTest = testing::TestWithParam; -TEST_P(UnaryDerivativeTest, Emit_ModifierNone) { - auto params = GetParam(); - - auto expr = std::make_unique("expr"); - - ast::UnaryDerivativeExpression derivative( - params.derivative, ast::DerivativeModifier::kNone, std::move(expr)); - - GeneratorImpl g; - ASSERT_TRUE(g.EmitExpression(&derivative)) << g.error(); - EXPECT_EQ(g.result(), std::string(params.name) + "(expr)"); -} -TEST_P(UnaryDerivativeTest, Emit_ModifierFine) { - auto params = GetParam(); - - auto expr = std::make_unique("expr"); - - ast::UnaryDerivativeExpression derivative( - params.derivative, ast::DerivativeModifier::kFine, std::move(expr)); - - GeneratorImpl g; - ASSERT_TRUE(g.EmitExpression(&derivative)) << g.error(); - EXPECT_EQ(g.result(), std::string(params.name) + "(expr)"); -} -TEST_P(UnaryDerivativeTest, Emit_ModifierCoarse) { - auto params = GetParam(); - - auto expr = std::make_unique("expr"); - - ast::UnaryDerivativeExpression derivative( - params.derivative, ast::DerivativeModifier::kCoarse, std::move(expr)); - - GeneratorImpl g; - ASSERT_TRUE(g.EmitExpression(&derivative)) << g.error(); - EXPECT_EQ(g.result(), std::string(params.name) + "(expr)"); -} -INSTANTIATE_TEST_SUITE_P( - GeneratorImplTest, - UnaryDerivativeTest, - testing::Values(UnaryDerivativeData{"dpdx", ast::UnaryDerivative::kDpdx}, - UnaryDerivativeData{"dpdy", ast::UnaryDerivative::kDpdy}, - UnaryDerivativeData{"fwidth", - ast::UnaryDerivative::kFwidth})); - -} // namespace -} // namespace wgsl -} // namespace writer -} // namespace tint diff --git a/src/writer/wgsl/generator_impl_unary_method_test.cc b/src/writer/wgsl/generator_impl_unary_method_test.cc deleted file mode 100644 index 83eff87594..0000000000 --- a/src/writer/wgsl/generator_impl_unary_method_test.cc +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include "gtest/gtest.h" -#include "src/ast/identifier_expression.h" -#include "src/ast/unary_method_expression.h" -#include "src/writer/wgsl/generator_impl.h" - -namespace tint { -namespace writer { -namespace wgsl { -namespace { - -struct UnaryMethodData { - const char* name; - ast::UnaryMethod method; -}; -inline std::ostream& operator<<(std::ostream& out, UnaryMethodData data) { - out << data.method; - return out; -} -using UnaryMethodTest = testing::TestWithParam; -TEST_P(UnaryMethodTest, Emit) { - auto params = GetParam(); - - auto expr = std::make_unique("expr"); - ast::ExpressionList ops; - ops.push_back(std::move(expr)); - - ast::UnaryMethodExpression method(params.method, std::move(ops)); - - GeneratorImpl g; - ASSERT_TRUE(g.EmitExpression(&method)) << g.error(); - EXPECT_EQ(g.result(), std::string(params.name) + "(expr)"); -} -INSTANTIATE_TEST_SUITE_P( - GeneratorImplTest, - UnaryMethodTest, - testing::Values(UnaryMethodData{"any", ast::UnaryMethod::kAny}, - UnaryMethodData{"all", ast::UnaryMethod::kAll}, - UnaryMethodData{"is_nan", ast::UnaryMethod::kIsNan}, - UnaryMethodData{"is_finite", ast::UnaryMethod::kIsFinite}, - UnaryMethodData{"is_normal", ast::UnaryMethod::kIsNormal})); - -using UnaryMethodTest_MultiParam = testing::TestWithParam; -TEST_P(UnaryMethodTest_MultiParam, Emit) { - auto params = GetParam(); - - auto expr1 = std::make_unique("expr1"); - auto expr2 = std::make_unique("expr2"); - ast::ExpressionList ops; - ops.push_back(std::move(expr1)); - ops.push_back(std::move(expr2)); - - ast::UnaryMethodExpression method(params.method, std::move(ops)); - - GeneratorImpl g; - ASSERT_TRUE(g.EmitExpression(&method)) << g.error(); - EXPECT_EQ(g.result(), std::string(params.name) + "(expr1, expr2)"); -} -INSTANTIATE_TEST_SUITE_P( - GeneratorImplTest, - UnaryMethodTest_MultiParam, - testing::Values(UnaryMethodData{"dot", ast::UnaryMethod::kDot}, - UnaryMethodData{"outer_product", - ast::UnaryMethod::kOuterProduct})); - -} // namespace -} // namespace wgsl -} // namespace writer -} // namespace tint