Changeset 246052 in webkit


Ignore:
Timestamp:
Jun 3, 2019 5:25:40 PM (5 years ago)
Author:
rmorisset@apple.com
Message:

[WHLSL] Parsing and lexing the standard library is slow
https://bugs.webkit.org/show_bug.cgi?id=192890
<rdar://problem/50746335>

Reviewed by Myles Maxfield.

The main idea is to avoid backtracking by instead peeking at the next token (and occasionally at the one after that).
This implies a few things:

  • 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).
  • We now have "completeFooExpression" functions, to avoid having to reparse the prefix of some expression, if we find half-way through what it is.

I also fixed the following parser bug:

which was due to a mistake I made in the grammar

Finally I added two new macros: CONSUME_TYPE and PARSE to eliminate about 500 lines of error propagation boilerplate.

There are still lots of ways of improving the parser and lexer, such as:

  • finishing the conversion of tokens in the lexer, not bothering with allocating string views
  • make two special tokens Invalid and EOF, to remove the overhead of Optional
  • make peekTypes and consumeTypes use templates to avoid constructing a Vector and calling find on it.
  • 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)
  • Remove the last few pieces of backtracking from the parser.

The current patch is already enough to make parsing the full standard library (something like 85k lines) approximately 260ms.
This is still longer than I would like, but nowhere near the bottleneck any longer because of some other parts of the compiler.

  • Modules/webgpu/WHLSL/WHLSLLexer.h:

(WebCore::WHLSL::Lexer::Lexer):
(WebCore::WHLSL::Lexer::consumeToken):
(WebCore::WHLSL::Lexer::peek):
(WebCore::WHLSL::Lexer::peekFurther):
(WebCore::WHLSL::Lexer::state const):
(WebCore::WHLSL::Lexer::setState):
(WebCore::WHLSL::Lexer::unconsumeToken): Deleted.

  • Modules/webgpu/WHLSL/WHLSLParser.cpp:

(WebCore::WHLSL::Parser::parse):
(WebCore::WHLSL::Parser::peek):
(WebCore::WHLSL::Parser::peekTypes):
(WebCore::WHLSL::Parser::tryType):
(WebCore::WHLSL::Parser::tryTypes):
(WebCore::WHLSL::Parser::consumeTypes):
(WebCore::WHLSL::Parser::parseConstantExpression):
(WebCore::WHLSL::Parser::parseTypeArgument):
(WebCore::WHLSL::Parser::parseTypeArguments):
(WebCore::WHLSL::Parser::parseTypeSuffixAbbreviated):
(WebCore::WHLSL::Parser::parseTypeSuffixNonAbbreviated):
(WebCore::WHLSL::Parser::parseType):
(WebCore::WHLSL::Parser::parseTypeDefinition):
(WebCore::WHLSL::Parser::parseResourceSemantic):
(WebCore::WHLSL::Parser::parseSpecializationConstantSemantic):
(WebCore::WHLSL::Parser::parseStageInOutSemantic):
(WebCore::WHLSL::Parser::parseSemantic):
(WebCore::WHLSL::Parser::parseQualifiers):
(WebCore::WHLSL::Parser::parseStructureElement):
(WebCore::WHLSL::Parser::parseStructureDefinition):
(WebCore::WHLSL::Parser::parseEnumerationDefinition):
(WebCore::WHLSL::Parser::parseEnumerationMember):
(WebCore::WHLSL::Parser::parseNativeTypeDeclaration):
(WebCore::WHLSL::Parser::parseNumThreadsFunctionAttribute):
(WebCore::WHLSL::Parser::parseAttributeBlock):
(WebCore::WHLSL::Parser::parseParameter):
(WebCore::WHLSL::Parser::parseParameters):
(WebCore::WHLSL::Parser::parseFunctionDefinition):
(WebCore::WHLSL::Parser::parseComputeFunctionDeclaration):
(WebCore::WHLSL::Parser::parseVertexFragmentFunctionDeclaration):
(WebCore::WHLSL::Parser::parseRegularFunctionDeclaration):
(WebCore::WHLSL::Parser::parseOperatorFunctionDeclaration):
(WebCore::WHLSL::Parser::parseFunctionDeclaration):
(WebCore::WHLSL::Parser::parseNativeFunctionDeclaration):
(WebCore::WHLSL::Parser::parseBlock):
(WebCore::WHLSL::Parser::parseBlockBody):
(WebCore::WHLSL::Parser::parseIfStatement):
(WebCore::WHLSL::Parser::parseSwitchStatement):
(WebCore::WHLSL::Parser::parseSwitchCase):
(WebCore::WHLSL::Parser::parseForLoop):
(WebCore::WHLSL::Parser::parseWhileLoop):
(WebCore::WHLSL::Parser::parseDoWhileLoop):
(WebCore::WHLSL::Parser::parseVariableDeclaration):
(WebCore::WHLSL::Parser::parseVariableDeclarations):
(WebCore::WHLSL::Parser::parseStatement):
(WebCore::WHLSL::Parser::parseEffectfulExpression):
(WebCore::WHLSL::Parser::parseEffectfulAssignment):
(WebCore::WHLSL::Parser::parseExpression):
(WebCore::WHLSL::Parser::parseTernaryConditional):
(WebCore::WHLSL::Parser::completeTernaryConditional):
(WebCore::WHLSL::Parser::parseAssignment):
(WebCore::WHLSL::Parser::completeAssignment):
(WebCore::WHLSL::Parser::parsePossibleTernaryConditional):
(WebCore::WHLSL::Parser::parsePossibleLogicalBinaryOperation):
(WebCore::WHLSL::Parser::completePossibleLogicalBinaryOperation):
(WebCore::WHLSL::Parser::parsePossibleRelationalBinaryOperation):
(WebCore::WHLSL::Parser::completePossibleRelationalBinaryOperation):
(WebCore::WHLSL::Parser::parsePossibleShift):
(WebCore::WHLSL::Parser::completePossibleShift):
(WebCore::WHLSL::Parser::parsePossibleAdd):
(WebCore::WHLSL::Parser::completePossibleAdd):
(WebCore::WHLSL::Parser::parsePossibleMultiply):
(WebCore::WHLSL::Parser::completePossibleMultiply):
(WebCore::WHLSL::Parser::parsePossiblePrefix):
(WebCore::WHLSL::Parser::parsePossibleSuffix):
(WebCore::WHLSL::Parser::parseCallExpression):
(WebCore::WHLSL::Parser::parseTerm):
(WebCore::WHLSL::Parser::parseAddressSpaceType): Deleted.
(WebCore::WHLSL::Parser::parseNonAddressSpaceType): Deleted.
(WebCore::WHLSL::Parser::parseEntryPointFunctionDeclaration): Deleted.
(WebCore::WHLSL::Parser::parseEffectfulPrefix): Deleted.
(WebCore::WHLSL::Parser::parseEffectfulSuffix): Deleted.

  • Modules/webgpu/WHLSL/WHLSLParser.h:

