| 1 | /* |
| 2 | * Copyright (C) 2019 Apple Inc. All rights reserved. |
| 3 | * |
| 4 | * Redistribution and use in source and binary forms, with or without |
| 5 | * modification, are permitted provided that the following conditions |
| 6 | * are met: |
| 7 | * 1. Redistributions of source code must retain the above copyright |
| 8 | * notice, this list of conditions and the following disclaimer. |
| 9 | * 2. Redistributions in binary form must reproduce the above copyright |
| 10 | * notice, this list of conditions and the following disclaimer in the |
| 11 | * documentation and/or other materials provided with the distribution. |
| 12 | * |
| 13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
| 14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| 15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
| 17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| 23 | * THE POSSIBILITY OF SUCH DAMAGE. |
| 24 | */ |
| 25 | |
| 26 | #pragma once |
| 27 | |
| 28 | #if ENABLE(WEBGPU) |
| 29 | |
| 30 | #include "WHLSLArrayReferenceType.h" |
| 31 | #include "WHLSLArrayType.h" |
| 32 | #include "WHLSLAssignmentExpression.h" |
| 33 | #include "WHLSLBaseFunctionAttribute.h" |
| 34 | #include "WHLSLBaseSemantic.h" |
| 35 | #include "WHLSLBlock.h" |
| 36 | #include "WHLSLBooleanLiteral.h" |
| 37 | #include "WHLSLBreak.h" |
| 38 | #include "WHLSLBuiltInSemantic.h" |
| 39 | #include "WHLSLCallExpression.h" |
| 40 | #include "WHLSLCommaExpression.h" |
| 41 | #include "WHLSLConstantExpression.h" |
| 42 | #include "WHLSLContinue.h" |
| 43 | #include "WHLSLDereferenceExpression.h" |
| 44 | #include "WHLSLDoWhileLoop.h" |
| 45 | #include "WHLSLDotExpression.h" |
| 46 | #include "WHLSLEffectfulExpressionStatement.h" |
| 47 | #include "WHLSLEnumerationDefinition.h" |
| 48 | #include "WHLSLEnumerationMember.h" |
| 49 | #include "WHLSLExpression.h" |
| 50 | #include "WHLSLFallthrough.h" |
| 51 | #include "WHLSLFloatLiteral.h" |
| 52 | #include "WHLSLForLoop.h" |
| 53 | #include "WHLSLFunctionAttribute.h" |
| 54 | #include "WHLSLFunctionDeclaration.h" |
| 55 | #include "WHLSLFunctionDefinition.h" |
| 56 | #include "WHLSLIfStatement.h" |
| 57 | #include "WHLSLIndexExpression.h" |
| 58 | #include "WHLSLIntegerLiteral.h" |
| 59 | #include "WHLSLLexer.h" |
| 60 | #include "WHLSLLogicalExpression.h" |
| 61 | #include "WHLSLLogicalNotExpression.h" |
| 62 | #include "WHLSLMakeArrayReferenceExpression.h" |
| 63 | #include "WHLSLMakePointerExpression.h" |
| 64 | #include "WHLSLNativeFunctionDeclaration.h" |
| 65 | #include "WHLSLNativeTypeDeclaration.h" |
| 66 | #include "WHLSLNode.h" |
| 67 | #include "WHLSLNullLiteral.h" |
| 68 | #include "WHLSLNumThreadsFunctionAttribute.h" |
| 69 | #include "WHLSLPointerType.h" |
| 70 | #include "WHLSLProgram.h" |
| 71 | #include "WHLSLPropertyAccessExpression.h" |
| 72 | #include "WHLSLQualifier.h" |
| 73 | #include "WHLSLReadModifyWriteExpression.h" |
| 74 | #include "WHLSLReferenceType.h" |
| 75 | #include "WHLSLResourceSemantic.h" |
| 76 | #include "WHLSLReturn.h" |
| 77 | #include "WHLSLSemantic.h" |
| 78 | #include "WHLSLSpecializationConstantSemantic.h" |
| 79 | #include "WHLSLStageInOutSemantic.h" |
| 80 | #include "WHLSLStatement.h" |
| 81 | #include "WHLSLStructureDefinition.h" |
| 82 | #include "WHLSLStructureElement.h" |
| 83 | #include "WHLSLSwitchCase.h" |
| 84 | #include "WHLSLSwitchStatement.h" |
| 85 | #include "WHLSLTernaryExpression.h" |
| 86 | #include "WHLSLTrap.h" |
| 87 | #include "WHLSLType.h" |
| 88 | #include "WHLSLTypeArgument.h" |
| 89 | #include "WHLSLTypeDefinition.h" |
| 90 | #include "WHLSLTypeReference.h" |
| 91 | #include "WHLSLUnsignedIntegerLiteral.h" |
| 92 | #include "WHLSLValue.h" |
| 93 | #include "WHLSLVariableDeclaration.h" |
| 94 | #include "WHLSLVariableDeclarationsStatement.h" |
| 95 | #include "WHLSLVariableReference.h" |
| 96 | #include "WHLSLWhileLoop.h" |
| 97 | #include <wtf/Expected.h> |
| 98 | #include <wtf/Optional.h> |
| 99 | |
| 100 | namespace WebCore { |
| 101 | |
| 102 | namespace WHLSL { |
| 103 | |
| 104 | class Parser { |
| 105 | public: |
| 106 | enum class Mode { |
| 107 | StandardLibrary, |
| 108 | User |
| 109 | }; |
| 110 | |
| 111 | struct Error { |
| 112 | Error(String&& error) |
| 113 | : error(WTFMove(error)) |
| 114 | { |
| 115 | } |
| 116 | |
| 117 | String error; |
| 118 | }; |
| 119 | |
| 120 | Optional<Error> parse(Program&, StringView, Mode); |
| 121 | |
| 122 | private: |
| 123 | template<typename T> T backtrackingScope(std::function<T()> callback) |
| 124 | { |
| 125 | auto state = m_lexer.state(); |
| 126 | auto result = callback(); |
| 127 | if (result) |
| 128 | return result; |
| 129 | m_lexer.setState(WTFMove(state)); |
| 130 | return result; |
| 131 | } |
| 132 | |
| 133 | enum class TryToPeek { |
| 134 | Yes, |
| 135 | No |
| 136 | }; |
| 137 | Unexpected<Error> fail(const String& message, TryToPeek = TryToPeek::Yes); |
| 138 | Expected<Lexer::Token, Error> peek(); |
| 139 | Optional<Lexer::Token> tryType(Lexer::Token::Type); |
| 140 | Optional<Lexer::Token> tryTypes(Vector<Lexer::Token::Type>); |
| 141 | Expected<Lexer::Token, Error> consumeType(Lexer::Token::Type); |
| 142 | Expected<Lexer::Token, Error> consumeTypes(Vector<Lexer::Token::Type>); |
| 143 | |
| 144 | Expected<Variant<int, unsigned>, Error> consumeIntegralLiteral(); |
| 145 | Expected<unsigned, Error> consumeNonNegativeIntegralLiteral(); |
| 146 | Expected<AST::ConstantExpression, Error> parseConstantExpression(); |
| 147 | Expected<AST::TypeArgument, Error> parseTypeArgument(); |
| 148 | Expected<AST::TypeArguments, Error> parseTypeArguments(); |
| 149 | struct TypeSuffixAbbreviated { |
| 150 | Lexer::Token token; |
| 151 | Optional<unsigned> numElements; |
| 152 | }; |
| 153 | Expected<TypeSuffixAbbreviated, Error> parseTypeSuffixAbbreviated(); |
| 154 | struct TypeSuffixNonAbbreviated { |
| 155 | Lexer::Token token; |
| 156 | Optional<AST::AddressSpace> addressSpace; |
| 157 | Optional<unsigned> numElements; |
| 158 | }; |
| 159 | Expected<TypeSuffixNonAbbreviated, Error> parseTypeSuffixNonAbbreviated(); |
| 160 | Expected<UniqueRef<AST::UnnamedType>, Error> parseAddressSpaceType(); |
| 161 | Expected<UniqueRef<AST::UnnamedType>, Error> parseNonAddressSpaceType(); |
| 162 | Expected<UniqueRef<AST::UnnamedType>, Error> parseType(); |
| 163 | Expected<AST::TypeDefinition, Error> parseTypeDefinition(); |
| 164 | Expected<AST::BuiltInSemantic, Error> parseBuiltInSemantic(); |
| 165 | Expected<AST::ResourceSemantic, Error> parseResourceSemantic(); |
| 166 | Expected<AST::SpecializationConstantSemantic, Error> parseSpecializationConstantSemantic(); |
| 167 | Expected<AST::StageInOutSemantic, Error> parseStageInOutSemantic(); |
| 168 | Expected<AST::Semantic, Error> parseSemantic(); |
| 169 | AST::Qualifiers parseQualifiers(); |
| 170 | Expected<AST::StructureElement, Error> parseStructureElement(); |
| 171 | Expected<AST::StructureDefinition, Error> parseStructureDefinition(); |
| 172 | Expected<AST::EnumerationDefinition, Error> parseEnumerationDefinition(); |
| 173 | Expected<AST::EnumerationMember, Error> parseEnumerationMember(); |
| 174 | Expected<AST::NativeTypeDeclaration, Error> parseNativeTypeDeclaration(); |
| 175 | Expected<AST::NumThreadsFunctionAttribute, Error> parseNumThreadsFunctionAttribute(); |
| 176 | Expected<AST::AttributeBlock, Error> parseAttributeBlock(); |
| 177 | Expected<AST::VariableDeclaration, Error> parseParameter(); |
| 178 | Expected<AST::VariableDeclarations, Error> parseParameters(); |
| 179 | Expected<AST::FunctionDeclaration, Error> parseEntryPointFunctionDeclaration(); |
| 180 | Expected<AST::FunctionDeclaration, Error> parseRegularFunctionDeclaration(); |
| 181 | Expected<AST::FunctionDeclaration, Error> parseOperatorFunctionDeclaration(); |
| 182 | Expected<AST::FunctionDeclaration, Error> parseFunctionDeclaration(); |
| 183 | Expected<AST::FunctionDefinition, Error> parseFunctionDefinition(); |
| 184 | Expected<AST::NativeFunctionDeclaration, Error> parseNativeFunctionDeclaration(); |
| 185 | |
| 186 | Expected<AST::Block, Error> parseBlock(); |
| 187 | AST::Block parseBlockBody(Lexer::Token&& origin); |
| 188 | Expected<AST::IfStatement, Error> parseIfStatement(); |
| 189 | Expected<AST::SwitchStatement, Error> parseSwitchStatement(); |
| 190 | Expected<AST::SwitchCase, Error> parseSwitchCase(); |
| 191 | Expected<AST::ForLoop, Error> parseForLoop(); |
| 192 | Expected<AST::WhileLoop, Error> parseWhileLoop(); |
| 193 | Expected<AST::DoWhileLoop, Error> parseDoWhileLoop(); |
| 194 | Expected<AST::VariableDeclaration, Error> parseVariableDeclaration(UniqueRef<AST::UnnamedType>&&); |
| 195 | Expected<AST::VariableDeclarationsStatement, Error> parseVariableDeclarations(); |
| 196 | Expected<UniqueRef<AST::Statement>, Error> parseStatement(); |
| 197 | |
| 198 | Expected<UniqueRef<AST::Expression>, Error> parseEffectfulExpression(); |
| 199 | Expected<UniqueRef<AST::Expression>, Error> parseEffectfulAssignment(); |
| 200 | Expected<UniqueRef<AST::Expression>, Error> parseEffectfulPrefix(); |
| 201 | Expected<UniqueRef<AST::Expression>, Error> parseEffectfulSuffix(); |
| 202 | struct SuffixExpression { |
| 203 | SuffixExpression(UniqueRef<AST::Expression>&& result, bool success) |
| 204 | : result(WTFMove(result)) |
| 205 | , success(success) |
| 206 | { |
| 207 | } |
| 208 | |
| 209 | UniqueRef<AST::Expression> result; |
| 210 | bool success; |
| 211 | operator bool() const { return success; } |
| 212 | }; |
| 213 | SuffixExpression parseLimitedSuffixOperator(UniqueRef<AST::Expression>&&); |
| 214 | SuffixExpression parseSuffixOperator(UniqueRef<AST::Expression>&&); |
| 215 | |
| 216 | Expected<UniqueRef<AST::Expression>, Error> parseExpression(); |
| 217 | Expected<UniqueRef<AST::Expression>, Error> parseTernaryConditional(); |
| 218 | Expected<UniqueRef<AST::Expression>, Error> parseAssignment(); |
| 219 | Expected<UniqueRef<AST::Expression>, Error> parsePossibleTernaryConditional(); |
| 220 | Expected<UniqueRef<AST::Expression>, Error> parsePossibleLogicalBinaryOperation(); |
| 221 | Expected<UniqueRef<AST::Expression>, Error> parsePossibleRelationalBinaryOperation(); |
| 222 | Expected<UniqueRef<AST::Expression>, Error> parsePossibleShift(); |
| 223 | Expected<UniqueRef<AST::Expression>, Error> parsePossibleAdd(); |
| 224 | Expected<UniqueRef<AST::Expression>, Error> parsePossibleMultiply(); |
| 225 | Expected<UniqueRef<AST::Expression>, Error> parsePossiblePrefix(); |
| 226 | Expected<UniqueRef<AST::Expression>, Error> parsePossibleSuffix(); |
| 227 | Expected<UniqueRef<AST::Expression>, Error> parseCallExpression(); |
| 228 | Expected<UniqueRef<AST::Expression>, Error> parseTerm(); |
| 229 | |
| 230 | Lexer m_lexer; |
| 231 | Mode m_mode; |
| 232 | }; |
| 233 | |
| 234 | } // namespace WHLSL |
| 235 | |
| 236 | } // namespace WebCore |
| 237 | |
| 238 | #endif // ENABLE(WEBGPU) |
| 239 | |