Changeset 246052 in webkit
- Timestamp:
- Jun 3, 2019 5:25:40 PM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r246049 r246052 1 2019-06-03 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): 88 (WebCore::WHLSL::Parser::completeTernaryConditional): 89 (WebCore::WHLSL::Parser::parseAssignment): 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-03 Youenn Fablet <youenn@apple.com> 2 115 -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.h
r245897 r246052 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
r245897 r246052 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 } 1054 1055 m_lexer.consumeToken(); 1374 1056 1375 1057 return AST::SwitchStatement(WTFMove(*origin), WTFMove(*value), WTFMove(switchCases)); … … 1384 1066 switch (origin->type) { 1385 1067 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)); 1068 PARSE(value, ConstantExpression); 1069 CONSUME_TYPE(colon, Colon); 1070 1071 PARSE(block, BlockBody, Lexer::Token(*origin)); 1072 1073 return AST::SwitchCase(WTFMove(*origin), WTFMove(*value), WTFMove(*block)); 1397 1074 } 1398 1075 default: { 1399 1076 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)); 1077 CONSUME_TYPE(colon, Colon); 1078 1079 PARSE(block, BlockBody, Lexer::Token(*origin)); 1080 1081 return AST::SwitchCase(WTFMove(*origin), WTF::nullopt, WTFMove(*block)); 1407 1082 } 1408 1083 } … … 1411 1086 auto Parser::parseForLoop() -> Expected<AST::ForLoop, Error> 1412 1087 { 1413 auto origin = consumeType(Lexer::Token::Type::For); 1414 if (!origin) 1415 return Unexpected<Error>(origin.error()); 1088 CONSUME_TYPE(origin, For); 1089 CONSUME_TYPE(leftParenthesis, LeftParenthesis); 1416 1090 1417 1091 auto parseRemainder = [&](Variant<AST::VariableDeclarationsStatement, 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>> { 1092 CONSUME_TYPE(semicolon, Semicolon); 1093 1094 Optional<UniqueRef<AST::Expression>> condition = WTF::nullopt; 1095 if (!tryType(Lexer::Token::Type::Semicolon)) { 1423 1096 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>> { 1097 condition = { WTFMove(*expression) }; 1098 else 1099 return Unexpected<Error>(expression.error()); 1100 CONSUME_TYPE(secondSemicolon, Semicolon); 1101 } 1102 1103 Optional<UniqueRef<AST::Expression>> increment = WTF::nullopt; 1104 if (!tryType(Lexer::Token::Type::RightParenthesis)) { 1433 1105 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()); 1106 increment = { WTFMove(*expression) }; 1107 else 1108 return Unexpected<Error>(expression.error()); 1109 CONSUME_TYPE(rightParenthesis, RightParenthesis); 1110 } 1111 1112 PARSE(body, Statement); 1445 1113 1446 1114 return AST::ForLoop(WTFMove(*origin), WTFMove(initialization), WTFMove(condition), WTFMove(increment), WTFMove(*body)); 1447 1115 }; 1448 1449 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis);1450 if (!leftParenthesis)1451 return Unexpected<Error>(leftParenthesis.error());1452 1116 1453 1117 auto variableDeclarations = backtrackingScope<Expected<AST::VariableDeclarationsStatement, Error>>([&]() { … … 1457 1121 return parseRemainder(WTFMove(*variableDeclarations)); 1458 1122 1459 auto effectfulExpression = parseEffectfulExpression(); 1460 if (!effectfulExpression) 1461 return Unexpected<Error>(effectfulExpression.error()); 1123 PARSE(effectfulExpression, EffectfulExpression); 1462 1124 1463 1125 return parseRemainder(WTFMove(*effectfulExpression)); … … 1466 1128 auto Parser::parseWhileLoop() -> Expected<AST::WhileLoop, Error> 1467 1129 { 1468 auto origin = consumeType(Lexer::Token::Type::While); 1469 if (!origin) 1470 return Unexpected<Error>(origin.error()); 1471 1472 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); 1473 if (!leftParenthesis) 1474 return Unexpected<Error>(leftParenthesis.error()); 1475 1476 auto conditional = parseExpression(); 1477 if (!conditional) 1478 return Unexpected<Error>(conditional.error()); 1479 1480 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 1481 if (!rightParenthesis) 1482 return Unexpected<Error>(rightParenthesis.error()); 1483 1484 auto body = parseStatement(); 1485 if (!body) 1486 return Unexpected<Error>(body.error()); 1130 CONSUME_TYPE(origin, While); 1131 CONSUME_TYPE(leftParenthesis, LeftParenthesis); 1132 PARSE(conditional, Expression); 1133 CONSUME_TYPE(rightParenthesis, RightParenthesis); 1134 PARSE(body, Statement); 1487 1135 1488 1136 return AST::WhileLoop(WTFMove(*origin), WTFMove(*conditional), WTFMove(*body)); … … 1491 1139 auto Parser::parseDoWhileLoop() -> Expected<AST::DoWhileLoop, Error> 1492 1140 { 1493 auto origin = consumeType(Lexer::Token::Type::Do); 1494 if (!origin) 1495 return Unexpected<Error>(origin.error()); 1496 1497 auto body = parseStatement(); 1498 if (!body) 1499 return Unexpected<Error>(body.error()); 1500 1501 auto whileKeyword = consumeType(Lexer::Token::Type::While); 1502 if (!whileKeyword) 1503 return Unexpected<Error>(whileKeyword.error()); 1504 1505 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); 1506 if (!leftParenthesis) 1507 return Unexpected<Error>(leftParenthesis.error()); 1508 1509 auto conditional = parseExpression(); 1510 if (!conditional) 1511 return Unexpected<Error>(conditional.error()); 1512 1513 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 1514 if (!rightParenthesis) 1515 return Unexpected<Error>(rightParenthesis.error()); 1141 CONSUME_TYPE(origin, Do); 1142 PARSE(body, Statement); 1143 CONSUME_TYPE(whileKeyword, While); 1144 CONSUME_TYPE(leftParenthesis, LeftParenthesis); 1145 PARSE(conditional, Expression); 1146 CONSUME_TYPE(rightParenthesis, RightParenthesis); 1147 CONSUME_TYPE(semicolon, Semicolon); 1516 1148 1517 1149 return AST::DoWhileLoop(WTFMove(*origin), WTFMove(*body), WTFMove(*conditional)); … … 1520 1152 auto Parser::parseVariableDeclaration(UniqueRef<AST::UnnamedType>&& type) -> Expected<AST::VariableDeclaration, Error> 1521 1153 { 1522 auto origin = peek(); 1523 if (!origin) 1524 return Unexpected<Error>(origin.error()); 1154 PEEK(origin); 1525 1155 1526 1156 auto qualifiers = parseQualifiers(); 1527 1157 1528 auto name = consumeType(Lexer::Token::Type::Identifier); 1529 if (!name) 1530 return Unexpected<Error>(name.error()); 1531 1532 if (tryType(Lexer::Token::Type::Colon)) { 1533 auto semantic = parseSemantic(); 1534 if (!semantic) 1535 return Unexpected<Error>(semantic.error()); 1536 1537 if (tryType(Lexer::Token::Type::EqualsSign)) { 1538 auto initializer = parseExpression(); 1539 if (!initializer) 1540 return Unexpected<Error>(initializer.error()); 1541 return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(type) }, name->stringView.toString(), WTFMove(*semantic), WTFMove(*initializer)); 1542 } 1543 1544 return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(type) }, name->stringView.toString(), WTFMove(*semantic), WTF::nullopt); 1545 } 1158 CONSUME_TYPE(name, Identifier); 1159 PARSE(semantic, Semantic); 1546 1160 1547 1161 if (tryType(Lexer::Token::Type::EqualsSign)) { 1548 auto initializer = parseExpression(); 1549 if (!initializer) 1550 return Unexpected<Error>(initializer.error()); 1551 return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(type) }, name->stringView.toString(), WTF::nullopt, WTFMove(*initializer)); 1552 } 1553 1554 return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(type) }, name->stringView.toString(), WTF::nullopt, WTF::nullopt); 1162 PARSE(initializer, PossibleTernaryConditional); 1163 return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(type) }, name->stringView.toString(), WTFMove(*semantic), WTFMove(*initializer)); 1164 } 1165 1166 return AST::VariableDeclaration(WTFMove(*origin), WTFMove(qualifiers), { WTFMove(type) }, name->stringView.toString(), WTFMove(*semantic), WTF::nullopt); 1555 1167 } 1556 1168 1557 1169 auto Parser::parseVariableDeclarations() -> Expected<AST::VariableDeclarationsStatement, Error> 1558 1170 { 1559 auto origin = peek(); 1560 if (!origin) 1561 return Unexpected<Error>(origin.error()); 1562 1563 auto type = parseType(); 1564 if (!type) 1565 return Unexpected<Error>(type.error()); 1171 PEEK(origin); 1172 1173 PARSE(type, Type); 1566 1174 1567 1175 auto firstVariableDeclaration = parseVariableDeclaration((*type)->clone()); … … 1584 1192 auto Parser::parseStatement() -> Expected<UniqueRef<AST::Statement>, Error> 1585 1193 { 1194 PEEK(token); 1195 switch (token->type) { 1196 case Lexer::Token::Type::LeftCurlyBracket: { 1197 PARSE(block, Block); 1198 return { makeUniqueRef<AST::Block>(WTFMove(*block)) }; 1199 } 1200 case Lexer::Token::Type::If: { 1201 PARSE(ifStatement, IfStatement); 1202 return { makeUniqueRef<AST::IfStatement>(WTFMove(*ifStatement)) }; 1203 } 1204 case Lexer::Token::Type::Switch: { 1205 PARSE(switchStatement, SwitchStatement); 1206 return { makeUniqueRef<AST::SwitchStatement>(WTFMove(*switchStatement)) }; 1207 } 1208 case Lexer::Token::Type::For: { 1209 PARSE(forLoop, ForLoop); 1210 return { makeUniqueRef<AST::ForLoop>(WTFMove(*forLoop)) }; 1211 } 1212 case Lexer::Token::Type::While: { 1213 PARSE(whileLoop, WhileLoop); 1214 return { makeUniqueRef<AST::WhileLoop>(WTFMove(*whileLoop)) }; 1215 } 1216 case Lexer::Token::Type::Do: { 1217 PARSE(doWhileLoop, DoWhileLoop); 1218 return { makeUniqueRef<AST::DoWhileLoop>(WTFMove(*doWhileLoop)) }; 1219 } 1220 case Lexer::Token::Type::Break: { 1221 auto breakToken = m_lexer.consumeToken(); 1222 CONSUME_TYPE(semicolon, Semicolon); 1223 auto breakObject = AST::Break(WTFMove(*breakToken)); 1224 return { makeUniqueRef<AST::Break>(WTFMove(breakObject)) }; 1225 } 1226 case Lexer::Token::Type::Continue: { 1227 auto continueToken = m_lexer.consumeToken(); 1228 CONSUME_TYPE(semicolon, Semicolon); 1229 auto continueObject = AST::Continue(WTFMove(*continueToken)); 1230 return { makeUniqueRef<AST::Continue>(WTFMove(continueObject)) }; 1231 } 1232 case Lexer::Token::Type::Fallthrough: { 1233 auto fallthroughToken = m_lexer.consumeToken(); 1234 CONSUME_TYPE(semicolon, Semicolon); 1235 auto fallthroughObject = AST::Fallthrough(WTFMove(*fallthroughToken)); 1236 return { makeUniqueRef<AST::Fallthrough>(WTFMove(fallthroughObject)) }; 1237 } 1238 case Lexer::Token::Type::Trap: { 1239 auto trapToken = m_lexer.consumeToken(); 1240 CONSUME_TYPE(semicolon, Semicolon); 1241 auto trapObject = AST::Trap(WTFMove(*trapToken)); 1242 return { makeUniqueRef<AST::Trap>(WTFMove(trapObject)) }; 1243 } 1244 case Lexer::Token::Type::Return: { 1245 auto returnToken = m_lexer.consumeToken(); 1246 if (auto semicolon = tryType(Lexer::Token::Type::Semicolon)) { 1247 auto returnObject = AST::Return(WTFMove(*returnToken), WTF::nullopt); 1248 return { makeUniqueRef<AST::Return>(WTFMove(returnObject)) }; 1249 } 1250 PARSE(expression, Expression); 1251 CONSUME_TYPE(finalSemicolon, Semicolon); 1252 auto returnObject = AST::Return(WTFMove(*returnToken), { WTFMove(*expression) }); 1253 return { makeUniqueRef<AST::Return>(WTFMove(returnObject)) }; 1254 } 1255 case Lexer::Token::Type::Constant: 1256 case Lexer::Token::Type::Device: 1257 case Lexer::Token::Type::Threadgroup: 1258 case Lexer::Token::Type::Thread: { 1259 PARSE(variableDeclarations, VariableDeclarations); 1260 CONSUME_TYPE(semicolon, Semicolon); 1261 return { makeUniqueRef<AST::VariableDeclarationsStatement>(WTFMove(*variableDeclarations)) }; 1262 } 1263 case Lexer::Token::Type::Identifier: { 1264 PEEK_FURTHER(nextToken); 1265 switch (nextToken->type) { 1266 case Lexer::Token::Type::Identifier: 1267 case Lexer::Token::Type::LessThanSign: 1268 case Lexer::Token::Type::Star: 1269 case Lexer::Token::Type::Qualifier: { 1270 PARSE(variableDeclarations, VariableDeclarations); 1271 CONSUME_TYPE(semicolon, Semicolon); 1272 return { makeUniqueRef<AST::VariableDeclarationsStatement>(WTFMove(*variableDeclarations)) }; 1273 } 1274 default: 1275 break; 1276 } 1277 break; 1278 } 1279 default: 1280 break; 1281 } 1282 1586 1283 { 1587 auto block = backtrackingScope<Expected<AST::Block, Error>>([&]() { 1588 return parseBlock(); 1589 }); 1590 if (block) 1591 return { makeUniqueRef<AST::Block>(WTFMove(*block)) }; 1592 } 1593 1594 { 1595 auto ifStatement = backtrackingScope<Expected<AST::IfStatement, Error>>([&]() { 1596 return parseIfStatement(); 1597 }); 1598 if (ifStatement) 1599 return { makeUniqueRef<AST::IfStatement>(WTFMove(*ifStatement)) }; 1600 } 1601 1602 { 1603 auto switchStatement = backtrackingScope<Expected<AST::SwitchStatement, Error>>([&]() { 1604 return parseSwitchStatement(); 1605 }); 1606 if (switchStatement) 1607 return { makeUniqueRef<AST::SwitchStatement>(WTFMove(*switchStatement)) }; 1608 } 1609 1610 { 1611 auto forLoop = backtrackingScope<Expected<AST::ForLoop, Error>>([&]() { 1612 return parseForLoop(); 1613 }); 1614 if (forLoop) 1615 return { makeUniqueRef<AST::ForLoop>(WTFMove(*forLoop)) }; 1616 } 1617 1618 { 1619 auto whileLoop = backtrackingScope<Expected<AST::WhileLoop, Error>>([&]() { 1620 return parseWhileLoop(); 1621 }); 1622 if (whileLoop) 1623 return { makeUniqueRef<AST::WhileLoop>(WTFMove(*whileLoop)) }; 1624 } 1625 1626 { 1627 auto doWhileLoop = backtrackingScope<Expected<AST::DoWhileLoop, Error>>([&]() -> Expected<AST::DoWhileLoop, Error> { 1628 auto result = parseDoWhileLoop(); 1629 if (!result) 1630 return Unexpected<Error>(result.error()); 1631 1632 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1633 if (!semicolon) 1634 return Unexpected<Error>(semicolon.error()); 1635 1284 auto effectfulExpression = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { 1285 PARSE(result, EffectfulExpression); 1286 CONSUME_TYPE(semicolon, Semicolon); 1636 1287 return result; 1637 1288 }); 1638 if (doWhileLoop) 1639 return { makeUniqueRef<AST::DoWhileLoop>(WTFMove(*doWhileLoop)) }; 1640 } 1641 1642 { 1643 auto breakObject = backtrackingScope<Expected<AST::Break, Error>>([&]() -> Expected<AST::Break, Error> { 1644 auto origin = consumeType(Lexer::Token::Type::Break); 1645 if (!origin) 1646 return Unexpected<Error>(origin.error()); 1647 1648 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1649 if (!semicolon) 1650 return Unexpected<Error>(semicolon.error()); 1651 1652 return AST::Break(WTFMove(*origin)); 1653 }); 1654 if (breakObject) 1655 return { makeUniqueRef<AST::Break>(WTFMove(*breakObject)) }; 1656 } 1657 1658 { 1659 auto continueObject = backtrackingScope<Expected<AST::Continue, Error>>([&]() -> Expected<AST::Continue, Error> { 1660 auto origin = consumeType(Lexer::Token::Type::Continue); 1661 if (!origin) 1662 return Unexpected<Error>(origin.error()); 1663 1664 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1665 if (!semicolon) 1666 return Unexpected<Error>(semicolon.error()); 1667 1668 return AST::Continue(WTFMove(*origin)); 1669 }); 1670 if (continueObject) 1671 return { makeUniqueRef<AST::Continue>(WTFMove(*continueObject)) }; 1672 } 1673 1674 { 1675 auto fallthroughObject = backtrackingScope<Expected<AST::Fallthrough, Error>>([&]() -> Expected<AST::Fallthrough, Error> { 1676 auto origin = consumeType(Lexer::Token::Type::Fallthrough); 1677 if (!origin) 1678 return Unexpected<Error>(origin.error()); 1679 1680 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1681 if (!semicolon) 1682 return Unexpected<Error>(semicolon.error()); 1683 1684 return AST::Fallthrough(WTFMove(*origin)); 1685 }); 1686 if (fallthroughObject) 1687 return { makeUniqueRef<AST::Fallthrough>(WTFMove(*fallthroughObject)) }; 1688 } 1689 1690 { 1691 auto trapObject = backtrackingScope<Expected<AST::Trap, Error>>([&]() -> Expected<AST::Trap, Error> { 1692 auto origin = consumeType(Lexer::Token::Type::Trap); 1693 if (!origin) 1694 return Unexpected<Error>(origin.error()); 1695 1696 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1697 if (!semicolon) 1698 return Unexpected<Error>(semicolon.error()); 1699 1700 return AST::Trap(WTFMove(*origin)); 1701 }); 1702 if (trapObject) 1703 return { makeUniqueRef<AST::Trap>(WTFMove(*trapObject)) }; 1704 } 1705 1706 { 1707 auto returnObject = backtrackingScope<Expected<AST::Return, Error>>([&]() -> Expected<AST::Return, Error> { 1708 auto origin = consumeType(Lexer::Token::Type::Return); 1709 if (!origin) 1710 return Unexpected<Error>(origin.error()); 1711 1712 if (auto semicolon = tryType(Lexer::Token::Type::Semicolon)) 1713 return AST::Return(WTFMove(*origin), WTF::nullopt); 1714 1715 auto expression = parseExpression(); 1716 if (!expression) 1717 return Unexpected<Error>(expression.error()); 1718 1719 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1720 if (!semicolon) 1721 return Unexpected<Error>(semicolon.error()); 1722 1723 return AST::Return(WTFMove(*origin), { WTFMove(*expression) }); 1724 }); 1725 if (returnObject) 1726 return { makeUniqueRef<AST::Return>(WTFMove(*returnObject)) }; 1727 } 1728 1729 { 1730 auto variableDeclarations = backtrackingScope<Expected<AST::VariableDeclarationsStatement, Error>>([&]() -> Expected<AST::VariableDeclarationsStatement, Error> { 1731 auto result = parseVariableDeclarations(); 1732 if (!result) 1733 return Unexpected<Error>(result.error()); 1734 1735 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1736 if (!semicolon) 1737 return Unexpected<Error>(semicolon.error()); 1738 1739 return result; 1740 }); 1741 if (variableDeclarations) 1742 return { makeUniqueRef<AST::VariableDeclarationsStatement>(WTFMove(*variableDeclarations)) }; 1743 } 1744 1745 auto effectfulExpression = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { 1746 auto result = parseEffectfulExpression(); 1747 if (!result) 1748 return Unexpected<Error>(result.error()); 1749 1750 auto semicolon = consumeType(Lexer::Token::Type::Semicolon); 1751 if (!semicolon) 1752 return Unexpected<Error>(semicolon.error()); 1753 1754 return result; 1755 }); 1756 if (effectfulExpression) 1757 return { makeUniqueRef<AST::EffectfulExpressionStatement>(WTFMove(*effectfulExpression)) }; 1758 1759 return Unexpected<Error>(effectfulExpression.error()); 1289 if (effectfulExpression) 1290 return { makeUniqueRef<AST::EffectfulExpressionStatement>(WTFMove(*effectfulExpression)) }; 1291 } 1292 1293 PARSE(variableDeclarations, VariableDeclarations); 1294 CONSUME_TYPE(semicolon, Semicolon); 1295 return { makeUniqueRef<AST::VariableDeclarationsStatement>(WTFMove(*variableDeclarations)) }; 1760 1296 } 1761 1297 1762 1298 auto Parser::parseEffectfulExpression() -> Expected<UniqueRef<AST::Expression>, Error> 1763 1299 { 1764 auto origin = peek(); 1765 if (!origin) 1766 return Unexpected<Error>(origin.error()); 1300 PEEK(origin); 1767 1301 1768 1302 Vector<UniqueRef<AST::Expression>> expressions; 1769 1770 auto first = backtrackingScope<Optional<UniqueRef<AST::Expression>>>([&]() -> Optional<UniqueRef<AST::Expression>> { 1771 auto effectfulExpression = parseEffectfulAssignment(); 1772 if (!effectfulExpression) 1773 return WTF::nullopt; 1774 return { WTFMove(*effectfulExpression) }; 1775 }); 1776 if (!first) 1303 if (origin->type == Lexer::Token::Type::Semicolon) 1777 1304 return { makeUniqueRef<AST::CommaExpression>(WTFMove(*origin), WTFMove(expressions)) }; 1778 1305 1779 expressions.append(WTFMove(*first)); 1306 PARSE(effectfulExpression, EffectfulAssignment); 1307 expressions.append(WTFMove(*effectfulExpression)); 1780 1308 1781 1309 while (tryType(Lexer::Token::Type::Comma)) { 1782 auto expression = parseEffectfulAssignment(); 1783 if (!expression) 1784 return Unexpected<Error>(expression.error()); 1310 PARSE(expression, EffectfulAssignment); 1785 1311 expressions.append(WTFMove(*expression)); 1786 1312 } … … 1793 1319 auto Parser::parseEffectfulAssignment() -> Expected<UniqueRef<AST::Expression>, Error> 1794 1320 { 1795 auto assignment = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { 1796 return parseAssignment(); 1797 }); 1798 if (assignment) 1799 return assignment; 1800 1801 assignment = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { 1802 return parseEffectfulPrefix(); 1803 }); 1804 if (assignment) 1805 return assignment; 1806 1807 return Unexpected<Error>(assignment.error()); 1808 } 1809 1810 auto Parser::parseEffectfulPrefix() -> Expected<UniqueRef<AST::Expression>, Error> 1811 { 1812 auto prefix = consumeTypes({ Lexer::Token::Type::PlusPlus, Lexer::Token::Type::MinusMinus }); 1813 if (!prefix) 1814 return parseEffectfulSuffix(); 1815 1816 auto previous = parsePossiblePrefix(); 1817 if (!previous) 1818 return Unexpected<Error>(previous.error()); 1819 1820 switch (prefix->type) { 1821 case Lexer::Token::Type::PlusPlus: { 1822 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*prefix), WTFMove(*previous)); 1823 Vector<UniqueRef<AST::Expression>> callArguments; 1824 callArguments.append(result->oldVariableReference()); 1825 result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*prefix), "operator++"_str, WTFMove(callArguments))); 1826 result->setResultExpression(result->newVariableReference()); 1827 return { WTFMove(result) }; 1828 } 1829 default: { 1830 ASSERT(prefix->type == Lexer::Token::Type::MinusMinus); 1831 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*prefix), WTFMove(*previous)); 1832 Vector<UniqueRef<AST::Expression>> callArguments; 1833 callArguments.append(result->oldVariableReference()); 1834 result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*prefix), "operator--"_str, WTFMove(callArguments))); 1835 result->setResultExpression(result->newVariableReference()); 1836 return { WTFMove(result) }; 1837 } 1838 } 1839 } 1840 1841 auto Parser::parseEffectfulSuffix() -> Expected<UniqueRef<AST::Expression>, Error> 1842 { 1843 auto effectfulSuffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { 1844 auto previous = parsePossibleSuffix(); 1845 if (!previous) 1846 return Unexpected<Error>(previous.error()); 1847 1848 auto suffix = consumeTypes({ Lexer::Token::Type::PlusPlus, Lexer::Token::Type::MinusMinus }); 1849 if (!suffix) 1850 return Unexpected<Error>(suffix.error()); 1851 1852 switch (suffix->type) { 1853 case Lexer::Token::Type::PlusPlus: { 1854 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*suffix), WTFMove(*previous)); 1855 Vector<UniqueRef<AST::Expression>> callArguments; 1856 callArguments.append(result->oldVariableReference()); 1857 result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*suffix), "operator++"_str, WTFMove(callArguments))); 1858 result->setResultExpression(result->oldVariableReference()); 1859 return { WTFMove(result) }; 1860 } 1861 default: { 1862 ASSERT(suffix->type == Lexer::Token::Type::MinusMinus); 1863 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*suffix), WTFMove(*previous)); 1864 Vector<UniqueRef<AST::Expression>> callArguments; 1865 callArguments.append(result->oldVariableReference()); 1866 result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(*suffix), "operator--"_str, WTFMove(callArguments))); 1867 result->setResultExpression(result->oldVariableReference()); 1868 return { WTFMove(result) }; 1869 } 1870 } 1871 }); 1872 if (effectfulSuffix) 1873 return effectfulSuffix; 1874 1875 effectfulSuffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { 1876 return parseCallExpression(); 1877 }); 1878 if (effectfulSuffix) 1879 return effectfulSuffix; 1880 1881 effectfulSuffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { 1882 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); 1883 if (!leftParenthesis) 1884 return Unexpected<Error>(leftParenthesis.error()); 1885 1886 auto expression = parseExpression(); 1887 if (!expression) 1888 return Unexpected<Error>(expression.error()); 1889 1890 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 1891 if (!rightParenthesis) 1892 return Unexpected<Error>(rightParenthesis.error()); 1893 1894 return { WTFMove(*expression) }; 1895 }); 1896 if (effectfulSuffix) 1897 return effectfulSuffix; 1898 1899 return Unexpected<Error>(effectfulSuffix.error()); 1321 PEEK(origin); 1322 1323 bool isEffectful = false; 1324 PARSE(expression, PossiblePrefix, &isEffectful); 1325 1326 if (!isEffectful || peekTypes({ 1327 Lexer::Token::Type::EqualsSign, 1328 Lexer::Token::Type::PlusEquals, 1329 Lexer::Token::Type::MinusEquals, 1330 Lexer::Token::Type::TimesEquals, 1331 Lexer::Token::Type::DivideEquals, 1332 Lexer::Token::Type::ModEquals, 1333 Lexer::Token::Type::XorEquals, 1334 Lexer::Token::Type::AndEquals, 1335 Lexer::Token::Type::OrEquals, 1336 Lexer::Token::Type::RightShiftEquals, 1337 Lexer::Token::Type::LeftShiftEquals 1338 })) { 1339 return completeAssignment(WTFMove(*origin), WTFMove(*expression)); 1340 } 1341 1342 return expression; 1900 1343 } 1901 1344 … … 1980 1423 auto Parser::parseExpression() -> Expected<UniqueRef<AST::Expression>, Error> 1981 1424 { 1982 auto origin = peek(); 1983 if (!origin) 1984 return Unexpected<Error>(origin.error()); 1985 1986 auto first = parsePossibleTernaryConditional(); 1987 if (!first) 1988 return Unexpected<Error>(first.error()); 1989 1425 PEEK(origin); 1426 1427 PARSE(first, PossibleTernaryConditional); 1990 1428 Vector<UniqueRef<AST::Expression>> expressions; 1991 1429 expressions.append(WTFMove(*first)); 1992 1430 1993 1431 while (tryType(Lexer::Token::Type::Comma)) { 1994 auto expression = parsePossibleTernaryConditional(); 1995 if (!expression) 1996 return Unexpected<Error>(expression.error()); 1432 PARSE(expression, PossibleTernaryConditional); 1997 1433 expressions.append(WTFMove(*expression)); 1998 1434 } … … 2005 1441 auto Parser::parseTernaryConditional() -> Expected<UniqueRef<AST::Expression>, Error> 2006 1442 { 2007 auto origin = peek(); 2008 if (!origin) 2009 return Unexpected<Error>(origin.error()); 2010 2011 auto predicate = parsePossibleLogicalBinaryOperation(); 2012 if (!predicate) 2013 return Unexpected<Error>(predicate.error()); 2014 2015 auto questionMark = consumeType(Lexer::Token::Type::QuestionMark); 2016 if (!questionMark) 2017 return Unexpected<Error>(questionMark.error()); 2018 2019 auto bodyExpression = parseExpression(); 2020 if (!bodyExpression) 2021 return Unexpected<Error>(bodyExpression.error()); 2022 2023 auto colon = consumeType(Lexer::Token::Type::Colon); 2024 if (!colon) 2025 return Unexpected<Error>(colon.error()); 2026 2027 auto elseExpression = parsePossibleTernaryConditional(); 2028 if (!elseExpression) 2029 return Unexpected<Error>(elseExpression.error()); 1443 PEEK(origin); 1444 1445 PARSE(predicate, PossibleLogicalBinaryOperation); 1446 1447 return completeTernaryConditional(WTFMove(*origin), WTFMove(*predicate)); 1448 } 1449 1450 auto Parser::completeTernaryConditional(Lexer::Token&& origin, UniqueRef<AST::Expression>&& predicate) -> Expected<UniqueRef<AST::Expression>, Error> 1451 { 1452 CONSUME_TYPE(questionMark, QuestionMark); 1453 PARSE(bodyExpression, Expression); 1454 CONSUME_TYPE(colon, Colon); 1455 PARSE(elseExpression, PossibleTernaryConditional); 2030 1456 2031 1457 Vector<UniqueRef<AST::Expression>> castArguments; 2032 castArguments.append(WTFMove( *predicate));2033 auto boolCast = makeUniqueRef<AST::CallExpression>(Lexer::Token( *origin), "bool"_str, WTFMove(castArguments));2034 return { makeUniqueRef<AST::TernaryExpression>(WTFMove( *origin), WTFMove(boolCast), WTFMove(*bodyExpression), WTFMove(*elseExpression)) };1458 castArguments.append(WTFMove(predicate)); 1459 auto boolCast = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), "bool"_str, WTFMove(castArguments)); 1460 return { makeUniqueRef<AST::TernaryExpression>(WTFMove(origin), WTFMove(boolCast), WTFMove(*bodyExpression), WTFMove(*elseExpression)) }; 2035 1461 } 2036 1462 2037 1463 auto Parser::parseAssignment() -> Expected<UniqueRef<AST::Expression>, Error> 2038 1464 { 2039 auto origin = peek(); 2040 if (!origin) 2041 return Unexpected<Error>(origin.error()); 2042 2043 auto left = parsePossiblePrefix(); 2044 if (!left) 2045 return Unexpected<Error>(left.error()); 2046 1465 PEEK(origin); 1466 1467 PARSE(left, PossiblePrefix); 1468 1469 return completeAssignment(WTFMove(*origin), WTFMove(*left)); 1470 } 1471 1472 auto Parser::completeAssignment(Lexer::Token&& origin, UniqueRef<AST::Expression>&& left) -> Expected<UniqueRef<AST::Expression>, Error> 1473 { 2047 1474 auto assignmentOperator = consumeTypes({ 2048 1475 Lexer::Token::Type::EqualsSign, … … 2061 1488 return Unexpected<Error>(assignmentOperator.error()); 2062 1489 2063 auto right = parsePossibleTernaryConditional(); 2064 if (!right) 2065 return Unexpected<Error>(right.error()); 1490 PARSE(right, PossibleTernaryConditional); 2066 1491 2067 1492 if (assignmentOperator->type == Lexer::Token::Type::EqualsSign) 2068 return { makeUniqueRef<AST::AssignmentExpression>(WTFMove( *origin), WTFMove(*left), WTFMove(*right))};1493 return { makeUniqueRef<AST::AssignmentExpression>(WTFMove(origin), WTFMove(left), WTFMove(*right))}; 2069 1494 2070 1495 String name; … … 2103 1528 } 2104 1529 2105 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token( *origin), WTFMove(*left));1530 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(origin), WTFMove(left)); 2106 1531 Vector<UniqueRef<AST::Expression>> callArguments; 2107 1532 callArguments.append(result->oldVariableReference()); 2108 1533 callArguments.append(WTFMove(*right)); 2109 result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove( *origin), WTFMove(name), WTFMove(callArguments)));1534 result->setNewValueExpression(makeUniqueRef<AST::CallExpression>(WTFMove(origin), WTFMove(name), WTFMove(callArguments))); 2110 1535 result->setResultExpression(result->newVariableReference()); 2111 1536 return { WTFMove(result) }; … … 2114 1539 auto Parser::parsePossibleTernaryConditional() -> Expected<UniqueRef<AST::Expression>, Error> 2115 1540 { 2116 auto ternaryExpression = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { 2117 return parseTernaryConditional(); 2118 }); 2119 if (ternaryExpression) 2120 return ternaryExpression; 2121 2122 auto assignmentExpression = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { 2123 return parseAssignment(); 2124 }); 2125 if (assignmentExpression) 2126 return assignmentExpression; 2127 2128 auto binaryOperation = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() { 2129 return parsePossibleLogicalBinaryOperation(); 2130 }); 2131 if (binaryOperation) 2132 return binaryOperation; 2133 2134 return Unexpected<Error>(binaryOperation.error()); 1541 PEEK(origin); 1542 1543 PARSE(expression, PossiblePrefix); 1544 1545 if (tryTypes({Lexer::Token::Type::EqualsSign, 1546 Lexer::Token::Type::PlusEquals, 1547 Lexer::Token::Type::MinusEquals, 1548 Lexer::Token::Type::TimesEquals, 1549 Lexer::Token::Type::DivideEquals, 1550 Lexer::Token::Type::ModEquals, 1551 Lexer::Token::Type::XorEquals, 1552 Lexer::Token::Type::AndEquals, 1553 Lexer::Token::Type::OrEquals, 1554 Lexer::Token::Type::RightShiftEquals, 1555 Lexer::Token::Type::LeftShiftEquals})) { 1556 return completeAssignment(WTFMove(*origin), WTFMove(*expression)); 1557 } 1558 1559 expression = completePossibleShift(WTFMove(*expression)); 1560 expression = completePossibleMultiply(WTFMove(*expression)); 1561 expression = completePossibleAdd(WTFMove(*expression)); 1562 expression = completePossibleRelationalBinaryOperation(WTFMove(*expression)); 1563 expression = completePossibleLogicalBinaryOperation(WTFMove(*expression)); 1564 1565 PEEK(nextToken); 1566 if (nextToken->type == Lexer::Token::Type::QuestionMark) 1567 return completeTernaryConditional(WTFMove(*origin), WTFMove(*expression)); 1568 return expression; 2135 1569 } 2136 1570 2137 1571 auto Parser::parsePossibleLogicalBinaryOperation() -> Expected<UniqueRef<AST::Expression>, Error> 2138 1572 { 2139 auto parsedPrevious = parsePossibleRelationalBinaryOperation(); 2140 if (!parsedPrevious) 2141 return Unexpected<Error>(parsedPrevious.error()); 2142 UniqueRef<AST::Expression> previous = WTFMove(*parsedPrevious); 2143 1573 PARSE(parsedPrevious, PossibleRelationalBinaryOperation); 1574 return completePossibleLogicalBinaryOperation(WTFMove(*parsedPrevious)); 1575 } 1576 1577 auto Parser::completePossibleLogicalBinaryOperation(UniqueRef<AST::Expression>&& previous) -> Expected<UniqueRef<AST::Expression>, Error> 1578 { 2144 1579 while (auto logicalBinaryOperation = tryTypes({ 2145 1580 Lexer::Token::Type::OrOr, … … 2149 1584 Lexer::Token::Type::And 2150 1585 })) { 2151 auto next = parsePossibleRelationalBinaryOperation(); 2152 if (!next) 2153 return Unexpected<Error>(next.error()); 1586 PARSE(next, PossibleRelationalBinaryOperation); 2154 1587 2155 1588 switch (logicalBinaryOperation->type) { … … 2190 1623 auto Parser::parsePossibleRelationalBinaryOperation() -> Expected<UniqueRef<AST::Expression>, Error> 2191 1624 { 2192 auto parsedPrevious = parsePossibleShift(); 2193 if (!parsedPrevious) 2194 return Unexpected<Error>(parsedPrevious.error()); 2195 UniqueRef<AST::Expression> previous = WTFMove(*parsedPrevious); 2196 1625 PARSE(parsedPrevious, PossibleShift); 1626 return completePossibleRelationalBinaryOperation(WTFMove(*parsedPrevious)); 1627 } 1628 1629 auto Parser::completePossibleRelationalBinaryOperation(UniqueRef<AST::Expression>&& previous) -> Expected<UniqueRef<AST::Expression>, Error> 1630 { 2197 1631 while (auto relationalBinaryOperation = tryTypes({ 2198 1632 Lexer::Token::Type::LessThanSign, … … 2203 1637 Lexer::Token::Type::NotEqual 2204 1638 })) { 2205 auto next = parsePossibleShift(); 2206 if (!next) 2207 return Unexpected<Error>(next.error()); 1639 PARSE(next, PossibleShift); 1640 1641 Vector<UniqueRef<AST::Expression>> callArguments; 1642 callArguments.append(WTFMove(previous)); 1643 callArguments.append(WTFMove(*next)); 2208 1644 2209 1645 switch (relationalBinaryOperation->type) { 2210 1646 case Lexer::Token::Type::LessThanSign: { 2211 Vector<UniqueRef<AST::Expression>> callArguments;2212 callArguments.append(WTFMove(previous));2213 callArguments.append(WTFMove(*next));2214 1647 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), "operator<"_str, WTFMove(callArguments)); 2215 1648 break; 2216 1649 } 2217 1650 case Lexer::Token::Type::GreaterThanSign: { 2218 Vector<UniqueRef<AST::Expression>> callArguments;2219 callArguments.append(WTFMove(previous));2220 callArguments.append(WTFMove(*next));2221 1651 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), "operator>"_str, WTFMove(callArguments)); 2222 1652 break; 2223 1653 } 2224 1654 case Lexer::Token::Type::LessThanOrEqualTo: { 2225 Vector<UniqueRef<AST::Expression>> callArguments;2226 callArguments.append(WTFMove(previous));2227 callArguments.append(WTFMove(*next));2228 1655 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), "operator<="_str, WTFMove(callArguments)); 2229 1656 break; 2230 1657 } 2231 1658 case Lexer::Token::Type::GreaterThanOrEqualTo: { 2232 Vector<UniqueRef<AST::Expression>> callArguments;2233 callArguments.append(WTFMove(previous));2234 callArguments.append(WTFMove(*next));2235 1659 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), "operator>="_str, WTFMove(callArguments)); 2236 1660 break; 2237 1661 } 2238 1662 case Lexer::Token::Type::EqualComparison: { 2239 Vector<UniqueRef<AST::Expression>> callArguments;2240 callArguments.append(WTFMove(previous));2241 callArguments.append(WTFMove(*next));2242 1663 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), "operator=="_str, WTFMove(callArguments)); 2243 1664 break; … … 2245 1666 default: { 2246 1667 ASSERT(relationalBinaryOperation->type == Lexer::Token::Type::NotEqual); 2247 Vector<UniqueRef<AST::Expression>> callArguments;2248 callArguments.append(WTFMove(previous));2249 callArguments.append(WTFMove(*next));2250 1668 previous = makeUniqueRef<AST::CallExpression>(Lexer::Token(*relationalBinaryOperation), "operator=="_str, WTFMove(callArguments)); 2251 1669 previous = makeUniqueRef<AST::LogicalNotExpression>(WTFMove(*relationalBinaryOperation), WTFMove(previous)); … … 2260 1678 auto Parser::parsePossibleShift() -> Expected<UniqueRef<AST::Expression>, Error> 2261 1679 { 2262 auto parsedPrevious = parsePossibleAdd(); 2263 if (!parsedPrevious) 2264 return Unexpected<Error>(parsedPrevious.error()); 2265 UniqueRef<AST::Expression> previous = WTFMove(*parsedPrevious); 2266 1680 PARSE(parsedPrevious, PossibleAdd); 1681 return completePossibleShift(WTFMove(*parsedPrevious)); 1682 } 1683 1684 auto Parser::completePossibleShift(UniqueRef<AST::Expression>&& previous) -> Expected<UniqueRef<AST::Expression>, Error> 1685 { 2267 1686 while (auto shift = tryTypes({ 2268 1687 Lexer::Token::Type::LeftShift, 2269 1688 Lexer::Token::Type::RightShift 2270 1689 })) { 2271 auto next = parsePossibleAdd(); 2272 if (!next) 2273 return Unexpected<Error>(next.error()); 1690 PARSE(next, PossibleAdd); 1691 1692 Vector<UniqueRef<AST::Expression>> callArguments; 1693 callArguments.append(WTFMove(previous)); 1694 callArguments.append(WTFMove(*next)); 2274 1695 2275 1696 switch (shift->type) { 2276 1697 case Lexer::Token::Type::LeftShift: { 2277 Vector<UniqueRef<AST::Expression>> callArguments;2278 callArguments.append(WTFMove(previous));2279 callArguments.append(WTFMove(*next));2280 1698 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*shift), "operator<<"_str, WTFMove(callArguments)); 2281 1699 break; … … 2283 1701 default: { 2284 1702 ASSERT(shift->type == Lexer::Token::Type::RightShift); 2285 Vector<UniqueRef<AST::Expression>> callArguments;2286 callArguments.append(WTFMove(previous));2287 callArguments.append(WTFMove(*next));2288 1703 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*shift), "operator>>"_str, WTFMove(callArguments)); 2289 1704 break; … … 2297 1712 auto Parser::parsePossibleAdd() -> Expected<UniqueRef<AST::Expression>, Error> 2298 1713 { 2299 auto parsedPrevious = parsePossibleMultiply(); 2300 if (!parsedPrevious) 2301 return Unexpected<Error>(parsedPrevious.error()); 2302 UniqueRef<AST::Expression> previous = WTFMove(*parsedPrevious); 2303 1714 PARSE(parsedPrevious, PossibleMultiply); 1715 return completePossibleAdd(WTFMove(*parsedPrevious)); 1716 } 1717 1718 auto Parser::completePossibleAdd(UniqueRef<AST::Expression>&& previous) -> Expected<UniqueRef<AST::Expression>, Error> 1719 { 2304 1720 while (auto add = tryTypes({ 2305 1721 Lexer::Token::Type::Plus, 2306 1722 Lexer::Token::Type::Minus 2307 1723 })) { 2308 auto next = parsePossibleMultiply(); 2309 if (!next) 2310 return Unexpected<Error>(next.error()); 1724 PARSE(next, PossibleMultiply); 1725 1726 Vector<UniqueRef<AST::Expression>> callArguments; 1727 callArguments.append(WTFMove(previous)); 1728 callArguments.append(WTFMove(*next)); 2311 1729 2312 1730 switch (add->type) { 2313 1731 case Lexer::Token::Type::Plus: { 2314 Vector<UniqueRef<AST::Expression>> callArguments;2315 callArguments.append(WTFMove(previous));2316 callArguments.append(WTFMove(*next));2317 1732 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*add), "operator+"_str, WTFMove(callArguments)); 2318 1733 break; … … 2320 1735 default: { 2321 1736 ASSERT(add->type == Lexer::Token::Type::Minus); 2322 Vector<UniqueRef<AST::Expression>> callArguments;2323 callArguments.append(WTFMove(previous));2324 callArguments.append(WTFMove(*next));2325 1737 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*add), "operator-"_str, WTFMove(callArguments)); 2326 1738 break; … … 2334 1746 auto Parser::parsePossibleMultiply() -> Expected<UniqueRef<AST::Expression>, Error> 2335 1747 { 2336 auto parsedPrevious = parsePossiblePrefix(); 2337 if (!parsedPrevious) 2338 return Unexpected<Error>(parsedPrevious.error()); 2339 UniqueRef<AST::Expression> previous = WTFMove(*parsedPrevious); 2340 1748 PARSE(parsedPrevious, PossiblePrefix); 1749 return completePossibleMultiply(WTFMove(*parsedPrevious)); 1750 } 1751 1752 auto Parser::completePossibleMultiply(UniqueRef<AST::Expression>&& previous) -> Expected<UniqueRef<AST::Expression>, Error> 1753 { 2341 1754 while (auto multiply = tryTypes({ 2342 1755 Lexer::Token::Type::Star, … … 2344 1757 Lexer::Token::Type::Mod 2345 1758 })) { 2346 auto next = parsePossiblePrefix(); 2347 if (!next) 2348 return Unexpected<Error>(next.error()); 1759 PARSE(next, PossiblePrefix); 1760 1761 Vector<UniqueRef<AST::Expression>> callArguments; 1762 callArguments.append(WTFMove(previous)); 1763 callArguments.append(WTFMove(*next)); 2349 1764 2350 1765 switch (multiply->type) { 2351 1766 case Lexer::Token::Type::Star: { 2352 Vector<UniqueRef<AST::Expression>> callArguments;2353 callArguments.append(WTFMove(previous));2354 callArguments.append(WTFMove(*next));2355 1767 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*multiply), "operator*"_str, WTFMove(callArguments)); 2356 1768 break; 2357 1769 } 2358 1770 case Lexer::Token::Type::Divide: { 2359 Vector<UniqueRef<AST::Expression>> callArguments;2360 callArguments.append(WTFMove(previous));2361 callArguments.append(WTFMove(*next));2362 1771 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*multiply), "operator/"_str, WTFMove(callArguments)); 2363 1772 break; … … 2365 1774 default: { 2366 1775 ASSERT(multiply->type == Lexer::Token::Type::Mod); 2367 Vector<UniqueRef<AST::Expression>> callArguments;2368 callArguments.append(WTFMove(previous));2369 callArguments.append(WTFMove(*next));2370 1776 previous = makeUniqueRef<AST::CallExpression>(WTFMove(*multiply), "operator%"_str, WTFMove(callArguments)); 2371 1777 break; … … 2377 1783 } 2378 1784 2379 auto Parser::parsePossiblePrefix( ) -> Expected<UniqueRef<AST::Expression>, Error>1785 auto Parser::parsePossiblePrefix(bool *isEffectful) -> Expected<UniqueRef<AST::Expression>, Error> 2380 1786 { 2381 1787 if (auto prefix = tryTypes({ … … 2390 1796 Lexer::Token::Type::Star 2391 1797 })) { 2392 auto next = parsePossiblePrefix(); 2393 if (!next) 2394 return Unexpected<Error>(next.error()); 1798 PARSE(next, PossiblePrefix); 2395 1799 2396 1800 switch (prefix->type) { 2397 1801 case Lexer::Token::Type::PlusPlus: { 1802 if (isEffectful) 1803 *isEffectful = true; 2398 1804 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*prefix), WTFMove(*next)); 2399 1805 Vector<UniqueRef<AST::Expression>> callArguments; … … 2404 1810 } 2405 1811 case Lexer::Token::Type::MinusMinus: { 1812 if (isEffectful) 1813 *isEffectful = true; 2406 1814 auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*prefix), WTFMove(*next)); 2407 1815 Vector<UniqueRef<AST::Expression>> callArguments; … … 2442 1850 } 2443 1851 2444 return parsePossibleSuffix(); 2445 } 2446 2447 auto Parser::parsePossibleSuffix() -> Expected<UniqueRef<AST::Expression>, Error> 2448 { 2449 auto suffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { 2450 auto expression = parseCallExpression(); 2451 if (!expression) 2452 return Unexpected<Error>(expression.error()); 2453 1852 return parsePossibleSuffix(isEffectful); 1853 } 1854 1855 auto Parser::parsePossibleSuffix(bool *isEffectful) -> Expected<UniqueRef<AST::Expression>, Error> 1856 { 1857 PEEK(token); 1858 PEEK_FURTHER(nextToken); 1859 1860 if (token->type == Lexer::Token::Type::Identifier && nextToken->type == Lexer::Token::Type::LeftParenthesis) { 1861 PARSE(expression, CallExpression); 1862 if (isEffectful) 1863 *isEffectful = true; 2454 1864 while (true) { 2455 auto result = backtrackingScope<SuffixExpression>([&]() -> SuffixExpression { 2456 return parseLimitedSuffixOperator(WTFMove(*expression)); 2457 }); 1865 PEEK(suffixToken); 1866 if (suffixToken->type != Lexer::Token::Type::FullStop && suffixToken->type != Lexer::Token::Type::Arrow && suffixToken->type != Lexer::Token::Type::LeftSquareBracket) 1867 break; 1868 auto result = parseLimitedSuffixOperator(WTFMove(*expression)); 2458 1869 expression = WTFMove(result.result); 2459 if (!result)2460 break;2461 1870 } 2462 1871 return expression; 2463 } );2464 if (suffix) 2465 return suffix;2466 2467 suffix = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> { 2468 auto expression = parseTerm();2469 if (!expression)2470 return Unexpected<Error>(expression.error());2471 2472 while (true) {2473 auto result = backtrackingScope<SuffixExpression>([&]() -> SuffixExpression {2474 return parseSuffixOperator(WTFMove(*expression));2475 });2476 expression = WTFMove(result.result);2477 if (!result)2478 break;2479 }2480 return expression;2481 });2482 if (suffix)2483 return suffix;2484 2485 return Unexpected<Error>(suffix.error());1872 } 1873 1874 if (token->type == Lexer::Token::Type::LeftParenthesis && isEffectful) 1875 *isEffectful = true; 1876 1877 PARSE(expression, Term); 1878 bool isLastSuffixTokenEffectful = false; 1879 while (true) { 1880 PEEK(suffixToken); 1881 if (suffixToken->type != Lexer::Token::Type::FullStop 1882 && suffixToken->type != Lexer::Token::Type::Arrow 1883 && suffixToken->type != Lexer::Token::Type::LeftSquareBracket 1884 && suffixToken->type != Lexer::Token::Type::PlusPlus 1885 && suffixToken->type != Lexer::Token::Type::MinusMinus) { 1886 break; 1887 } 1888 isLastSuffixTokenEffectful = suffixToken->type == Lexer::Token::Type::PlusPlus || suffixToken->type == Lexer::Token::Type::MinusMinus; 1889 auto result = parseSuffixOperator(WTFMove(*expression)); 1890 expression = WTFMove(result.result); 1891 } 1892 if (isLastSuffixTokenEffectful && isEffectful) 1893 *isEffectful = true; 1894 return expression; 2486 1895 } 2487 1896 2488 1897 auto Parser::parseCallExpression() -> Expected<UniqueRef<AST::Expression>, Error> 2489 1898 { 2490 auto name = consumeType(Lexer::Token::Type::Identifier); 2491 if (!name) 2492 return Unexpected<Error>(name.error()); 1899 CONSUME_TYPE(name, Identifier); 2493 1900 auto callName = name->stringView.toString(); 2494 1901 2495 auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis); 2496 if (!leftParenthesis) 2497 return Unexpected<Error>(leftParenthesis.error()); 1902 CONSUME_TYPE(leftParenthesis, LeftParenthesis); 2498 1903 2499 1904 Vector<UniqueRef<AST::Expression>> arguments; … … 2501 1906 return { makeUniqueRef<AST::CallExpression>(WTFMove(*name), WTFMove(callName), WTFMove(arguments)) }; 2502 1907 2503 auto firstArgument = parsePossibleTernaryConditional(); 2504 if (!firstArgument) 2505 return Unexpected<Error>(firstArgument.error()); 1908 PARSE(firstArgument, PossibleTernaryConditional); 2506 1909 arguments.append(WTFMove(*firstArgument)); 2507 1910 while (tryType(Lexer::Token::Type::Comma)) { 2508 auto argument = parsePossibleTernaryConditional(); 2509 if (!argument) 2510 return Unexpected<Error>(argument.error()); 1911 PARSE(argument, PossibleTernaryConditional); 2511 1912 arguments.append(WTFMove(*argument)); 2512 1913 } 2513 1914 2514 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 2515 if (!rightParenthesis) 2516 return Unexpected<Error>(rightParenthesis.error()); 1915 CONSUME_TYPE(rightParenthesis, RightParenthesis); 2517 1916 2518 1917 return { makeUniqueRef<AST::CallExpression>(WTFMove(*name), WTFMove(callName), WTFMove(arguments)) }; … … 2565 1964 default: { 2566 1965 ASSERT(type->type == Lexer::Token::Type::LeftParenthesis); 2567 auto expression = parseExpression(); 2568 if (!expression) 2569 return Unexpected<Error>(expression.error()); 2570 2571 auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis); 2572 if (!rightParenthesis) 2573 return Unexpected<Error>(rightParenthesis.error()); 1966 PARSE(expression, Expression); 1967 CONSUME_TYPE(rightParenthesis, RightParenthesis); 2574 1968 2575 1969 return { WTFMove(*expression) }; -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.h
r245897 r246052 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) … … 216 225 Expected<UniqueRef<AST::Expression>, Error> parseExpression(); 217 226 Expected<UniqueRef<AST::Expression>, Error> parseTernaryConditional(); 227 Expected<UniqueRef<AST::Expression>, Error> completeTernaryConditional(Lexer::Token&& origin, UniqueRef<AST::Expression>&& predicate); 218 228 Expected<UniqueRef<AST::Expression>, Error> parseAssignment(); 229 Expected<UniqueRef<AST::Expression>, Error> completeAssignment(Lexer::Token&& origin, UniqueRef<AST::Expression>&& left); 219 230 Expected<UniqueRef<AST::Expression>, Error> parsePossibleTernaryConditional(); 220 231 Expected<UniqueRef<AST::Expression>, Error> parsePossibleLogicalBinaryOperation(); 232 Expected<UniqueRef<AST::Expression>, Error> completePossibleLogicalBinaryOperation(UniqueRef<AST::Expression>&& previous); 221 233 Expected<UniqueRef<AST::Expression>, Error> parsePossibleRelationalBinaryOperation(); 234 Expected<UniqueRef<AST::Expression>, Error> completePossibleRelationalBinaryOperation(UniqueRef<AST::Expression>&& previous); 222 235 Expected<UniqueRef<AST::Expression>, Error> parsePossibleShift(); 236 Expected<UniqueRef<AST::Expression>, Error> completePossibleShift(UniqueRef<AST::Expression>&& previous); 223 237 Expected<UniqueRef<AST::Expression>, Error> parsePossibleAdd(); 238 Expected<UniqueRef<AST::Expression>, Error> completePossibleAdd(UniqueRef<AST::Expression>&& previous); 224 239 Expected<UniqueRef<AST::Expression>, Error> parsePossibleMultiply(); 225 Expected<UniqueRef<AST::Expression>, Error> parsePossiblePrefix(); 226 Expected<UniqueRef<AST::Expression>, Error> parsePossibleSuffix(); 240 Expected<UniqueRef<AST::Expression>, Error> completePossibleMultiply(UniqueRef<AST::Expression>&& previous); 241 Expected<UniqueRef<AST::Expression>, Error> parsePossiblePrefix(bool *isEffectful = nullptr); 242 Expected<UniqueRef<AST::Expression>, Error> parsePossibleSuffix(bool *isEffectful = nullptr); 227 243 Expected<UniqueRef<AST::Expression>, Error> parseCallExpression(); 228 244 Expected<UniqueRef<AST::Expression>, Error> parseTerm();
Note: See TracChangeset
for help on using the changeset viewer.