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