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