xref: /aosp_15_r20/external/skia/src/sksl/SkSLParser.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2021 Google LLC.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SKSL_PARSER
9*c8dee2aaSAndroid Build Coastguard Worker #define SKSL_PARSER
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLDefines.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLLexer.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLOperator.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLPosition.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLProgramSettings.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLLayout.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLModifiers.h"
19*c8dee2aaSAndroid Build Coastguard Worker 
20*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
21*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
22*c8dee2aaSAndroid Build Coastguard Worker #include <string>
23*c8dee2aaSAndroid Build Coastguard Worker #include <string_view>
24*c8dee2aaSAndroid Build Coastguard Worker #include <vector>
25*c8dee2aaSAndroid Build Coastguard Worker 
26*c8dee2aaSAndroid Build Coastguard Worker namespace SkSL {
27*c8dee2aaSAndroid Build Coastguard Worker 
28*c8dee2aaSAndroid Build Coastguard Worker class Compiler;
29*c8dee2aaSAndroid Build Coastguard Worker class ErrorReporter;
30*c8dee2aaSAndroid Build Coastguard Worker class Expression;
31*c8dee2aaSAndroid Build Coastguard Worker class FunctionDeclaration;
32*c8dee2aaSAndroid Build Coastguard Worker struct Module;
33*c8dee2aaSAndroid Build Coastguard Worker struct Program;
34*c8dee2aaSAndroid Build Coastguard Worker class ProgramElement;
35*c8dee2aaSAndroid Build Coastguard Worker enum class ProgramKind : int8_t;
36*c8dee2aaSAndroid Build Coastguard Worker class Statement;
37*c8dee2aaSAndroid Build Coastguard Worker class SymbolTable;
38*c8dee2aaSAndroid Build Coastguard Worker class Type;
39*c8dee2aaSAndroid Build Coastguard Worker class VarDeclaration;
40*c8dee2aaSAndroid Build Coastguard Worker class Variable;
41*c8dee2aaSAndroid Build Coastguard Worker 
42*c8dee2aaSAndroid Build Coastguard Worker /**
43*c8dee2aaSAndroid Build Coastguard Worker  * Consumes .sksl text and converts it into an IR tree, encapsulated in a Program.
44*c8dee2aaSAndroid Build Coastguard Worker  */
45*c8dee2aaSAndroid Build Coastguard Worker class Parser {
46*c8dee2aaSAndroid Build Coastguard Worker public:
47*c8dee2aaSAndroid Build Coastguard Worker     Parser(Compiler* compiler,
48*c8dee2aaSAndroid Build Coastguard Worker            const ProgramSettings& settings,
49*c8dee2aaSAndroid Build Coastguard Worker            ProgramKind kind,
50*c8dee2aaSAndroid Build Coastguard Worker            std::unique_ptr<std::string> text);
51*c8dee2aaSAndroid Build Coastguard Worker     ~Parser();
52*c8dee2aaSAndroid Build Coastguard Worker 
53*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Program> programInheritingFrom(const Module* module);
54*c8dee2aaSAndroid Build Coastguard Worker 
55*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Module> moduleInheritingFrom(const Module* parentModule);
56*c8dee2aaSAndroid Build Coastguard Worker 
57*c8dee2aaSAndroid Build Coastguard Worker     std::string_view text(Token token);
58*c8dee2aaSAndroid Build Coastguard Worker 
59*c8dee2aaSAndroid Build Coastguard Worker     Position position(Token token);
60*c8dee2aaSAndroid Build Coastguard Worker 
61*c8dee2aaSAndroid Build Coastguard Worker private:
62*c8dee2aaSAndroid Build Coastguard Worker     class AutoDepth;
63*c8dee2aaSAndroid Build Coastguard Worker     class AutoSymbolTable;
64*c8dee2aaSAndroid Build Coastguard Worker     class Checkpoint;
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker     /**
67*c8dee2aaSAndroid Build Coastguard Worker      * Return the next token, including whitespace tokens, from the parse stream.
68*c8dee2aaSAndroid Build Coastguard Worker      */
69*c8dee2aaSAndroid Build Coastguard Worker     Token nextRawToken();
70*c8dee2aaSAndroid Build Coastguard Worker 
71*c8dee2aaSAndroid Build Coastguard Worker     /**
72*c8dee2aaSAndroid Build Coastguard Worker      * Return the next non-whitespace token from the parse stream.
73*c8dee2aaSAndroid Build Coastguard Worker      */
74*c8dee2aaSAndroid Build Coastguard Worker     Token nextToken();
75*c8dee2aaSAndroid Build Coastguard Worker 
76*c8dee2aaSAndroid Build Coastguard Worker     /**
77*c8dee2aaSAndroid Build Coastguard Worker      * Push a token back onto the parse stream, so that it is the next one read. Only a single level
78*c8dee2aaSAndroid Build Coastguard Worker      * of pushback is supported (that is, it is an error to call pushback() twice in a row without
79*c8dee2aaSAndroid Build Coastguard Worker      * an intervening nextToken()).
80*c8dee2aaSAndroid Build Coastguard Worker      */
81*c8dee2aaSAndroid Build Coastguard Worker     void pushback(Token t);
82*c8dee2aaSAndroid Build Coastguard Worker 
83*c8dee2aaSAndroid Build Coastguard Worker     /**
84*c8dee2aaSAndroid Build Coastguard Worker      * Returns the next non-whitespace token without consuming it from the stream.
85*c8dee2aaSAndroid Build Coastguard Worker      */
86*c8dee2aaSAndroid Build Coastguard Worker     Token peek();
87*c8dee2aaSAndroid Build Coastguard Worker 
88*c8dee2aaSAndroid Build Coastguard Worker     /**
89*c8dee2aaSAndroid Build Coastguard Worker      * Checks to see if the next token is of the specified type. If so, stores it in result (if
90*c8dee2aaSAndroid Build Coastguard Worker      * result is non-null) and returns true. Otherwise, pushes it back and returns false.
91*c8dee2aaSAndroid Build Coastguard Worker      */
92*c8dee2aaSAndroid Build Coastguard Worker     bool checkNext(Token::Kind kind, Token* result = nullptr);
93*c8dee2aaSAndroid Build Coastguard Worker 
94*c8dee2aaSAndroid Build Coastguard Worker     /**
95*c8dee2aaSAndroid Build Coastguard Worker      * Behaves like checkNext(TK_IDENTIFIER), but also verifies that identifier is not a builtin
96*c8dee2aaSAndroid Build Coastguard Worker      * type. If the token was actually a builtin type, false is returned (the next token is not
97*c8dee2aaSAndroid Build Coastguard Worker      * considered to be an identifier).
98*c8dee2aaSAndroid Build Coastguard Worker      */
99*c8dee2aaSAndroid Build Coastguard Worker     bool checkIdentifier(Token* result = nullptr);
100*c8dee2aaSAndroid Build Coastguard Worker 
101*c8dee2aaSAndroid Build Coastguard Worker     /**
102*c8dee2aaSAndroid Build Coastguard Worker      * Reads the next non-whitespace token and generates an error if it is not the expected type.
103*c8dee2aaSAndroid Build Coastguard Worker      * The 'expected' string is part of the error message, which reads:
104*c8dee2aaSAndroid Build Coastguard Worker      *
105*c8dee2aaSAndroid Build Coastguard Worker      * "expected <expected>, but found '<actual text>'"
106*c8dee2aaSAndroid Build Coastguard Worker      *
107*c8dee2aaSAndroid Build Coastguard Worker      * If 'result' is non-null, it is set to point to the token that was read.
108*c8dee2aaSAndroid Build Coastguard Worker      * Returns true if the read token was as expected, false otherwise.
109*c8dee2aaSAndroid Build Coastguard Worker      */
110*c8dee2aaSAndroid Build Coastguard Worker     bool expect(Token::Kind kind, const char* expected, Token* result = nullptr);
111*c8dee2aaSAndroid Build Coastguard Worker     bool expect(Token::Kind kind, std::string expected, Token* result = nullptr);
112*c8dee2aaSAndroid Build Coastguard Worker 
113*c8dee2aaSAndroid Build Coastguard Worker     /**
114*c8dee2aaSAndroid Build Coastguard Worker      * Behaves like expect(TK_IDENTIFIER), but also verifies that identifier is not a type.
115*c8dee2aaSAndroid Build Coastguard Worker      * If the token was actually a type, generates an error message of the form:
116*c8dee2aaSAndroid Build Coastguard Worker      *
117*c8dee2aaSAndroid Build Coastguard Worker      * "expected an identifier, but found type 'float2'"
118*c8dee2aaSAndroid Build Coastguard Worker      */
119*c8dee2aaSAndroid Build Coastguard Worker     bool expectIdentifier(Token* result);
120*c8dee2aaSAndroid Build Coastguard Worker 
121*c8dee2aaSAndroid Build Coastguard Worker     /** If the next token is a newline, consumes it and returns true. If not, returns false. */
122*c8dee2aaSAndroid Build Coastguard Worker     bool expectNewline();
123*c8dee2aaSAndroid Build Coastguard Worker 
124*c8dee2aaSAndroid Build Coastguard Worker     void error(Token token, std::string_view msg);
125*c8dee2aaSAndroid Build Coastguard Worker     void error(Position position, std::string_view msg);
126*c8dee2aaSAndroid Build Coastguard Worker 
127*c8dee2aaSAndroid Build Coastguard Worker     // Returns the range from `start` to the current parse position.
128*c8dee2aaSAndroid Build Coastguard Worker     Position rangeFrom(Position start);
129*c8dee2aaSAndroid Build Coastguard Worker     Position rangeFrom(Token start);
130*c8dee2aaSAndroid Build Coastguard Worker 
131*c8dee2aaSAndroid Build Coastguard Worker     // these functions parse individual grammar rules from the current parse position; you probably
132*c8dee2aaSAndroid Build Coastguard Worker     // don't need to call any of these outside of the parser. The function declarations in the .cpp
133*c8dee2aaSAndroid Build Coastguard Worker     // file have comments describing the grammar rules.
134*c8dee2aaSAndroid Build Coastguard Worker 
135*c8dee2aaSAndroid Build Coastguard Worker     void declarations();
136*c8dee2aaSAndroid Build Coastguard Worker 
137*c8dee2aaSAndroid Build Coastguard Worker     /**
138*c8dee2aaSAndroid Build Coastguard Worker      * Parses an expression representing an array size. Reports errors if the array size is not
139*c8dee2aaSAndroid Build Coastguard Worker      * valid (out of bounds, not a literal integer). Returns true if an expression was
140*c8dee2aaSAndroid Build Coastguard Worker      * successfully parsed, even if that array size is not actually valid. In the event of a true
141*c8dee2aaSAndroid Build Coastguard Worker      * return, outResult always contains a valid array size (even if the parsed array size was not
142*c8dee2aaSAndroid Build Coastguard Worker      * actually valid; invalid array sizes result in a 1 to avoid additional errors downstream).
143*c8dee2aaSAndroid Build Coastguard Worker      */
144*c8dee2aaSAndroid Build Coastguard Worker     bool arraySize(SKSL_INT* outResult);
145*c8dee2aaSAndroid Build Coastguard Worker 
146*c8dee2aaSAndroid Build Coastguard Worker     void directive(bool allowVersion);
147*c8dee2aaSAndroid Build Coastguard Worker 
148*c8dee2aaSAndroid Build Coastguard Worker     void extensionDirective(Position start);
149*c8dee2aaSAndroid Build Coastguard Worker 
150*c8dee2aaSAndroid Build Coastguard Worker     void versionDirective(Position start, bool allowVersion);
151*c8dee2aaSAndroid Build Coastguard Worker 
152*c8dee2aaSAndroid Build Coastguard Worker     bool declaration();
153*c8dee2aaSAndroid Build Coastguard Worker 
154*c8dee2aaSAndroid Build Coastguard Worker     bool functionDeclarationEnd(Position start,
155*c8dee2aaSAndroid Build Coastguard Worker                                 Modifiers& modifiers,
156*c8dee2aaSAndroid Build Coastguard Worker                                 const Type* returnType,
157*c8dee2aaSAndroid Build Coastguard Worker                                 const Token& name);
158*c8dee2aaSAndroid Build Coastguard Worker 
159*c8dee2aaSAndroid Build Coastguard Worker     bool prototypeFunction(SkSL::FunctionDeclaration* decl);
160*c8dee2aaSAndroid Build Coastguard Worker 
161*c8dee2aaSAndroid Build Coastguard Worker     bool defineFunction(SkSL::FunctionDeclaration* decl);
162*c8dee2aaSAndroid Build Coastguard Worker 
163*c8dee2aaSAndroid Build Coastguard Worker     struct VarDeclarationsPrefix {
164*c8dee2aaSAndroid Build Coastguard Worker         Position fPosition;
165*c8dee2aaSAndroid Build Coastguard Worker         Modifiers fModifiers;
166*c8dee2aaSAndroid Build Coastguard Worker         const Type* fType;
167*c8dee2aaSAndroid Build Coastguard Worker         Token fName;
168*c8dee2aaSAndroid Build Coastguard Worker     };
169*c8dee2aaSAndroid Build Coastguard Worker 
170*c8dee2aaSAndroid Build Coastguard Worker     bool varDeclarationsPrefix(VarDeclarationsPrefix* prefixData);
171*c8dee2aaSAndroid Build Coastguard Worker 
172*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> varDeclarationsOrExpressionStatement();
173*c8dee2aaSAndroid Build Coastguard Worker 
174*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> varDeclarations();
175*c8dee2aaSAndroid Build Coastguard Worker 
176*c8dee2aaSAndroid Build Coastguard Worker     const Type* structDeclaration();
177*c8dee2aaSAndroid Build Coastguard Worker 
178*c8dee2aaSAndroid Build Coastguard Worker     void structVarDeclaration(Position start, const Modifiers& modifiers);
179*c8dee2aaSAndroid Build Coastguard Worker 
allowUnsizedArrays()180*c8dee2aaSAndroid Build Coastguard Worker     bool allowUnsizedArrays() {
181*c8dee2aaSAndroid Build Coastguard Worker         return ProgramConfig::IsCompute(fKind) || ProgramConfig::IsFragment(fKind) ||
182*c8dee2aaSAndroid Build Coastguard Worker                ProgramConfig::IsVertex(fKind);
183*c8dee2aaSAndroid Build Coastguard Worker     }
184*c8dee2aaSAndroid Build Coastguard Worker 
185*c8dee2aaSAndroid Build Coastguard Worker     const Type* arrayType(const Type* base, int count, Position pos);
186*c8dee2aaSAndroid Build Coastguard Worker 
187*c8dee2aaSAndroid Build Coastguard Worker     const Type* unsizedArrayType(const Type* base, Position pos);
188*c8dee2aaSAndroid Build Coastguard Worker 
189*c8dee2aaSAndroid Build Coastguard Worker     bool parseArrayDimensions(Position pos, const Type** type);
190*c8dee2aaSAndroid Build Coastguard Worker 
191*c8dee2aaSAndroid Build Coastguard Worker     bool parseInitializer(Position pos, std::unique_ptr<Expression>* initializer);
192*c8dee2aaSAndroid Build Coastguard Worker 
193*c8dee2aaSAndroid Build Coastguard Worker     void addGlobalVarDeclaration(std::unique_ptr<SkSL::VarDeclaration> decl);
194*c8dee2aaSAndroid Build Coastguard Worker 
195*c8dee2aaSAndroid Build Coastguard Worker     void globalVarDeclarationEnd(Position position, const Modifiers& mods,
196*c8dee2aaSAndroid Build Coastguard Worker                                  const Type* baseType, Token name);
197*c8dee2aaSAndroid Build Coastguard Worker 
198*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> localVarDeclarationEnd(Position position,
199*c8dee2aaSAndroid Build Coastguard Worker                                                       const Modifiers& mods,
200*c8dee2aaSAndroid Build Coastguard Worker                                                       const Type* baseType,
201*c8dee2aaSAndroid Build Coastguard Worker                                                       Token name);
202*c8dee2aaSAndroid Build Coastguard Worker 
203*c8dee2aaSAndroid Build Coastguard Worker     bool modifiersDeclarationEnd(const Modifiers& mods);
204*c8dee2aaSAndroid Build Coastguard Worker 
205*c8dee2aaSAndroid Build Coastguard Worker     bool parameter(std::unique_ptr<SkSL::Variable>* outParam);
206*c8dee2aaSAndroid Build Coastguard Worker 
207*c8dee2aaSAndroid Build Coastguard Worker     int layoutInt();
208*c8dee2aaSAndroid Build Coastguard Worker 
209*c8dee2aaSAndroid Build Coastguard Worker     std::string_view layoutIdentifier();
210*c8dee2aaSAndroid Build Coastguard Worker 
211*c8dee2aaSAndroid Build Coastguard Worker     SkSL::Layout layout();
212*c8dee2aaSAndroid Build Coastguard Worker 
213*c8dee2aaSAndroid Build Coastguard Worker     Modifiers modifiers();
214*c8dee2aaSAndroid Build Coastguard Worker 
215*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> statementOrNop(Position pos, std::unique_ptr<Statement> stmt);
216*c8dee2aaSAndroid Build Coastguard Worker 
217*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> statement(bool bracesIntroduceNewScope = true);
218*c8dee2aaSAndroid Build Coastguard Worker 
219*c8dee2aaSAndroid Build Coastguard Worker     const Type* findType(Position pos, Modifiers* modifiers, std::string_view name);
220*c8dee2aaSAndroid Build Coastguard Worker 
221*c8dee2aaSAndroid Build Coastguard Worker     const Type* type(Modifiers* modifiers);
222*c8dee2aaSAndroid Build Coastguard Worker 
223*c8dee2aaSAndroid Build Coastguard Worker     bool interfaceBlock(const Modifiers& mods);
224*c8dee2aaSAndroid Build Coastguard Worker 
225*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> ifStatement();
226*c8dee2aaSAndroid Build Coastguard Worker 
227*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> doStatement();
228*c8dee2aaSAndroid Build Coastguard Worker 
229*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> whileStatement();
230*c8dee2aaSAndroid Build Coastguard Worker 
231*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> forStatement();
232*c8dee2aaSAndroid Build Coastguard Worker 
233*c8dee2aaSAndroid Build Coastguard Worker     bool switchCaseBody(ExpressionArray* values,
234*c8dee2aaSAndroid Build Coastguard Worker                         StatementArray* caseBlocks,
235*c8dee2aaSAndroid Build Coastguard Worker                         std::unique_ptr<Expression> value);
236*c8dee2aaSAndroid Build Coastguard Worker 
237*c8dee2aaSAndroid Build Coastguard Worker     bool switchCase(ExpressionArray* values, StatementArray* caseBlocks);
238*c8dee2aaSAndroid Build Coastguard Worker 
239*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> switchStatement();
240*c8dee2aaSAndroid Build Coastguard Worker 
241*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> returnStatement();
242*c8dee2aaSAndroid Build Coastguard Worker 
243*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> breakStatement();
244*c8dee2aaSAndroid Build Coastguard Worker 
245*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> continueStatement();
246*c8dee2aaSAndroid Build Coastguard Worker 
247*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> discardStatement();
248*c8dee2aaSAndroid Build Coastguard Worker 
249*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> block(bool introduceNewScope,
250*c8dee2aaSAndroid Build Coastguard Worker                                      std::unique_ptr<SymbolTable>* adoptExistingSymbolTable);
251*c8dee2aaSAndroid Build Coastguard Worker 
252*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Statement> expressionStatement();
253*c8dee2aaSAndroid Build Coastguard Worker 
254*c8dee2aaSAndroid Build Coastguard Worker     using BinaryParseFn = std::unique_ptr<Expression> (Parser::*)();
255*c8dee2aaSAndroid Build Coastguard Worker     [[nodiscard]] bool operatorRight(AutoDepth& depth,
256*c8dee2aaSAndroid Build Coastguard Worker                                      Operator::Kind op,
257*c8dee2aaSAndroid Build Coastguard Worker                                      BinaryParseFn rightFn,
258*c8dee2aaSAndroid Build Coastguard Worker                                      std::unique_ptr<Expression>& expr);
259*c8dee2aaSAndroid Build Coastguard Worker 
260*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> poison(Position pos);
261*c8dee2aaSAndroid Build Coastguard Worker 
262*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> expressionOrPoison(Position pos, std::unique_ptr<Expression> expr);
263*c8dee2aaSAndroid Build Coastguard Worker 
264*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> expression();
265*c8dee2aaSAndroid Build Coastguard Worker 
266*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> assignmentExpression();
267*c8dee2aaSAndroid Build Coastguard Worker 
268*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> ternaryExpression();
269*c8dee2aaSAndroid Build Coastguard Worker 
270*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> logicalOrExpression();
271*c8dee2aaSAndroid Build Coastguard Worker 
272*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> logicalXorExpression();
273*c8dee2aaSAndroid Build Coastguard Worker 
274*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> logicalAndExpression();
275*c8dee2aaSAndroid Build Coastguard Worker 
276*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> bitwiseOrExpression();
277*c8dee2aaSAndroid Build Coastguard Worker 
278*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> bitwiseXorExpression();
279*c8dee2aaSAndroid Build Coastguard Worker 
280*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> bitwiseAndExpression();
281*c8dee2aaSAndroid Build Coastguard Worker 
282*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> equalityExpression();
283*c8dee2aaSAndroid Build Coastguard Worker 
284*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> relationalExpression();
285*c8dee2aaSAndroid Build Coastguard Worker 
286*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> shiftExpression();
287*c8dee2aaSAndroid Build Coastguard Worker 
288*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> additiveExpression();
289*c8dee2aaSAndroid Build Coastguard Worker 
290*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> multiplicativeExpression();
291*c8dee2aaSAndroid Build Coastguard Worker 
292*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> unaryExpression();
293*c8dee2aaSAndroid Build Coastguard Worker 
294*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> postfixExpression();
295*c8dee2aaSAndroid Build Coastguard Worker 
296*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> swizzle(Position pos,
297*c8dee2aaSAndroid Build Coastguard Worker                                         std::unique_ptr<Expression> base,
298*c8dee2aaSAndroid Build Coastguard Worker                                         std::string_view swizzleMask,
299*c8dee2aaSAndroid Build Coastguard Worker                                         Position maskPos);
300*c8dee2aaSAndroid Build Coastguard Worker 
301*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> call(Position pos,
302*c8dee2aaSAndroid Build Coastguard Worker                                      std::unique_ptr<Expression> base,
303*c8dee2aaSAndroid Build Coastguard Worker                                      ExpressionArray args);
304*c8dee2aaSAndroid Build Coastguard Worker 
305*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> suffix(std::unique_ptr<Expression> base);
306*c8dee2aaSAndroid Build Coastguard Worker 
307*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Expression> term();
308*c8dee2aaSAndroid Build Coastguard Worker 
309*c8dee2aaSAndroid Build Coastguard Worker     bool intLiteral(SKSL_INT* dest);
310*c8dee2aaSAndroid Build Coastguard Worker 
311*c8dee2aaSAndroid Build Coastguard Worker     bool floatLiteral(SKSL_FLOAT* dest);
312*c8dee2aaSAndroid Build Coastguard Worker 
313*c8dee2aaSAndroid Build Coastguard Worker     bool boolLiteral(bool* dest);
314*c8dee2aaSAndroid Build Coastguard Worker 
315*c8dee2aaSAndroid Build Coastguard Worker     bool identifier(std::string_view* dest);
316*c8dee2aaSAndroid Build Coastguard Worker 
317*c8dee2aaSAndroid Build Coastguard Worker     SymbolTable* symbolTable();
318*c8dee2aaSAndroid Build Coastguard Worker 
319*c8dee2aaSAndroid Build Coastguard Worker     Compiler& fCompiler;
320*c8dee2aaSAndroid Build Coastguard Worker     ProgramSettings fSettings;
321*c8dee2aaSAndroid Build Coastguard Worker     ErrorReporter* fErrorReporter;
322*c8dee2aaSAndroid Build Coastguard Worker     bool fEncounteredFatalError;
323*c8dee2aaSAndroid Build Coastguard Worker     ProgramKind fKind;
324*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<std::string> fText;
325*c8dee2aaSAndroid Build Coastguard Worker     std::vector<std::unique_ptr<SkSL::ProgramElement>> fProgramElements;
326*c8dee2aaSAndroid Build Coastguard Worker     Lexer fLexer;
327*c8dee2aaSAndroid Build Coastguard Worker     // current parse depth, used to enforce a recursion limit to try to keep us from overflowing the
328*c8dee2aaSAndroid Build Coastguard Worker     // stack on pathological inputs
329*c8dee2aaSAndroid Build Coastguard Worker     int fDepth = 0;
330*c8dee2aaSAndroid Build Coastguard Worker     Token fPushback;
331*c8dee2aaSAndroid Build Coastguard Worker };
332*c8dee2aaSAndroid Build Coastguard Worker 
333*c8dee2aaSAndroid Build Coastguard Worker }  // namespace SkSL
334*c8dee2aaSAndroid Build Coastguard Worker 
335*c8dee2aaSAndroid Build Coastguard Worker #endif
336