(WebCore::WHLSL::Parser::Error::dump const):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r246049 r246052  
     12019-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
    11142019-06-03  Youenn Fablet  <youenn@apple.com>
    2115
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.h

    r245897 r246052  
    4747    {
    4848        skipWhitespaceAndComments();
     49        m_ringBuffer[0] = consumeTokenFromStream();
     50        m_ringBuffer[1] = consumeTokenFromStream();
    4951    }
    5052
     
    178180    Optional<Token> consumeToken()
    179181    {
    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
    190200    struct State {
    191         Vector<Token> stack;
     201        Optional<Token> ringBuffer[2];
     202        unsigned ringBufferIndex;
    192203        unsigned offset;
    193204        unsigned lineNumber;
     
    196207    State state() const
    197208    {
    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;
    199216    }
    200217
    201218    void setState(const State& state)
    202219    {
    203         m_stack = state.stack;
     220        m_ringBuffer[0] = state.ringBuffer[0];
     221        m_ringBuffer[1] = state.ringBuffer[1];
     222        m_ringBufferIndex = state.ringBufferIndex;
    204223        m_offset = state.offset;
    205224        m_lineNumber = state.lineNumber;
     225
    206226    }
    207227
    208228    void setState(State&& state)
    209229    {
    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);
    211233        m_offset = WTFMove(state.offset);
    212234        m_lineNumber = WTFMove(state.lineNumber);
     
    254276
    255277    StringView m_stringView;
    256     Vector<Token> m_stack;
     278    Optional<Token> m_ringBuffer[2];
     279    unsigned m_ringBufferIndex { 0 };
    257280    unsigned m_offset { 0 };
    258281    unsigned m_lineNumber { 0 };
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp

    r245897 r246052  
    3939namespace WHLSL {
    4040
     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
    4161// FIXME: https://bugs.webkit.org/show_bug.cgi?id=195682 Return a better error code from this, and report it to JavaScript.
    4262auto Parser::parse(Program& program, StringView stringView, Mode mode) -> Optional<Error>
     
    4666
    4767    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:
    4973            m_lexer.consumeToken();
    5074            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));
    61106                continue;
    62107            }
    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
    129124    return WTF::nullopt;
    130125}
     
    141136auto Parser::peek() -> Expected<Lexer::Token, Error>
    142137{
    143     if (auto token = m_lexer.consumeToken()) {
    144         m_lexer.unconsumeToken(Lexer::Token(*token));
     138    if (auto token = m_lexer.peek()) {
    145139        return *token;
    146140    }
     
    148142}
    149143
     144auto 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
     152bool 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
    150159Optional<Lexer::Token> Parser::tryType(Lexer::Token::Type type)
    151160{
    152     if (auto token = m_lexer.consumeToken()) {
     161    if (auto token = m_lexer.peek()) {
    153162        if (token->type == type)
    154             return token;
    155         m_lexer.unconsumeToken(Lexer::Token(*token));
     163            return m_lexer.consumeToken();
    156164    }
    157165    return WTF::nullopt;
    158166}
    159167
    160 Optional<Lexer::Token> Parser::tryTypes(Vector<Lexer::Token::Type> types)
    161 {
    162     if (auto token = m_lexer.consumeToken()) {
     168Optional<Lexer::Token> Parser::tryTypes(const Vector<Lexer::Token::Type>& types)
     169{
     170    if (auto token = m_lexer.peek()) {
    163171        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();
    166173    }
    167174    return WTF::nullopt;
     
    178185}
    179186
    180 auto Parser::consumeTypes(Vector<Lexer::Token::Type> types) -> Expected<Lexer::Token, Error>
     187auto Parser::consumeTypes(const Vector<Lexer::Token::Type>& types) -> Expected<Lexer::Token, Error>
    181188{
    182189    auto buildExpectedString = [&]() -> String {
     
    368375    default: {
    369376        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);
    376379        return { AST::EnumerationMemberLiteral(WTFMove(*origin), type->stringView.toString(), next->stringView.toString()) };
    377380    }
     
    381384auto Parser::parseTypeArgument() -> Expected<AST::TypeArgument, Error>
    382385{
    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);
    387390        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);
    391393    return AST::TypeArgument(makeUniqueRef<AST::TypeReference>(Lexer::Token(*result), result->stringView.toString(), AST::TypeArguments()));
    392394}
     
    394396auto Parser::parseTypeArguments() -> Expected<AST::TypeArguments, Error>
    395397{
    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);
    404417        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;
    432421}
    433422
     
    441430        if (!numElements)
    442431            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);
    446433        return {{ *token, *numElements }};
    447434    }
     
    458445        if (!numElements)
    459446            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);
    463448        return {{ *token, WTF::nullopt, *numElements }};
    464449    }
     
    485470}
    486471
    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)) };
     472auto 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;
    521491        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));
    541510        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    }
    558525
    559526    auto constructTypeFromSuffixNonAbbreviated = [&](const TypeSuffixNonAbbreviated& typeSuffixNonAbbreviated, UniqueRef<AST::UnnamedType>&& previous) -> UniqueRef<AST::UnnamedType> {
     
    568535        }
    569536    };
    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));
    572538    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);
    578546        // FIXME: The nesting here might be in the wrong order.
    579547        auto next = constructTypeFromSuffixNonAbbreviated(*typeSuffixNonAbbreviated, WTFMove(result));
    580548        result = WTFMove(next);
    581549    }
    582 
    583550    return WTFMove(result);
    584551}
    585552
    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 
    605553auto Parser::parseTypeDefinition() -> Expected<AST::TypeDefinition, Error>
    606554{
    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);
    622560    return AST::TypeDefinition(WTFMove(*origin), name->stringView.toString(), WTFMove(*type));
    623561}
     
    682620auto Parser::parseResourceSemantic() -> Expected<AST::ResourceSemantic, Error>
    683621{
    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);
    695626    if (info->stringView.length() < 2 || (info->stringView[0] != 'u'
    696627        && info->stringView[0] != 't'
     
    721652    unsigned space = 0;
    722653    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);
    726655        auto prefix = "space"_str;
    727656        if (!spaceToken->stringView.startsWith(StringView(prefix)))
     
    735664    }
    736665
    737     auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis);
    738     if (!rightParenthesis)
    739         return Unexpected<Error>(rightParenthesis.error());
     666    CONSUME_TYPE(rightParenthesis, RightParenthesis);
    740667
    741668    return AST::ResourceSemantic(WTFMove(*origin), mode, *index, space);
     
    744671auto Parser::parseSpecializationConstantSemantic() -> Expected<AST::SpecializationConstantSemantic, Error>
    745672{
    746     auto origin = consumeType(Lexer::Token::Type::Specialized);
    747     if (!origin)
    748         return Unexpected<Error>(origin.error());
     673    CONSUME_TYPE(origin, Specialized);
    749674    return AST::SpecializationConstantSemantic(WTFMove(*origin));
    750675}
     
    752677auto Parser::parseStageInOutSemantic() -> Expected<AST::StageInOutSemantic, Error>
    753678{
    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);
    761681
    762682    auto index = consumeNonNegativeIntegralLiteral();
     
    764684        return Unexpected<Error>(index.error());
    765685
    766     auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis);
    767     if (!rightParenthesis)
    768         return Unexpected<Error>(rightParenthesis.error());
     686    CONSUME_TYPE(rightParenthesis, RightParenthesis);
    769687
    770688    return AST::StageInOutSemantic(WTFMove(*origin), *index);
    771689}
    772690
    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());
     691auto 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    }
    800715}
    801716AST::Qualifiers Parser::parseQualifiers()
    802717{
    803718    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        }
    820732    }
    821733    return qualifiers;
     
    824736auto Parser::parseStructureElement() -> Expected<AST::StructureElement, Error>
    825737{
    826     auto origin = peek();
    827     if (!origin)
    828         return Unexpected<Error>(origin.error());
     738    PEEK(origin);
    829739
    830740    AST::Qualifiers qualifiers = parseQualifiers();
    831741
    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));
    857748}
    858749
    859750auto Parser::parseStructureDefinition() -> Expected<AST::StructureDefinition, Error>
    860751{
    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);
    872755
    873756    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    }
    887761
    888762    return AST::StructureDefinition(WTFMove(*origin), name->stringView.toString(), WTFMove(structureElements));
     
    891765auto Parser::parseEnumerationDefinition() -> Expected<AST::EnumerationDefinition, Error>
    892766{
    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);
    900769
    901770    auto type = ([&]() -> Expected<UniqueRef<AST::UnnamedType>, Error> {
    902771        if (tryType(Lexer::Token::Type::Colon)) {
    903             auto parsedType = parseType();
    904             if (!parsedType)
    905                 return Unexpected<Error>(parsedType.error());
     772            PARSE(parsedType, Type);
    906773            return WTFMove(*parsedType);
    907774        }
     
    911778        return Unexpected<Error>(type.error());
    912779
    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);
    920783
    921784    AST::EnumerationDefinition result(WTFMove(*origin), name->stringView.toString(), WTFMove(*type));
     
    925788
    926789    while (tryType(Lexer::Token::Type::Comma)) {
    927         auto member = parseEnumerationMember();
    928         if (!member)
    929             return Unexpected<Error>(member.error());
     790        PARSE(member, EnumerationMember);
    930791        success = result.add(WTFMove(*member));
    931792        if (!success)
     
    933794    }
    934795
    935     auto rightCurlyBracket = consumeType(Lexer::Token::Type::RightCurlyBracket);
    936     if (!rightCurlyBracket)
    937         return Unexpected<Error>(rightCurlyBracket.error());
     796    CONSUME_TYPE(rightCurlyBracket, RightCurlyBracket);
    938797
    939798    return WTFMove(result);
     
    942801auto Parser::parseEnumerationMember() -> Expected<AST::EnumerationMember, Error>
    943802{
    944     auto identifier = consumeType(Lexer::Token::Type::Identifier);
    945     if (!identifier)
    946         return Unexpected<Error>(identifier.error());
     803    CONSUME_TYPE(identifier, Identifier);
    947804    auto name = identifier->stringView.toString();
    948805
    949806    if (tryType(Lexer::Token::Type::EqualsSign)) {
    950         auto constantExpression = parseConstantExpression();
    951         if (!constantExpression)
    952             return Unexpected<Error>(constantExpression.error());
     807        PARSE(constantExpression, ConstantExpression);
    953808        return AST::EnumerationMember(Lexer::Token(*identifier), WTFMove(name), WTFMove(*constantExpression));
    954809    }
     
    958813auto Parser::parseNativeTypeDeclaration() -> Expected<AST::NativeTypeDeclaration, Error>
    959814{
    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);
    979820
    980821    return AST::NativeTypeDeclaration(WTFMove(*origin), name->stringView.toString(), WTFMove(*typeArguments));
     
    983824auto Parser::parseNumThreadsFunctionAttribute() -> Expected<AST::NumThreadsFunctionAttribute, Error>
    984825{
    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);
    992828
    993829    auto width = consumeNonNegativeIntegralLiteral();
     
    995831        return Unexpected<Error>(width.error());
    996832
    997     auto comma = consumeType(Lexer::Token::Type::Comma);
    998     if (!comma)
    999         return Unexpected<Error>(comma.error());
     833    CONSUME_TYPE(comma, Comma);
    1000834
    1001835    auto height = consumeNonNegativeIntegralLiteral();
     
    1003837        return Unexpected<Error>(height.error());
    1004838
    1005     comma = consumeType(Lexer::Token::Type::Comma);
    1006     if (!comma)
    1007         return Unexpected<Error>(comma.error());
     839    CONSUME_TYPE(secondComma, Comma);
    1008840
    1009841    auto depth = consumeNonNegativeIntegralLiteral();
     
    1011843        return Unexpected<Error>(depth.error());
    1012844
    1013     auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis);
    1014     if (!rightParenthesis)
    1015         return Unexpected<Error>(rightParenthesis.error());
     845    CONSUME_TYPE(rightParenthesis, RightParenthesis);
    1016846
    1017847    return AST::NumThreadsFunctionAttribute(WTFMove(*origin), *width, *height, *depth);
     
    1020850auto Parser::parseAttributeBlock() -> Expected<AST::AttributeBlock, Error>
    1021851{
    1022     auto leftSquareBracket = consumeType(Lexer::Token::Type::LeftSquareBracket);
    1023     if (!leftSquareBracket)
    1024         return Unexpected<Error>(leftSquareBracket.error());
     852    CONSUME_TYPE(leftSquareBracket, LeftSquareBracket);
    1025853
    1026854    AST::AttributeBlock result;
     
    1038866    }
    1039867
    1040     auto rightSquareBracket = consumeType(Lexer::Token::Type::RightSquareBracket);
    1041     if (!rightSquareBracket)
    1042         return Unexpected<Error>(rightSquareBracket.error());
     868    CONSUME_TYPE(rightSquareBracket, RightSquareBracket);
    1043869
    1044870    return WTFMove(result);
     
    1047873auto Parser::parseParameter() -> Expected<AST::VariableDeclaration, Error>
    1048874{
    1049     auto origin = peek();
    1050     if (!origin)
    1051         return Unexpected<Error>(origin.error());
     875    PEEK(origin);
    1052876
    1053877    AST::Qualifiers qualifiers = parseQualifiers();
    1054878
    1055     auto type = parseType();
    1056     if (!type)
    1057         return Unexpected<Error>(type.error());
     879    PARSE(type, Type);
    1058880
    1059881    String name;
     
    1061883        name = token->stringView.toString();
    1062884
    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);
    1071888}
    1072889
    1073890auto Parser::parseParameters() -> Expected<AST::VariableDeclarations, Error>
    1074891{
    1075     auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis);
    1076     if (!leftParenthesis)
    1077         return Unexpected<Error>(leftParenthesis.error());
    1078 
    1079892    AST::VariableDeclarations parameters;
     893
     894    CONSUME_TYPE(leftParenthesis, LeftParenthesis);
     895
    1080896    if (tryType(Lexer::Token::Type::RightParenthesis))
    1081897        return WTFMove(parameters);
    1082898
    1083     auto firstParameter = parseParameter();
    1084     if (!firstParameter)
    1085         return Unexpected<Error>(firstParameter.error());
     899    PARSE(firstParameter, Parameter);
    1086900    parameters.append(makeUniqueRef<AST::VariableDeclaration>(WTFMove(*firstParameter)));
    1087901
    1088902    while (tryType(Lexer::Token::Type::Comma)) {
    1089         auto parameter = parseParameter();
    1090         if (!parameter)
    1091             return Unexpected<Error>(parameter.error());
     903        PARSE(parameter, Parameter);
    1092904        parameters.append(makeUniqueRef<AST::VariableDeclaration>(WTFMove(*parameter)));
    1093905    }
    1094906
    1095     auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis);
    1096     if (!rightParenthesis)
    1097         return Unexpected<Error>(rightParenthesis.error());
     907    CONSUME_TYPE(rightParenthesis, RightParenthesis);
    1098908
    1099909    return WTFMove(parameters);
     
    1102912auto Parser::parseFunctionDefinition() -> Expected<AST::FunctionDefinition, Error>
    1103913{
    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);
    1112916    return AST::FunctionDefinition(WTFMove(*functionDeclaration), WTFMove(*block));
    1113917}
    1114918
    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 
     919auto 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);
    1161929    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
     933auto 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);
    1171947}
    1172948
    1173949auto Parser::parseRegularFunctionDeclaration() -> Expected<AST::FunctionDeclaration, Error>
    1174950{
    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);
    1182954
    1183955    auto name = consumeTypes({ Lexer::Token::Type::Identifier, Lexer::Token::Type::OperatorName });
     
    1186958    auto isOperator = name->type == Lexer::Token::Type::OperatorName;
    1187959
    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);
    1200964}
    1201965
    1202966auto Parser::parseOperatorFunctionDeclaration() -> Expected<AST::FunctionDeclaration, Error>
    1203967{
    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);
    1215972
    1216973    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);
    1226975}
    1227976
    1228977auto Parser::parseFunctionDeclaration() -> Expected<AST::FunctionDeclaration, Error>
    1229978{
    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:
    1237989        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    }
    1249991}
    1250992
    1251993auto Parser::parseNativeFunctionDeclaration() -> Expected<AST::NativeFunctionDeclaration, Error>
    1252994{
    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);
    1268998
    1269999    return AST::NativeFunctionDeclaration(WTFMove(*functionDeclaration));
     
    12721002auto Parser::parseBlock() -> Expected<AST::Block, Error>
    12731003{
    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
     1010auto Parser::parseBlockBody(Lexer::Token&& origin) -> Expected<AST::Block, Error>
    12881011{
    12891012    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));
    12981016    }
    12991017    return AST::Block(WTFMove(origin), WTFMove(statements));
     
    13021020auto Parser::parseIfStatement() -> Expected<AST::IfStatement, Error>
    13031021{
    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);
    13231027
    13241028    Optional<UniqueRef<AST::Statement>> elseBody;
    13251029    if (tryType(Lexer::Token::Type::Else)) {
    1326         auto parsedElseBody = parseStatement();
    1327         if (!parsedElseBody)
    1328             return Unexpected<Error>(parsedElseBody.error());
     1030        PARSE(parsedElseBody, Statement);
    13291031        elseBody = WTFMove(*parsedElseBody);
    13301032    }
     
    13381040auto Parser::parseSwitchStatement() -> Expected<AST::SwitchStatement, Error>
    13391041{
    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);
    13591047
    13601048    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();
    13741056
    13751057    return AST::SwitchStatement(WTFMove(*origin), WTFMove(*value), WTFMove(switchCases));
     
    13841066    switch (origin->type) {
    13851067    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));
    13971074    }
    13981075    default: {
    13991076        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));
    14071082    }
    14081083    }
     
    14111086auto Parser::parseForLoop() -> Expected<AST::ForLoop, Error>
    14121087{
    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);
    14161090
    14171091    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)) {
    14231096            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)) {
    14331105            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);
    14451113
    14461114        return AST::ForLoop(WTFMove(*origin), WTFMove(initialization), WTFMove(condition), WTFMove(increment), WTFMove(*body));
    14471115    };
    1448 
    1449     auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis);
    1450     if (!leftParenthesis)
    1451         return Unexpected<Error>(leftParenthesis.error());
    14521116
    14531117    auto variableDeclarations = backtrackingScope<Expected<AST::VariableDeclarationsStatement, Error>>([&]() {
     
    14571121        return parseRemainder(WTFMove(*variableDeclarations));
    14581122
    1459     auto effectfulExpression = parseEffectfulExpression();
    1460     if (!effectfulExpression)
    1461         return Unexpected<Error>(effectfulExpression.error());
     1123    PARSE(effectfulExpression, EffectfulExpression);
    14621124
    14631125    return parseRemainder(WTFMove(*effectfulExpression));
     
    14661128auto Parser::parseWhileLoop() -> Expected<AST::WhileLoop, Error>
    14671129{
    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);
    14871135
    14881136    return AST::WhileLoop(WTFMove(*origin), WTFMove(*conditional), WTFMove(*body));
     
    14911139auto Parser::parseDoWhileLoop() -> Expected<AST::DoWhileLoop, Error>
    14921140{
    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);
    15161148
    15171149    return AST::DoWhileLoop(WTFMove(*origin), WTFMove(*body), WTFMove(*conditional));
     
    15201152auto Parser::parseVariableDeclaration(UniqueRef<AST::UnnamedType>&& type) -> Expected<AST::VariableDeclaration, Error>
    15211153{
    1522     auto origin = peek();
    1523     if (!origin)
    1524         return Unexpected<Error>(origin.error());
     1154    PEEK(origin);
    15251155
    15261156    auto qualifiers = parseQualifiers();
    15271157
    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);
    15461160
    15471161    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);
    15551167}
    15561168
    15571169auto Parser::parseVariableDeclarations() -> Expected<AST::VariableDeclarationsStatement, Error>
    15581170{
    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);
    15661174
    15671175    auto firstVariableDeclaration = parseVariableDeclaration((*type)->clone());
     
    15841192auto Parser::parseStatement() -> Expected<UniqueRef<AST::Statement>, Error>
    15851193{
     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
    15861283    {
    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);
    16361287            return result;
    16371288        });
    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)) };
    17601296}
    17611297
    17621298auto Parser::parseEffectfulExpression() -> Expected<UniqueRef<AST::Expression>, Error>
    17631299{
    1764     auto origin = peek();
    1765     if (!origin)
    1766         return Unexpected<Error>(origin.error());
     1300    PEEK(origin);
    17671301
    17681302    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)
    17771304        return { makeUniqueRef<AST::CommaExpression>(WTFMove(*origin), WTFMove(expressions)) };
    17781305
    1779     expressions.append(WTFMove(*first));
     1306    PARSE(effectfulExpression, EffectfulAssignment);
     1307    expressions.append(WTFMove(*effectfulExpression));
    17801308
    17811309    while (tryType(Lexer::Token::Type::Comma)) {
    1782         auto expression = parseEffectfulAssignment();
    1783         if (!expression)
    1784             return Unexpected<Error>(expression.error());
     1310        PARSE(expression, EffectfulAssignment);
    17851311        expressions.append(WTFMove(*expression));
    17861312    }
     
    17931319auto Parser::parseEffectfulAssignment() -> Expected<UniqueRef<AST::Expression>, Error>
    17941320{
    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;
    19001343}
    19011344
     
    19801423auto Parser::parseExpression() -> Expected<UniqueRef<AST::Expression>, Error>
    19811424{
    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);
    19901428    Vector<UniqueRef<AST::Expression>> expressions;
    19911429    expressions.append(WTFMove(*first));
    19921430
    19931431    while (tryType(Lexer::Token::Type::Comma)) {
    1994         auto expression = parsePossibleTernaryConditional();
    1995         if (!expression)
    1996             return Unexpected<Error>(expression.error());
     1432        PARSE(expression, PossibleTernaryConditional);
    19971433        expressions.append(WTFMove(*expression));
    19981434    }
     
    20051441auto Parser::parseTernaryConditional() -> Expected<UniqueRef<AST::Expression>, Error>
    20061442{
    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
     1450auto 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);
    20301456
    20311457    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)) };
    20351461}
    20361462
    20371463auto Parser::parseAssignment() -> Expected<UniqueRef<AST::Expression>, Error>
    20381464{
    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
     1472auto Parser::completeAssignment(Lexer::Token&& origin, UniqueRef<AST::Expression>&& left) -> Expected<UniqueRef<AST::Expression>, Error>
     1473{
    20471474    auto assignmentOperator = consumeTypes({
    20481475        Lexer::Token::Type::EqualsSign,
     
    20611488        return Unexpected<Error>(assignmentOperator.error());
    20621489
    2063     auto right = parsePossibleTernaryConditional();
    2064     if (!right)
    2065         return Unexpected<Error>(right.error());
     1490    PARSE(right, PossibleTernaryConditional);
    20661491
    20671492    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))};
    20691494
    20701495    String name;
     
    21031528    }
    21041529
    2105     auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*origin), WTFMove(*left));
     1530    auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(origin), WTFMove(left));
    21061531    Vector<UniqueRef<AST::Expression>> callArguments;
    21071532    callArguments.append(result->oldVariableReference());
    21081533    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)));
    21101535    result->setResultExpression(result->newVariableReference());
    21111536    return { WTFMove(result) };
     
    21141539auto Parser::parsePossibleTernaryConditional() -> Expected<UniqueRef<AST::Expression>, Error>
    21151540{
    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;
    21351569}
    21361570
    21371571auto Parser::parsePossibleLogicalBinaryOperation() -> Expected<UniqueRef<AST::Expression>, Error>
    21381572{
    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
     1577auto Parser::completePossibleLogicalBinaryOperation(UniqueRef<AST::Expression>&& previous) -> Expected<UniqueRef<AST::Expression>, Error>
     1578{
    21441579    while (auto logicalBinaryOperation = tryTypes({
    21451580        Lexer::Token::Type::OrOr,
     
    21491584        Lexer::Token::Type::And
    21501585        })) {
    2151         auto next = parsePossibleRelationalBinaryOperation();
    2152         if (!next)
    2153             return Unexpected<Error>(next.error());
     1586        PARSE(next, PossibleRelationalBinaryOperation);
    21541587
    21551588        switch (logicalBinaryOperation->type) {
     
    21901623auto Parser::parsePossibleRelationalBinaryOperation() -> Expected<UniqueRef<AST::Expression>, Error>
    21911624{
    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
     1629auto Parser::completePossibleRelationalBinaryOperation(UniqueRef<AST::Expression>&& previous) -> Expected<UniqueRef<AST::Expression>, Error>
     1630{
    21971631    while (auto relationalBinaryOperation = tryTypes({
    21981632        Lexer::Token::Type::LessThanSign,
     
    22031637        Lexer::Token::Type::NotEqual
    22041638        })) {
    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));
    22081644
    22091645        switch (relationalBinaryOperation->type) {
    22101646        case Lexer::Token::Type::LessThanSign: {
    2211             Vector<UniqueRef<AST::Expression>> callArguments;
    2212             callArguments.append(WTFMove(previous));
    2213             callArguments.append(WTFMove(*next));
    22141647            previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), "operator<"_str, WTFMove(callArguments));
    22151648            break;
    22161649        }
    22171650        case Lexer::Token::Type::GreaterThanSign: {
    2218             Vector<UniqueRef<AST::Expression>> callArguments;
    2219             callArguments.append(WTFMove(previous));
    2220             callArguments.append(WTFMove(*next));
    22211651            previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), "operator>"_str, WTFMove(callArguments));
    22221652            break;
    22231653        }
    22241654        case Lexer::Token::Type::LessThanOrEqualTo: {
    2225             Vector<UniqueRef<AST::Expression>> callArguments;
    2226             callArguments.append(WTFMove(previous));
    2227             callArguments.append(WTFMove(*next));
    22281655            previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), "operator<="_str, WTFMove(callArguments));
    22291656            break;
    22301657        }
    22311658        case Lexer::Token::Type::GreaterThanOrEqualTo: {
    2232             Vector<UniqueRef<AST::Expression>> callArguments;
    2233             callArguments.append(WTFMove(previous));
    2234             callArguments.append(WTFMove(*next));
    22351659            previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), "operator>="_str, WTFMove(callArguments));
    22361660            break;
    22371661        }
    22381662        case Lexer::Token::Type::EqualComparison: {
    2239             Vector<UniqueRef<AST::Expression>> callArguments;
    2240             callArguments.append(WTFMove(previous));
    2241             callArguments.append(WTFMove(*next));
    22421663            previous = makeUniqueRef<AST::CallExpression>(WTFMove(*relationalBinaryOperation), "operator=="_str, WTFMove(callArguments));
    22431664            break;
     
    22451666        default: {
    22461667            ASSERT(relationalBinaryOperation->type == Lexer::Token::Type::NotEqual);
    2247             Vector<UniqueRef<AST::Expression>> callArguments;
    2248             callArguments.append(WTFMove(previous));
    2249             callArguments.append(WTFMove(*next));
    22501668            previous = makeUniqueRef<AST::CallExpression>(Lexer::Token(*relationalBinaryOperation), "operator=="_str, WTFMove(callArguments));
    22511669            previous = makeUniqueRef<AST::LogicalNotExpression>(WTFMove(*relationalBinaryOperation), WTFMove(previous));
     
    22601678auto Parser::parsePossibleShift() -> Expected<UniqueRef<AST::Expression>, Error>
    22611679{
    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
     1684auto Parser::completePossibleShift(UniqueRef<AST::Expression>&& previous) -> Expected<UniqueRef<AST::Expression>, Error>
     1685{
    22671686    while (auto shift = tryTypes({
    22681687        Lexer::Token::Type::LeftShift,
    22691688        Lexer::Token::Type::RightShift
    22701689        })) {
    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));
    22741695
    22751696        switch (shift->type) {
    22761697        case Lexer::Token::Type::LeftShift: {
    2277             Vector<UniqueRef<AST::Expression>> callArguments;
    2278             callArguments.append(WTFMove(previous));
    2279             callArguments.append(WTFMove(*next));
    22801698            previous = makeUniqueRef<AST::CallExpression>(WTFMove(*shift), "operator<<"_str, WTFMove(callArguments));
    22811699            break;
     
    22831701        default: {
    22841702            ASSERT(shift->type == Lexer::Token::Type::RightShift);
    2285             Vector<UniqueRef<AST::Expression>> callArguments;
    2286             callArguments.append(WTFMove(previous));
    2287             callArguments.append(WTFMove(*next));
    22881703            previous = makeUniqueRef<AST::CallExpression>(WTFMove(*shift), "operator>>"_str, WTFMove(callArguments));
    22891704            break;
     
    22971712auto Parser::parsePossibleAdd() -> Expected<UniqueRef<AST::Expression>, Error>
    22981713{
    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
     1718auto Parser::completePossibleAdd(UniqueRef<AST::Expression>&& previous) -> Expected<UniqueRef<AST::Expression>, Error>
     1719{
    23041720    while (auto add = tryTypes({
    23051721        Lexer::Token::Type::Plus,
    23061722        Lexer::Token::Type::Minus
    23071723        })) {
    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));
    23111729
    23121730        switch (add->type) {
    23131731        case Lexer::Token::Type::Plus: {
    2314             Vector<UniqueRef<AST::Expression>> callArguments;
    2315             callArguments.append(WTFMove(previous));
    2316             callArguments.append(WTFMove(*next));
    23171732            previous = makeUniqueRef<AST::CallExpression>(WTFMove(*add), "operator+"_str, WTFMove(callArguments));
    23181733            break;
     
    23201735        default: {
    23211736            ASSERT(add->type == Lexer::Token::Type::Minus);
    2322             Vector<UniqueRef<AST::Expression>> callArguments;
    2323             callArguments.append(WTFMove(previous));
    2324             callArguments.append(WTFMove(*next));
    23251737            previous = makeUniqueRef<AST::CallExpression>(WTFMove(*add), "operator-"_str, WTFMove(callArguments));
    23261738            break;
     
    23341746auto Parser::parsePossibleMultiply() -> Expected<UniqueRef<AST::Expression>, Error>
    23351747{
    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
     1752auto Parser::completePossibleMultiply(UniqueRef<AST::Expression>&& previous) -> Expected<UniqueRef<AST::Expression>, Error>
     1753{
    23411754    while (auto multiply = tryTypes({
    23421755        Lexer::Token::Type::Star,
     
    23441757        Lexer::Token::Type::Mod
    23451758        })) {
    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));
    23491764
    23501765        switch (multiply->type) {
    23511766        case Lexer::Token::Type::Star: {
    2352             Vector<UniqueRef<AST::Expression>> callArguments;
    2353             callArguments.append(WTFMove(previous));
    2354             callArguments.append(WTFMove(*next));
    23551767            previous = makeUniqueRef<AST::CallExpression>(WTFMove(*multiply), "operator*"_str, WTFMove(callArguments));
    23561768            break;
    23571769        }
    23581770        case Lexer::Token::Type::Divide: {
    2359             Vector<UniqueRef<AST::Expression>> callArguments;
    2360             callArguments.append(WTFMove(previous));
    2361             callArguments.append(WTFMove(*next));
    23621771            previous = makeUniqueRef<AST::CallExpression>(WTFMove(*multiply), "operator/"_str, WTFMove(callArguments));
    23631772            break;
     
    23651774        default: {
    23661775            ASSERT(multiply->type == Lexer::Token::Type::Mod);
    2367             Vector<UniqueRef<AST::Expression>> callArguments;
    2368             callArguments.append(WTFMove(previous));
    2369             callArguments.append(WTFMove(*next));
    23701776            previous = makeUniqueRef<AST::CallExpression>(WTFMove(*multiply), "operator%"_str, WTFMove(callArguments));
    23711777            break;
     
    23771783}
    23781784
    2379 auto Parser::parsePossiblePrefix() -> Expected<UniqueRef<AST::Expression>, Error>
     1785auto Parser::parsePossiblePrefix(bool *isEffectful) -> Expected<UniqueRef<AST::Expression>, Error>
    23801786{
    23811787    if (auto prefix = tryTypes({
     
    23901796        Lexer::Token::Type::Star
    23911797    })) {
    2392         auto next = parsePossiblePrefix();
    2393         if (!next)
    2394             return Unexpected<Error>(next.error());
     1798        PARSE(next, PossiblePrefix);
    23951799
    23961800        switch (prefix->type) {
    23971801        case Lexer::Token::Type::PlusPlus: {
     1802            if (isEffectful)
     1803                *isEffectful = true;
    23981804            auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*prefix), WTFMove(*next));
    23991805            Vector<UniqueRef<AST::Expression>> callArguments;
     
    24041810        }
    24051811        case Lexer::Token::Type::MinusMinus: {
     1812            if (isEffectful)
     1813                *isEffectful = true;
    24061814            auto result = AST::ReadModifyWriteExpression::create(Lexer::Token(*prefix), WTFMove(*next));
    24071815            Vector<UniqueRef<AST::Expression>> callArguments;
     
    24421850    }
    24431851
    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
     1855auto 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;
    24541864        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));
    24581869            expression = WTFMove(result.result);
    2459             if (!result)
    2460                 break;
    24611870        }
    24621871        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;
    24861895}
    24871896
    24881897auto Parser::parseCallExpression() -> Expected<UniqueRef<AST::Expression>, Error>
    24891898{
    2490     auto name = consumeType(Lexer::Token::Type::Identifier);
    2491     if (!name)
    2492         return Unexpected<Error>(name.error());
     1899    CONSUME_TYPE(name, Identifier);
    24931900    auto callName = name->stringView.toString();
    24941901
    2495     auto leftParenthesis = consumeType(Lexer::Token::Type::LeftParenthesis);
    2496     if (!leftParenthesis)
    2497         return Unexpected<Error>(leftParenthesis.error());
     1902    CONSUME_TYPE(leftParenthesis, LeftParenthesis);
    24981903
    24991904    Vector<UniqueRef<AST::Expression>> arguments;
     
    25011906        return { makeUniqueRef<AST::CallExpression>(WTFMove(*name), WTFMove(callName), WTFMove(arguments)) };
    25021907
    2503     auto firstArgument = parsePossibleTernaryConditional();
    2504     if (!firstArgument)
    2505         return Unexpected<Error>(firstArgument.error());
     1908    PARSE(firstArgument, PossibleTernaryConditional);
    25061909    arguments.append(WTFMove(*firstArgument));
    25071910    while (tryType(Lexer::Token::Type::Comma)) {
    2508         auto argument = parsePossibleTernaryConditional();
    2509         if (!argument)
    2510             return Unexpected<Error>(argument.error());
     1911        PARSE(argument, PossibleTernaryConditional);
    25111912        arguments.append(WTFMove(*argument));
    25121913    }
    25131914
    2514     auto rightParenthesis = consumeType(Lexer::Token::Type::RightParenthesis);
    2515     if (!rightParenthesis)
    2516         return Unexpected<Error>(rightParenthesis.error());
     1915    CONSUME_TYPE(rightParenthesis, RightParenthesis);
    25171916
    25181917    return { makeUniqueRef<AST::CallExpression>(WTFMove(*name), WTFMove(callName), WTFMove(arguments)) };
     
    25651964    default: {
    25661965        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);
    25741968
    25751969        return { WTFMove(*expression) };
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.h

    r245897 r246052  
    9797#include <wtf/Expected.h>
    9898#include <wtf/Optional.h>
     99#include <wtf/PrintStream.h>
    99100
    100101namespace WebCore {
     
    116117
    117118        String error;
     119
     120        void dump(PrintStream& out) const
     121        {
     122            out.print(error);
     123        }
    118124    };
    119125
     
    121127
    122128private:
     129    // FIXME: We should not need this
     130    // https://bugs.webkit.org/show_bug.cgi?id=198357
    123131    template<typename T> T backtrackingScope(std::function<T()> callback)
    124132    {
     
    137145    Unexpected<Error> fail(const String& message, TryToPeek = TryToPeek::Yes);
    138146    Expected<Lexer::Token, Error> peek();
     147    Expected<Lexer::Token, Error> peekFurther();
     148    bool peekTypes(const Vector<Lexer::Token::Type>&);
    139149    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>&);
    141151    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>&);
    143153
    144154    Expected<Variant<int, unsigned>, Error> consumeIntegralLiteral();
     
    166176    Expected<AST::SpecializationConstantSemantic, Error> parseSpecializationConstantSemantic();
    167177    Expected<AST::StageInOutSemantic, Error> parseStageInOutSemantic();
    168     Expected<AST::Semantic, Error> parseSemantic();
     178    Expected<Optional<AST::Semantic>, Error> parseSemantic();
    169179    AST::Qualifiers parseQualifiers();
    170180    Expected<AST::StructureElement, Error> parseStructureElement();
     
    177187    Expected<AST::VariableDeclaration, Error> parseParameter();
    178188    Expected<AST::VariableDeclarations, Error> parseParameters();
    179     Expected<AST::FunctionDeclaration, Error> parseEntryPointFunctionDeclaration();
     189    Expected<AST::FunctionDeclaration, Error> parseComputeFunctionDeclaration();
     190    Expected<AST::FunctionDeclaration, Error> parseVertexOrFragmentFunctionDeclaration();
    180191    Expected<AST::FunctionDeclaration, Error> parseRegularFunctionDeclaration();
    181192    Expected<AST::FunctionDeclaration, Error> parseOperatorFunctionDeclaration();
     
    185196
    186197    Expected<AST::Block, Error> parseBlock();
    187     AST::Block parseBlockBody(Lexer::Token&& origin);
     198    Expected<AST::Block, Error> parseBlockBody(Lexer::Token&& origin);
    188199    Expected<AST::IfStatement, Error> parseIfStatement();
    189200    Expected<AST::SwitchStatement, Error> parseSwitchStatement();
     
    198209    Expected<UniqueRef<AST::Expression>, Error> parseEffectfulExpression();
    199210    Expected<UniqueRef<AST::Expression>, Error> parseEffectfulAssignment();
    200     Expected<UniqueRef<AST::Expression>, Error> parseEffectfulPrefix();
    201     Expected<UniqueRef<AST::Expression>, Error> parseEffectfulSuffix();
    202211    struct SuffixExpression {
    203212        SuffixExpression(UniqueRef<AST::Expression>&& result, bool success)
     
    216225    Expected<UniqueRef<AST::Expression>, Error> parseExpression();
    217226    Expected<UniqueRef<AST::Expression>, Error> parseTernaryConditional();
     227    Expected<UniqueRef<AST::Expression>, Error> completeTernaryConditional(Lexer::Token&& origin, UniqueRef<AST::Expression>&& predicate);
    218228    Expected<UniqueRef<AST::Expression>, Error> parseAssignment();
     229    Expected<UniqueRef<AST::Expression>, Error> completeAssignment(Lexer::Token&& origin, UniqueRef<AST::Expression>&& left);
    219230    Expected<UniqueRef<AST::Expression>, Error> parsePossibleTernaryConditional();
    220231    Expected<UniqueRef<AST::Expression>, Error> parsePossibleLogicalBinaryOperation();
     232    Expected<UniqueRef<AST::Expression>, Error> completePossibleLogicalBinaryOperation(UniqueRef<AST::Expression>&& previous);
    221233    Expected<UniqueRef<AST::Expression>, Error> parsePossibleRelationalBinaryOperation();
     234    Expected<UniqueRef<AST::Expression>, Error> completePossibleRelationalBinaryOperation(UniqueRef<AST::Expression>&& previous);
    222235    Expected<UniqueRef<AST::Expression>, Error> parsePossibleShift();
     236    Expected<UniqueRef<AST::Expression>, Error> completePossibleShift(UniqueRef<AST::Expression>&& previous);
    223237    Expected<UniqueRef<AST::Expression>, Error> parsePossibleAdd();
     238    Expected<UniqueRef<AST::Expression>, Error> completePossibleAdd(UniqueRef<AST::Expression>&& previous);
    224239    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);
    227243    Expected<UniqueRef<AST::Expression>, Error> parseCallExpression();
    228244    Expected<UniqueRef<AST::Expression>, Error> parseTerm();
Note: See TracChangeset for help on using the changeset viewer.