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