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