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
100namespace WebCore {
101
102namespace WHLSL {
103
104class Parser {
105public:
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
122private:
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