Changeset 246135 in webkit
- Timestamp:
- Jun 5, 2019 5:46:25 PM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r246131 r246135 1 2019-06-05 Robin Morisset <rmorisset@apple.com> 2 3 [WHLSL] Parsing and lexing the standard library is slow 4 https://bugs.webkit.org/show_bug.cgi?id=192890 5 <rdar://problem/50746335> 6 7 Reviewed by Myles Maxfield. 8 9 The main idea is to avoid backtracking by instead peeking at the next token (and occasionally at the one after that). 10 This implies a few things: 11 - We can replace the stack of tokens by a trivial ring buffer of size 2 (holding the next token and the one after, or WTF::nullopt if we are at the end of the file). 12 - We now have "completeFooExpression" functions, to avoid having to reparse the prefix of some expression, if we find half-way through what it is. 13 14 I also fixed the following parser bug: 15 - https://bugs.webkit.org/show_bug.cgi?id=198305 [WHLSL] Multiple variables with initializers in a declaration statement crashes the compiler 16 which was due to a mistake I made in the grammar 17 18 Finally I added two new macros: CONSUME_TYPE and PARSE to eliminate about 500 lines of error propagation boilerplate. 19 20 There are still lots of ways of improving the parser and lexer, such as: 21 - finishing the conversion of tokens in the lexer, not bothering with allocating string views 22 - make two special tokens Invalid and EOF, to remove the overhead of Optional 23 - make peekTypes and consumeTypes use templates to avoid constructing a Vector and calling find on it. 24 - Turn the entire lexer into a proper automata, not going through the same characters again and again (this is certainly the largest win by far) 25 - Remove the last few pieces of backtracking from the parser. 26 27 The current patch is already enough to make parsing the full standard library (something like 85k lines) approximately 260ms. 28 This is still longer than I would like, but nowhere near the bottleneck any longer because of some other parts of the compiler. 29 30 * Modules/webgpu/WHLSL/WHLSLLexer.h: 31 (WebCore::WHLSL::Lexer::Lexer): 32 (WebCore::WHLSL::Lexer::consumeToken): 33 (WebCore::WHLSL::Lexer::peek): 34 (WebCore::WHLSL::Lexer::peekFurther): 35 (WebCore::WHLSL::Lexer::state const): 36 (WebCore::WHLSL::Lexer::setState): 37 (WebCore::WHLSL::Lexer::unconsumeToken): Deleted. 38 * Modules/webgpu/WHLSL/WHLSLParser.cpp: 39 (WebCore::WHLSL::Parser::parse): 40 (WebCore::WHLSL::Parser::peek): 41 (WebCore::WHLSL::Parser::peekTypes): 42 (WebCore::WHLSL::Parser::tryType): 43 (WebCore::WHLSL::Parser::tryTypes): 44 (WebCore::WHLSL::Parser::consumeTypes): 45 (WebCore::WHLSL::Parser::parseConstantExpression): 46 (WebCore::WHLSL::Parser::parseTypeArgument): 47 (WebCore::WHLSL::Parser::parseTypeArguments): 48 (WebCore::WHLSL::Parser::parseTypeSuffixAbbreviated): 49 (WebCore::WHLSL::Parser::parseTypeSuffixNonAbbreviated): 50 (WebCore::WHLSL::Parser::parseType): 51 (WebCore::WHLSL::Parser::parseTypeDefinition): 52 (WebCore::WHLSL::Parser::parseResourceSemantic): 53 (WebCore::WHLSL::Parser::parseSpecializationConstantSemantic): 54 (WebCore::WHLSL::Parser::parseStageInOutSemantic): 55 (WebCore::WHLSL::Parser::parseSemantic): 56 (WebCore::WHLSL::Parser::parseQualifiers): 57 (WebCore::WHLSL::Parser::parseStructureElement): 58 (WebCore::WHLSL::Parser::parseStructureDefinition): 59 (WebCore::WHLSL::Parser::parseEnumerationDefinition): 60 (WebCore::WHLSL::Parser::parseEnumerationMember): 61 (WebCore::WHLSL::Parser::parseNativeTypeDeclaration): 62 (WebCore::WHLSL::Parser::parseNumThreadsFunctionAttribute): 63 (WebCore::WHLSL::Parser::parseAttributeBlock): 64 (WebCore::WHLSL::Parser::parseParameter): 65 (WebCore::WHLSL::Parser::parseParameters): 66 (WebCore::WHLSL::Parser::parseFunctionDefinition): 67 (WebCore::WHLSL::Parser::parseComputeFunctionDeclaration): 68 (WebCore::WHLSL::Parser::parseVertexFragmentFunctionDeclaration): 69 (WebCore::WHLSL::Parser::parseRegularFunctionDeclaration): 70 (WebCore::WHLSL::Parser::parseOperatorFunctionDeclaration): 71 (WebCore::WHLSL::Parser::parseFunctionDeclaration): 72 (WebCore::WHLSL::Parser::parseNativeFunctionDeclaration): 73 (WebCore::WHLSL::Parser::parseBlock): 74 (WebCore::WHLSL::Parser::parseBlockBody): 75 (WebCore::WHLSL::Parser::parseIfStatement): 76 (WebCore::WHLSL::Parser::parseSwitchStatement): 77 (WebCore::WHLSL::Parser::parseSwitchCase): 78 (WebCore::WHLSL::Parser::parseForLoop): 79 (WebCore::WHLSL::Parser::parseWhileLoop): 80 (WebCore::WHLSL::Parser::parseDoWhileLoop): 81 (WebCore::WHLSL::Parser::parseVariableDeclaration): 82 (WebCore::WHLSL::Parser::parseVariableDeclarations): 83 (WebCore::WHLSL::Parser::parseStatement): 84 (WebCore::WHLSL::Parser::parseEffectfulExpression): 85 (WebCore::WHLSL::Parser::parseEffectfulAssignment): 86 (WebCore::WHLSL::Parser::parseExpression): 87 (WebCore::WHLSL::Parser::parseTernaryConditional): Deleted. 88 (WebCore::WHLSL::Parser::completeTernaryConditional): 89 (WebCore::WHLSL::Parser::parseAssignment): Deleted. 90 (WebCore::WHLSL::Parser::completeAssignment): 91 (WebCore::WHLSL::Parser::parsePossibleTernaryConditional): 92 (WebCore::WHLSL::Parser::parsePossibleLogicalBinaryOperation): 93 (WebCore::WHLSL::Parser::completePossibleLogicalBinaryOperation): 94 (WebCore::WHLSL::Parser::parsePossibleRelationalBinaryOperation): 95 (WebCore::WHLSL::Parser::completePossibleRelationalBinaryOperation): 96 (WebCore::WHLSL::Parser::parsePossibleShift): 97 (WebCore::WHLSL::Parser::completePossibleShift): 98 (WebCore::WHLSL::Parser::parsePossibleAdd): 99 (WebCore::WHLSL::Parser::completePossibleAdd): 100 (WebCore::WHLSL::Parser::parsePossibleMultiply): 101 (WebCore::WHLSL::Parser::completePossibleMultiply): 102 (WebCore::WHLSL::Parser::parsePossiblePrefix): 103 (WebCore::WHLSL::Parser::parsePossibleSuffix): 104 (WebCore::WHLSL::Parser::parseCallExpression): 105 (WebCore::WHLSL::Parser::parseTerm): 106 (WebCore::WHLSL::Parser::parseAddressSpaceType): Deleted. 107 (WebCore::WHLSL::Parser::parseNonAddressSpaceType): Deleted. 108 (WebCore::WHLSL::Parser::parseEntryPointFunctionDeclaration): Deleted. 109 (WebCore::WHLSL::Parser::parseEffectfulPrefix): Deleted. 110 (WebCore::WHLSL::Parser::parseEffectfulSuffix): Deleted. 111 * Modules/webgpu/WHLSL/WHLSLParser.h: 112 (WebCore::WHLSL::Parser::Error::dump const): 113 1 114 2019-06-05 Alex Christensen <achristensen@webkit.org> 2 115 -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.h
r246108 r246135 47 47 { 48 48 skipWhitespaceAndComments(); 49 m_ringBuffer[0] = consumeTokenFromStream(); 50 m_ringBuffer[1] = consumeTokenFromStream(); 49 51 } 50 52 … … 178 180 Optional<Token> consumeToken() 179 181 { 180 if (!m_stack.isEmpty()) 181 return m_stack.takeLast(); 182 return consumeTokenFromStream(); 183 } 184 185 void unconsumeToken(Token&& token) 186 { 187 m_stack.append(WTFMove(token)); 188 } 189 182 auto result = m_ringBuffer[m_ringBufferIndex]; 183 m_ringBuffer[m_ringBufferIndex] = consumeTokenFromStream(); 184 m_ringBufferIndex = (m_ringBufferIndex + 1) % 2; 185 return result; 186 } 187 188 Optional<Token> peek() 189 { 190 return m_ringBuffer[m_ringBufferIndex]; 191 } 192 193 Optional<Token> peekFurther() 194 { 195 return m_ringBuffer[(m_ringBufferIndex + 1) % 2]; 196 } 197 198 // FIXME: We should not need this 199 // https://bugs.webkit.org/show_bug.cgi?id=198357 190 200 struct State { 191 Vector<Token> stack; 201 Optional<Token> ringBuffer[2]; 202 unsigned ringBufferIndex; 192 203 unsigned offset; 193 204 unsigned lineNumber; … … 196 207 State state() const 197 208 { 198 return { m_stack, m_offset, m_lineNumber }; 209 State state; 210 state.ringBuffer[0] = m_ringBuffer[0]; 211 state.ringBuffer[1] = m_ringBuffer[1]; 212 state.ringBufferIndex = m_ringBufferIndex; 213 state.offset = m_offset; 214 state.lineNumber = m_lineNumber; 215 return state; 199 216 } 200 217 201 218 void setState(const State& state) 202 219 { 203 m_stack = state.stack; 220 m_ringBuffer[0] = state.ringBuffer[0]; 221 m_ringBuffer[1] = state.ringBuffer[1]; 222 m_ringBufferIndex = state.ringBufferIndex; 204 223 m_offset = state.offset; 205 224 m_lineNumber = state.lineNumber; 225 206 226 } 207 227 208 228 void setState(State&& state) 209 229 { 210 m_stack = WTFMove(state.stack); 230 m_ringBuffer[0] = WTFMove(state.ringBuffer[0]); 231 m_ringBuffer[1] = WTFMove(state.ringBuffer[1]); 232 m_ringBufferIndex = WTFMove(state.ringBufferIndex); 211 233 m_offset = WTFMove(state.offset); 212 234 m_lineNumber = WTFMove(state.lineNumber); … … 254 276 255 277 StringView m_stringView; 256 Vector<Token> m_stack; 278 Optional<Token> m_ringBuffer[2]; 279 unsigned m_ringBufferIndex { 0 }; 257 280 unsigned m_offset { 0 }; 258 281 unsigned m_lineNumber { 0 }; -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp
r246121 r246135 39 39 namespace WHLSL { 40 40 41 #define PARSE(name, element, ...) \ 42 auto name = parse##element(__VA_ARGS__); \ 43 if (!name) \ 44 return Unexpected<Error>(name.error()); 45 46 #define CONSUME_TYPE(name, type) \ 47 auto name = consumeType(Lexer::Token::Type::type); \ 48 if (!name) \ 49 return Unexpected<Error>(name.error()); 50 51 #define PEEK(name) \ 52 auto name = peek(); \ 53 if (!name) \ 54 return Unexpected<Error>(name.error()); 55 56 #define PEEK_FURTHER(name) \ 57 auto name = peekFurther(); \ 58 if (!name) \ 59 return Unexpected<Error>(name.error()); 60 41 61 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195682 Return a better error code from this, and report it to JavaScript. 42 62 auto Parser::parse(Program& program, StringView stringView, Mode mode) -> Optional<Error> … … 46 66 47 67 while (!m_lexer.isFullyConsumed()) { 48 if (tryType(Lexer::Token::Type::Semicolon)) { 68 auto token = m_lexer.peek(); 69 if (!token) 70 break; 71 switch (token->type) { 72 case Lexer::Token::Type::Semicolon: 49 73 m_lexer.consumeToken(); 50 74 continue; 51 } 52 53 { 54 auto typeDefinition = backtrackingScope<Expected<AST::TypeDefinition, Error>>([&]() { 55 return parseTypeDefinition(); 56 }); 57 if (typeDefinition) { 58 auto success = program.append(WTFMove(*typeDefinition)); 59 if (!success) 60 return WTF::nullopt; 75 case Lexer::Token::Type::Typedef: { 76 auto typeDefinition = parseTypeDefinition(); 77 if (!typeDefinition) 78 return typeDefinition.error(); 79 program.append(WTFMove(*typeDefinition)); 80 continue; 81 } 82 case Lexer::Token::Type::Struct: { 83 auto structureDefinition = parseStructureDefinition(); 84 if (!structureDefinition) 85 return structureDefinition.error(); 86 program.append(WTFMove(*structureDefinition)); 87 continue; 88 } 89 case Lexer::Token::Type::Enum: { 90 auto enumerationDefinition = parseEnumerationDefinition(); 91 if (!enumerationDefinition) 92 return enumerationDefinition.error(); 93 program.append(WTFMove(*enumerationDefinition)); 94 continue; 95 } 96 case Lexer::Token::Type::Native: { 97 ASSERT(m_mode == Mode::StandardLibrary); 98 auto furtherToken = peekFurther(); 99 if (!furtherToken) 100 return WTF::nullopt; 101 if (furtherToken->type == Lexer::Token::Type::Typedef) { 102 auto nativeTypeDeclaration = parseNativeTypeDeclaration(); 103 if (!nativeTypeDeclaration) 104 return nativeTypeDeclaration.error(); 105 program.append(WTFMove(*nativeTypeDeclaration)); 61 106 continue; 62 107 } 63 } 64 65 { 66 auto structureDefinition = backtrackingScope<Expected<AST::StructureDefinition, Error>>([&]() { 67 return parseStructureDefinition(); 68 }); 69 if (structureDefinition) { 70 auto success = program.append(WTFMove(*structureDefinition)); 71 if (!success) 72 return WTF::nullopt; 73 continue; 74 } 75 } 76 77 { 78 auto enumerationDefinition = backtrackingScope<Expected<AST::EnumerationDefinition, Error>>([&]() { 79 return parseEnumerationDefinition(); 80 }); 81 if (enumerationDefinition) { 82 auto success = program.append(WTFMove(*enumerationDefinition)); 83 if (!success) 84 return WTF::nullopt; 85 continue; 86 } 87 } 88 89 Optional<Error> error; 90 { 91 auto functionDefinition = backtrackingScope<Expected<AST::FunctionDefinition, Error>>([&]() { 92 return parseFunctionDefinition(); 93 }); 94 if (functionDefinition) { 95 auto success = program.append(WTFMove(*functionDefinition)); 96 if (!success) 97 return WTF::nullopt; 98 continue; 99 } 100 error = functionDefinition.error(); 101 } 102 103 if (m_mode == Mode::StandardLibrary) { 104 auto nativeFunctionDeclaration = backtrackingScope<Expected<AST::NativeFunctionDeclaration, Error>>([&]() { 105 return parseNativeFunctionDeclaration(); 106 }); 107 if (nativeFunctionDeclaration) { 108 auto success = program.append(WTFMove(*nativeFunctionDeclaration)); 109 if (!success) 110 return WTF::nullopt; 111 continue; 112 } 113 } 114 115 if (m_mode == Mode::StandardLibrary) { 116 auto nativeTypeDeclaration = backtrackingScope<Expected<AST::NativeTypeDeclaration, Error>>([&]() { 117 return parseNativeTypeDeclaration(); 118 }); 119 if (nativeTypeDeclaration) { 120 auto success = program.append(WTFMove(*nativeTypeDeclaration)); 121 if (!success) 122 return WTF::nullopt; 123 continue; 124 } 125 } 126 127 return WTFMove(*error); 128 } 108 auto nativeFunctionDeclaration = parseNativeFunctionDeclaration(); 109 if (!nativeFunctionDeclaration) 110 return nativeFunctionDeclaration.error(); 111 program.append(WTFMove(*nativeFunctionDeclaration)); 112 continue; 113 } 114 default: { 115 auto functionDefinition = parseFunctionDefinition(); 116 if (!functionDefinition) 117 return functionDefinition.error(); 118 program.append(WTFMove(*functionDefinition)); 119 continue; 120 } 121 } 122 } 123 129 124 return WTF::nullopt; 130 125 } … … 141 136 auto Parser::peek() -> Expected<Lexer::Token, Error> 142 137 { 143 if (auto token = m_lexer.consumeToken()) { 144 m_lexer.unconsumeToken(Lexer::Token(*token)); 138 if (auto token = m_lexer.peek()) { 145 139 return *token; 146 140 } … … 148 142 } 149 143 144 auto Parser::peekFurther() -> Expected<Lexer::Token, Error> 145 { 146 if (auto token = m_lexer.peekFurther()) { 147 return *token; 148 } 149 return fail("Cannot consume two tokens"_str, TryToPeek::No); 150 } 151 152 bool Parser::peekTypes(const Vector<Lexer::Token::Type>& types) 153 { 154 if (auto token = m_lexer.peek()) 155 return std::find(types.begin(), types.end(), token->type) != types.end(); 156 return false; 157 } 158 150 159 Optional<Lexer::Token> Parser::tryType(Lexer::Token::Type type) 151 160 { 152 if (auto token = m_lexer. consumeToken()) {161 if (auto token = m_lexer.peek()) { 153 162 if (token->type == type) 154 return token; 155 m_lexer.unconsumeToken(Lexer::Token(*token)); 163 return m_lexer.consumeToken(); 156 164 } 157 165 return WTF::nullopt; 158 166 } 159 167 160 Optional<Lexer::Token> Parser::tryTypes( Vector<Lexer::Token::Type>types)161 { 162 if (auto token = m_lexer. consumeToken()) {168 Optional<Lexer::Token> Parser::tryTypes(const Vector<Lexer::Token::Type>& types) 169 { 170 if (auto token = m_lexer.peek()) { 163 171 if (std::find(types.begin(), types.end(), token->type) != types.end()) 164 return token; 165 m_lexer.unconsumeToken(Lexer::Token(*token)); 172 return m_lexer.consumeToken(); 166 173 } 167 174 return WTF::nullopt; … … 178 185 } 179 186 180 auto Parser::consumeTypes( Vector<Lexer::Token::Type>types) -> Expected<Lexer::Token, Error>187 auto Parser::consumeTypes(const Vector<Lexer::Token::Type>& types) -> Expected<Lexer::Token, Error> 181 188 { 182 189 auto buildExpectedString = [&]() -> String { … … 368 375 default: { 369 376 ASSERT(type->type == Lexer::Token::Type::Identifier); 370 auto origin = consumeType(Lexer::Token::Type::FullStop); 371 if (!origin) 372 return Unexpected<Error>(origin.error()); 373 auto next = consumeType(Lexer::Token::Type::Identifier); 374 if (!next) 375 return Unexpected<Error>(next.error()); 377 CONSUME_TYPE(origin, FullStop); 378 CONSUME_TYPE(next, Identifier); 376 379 return { AST::EnumerationMemberLiteral(WTFMove(*origin), type->stringView.toString(), next->stringView.toString()) }; 377 380 } … … 381 384 auto Parser::parseTypeArgument() -> Expected<AST::TypeArgument, Error> 382 385 { 383 auto constantExpression = backtrackingScope<Expected<AST::ConstantExpression, Error>>([&]() {384 return parseConstantExpression();385 });386 if (constantExpression)386 PEEK(nextToken); 387 PEEK_FURTHER(furtherToken); 388 if (nextToken->type != Lexer::Token::Type::Identifier || furtherToken->type == Lexer::Token::Type::FullStop) { 389 PARSE(constantExpression, ConstantExpression); 387 390 return AST::TypeArgument(WTFMove(*constantExpression)); 388 auto result = consumeType(Lexer::Token::Type::Identifier); 389 if (!result) 390 return Unexpected<Error>(result.error()); 391 } 392 CONSUME_TYPE(result, Identifier); 391 393 return AST::TypeArgument(makeUniqueRef<AST::TypeReference>(Lexer::Token(*result), result->stringView.toString(), AST::TypeArguments())); 392 394 } … … 394 396 auto Parser::parseTypeArguments() -> Expected<AST::TypeArguments, Error> 395 397 { 396 auto typeArguments = backtrackingScope<Optional<AST::TypeArguments>>([&]() -> Optional<AST::TypeArguments> { 397 auto lessThanSign = consumeType(Lexer::Token::Type::LessThanSign); 398 if (!lessThanSign) 399 return WTF::nullopt; 400 AST::TypeArguments typeArguments; 401 auto typeArgument = parseTypeArgument(); 402 if (!typeArgument) 403 return WTF::nullopt; 398 AST::TypeArguments typeArguments; 399 auto lessThanSign = tryType(Lexer::Token::Type::LessThanSign); 400 if (!lessThanSign) 401 return typeArguments; 402 403 auto greaterThanSign = tryType(Lexer::Token::Type::GreaterThanSign); 404 if (greaterThanSign) 405 return typeArguments; 406 407 PARSE(typeArgument, TypeArgument); 408 typeArguments.append(WTFMove(*typeArgument)); 409 410 while (true) { 411 auto greaterThanSign = tryType(Lexer::Token::Type::GreaterThanSign); 412 if (greaterThanSign) 413 break; 414 415 CONSUME_TYPE(comma, Comma); 416 PARSE(typeArgument, TypeArgument); 404 417 typeArguments.append(WTFMove(*typeArgument)); 405 while (tryType(Lexer::Token::Type::Comma)) { 406 auto typeArgument = parseTypeArgument(); 407 if (!typeArgument) 408 return WTF::nullopt; 409 typeArguments.append(WTFMove(*typeArgument)); 410 } 411 auto greaterThanSign = consumeType(Lexer::Token::Type::GreaterThanSign); 412 if (!greaterThanSign) 413 return WTF::nullopt; 414 return typeArguments; 415 }); 416 if (typeArguments) 417 return WTFMove(*typeArguments); 418 419 typeArguments = backtrackingScope<Optional<AST::TypeArguments>>([&]() -> Optional<AST::TypeArguments> { 420 auto lessThanSign = consumeType(Lexer::Token::Type::LessThanSign); 421 if (!lessThanSign) 422 return WTF::nullopt; 423 auto greaterThanSign = consumeType(Lexer::Token::Type::GreaterThanSign); 424 if (!greaterThanSign) 425 return WTF::nullopt; 426 return {{ }}; 427 }); 428 if (typeArguments) 429 return WTFMove(*typeArguments); 430 431 return AST::TypeArguments(); 418 } 419 420 return typeArguments; 432 421 } 433 422 … … 441 430 if (!numElements) 442 431 return Unexpected<Error>(numElements.error()); 443 auto rightSquareBracket = consumeType(Lexer::Token::Type::RightSquareBracket); 444 if (!rightSquareBracket) 445 return Unexpected<Error>(rightSquareBracket.error()); 432 CONSUME_TYPE(rightSquareBracket, RightSquareBracket); 446 433 return {{ *token, *numElements }}; 447 434 } … … 458 445 if (!numElements) 459 446 return Unexpected<Error>(numElements.error()); 460 auto rightSquareBracket = consumeType(Lexer::Token::Type::RightSquareBracket); 461 if (!rightSquareBracket) 462 return Unexpected<Error>(rightSquareBracket.error()); 447 CONSUME_TYPE(rightSquareBracket, RightSquareBracket); 463 448 return {{ *token, WTF::nullopt, *numElements }}; 464 449 } … … 485 470 } 486 471 487 auto Parser::parseAddressSpaceType() -> Expected<UniqueRef<AST::UnnamedType>, Error> 488 { 489 auto addressSpaceToken = consumeTypes({ Lexer::Token::Type::Constant, Lexer::Token::Type::Device, Lexer::Token::Type::Threadgroup, Lexer::Token::Type::Thread}); 490 if (!addressSpaceToken) 491 return Unexpected<Error>(addressSpaceToken.error()); 492 AST::AddressSpace addressSpace; 493 switch (addressSpaceToken->type) { 494 case Lexer::Token::Type::Constant: 495 addressSpace = AST::AddressSpace::Constant; 496 break; 497 case Lexer::Token::Type::Device: 498 addressSpace = AST::AddressSpace::Device; 499 break; 500 case Lexer::Token::Type::Threadgroup: 501 addressSpace = AST::AddressSpace::Threadgroup; 502 break; 503 default: 504 ASSERT(addressSpaceToken->type == Lexer::Token::Type::Thread); 505 addressSpace = AST::AddressSpace::Thread; 506 break; 507 } 508 auto name = consumeType(Lexer::Token::Type::Identifier); 509 if (!name) 510 return Unexpected<Error>(name.error()); 511 auto typeArguments = parseTypeArguments(); 512 if (!typeArguments) 513 return Unexpected<Error>(typeArguments.error()); 514 515 auto constructTypeFromSuffixAbbreviated = [&](const TypeSuffixAbbreviated& typeSuffixAbbreviated, UniqueRef<AST::UnnamedType>&& previous) -> UniqueRef<AST::UnnamedType> { 516 switch (typeSuffixAbbreviated.token.type) { 517 case Lexer::Token::Type::Star: 518 return { makeUniqueRef<AST::PointerType>(Lexer::Token(typeSuffixAbbreviated.token), addressSpace, WTFMove(previous)) }; 519 case Lexer::Token::Type::SquareBracketPair: 520 return { makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(typeSuffixAbbreviated.token), addressSpace, WTFMove(previous)) }; 472 auto Parser::parseType() -> Expected<UniqueRef<AST::UnnamedType>, Error> 473 { 474 auto addressSpaceToken = tryTypes({ Lexer::Token::Type::Constant, Lexer::Token::Type::Device, Lexer::Token::Type::Threadgroup, Lexer::Token::Type::Thread}); 475 476 CONSUME_TYPE(name, Identifier); 477 PARSE(typeArguments, TypeArguments); 478 479 if (addressSpaceToken) { 480 AST::AddressSpace addressSpace; 481 switch (addressSpaceToken->type) { 482 case Lexer::Token::Type::Constant: 483 addressSpace = AST::AddressSpace::Constant; 484 break; 485 case Lexer::Token::Type::Device: 486 addressSpace = AST::AddressSpace::Device; 487 break; 488 case Lexer::Token::Type::Threadgroup: 489 addressSpace = AST::AddressSpace::Threadgroup; 490 break; 521 491 default: 522 ASSERT(typeSuffixAbbreviated.token.type == Lexer::Token::Type::LeftSquareBracket); 523 return { makeUniqueRef<AST::ArrayType>(Lexer::Token(typeSuffixAbbreviated.token), WTFMove(previous), *typeSuffixAbbreviated.numElements) }; 524 } 525 }; 526 527 auto firstTypeSuffixAbbreviated = parseTypeSuffixAbbreviated(); 528 if (!firstTypeSuffixAbbreviated) 529 return Unexpected<Error>(firstTypeSuffixAbbreviated.error()); 530 UniqueRef<AST::UnnamedType> result = makeUniqueRef<AST::TypeReference>(WTFMove(*addressSpaceToken), name->stringView.toString(), WTFMove(*typeArguments)); 531 auto next = constructTypeFromSuffixAbbreviated(*firstTypeSuffixAbbreviated, WTFMove(result)); 532 result = WTFMove(next); 533 while (true) { 534 auto typeSuffixAbbreviated = backtrackingScope<Expected<TypeSuffixAbbreviated, Error>>([&]() { 535 return parseTypeSuffixAbbreviated(); 536 }); 537 if (!typeSuffixAbbreviated) 538 break; 539 // FIXME: The nesting here might be in the wrong order. 540 next = constructTypeFromSuffixAbbreviated(*typeSuffixAbbreviated, WTFMove(result)); 492 ASSERT(addressSpaceToken->type == Lexer::Token::Type::Thread); 493 addressSpace = AST::AddressSpace::Thread; 494 break; 495 } 496 auto constructTypeFromSuffixAbbreviated = [&](const TypeSuffixAbbreviated& typeSuffixAbbreviated, UniqueRef<AST::UnnamedType>&& previous) -> UniqueRef<AST::UnnamedType> { 497 switch (typeSuffixAbbreviated.token.type) { 498 case Lexer::Token::Type::Star: 499 return { makeUniqueRef<AST::PointerType>(Lexer::Token(typeSuffixAbbreviated.token), addressSpace, WTFMove(previous)) }; 500 case Lexer::Token::Type::SquareBracketPair: 501 return { makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(typeSuffixAbbreviated.token), addressSpace, WTFMove(previous)) }; 502 default: 503 ASSERT(typeSuffixAbbreviated.token.type == Lexer::Token::Type::LeftSquareBracket); 504 return { makeUniqueRef<AST::ArrayType>(Lexer::Token(typeSuffixAbbreviated.token), WTFMove(previous), *typeSuffixAbbreviated.numElements) }; 505 } 506 }; 507 PARSE(firstTypeSuffixAbbreviated, TypeSuffixAbbreviated); 508 UniqueRef<AST::UnnamedType> result = makeUniqueRef<AST::TypeReference>(WTFMove(*addressSpaceToken), name->stringView.toString(), WTFMove(*typeArguments)); 509 auto next = constructTypeFromSuffixAbbreviated(*firstTypeSuffixAbbreviated, WTFMove(result)); 541 510 result = WTFMove(next); 542 } 543 544 return WTFMove(result); 545 } 546 547 auto Parser::parseNonAddressSpaceType() -> Expected<UniqueRef<AST::UnnamedType>, Error> 548 { 549 auto origin = peek(); 550 if (!origin) 551 return Unexpected<Error>(origin.error()); 552 auto name = consumeType(Lexer::Token::Type::Identifier); 553 if (!name) 554 return Unexpected<Error>(name.error()); 555 auto typeArguments = parseTypeArguments(); 556 if (!typeArguments) 557 return Unexpected<Error>(typeArguments.error()); 511 while (true) { 512 PEEK(nextToken); 513 if (nextToken->type != Lexer::Token::Type::Star 514 && nextToken->type != Lexer::Token::Type::SquareBracketPair 515 && nextToken->type != Lexer::Token::Type::LeftSquareBracket) { 516 break; 517 } 518 PARSE(typeSuffixAbbreviated, TypeSuffixAbbreviated); 519 // FIXME: The nesting here might be in the wrong order. 520 next = constructTypeFromSuffixAbbreviated(*typeSuffixAbbreviated, WTFMove(result)); 521 result = WTFMove(next); 522 } 523 return WTFMove(result); 524 } 558 525 559 526 auto constructTypeFromSuffixNonAbbreviated = [&](const TypeSuffixNonAbbreviated& typeSuffixNonAbbreviated, UniqueRef<AST::UnnamedType>&& previous) -> UniqueRef<AST::UnnamedType> { … … 568 535 } 569 536 }; 570 571 UniqueRef<AST::UnnamedType> result = makeUniqueRef<AST::TypeReference>(WTFMove(*origin), name->stringView.toString(), WTFMove(*typeArguments)); 537 UniqueRef<AST::UnnamedType> result = makeUniqueRef<AST::TypeReference>(WTFMove(*name), name->stringView.toString(), WTFMove(*typeArguments)); 572 538 while (true) { 573 auto typeSuffixNonAbbreviated = backtrackingScope<Expected<TypeSuffixNonAbbreviated, Error>>([&]() { 574 return parseTypeSuffixNonAbbreviated(); 575 }); 576 if (!typeSuffixNonAbbreviated) 577 break; 539 PEEK(nextToken); 540 if (nextToken->type != Lexer::Token::Type::Star 541 && nextToken->type != Lexer::Token::Type::SquareBracketPair 542 && nextToken->type != Lexer::Token::Type::LeftSquareBracket) { 543 break; 544 } 545 PARSE(typeSuffixNonAbbreviated, TypeSuffixNonAbbreviated); 578 546 // FIXME: The nesting here might be in the wrong order. 579 547 auto next = constructTypeFromSuffixNonAbbreviated(*typeSuffixNonAbbreviated, WTFMove(result)); 580 548 result = WTFMove(next); 581 549 } 582 583 550 return WTFMove(result); 584 551 } 585 552 586 auto Parser::parseType() -> Expected<UniqueRef<AST::UnnamedType>, Error>587 {588 {589 auto type = backtrackingScope<Expected<UniqueRef<AST::UnnamedType>, Error>>([&]() {590 return parseAddressSpaceType();591 });592 if (type)593 return type;594 }595 596 auto type = backtrackingScope<Expected<UniqueRef<AST::UnnamedType>, Error>>([&]() {597 return parseNonAddressSpaceType();598 });599 if (type)600 return type;601 602 return Unexpected<Error>(type.error());603 }604 605 553 auto Parser::parseTypeDefinition() -> Expected<AST::TypeDefinition, Error> 606 554 { 607 auto origin = consumeType(Lexer::Token::Type::Typedef); 608 if (!origin) 609 return Unexpected<Error>(origin.error()); 610 auto name = consumeType(Lexer::Token::Type::Identifier); 611 if (!name) 612 return Unexpected<Error>(name.error()); 613 auto equals = consumeType(Lexer::Token::Type::EqualsSign); 614 if (!equals) 615 return Unexpected<Error>(equals.error()); 616 auto type = parseType(); 617 if (!type) 618 return Unexpected<Error>(type.error()); 619 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 620 if (!semicolon) 621 return Unexpected<Error>(semicolon.error()); 555 CONSUME_TYPE(origin, Typedef); 556 CONSUME_TYPE(name, Identifier); 557 CONSUME_TYPE(equals, EqualsSign); 558 PARSE(type, Type); 559 CONSUME_TYPE(semicolon, Semicolon); 622 560 return AST::TypeDefinition(WTFMove(*origin), name->stringView.toString(), WTFMove(*type)); 623 561 } … … 682 620 auto Parser::parseResourceSemantic() -> Expected<AST::ResourceSemantic, Error> 683 621 { 684 auto origin = consumeType(Lexer::Token::Type::Register); 685 if (!origin) 686 return Unexpected<Error>(origin.error()); 687 688 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); 689 if (!leftParenthesis) 690 return Unexpected<Error>(leftParenthesis.error()); 691 692 auto info = consumeType(Lexer::Token::Type::Identifier); 693 if (!info) 694 return Unexpected<Error>(info.error()); 622 CONSUME_TYPE(origin, Register); 623 CONSUME_TYPE(leftParenthesis, LeftParenthesis); 624 625 CONSUME_TYPE(info, Identifier); 695 626 if (info->stringView.length() < 2 || (info->stringView[0] != 'u' 696 627 && info->stringView[0] != 't' … … 721 652 unsigned space = 0; 722 653 if (tryType(Lexer::Token::Type::Comma)) { 723 auto spaceToken = consumeType(Lexer::Token::Type::Identifier); 724 if (!spaceToken) 725 return Unexpected<Error>(spaceToken.error()); 654 CONSUME_TYPE(spaceToken, Identifier); 726 655 auto prefix = "space"_str; 727 656 if (!spaceToken->stringView.startsWith(StringView(prefix))) … … 735 664 } 736 665 737 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 738 if (!rightParenthesis) 739 return Unexpected<Error>(rightParenthesis.error()); 666 CONSUME_TYPE(rightParenthesis, RightParenthesis); 740 667 741 668 return AST::ResourceSemantic(WTFMove(*origin), mode, *index, space); … … 744 671 auto Parser::parseSpecializationConstantSemantic() -> Expected<AST::SpecializationConstantSemantic, Error> 745 672 { 746 auto origin = consumeType(Lexer::Token::Type::Specialized); 747 if (!origin) 748 return Unexpected<Error>(origin.error()); 673 CONSUME_TYPE(origin, Specialized); 749 674 return AST::SpecializationConstantSemantic(WTFMove(*origin)); 750 675 } … … 752 677 auto Parser::parseStageInOutSemantic() -> Expected<AST::StageInOutSemantic, Error> 753 678 { 754 auto origin = consumeType(Lexer::Token::Type::Attribute); 755 if (!origin) 756 return Unexpected<Error>(origin.error()); 757 758 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); 759 if (!leftParenthesis) 760 return Unexpected<Error>(leftParenthesis.error()); 679 CONSUME_TYPE(origin, Attribute); 680 CONSUME_TYPE(leftParenthesis, LeftParenthesis); 761 681 762 682 auto index = consumeNonNegativeIntegralLiteral(); … … 764 684 return Unexpected<Error>(index.error()); 765 685 766 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 767 if (!rightParenthesis) 768 return Unexpected<Error>(rightParenthesis.error()); 686 CONSUME_TYPE(rightParenthesis, RightParenthesis); 769 687 770 688 return AST::StageInOutSemantic(WTFMove(*origin), *index); 771 689 } 772 690 773 auto Parser::parseSemantic() -> Expected<AST::Semantic, Error> 774 { 775 auto builtInSemantic = backtrackingScope<Expected<AST::BuiltInSemantic, Error>>([&]() { 776 return parseBuiltInSemantic(); 777 }); 778 if (builtInSemantic) 779 return AST::Semantic(WTFMove(*builtInSemantic)); 780 781 auto resourceSemantic = backtrackingScope<Expected<AST::ResourceSemantic, Error>>([&]() { 782 return parseResourceSemantic(); 783 }); 784 if (resourceSemantic) 785 return AST::Semantic(WTFMove(*resourceSemantic)); 786 787 auto specializationConstantSemantic = backtrackingScope<Expected<AST::SpecializationConstantSemantic, Error>>([&]() { 788 return parseSpecializationConstantSemantic(); 789 }); 790 if (specializationConstantSemantic) 791 return AST::Semantic(WTFMove(*specializationConstantSemantic)); 792 793 auto stageInOutSemantic = backtrackingScope<Expected<AST::StageInOutSemantic, Error>>([&]() { 794 return parseStageInOutSemantic(); 795 }); 796 if (stageInOutSemantic) 797 return AST::Semantic(WTFMove(*stageInOutSemantic)); 798 799 return Unexpected<Error>(stageInOutSemantic.error()); 691 auto Parser::parseSemantic() -> Expected<Optional<AST::Semantic>, Error> 692 { 693 if (!tryType(Lexer::Token::Type::Colon)) 694 return { WTF::nullopt }; 695 696 PEEK(token); 697 switch (token->type) { 698 case Lexer::Token::Type::Attribute: { 699 PARSE(result, StageInOutSemantic); 700 return { AST::Semantic(WTFMove(*result)) }; 701 } 702 case Lexer::Token::Type::Specialized: { 703 PARSE(result, SpecializationConstantSemantic); 704 return { AST::Semantic(WTFMove(*result)) }; 705 } 706 case Lexer::Token::Type::Register: { 707 PARSE(result, ResourceSemantic); 708 return { AST::Semantic(WTFMove(*result)) }; 709 } 710 default: { 711 PARSE(result, BuiltInSemantic); 712 return { AST::Semantic(WTFMove(*result)) }; 713 } 714 } 800 715 } 801 716 AST::Qualifiers Parser::parseQualifiers() 802 717 { 803 718 AST::Qualifiers qualifiers; 804 while (true) { 805 if (auto next = tryType(Lexer::Token::Type::Qualifier)) { 806 if ("nointerpolation" == next->stringView) 807 qualifiers.append(AST::Qualifier::Nointerpolation); 808 else if ("noperspective" == next->stringView) 809 qualifiers.append(AST::Qualifier::Noperspective); 810 else if ("uniform" == next->stringView) 811 qualifiers.append(AST::Qualifier::Uniform); 812 else if ("centroid" == next->stringView) 813 qualifiers.append(AST::Qualifier::Centroid); 814 else { 815 ASSERT("sample" == next->stringView); 816 qualifiers.append(AST::Qualifier::Sample); 817 } 818 } else 819 break; 719 while (auto next = tryType(Lexer::Token::Type::Qualifier)) { 720 if ("nointerpolation" == next->stringView) 721 qualifiers.append(AST::Qualifier::Nointerpolation); 722 else if ("noperspective" == next->stringView) 723 qualifiers.append(AST::Qualifier::Noperspective); 724 else if ("uniform" == next->stringView) 725 qualifiers.append(AST::Qualifier::Uniform); 726 else if ("centroid" == next->stringView) 727 qualifiers.append(AST::Qualifier::Centroid); 728 else { 729 ASSERT("sample" == next->stringView); 730 qualifiers.append(AST::Qualifier::Sample); 731 } 820 732 } 821 733 return qualifiers; … … 824 736 auto Parser::parseStructureElement() -> Expected<AST::StructureElement, Error> 825 737 { 826 auto origin = peek(); 827 if (!origin) 828 return Unexpected<Error>(origin.error()); 738 PEEK(origin); 829 739 830 740 AST::Qualifiers qualifiers = parseQualifiers(); 831 741 832 auto type = parseType(); 833 if (!type) 834 return Unexpected<Error>(type.error()); 835 836 auto name = consumeType(Lexer::Token::Type::Identifier); 837 if (!name) 838 return Unexpected<Error>(name.error()); 839 840 if (tryType(Lexer::Token::Type::Colon)) { 841 auto semantic = parseSemantic(); 842 if (!semantic) 843 return Unexpected<Error>(semantic.error()); 844 845 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 846 if (!semicolon) 847 return Unexpected<Error>(semicolon.error()); 848 849 return AST::StructureElement(WTFMove(*origin), WTFMove(qualifiers), WTFMove(*type), name->stringView.toString(), WTFMove(*semantic)); 850 } 851 852 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 853 if (!semicolon) 854 return Unexpected<Error>(semicolon.error()); 855 856 return AST::StructureElement(WTFMove(*origin), WTFMove(qualifiers), WTFMove(*type), name->stringView.toString(), WTF::nullopt); 742 PARSE(type, Type); 743 CONSUME_TYPE(name, Identifier); 744 PARSE(semantic, Semantic); 745 CONSUME_TYPE(semicolon, Semicolon); 746 747 return AST::StructureElement(WTFMove(*origin), WTFMove(qualifiers), WTFMove(*type), name->stringView.toString(), WTFMove(*semantic)); 857 748 } 858 749 859 750 auto Parser::parseStructureDefinition() -> Expected<AST::StructureDefinition, Error> 860 751 { 861 auto origin = consumeType(Lexer::Token::Type::Struct); 862 if (!origin) 863 return Unexpected<Error>(origin.error()); 864 865 auto name = consumeType(Lexer::Token::Type::Identifier); 866 if (!name) 867 return Unexpected<Error>(name.error()); 868 869 auto leftCurlyBracket = consumeType(Lexer::Token::Type::LeftCurlyBracket); 870 if (!leftCurlyBracket) 871 return Unexpected<Error>(leftCurlyBracket.error()); 752 CONSUME_TYPE(origin, Struct); 753 CONSUME_TYPE(name, Identifier); 754 CONSUME_TYPE(leftCurlyBracket, LeftCurlyBracket); 872 755 873 756 AST::StructureElements structureElements; 874 while (true) { 875 auto structureElement = backtrackingScope<Expected<AST::StructureElement, Error>>([&]() { 876 return parseStructureElement(); 877 }); 878 if (structureElement) 879 structureElements.append(WTFMove(*structureElement)); 880 else 881 break; 882 } 883 884 auto rightCurlyBracket = consumeType(Lexer::Token::Type::RightCurlyBracket); 885 if (!rightCurlyBracket) 886 return Unexpected<Error>(rightCurlyBracket.error()); 757 while (!tryType(Lexer::Token::Type::RightCurlyBracket)) { 758 PARSE(structureElement, StructureElement); 759 structureElements.append(WTFMove(*structureElement)); 760 } 887 761 888 762 return AST::StructureDefinition(WTFMove(*origin), name->stringView.toString(), WTFMove(structureElements)); … … 891 765 auto Parser::parseEnumerationDefinition() -> Expected<AST::EnumerationDefinition, Error> 892 766 { 893 auto origin = consumeType(Lexer::Token::Type::Enum); 894 if (!origin) 895 return Unexpected<Error>(origin.error()); 896 897 auto name = consumeType(Lexer::Token::Type::Identifier); 898 if (!name) 899 return Unexpected<Error>(name.error()); 767 CONSUME_TYPE(origin, Enum); 768 CONSUME_TYPE(name, Identifier); 900 769 901 770 auto type = ([&]() -> Expected<UniqueRef<AST::UnnamedType>, Error> { 902 771 if (tryType(Lexer::Token::Type::Colon)) { 903 auto parsedType = parseType(); 904 if (!parsedType) 905 return Unexpected<Error>(parsedType.error()); 772 PARSE(parsedType, Type); 906 773 return WTFMove(*parsedType); 907 774 } … … 911 778 return Unexpected<Error>(type.error()); 912 779 913 auto leftCurlyBracket = consumeType(Lexer::Token::Type::LeftCurlyBracket); 914 if (!leftCurlyBracket) 915 return Unexpected<Error>(leftCurlyBracket.error()); 916 917 auto firstEnumerationMember = parseEnumerationMember(); 918 if (!firstEnumerationMember) 919 return Unexpected<Error>(firstEnumerationMember.error()); 780 CONSUME_TYPE(leftCurlyBracket, LeftCurlyBracket); 781 782 PARSE(firstEnumerationMember, EnumerationMember); 920 783 921 784 AST::EnumerationDefinition result(WTFMove(*origin), name->stringView.toString(), WTFMove(*type)); … … 925 788 926 789 while (tryType(Lexer::Token::Type::Comma)) { 927 auto member = parseEnumerationMember(); 928 if (!member) 929 return Unexpected<Error>(member.error()); 790 PARSE(member, EnumerationMember); 930 791 success = result.add(WTFMove(*member)); 931 792 if (!success) … … 933 794 } 934 795 935 auto rightCurlyBracket = consumeType(Lexer::Token::Type::RightCurlyBracket); 936 if (!rightCurlyBracket) 937 return Unexpected<Error>(rightCurlyBracket.error()); 796 CONSUME_TYPE(rightCurlyBracket, RightCurlyBracket); 938 797 939 798 return WTFMove(result); … … 942 801 auto Parser::parseEnumerationMember() -> Expected<AST::EnumerationMember, Error> 943 802 { 944 auto identifier = consumeType(Lexer::Token::Type::Identifier); 945 if (!identifier) 946 return Unexpected<Error>(identifier.error()); 803 CONSUME_TYPE(identifier, Identifier); 947 804 auto name = identifier->stringView.toString(); 948 805 949 806 if (tryType(Lexer::Token::Type::EqualsSign)) { 950 auto constantExpression = parseConstantExpression(); 951 if (!constantExpression) 952 return Unexpected<Error>(constantExpression.error()); 807 PARSE(constantExpression, ConstantExpression); 953 808 return AST::EnumerationMember(Lexer::Token(*identifier), WTFMove(name), WTFMove(*constantExpression)); 954 809 } … … 958 813 auto Parser::parseNativeTypeDeclaration() -> Expected<AST::NativeTypeDeclaration, Error> 959 814 { 960 auto origin = consumeType(Lexer::Token::Type::Native); 961 if (!origin) 962 return Unexpected<Error>(origin.error()); 963 964 auto parsedTypedef = consumeType(Lexer::Token::Type::Typedef); 965 if (!parsedTypedef) 966 return Unexpected<Error>(parsedTypedef.error()); 967 968 auto name = consumeType(Lexer::Token::Type::Identifier); 969 if (!name) 970 return Unexpected<Error>(name.error()); 971 972 auto typeArguments = parseTypeArguments(); 973 if (!typeArguments) 974 return Unexpected<Error>(typeArguments.error()); 975 976 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 977 if (!semicolon) 978 return Unexpected<Error>(semicolon.error()); 815 CONSUME_TYPE(origin, Native); 816 CONSUME_TYPE(parsedTypedef, Typedef); 817 CONSUME_TYPE(name, Identifier); 818 PARSE(typeArguments, TypeArguments); 819 CONSUME_TYPE(semicolon, Semicolon); 979 820 980 821 return AST::NativeTypeDeclaration(WTFMove(*origin), name->stringView.toString(), WTFMove(*typeArguments)); … … 983 824 auto Parser::parseNumThreadsFunctionAttribute() -> Expected<AST::NumThreadsFunctionAttribute, Error> 984 825 { 985 auto origin = consumeType(Lexer::Token::Type::NumThreads); 986 if (!origin) 987 return Unexpected<Error>(origin.error()); 988 989 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); 990 if (!leftParenthesis) 991 return Unexpected<Error>(leftParenthesis.error()); 826 CONSUME_TYPE(origin, NumThreads); 827 CONSUME_TYPE(leftParenthesis, LeftParenthesis); 992 828 993 829 auto width = consumeNonNegativeIntegralLiteral(); … … 995 831 return Unexpected<Error>(width.error()); 996 832 997 auto comma = consumeType(Lexer::Token::Type::Comma); 998 if (!comma) 999 return Unexpected<Error>(comma.error()); 833 CONSUME_TYPE(comma, Comma); 1000 834 1001 835 auto height = consumeNonNegativeIntegralLiteral(); … … 1003 837 return Unexpected<Error>(height.error()); 1004 838 1005 comma = consumeType(Lexer::Token::Type::Comma); 1006 if (!comma) 1007 return Unexpected<Error>(comma.error()); 839 CONSUME_TYPE(secondComma, Comma); 1008 840 1009 841 auto depth = consumeNonNegativeIntegralLiteral(); … … 1011 843 return Unexpected<Error>(depth.error()); 1012 844 1013 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 1014 if (!rightParenthesis) 1015 return Unexpected<Error>(rightParenthesis.error()); 845 CONSUME_TYPE(rightParenthesis, RightParenthesis); 1016 846 1017 847 return AST::NumThreadsFunctionAttribute(WTFMove(*origin), *width, *height, *depth); … … 1020 850 auto Parser::parseAttributeBlock() -> Expected<AST::AttributeBlock, Error> 1021 851 { 1022 auto leftSquareBracket = consumeType(Lexer::Token::Type::LeftSquareBracket); 1023 if (!leftSquareBracket) 1024 return Unexpected<Error>(leftSquareBracket.error()); 852 CONSUME_TYPE(leftSquareBracket, LeftSquareBracket); 1025 853 1026 854 AST::AttributeBlock result; … … 1038 866 } 1039 867 1040 auto rightSquareBracket = consumeType(Lexer::Token::Type::RightSquareBracket); 1041 if (!rightSquareBracket) 1042 return Unexpected<Error>(rightSquareBracket.error()); 868 CONSUME_TYPE(rightSquareBracket, RightSquareBracket); 1043 869 1044 870 return WTFMove(result); … … 1047 873 auto Parser::parseParameter() -> Expected<AST::VariableDeclaration, Error> 1048 874 { 1049 auto origin = peek(); 1050 if (!origin) 1051 return Unexpected<Error>(origin.error()); 875 PEEK(origin); 1052 876 1053 877 AST::Qualifiers qualifiers = parseQualifiers(); 1054 878 1055 auto type = parseType(); 1056 if (!type) 1057 return Unexpected<Error>(type.error()); 879 PARSE(type, Type); 1058 880 1059 881 String name; … … 1061 883 name = token->stringView.toString(); 1062 884 1063 if (tryType(Lexer::Token::Type::Colon)) { 1064 auto semantic = parseSemantic(); 1065 if (!semantic) 1066 return Unexpected<Error>(semantic.error()); 1067 return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), Optional<UniqueRef<AST::UnnamedType>>(WTFMove(*type)), WTFMove(name), WTFMove(*semantic), WTF::nullopt); 1068 } 1069 1070 return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(*type) }, WTFMove(name), WTF::nullopt, WTF::nullopt); 885 PARSE(semantic, Semantic); 886 887 return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(*type) }, WTFMove(name), WTFMove(*semantic), WTF::nullopt); 1071 888 } 1072 889 1073 890 auto Parser::parseParameters() -> Expected<AST::VariableDeclarations, Error> 1074 891 { 1075 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis);1076 if (!leftParenthesis)1077 return Unexpected<Error>(leftParenthesis.error());1078 1079 892 AST::VariableDeclarations parameters; 893 894 CONSUME_TYPE(leftParenthesis, LeftParenthesis); 895 1080 896 if (tryType(Lexer::Token::Type::RightParenthesis)) 1081 897 return WTFMove(parameters); 1082 898 1083 auto firstParameter = parseParameter(); 1084 if (!firstParameter) 1085 return Unexpected<Error>(firstParameter.error()); 899 PARSE(firstParameter, Parameter); 1086 900 parameters.append(makeUniqueRef<AST::VariableDeclaration>(WTFMove(*firstParameter))); 1087 901 1088 902 while (tryType(Lexer::Token::Type::Comma)) { 1089 auto parameter = parseParameter(); 1090 if (!parameter) 1091 return Unexpected<Error>(parameter.error()); 903 PARSE(parameter, Parameter); 1092 904 parameters.append(makeUniqueRef<AST::VariableDeclaration>(WTFMove(*parameter))); 1093 905 } 1094 906 1095 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 1096 if (!rightParenthesis) 1097 return Unexpected<Error>(rightParenthesis.error()); 907 CONSUME_TYPE(rightParenthesis, RightParenthesis); 1098 908 1099 909 return WTFMove(parameters); … … 1102 912 auto Parser::parseFunctionDefinition() -> Expected<AST::FunctionDefinition, Error> 1103 913 { 1104 auto functionDeclaration = parseFunctionDeclaration(); 1105 if (!functionDeclaration) 1106 return Unexpected<Error>(functionDeclaration.error()); 1107 1108 auto block = parseBlock(); 1109 if (!block) 1110 return Unexpected<Error>(block.error()); 1111 914 PARSE(functionDeclaration, FunctionDeclaration); 915 PARSE(block, Block); 1112 916 return AST::FunctionDefinition(WTFMove(*functionDeclaration), WTFMove(*block)); 1113 917 } 1114 918 1115 auto Parser::parseEntryPointFunctionDeclaration() -> Expected<AST::FunctionDeclaration, Error> 1116 { 1117 auto origin = peek(); 1118 if (!origin) 1119 return Unexpected<Error>(origin.error()); 1120 1121 AST::AttributeBlock attributeBlock; 1122 AST::EntryPointType entryPointType; 1123 1124 auto parsedAttributeBlock = backtrackingScope<Expected<AST::AttributeBlock, Error>>([&]() { 1125 return parseAttributeBlock(); 1126 }); 1127 if (parsedAttributeBlock) { 1128 auto compute = consumeType(Lexer::Token::Type::Compute); 1129 if (!compute) 1130 return Unexpected<Error>(compute.error()); 1131 attributeBlock = WTFMove(*parsedAttributeBlock); 1132 entryPointType = AST::EntryPointType::Compute; 1133 } else { 1134 auto type = consumeTypes({ Lexer::Token::Type::Vertex, Lexer::Token::Type::Fragment }); 1135 if (!type) 1136 return Unexpected<Error>(type.error()); 1137 1138 switch (origin->type) { 1139 case Lexer::Token::Type::Vertex: 1140 entryPointType = AST::EntryPointType::Vertex; 1141 break; 1142 default: 1143 ASSERT(origin->type == Lexer::Token::Type::Fragment); 1144 entryPointType = AST::EntryPointType::Fragment; 1145 break; 1146 } 1147 } 1148 1149 auto type = parseType(); 1150 if (!type) 1151 return Unexpected<Error>(type.error()); 1152 1153 auto name = consumeType(Lexer::Token::Type::Identifier); 1154 if (!name) 1155 return Unexpected<Error>(name.error()); 1156 1157 auto parameters = parseParameters(); 1158 if (!parameters) 1159 return Unexpected<Error>(parameters.error()); 1160 919 auto Parser::parseComputeFunctionDeclaration() -> Expected<AST::FunctionDeclaration, Error> 920 { 921 PEEK(origin); 922 923 PARSE(attributeBlock, AttributeBlock); 924 CONSUME_TYPE(compute, Compute); 925 PARSE(type, Type); 926 CONSUME_TYPE(name, Identifier); 927 PARSE(parameters, Parameters); 928 PARSE(semantic, Semantic); 1161 929 bool isOperator = false; 1162 1163 if (tryType(Lexer::Token::Type::Colon)) { 1164 auto semantic = parseSemantic(); 1165 if (!semantic) 1166 return Unexpected<Error>(semantic.error()); 1167 return AST::FunctionDeclaration(WTFMove(*origin), WTFMove(attributeBlock), entryPointType, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTFMove(*semantic), isOperator); 1168 } 1169 1170 return AST::FunctionDeclaration(WTFMove(*origin), WTFMove(attributeBlock), entryPointType, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTF::nullopt, isOperator); 930 return AST::FunctionDeclaration(WTFMove(*origin), WTFMove(*attributeBlock), AST::EntryPointType::Compute, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTFMove(*semantic), isOperator); 931 } 932 933 auto Parser::parseVertexOrFragmentFunctionDeclaration() -> Expected<AST::FunctionDeclaration, Error> 934 { 935 auto entryPoint = consumeTypes({ Lexer::Token::Type::Vertex, Lexer::Token::Type::Fragment }); 936 if (!entryPoint) 937 return Unexpected<Error>(entryPoint.error()); 938 auto entryPointType = (entryPoint->type == Lexer::Token::Type::Vertex) ? AST::EntryPointType::Vertex : AST::EntryPointType::Fragment; 939 940 PARSE(type, Type); 941 CONSUME_TYPE(name, Identifier); 942 PARSE(parameters, Parameters); 943 PARSE(semantic, Semantic); 944 945 bool isOperator = false; 946 return AST::FunctionDeclaration(WTFMove(*entryPoint), { }, entryPointType, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTFMove(*semantic), isOperator); 1171 947 } 1172 948 1173 949 auto Parser::parseRegularFunctionDeclaration() -> Expected<AST::FunctionDeclaration, Error> 1174 950 { 1175 auto origin = peek(); 1176 if (!origin) 1177 return Unexpected<Error>(origin.error()); 1178 1179 auto type = parseType(); 1180 if (!type) 1181 return Unexpected<Error>(type.error()); 951 PEEK(origin); 952 953 PARSE(type, Type); 1182 954 1183 955 auto name = consumeTypes({ Lexer::Token::Type::Identifier, Lexer::Token::Type::OperatorName }); … … 1186 958 auto isOperator = name->type == Lexer::Token::Type::OperatorName; 1187 959 1188 auto parameters = parseParameters(); 1189 if (!parameters) 1190 return Unexpected<Error>(parameters.error()); 1191 1192 if (tryType(Lexer::Token::Type::Colon)) { 1193 auto semantic = parseSemantic(); 1194 if (!semantic) 1195 return Unexpected<Error>(semantic.error()); 1196 return AST::FunctionDeclaration(WTFMove(*origin), { }, WTF::nullopt, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTFMove(*semantic), isOperator); 1197 } 1198 1199 return AST::FunctionDeclaration(WTFMove(*origin), { }, WTF::nullopt, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTF::nullopt, isOperator); 960 PARSE(parameters, Parameters); 961 PARSE(semantic, Semantic); 962 963 return AST::FunctionDeclaration(WTFMove(*origin), { }, WTF::nullopt, WTFMove(*type), name->stringView.toString(), WTFMove(*parameters), WTFMove(*semantic), isOperator); 1200 964 } 1201 965 1202 966 auto Parser::parseOperatorFunctionDeclaration() -> Expected<AST::FunctionDeclaration, Error> 1203 967 { 1204 auto origin = consumeType(Lexer::Token::Type::Operator); 1205 if (!origin) 1206 return Unexpected<Error>(origin.error()); 1207 1208 auto type = parseType(); 1209 if (!type) 1210 return Unexpected<Error>(type.error()); 1211 1212 auto parameters = parseParameters(); 1213 if (!parameters) 1214 return Unexpected<Error>(parameters.error()); 968 CONSUME_TYPE(origin, Operator); 969 PARSE(type, Type); 970 PARSE(parameters, Parameters); 971 PARSE(semantic, Semantic); 1215 972 1216 973 bool isOperator = true; 1217 1218 if (tryType(Lexer::Token::Type::Colon)) { 1219 auto semantic = parseSemantic(); 1220 if (!semantic) 1221 return Unexpected<Error>(semantic.error()); 1222 return AST::FunctionDeclaration(WTFMove(*origin), { }, WTF::nullopt, WTFMove(*type), "operator cast"_str, WTFMove(*parameters), WTFMove(*semantic), isOperator); 1223 } 1224 1225 return AST::FunctionDeclaration(WTFMove(*origin), { }, WTF::nullopt, WTFMove(*type), "operator cast"_str, WTFMove(*parameters), WTF::nullopt, isOperator); 974 return AST::FunctionDeclaration(WTFMove(*origin), { }, WTF::nullopt, WTFMove(*type), "operator cast"_str, WTFMove(*parameters), WTFMove(*semantic), isOperator); 1226 975 } 1227 976 1228 977 auto Parser::parseFunctionDeclaration() -> Expected<AST::FunctionDeclaration, Error> 1229 978 { 1230 auto entryPointFunctionDeclaration = backtrackingScope<Expected<AST::FunctionDeclaration, Error>>([&]() { 1231 return parseEntryPointFunctionDeclaration(); 1232 }); 1233 if (entryPointFunctionDeclaration) 1234 return WTFMove(*entryPointFunctionDeclaration); 1235 1236 auto regularFunctionDeclaration = backtrackingScope<Expected<AST::FunctionDeclaration, Error>>([&]() { 979 PEEK(token); 980 switch (token->type) { 981 case Lexer::Token::Type::Operator: 982 return parseOperatorFunctionDeclaration(); 983 case Lexer::Token::Type::Vertex: 984 case Lexer::Token::Type::Fragment: 985 return parseVertexOrFragmentFunctionDeclaration(); 986 case Lexer::Token::Type::LeftSquareBracket: 987 return parseComputeFunctionDeclaration(); 988 default: 1237 989 return parseRegularFunctionDeclaration(); 1238 }); 1239 if (regularFunctionDeclaration) 1240 return WTFMove(*regularFunctionDeclaration); 1241 1242 auto operatorFunctionDeclaration = backtrackingScope<Expected<AST::FunctionDeclaration, Error>>([&]() { 1243 return parseOperatorFunctionDeclaration(); 1244 }); 1245 if (operatorFunctionDeclaration) 1246 return WTFMove(*operatorFunctionDeclaration); 1247 1248 return Unexpected<Error>(operatorFunctionDeclaration.error()); 990 } 1249 991 } 1250 992 1251 993 auto Parser::parseNativeFunctionDeclaration() -> Expected<AST::NativeFunctionDeclaration, Error> 1252 994 { 1253 Optional<Lexer::Token> origin; 1254 1255 auto native = consumeType(Lexer::Token::Type::Native); 1256 if (!native) 1257 return Unexpected<Error>(native.error()); 1258 if (!origin) 1259 origin = *native; 1260 1261 auto functionDeclaration = parseFunctionDeclaration(); 1262 if (!functionDeclaration) 1263 return Unexpected<Error>(functionDeclaration.error()); 1264 1265 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1266 if (!semicolon) 1267 return Unexpected<Error>(semicolon.error()); 995 CONSUME_TYPE(native, Native); 996 PARSE(functionDeclaration, FunctionDeclaration); 997 CONSUME_TYPE(semicolon, Semicolon); 1268 998 1269 999 return AST::NativeFunctionDeclaration(WTFMove(*functionDeclaration)); … … 1272 1002 auto Parser::parseBlock() -> Expected<AST::Block, Error> 1273 1003 { 1274 auto origin = consumeType(Lexer::Token::Type::LeftCurlyBracket); 1275 if (!origin) 1276 return Unexpected<Error>(origin.error()); 1277 1278 auto result = parseBlockBody(WTFMove(*origin)); 1279 1280 auto rightCurlyBracket = consumeType(Lexer::Token::Type::RightCurlyBracket); 1281 if (!rightCurlyBracket) 1282 return Unexpected<Error>(rightCurlyBracket.error()); 1283 1284 return WTFMove(result); 1285 } 1286 1287 AST::Block Parser::parseBlockBody(Lexer::Token&& origin) 1004 CONSUME_TYPE(origin, LeftCurlyBracket); 1005 PARSE(result, BlockBody, WTFMove(*origin)); 1006 CONSUME_TYPE(rightCurlyBracket, RightCurlyBracket); 1007 return WTFMove(*result); 1008 } 1009 1010 auto Parser::parseBlockBody(Lexer::Token&& origin) -> Expected<AST::Block, Error> 1288 1011 { 1289 1012 AST::Statements statements; 1290 while (true) { 1291 auto statement = backtrackingScope<Expected<UniqueRef<AST::Statement>, Error>>([&]() { 1292 return parseStatement(); 1293 }); 1294 if (statement) 1295 statements.append(WTFMove(*statement)); 1296 else 1297 break; 1013 while (!peekTypes({Lexer::Token::Type::RightCurlyBracket, Lexer::Token::Type::Case, Lexer::Token::Type::Default})) { 1014 PARSE(statement, Statement); 1015 statements.append(WTFMove(*statement)); 1298 1016 } 1299 1017 return AST::Block(WTFMove(origin), WTFMove(statements)); … … 1302 1020 auto Parser::parseIfStatement() -> Expected<AST::IfStatement, Error> 1303 1021 { 1304 auto origin = consumeType(Lexer::Token::Type::If); 1305 if (!origin) 1306 return Unexpected<Error>(origin.error()); 1307 1308 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); 1309 if (!leftParenthesis) 1310 return Unexpected<Error>(leftParenthesis.error()); 1311 1312 auto conditional = parseExpression(); 1313 if (!conditional) 1314 return Unexpected<Error>(conditional.error()); 1315 1316 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 1317 if (!rightParenthesis) 1318 return Unexpected<Error>(rightParenthesis.error()); 1319 1320 auto body = parseStatement(); 1321 if (!body) 1322 return Unexpected<Error>(body.error()); 1022 CONSUME_TYPE(origin, If); 1023 CONSUME_TYPE(leftParenthesis, LeftParenthesis); 1024 PARSE(conditional, Expression); 1025 CONSUME_TYPE(rightParenthesis, RightParenthesis); 1026 PARSE(body, Statement); 1323 1027 1324 1028 Optional<UniqueRef<AST::Statement>> elseBody; 1325 1029 if (tryType(Lexer::Token::Type::Else)) { 1326 auto parsedElseBody = parseStatement(); 1327 if (!parsedElseBody) 1328 return Unexpected<Error>(parsedElseBody.error()); 1030 PARSE(parsedElseBody, Statement); 1329 1031 elseBody = WTFMove(*parsedElseBody); 1330 1032 } … … 1338 1040 auto Parser::parseSwitchStatement() -> Expected<AST::SwitchStatement, Error> 1339 1041 { 1340 auto origin = consumeType(Lexer::Token::Type::Switch); 1341 if (!origin) 1342 return Unexpected<Error>(origin.error()); 1343 1344 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); 1345 if (!leftParenthesis) 1346 return Unexpected<Error>(leftParenthesis.error()); 1347 1348 auto value = parseExpression(); 1349 if (!value) 1350 return Unexpected<Error>(value.error()); 1351 1352 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 1353 if (!rightParenthesis) 1354 return Unexpected<Error>(rightParenthesis.error()); 1355 1356 auto leftCurlyBracket = consumeType(Lexer::Token::Type::LeftCurlyBracket); 1357 if (!leftCurlyBracket) 1358 return Unexpected<Error>(leftCurlyBracket.error()); 1042 CONSUME_TYPE(origin, Switch); 1043 CONSUME_TYPE(leftParenthesis, LeftParenthesis); 1044 PARSE(value, Expression); 1045 CONSUME_TYPE(rightParenthesis, RightParenthesis); 1046 CONSUME_TYPE(leftCurlyBracket, LeftCurlyBracket); 1359 1047 1360 1048 Vector<AST::SwitchCase> switchCases; 1361 while (true) { 1362 auto switchCase = backtrackingScope<Expected<AST::SwitchCase, Error>>([&]() { 1363 return parseSwitchCase(); 1364 }); 1365 if (switchCase) 1366 switchCases.append(WTFMove(*switchCase)); 1367 else 1368 break; 1369 } 1370 1371 auto rightCurlyBracket = consumeType(Lexer::Token::Type::RightCurlyBracket); 1372 if (!rightCurlyBracket) 1373 return Unexpected<Error>(rightCurlyBracket.error()); 1049 PEEK(nextToken); 1050 while (nextToken->type != Lexer::Token::Type::RightCurlyBracket) { 1051 PARSE(switchCase, SwitchCase); 1052 switchCases.append(WTFMove(*switchCase)); 1053 PEEK(nextTokenInLoop); 1054 nextToken = nextTokenInLoop; 1055 } 1056 1057 m_lexer.consumeToken(); 1374 1058 1375 1059 return AST::SwitchStatement(WTFMove(*origin), WTFMove(*value), WTFMove(switchCases)); … … 1384 1068 switch (origin->type) { 1385 1069 case Lexer::Token::Type::Case: { 1386 auto value = parseConstantExpression(); 1387 if (!value) 1388 return Unexpected<Error>(value.error()); 1389 1390 auto origin = consumeType(Lexer::Token::Type::Colon); 1391 if (!origin) 1392 return Unexpected<Error>(origin.error()); 1393 1394 auto block = parseBlockBody(Lexer::Token(*origin)); 1395 1396 return AST::SwitchCase(WTFMove(*origin), WTFMove(*value), WTFMove(block)); 1070 PARSE(value, ConstantExpression); 1071 CONSUME_TYPE(colon, Colon); 1072 1073 PARSE(block, BlockBody, Lexer::Token(*origin)); 1074 1075 return AST::SwitchCase(WTFMove(*origin), WTFMove(*value), WTFMove(*block)); 1397 1076 } 1398 1077 default: { 1399 1078 ASSERT(origin->type == Lexer::Token::Type::Default); 1400 auto origin = consumeType(Lexer::Token::Type::Colon); 1401 if (!origin) 1402 return Unexpected<Error>(origin.error()); 1403 1404 auto block = parseBlockBody(Lexer::Token(*origin)); 1405 1406 return AST::SwitchCase(WTFMove(*origin), WTF::nullopt, WTFMove(block)); 1079 CONSUME_TYPE(colon, Colon); 1080 1081 PARSE(block, BlockBody, Lexer::Token(*origin)); 1082 1083 return AST::SwitchCase(WTFMove(*origin), WTF::nullopt, WTFMove(*block)); 1407 1084 } 1408 1085 } … … 1411 1088 auto Parser::parseForLoop() -> Expected<AST::ForLoop, Error> 1412 1089 { 1413 auto origin = consumeType(Lexer::Token::Type::For); 1414 if (!origin) 1415 return Unexpected<Error>(origin.error()); 1090 CONSUME_TYPE(origin, For); 1091 CONSUME_TYPE(leftParenthesis, LeftParenthesis); 1416 1092 1417 1093 auto parseRemainder = [&](Variant<UniqueRef<AST::Statement>, UniqueRef<AST::Expression>>&& initialization) -> Expected<AST::ForLoop, Error> { 1418 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1419 if (!semicolon) 1420 return Unexpected<Error>(semicolon.error()); 1421 1422 auto condition = backtrackingScope<Optional<UniqueRef<AST::Expression>>>([&]() -> Optional<UniqueRef<AST::Expression>> { 1094 CONSUME_TYPE(semicolon, Semicolon); 1095 1096 Optional<UniqueRef<AST::Expression>> condition = WTF::nullopt; 1097 if (!tryType(Lexer::Token::Type::Semicolon)) { 1423 1098 if (auto expression = parseExpression()) 1424 return { WTFMove(*expression) }; 1425 return WTF::nullopt; 1426 }); 1427 1428 semicolon = consumeType(Lexer::Token::Type::Semicolon); 1429 if (!semicolon) 1430 return Unexpected<Error>(semicolon.error()); 1431 1432 auto increment = backtrackingScope<Optional<UniqueRef<AST::Expression>>>([&]() -> Optional<UniqueRef<AST::Expression>> { 1099 condition = { WTFMove(*expression) }; 1100 else 1101 return Unexpected<Error>(expression.error()); 1102 CONSUME_TYPE(secondSemicolon, Semicolon); 1103 } 1104 1105 Optional<UniqueRef<AST::Expression>> increment = WTF::nullopt; 1106 if (!tryType(Lexer::Token::Type::RightParenthesis)) { 1433 1107 if (auto expression = parseExpression()) 1434 return { WTFMove(*expression) }; 1435 return WTF::nullopt; 1436 }); 1437 1438 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 1439 if (!rightParenthesis) 1440 return Unexpected<Error>(rightParenthesis.error()); 1441 1442 auto body = parseStatement(); 1443 if (!body) 1444 return Unexpected<Error>(body.error()); 1108 increment = { WTFMove(*expression) }; 1109 else 1110 return Unexpected<Error>(expression.error()); 1111 CONSUME_TYPE(rightParenthesis, RightParenthesis); 1112 } 1113 1114 PARSE(body, Statement); 1445 1115 1446 1116 return AST::ForLoop(WTFMove(*origin), WTFMove(initialization), WTFMove(condition), WTFMove(increment), WTFMove(*body)); 1447 1117 }; 1448 1449 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis);1450 if (!leftParenthesis)1451 return Unexpected<Error>(leftParenthesis.error());1452 1118 1453 1119 auto variableDeclarations = backtrackingScope<Expected<AST::VariableDeclarationsStatement, Error>>([&]() { … … 1459 1125 } 1460 1126 1461 auto effectfulExpression = parseEffectfulExpression(); 1462 if (!effectfulExpression) 1463 return Unexpected<Error>(effectfulExpression.error()); 1127 PARSE(effectfulExpression, EffectfulExpression); 1464 1128 1465 1129 return parseRemainder(WTFMove(*effectfulExpression)); … … 1468 1132 auto Parser::parseWhileLoop() -> Expected<AST::WhileLoop, Error> 1469 1133 { 1470 auto origin = consumeType(Lexer::Token::Type::While); 1471 if (!origin) 1472 return Unexpected<Error>(origin.error()); 1473 1474 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); 1475 if (!leftParenthesis) 1476 return Unexpected<Error>(leftParenthesis.error()); 1477 1478 auto conditional = parseExpression(); 1479 if (!conditional) 1480 return Unexpected<Error>(conditional.error()); 1481 1482 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 1483 if (!rightParenthesis) 1484 return Unexpected<Error>(rightParenthesis.error()); 1485 1486 auto body = parseStatement(); 1487 if (!body) 1488 return Unexpected<Error>(body.error()); 1134 CONSUME_TYPE(origin, While); 1135 CONSUME_TYPE(leftParenthesis, LeftParenthesis); 1136 PARSE(conditional, Expression); 1137 CONSUME_TYPE(rightParenthesis, RightParenthesis); 1138 PARSE(body, Statement); 1489 1139 1490 1140 return AST::WhileLoop(WTFMove(*origin), WTFMove(*conditional), WTFMove(*body)); … … 1493 1143 auto Parser::parseDoWhileLoop() -> Expected<AST::DoWhileLoop, Error> 1494 1144 { 1495 auto origin = consumeType(Lexer::Token::Type::Do); 1496 if (!origin) 1497 return Unexpected<Error>(origin.error()); 1498 1499 auto body = parseStatement(); 1500 if (!body) 1501 return Unexpected<Error>(body.error()); 1502 1503 auto whileKeyword = consumeType(Lexer::Token::Type::While); 1504 if (!whileKeyword) 1505 return Unexpected<Error>(whileKeyword.error()); 1506 1507 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); 1508 if (!leftParenthesis) 1509 return Unexpected<Error>(leftParenthesis.error()); 1510 1511 auto conditional = parseExpression(); 1512 if (!conditional) 1513 return Unexpected<Error>(conditional.error()); 1514 1515 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 1516 if (!rightParenthesis) 1517 return Unexpected<Error>(rightParenthesis.error()); 1145 CONSUME_TYPE(origin, Do); 1146 PARSE(body, Statement); 1147 CONSUME_TYPE(whileKeyword, While); 1148 CONSUME_TYPE(leftParenthesis, LeftParenthesis); 1149 PARSE(conditional, Expression); 1150 CONSUME_TYPE(rightParenthesis, RightParenthesis); 1151 CONSUME_TYPE(semicolon, Semicolon); 1518 1152 1519 1153 return AST::DoWhileLoop(WTFMove(*origin), WTFMove(*body), WTFMove(*conditional)); … … 1522 1156 auto Parser::parseVariableDeclaration(UniqueRef<AST::UnnamedType>&& type) -> Expected<AST::VariableDeclaration, Error> 1523 1157 { 1524 auto origin = peek(); 1525 if (!origin) 1526 return Unexpected<Error>(origin.error()); 1158 PEEK(origin); 1527 1159 1528 1160 auto qualifiers = parseQualifiers(); 1529 1161 1530 auto name = consumeType(Lexer::Token::Type::Identifier); 1531 if (!name) 1532 return Unexpected<Error>(name.error()); 1533 1534 if (tryType(Lexer::Token::Type::Colon)) { 1535 auto semantic = parseSemantic(); 1536 if (!semantic) 1537 return Unexpected<Error>(semantic.error()); 1538 1539 if (tryType(Lexer::Token::Type::EqualsSign)) { 1540 auto initializer = parseExpression(); 1541 if (!initializer) 1542 return Unexpected<Error>(initializer.error()); 1543 return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(type) }, name->stringView.toString(), WTFMove(*semantic), WTFMove(*initializer)); 1544 } 1545 1546 return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(type) }, name->stringView.toString(), WTFMove(*semantic), WTF::nullopt); 1547 } 1162 CONSUME_TYPE(name, Identifier); 1163 PARSE(semantic, Semantic); 1548 1164 1549 1165 if (tryType(Lexer::Token::Type::EqualsSign)) { 1550 auto initializer = parseExpression(); 1551 if (!initializer) 1552 return Unexpected<Error>(initializer.error()); 1553 return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(type) }, name->stringView.toString(), WTF::nullopt, WTFMove(*initializer)); 1554 } 1555 1556 return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(type) }, name->stringView.toString(), WTF::nullopt, WTF::nullopt); 1166 PARSE(initializer, PossibleTernaryConditional); 1167 return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(type) }, name->stringView.toString(), WTFMove(*semantic), WTFMove(*initializer)); 1168 } 1169 1170 return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(type) }, name->stringView.toString(), WTFMove(*semantic), WTF::nullopt); 1557 1171 } 1558 1172 1559 1173 auto Parser::parseVariableDeclarations() -> Expected<AST::VariableDeclarationsStatement, Error> 1560 1174 { 1561 auto origin = peek(); 1562 if (!origin) 1563 return Unexpected<Error>(origin.error()); 1564 1565 auto type = parseType(); 1566 if (!type) 1567 return Unexpected<Error>(type.error()); 1175 PEEK(origin); 1176 1177 PARSE(type, Type); 1568 1178 1569 1179 auto firstVariableDeclaration = parseVariableDeclaration((*type)->clone()); … … 1586 1196 auto Parser::parseStatement() -> Expected<UniqueRef<AST::Statement>, Error> 1587 1197 { 1198 PEEK(token); 1199 switch (token->type) { 1200 case Lexer::Token::Type::LeftCurlyBracket: { 1201 PARSE(block, Block); 1202 return { makeUniqueRef<AST::Block>(WTFMove(*block)) }; 1203 } 1204 case Lexer::Token::Type::If: { 1205 PARSE(ifStatement, IfStatement); 1206 return { makeUniqueRef<AST::IfStatement>(WTFMove(*ifStatement)) }; 1207 } 1208 case Lexer::Token::Type::Switch: { 1209 PARSE(switchStatement, SwitchStatement); 1210 return { makeUniqueRef<AST::SwitchStatement>(WTFMove(*switchStatement)) }; 1211 } 1212 case Lexer::Token::Type::For: { 1213 PARSE(forLoop, ForLoop); 1214 return { makeUniqueRef<AST::ForLoop>(WTFMove(*forLoop)) }; 1215 } 1216 case Lexer::Token::Type::While: { 1217 PARSE(whileLoop, WhileLoop); 1218 return { makeUniqueRef<AST::WhileLoop>(WTFMove(*whileLoop)) }; 1219 } 1220 case Lexer::Token::Type::Do: { 1221 PARSE(doWhileLoop, DoWhileLoop); 1222 return { makeUniqueRef<AST::DoWhileLoop>(WTFMove(*doWhileLoop)) }; 1223 } 1224 case Lexer::Token::Type::Break: { 1225 auto breakToken = m_lexer.consumeToken(); 1226 CONSUME_TYPE(semicolon, Semicolon); 1227 auto breakObject = AST::Break(WTFMove(*breakToken)); 1228 return { makeUniqueRef<AST::Break>(WTFMove(breakObject)) }; 1229 } 1230 case Lexer::Token::Type::Continue: { 1231 auto continueToken = m_lexer.consumeToken(); 1232 CONSUME_TYPE(semicolon, Semicolon); 1233 auto continueObject = AST::Continue(WTFMove(*continueToken)); 1234 return { makeUniqueRef<AST::Continue>(WTFMove(continueObject)) }; 1235 } 1236 case Lexer::Token::Type::Fallthrough: { 1237 auto fallthroughToken = m_lexer.consumeToken(); 1238 CONSUME_TYPE(semicolon, Semicolon); 1239 auto fallthroughObject = AST::Fallthrough(WTFMove(*fallthroughToken)); 1240 return { makeUniqueRef<AST::Fallthrough>(WTFMove(fallthroughObject)) }; 1241 } 1242 case Lexer::Token::Type::Trap: { 1243 auto trapToken = m_lexer.consumeToken(); 1244 CONSUME_TYPE(semicolon, Semicolon); 1245 auto trapObject = AST::Trap(WTFMove(*trapToken)); 1246 return { makeUniqueRef<AST::Trap>(WTFMove(trapObject)) }; 1247 } 1248 case Lexer::Token::Type::Return: { 1249 auto returnToken = m_lexer.consumeToken(); 1250 if (auto semicolon = tryType(Lexer::Token::Type::Semicolon)) { 1251 auto returnObject = AST::Return(WTFMove(*returnToken), WTF::nullopt); 1252 return { makeUniqueRef<AST::Return>(WTFMove(returnObject)) }; 1253 } 1254 PARSE(expression, Expression); 1255 CONSUME_TYPE(finalSemicolon, Semicolon); 1256 auto returnObject = AST::Return(WTFMove(*returnToken), { WTFMove(*expression) }); 1257 return { makeUniqueRef<AST::Return>(WTFMove(returnObject)) }; 1258 } 1259 case Lexer::Token::Type::Constant: 1260 case Lexer::Token::Type::Device: 1261 case Lexer::Token::Type::Threadgroup: 1262 case Lexer::Token::Type::Thread: { 1263 PARSE(variableDeclarations, VariableDeclarations); 1264 CONSUME_TYPE(semicolon, Semicolon); 1265 return { makeUniqueRef<AST::VariableDeclarationsStatement>(WTFMove(*variableDeclarations)) }; 1266 } 1267 case Lexer::Token::Type::Identifier: { 1268 PEEK_FURTHER(nextToken); 1269 switch (nextToken->type) { 1270 case Lexer::Token::Type::Identifier: 1271 case Lexer::Token::Type::LessThanSign: 1272 case Lexer::Token::Type::Star: 1273 case Lexer::Token::Type::Qualifier: { 1274 PARSE(variableDeclarations, VariableDeclarations); 1275 CONSUME_TYPE(semicolon, Semicolon); 1276 return { makeUniqueRef<AST::VariableDeclarationsStatement>(WTFMove(*variableDeclarations)) }; 1277 } 1278 default: 1279 break; 1280 } 1281 break; 1282 } 1283 default: 1284 break; 1285 } 1286 1588 1287 { 1589 auto block = backtrackingScope<Expected<AST::Block, Error>>([&]() { 1590 return parseBlock(); 1591 }); 1592 if (block) 1593 return { makeUniqueRef<AST::Block>(WTFMove(*block)) }; 1594 } 1595 1596 { 1597 auto ifStatement = backtrackingScope<Expected<AST::IfStatement, Error>>([&]() { 1598 return parseIfStatement(); 1599 }); 1600 if (ifStatement) 1601 return { makeUniqueRef<AST::IfStatement>(WTFMove(*ifStatement)) }; 1602 } 1603 1604 { 1605 auto switchStatement = backtrackingScope<Expected<AST::SwitchStatement, Error>>([&]() { 1606 return parseSwitchStatement(); 1607 }); 1608 if (switchStatement) 1609 return { makeUniqueRef<AST::SwitchStatement>(WTFMove(*switchStatement)) }; 1610 } 1611 1612 { 1613 auto forLoop = backtrackingScope<Expected<AST::ForLoop, Error>>([&]() { 1614 return parseForLoop(); 1615 }); 1616 if (forLoop) 1617 return { makeUniqueRef<AST::ForLoop>(WTFMove(*forLoop)) }; 1618 } 1619 1620 { 1621 auto whileLoop = backtrackingScope<Expected<AST::WhileLoop, Error>>([&]() { 1622 return parseWhileLoop(); 1623 }); 1624 if (whileLoop) 1625 return { makeUniqueRef<AST::WhileLoop>(WTFMove(*whileLoop)) }; 1626 } 1627 1628 { 1629 auto doWhileLoop = backtrackingScope<Expected<AST::DoWhileLoop, Error>>([&]() -> Expected<AST::DoWhileLoop, Error> { 1630 auto result = parseDoWhileLoop(); 1631 if (!result) 1632 return Unexpected<Error>(result.error()); 1633 1634 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1635 if (!semicolon) 1636 return Unexpected<Error>(semicolon.error()); 1637 1288 auto effectfulExpression = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { 1289 PARSE(result, EffectfulExpression); 1290 CONSUME_TYPE(semicolon, Semicolon); 1638 1291 return result; 1639 1292 }); 1640 if (doWhileLoop) 1641 return { makeUniqueRef<AST::DoWhileLoop>(WTFMove(*doWhileLoop)) }; 1642 } 1643 1644 { 1645 auto breakObject = backtrackingScope<Expected<AST::Break, Error>>([&]() -> Expected<AST::Break, Error> { 1646 auto origin = consumeType(Lexer::Token::Type::Break); 1647 if (!origin) 1648 return Unexpected<Error>(origin.error()); 1649 1650 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1651 if (!semicolon) 1652 return Unexpected<Error>(semicolon.error()); 1653 1654 return AST::Break(WTFMove(*origin)); 1655 }); 1656 if (breakObject) 1657 return { makeUniqueRef<AST::Break>(WTFMove(*breakObject)) }; 1658 } 1659 1660 { 1661 auto continueObject = backtrackingScope<Expected<AST::Continue, Error>>([&]() -> Expected<AST::Continue, Error> { 1662 auto origin = consumeType(Lexer::Token::Type::Continue); 1663 if (!origin) 1664 return Unexpected<Error>(origin.error()); 1665 1666 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1667 if (!semicolon) 1668 return Unexpected<Error>(semicolon.error()); 1669 1670 return AST::Continue(WTFMove(*origin)); 1671 }); 1672 if (continueObject) 1673 return { makeUniqueRef<AST::Continue>(WTFMove(*continueObject)) }; 1674 } 1675 1676 { 1677 auto fallthroughObject = backtrackingScope<Expected<AST::Fallthrough, Error>>([&]() -> Expected<AST::Fallthrough, Error> { 1678 auto origin = consumeType(Lexer::Token::Type::Fallthrough); 1679 if (!origin) 1680 return Unexpected<Error>(origin.error()); 1681 1682 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1683 if (!semicolon) 1684 return Unexpected<Error>(semicolon.error()); 1685 1686 return AST::Fallthrough(WTFMove(*origin)); 1687 }); 1688 if (fallthroughObject) 1689 return { makeUniqueRef<AST::Fallthrough>(WTFMove(*fallthroughObject)) }; 1690 } 1691 1692 { 1693 auto trapObject = backtrackingScope<Expected<AST::Trap, Error>>([&]() -> Expected<AST::Trap, Error> { 1694 auto origin = consumeType(Lexer::Token::Type::Trap); 1695 if (!origin) 1696 return Unexpected<Error>(origin.error()); 1697 1698 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1699 if (!semicolon) 1700 return Unexpected<Error>(semicolon.error()); 1701 1702 return AST::Trap(WTFMove(*origin)); 1703 }); 1704 if (trapObject) 1705 return { makeUniqueRef<AST::Trap>(WTFMove(*trapObject)) }; 1706 } 1707 1708 { 1709 auto returnObject = backtrackingScope<Expected<AST::Return, Error>>([&]() -> Expected<AST::Return, Error> { 1710 auto origin = consumeType(Lexer::Token::Type::Return); 1711 if (!origin) 1712 return Unexpected<Error>(origin.error()); 1713 1714 if (auto semicolon = tryType(Lexer::Token::Type::Semicolon)) 1715 return AST::Return(WTFMove(*origin), WTF::nullopt); 1716 1717 auto expression = parseExpression(); 1718 if (!expression) 1719 return Unexpected<Error>(expression.error()); 1720 1721 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1722 if (!semicolon) 1723 return Unexpected<Error>(semicolon.error()); 1724 1725 return AST::Return(WTFMove(*origin), { WTFMove(*expression) }); 1726 }); 1727 if (returnObject) 1728 return { makeUniqueRef<AST::Return>(WTFMove(*returnObject)) }; 1729 } 1730 1731 { 1732 auto variableDeclarations = backtrackingScope<Expected<AST::VariableDeclarationsStatement, Error>>([&]() -> Expected<AST::VariableDeclarationsStatement, Error> { 1733 auto result = parseVariableDeclarations(); 1734 if (!result) 1735 return Unexpected<Error>(result.error()); 1736 1737 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1738 if (!semicolon) 1739 return Unexpected<Error>(semicolon.error()); 1740 1741 return result; 1742 }); 1743 if (variableDeclarations) 1744 return { makeUniqueRef<AST::VariableDeclarationsStatement>(WTFMove(*variableDeclarations)) }; 1745 } 1746 1747 auto effectfulExpression = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { 1748 auto result = parseEffectfulExpression(); 1749 if (!result) 1750 return Unexpected<Error>(result.error()); 1751 1752 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1753 if (!semicolon) 1754 return Unexpected<Error>(semicolon.error()); 1755 1756 return result; 1757 }); 1758 if (effectfulExpression) 1759 return { makeUniqueRef<AST::EffectfulExpressionStatement>(WTFMove(*effectfulExpression)) }; 1760 1761 return Unexpected<Error>(effectfulExpression.error()); 1293 if (effectfulExpression) 1294 return { makeUniqueRef<AST::EffectfulExpressionStatement>(WTFMove(*effectfulExpression)) }; 1295 } 1296 1297 PARSE(variableDeclarations, VariableDeclarations); 1298 CONSUME_TYPE(semicolon, Semicolon); 1299 return { makeUniqueRef<AST::VariableDeclarationsStatement>(WTFMove(*variableDeclarations)) }; 1762 1300 } 1763 1301 1764 1302 auto Parser::parseEffectfulExpression() -> Expected<UniqueRef<AST::Expression>, Error> 1765 1303 { 1766 auto origin = peek(); 1767 if (!origin) 1768 return Unexpected<Error>(origin.error()); 1304 PEEK(origin); 1769 1305 1770 1306 Vector<UniqueRef<AST::Expression>> expressions; 1771 1772 auto first = backtrackingScope<Optional<UniqueRef<AST::Expression>>>([&]() -> Optional<UniqueRef<AST::Expression>> { 1773 auto effectfulExpression = parseEffectfulAssignment(); 1774 if (!effectfulExpression) 1775 return WTF::nullopt; 1776 return { WTFMove(*effectfulExpression) }; 1777 }); 1778 if (!first) 1307 if (origin->type == Lexer::Token::Type::Semicolon) 1779 1308 return { makeUniqueRef<AST::CommaExpression>(WTFMove(*origin), WTFMove(expressions)) }; 1780 1309 1781 expressions.append(WTFMove(*first)); 1310 PARSE(effectfulExpression, EffectfulAssignment); 1311 expressions.append(WTFMove(*effectfulExpression)); 1782 1312 1783 1313 while (tryType(Lexer::Token::Type::Comma)) { 1784 auto expression = parseEffectfulAssignment(); 1785 if (!expression) 1786 return Unexpected<Error>(expression.error()); 1314 PARSE(expression, EffectfulAssignment); 1787 1315 expressions.append(WTFMove(*expression)); 1788 1316 } … … 1795 1323 auto Parser::parseEffectfulAssignment() -> Expected<UniqueRef<AST::Expression>, Error> 1796 1324 { 1797 auto assignment = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { 1798 return parseAssignment(); 1799 }); 1800 if (assignment) 1801 return assignment; 1802 1803 assignment = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { 1804 return parseEffectfulPrefix(); 1805 }); 1806 if (assignment) 1807 return assignment; 1808 1809 return Unexpected<Error>(assignment.error()); 1810 } 1811 1812 auto Parser::parseEffectfulPrefix() -> Expected<UniqueRef<AST::Expression>, Error> 1813 { 1814 auto prefix = consumeTypes({ Lexer::Token::Type::PlusPlus, Lexer::Token::Type::MinusMinus }); 1815 if (!prefix) 1816 return parseEffectfulSuffix(); 1817 1818 auto previous = parsePossiblePrefix(); 1819 if (!previous) 1820 return Unexpected<Error>(previous.error()); 1821 1822 switch (prefix->type) { 1823 case Lexer::Token::Type::PlusPlus: { 1824 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*prefix), WTFMove(*previous)); 1825 Vector<UniqueRef<AST::Expression>> callArguments; 1826 callArguments.append(result->oldVariableReference()); 1827 result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*prefix), "operator++"_str, WTFMove(callArguments))); 1828 result->setResultExpression(result->newVariableReference()); 1829 return { WTFMove(result) }; 1830 } 1831 default: { 1832 ASSERT(prefix->type == Lexer::Token::Type::MinusMinus); 1833 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*prefix), WTFMove(*previous)); 1834 Vector<UniqueRef<AST::Expression>> callArguments; 1835 callArguments.append(result->oldVariableReference()); 1836 result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*prefix), "operator--"_str, WTFMove(callArguments))); 1837 result->setResultExpression(result->newVariableReference()); 1838 return { WTFMove(result) }; 1839 } 1840 } 1841 } 1842 1843 auto Parser::parseEffectfulSuffix() -> Expected<UniqueRef<AST::Expression>, Error> 1844 { 1845 auto effectfulSuffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { 1846 auto previous = parsePossibleSuffix(); 1847 if (!previous) 1848 return Unexpected<Error>(previous.error()); 1849 1850 auto suffix = consumeTypes({ Lexer::Token::Type::PlusPlus, Lexer::Token::Type::MinusMinus }); 1851 if (!suffix) 1852 return Unexpected<Error>(suffix.error()); 1853 1854 switch (suffix->type) { 1855 case Lexer::Token::Type::PlusPlus: { 1856 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*suffix), WTFMove(*previous)); 1857 Vector<UniqueRef<AST::Expression>> callArguments; 1858 callArguments.append(result->oldVariableReference()); 1859 result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*suffix), "operator++"_str, WTFMove(callArguments))); 1860 result->setResultExpression(result->oldVariableReference()); 1861 return { WTFMove(result) }; 1862 } 1863 default: { 1864 ASSERT(suffix->type == Lexer::Token::Type::MinusMinus); 1865 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*suffix), WTFMove(*previous)); 1866 Vector<UniqueRef<AST::Expression>> callArguments; 1867 callArguments.append(result->oldVariableReference()); 1868 result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*suffix), "operator--"_str, WTFMove(callArguments))); 1869 result->setResultExpression(result->oldVariableReference()); 1870 return { WTFMove(result) }; 1871 } 1872 } 1873 }); 1874 if (effectfulSuffix) 1875 return effectfulSuffix; 1876 1877 effectfulSuffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { 1878 return parseCallExpression(); 1879 }); 1880 if (effectfulSuffix) 1881 return effectfulSuffix; 1882 1883 effectfulSuffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { 1884 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); 1885 if (!leftParenthesis) 1886 return Unexpected<Error>(leftParenthesis.error()); 1887 1888 auto expression = parseExpression(); 1889 if (!expression) 1890 return Unexpected<Error>(expression.error()); 1891 1892 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 1893 if (!rightParenthesis) 1894 return Unexpected<Error>(rightParenthesis.error()); 1895 1896 return { WTFMove(*expression) }; 1897 }); 1898 if (effectfulSuffix) 1899 return effectfulSuffix; 1900 1901 return Unexpected<Error>(effectfulSuffix.error()); 1325 PEEK(origin); 1326 1327 bool isEffectful = false; 1328 PARSE(expression, PossiblePrefix, &isEffectful); 1329 1330 if (!isEffectful || peekTypes({ 1331 Lexer::Token::Type::EqualsSign, 1332 Lexer::Token::Type::PlusEquals, 1333 Lexer::Token::Type::MinusEquals, 1334 Lexer::Token::Type::TimesEquals, 1335 Lexer::Token::Type::DivideEquals, 1336 Lexer::Token::Type::ModEquals, 1337 Lexer::Token::Type::XorEquals, 1338 Lexer::Token::Type::AndEquals, 1339 Lexer::Token::Type::OrEquals, 1340 Lexer::Token::Type::RightShiftEquals, 1341 Lexer::Token::Type::LeftShiftEquals 1342 })) { 1343 return completeAssignment(WTFMove(*origin), WTFMove(*expression)); 1344 } 1345 1346 return expression; 1902 1347 } 1903 1348 … … 1982 1427 auto Parser::parseExpression() -> Expected<UniqueRef<AST::Expression>, Error> 1983 1428 { 1984 auto origin = peek(); 1985 if (!origin) 1986 return Unexpected<Error>(origin.error()); 1987 1988 auto first = parsePossibleTernaryConditional(); 1989 if (!first) 1990 return Unexpected<Error>(first.error()); 1991 1429 PEEK(origin); 1430 1431 PARSE(first, PossibleTernaryConditional); 1992 1432 Vector<UniqueRef<AST::Expression>> expressions; 1993 1433 expressions.append(WTFMove(*first)); 1994 1434 1995 1435 while (tryType(Lexer::Token::Type::Comma)) { 1996 auto expression = parsePossibleTernaryConditional(); 1997 if (!expression) 1998 return Unexpected<Error>(expression.error()); 1436 PARSE(expression, PossibleTernaryConditional); 1999 1437 expressions.append(WTFMove(*expression)); 2000 1438 } … … 2005 1443 } 2006 1444 2007 auto Parser::parseTernaryConditional() -> Expected<UniqueRef<AST::Expression>, Error> 2008 { 2009 auto origin = peek(); 2010 if (!origin) 2011 return Unexpected<Error>(origin.error()); 2012 2013 auto predicate = parsePossibleLogicalBinaryOperation(); 2014 if (!predicate) 2015 return Unexpected<Error>(predicate.error()); 2016 2017 auto questionMark = consumeType(Lexer::Token::Type::QuestionMark); 2018 if (!questionMark) 2019 return Unexpected<Error>(questionMark.error()); 2020 2021 auto bodyExpression = parseExpression(); 2022 if (!bodyExpression) 2023 return Unexpected<Error>(bodyExpression.error()); 2024 2025 auto colon = consumeType(Lexer::Token::Type::Colon); 2026 if (!colon) 2027 return Unexpected<Error>(colon.error()); 2028 2029 auto elseExpression = parsePossibleTernaryConditional(); 2030 if (!elseExpression) 2031 return Unexpected<Error>(elseExpression.error()); 1445 auto Parser::completeTernaryConditional(Lexer::Token&& origin, UniqueRef<AST::Expression>&& predicate) -> Expected<UniqueRef<AST::Expression>, Error> 1446 { 1447 CONSUME_TYPE(questionMark, QuestionMark); 1448 PARSE(bodyExpression, Expression); 1449 CONSUME_TYPE(colon, Colon); 1450 PARSE(elseExpression, PossibleTernaryConditional); 2032 1451 2033 1452 Vector<UniqueRef<AST::Expression>> castArguments; 2034 castArguments.append(WTFMove(*predicate)); 2035 auto boolCast = makeUniqueRef<AST::CallExpression>(Lexer::Token(*origin), "bool"_str, WTFMove(castArguments)); 2036 return { makeUniqueRef<AST::TernaryExpression>(WTFMove(*origin), WTFMove(boolCast), WTFMove(*bodyExpression), WTFMove(*elseExpression)) }; 2037 } 2038 2039 auto Parser::parseAssignment() -> Expected<UniqueRef<AST::Expression>, Error> 2040 { 2041 auto origin = peek(); 2042 if (!origin) 2043 return Unexpected<Error>(origin.error()); 2044 2045 auto left = parsePossiblePrefix(); 2046 if (!left) 2047 return Unexpected<Error>(left.error()); 2048 1453 castArguments.append(WTFMove(predicate)); 1454 auto boolCast = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), "bool"_str, WTFMove(castArguments)); 1455 return { makeUniqueRef<AST::TernaryExpression>(WTFMove(origin), WTFMove(boolCast), WTFMove(*bodyExpression), WTFMove(*elseExpression)) }; 1456 } 1457 1458 auto Parser::completeAssignment(Lexer::Token&& origin, UniqueRef<AST::Expression>&& left) -> Expected<UniqueRef<AST::Expression>, Error> 1459 { 2049 1460 auto assignmentOperator = consumeTypes({ 2050 1461 Lexer::Token::Type::EqualsSign, … … 2063 1474 return Unexpected<Error>(assignmentOperator.error()); 2064 1475 2065 auto right = parsePossibleTernaryConditional(); 2066 if (!right) 2067 return Unexpected<Error>(right.error()); 1476 PARSE(right, PossibleTernaryConditional); 2068 1477 2069 1478 if (assignmentOperator->type == Lexer::Token::Type::EqualsSign) 2070 return { makeUniqueRef<AST::AssignmentExpression>(WTFMove( *origin), WTFMove(*left), WTFMove(*right))};1479 return { makeUniqueRef<AST::AssignmentExpression>(WTFMove(origin), WTFMove(left), WTFMove(*right))}; 2071 1480 2072 1481 String name; … … 2105 1514 } 2106 1515 2107 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token( *origin), WTFMove(*left));1516 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(origin), WTFMove(left)); 2108 1517 Vector<UniqueRef<AST::Expression>> callArguments; 2109 1518 callArguments.append(result->oldVariableReference()); 2110 1519 callArguments.append(WTFMove(*right)); 2111 result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove( *origin), WTFMove(name), WTFMove(callArguments)));1520 result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(origin), WTFMove(name), WTFMove(callArguments))); 2112 1521 result->setResultExpression(result->newVariableReference()); 2113 1522 return { WTFMove(result) }; … … 2116 1525 auto Parser::parsePossibleTernaryConditional() -> Expected<UniqueRef<AST::Expression>, Error> 2117 1526 { 2118 auto ternaryExpression = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { 2119 return parseTernaryConditional(); 2120 }); 2121 if (ternaryExpression) 2122 return ternaryExpression; 2123 2124 auto assignmentExpression = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { 2125 return parseAssignment(); 2126 }); 2127 if (assignmentExpression) 2128 return assignmentExpression; 2129 2130 auto binaryOperation = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { 2131 return parsePossibleLogicalBinaryOperation(); 2132 }); 2133 if (binaryOperation) 2134 return binaryOperation; 2135 2136 return Unexpected<Error>(binaryOperation.error()); 1527 PEEK(origin); 1528 1529 PARSE(expression, PossiblePrefix); 1530 1531 if (peekTypes({Lexer::Token::Type::EqualsSign, 1532 Lexer::Token::Type::PlusEquals, 1533 Lexer::Token::Type::MinusEquals, 1534 Lexer::Token::Type::TimesEquals, 1535 Lexer::Token::Type::DivideEquals, 1536 Lexer::Token::Type::ModEquals, 1537 Lexer::Token::Type::XorEquals, 1538 Lexer::Token::Type::AndEquals, 1539 Lexer::Token::Type::OrEquals, 1540 Lexer::Token::Type::RightShiftEquals, 1541 Lexer::Token::Type::LeftShiftEquals})) { 1542 return completeAssignment(WTFMove(*origin), WTFMove(*expression)); 1543 } 1544 1545 expression = completePossibleShift(WTFMove(*expression)); 1546 expression = completePossibleMultiply(WTFMove(*expression)); 1547 expression = completePossibleAdd(WTFMove(*expression)); 1548 expression = completePossibleRelationalBinaryOperation(WTFMove(*expression)); 1549 expression = completePossibleLogicalBinaryOperation(WTFMove(*expression)); 1550 1551 PEEK(nextToken); 1552 if (nextToken->type == Lexer::Token::Type::QuestionMark) 1553 return completeTernaryConditional(WTFMove(*origin), WTFMove(*expression)); 1554 return expression; 2137 1555 } 2138 1556 2139 1557 auto Parser::parsePossibleLogicalBinaryOperation() -> Expected<UniqueRef<AST::Expression>, Error> 2140 1558 { 2141 auto parsedPrevious = parsePossibleRelationalBinaryOperation(); 2142 if (!parsedPrevious) 2143 return Unexpected<Error>(parsedPrevious.error()); 2144 UniqueRef<AST::Expression> previous = WTFMove(*parsedPrevious); 2145 1559 PARSE(parsedPrevious, PossibleRelationalBinaryOperation); 1560 return completePossibleLogicalBinaryOperation(WTFMove(*parsedPrevious)); 1561 } 1562 1563 auto Parser::completePossibleLogicalBinaryOperation(UniqueRef<AST::Expression>&& previous) -> Expected<UniqueRef<AST::Expression>, Error> 1564 { 2146 1565 while (auto logicalBinaryOperation = tryTypes({ 2147 1566 Lexer::Token::Type::OrOr, … … 2151 1570 Lexer::Token::Type::And 2152 1571 })) { 2153 auto next = parsePossibleRelationalBinaryOperation(); 2154 if (!next) 2155 return Unexpected<Error>(next.error()); 1572 PARSE(next, PossibleRelationalBinaryOperation); 2156 1573 2157 1574 switch (logicalBinaryOperation->type) { … … 2192 1609 auto Parser::parsePossibleRelationalBinaryOperation() -> Expected<UniqueRef<AST::Expression>, Error> 2193 1610 { 2194 auto parsedPrevious = parsePossibleShift(); 2195 if (!parsedPrevious) 2196 return Unexpected<Error>(parsedPrevious.error()); 2197 UniqueRef<AST::Expression> previous = WTFMove(*parsedPrevious); 2198 1611 PARSE(parsedPrevious, PossibleShift); 1612 return completePossibleRelationalBinaryOperation(WTFMove(*parsedPrevious)); 1613 } 1614 1615 auto Parser::completePossibleRelationalBinaryOperation(UniqueRef<AST::Expression>&& previous) -> Expected<UniqueRef<AST::Expression>, Error> 1616 { 2199 1617 while (auto relationalBinaryOperation = tryTypes({ 2200 1618 Lexer::Token::Type::LessThanSign, … … 2205 1623 Lexer::Token::Type::NotEqual 2206 1624 })) { 2207 auto next = parsePossibleShift(); 2208 if (!next) 2209 return Unexpected<Error>(next.error()); 1625 PARSE(next, PossibleShift); 1626 1627 Vector<UniqueRef<AST::Expression>> callArguments; 1628 callArguments.append(WTFMove(previous)); 1629 callArguments.append(WTFMove(*next)); 2210 1630 2211 1631 switch (relationalBinaryOperation->type) { 2212 1632 case Lexer::Token::Type::LessThanSign: { 2213 Vector<UniqueRef<AST::Expression>> callArguments;2214 callArguments.append(WTFMove(previous));2215 callArguments.append(WTFMove(*next));2216 1633 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), "operator<"_str, WTFMove(callArguments)); 2217 1634 break; 2218 1635 } 2219 1636 case Lexer::Token::Type::GreaterThanSign: { 2220 Vector<UniqueRef<AST::Expression>> callArguments;2221 callArguments.append(WTFMove(previous));2222 callArguments.append(WTFMove(*next));2223 1637 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), "operator>"_str, WTFMove(callArguments)); 2224 1638 break; 2225 1639 } 2226 1640 case Lexer::Token::Type::LessThanOrEqualTo: { 2227 Vector<UniqueRef<AST::Expression>> callArguments;2228 callArguments.append(WTFMove(previous));2229 callArguments.append(WTFMove(*next));2230 1641 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), "operator<="_str, WTFMove(callArguments)); 2231 1642 break; 2232 1643 } 2233 1644 case Lexer::Token::Type::GreaterThanOrEqualTo: { 2234 Vector<UniqueRef<AST::Expression>> callArguments;2235 callArguments.append(WTFMove(previous));2236 callArguments.append(WTFMove(*next));2237 1645 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), "operator>="_str, WTFMove(callArguments)); 2238 1646 break; 2239 1647 } 2240 1648 case Lexer::Token::Type::EqualComparison: { 2241 Vector<UniqueRef<AST::Expression>> callArguments;2242 callArguments.append(WTFMove(previous));2243 callArguments.append(WTFMove(*next));2244 1649 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), "operator=="_str, WTFMove(callArguments)); 2245 1650 break; … … 2247 1652 default: { 2248 1653 ASSERT(relationalBinaryOperation->type == Lexer::Token::Type::NotEqual); 2249 Vector<UniqueRef<AST::Expression>> callArguments;2250 callArguments.append(WTFMove(previous));2251 callArguments.append(WTFMove(*next));2252 1654 previous = makeUniqueRef<AST::CallExpression>(Lexer::Token(*relationalBinaryOperation), "operator=="_str, WTFMove(callArguments)); 2253 1655 previous = makeUniqueRef<AST::LogicalNotExpression>(WTFMove(*relationalBinaryOperation), WTFMove(previous)); … … 2262 1664 auto Parser::parsePossibleShift() -> Expected<UniqueRef<AST::Expression>, Error> 2263 1665 { 2264 auto parsedPrevious = parsePossibleAdd(); 2265 if (!parsedPrevious) 2266 return Unexpected<Error>(parsedPrevious.error()); 2267 UniqueRef<AST::Expression> previous = WTFMove(*parsedPrevious); 2268 1666 PARSE(parsedPrevious, PossibleAdd); 1667 return completePossibleShift(WTFMove(*parsedPrevious)); 1668 } 1669 1670 auto Parser::completePossibleShift(UniqueRef<AST::Expression>&& previous) -> Expected<UniqueRef<AST::Expression>, Error> 1671 { 2269 1672 while (auto shift = tryTypes({ 2270 1673 Lexer::Token::Type::LeftShift, 2271 1674 Lexer::Token::Type::RightShift 2272 1675 })) { 2273 auto next = parsePossibleAdd(); 2274 if (!next) 2275 return Unexpected<Error>(next.error()); 1676 PARSE(next, PossibleAdd); 1677 1678 Vector<UniqueRef<AST::Expression>> callArguments; 1679 callArguments.append(WTFMove(previous)); 1680 callArguments.append(WTFMove(*next)); 2276 1681 2277 1682 switch (shift->type) { 2278 1683 case Lexer::Token::Type::LeftShift: { 2279 Vector<UniqueRef<AST::Expression>> callArguments;2280 callArguments.append(WTFMove(previous));2281 callArguments.append(WTFMove(*next));2282 1684 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*shift), "operator<<"_str, WTFMove(callArguments)); 2283 1685 break; … … 2285 1687 default: { 2286 1688 ASSERT(shift->type == Lexer::Token::Type::RightShift); 2287 Vector<UniqueRef<AST::Expression>> callArguments;2288 callArguments.append(WTFMove(previous));2289 callArguments.append(WTFMove(*next));2290 1689 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*shift), "operator>>"_str, WTFMove(callArguments)); 2291 1690 break; … … 2299 1698 auto Parser::parsePossibleAdd() -> Expected<UniqueRef<AST::Expression>, Error> 2300 1699 { 2301 auto parsedPrevious = parsePossibleMultiply(); 2302 if (!parsedPrevious) 2303 return Unexpected<Error>(parsedPrevious.error()); 2304 UniqueRef<AST::Expression> previous = WTFMove(*parsedPrevious); 2305 1700 PARSE(parsedPrevious, PossibleMultiply); 1701 return completePossibleAdd(WTFMove(*parsedPrevious)); 1702 } 1703 1704 auto Parser::completePossibleAdd(UniqueRef<AST::Expression>&& previous) -> Expected<UniqueRef<AST::Expression>, Error> 1705 { 2306 1706 while (auto add = tryTypes({ 2307 1707 Lexer::Token::Type::Plus, 2308 1708 Lexer::Token::Type::Minus 2309 1709 })) { 2310 auto next = parsePossibleMultiply(); 2311 if (!next) 2312 return Unexpected<Error>(next.error()); 1710 PARSE(next, PossibleMultiply); 1711 1712 Vector<UniqueRef<AST::Expression>> callArguments; 1713 callArguments.append(WTFMove(previous)); 1714 callArguments.append(WTFMove(*next)); 2313 1715 2314 1716 switch (add->type) { 2315 1717 case Lexer::Token::Type::Plus: { 2316 Vector<UniqueRef<AST::Expression>> callArguments;2317 callArguments.append(WTFMove(previous));2318 callArguments.append(WTFMove(*next));2319 1718 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*add), "operator+"_str, WTFMove(callArguments)); 2320 1719 break; … … 2322 1721 default: { 2323 1722 ASSERT(add->type == Lexer::Token::Type::Minus); 2324 Vector<UniqueRef<AST::Expression>> callArguments;2325 callArguments.append(WTFMove(previous));2326 callArguments.append(WTFMove(*next));2327 1723 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*add), "operator-"_str, WTFMove(callArguments)); 2328 1724 break; … … 2336 1732 auto Parser::parsePossibleMultiply() -> Expected<UniqueRef<AST::Expression>, Error> 2337 1733 { 2338 auto parsedPrevious = parsePossiblePrefix(); 2339 if (!parsedPrevious) 2340 return Unexpected<Error>(parsedPrevious.error()); 2341 UniqueRef<AST::Expression> previous = WTFMove(*parsedPrevious); 2342 1734 PARSE(parsedPrevious, PossiblePrefix); 1735 return completePossibleMultiply(WTFMove(*parsedPrevious)); 1736 } 1737 1738 auto Parser::completePossibleMultiply(UniqueRef<AST::Expression>&& previous) -> Expected<UniqueRef<AST::Expression>, Error> 1739 { 2343 1740 while (auto multiply = tryTypes({ 2344 1741 Lexer::Token::Type::Star, … … 2346 1743 Lexer::Token::Type::Mod 2347 1744 })) { 2348 auto next = parsePossiblePrefix(); 2349 if (!next) 2350 return Unexpected<Error>(next.error()); 1745 PARSE(next, PossiblePrefix); 1746 1747 Vector<UniqueRef<AST::Expression>> callArguments; 1748 callArguments.append(WTFMove(previous)); 1749 callArguments.append(WTFMove(*next)); 2351 1750 2352 1751 switch (multiply->type) { 2353 1752 case Lexer::Token::Type::Star: { 2354 Vector<UniqueRef<AST::Expression>> callArguments;2355 callArguments.append(WTFMove(previous));2356 callArguments.append(WTFMove(*next));2357 1753 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*multiply), "operator*"_str, WTFMove(callArguments)); 2358 1754 break; 2359 1755 } 2360 1756 case Lexer::Token::Type::Divide: { 2361 Vector<UniqueRef<AST::Expression>> callArguments;2362 callArguments.append(WTFMove(previous));2363 callArguments.append(WTFMove(*next));2364 1757 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*multiply), "operator/"_str, WTFMove(callArguments)); 2365 1758 break; … … 2367 1760 default: { 2368 1761 ASSERT(multiply->type == Lexer::Token::Type::Mod); 2369 Vector<UniqueRef<AST::Expression>> callArguments;2370 callArguments.append(WTFMove(previous));2371 callArguments.append(WTFMove(*next));2372 1762 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*multiply), "operator%"_str, WTFMove(callArguments)); 2373 1763 break; … … 2379 1769 } 2380 1770 2381 auto Parser::parsePossiblePrefix( ) -> Expected<UniqueRef<AST::Expression>, Error>1771 auto Parser::parsePossiblePrefix(bool *isEffectful) -> Expected<UniqueRef<AST::Expression>, Error> 2382 1772 { 2383 1773 if (auto prefix = tryTypes({ … … 2392 1782 Lexer::Token::Type::Star 2393 1783 })) { 2394 auto next = parsePossiblePrefix(); 2395 if (!next) 2396 return Unexpected<Error>(next.error()); 1784 PARSE(next, PossiblePrefix); 2397 1785 2398 1786 switch (prefix->type) { 2399 1787 case Lexer::Token::Type::PlusPlus: { 1788 if (isEffectful) 1789 *isEffectful = true; 2400 1790 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*prefix), WTFMove(*next)); 2401 1791 Vector<UniqueRef<AST::Expression>> callArguments; … … 2406 1796 } 2407 1797 case Lexer::Token::Type::MinusMinus: { 1798 if (isEffectful) 1799 *isEffectful = true; 2408 1800 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*prefix), WTFMove(*next)); 2409 1801 Vector<UniqueRef<AST::Expression>> callArguments; … … 2444 1836 } 2445 1837 2446 return parsePossibleSuffix(); 2447 } 2448 2449 auto Parser::parsePossibleSuffix() -> Expected<UniqueRef<AST::Expression>, Error> 2450 { 2451 auto suffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { 2452 auto expression = parseCallExpression(); 2453 if (!expression) 2454 return Unexpected<Error>(expression.error()); 2455 1838 return parsePossibleSuffix(isEffectful); 1839 } 1840 1841 auto Parser::parsePossibleSuffix(bool *isEffectful) -> Expected<UniqueRef<AST::Expression>, Error> 1842 { 1843 PEEK(token); 1844 PEEK_FURTHER(nextToken); 1845 1846 if (token->type == Lexer::Token::Type::Identifier && nextToken->type == Lexer::Token::Type::LeftParenthesis) { 1847 PARSE(expression, CallExpression); 1848 if (isEffectful) 1849 *isEffectful = true; 2456 1850 while (true) { 2457 auto result = backtrackingScope<SuffixExpression>([&]() -> SuffixExpression { 2458 return parseLimitedSuffixOperator(WTFMove(*expression)); 2459 }); 1851 PEEK(suffixToken); 1852 if (suffixToken->type != Lexer::Token::Type::FullStop && suffixToken->type != Lexer::Token::Type::Arrow && suffixToken->type != Lexer::Token::Type::LeftSquareBracket) 1853 break; 1854 auto result = parseLimitedSuffixOperator(WTFMove(*expression)); 2460 1855 expression = WTFMove(result.result); 2461 if (!result)2462 break;2463 1856 } 2464 1857 return expression; 2465 } );2466 if (suffix) 2467 return suffix;2468 2469 suffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { 2470 auto expression = parseTerm();2471 if (!expression)2472 return Unexpected<Error>(expression.error());2473 2474 while (true) {2475 auto result = backtrackingScope<SuffixExpression>([&]() -> SuffixExpression {2476 return parseSuffixOperator(WTFMove(*expression));2477 });2478 expression = WTFMove(result.result);2479 if (!result)2480 break;2481 }2482 return expression;2483 });2484 if (suffix)2485 return suffix;2486 2487 return Unexpected<Error>(suffix.error());1858 } 1859 1860 if (token->type == Lexer::Token::Type::LeftParenthesis && isEffectful) 1861 *isEffectful = true; 1862 1863 PARSE(expression, Term); 1864 bool isLastSuffixTokenEffectful = false; 1865 while (true) { 1866 PEEK(suffixToken); 1867 if (suffixToken->type != Lexer::Token::Type::FullStop 1868 && suffixToken->type != Lexer::Token::Type::Arrow 1869 && suffixToken->type != Lexer::Token::Type::LeftSquareBracket 1870 && suffixToken->type != Lexer::Token::Type::PlusPlus 1871 && suffixToken->type != Lexer::Token::Type::MinusMinus) { 1872 break; 1873 } 1874 isLastSuffixTokenEffectful = suffixToken->type == Lexer::Token::Type::PlusPlus || suffixToken->type == Lexer::Token::Type::MinusMinus; 1875 auto result = parseSuffixOperator(WTFMove(*expression)); 1876 expression = WTFMove(result.result); 1877 } 1878 if (isLastSuffixTokenEffectful && isEffectful) 1879 *isEffectful = true; 1880 return expression; 2488 1881 } 2489 1882 2490 1883 auto Parser::parseCallExpression() -> Expected<UniqueRef<AST::Expression>, Error> 2491 1884 { 2492 auto name = consumeType(Lexer::Token::Type::Identifier); 2493 if (!name) 2494 return Unexpected<Error>(name.error()); 1885 CONSUME_TYPE(name, Identifier); 2495 1886 auto callName = name->stringView.toString(); 2496 1887 2497 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); 2498 if (!leftParenthesis) 2499 return Unexpected<Error>(leftParenthesis.error()); 1888 CONSUME_TYPE(leftParenthesis, LeftParenthesis); 2500 1889 2501 1890 Vector<UniqueRef<AST::Expression>> arguments; … … 2503 1892 return { makeUniqueRef<AST::CallExpression>(WTFMove(*name), WTFMove(callName), WTFMove(arguments)) }; 2504 1893 2505 auto firstArgument = parsePossibleTernaryConditional(); 2506 if (!firstArgument) 2507 return Unexpected<Error>(firstArgument.error()); 1894 PARSE(firstArgument, PossibleTernaryConditional); 2508 1895 arguments.append(WTFMove(*firstArgument)); 2509 1896 while (tryType(Lexer::Token::Type::Comma)) { 2510 auto argument = parsePossibleTernaryConditional(); 2511 if (!argument) 2512 return Unexpected<Error>(argument.error()); 1897 PARSE(argument, PossibleTernaryConditional); 2513 1898 arguments.append(WTFMove(*argument)); 2514 1899 } 2515 1900 2516 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 2517 if (!rightParenthesis) 2518 return Unexpected<Error>(rightParenthesis.error()); 1901 CONSUME_TYPE(rightParenthesis, RightParenthesis); 2519 1902 2520 1903 return { makeUniqueRef<AST::CallExpression>(WTFMove(*name), WTFMove(callName), WTFMove(arguments)) }; … … 2567 1950 default: { 2568 1951 ASSERT(type->type == Lexer::Token::Type::LeftParenthesis); 2569 auto expression = parseExpression(); 2570 if (!expression) 2571 return Unexpected<Error>(expression.error()); 2572 2573 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 2574 if (!rightParenthesis) 2575 return Unexpected<Error>(rightParenthesis.error()); 1952 PARSE(expression, Expression); 1953 CONSUME_TYPE(rightParenthesis, RightParenthesis); 2576 1954 2577 1955 return { WTFMove(*expression) }; -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.h
r246108 r246135 97 97 #include <wtf/Expected.h> 98 98 #include <wtf/Optional.h> 99 #include <wtf/PrintStream.h> 99 100 100 101 namespace WebCore { … … 116 117 117 118 String error; 119 120 void dump(PrintStream& out) const 121 { 122 out.print(error); 123 } 118 124 }; 119 125 … … 121 127 122 128 private: 129 // FIXME: We should not need this 130 // https://bugs.webkit.org/show_bug.cgi?id=198357 123 131 template<typename T> T backtrackingScope(std::function<T()> callback) 124 132 { … … 137 145 Unexpected<Error> fail(const String& message, TryToPeek = TryToPeek::Yes); 138 146 Expected<Lexer::Token, Error> peek(); 147 Expected<Lexer::Token, Error> peekFurther(); 148 bool peekTypes(const Vector<Lexer::Token::Type>&); 139 149 Optional<Lexer::Token> tryType(Lexer::Token::Type); 140 Optional<Lexer::Token> tryTypes( Vector<Lexer::Token::Type>);150 Optional<Lexer::Token> tryTypes(const Vector<Lexer::Token::Type>&); 141 151 Expected<Lexer::Token, Error> consumeType(Lexer::Token::Type); 142 Expected<Lexer::Token, Error> consumeTypes( Vector<Lexer::Token::Type>);152 Expected<Lexer::Token, Error> consumeTypes(const Vector<Lexer::Token::Type>&); 143 153 144 154 Expected<Variant<int, unsigned>, Error> consumeIntegralLiteral(); … … 166 176 Expected<AST::SpecializationConstantSemantic, Error> parseSpecializationConstantSemantic(); 167 177 Expected<AST::StageInOutSemantic, Error> parseStageInOutSemantic(); 168 Expected< AST::Semantic, Error> parseSemantic();178 Expected<Optional<AST::Semantic>, Error> parseSemantic(); 169 179 AST::Qualifiers parseQualifiers(); 170 180 Expected<AST::StructureElement, Error> parseStructureElement(); … … 177 187 Expected<AST::VariableDeclaration, Error> parseParameter(); 178 188 Expected<AST::VariableDeclarations, Error> parseParameters(); 179 Expected<AST::FunctionDeclaration, Error> parseEntryPointFunctionDeclaration(); 189 Expected<AST::FunctionDeclaration, Error> parseComputeFunctionDeclaration(); 190 Expected<AST::FunctionDeclaration, Error> parseVertexOrFragmentFunctionDeclaration(); 180 191 Expected<AST::FunctionDeclaration, Error> parseRegularFunctionDeclaration(); 181 192 Expected<AST::FunctionDeclaration, Error> parseOperatorFunctionDeclaration(); … … 185 196 186 197 Expected<AST::Block, Error> parseBlock(); 187 AST::BlockparseBlockBody(Lexer::Token&& origin);198 Expected<AST::Block, Error> parseBlockBody(Lexer::Token&& origin); 188 199 Expected<AST::IfStatement, Error> parseIfStatement(); 189 200 Expected<AST::SwitchStatement, Error> parseSwitchStatement(); … … 198 209 Expected<UniqueRef<AST::Expression>, Error> parseEffectfulExpression(); 199 210 Expected<UniqueRef<AST::Expression>, Error> parseEffectfulAssignment(); 200 Expected<UniqueRef<AST::Expression>, Error> parseEffectfulPrefix();201 Expected<UniqueRef<AST::Expression>, Error> parseEffectfulSuffix();202 211 struct SuffixExpression { 203 212 SuffixExpression(UniqueRef<AST::Expression>&& result, bool success) … … 215 224 216 225 Expected<UniqueRef<AST::Expression>, Error> parseExpression(); 217 Expected<UniqueRef<AST::Expression>, Error> parseTernaryConditional();218 Expected<UniqueRef<AST::Expression>, Error> parseAssignment();219 226 Expected<UniqueRef<AST::Expression>, Error> parsePossibleTernaryConditional(); 227 Expected<UniqueRef<AST::Expression>, Error> completeTernaryConditional(Lexer::Token&& origin, UniqueRef<AST::Expression>&& predicate); 228 Expected<UniqueRef<AST::Expression>, Error> completeAssignment(Lexer::Token&& origin, UniqueRef<AST::Expression>&& left); 220 229 Expected<UniqueRef<AST::Expression>, Error> parsePossibleLogicalBinaryOperation(); 230 Expected<UniqueRef<AST::Expression>, Error> completePossibleLogicalBinaryOperation(UniqueRef<AST::Expression>&& previous); 221 231 Expected<UniqueRef<AST::Expression>, Error> parsePossibleRelationalBinaryOperation(); 232 Expected<UniqueRef<AST::Expression>, Error> completePossibleRelationalBinaryOperation(UniqueRef<AST::Expression>&& previous); 222 233 Expected<UniqueRef<AST::Expression>, Error> parsePossibleShift(); 234 Expected<UniqueRef<AST::Expression>, Error> completePossibleShift(UniqueRef<AST::Expression>&& previous); 223 235 Expected<UniqueRef<AST::Expression>, Error> parsePossibleAdd(); 236 Expected<UniqueRef<AST::Expression>, Error> completePossibleAdd(UniqueRef<AST::Expression>&& previous); 224 237 Expected<UniqueRef<AST::Expression>, Error> parsePossibleMultiply(); 225 Expected<UniqueRef<AST::Expression>, Error> parsePossiblePrefix(); 226 Expected<UniqueRef<AST::Expression>, Error> parsePossibleSuffix(); 238 Expected<UniqueRef<AST::Expression>, Error> completePossibleMultiply(UniqueRef<AST::Expression>&& previous); 239 Expected<UniqueRef<AST::Expression>, Error> parsePossiblePrefix(bool *isEffectful = nullptr); 240 Expected<UniqueRef<AST::Expression>, Error> parsePossibleSuffix(bool *isEffectful = nullptr); 227 241 Expected<UniqueRef<AST::Expression>, Error> parseCallExpression(); 228 242 Expected<UniqueRef<AST::Expression>, Error> parseTerm(); -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp
r246121 r246135 59 59 static constexpr bool dumpASTAfterParsing = false; 60 60 static constexpr bool dumpASTAtEnd = false; 61 static constexpr bool alwaysDumpPassFailures = false;61 static constexpr bool alwaysDumpPassFailures = true; 62 62 static constexpr bool dumpPassFailure = dumpASTBeforeEachPass || dumpASTAfterParsing || dumpASTAtEnd || alwaysDumpPassFailures; 63 63 … … 104 104 Parser parser; 105 105 auto standardLibrary = String::fromUTF8(WHLSLStandardLibrary, sizeof(WHLSLStandardLibrary)); 106 auto failure = static_cast<bool>(parser.parse(program, standardLibrary, Parser::Mode::StandardLibrary)); 107 ASSERT_UNUSED(failure, !failure); 108 if (parser.parse(program, whlslSource, Parser::Mode::User)) 106 auto parseStdLibFailure = parser.parse(program, standardLibrary, Parser::Mode::StandardLibrary); 107 if (!ASSERT_DISABLED && parseStdLibFailure) { 108 dataLogLn("failed to parse the standard library: ", *parseStdLibFailure); 109 RELEASE_ASSERT_NOT_REACHED(); 110 } 111 if (auto parseFailure = parser.parse(program, whlslSource, Parser::Mode::User)) { 112 if (dumpPassFailure) 113 dataLogLn("failed to parse the program: ", *parseFailure); 109 114 return WTF::nullopt; 115 } 110 116 111 117 if (!dumpASTBetweenEachPassIfNeeded(program, "AST after parsing"))
Note: See TracChangeset
for help on using the changeset viewer.