• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "stdio.h"
9 #include "SkSLParser.h"
10 #include "SkSLToken.h"
11 
12 #define register
13 #include "disable_flex_warnings.h"
14 #include "lex.sksl.c"
15 #undef register
16 #ifdef __clang__
17 #pragma clang diagnostic pop
18 #endif
19 #ifdef __GNUC__
20 #pragma GCC diagnostic pop
21 #endif
22 #ifdef _MSC_VER
23 #pragma warning(pop)
24 #endif
25 
26 #include "lex.layout.h"
27 #include "ast/SkSLASTBinaryExpression.h"
28 #include "ast/SkSLASTBlock.h"
29 #include "ast/SkSLASTBoolLiteral.h"
30 #include "ast/SkSLASTBreakStatement.h"
31 #include "ast/SkSLASTCallSuffix.h"
32 #include "ast/SkSLASTContinueStatement.h"
33 #include "ast/SkSLASTDiscardStatement.h"
34 #include "ast/SkSLASTDoStatement.h"
35 #include "ast/SkSLASTExpression.h"
36 #include "ast/SkSLASTExpressionStatement.h"
37 #include "ast/SkSLASTExtension.h"
38 #include "ast/SkSLASTFieldSuffix.h"
39 #include "ast/SkSLASTFloatLiteral.h"
40 #include "ast/SkSLASTForStatement.h"
41 #include "ast/SkSLASTFunction.h"
42 #include "ast/SkSLASTIdentifier.h"
43 #include "ast/SkSLASTIfStatement.h"
44 #include "ast/SkSLASTIndexSuffix.h"
45 #include "ast/SkSLASTInterfaceBlock.h"
46 #include "ast/SkSLASTIntLiteral.h"
47 #include "ast/SkSLASTModifiersDeclaration.h"
48 #include "ast/SkSLASTParameter.h"
49 #include "ast/SkSLASTPrecision.h"
50 #include "ast/SkSLASTPrefixExpression.h"
51 #include "ast/SkSLASTReturnStatement.h"
52 #include "ast/SkSLASTStatement.h"
53 #include "ast/SkSLASTSuffixExpression.h"
54 #include "ast/SkSLASTSwitchCase.h"
55 #include "ast/SkSLASTSwitchStatement.h"
56 #include "ast/SkSLASTTernaryExpression.h"
57 #include "ast/SkSLASTType.h"
58 #include "ast/SkSLASTVarDeclaration.h"
59 #include "ast/SkSLASTVarDeclarationStatement.h"
60 #include "ast/SkSLASTWhileStatement.h"
61 #include "ir/SkSLSymbolTable.h"
62 #include "ir/SkSLModifiers.h"
63 #include "ir/SkSLType.h"
64 
65 namespace SkSL {
66 
67 #define MAX_PARSE_DEPTH 50
68 
69 class AutoDepth {
70 public:
AutoDepth(Parser * p)71     AutoDepth(Parser* p)
72     : fParser(p) {
73         fParser->fDepth++;
74     }
75 
~AutoDepth()76     ~AutoDepth() {
77         fParser->fDepth--;
78     }
79 
checkValid()80     bool checkValid() {
81         if (fParser->fDepth > MAX_PARSE_DEPTH) {
82             fParser->error(fParser->peek().fPosition, SkString("exceeded max parse depth"));
83             return false;
84         }
85         return true;
86     }
87 
88 private:
89     Parser* fParser;
90 };
91 
Parser(SkString text,SymbolTable & types,ErrorReporter & errors)92 Parser::Parser(SkString text, SymbolTable& types, ErrorReporter& errors)
93 : fPushback(Position(-1, -1), Token::INVALID_TOKEN, SkString())
94 , fTypes(types)
95 , fErrors(errors) {
96     sksllex_init(&fScanner);
97     layoutlex_init(&fLayoutScanner);
98     fBuffer = sksl_scan_string(text.c_str(), fScanner);
99     skslset_lineno(1, fScanner);
100 
101     if (false) {
102         // avoid unused warning
103         yyunput(0, nullptr, fScanner);
104     }
105 }
106 
~Parser()107 Parser::~Parser() {
108     sksl_delete_buffer(fBuffer, fScanner);
109     sksllex_destroy(fScanner);
110     layoutlex_destroy(fLayoutScanner);
111 }
112 
113 /* (precision | directive | declaration)* END_OF_FILE */
file()114 std::vector<std::unique_ptr<ASTDeclaration>> Parser::file() {
115     std::vector<std::unique_ptr<ASTDeclaration>> result;
116     for (;;) {
117         switch (this->peek().fKind) {
118             case Token::END_OF_FILE:
119                 return result;
120             case Token::PRECISION: {
121                 std::unique_ptr<ASTDeclaration> precision = this->precision();
122                 if (precision) {
123                     result.push_back(std::move(precision));
124                 }
125                 break;
126             }
127             case Token::DIRECTIVE: {
128                 std::unique_ptr<ASTDeclaration> decl = this->directive();
129                 if (decl) {
130                     result.push_back(std::move(decl));
131                 }
132                 break;
133             }
134             default: {
135                 std::unique_ptr<ASTDeclaration> decl = this->declaration();
136                 if (!decl) {
137                     continue;
138                 }
139                 result.push_back(std::move(decl));
140             }
141         }
142     }
143 }
144 
nextToken()145 Token Parser::nextToken() {
146     if (fPushback.fKind != Token::INVALID_TOKEN) {
147         Token result = fPushback;
148         fPushback.fKind = Token::INVALID_TOKEN;
149         fPushback.fText = "";
150         return result;
151     }
152     int token = sksllex(fScanner);
153     SkString text;
154     switch ((Token::Kind) token) {
155         case Token::IDENTIFIER:    // fall through
156         case Token::INT_LITERAL:   // fall through
157         case Token::FLOAT_LITERAL: // fall through
158         case Token::DIRECTIVE:
159             text = SkString(skslget_text(fScanner));
160             break;
161         default:
162 #ifdef SK_DEBUG
163             text = SkString(skslget_text(fScanner));
164 #endif
165             break;
166     }
167     return Token(Position(skslget_lineno(fScanner), -1), (Token::Kind) token, text);
168 }
169 
pushback(Token t)170 void Parser::pushback(Token t) {
171     ASSERT(fPushback.fKind == Token::INVALID_TOKEN);
172     fPushback = t;
173 }
174 
peek()175 Token Parser::peek() {
176     fPushback = this->nextToken();
177     return fPushback;
178 }
179 
180 
expect(Token::Kind kind,const char * expected,Token * result)181 bool Parser::expect(Token::Kind kind, const char* expected, Token* result) {
182     return this->expect(kind, SkString(expected), result);
183 }
184 
expect(Token::Kind kind,SkString expected,Token * result)185 bool Parser::expect(Token::Kind kind, SkString expected, Token* result) {
186     Token next = this->nextToken();
187     if (next.fKind == kind) {
188         if (result) {
189             *result = next;
190         }
191         return true;
192     } else {
193         if (next.fText.size()) {
194             this->error(next.fPosition, "expected " + expected + ", but found '" + next.fText +
195                                         "'");
196         } else {
197             this->error(next.fPosition, "parse error, recompile in debug mode for details");
198         }
199         return false;
200     }
201 }
202 
error(Position p,const char * msg)203 void Parser::error(Position p, const char* msg) {
204     this->error(p, SkString(msg));
205 }
206 
error(Position p,SkString msg)207 void Parser::error(Position p, SkString msg) {
208     fErrors.error(p, msg);
209 }
210 
isType(SkString name)211 bool Parser::isType(SkString name) {
212     return nullptr != fTypes[name];
213 }
214 
215 /* PRECISION (LOWP | MEDIUMP | HIGHP) type SEMICOLON */
precision()216 std::unique_ptr<ASTDeclaration> Parser::precision() {
217     if (!this->expect(Token::PRECISION, "'precision'")) {
218         return nullptr;
219     }
220     Modifiers::Flag result;
221     Token p = this->nextToken();
222     switch (p.fKind) {
223         case Token::LOWP:
224             result = Modifiers::kLowp_Flag;
225             break;
226         case Token::MEDIUMP:
227             result = Modifiers::kMediump_Flag;
228             break;
229         case Token::HIGHP:
230             result = Modifiers::kHighp_Flag;
231             break;
232         default:
233             this->error(p.fPosition, "expected 'lowp', 'mediump', or 'highp', but found '" +
234                                      p.fText + "'");
235             return nullptr;
236     }
237     // FIXME handle the type
238     if (!this->type()) {
239         return nullptr;
240     }
241     this->expect(Token::SEMICOLON, "';'");
242     return std::unique_ptr<ASTDeclaration>(new ASTPrecision(p.fPosition, result));
243 }
244 
245 /* DIRECTIVE(#version) INT_LITERAL ("es" | "compatibility")? |
246    DIRECTIVE(#extension) IDENTIFIER COLON IDENTIFIER */
directive()247 std::unique_ptr<ASTDeclaration> Parser::directive() {
248     Token start;
249     if (!this->expect(Token::DIRECTIVE, "a directive", &start)) {
250         return nullptr;
251     }
252     if (start.fText == "#version") {
253         this->expect(Token::INT_LITERAL, "a version number");
254         Token next = this->peek();
255         if (next.fText == "es" || next.fText == "compatibility") {
256             this->nextToken();
257         }
258         // version is ignored for now; it will eventually become an error when we stop pretending
259         // to be GLSL
260         return nullptr;
261     } else if (start.fText == "#extension") {
262         Token name;
263         if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
264             return nullptr;
265         }
266         if (!this->expect(Token::COLON, "':'")) {
267             return nullptr;
268         }
269         // FIXME: need to start paying attention to this token
270         if (!this->expect(Token::IDENTIFIER, "an identifier")) {
271             return nullptr;
272         }
273         return std::unique_ptr<ASTDeclaration>(new ASTExtension(start.fPosition,
274                                                                 std::move(name.fText)));
275     } else {
276         this->error(start.fPosition, "unsupported directive '" + start.fText + "'");
277         return nullptr;
278     }
279 }
280 
281 /* modifiers (structVarDeclaration | type IDENTIFIER ((LPAREN parameter
282    (COMMA parameter)* RPAREN (block | SEMICOLON)) | SEMICOLON) | interfaceBlock) */
declaration()283 std::unique_ptr<ASTDeclaration> Parser::declaration() {
284     Modifiers modifiers = this->modifiers();
285     Token lookahead = this->peek();
286     if (lookahead.fKind == Token::IDENTIFIER && !this->isType(lookahead.fText)) {
287         // we have an identifier that's not a type, could be the start of an interface block
288         return this->interfaceBlock(modifiers);
289     }
290     if (lookahead.fKind == Token::STRUCT) {
291         return this->structVarDeclaration(modifiers);
292     }
293     if (lookahead.fKind == Token::SEMICOLON) {
294         this->nextToken();
295         return std::unique_ptr<ASTDeclaration>(new ASTModifiersDeclaration(modifiers));
296     }
297     std::unique_ptr<ASTType> type(this->type());
298     if (!type) {
299         return nullptr;
300     }
301     if (type->fKind == ASTType::kStruct_Kind && peek().fKind == Token::SEMICOLON) {
302         this->nextToken();
303         return nullptr;
304     }
305     Token name;
306     if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
307         return nullptr;
308     }
309     if (!modifiers.fFlags && this->peek().fKind == Token::LPAREN) {
310         this->nextToken();
311         std::vector<std::unique_ptr<ASTParameter>> parameters;
312         while (this->peek().fKind != Token::RPAREN) {
313             if (parameters.size() > 0) {
314                 if (!this->expect(Token::COMMA, "','")) {
315                     return nullptr;
316                 }
317             }
318             std::unique_ptr<ASTParameter> parameter = this->parameter();
319             if (!parameter) {
320                 return nullptr;
321             }
322             parameters.push_back(std::move(parameter));
323         }
324         this->nextToken();
325         std::unique_ptr<ASTBlock> body;
326         if (this->peek().fKind == Token::SEMICOLON) {
327             this->nextToken();
328         } else {
329             body = this->block();
330             if (!body) {
331                 return nullptr;
332             }
333         }
334         return std::unique_ptr<ASTDeclaration>(new ASTFunction(name.fPosition, std::move(type),
335                                                                std::move(name.fText),
336                                                                std::move(parameters),
337                                                                std::move(body)));
338     } else {
339         return this->varDeclarationEnd(modifiers, std::move(type), name.fText);
340     }
341 }
342 
343 /* modifiers type IDENTIFIER varDeclarationEnd */
varDeclarations()344 std::unique_ptr<ASTVarDeclarations> Parser::varDeclarations() {
345     Modifiers modifiers = this->modifiers();
346     std::unique_ptr<ASTType> type(this->type());
347     if (!type) {
348         return nullptr;
349     }
350     Token name;
351     if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
352         return nullptr;
353     }
354     return this->varDeclarationEnd(modifiers, std::move(type), std::move(name.fText));
355 }
356 
357 /* STRUCT IDENTIFIER LBRACE varDeclaration* RBRACE */
structDeclaration()358 std::unique_ptr<ASTType> Parser::structDeclaration() {
359     if (!this->expect(Token::STRUCT, "'struct'")) {
360         return nullptr;
361     }
362     Token name;
363     if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
364         return nullptr;
365     }
366     if (!this->expect(Token::LBRACE, "'{'")) {
367         return nullptr;
368     }
369     std::vector<Type::Field> fields;
370     while (this->peek().fKind != Token::RBRACE) {
371         std::unique_ptr<ASTVarDeclarations> decl = this->varDeclarations();
372         if (!decl) {
373             return nullptr;
374         }
375         for (const auto& var : decl->fVars) {
376             auto type = (const Type*) fTypes[decl->fType->fName];
377             for (int i = (int) var.fSizes.size() - 1; i >= 0; i--) {
378                 if (!var.fSizes[i] || var.fSizes[i]->fKind != ASTExpression::kInt_Kind) {
379                     this->error(decl->fPosition, "array size in struct field must be a constant");
380                     return nullptr;
381                 }
382                 uint64_t columns = ((ASTIntLiteral&) *var.fSizes[i]).fValue;
383                 SkString name = type->name() + "[" + to_string(columns) + "]";
384                 type = new Type(name, Type::kArray_Kind, *type, (int) columns);
385                 fTypes.takeOwnership((Type*) type);
386             }
387             fields.push_back(Type::Field(decl->fModifiers, var.fName, type));
388             if (var.fValue) {
389                 this->error(decl->fPosition, "initializers are not permitted on struct fields");
390             }
391         }
392     }
393     if (!this->expect(Token::RBRACE, "'}'")) {
394         return nullptr;
395     }
396     fTypes.add(name.fText, std::unique_ptr<Type>(new Type(name.fPosition, name.fText, fields)));
397     return std::unique_ptr<ASTType>(new ASTType(name.fPosition, name.fText,
398                                                 ASTType::kStruct_Kind, std::vector<int>()));
399 }
400 
401 /* structDeclaration ((IDENTIFIER varDeclarationEnd) | SEMICOLON) */
structVarDeclaration(Modifiers modifiers)402 std::unique_ptr<ASTVarDeclarations> Parser::structVarDeclaration(Modifiers modifiers) {
403     std::unique_ptr<ASTType> type = this->structDeclaration();
404     if (!type) {
405         return nullptr;
406     }
407     if (peek().fKind == Token::IDENTIFIER) {
408         Token name = this->nextToken();
409         std::unique_ptr<ASTVarDeclarations> result = this->varDeclarationEnd(modifiers,
410                                                                              std::move(type),
411                                                                              std::move(name.fText));
412         if (result) {
413             for (const auto& var : result->fVars) {
414                 if (var.fValue) {
415                     this->error(var.fValue->fPosition,
416                                 "struct variables cannot be initialized");
417                 }
418             }
419         }
420         return result;
421     }
422     this->expect(Token::SEMICOLON, "';'");
423     return nullptr;
424 }
425 
426 /* (LBRACKET expression? RBRACKET)* (EQ expression)? (COMMA IDENTIFER
427    (LBRACKET expression? RBRACKET)* (EQ expression)?)* SEMICOLON */
varDeclarationEnd(Modifiers mods,std::unique_ptr<ASTType> type,SkString name)428 std::unique_ptr<ASTVarDeclarations> Parser::varDeclarationEnd(Modifiers mods,
429                                                               std::unique_ptr<ASTType> type,
430                                                               SkString name) {
431     std::vector<ASTVarDeclaration> vars;
432     std::vector<std::unique_ptr<ASTExpression>> currentVarSizes;
433     while (this->peek().fKind == Token::LBRACKET) {
434         this->nextToken();
435         if (this->peek().fKind == Token::RBRACKET) {
436             this->nextToken();
437             currentVarSizes.push_back(nullptr);
438         } else {
439             std::unique_ptr<ASTExpression> size(this->expression());
440             if (!size) {
441                 return nullptr;
442             }
443             currentVarSizes.push_back(std::move(size));
444             if (!this->expect(Token::RBRACKET, "']'")) {
445                 return nullptr;
446             }
447         }
448     }
449     std::unique_ptr<ASTExpression> value;
450     if (this->peek().fKind == Token::EQ) {
451         this->nextToken();
452         value = this->expression();
453         if (!value) {
454             return nullptr;
455         }
456     }
457     vars.emplace_back(std::move(name), std::move(currentVarSizes), std::move(value));
458     while (this->peek().fKind == Token::COMMA) {
459         this->nextToken();
460         Token name;
461         if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
462             return nullptr;
463         }
464         currentVarSizes.clear();
465         value.reset();
466         while (this->peek().fKind == Token::LBRACKET) {
467             this->nextToken();
468             if (this->peek().fKind == Token::RBRACKET) {
469                 this->nextToken();
470                 currentVarSizes.push_back(nullptr);
471             } else {
472                 std::unique_ptr<ASTExpression> size(this->expression());
473                 if (!size) {
474                     return nullptr;
475                 }
476                 currentVarSizes.push_back(std::move(size));
477                 if (!this->expect(Token::RBRACKET, "']'")) {
478                     return nullptr;
479                 }
480             }
481         }
482         if (this->peek().fKind == Token::EQ) {
483             this->nextToken();
484             value = this->expression();
485             if (!value) {
486                 return nullptr;
487             }
488         }
489         vars.emplace_back(std::move(name.fText), std::move(currentVarSizes), std::move(value));
490     }
491     if (!this->expect(Token::SEMICOLON, "';'")) {
492         return nullptr;
493     }
494     return std::unique_ptr<ASTVarDeclarations>(new ASTVarDeclarations(std::move(mods),
495                                                                       std::move(type),
496                                                                       std::move(vars)));
497 }
498 
499 /* modifiers type IDENTIFIER (LBRACKET INT_LITERAL RBRACKET)? */
parameter()500 std::unique_ptr<ASTParameter> Parser::parameter() {
501     Modifiers modifiers = this->modifiersWithDefaults(Modifiers::kIn_Flag);
502     std::unique_ptr<ASTType> type = this->type();
503     if (!type) {
504         return nullptr;
505     }
506     Token name;
507     if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
508         return nullptr;
509     }
510     std::vector<int> sizes;
511     while (this->peek().fKind == Token::LBRACKET) {
512         this->nextToken();
513         Token sizeToken;
514         if (!this->expect(Token::INT_LITERAL, "a positive integer", &sizeToken)) {
515             return nullptr;
516         }
517         sizes.push_back(SkSL::stoi(sizeToken.fText));
518         if (!this->expect(Token::RBRACKET, "']'")) {
519             return nullptr;
520         }
521     }
522     return std::unique_ptr<ASTParameter>(new ASTParameter(name.fPosition, modifiers,
523                                                           std::move(type), name.fText,
524                                                           std::move(sizes)));
525 }
526 
527 /** (EQ INT_LITERAL)? */
layoutInt()528 int Parser::layoutInt() {
529     if (!this->expect(Token::EQ, "'='")) {
530         return -1;
531     }
532     Token resultToken;
533     if (this->expect(Token::INT_LITERAL, "a non-negative integer", &resultToken)) {
534         return SkSL::stoi(resultToken.fText);
535     }
536     return -1;
537 }
538 
539 /* LAYOUT LPAREN IDENTIFIER (EQ INT_LITERAL)? (COMMA IDENTIFIER (EQ INT_LITERAL)?)* RPAREN */
layout()540 Layout Parser::layout() {
541     int location = -1;
542     int offset = -1;
543     int binding = -1;
544     int index = -1;
545     int set = -1;
546     int builtin = -1;
547     int inputAttachmentIndex = -1;
548     bool originUpperLeft = false;
549     bool overrideCoverage = false;
550     bool blendSupportAllEquations = false;
551     Layout::Format format = Layout::Format::kUnspecified;
552     bool pushConstant = false;
553     Layout::Primitive primitive = Layout::kUnspecified_Primitive;
554     int maxVertices = -1;
555     int invocations = -1;
556     if (this->peek().fKind == Token::LAYOUT) {
557         this->nextToken();
558         if (!this->expect(Token::LPAREN, "'('")) {
559             return Layout(location, offset, binding, index, set, builtin, inputAttachmentIndex,
560                           originUpperLeft, overrideCoverage, blendSupportAllEquations, format,
561                           pushConstant, primitive, maxVertices, invocations);
562         }
563         for (;;) {
564             Token t = this->nextToken();
565             YY_BUFFER_STATE buffer;
566             buffer = layout_scan_string(t.fText.c_str(), fLayoutScanner);
567             int token = layoutlex(fLayoutScanner);
568             layout_delete_buffer(buffer, fLayoutScanner);
569             if (token != Token::INVALID_TOKEN) {
570                 switch (token) {
571                     case Token::LOCATION:
572                         location = this->layoutInt();
573                         break;
574                     case Token::OFFSET:
575                         offset = this->layoutInt();
576                         break;
577                     case Token::BINDING:
578                         binding = this->layoutInt();
579                         break;
580                     case Token::INDEX:
581                         index = this->layoutInt();
582                         break;
583                     case Token::SET:
584                         set = this->layoutInt();
585                         break;
586                     case Token::BUILTIN:
587                         builtin = this->layoutInt();
588                         break;
589                     case Token::INPUT_ATTACHMENT_INDEX:
590                         inputAttachmentIndex = this->layoutInt();
591                         break;
592                     case Token::ORIGIN_UPPER_LEFT:
593                         originUpperLeft = true;
594                         break;
595                     case Token::OVERRIDE_COVERAGE:
596                         overrideCoverage = true;
597                         break;
598                     case Token::BLEND_SUPPORT_ALL_EQUATIONS:
599                         blendSupportAllEquations = true;
600                         break;
601                     case Token::PUSH_CONSTANT:
602                         pushConstant = true;
603                         break;
604                     case Token::POINTS:
605                         primitive = Layout::kPoints_Primitive;
606                         break;
607                     case Token::LINES:
608                         primitive = Layout::kLines_Primitive;
609                         break;
610                     case Token::LINE_STRIP:
611                         primitive = Layout::kLineStrip_Primitive;
612                         break;
613                     case Token::LINES_ADJACENCY:
614                         primitive = Layout::kLinesAdjacency_Primitive;
615                         break;
616                     case Token::TRIANGLES:
617                         primitive = Layout::kTriangles_Primitive;
618                         break;
619                     case Token::TRIANGLE_STRIP:
620                         primitive = Layout::kTriangleStrip_Primitive;
621                         break;
622                     case Token::TRIANGLES_ADJACENCY:
623                         primitive = Layout::kTrianglesAdjacency_Primitive;
624                         break;
625                     case Token::MAX_VERTICES:
626                         maxVertices = this->layoutInt();
627                         break;
628                     case Token::INVOCATIONS:
629                         invocations = this->layoutInt();
630                         break;
631                 }
632             } else if (Layout::ReadFormat(t.fText, &format)) {
633                // AST::ReadFormat stored the result in 'format'.
634             } else {
635                 this->error(t.fPosition, ("'" + t.fText +
636                                           "' is not a valid layout qualifier").c_str());
637             }
638             if (this->peek().fKind == Token::RPAREN) {
639                 this->nextToken();
640                 break;
641             }
642             if (!this->expect(Token::COMMA, "','")) {
643                 break;
644             }
645         }
646     }
647     return Layout(location, offset, binding, index, set, builtin, inputAttachmentIndex,
648                   originUpperLeft, overrideCoverage, blendSupportAllEquations, format,
649                   pushConstant, primitive, maxVertices, invocations);
650 }
651 
652 /* layout? (UNIFORM | CONST | IN | OUT | INOUT | LOWP | MEDIUMP | HIGHP | FLAT | NOPERSPECTIVE |
653             READONLY | WRITEONLY | COHERENT | VOLATILE | RESTRICT)* */
modifiers()654 Modifiers Parser::modifiers() {
655     Layout layout = this->layout();
656     int flags = 0;
657     for (;;) {
658         // TODO: handle duplicate / incompatible flags
659         switch (peek().fKind) {
660             case Token::UNIFORM:
661                 this->nextToken();
662                 flags |= Modifiers::kUniform_Flag;
663                 break;
664             case Token::CONST:
665                 this->nextToken();
666                 flags |= Modifiers::kConst_Flag;
667                 break;
668             case Token::IN:
669                 this->nextToken();
670                 flags |= Modifiers::kIn_Flag;
671                 break;
672             case Token::OUT:
673                 this->nextToken();
674                 flags |= Modifiers::kOut_Flag;
675                 break;
676             case Token::INOUT:
677                 this->nextToken();
678                 flags |= Modifiers::kIn_Flag;
679                 flags |= Modifiers::kOut_Flag;
680                 break;
681             case Token::LOWP:
682                 this->nextToken();
683                 flags |= Modifiers::kLowp_Flag;
684                 break;
685             case Token::MEDIUMP:
686                 this->nextToken();
687                 flags |= Modifiers::kMediump_Flag;
688                 break;
689             case Token::HIGHP:
690                 this->nextToken();
691                 flags |= Modifiers::kHighp_Flag;
692                 break;
693             case Token::FLAT:
694                 this->nextToken();
695                 flags |= Modifiers::kFlat_Flag;
696                 break;
697             case Token::NOPERSPECTIVE:
698                 this->nextToken();
699                 flags |= Modifiers::kNoPerspective_Flag;
700                 break;
701             case Token::READONLY:
702                 this->nextToken();
703                 flags |= Modifiers::kReadOnly_Flag;
704                 break;
705             case Token::WRITEONLY:
706                 this->nextToken();
707                 flags |= Modifiers::kWriteOnly_Flag;
708                 break;
709             case Token::COHERENT:
710                 this->nextToken();
711                 flags |= Modifiers::kCoherent_Flag;
712                 break;
713             case Token::VOLATILE:
714                 this->nextToken();
715                 flags |= Modifiers::kVolatile_Flag;
716                 break;
717             case Token::RESTRICT:
718                 this->nextToken();
719                 flags |= Modifiers::kRestrict_Flag;
720                 break;
721             default:
722                 return Modifiers(layout, flags);
723         }
724     }
725 }
726 
modifiersWithDefaults(int defaultFlags)727 Modifiers Parser::modifiersWithDefaults(int defaultFlags) {
728     Modifiers result = this->modifiers();
729     if (!result.fFlags) {
730         return Modifiers(result.fLayout, defaultFlags);
731     }
732     return result;
733 }
734 
735 /* ifStatement | forStatement | doStatement | whileStatement | block | expression */
statement()736 std::unique_ptr<ASTStatement> Parser::statement() {
737     Token start = this->peek();
738     switch (start.fKind) {
739         case Token::IF:
740             return this->ifStatement();
741         case Token::FOR:
742             return this->forStatement();
743         case Token::DO:
744             return this->doStatement();
745         case Token::WHILE:
746             return this->whileStatement();
747         case Token::SWITCH:
748             return this->switchStatement();
749         case Token::RETURN:
750             return this->returnStatement();
751         case Token::BREAK:
752             return this->breakStatement();
753         case Token::CONTINUE:
754             return this->continueStatement();
755         case Token::DISCARD:
756             return this->discardStatement();
757         case Token::LBRACE:
758             return this->block();
759         case Token::SEMICOLON:
760             this->nextToken();
761             return std::unique_ptr<ASTStatement>(new ASTBlock(start.fPosition,
762                                                      std::vector<std::unique_ptr<ASTStatement>>()));
763         case Token::CONST:   // fall through
764         case Token::HIGHP:   // fall through
765         case Token::MEDIUMP: // fall through
766         case Token::LOWP: {
767             auto decl = this->varDeclarations();
768             if (!decl) {
769                 return nullptr;
770             }
771             return std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(std::move(decl)));
772         }
773         case Token::IDENTIFIER:
774             if (this->isType(start.fText)) {
775                 auto decl = this->varDeclarations();
776                 if (!decl) {
777                     return nullptr;
778                 }
779                 return std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
780                                                                                   std::move(decl)));
781             }
782             // fall through
783         default:
784             return this->expressionStatement();
785     }
786 }
787 
788 /* IDENTIFIER(type) (LBRACKET intLiteral? RBRACKET)* */
type()789 std::unique_ptr<ASTType> Parser::type() {
790     Token type;
791     if (!this->expect(Token::IDENTIFIER, "a type", &type)) {
792         return nullptr;
793     }
794     if (!this->isType(type.fText)) {
795         this->error(type.fPosition, ("no type named '" + type.fText + "'").c_str());
796         return nullptr;
797     }
798     std::vector<int> sizes;
799     while (this->peek().fKind == Token::LBRACKET) {
800         this->expect(Token::LBRACKET, "'['");
801         if (this->peek().fKind != Token::RBRACKET) {
802             int64_t i;
803             if (this->intLiteral(&i)) {
804                 sizes.push_back(i);
805             } else {
806                 return nullptr;
807             }
808         } else {
809             sizes.push_back(-1);
810         }
811         this->expect(Token::RBRACKET, "']'");
812     }
813     return std::unique_ptr<ASTType>(new ASTType(type.fPosition, std::move(type.fText),
814                                                 ASTType::kIdentifier_Kind, sizes));
815 }
816 
817 /* IDENTIFIER LBRACE varDeclaration* RBRACE (IDENTIFIER (LBRACKET expression? RBRACKET)*)? */
interfaceBlock(Modifiers mods)818 std::unique_ptr<ASTDeclaration> Parser::interfaceBlock(Modifiers mods) {
819     Token name;
820     if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
821         return nullptr;
822     }
823     if (peek().fKind != Token::LBRACE) {
824         // we only get into interfaceBlock if we found a top-level identifier which was not a type.
825         // 99% of the time, the user was not actually intending to create an interface block, so
826         // it's better to report it as an unknown type
827         this->error(name.fPosition, "no type named '" + name.fText + "'");
828         return nullptr;
829     }
830     this->nextToken();
831     std::vector<std::unique_ptr<ASTVarDeclarations>> decls;
832     while (this->peek().fKind != Token::RBRACE) {
833         std::unique_ptr<ASTVarDeclarations> decl = this->varDeclarations();
834         if (!decl) {
835             return nullptr;
836         }
837         decls.push_back(std::move(decl));
838     }
839     this->nextToken();
840     SkString instanceName;
841     std::vector<std::unique_ptr<ASTExpression>> sizes;
842     if (this->peek().fKind == Token::IDENTIFIER) {
843         instanceName = this->nextToken().fText;
844         while (this->peek().fKind == Token::LBRACKET) {
845             this->expect(Token::LBRACKET, "'['");
846             if (this->peek().fKind != Token::RBRACKET) {
847                 std::unique_ptr<ASTExpression> size = this->expression();
848                 if (!size) {
849                     return nullptr;
850                 }
851                 sizes.push_back(std::move(size));
852             } else {
853                 sizes.push_back(nullptr);
854             }
855             this->expect(Token::RBRACKET, "']'");
856         }
857     }
858     this->expect(Token::SEMICOLON, "';'");
859     return std::unique_ptr<ASTDeclaration>(new ASTInterfaceBlock(name.fPosition, mods,
860                                                                  name.fText, std::move(decls),
861                                                                  std::move(instanceName),
862                                                                  std::move(sizes)));
863 }
864 
865 /* IF LPAREN expression RPAREN statement (ELSE statement)? */
ifStatement()866 std::unique_ptr<ASTIfStatement> Parser::ifStatement() {
867     Token start;
868     if (!this->expect(Token::IF, "'if'", &start)) {
869         return nullptr;
870     }
871     if (!this->expect(Token::LPAREN, "'('")) {
872         return nullptr;
873     }
874     std::unique_ptr<ASTExpression> test(this->expression());
875     if (!test) {
876         return nullptr;
877     }
878     if (!this->expect(Token::RPAREN, "')'")) {
879         return nullptr;
880     }
881     std::unique_ptr<ASTStatement> ifTrue(this->statement());
882     if (!ifTrue) {
883         return nullptr;
884     }
885     std::unique_ptr<ASTStatement> ifFalse;
886     if (this->peek().fKind == Token::ELSE) {
887         this->nextToken();
888         ifFalse = this->statement();
889         if (!ifFalse) {
890             return nullptr;
891         }
892     }
893     return std::unique_ptr<ASTIfStatement>(new ASTIfStatement(start.fPosition, std::move(test),
894                                                               std::move(ifTrue),
895                                                               std::move(ifFalse)));
896 }
897 
898 /* DO statement WHILE LPAREN expression RPAREN SEMICOLON */
doStatement()899 std::unique_ptr<ASTDoStatement> Parser::doStatement() {
900     Token start;
901     if (!this->expect(Token::DO, "'do'", &start)) {
902         return nullptr;
903     }
904     std::unique_ptr<ASTStatement> statement(this->statement());
905     if (!statement) {
906         return nullptr;
907     }
908     if (!this->expect(Token::WHILE, "'while'")) {
909         return nullptr;
910     }
911     if (!this->expect(Token::LPAREN, "'('")) {
912         return nullptr;
913     }
914     std::unique_ptr<ASTExpression> test(this->expression());
915     if (!test) {
916         return nullptr;
917     }
918     if (!this->expect(Token::RPAREN, "')'")) {
919         return nullptr;
920     }
921     if (!this->expect(Token::SEMICOLON, "';'")) {
922         return nullptr;
923     }
924     return std::unique_ptr<ASTDoStatement>(new ASTDoStatement(start.fPosition,
925                                                               std::move(statement),
926                                                               std::move(test)));
927 }
928 
929 /* WHILE LPAREN expression RPAREN STATEMENT */
whileStatement()930 std::unique_ptr<ASTWhileStatement> Parser::whileStatement() {
931     Token start;
932     if (!this->expect(Token::WHILE, "'while'", &start)) {
933         return nullptr;
934     }
935     if (!this->expect(Token::LPAREN, "'('")) {
936         return nullptr;
937     }
938     std::unique_ptr<ASTExpression> test(this->expression());
939     if (!test) {
940         return nullptr;
941     }
942     if (!this->expect(Token::RPAREN, "')'")) {
943         return nullptr;
944     }
945     std::unique_ptr<ASTStatement> statement(this->statement());
946     if (!statement) {
947         return nullptr;
948     }
949     return std::unique_ptr<ASTWhileStatement>(new ASTWhileStatement(start.fPosition,
950                                                                     std::move(test),
951                                                                     std::move(statement)));
952 }
953 
954 /* CASE expression COLON statement* */
switchCase()955 std::unique_ptr<ASTSwitchCase> Parser::switchCase() {
956     Token start;
957     if (!this->expect(Token::CASE, "'case'", &start)) {
958         return nullptr;
959     }
960     std::unique_ptr<ASTExpression> value = this->expression();
961     if (!value) {
962         return nullptr;
963     }
964     if (!this->expect(Token::COLON, "':'")) {
965         return nullptr;
966     }
967     std::vector<std::unique_ptr<ASTStatement>> statements;
968     while (this->peek().fKind != Token::RBRACE && this->peek().fKind != Token::CASE &&
969            this->peek().fKind != Token::DEFAULT) {
970         std::unique_ptr<ASTStatement> s = this->statement();
971         if (!s) {
972             return nullptr;
973         }
974         statements.push_back(std::move(s));
975     }
976     return std::unique_ptr<ASTSwitchCase>(new ASTSwitchCase(start.fPosition, std::move(value),
977                                                             std::move(statements)));
978 }
979 
980 /* SWITCH LPAREN expression RPAREN LBRACE switchCase* (DEFAULT COLON statement*)? RBRACE */
switchStatement()981 std::unique_ptr<ASTStatement> Parser::switchStatement() {
982     Token start;
983     if (!this->expect(Token::SWITCH, "'switch'", &start)) {
984         return nullptr;
985     }
986     if (!this->expect(Token::LPAREN, "'('")) {
987         return nullptr;
988     }
989     std::unique_ptr<ASTExpression> value(this->expression());
990     if (!value) {
991         return nullptr;
992     }
993     if (!this->expect(Token::RPAREN, "')'")) {
994         return nullptr;
995     }
996     if (!this->expect(Token::LBRACE, "'{'")) {
997         return nullptr;
998     }
999     std::vector<std::unique_ptr<ASTSwitchCase>> cases;
1000     while (this->peek().fKind == Token::CASE) {
1001         std::unique_ptr<ASTSwitchCase> c = this->switchCase();
1002         if (!c) {
1003             return nullptr;
1004         }
1005         cases.push_back(std::move(c));
1006     }
1007     // Requiring default: to be last (in defiance of C and GLSL) was a deliberate decision. Other
1008     // parts of the compiler may rely upon this assumption.
1009     if (this->peek().fKind == Token::DEFAULT) {
1010         Token defaultStart;
1011         SkAssertResult(this->expect(Token::DEFAULT, "'default'", &defaultStart));
1012         if (!this->expect(Token::COLON, "':'")) {
1013             return nullptr;
1014         }
1015         std::vector<std::unique_ptr<ASTStatement>> statements;
1016         while (this->peek().fKind != Token::RBRACE) {
1017             std::unique_ptr<ASTStatement> s = this->statement();
1018             if (!s) {
1019                 return nullptr;
1020             }
1021             statements.push_back(std::move(s));
1022         }
1023         cases.emplace_back(new ASTSwitchCase(defaultStart.fPosition, nullptr,
1024                                              std::move(statements)));
1025     }
1026     if (!this->expect(Token::RBRACE, "'}'")) {
1027         return nullptr;
1028     }
1029     return std::unique_ptr<ASTStatement>(new ASTSwitchStatement(start.fPosition,
1030                                                                 std::move(value),
1031                                                                 std::move(cases)));
1032 }
1033 
1034 /* FOR LPAREN (declaration | expression)? SEMICOLON expression? SEMICOLON expression? RPAREN
1035    STATEMENT */
forStatement()1036 std::unique_ptr<ASTForStatement> Parser::forStatement() {
1037     Token start;
1038     if (!this->expect(Token::FOR, "'for'", &start)) {
1039         return nullptr;
1040     }
1041     if (!this->expect(Token::LPAREN, "'('")) {
1042         return nullptr;
1043     }
1044     std::unique_ptr<ASTStatement> initializer;
1045     Token nextToken = this->peek();
1046     switch (nextToken.fKind) {
1047         case Token::SEMICOLON:
1048             this->nextToken();
1049             break;
1050         case Token::CONST: {
1051             std::unique_ptr<ASTVarDeclarations> vd = this->varDeclarations();
1052             if (!vd) {
1053                 return nullptr;
1054             }
1055             initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
1056                                                                                     std::move(vd)));
1057             break;
1058         }
1059         case Token::IDENTIFIER: {
1060             if (this->isType(nextToken.fText)) {
1061                 std::unique_ptr<ASTVarDeclarations> vd = this->varDeclarations();
1062                 if (!vd) {
1063                     return nullptr;
1064                 }
1065                 initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
1066                                                                                     std::move(vd)));
1067                 break;
1068             }
1069         } // fall through
1070         default:
1071             initializer = this->expressionStatement();
1072     }
1073     std::unique_ptr<ASTExpression> test;
1074     if (this->peek().fKind != Token::SEMICOLON) {
1075         test = this->expression();
1076         if (!test) {
1077             return nullptr;
1078         }
1079     }
1080     if (!this->expect(Token::SEMICOLON, "';'")) {
1081         return nullptr;
1082     }
1083     std::unique_ptr<ASTExpression> next;
1084     if (this->peek().fKind != Token::RPAREN) {
1085         next = this->expression();
1086         if (!next) {
1087             return nullptr;
1088         }
1089     }
1090     if (!this->expect(Token::RPAREN, "')'")) {
1091         return nullptr;
1092     }
1093     std::unique_ptr<ASTStatement> statement(this->statement());
1094     if (!statement) {
1095         return nullptr;
1096     }
1097     return std::unique_ptr<ASTForStatement>(new ASTForStatement(start.fPosition,
1098                                                                 std::move(initializer),
1099                                                                 std::move(test), std::move(next),
1100                                                                 std::move(statement)));
1101 }
1102 
1103 /* RETURN expression? SEMICOLON */
returnStatement()1104 std::unique_ptr<ASTReturnStatement> Parser::returnStatement() {
1105     Token start;
1106     if (!this->expect(Token::RETURN, "'return'", &start)) {
1107         return nullptr;
1108     }
1109     std::unique_ptr<ASTExpression> expression;
1110     if (this->peek().fKind != Token::SEMICOLON) {
1111         expression = this->expression();
1112         if (!expression) {
1113             return nullptr;
1114         }
1115     }
1116     if (!this->expect(Token::SEMICOLON, "';'")) {
1117         return nullptr;
1118     }
1119     return std::unique_ptr<ASTReturnStatement>(new ASTReturnStatement(start.fPosition,
1120                                                                       std::move(expression)));
1121 }
1122 
1123 /* BREAK SEMICOLON */
breakStatement()1124 std::unique_ptr<ASTBreakStatement> Parser::breakStatement() {
1125     Token start;
1126     if (!this->expect(Token::BREAK, "'break'", &start)) {
1127         return nullptr;
1128     }
1129     if (!this->expect(Token::SEMICOLON, "';'")) {
1130         return nullptr;
1131     }
1132     return std::unique_ptr<ASTBreakStatement>(new ASTBreakStatement(start.fPosition));
1133 }
1134 
1135 /* CONTINUE SEMICOLON */
continueStatement()1136 std::unique_ptr<ASTContinueStatement> Parser::continueStatement() {
1137     Token start;
1138     if (!this->expect(Token::CONTINUE, "'continue'", &start)) {
1139         return nullptr;
1140     }
1141     if (!this->expect(Token::SEMICOLON, "';'")) {
1142         return nullptr;
1143     }
1144     return std::unique_ptr<ASTContinueStatement>(new ASTContinueStatement(start.fPosition));
1145 }
1146 
1147 /* DISCARD SEMICOLON */
discardStatement()1148 std::unique_ptr<ASTDiscardStatement> Parser::discardStatement() {
1149     Token start;
1150     if (!this->expect(Token::DISCARD, "'continue'", &start)) {
1151         return nullptr;
1152     }
1153     if (!this->expect(Token::SEMICOLON, "';'")) {
1154         return nullptr;
1155     }
1156     return std::unique_ptr<ASTDiscardStatement>(new ASTDiscardStatement(start.fPosition));
1157 }
1158 
1159 /* LBRACE statement* RBRACE */
block()1160 std::unique_ptr<ASTBlock> Parser::block() {
1161     AutoDepth depth(this);
1162     if (!depth.checkValid()) {
1163         return nullptr;
1164     }
1165     Token start;
1166     if (!this->expect(Token::LBRACE, "'{'", &start)) {
1167         return nullptr;
1168     }
1169     std::vector<std::unique_ptr<ASTStatement>> statements;
1170     for (;;) {
1171         switch (this->peek().fKind) {
1172             case Token::RBRACE:
1173                 this->nextToken();
1174                 return std::unique_ptr<ASTBlock>(new ASTBlock(start.fPosition,
1175                                                               std::move(statements)));
1176             case Token::END_OF_FILE:
1177                 this->error(this->peek().fPosition, "expected '}', but found end of file");
1178                 return nullptr;
1179             default: {
1180                 std::unique_ptr<ASTStatement> statement = this->statement();
1181                 if (!statement) {
1182                     return nullptr;
1183                 }
1184                 statements.push_back(std::move(statement));
1185             }
1186         }
1187     }
1188 }
1189 
1190 /* expression SEMICOLON */
expressionStatement()1191 std::unique_ptr<ASTExpressionStatement> Parser::expressionStatement() {
1192     std::unique_ptr<ASTExpression> expr = this->expression();
1193     if (expr) {
1194         if (this->expect(Token::SEMICOLON, "';'")) {
1195             ASTExpressionStatement* result = new ASTExpressionStatement(std::move(expr));
1196             return std::unique_ptr<ASTExpressionStatement>(result);
1197         }
1198     }
1199     return nullptr;
1200 }
1201 
1202 /* assignmentExpression */
expression()1203 std::unique_ptr<ASTExpression> Parser::expression() {
1204     AutoDepth depth(this);
1205     if (!depth.checkValid()) {
1206         return nullptr;
1207     }
1208     return this->assignmentExpression();
1209 }
1210 
1211 /* ternaryExpression ((EQEQ | STAREQ | SLASHEQ | PERCENTEQ | PLUSEQ | MINUSEQ | SHLEQ | SHREQ |
1212    BITWISEANDEQ | BITWISEXOREQ | BITWISEOREQ | LOGICALANDEQ | LOGICALXOREQ | LOGICALOREQ)
1213    assignmentExpression)*
1214  */
assignmentExpression()1215 std::unique_ptr<ASTExpression> Parser::assignmentExpression() {
1216     std::unique_ptr<ASTExpression> result = this->ternaryExpression();
1217     if (!result) {
1218         return nullptr;
1219     }
1220     for (;;) {
1221         switch (this->peek().fKind) {
1222             case Token::EQ:           // fall through
1223             case Token::STAREQ:       // fall through
1224             case Token::SLASHEQ:      // fall through
1225             case Token::PERCENTEQ:    // fall through
1226             case Token::PLUSEQ:       // fall through
1227             case Token::MINUSEQ:      // fall through
1228             case Token::SHLEQ:        // fall through
1229             case Token::SHREQ:        // fall through
1230             case Token::BITWISEANDEQ: // fall through
1231             case Token::BITWISEXOREQ: // fall through
1232             case Token::BITWISEOREQ:  // fall through
1233             case Token::LOGICALANDEQ: // fall through
1234             case Token::LOGICALXOREQ: // fall through
1235             case Token::LOGICALOREQ: {
1236                 Token t = this->nextToken();
1237                 std::unique_ptr<ASTExpression> right = this->assignmentExpression();
1238                 if (!right) {
1239                     return nullptr;
1240                 }
1241                 result = std::unique_ptr<ASTExpression>(new ASTBinaryExpression(std::move(result),
1242                                                                                 t,
1243                                                                                 std::move(right)));
1244             }
1245             default:
1246                 return result;
1247         }
1248     }
1249 }
1250 
1251 /* logicalOrExpression ('?' expression ':' assignmentExpression)? */
ternaryExpression()1252 std::unique_ptr<ASTExpression> Parser::ternaryExpression() {
1253     std::unique_ptr<ASTExpression> result = this->logicalOrExpression();
1254     if (!result) {
1255         return nullptr;
1256     }
1257     if (this->peek().fKind == Token::QUESTION) {
1258         Token question = this->nextToken();
1259         std::unique_ptr<ASTExpression> trueExpr = this->expression();
1260         if (!trueExpr) {
1261             return nullptr;
1262         }
1263         if (this->expect(Token::COLON, "':'")) {
1264             std::unique_ptr<ASTExpression> falseExpr = this->assignmentExpression();
1265             return std::unique_ptr<ASTExpression>(new ASTTernaryExpression(std::move(result),
1266                                                                            std::move(trueExpr),
1267                                                                            std::move(falseExpr)));
1268         }
1269         return nullptr;
1270     }
1271     return result;
1272 }
1273 
1274 /* logicalXorExpression (LOGICALOR logicalXorExpression)* */
logicalOrExpression()1275 std::unique_ptr<ASTExpression> Parser::logicalOrExpression() {
1276     std::unique_ptr<ASTExpression> result = this->logicalXorExpression();
1277     if (!result) {
1278         return nullptr;
1279     }
1280     while (this->peek().fKind == Token::LOGICALOR) {
1281         Token t = this->nextToken();
1282         std::unique_ptr<ASTExpression> right = this->logicalXorExpression();
1283         if (!right) {
1284             return nullptr;
1285         }
1286         result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1287     }
1288     return result;
1289 }
1290 
1291 /* logicalAndExpression (LOGICALXOR logicalAndExpression)* */
logicalXorExpression()1292 std::unique_ptr<ASTExpression> Parser::logicalXorExpression() {
1293     std::unique_ptr<ASTExpression> result = this->logicalAndExpression();
1294     if (!result) {
1295         return nullptr;
1296     }
1297     while (this->peek().fKind == Token::LOGICALXOR) {
1298         Token t = this->nextToken();
1299         std::unique_ptr<ASTExpression> right = this->logicalAndExpression();
1300         if (!right) {
1301             return nullptr;
1302         }
1303         result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1304     }
1305     return result;
1306 }
1307 
1308 /* bitwiseOrExpression (LOGICALAND bitwiseOrExpression)* */
logicalAndExpression()1309 std::unique_ptr<ASTExpression> Parser::logicalAndExpression() {
1310     std::unique_ptr<ASTExpression> result = this->bitwiseOrExpression();
1311     if (!result) {
1312         return nullptr;
1313     }
1314     while (this->peek().fKind == Token::LOGICALAND) {
1315         Token t = this->nextToken();
1316         std::unique_ptr<ASTExpression> right = this->bitwiseOrExpression();
1317         if (!right) {
1318             return nullptr;
1319         }
1320         result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1321     }
1322     return result;
1323 }
1324 
1325 /* bitwiseXorExpression (BITWISEOR bitwiseXorExpression)* */
bitwiseOrExpression()1326 std::unique_ptr<ASTExpression> Parser::bitwiseOrExpression() {
1327     std::unique_ptr<ASTExpression> result = this->bitwiseXorExpression();
1328     if (!result) {
1329         return nullptr;
1330     }
1331     while (this->peek().fKind == Token::BITWISEOR) {
1332         Token t = this->nextToken();
1333         std::unique_ptr<ASTExpression> right = this->bitwiseXorExpression();
1334         if (!right) {
1335             return nullptr;
1336         }
1337         result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1338     }
1339     return result;
1340 }
1341 
1342 /* bitwiseAndExpression (BITWISEXOR bitwiseAndExpression)* */
bitwiseXorExpression()1343 std::unique_ptr<ASTExpression> Parser::bitwiseXorExpression() {
1344     std::unique_ptr<ASTExpression> result = this->bitwiseAndExpression();
1345     if (!result) {
1346         return nullptr;
1347     }
1348     while (this->peek().fKind == Token::BITWISEXOR) {
1349         Token t = this->nextToken();
1350         std::unique_ptr<ASTExpression> right = this->bitwiseAndExpression();
1351         if (!right) {
1352             return nullptr;
1353         }
1354         result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1355     }
1356     return result;
1357 }
1358 
1359 /* equalityExpression (BITWISEAND equalityExpression)* */
bitwiseAndExpression()1360 std::unique_ptr<ASTExpression> Parser::bitwiseAndExpression() {
1361     std::unique_ptr<ASTExpression> result = this->equalityExpression();
1362     if (!result) {
1363         return nullptr;
1364     }
1365     while (this->peek().fKind == Token::BITWISEAND) {
1366         Token t = this->nextToken();
1367         std::unique_ptr<ASTExpression> right = this->equalityExpression();
1368         if (!right) {
1369             return nullptr;
1370         }
1371         result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1372     }
1373     return result;
1374 }
1375 
1376 /* relationalExpression ((EQEQ | NEQ) relationalExpression)* */
equalityExpression()1377 std::unique_ptr<ASTExpression> Parser::equalityExpression() {
1378     std::unique_ptr<ASTExpression> result = this->relationalExpression();
1379     if (!result) {
1380         return nullptr;
1381     }
1382     for (;;) {
1383         switch (this->peek().fKind) {
1384             case Token::EQEQ:   // fall through
1385             case Token::NEQ: {
1386                 Token t = this->nextToken();
1387                 std::unique_ptr<ASTExpression> right = this->relationalExpression();
1388                 if (!right) {
1389                     return nullptr;
1390                 }
1391                 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1392                 break;
1393             }
1394             default:
1395                 return result;
1396         }
1397     }
1398 }
1399 
1400 /* shiftExpression ((LT | GT | LTEQ | GTEQ) shiftExpression)* */
relationalExpression()1401 std::unique_ptr<ASTExpression> Parser::relationalExpression() {
1402     std::unique_ptr<ASTExpression> result = this->shiftExpression();
1403     if (!result) {
1404         return nullptr;
1405     }
1406     for (;;) {
1407         switch (this->peek().fKind) {
1408             case Token::LT:   // fall through
1409             case Token::GT:   // fall through
1410             case Token::LTEQ: // fall through
1411             case Token::GTEQ: {
1412                 Token t = this->nextToken();
1413                 std::unique_ptr<ASTExpression> right = this->shiftExpression();
1414                 if (!right) {
1415                     return nullptr;
1416                 }
1417                 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1418                 break;
1419             }
1420             default:
1421                 return result;
1422         }
1423     }
1424 }
1425 
1426 /* additiveExpression ((SHL | SHR) additiveExpression)* */
shiftExpression()1427 std::unique_ptr<ASTExpression> Parser::shiftExpression() {
1428     std::unique_ptr<ASTExpression> result = this->additiveExpression();
1429     if (!result) {
1430         return nullptr;
1431     }
1432     for (;;) {
1433         switch (this->peek().fKind) {
1434             case Token::SHL: // fall through
1435             case Token::SHR: {
1436                 Token t = this->nextToken();
1437                 std::unique_ptr<ASTExpression> right = this->additiveExpression();
1438                 if (!right) {
1439                     return nullptr;
1440                 }
1441                 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1442                 break;
1443             }
1444             default:
1445                 return result;
1446         }
1447     }
1448 }
1449 
1450 /* multiplicativeExpression ((PLUS | MINUS) multiplicativeExpression)* */
additiveExpression()1451 std::unique_ptr<ASTExpression> Parser::additiveExpression() {
1452     std::unique_ptr<ASTExpression> result = this->multiplicativeExpression();
1453     if (!result) {
1454         return nullptr;
1455     }
1456     for (;;) {
1457         switch (this->peek().fKind) {
1458             case Token::PLUS: // fall through
1459             case Token::MINUS: {
1460                 Token t = this->nextToken();
1461                 std::unique_ptr<ASTExpression> right = this->multiplicativeExpression();
1462                 if (!right) {
1463                     return nullptr;
1464                 }
1465                 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1466                 break;
1467             }
1468             default:
1469                 return result;
1470         }
1471     }
1472 }
1473 
1474 /* unaryExpression ((STAR | SLASH | PERCENT) unaryExpression)* */
multiplicativeExpression()1475 std::unique_ptr<ASTExpression> Parser::multiplicativeExpression() {
1476     std::unique_ptr<ASTExpression> result = this->unaryExpression();
1477     if (!result) {
1478         return nullptr;
1479     }
1480     for (;;) {
1481         switch (this->peek().fKind) {
1482             case Token::STAR: // fall through
1483             case Token::SLASH: // fall through
1484             case Token::PERCENT: {
1485                 Token t = this->nextToken();
1486                 std::unique_ptr<ASTExpression> right = this->unaryExpression();
1487                 if (!right) {
1488                     return nullptr;
1489                 }
1490                 result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
1491                 break;
1492             }
1493             default:
1494                 return result;
1495         }
1496     }
1497 }
1498 
1499 /* postfixExpression | (PLUS | MINUS | NOT | PLUSPLUS | MINUSMINUS) unaryExpression */
unaryExpression()1500 std::unique_ptr<ASTExpression> Parser::unaryExpression() {
1501     switch (this->peek().fKind) {
1502         case Token::PLUS:       // fall through
1503         case Token::MINUS:      // fall through
1504         case Token::LOGICALNOT: // fall through
1505         case Token::BITWISENOT: // fall through
1506         case Token::PLUSPLUS:   // fall through
1507         case Token::MINUSMINUS: {
1508             Token t = this->nextToken();
1509             std::unique_ptr<ASTExpression> expr = this->unaryExpression();
1510             if (!expr) {
1511                 return nullptr;
1512             }
1513             return std::unique_ptr<ASTExpression>(new ASTPrefixExpression(t, std::move(expr)));
1514         }
1515         default:
1516             return this->postfixExpression();
1517     }
1518 }
1519 
1520 /* term suffix* */
postfixExpression()1521 std::unique_ptr<ASTExpression> Parser::postfixExpression() {
1522     std::unique_ptr<ASTExpression> result = this->term();
1523     if (!result) {
1524         return nullptr;
1525     }
1526     for (;;) {
1527         switch (this->peek().fKind) {
1528             case Token::LBRACKET: // fall through
1529             case Token::DOT:      // fall through
1530             case Token::LPAREN:   // fall through
1531             case Token::PLUSPLUS: // fall through
1532             case Token::MINUSMINUS: {
1533                 std::unique_ptr<ASTSuffix> s = this->suffix();
1534                 if (!s) {
1535                     return nullptr;
1536                 }
1537                 result.reset(new ASTSuffixExpression(std::move(result), std::move(s)));
1538                 break;
1539             }
1540             default:
1541                 return result;
1542         }
1543     }
1544 }
1545 
1546 /* LBRACKET expression? RBRACKET | DOT IDENTIFIER | LPAREN parameters RPAREN |
1547    PLUSPLUS | MINUSMINUS */
suffix()1548 std::unique_ptr<ASTSuffix> Parser::suffix() {
1549     Token next = this->nextToken();
1550     switch (next.fKind) {
1551         case Token::LBRACKET: {
1552             if (this->peek().fKind == Token::RBRACKET) {
1553                 this->nextToken();
1554                 return std::unique_ptr<ASTSuffix>(new ASTIndexSuffix(next.fPosition));
1555             }
1556             std::unique_ptr<ASTExpression> e = this->expression();
1557             if (!e) {
1558                 return nullptr;
1559             }
1560             this->expect(Token::RBRACKET, "']' to complete array access expression");
1561             return std::unique_ptr<ASTSuffix>(new ASTIndexSuffix(std::move(e)));
1562         }
1563         case Token::DOT: {
1564             Position pos = this->peek().fPosition;
1565             SkString text;
1566             if (this->identifier(&text)) {
1567                 return std::unique_ptr<ASTSuffix>(new ASTFieldSuffix(pos, std::move(text)));
1568             }
1569             return nullptr;
1570         }
1571         case Token::LPAREN: {
1572             std::vector<std::unique_ptr<ASTExpression>> parameters;
1573             if (this->peek().fKind != Token::RPAREN) {
1574                 for (;;) {
1575                     std::unique_ptr<ASTExpression> expr = this->expression();
1576                     if (!expr) {
1577                         return nullptr;
1578                     }
1579                     parameters.push_back(std::move(expr));
1580                     if (this->peek().fKind != Token::COMMA) {
1581                         break;
1582                     }
1583                     this->nextToken();
1584                 }
1585             }
1586             this->expect(Token::RPAREN, "')' to complete function parameters");
1587             return std::unique_ptr<ASTSuffix>(new ASTCallSuffix(next.fPosition,
1588                                                                 std::move(parameters)));
1589         }
1590         case Token::PLUSPLUS:
1591             return std::unique_ptr<ASTSuffix>(new ASTSuffix(next.fPosition,
1592                                                             ASTSuffix::kPostIncrement_Kind));
1593         case Token::MINUSMINUS:
1594             return std::unique_ptr<ASTSuffix>(new ASTSuffix(next.fPosition,
1595                                                             ASTSuffix::kPostDecrement_Kind));
1596         default: {
1597             this->error(next.fPosition,  "expected expression suffix, but found '" + next.fText +
1598                                          "'\n");
1599             return nullptr;
1600         }
1601     }
1602 }
1603 
1604 /* IDENTIFIER | intLiteral | floatLiteral | boolLiteral | '(' expression ')' */
term()1605 std::unique_ptr<ASTExpression> Parser::term() {
1606     std::unique_ptr<ASTExpression> result;
1607     Token t = this->peek();
1608     switch (t.fKind) {
1609         case Token::IDENTIFIER: {
1610             SkString text;
1611             if (this->identifier(&text)) {
1612                 result.reset(new ASTIdentifier(t.fPosition, std::move(text)));
1613             }
1614             break;
1615         }
1616         case Token::INT_LITERAL: {
1617             int64_t i;
1618             if (this->intLiteral(&i)) {
1619                 result.reset(new ASTIntLiteral(t.fPosition, i));
1620             }
1621             break;
1622         }
1623         case Token::FLOAT_LITERAL: {
1624             double f;
1625             if (this->floatLiteral(&f)) {
1626                 result.reset(new ASTFloatLiteral(t.fPosition, f));
1627             }
1628             break;
1629         }
1630         case Token::TRUE_LITERAL: // fall through
1631         case Token::FALSE_LITERAL: {
1632             bool b;
1633             if (this->boolLiteral(&b)) {
1634                 result.reset(new ASTBoolLiteral(t.fPosition, b));
1635             }
1636             break;
1637         }
1638         case Token::LPAREN: {
1639             this->nextToken();
1640             result = this->expression();
1641             if (result) {
1642                 this->expect(Token::RPAREN, "')' to complete expression");
1643             }
1644             break;
1645         }
1646         default:
1647             this->nextToken();
1648             this->error(t.fPosition,  "expected expression, but found '" + t.fText + "'\n");
1649             result = nullptr;
1650     }
1651     return result;
1652 }
1653 
1654 /* INT_LITERAL */
intLiteral(int64_t * dest)1655 bool Parser::intLiteral(int64_t* dest) {
1656     Token t;
1657     if (this->expect(Token::INT_LITERAL, "integer literal", &t)) {
1658         *dest = SkSL::stol(t.fText);
1659         return true;
1660     }
1661     return false;
1662 }
1663 
1664 /* FLOAT_LITERAL */
floatLiteral(double * dest)1665 bool Parser::floatLiteral(double* dest) {
1666     Token t;
1667     if (this->expect(Token::FLOAT_LITERAL, "float literal", &t)) {
1668         *dest = SkSL::stod(t.fText);
1669         return true;
1670     }
1671     return false;
1672 }
1673 
1674 /* TRUE_LITERAL | FALSE_LITERAL */
boolLiteral(bool * dest)1675 bool Parser::boolLiteral(bool* dest) {
1676     Token t = this->nextToken();
1677     switch (t.fKind) {
1678         case Token::TRUE_LITERAL:
1679             *dest = true;
1680             return true;
1681         case Token::FALSE_LITERAL:
1682             *dest = false;
1683             return true;
1684         default:
1685             this->error(t.fPosition, "expected 'true' or 'false', but found '" + t.fText + "'\n");
1686             return false;
1687     }
1688 }
1689 
1690 /* IDENTIFIER */
identifier(SkString * dest)1691 bool Parser::identifier(SkString* dest) {
1692     Token t;
1693     if (this->expect(Token::IDENTIFIER, "identifier", &t)) {
1694         *dest = t.fText;
1695         return true;
1696     }
1697     return false;
1698 }
1699 
1700 } // namespace
1701