diff --git a/Source/WebGPU/WGSL/Lexer.cpp b/Source/WebGPU/WGSL/Lexer.cpp index f04138cc2609..3553cde678d6 100644 --- a/Source/WebGPU/WGSL/Lexer.cpp +++ b/Source/WebGPU/WGSL/Lexer.cpp @@ -76,10 +76,18 @@ Token Lexer::lex() return makeToken(TokenType::Equal); case '>': shift(); - return makeToken(TokenType::GT); + if (m_current == '>') { + shift(); + return makeToken(TokenType::GtGt); + } + return makeToken(TokenType::Gt); case '<': shift(); - return makeToken(TokenType::LT); + if (m_current == '<') { + shift(); + return makeToken(TokenType::LtLt); + } + return makeToken(TokenType::Lt); case '@': shift(); return makeToken(TokenType::Attribute); @@ -116,7 +124,6 @@ Token Lexer::lex() return makeToken(TokenType::MinusMinus); } return makeToken(TokenType::Minus); - break; case '+': shift(); if (m_current == '+') { @@ -124,7 +131,6 @@ Token Lexer::lex() return makeToken(TokenType::PlusPlus); } return makeToken(TokenType::Plus); - break; case '0': { shift(); double literalValue = 0; diff --git a/Source/WebGPU/WGSL/Parser.cpp b/Source/WebGPU/WGSL/Parser.cpp index 32e6eff9b654..b7603a0155df 100644 --- a/Source/WebGPU/WGSL/Parser.cpp +++ b/Source/WebGPU/WGSL/Parser.cpp @@ -111,6 +111,29 @@ namespace WGSL { } \ } while (false) +static bool canContinueMultiplicativeExpression(const Token& token) +{ + switch (token.m_type) { + case TokenType::Modulo: + case TokenType::Slash: + case TokenType::Star: + return true; + default: + return false; + } +} + +static bool canContinueAdditiveExpression(const Token& token) +{ + switch (token.m_type) { + case TokenType::Minus: + case TokenType::Plus: + return true; + default: + return canContinueMultiplicativeExpression(token); + } +} + template std::optional parse(ShaderModule& shaderModule) { @@ -361,9 +384,9 @@ template Expected Parser::parseTypeNameAfterIdentifier(AST::Identifier&& name, SourcePosition _startOfElementPosition) { if (auto kind = AST::ParameterizedTypeName::stringViewToKind(name.id())) { - CONSUME_TYPE(LT); + CONSUME_TYPE(Lt); PARSE(elementType, TypeName); - CONSUME_TYPE(GT); + CONSUME_TYPE(Gt); RETURN_NODE_REF(ParameterizedTypeName, *kind, WTFMove(elementType)); } RETURN_NODE_REF(NamedTypeName, WTFMove(name)); @@ -379,7 +402,7 @@ Expected Parser::parseArrayType() AST::TypeName::Ptr maybeElementType; AST::Expression::Ptr maybeElementCount; - if (current().m_type == TokenType::LT) { + if (current().m_type == TokenType::Lt) { // We differ from the WGSL grammar here by allowing the type to be optional, // which allows us to use `parseArrayType` in `parseCallExpression`. consume(); @@ -395,10 +418,10 @@ Expected Parser::parseArrayType() // The WGSL grammar doesn't specify expression operator precedence so // until then just parse AdditiveExpression. PARSE(elementCountLHS, UnaryExpression); - PARSE(elementCount, AdditiveExpression, WTFMove(elementCountLHS)); + PARSE(elementCount, AdditiveExpressionPostUnary, WTFMove(elementCountLHS)); maybeElementCount = elementCount.moveToUniquePtr(); } - CONSUME_TYPE(GT); + CONSUME_TYPE(Gt); } RETURN_NODE_REF(ArrayTypeName, WTFMove(maybeElementType), WTFMove(maybeElementCount)); @@ -418,7 +441,7 @@ Expected Parser::parseVariableWithAttributes(A CONSUME_TYPE(KeywordVar); std::unique_ptr maybeQualifier = nullptr; - if (current().m_type == TokenType::LT) { + if (current().m_type == TokenType::Lt) { PARSE(variableQualifier, VariableQualifier); maybeQualifier = WTF::makeUnique(WTFMove(variableQualifier)); } @@ -447,7 +470,7 @@ Expected Parser::parseVariableQualifier() { START_PARSE(); - CONSUME_TYPE(LT); + CONSUME_TYPE(Lt); PARSE(storageClass, StorageClass); // FIXME: verify that Read is the correct default in all cases. @@ -458,7 +481,7 @@ Expected Parser::parseVariableQualifier() accessMode = actualAccessMode; } - CONSUME_TYPE(GT); + CONSUME_TYPE(Gt); RETURN_NODE(VariableQualifier, storageClass, accessMode); } @@ -631,46 +654,63 @@ Expected Parser::parseReturnStatement() } template -Expected, Error> Parser::parseRelationalExpression(AST::Expression::Ref&& lhs) +Expected, Error> Parser::parseRelationalExpressionPostUnary(AST::Expression::Ref&& lhs) { // FIXME: fill in - return parseShiftExpression(WTFMove(lhs)); + return parseShiftExpressionPostUnary(WTFMove(lhs)); } template -Expected, Error> Parser::parseShiftExpression(AST::Expression::Ref&& lhs) +Expected, Error> Parser::parseShiftExpressionPostUnary(AST::Expression::Ref&& lhs) { - // FIXME: fill in - return parseAdditiveExpression(WTFMove(lhs)); -} + if (canContinueAdditiveExpression(current())) + return parseAdditiveExpressionPostUnary(WTFMove(lhs)); -template -Expected Parser::parseAdditiveOperator() -{ START_PARSE(); - switch (current().m_type) { - case TokenType::Minus: + case TokenType::GtGt: { consume(); - return AST::BinaryOperation::Subtract; - case TokenType::Plus: + PARSE(rhs, UnaryExpression); + RETURN_NODE_UNIQUE_REF(BinaryExpression, WTFMove(lhs), WTFMove(rhs), AST::BinaryOperation::RightShift); + } + + case TokenType::LtLt: { consume(); - return AST::BinaryOperation::Add; + PARSE(rhs, UnaryExpression); + RETURN_NODE_UNIQUE_REF(BinaryExpression, WTFMove(lhs), WTFMove(rhs), AST::BinaryOperation::LeftShift); + } + default: - FAIL("Expected one of + or -"_s); + return WTFMove(lhs); } } template -Expected, Error> Parser::parseAdditiveExpression(AST::Expression::Ref&& lhs) +Expected, Error> Parser::parseAdditiveExpressionPostUnary(AST::Expression::Ref&& lhs) { START_PARSE(); - PARSE_MOVE(lhs, MultiplicativeExpression, WTFMove(lhs)); + PARSE_MOVE(lhs, MultiplicativeExpressionPostUnary, WTFMove(lhs)); + + while (canContinueAdditiveExpression(current())) { + auto op = AST::BinaryOperation::Add; + switch (current().m_type) { + case TokenType::Minus: + op = AST::BinaryOperation::Subtract; + break; + + case TokenType::Plus: + op = AST::BinaryOperation::Add; + break; + + default: + // parseMultiplicativeExpression handles multiplicative operators so + // token should be PLUS or MINUS. + RELEASE_ASSERT_NOT_REACHED_WITH_MESSAGE("Expected + or -"); + } - while (current().m_type == TokenType::Plus || current().m_type == TokenType::Minus) { - PARSE(op, AdditiveOperator); + consume(); PARSE(unary, UnaryExpression); - PARSE(rhs, MultiplicativeExpression, WTFMove(unary)); + PARSE(rhs, MultiplicativeExpressionPostUnary, WTFMove(unary)); lhs = MAKE_NODE_UNIQUE_REF(BinaryExpression, WTFMove(lhs), WTFMove(rhs), op); } @@ -678,32 +718,29 @@ Expected, Error> Parser::parseAdditiveExpressi } template -Expected Parser::parseMultiplicativeOperator() +Expected, Error> Parser::parseMultiplicativeExpressionPostUnary(AST::Expression::Ref&& lhs) { START_PARSE(); - switch (current().m_type) { - case TokenType::Modulo: - consume(); - return AST::BinaryOperation::Modulo; - case TokenType::Slash: - consume(); - return AST::BinaryOperation::Divide; - case TokenType::Star: - consume(); - return AST::BinaryOperation::Multiply; - default: - FAIL("Expected one of %, / or *"_s); - } -} + while (canContinueMultiplicativeExpression(current())) { + auto op = AST::BinaryOperation::Multiply; + switch (current().m_type) { + case TokenType::Modulo: + op = AST::BinaryOperation::Modulo; + break; -template -Expected, Error> Parser::parseMultiplicativeExpression(AST::Expression::Ref&& lhs) -{ - START_PARSE(); - while (current().m_type == TokenType::Modulo - || current().m_type == TokenType::Slash - || current().m_type == TokenType::Star) { - PARSE(op, MultiplicativeOperator) + case TokenType::Slash: + op = AST::BinaryOperation::Divide; + break; + + case TokenType::Star: + op = AST::BinaryOperation::Multiply; + break; + + default: + RELEASE_ASSERT_NOT_REACHED(); + } + + consume(); PARSE(rhs, UnaryExpression); lhs = MAKE_NODE_UNIQUE_REF(BinaryExpression, WTFMove(lhs), WTFMove(rhs), op); } @@ -790,7 +827,7 @@ Expected, Error> Parser::parsePrimaryExpressio } case TokenType::Identifier: { PARSE(ident, Identifier); - if (current().m_type == TokenType::LT || current().m_type == TokenType::ParenLeft) { + if (current().m_type == TokenType::Lt || current().m_type == TokenType::ParenLeft) { PARSE(type, TypeNameAfterIdentifier, WTFMove(ident), _startOfElementPosition); PARSE(arguments, ArgumentExpressionList); RETURN_NODE_UNIQUE_REF(CallExpression, WTFMove(type), WTFMove(arguments)); @@ -844,7 +881,7 @@ Expected, Error> Parser::parseExpression() { // FIXME: Fill in PARSE(lhs, UnaryExpression); - return parseRelationalExpression(WTFMove(lhs)); + return parseRelationalExpressionPostUnary(WTFMove(lhs)); } template diff --git a/Source/WebGPU/WGSL/ParserPrivate.h b/Source/WebGPU/WGSL/ParserPrivate.h index 3c470f15bbd7..84f2d20d1dba 100644 --- a/Source/WebGPU/WGSL/ParserPrivate.h +++ b/Source/WebGPU/WGSL/ParserPrivate.h @@ -73,12 +73,10 @@ class Parser { Expected parseCompoundStatement(); Expected parseReturnStatement(); Expected parseShortCircuitOrExpression(); - Expected parseRelationalExpression(AST::Expression::Ref&& lhs); - Expected parseShiftExpression(AST::Expression::Ref&& lhs); - Expected parseAdditiveExpression(AST::Expression::Ref&& lhs); - Expected parseAdditiveOperator(); - Expected parseMultiplicativeExpression(AST::Expression::Ref&& lhs); - Expected parseMultiplicativeOperator(); + Expected parseRelationalExpressionPostUnary(AST::Expression::Ref&& lhs); + Expected parseShiftExpressionPostUnary(AST::Expression::Ref&& lhs); + Expected parseAdditiveExpressionPostUnary(AST::Expression::Ref&& lhs); + Expected parseMultiplicativeExpressionPostUnary(AST::Expression::Ref&& lhs); Expected parseUnaryExpression(); Expected parseSingularExpression(); Expected parsePostfixExpression(AST::Expression::Ref&& base, SourcePosition startPosition); diff --git a/Source/WebGPU/WGSL/Token.cpp b/Source/WebGPU/WGSL/Token.cpp index dc54ed0e747e..03581a4cfc4b 100644 --- a/Source/WebGPU/WGSL/Token.cpp +++ b/Source/WebGPU/WGSL/Token.cpp @@ -105,10 +105,14 @@ String toString(TokenType type) return ","_s; case TokenType::Equal: return "="_s; - case TokenType::GT: + case TokenType::Gt: return ">"_s; - case TokenType::LT: + case TokenType::GtGt: + return ">>"_s; + case TokenType::Lt: return "<"_s; + case TokenType::LtLt: + return "<<"_s; case TokenType::Minus: return "-"_s; case TokenType::MinusMinus: diff --git a/Source/WebGPU/WGSL/Token.h b/Source/WebGPU/WGSL/Token.h index e58fd2bb5f17..10b59eacc97e 100644 --- a/Source/WebGPU/WGSL/Token.h +++ b/Source/WebGPU/WGSL/Token.h @@ -79,8 +79,10 @@ enum class TokenType: uint32_t { Colon, Comma, Equal, - GT, - LT, + Gt, + GtGt, + Lt, + LtLt, Minus, MinusMinus, Modulo, diff --git a/Tools/TestWebKitAPI/Tests/WGSL/LexerTests.cpp b/Tools/TestWebKitAPI/Tests/WGSL/LexerTests.cpp index ca7ec28a7d67..cb94853c8c83 100644 --- a/Tools/TestWebKitAPI/Tests/WGSL/LexerTests.cpp +++ b/Tools/TestWebKitAPI/Tests/WGSL/LexerTests.cpp @@ -134,8 +134,10 @@ TEST(WGSLLexerTests, SpecialTokens) checkSingleToken(":"_s, TokenType::Colon); checkSingleToken(","_s, TokenType::Comma); checkSingleToken("="_s, TokenType::Equal); - checkSingleToken(">"_s, TokenType::GT); - checkSingleToken("<"_s, TokenType::LT); + checkSingleToken(">"_s, TokenType::Gt); + checkSingleToken(">>"_s, TokenType::GtGt); + checkSingleToken("<"_s, TokenType::Lt); + checkSingleToken("<<"_s, TokenType::LtLt); checkSingleToken("-"_s, TokenType::Minus); checkSingleToken("--"_s, TokenType::MinusMinus); checkSingleToken("%"_s, TokenType::Modulo); @@ -197,11 +199,11 @@ TEST(WGSLLexerTests, ComputeShader) // var x: B; ++lineNumber; checkNextTokenIs(lexer, WGSL::TokenType::KeywordVar, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::LT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Lt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::KeywordStorage, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::Comma, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::KeywordReadWrite, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::GT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Gt, lineNumber); checkNextTokenIsIdentifier(lexer, "x"_s, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::Colon, lineNumber); checkNextTokenIsIdentifier(lexer, "B"_s, lineNumber); @@ -267,9 +269,9 @@ TEST(WGSLLexerTests, GraphicsShader) checkNextTokenIsIdentifier(lexer, "x"_s, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::Colon, lineNumber); checkNextTokenIsIdentifier(lexer, "vec4"_s, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::LT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Lt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::KeywordF32, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::GT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Gt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::ParenRight, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::Arrow, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::Attribute, lineNumber); @@ -278,9 +280,9 @@ TEST(WGSLLexerTests, GraphicsShader) checkNextTokenIsIdentifier(lexer, "position"_s, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::ParenRight, lineNumber); checkNextTokenIsIdentifier(lexer, "vec4"_s, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::LT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Lt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::KeywordF32, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::GT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Gt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::BraceLeft, lineNumber); // return x; @@ -311,18 +313,18 @@ TEST(WGSLLexerTests, GraphicsShader) checkNextTokenIsLiteral(lexer, WGSL::TokenType::IntegerLiteral, 0, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::ParenRight, lineNumber); checkNextTokenIsIdentifier(lexer, "vec4"_s, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::LT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Lt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::KeywordF32, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::GT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Gt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::BraceLeft, lineNumber); // return vec4(0.4, 0.4, 0.8, 1.0); ++lineNumber; checkNextTokenIs(lexer, WGSL::TokenType::KeywordReturn, lineNumber); checkNextTokenIsIdentifier(lexer, "vec4"_s, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::LT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Lt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::KeywordF32, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::GT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Gt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::ParenLeft, lineNumber); checkNextTokenIsLiteral(lexer, WGSL::TokenType::DecimalFloatLiteral, 0.4, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::Comma, lineNumber); @@ -380,9 +382,9 @@ TEST(WGSLLexerTests, TriangleVert) checkNextTokenIs(lexer, WGSL::TokenType::Arrow, lineNumber); checkNextTokensAreBuiltinAttr(lexer, "position"_s, lineNumber); checkNextTokenIsIdentifier(lexer, "vec4"_s, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::LT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Lt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::KeywordF32, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::GT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Gt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::BraceLeft, lineNumber); ++lineNumber; @@ -391,22 +393,22 @@ TEST(WGSLLexerTests, TriangleVert) checkNextTokenIsIdentifier(lexer, "pos"_s, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::Equal, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::KeywordArray, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::LT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Lt, lineNumber); checkNextTokenIsIdentifier(lexer, "vec2"_s, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::LT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Lt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::KeywordF32, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::GT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Gt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::Comma, lineNumber); checkNextTokenIsLiteral(lexer, WGSL::TokenType::IntegerLiteral, 3, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::GT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Gt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::ParenLeft, lineNumber); ++lineNumber; // vec2(0.0, 0.5), checkNextTokenIsIdentifier(lexer, "vec2"_s, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::LT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Lt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::KeywordF32, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::GT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Gt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::ParenLeft, lineNumber); checkNextTokenIsLiteral(lexer, WGSL::TokenType::DecimalFloatLiteral, 0.0, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::Comma, lineNumber); @@ -417,9 +419,9 @@ TEST(WGSLLexerTests, TriangleVert) ++lineNumber; // vec2(-0.5, -0.5), checkNextTokenIsIdentifier(lexer, "vec2"_s, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::LT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Lt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::KeywordF32, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::GT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Gt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::ParenLeft, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::Minus, lineNumber); checkNextTokenIsLiteral(lexer, WGSL::TokenType::DecimalFloatLiteral, 0.5, lineNumber); @@ -432,9 +434,9 @@ TEST(WGSLLexerTests, TriangleVert) ++lineNumber; // vec2(0.5, -0.5) checkNextTokenIsIdentifier(lexer, "vec2"_s, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::LT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Lt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::KeywordF32, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::GT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Gt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::ParenLeft, lineNumber); checkNextTokenIsLiteral(lexer, WGSL::TokenType::DecimalFloatLiteral, 0.5, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::Comma, lineNumber); @@ -451,9 +453,9 @@ TEST(WGSLLexerTests, TriangleVert) // return vec4(pos[VertexIndex] + vec2(0.5, 0.5), 0.0, 1.0); checkNextTokenIs(lexer, WGSL::TokenType::KeywordReturn, lineNumber); checkNextTokenIsIdentifier(lexer, "vec4"_s, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::LT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Lt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::KeywordF32, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::GT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Gt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::ParenLeft, lineNumber); checkNextTokenIsIdentifier(lexer, "pos"_s, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::BracketLeft, lineNumber); @@ -461,9 +463,9 @@ TEST(WGSLLexerTests, TriangleVert) checkNextTokenIs(lexer, WGSL::TokenType::BracketRight, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::Plus, lineNumber); checkNextTokenIsIdentifier(lexer, "vec2"_s, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::LT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Lt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::KeywordF32, lineNumber); - checkNextTokenIs(lexer, WGSL::TokenType::GT, lineNumber); + checkNextTokenIs(lexer, WGSL::TokenType::Gt, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::ParenLeft, lineNumber); checkNextTokenIsLiteral(lexer, WGSL::TokenType::DecimalFloatLiteral, 0.5, lineNumber); checkNextTokenIs(lexer, WGSL::TokenType::Comma, lineNumber); diff --git a/Tools/TestWebKitAPI/Tests/WGSL/ParserTests.cpp b/Tools/TestWebKitAPI/Tests/WGSL/ParserTests.cpp index 76e7f9f2cd38..74b440099058 100644 --- a/Tools/TestWebKitAPI/Tests/WGSL/ParserTests.cpp +++ b/Tools/TestWebKitAPI/Tests/WGSL/ParserTests.cpp @@ -595,6 +595,46 @@ TEST(WGSLParserTests, BinaryExpression4) } } +TEST(WGSLParserTests, BinaryLeftShiftExpression) +{ + EXPECT_EXPRESSION(expression, "x << y"_s); + EXPECT_TRUE(is(expression.get())); + auto& binaryExpression = downcast(expression.get()); + + { + // op: << + EXPECT_EQ(binaryExpression.operation(), WGSL::AST::BinaryOperation::LeftShift); + // lhs: x + EXPECT_TRUE(is(binaryExpression.leftExpression())); + auto& lhs = downcast(binaryExpression.leftExpression()); + EXPECT_EQ(lhs.identifier(), "x"_s); + // rhs: y + EXPECT_TRUE(is(binaryExpression.rightExpression())); + auto& rhs = downcast(binaryExpression.rightExpression()); + EXPECT_EQ(rhs.identifier(), "y"_s); + } +} + +TEST(WGSLParserTests, BinaryRightShiftExpression) +{ + EXPECT_EXPRESSION(expression, "x >> y"_s); + EXPECT_TRUE(is(expression.get())); + auto& binaryExpression = downcast(expression.get()); + + { + // op: >> + EXPECT_EQ(binaryExpression.operation(), WGSL::AST::BinaryOperation::RightShift); + // lhs: x + EXPECT_TRUE(is(binaryExpression.leftExpression())); + auto& lhs = downcast(binaryExpression.leftExpression()); + EXPECT_EQ(lhs.identifier(), "x"_s); + // rhs: y + EXPECT_TRUE(is(binaryExpression.rightExpression())); + auto& rhs = downcast(binaryExpression.rightExpression()); + EXPECT_EQ(rhs.identifier(), "y"_s); + } +} + #pragma mark - #pragma mark WebGPU Example Shaders