Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "stdio.h" | 8 #include "stdio.h" |
| 9 #include "SkSLParser.h" | 9 #include "SkSLParser.h" |
| 10 #include "SkSLToken.h" | 10 #include "SkSLToken.h" |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 267 return std::unique_ptr<ASTDeclaration>(new ASTFunction(name.fPosition, s td::move(type), | 267 return std::unique_ptr<ASTDeclaration>(new ASTFunction(name.fPosition, s td::move(type), |
| 268 std::move(name.fT ext), | 268 std::move(name.fT ext), |
| 269 std::move(paramet ers), | 269 std::move(paramet ers), |
| 270 std::move(body))) ; | 270 std::move(body))) ; |
| 271 } else { | 271 } else { |
| 272 return this->varDeclarationEnd(modifiers, std::move(type), name.fText); | 272 return this->varDeclarationEnd(modifiers, std::move(type), name.fText); |
| 273 } | 273 } |
| 274 } | 274 } |
| 275 | 275 |
| 276 /* modifiers type IDENTIFIER varDeclarationEnd */ | 276 /* modifiers type IDENTIFIER varDeclarationEnd */ |
| 277 std::unique_ptr<ASTVarDeclaration> Parser::varDeclaration() { | 277 std::unique_ptr<ASTVarDeclarations> Parser::varDeclarations() { |
| 278 ASTModifiers modifiers = this->modifiers(); | 278 ASTModifiers modifiers = this->modifiers(); |
| 279 std::unique_ptr<ASTType> type(this->type()); | 279 std::unique_ptr<ASTType> type(this->type()); |
| 280 if (!type) { | 280 if (!type) { |
| 281 return nullptr; | 281 return nullptr; |
| 282 } | 282 } |
| 283 Token name; | 283 Token name; |
| 284 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) { | 284 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) { |
| 285 return nullptr; | 285 return nullptr; |
| 286 } | 286 } |
| 287 return this->varDeclarationEnd(modifiers, std::move(type), std::move(name.fT ext)); | 287 return this->varDeclarationEnd(modifiers, std::move(type), std::move(name.fT ext)); |
| 288 } | 288 } |
| 289 | 289 |
| 290 /* STRUCT IDENTIFIER LBRACE varDeclaration* RBRACE */ | 290 /* STRUCT IDENTIFIER LBRACE varDeclaration* RBRACE */ |
| 291 std::unique_ptr<ASTType> Parser::structDeclaration() { | 291 std::unique_ptr<ASTType> Parser::structDeclaration() { |
| 292 if (!this->expect(Token::STRUCT, "'struct'")) { | 292 if (!this->expect(Token::STRUCT, "'struct'")) { |
| 293 return nullptr; | 293 return nullptr; |
| 294 } | 294 } |
| 295 Token name; | 295 Token name; |
| 296 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) { | 296 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) { |
| 297 return nullptr; | 297 return nullptr; |
| 298 } | 298 } |
| 299 if (!this->expect(Token::LBRACE, "'{'")) { | 299 if (!this->expect(Token::LBRACE, "'{'")) { |
| 300 return nullptr; | 300 return nullptr; |
| 301 } | 301 } |
| 302 std::vector<Type::Field> fields; | 302 std::vector<Type::Field> fields; |
| 303 while (this->peek().fKind != Token::RBRACE) { | 303 while (this->peek().fKind != Token::RBRACE) { |
| 304 std::unique_ptr<ASTVarDeclaration> decl = this->varDeclaration(); | 304 std::unique_ptr<ASTVarDeclarations> decl = this->varDeclarations(); |
| 305 if (!decl) { | 305 if (!decl) { |
| 306 return nullptr; | 306 return nullptr; |
| 307 } | 307 } |
| 308 for (size_t i = 0; i < decl->fNames.size(); i++) { | 308 for (const auto& var : decl->fVars) { |
| 309 auto type = (const Type*) fTypes[decl->fType->fName]; | 309 auto type = (const Type*) fTypes[decl->fType->fName]; |
| 310 for (int j = (int) decl->fSizes[i].size() - 1; j >= 0; j--) { | 310 for (int i = (int) var.fSizes.size() - 1; i >= 0; i--) { |
| 311 if (decl->fSizes[i][j]->fKind != ASTExpression::kInt_Kind) { | 311 if (var.fSizes[i]->fKind != ASTExpression::kInt_Kind) { |
| 312 this->error(decl->fPosition, "array size in struct field mus t be a constant"); | 312 this->error(decl->fPosition, "array size in struct field mus t be a constant"); |
| 313 } | 313 } |
| 314 uint64_t columns = ((ASTIntLiteral&) *decl->fSizes[i][j]).fValue ; | 314 uint64_t columns = ((ASTIntLiteral&) *var.fSizes[i]).fValue; |
| 315 std::string name = type->name() + "[" + to_string(columns) + "]" ; | 315 std::string name = type->name() + "[" + to_string(columns) + "]" ; |
| 316 type = new Type(name, Type::kArray_Kind, *type, (int) columns); | 316 type = new Type(name, Type::kArray_Kind, *type, (int) columns); |
| 317 fTypes.takeOwnership((Type*) type); | 317 fTypes.takeOwnership((Type*) type); |
| 318 } | 318 } |
| 319 fields.push_back(Type::Field(decl->fModifiers, decl->fNames[i], type )); | 319 fields.push_back(Type::Field(decl->fModifiers, var.fName, type)); |
| 320 if (decl->fValues[i]) { | 320 if (var.fValue) { |
| 321 this->error(decl->fPosition, "initializers are not permitted on struct fields"); | 321 this->error(decl->fPosition, "initializers are not permitted on struct fields"); |
| 322 } | 322 } |
| 323 } | 323 } |
| 324 } | 324 } |
| 325 if (!this->expect(Token::RBRACE, "'}'")) { | 325 if (!this->expect(Token::RBRACE, "'}'")) { |
| 326 return nullptr; | 326 return nullptr; |
| 327 } | 327 } |
| 328 fTypes.add(name.fText, std::unique_ptr<Type>(new Type(name.fText, fields))); | 328 fTypes.add(name.fText, std::unique_ptr<Type>(new Type(name.fText, fields))); |
| 329 return std::unique_ptr<ASTType>(new ASTType(name.fPosition, name.fText, | 329 return std::unique_ptr<ASTType>(new ASTType(name.fPosition, name.fText, |
| 330 ASTType::kStruct_Kind)); | 330 ASTType::kStruct_Kind)); |
| 331 } | 331 } |
| 332 | 332 |
| 333 /* structDeclaration ((IDENTIFIER varDeclarationEnd) | SEMICOLON) */ | 333 /* structDeclaration ((IDENTIFIER varDeclarationEnd) | SEMICOLON) */ |
| 334 std::unique_ptr<ASTVarDeclaration> Parser::structVarDeclaration(ASTModifiers mod ifiers) { | 334 std::unique_ptr<ASTVarDeclarations> Parser::structVarDeclaration(ASTModifiers mo difiers) { |
| 335 std::unique_ptr<ASTType> type = this->structDeclaration(); | 335 std::unique_ptr<ASTType> type = this->structDeclaration(); |
| 336 if (!type) { | 336 if (!type) { |
| 337 return nullptr; | 337 return nullptr; |
| 338 } | 338 } |
| 339 if (peek().fKind == Token::IDENTIFIER) { | 339 if (peek().fKind == Token::IDENTIFIER) { |
| 340 Token name = this->nextToken(); | 340 Token name = this->nextToken(); |
| 341 std::unique_ptr<ASTVarDeclaration> result = this->varDeclarationEnd(modi fiers, | 341 std::unique_ptr<ASTVarDeclarations> result = this->varDeclarationEnd(mod ifiers, |
| 342 std: :move(type), | 342 std ::move(type), |
| 343 std: :move(name.fText)); | 343 std ::move(name.fText)); |
| 344 if (result) { | 344 if (result) { |
| 345 for (size_t i = 0; i < result->fValues.size(); i++) { | 345 for (const auto& var : result->fVars) { |
| 346 if (result->fValues[i]) { | 346 if (var.fValue) { |
| 347 this->error(result->fValues[i]->fPosition, | 347 this->error(var.fValue->fPosition, |
| 348 "struct variables cannot be initialized"); | 348 "struct variables cannot be initialized"); |
| 349 } | 349 } |
| 350 } | 350 } |
| 351 } | 351 } |
| 352 return result; | 352 return result; |
| 353 } | 353 } |
| 354 this->expect(Token::SEMICOLON, "';'"); | 354 this->expect(Token::SEMICOLON, "';'"); |
| 355 return nullptr; | 355 return nullptr; |
| 356 } | 356 } |
| 357 | 357 |
| 358 /* (LBRACKET expression? RBRACKET)* (EQ expression)? (COMMA IDENTIFER | 358 /* (LBRACKET expression? RBRACKET)* (EQ expression)? (COMMA IDENTIFER |
| 359 (LBRACKET expression? RBRACKET)* (EQ expression)?)* SEMICOLON */ | 359 (LBRACKET expression? RBRACKET)* (EQ expression)?)* SEMICOLON */ |
| 360 std::unique_ptr<ASTVarDeclaration> Parser::varDeclarationEnd(ASTModifiers mods, | 360 std::unique_ptr<ASTVarDeclarations> Parser::varDeclarationEnd(ASTModifiers mods, |
| 361 std::unique_ptr<AST Type> type, | 361 std::unique_ptr<AS TType> type, |
| 362 std::string name) { | 362 std::string name) { |
| 363 std::vector<std::string> names; | 363 std::vector<ASTVarDeclaration> vars; |
| 364 std::vector<std::vector<std::unique_ptr<ASTExpression>>> sizes; | |
| 365 names.push_back(name); | |
| 366 std::vector<std::unique_ptr<ASTExpression>> currentVarSizes; | 364 std::vector<std::unique_ptr<ASTExpression>> currentVarSizes; |
| 367 while (this->peek().fKind == Token::LBRACKET) { | 365 while (this->peek().fKind == Token::LBRACKET) { |
| 368 this->nextToken(); | 366 this->nextToken(); |
| 369 if (this->peek().fKind == Token::RBRACKET) { | 367 if (this->peek().fKind == Token::RBRACKET) { |
| 370 this->nextToken(); | 368 this->nextToken(); |
| 371 currentVarSizes.push_back(nullptr); | 369 //currentVarSizes->push_back(nullptr); |
|
dogben
2016/09/07 17:35:42
Why is this commented out?
ethannicholas
2016/09/07 19:46:38
That was an accident, oops.
| |
| 372 } else { | 370 } else { |
| 373 std::unique_ptr<ASTExpression> size(this->expression()); | 371 std::unique_ptr<ASTExpression> size(this->expression()); |
| 374 if (!size) { | 372 if (!size) { |
| 375 return nullptr; | 373 return nullptr; |
| 376 } | 374 } |
| 377 currentVarSizes.push_back(std::move(size)); | 375 currentVarSizes.push_back(std::move(size)); |
| 378 if (!this->expect(Token::RBRACKET, "']'")) { | 376 if (!this->expect(Token::RBRACKET, "']'")) { |
| 379 return nullptr; | 377 return nullptr; |
| 380 } | 378 } |
| 381 } | 379 } |
| 382 } | 380 } |
| 383 sizes.push_back(std::move(currentVarSizes)); | 381 std::unique_ptr<ASTExpression> value; |
| 384 std::vector<std::unique_ptr<ASTExpression>> values; | |
| 385 if (this->peek().fKind == Token::EQ) { | 382 if (this->peek().fKind == Token::EQ) { |
| 386 this->nextToken(); | 383 this->nextToken(); |
| 387 std::unique_ptr<ASTExpression> value(this->expression()); | 384 value = this->expression(); |
| 388 if (!value) { | 385 if (!value) { |
| 389 return nullptr; | 386 return nullptr; |
| 390 } | 387 } |
| 391 values.push_back(std::move(value)); | |
| 392 } else { | |
| 393 values.push_back(nullptr); | |
| 394 } | 388 } |
| 389 vars.emplace_back(std::move(name), std::move(currentVarSizes), std::move(val ue)); | |
| 395 while (this->peek().fKind == Token::COMMA) { | 390 while (this->peek().fKind == Token::COMMA) { |
| 396 this->nextToken(); | 391 this->nextToken(); |
| 397 Token name; | 392 Token name; |
| 398 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) { | 393 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) { |
| 399 return nullptr; | 394 return nullptr; |
| 400 } | 395 } |
| 401 names.push_back(name.fText); | |
| 402 currentVarSizes.clear(); | 396 currentVarSizes.clear(); |
| 403 while (this->peek().fKind == Token::LBRACKET) { | 397 while (this->peek().fKind == Token::LBRACKET) { |
| 404 this->nextToken(); | 398 this->nextToken(); |
| 405 if (this->peek().fKind == Token::RBRACKET) { | 399 if (this->peek().fKind == Token::RBRACKET) { |
| 406 this->nextToken(); | 400 this->nextToken(); |
| 407 currentVarSizes.push_back(nullptr); | 401 currentVarSizes.push_back(nullptr); |
| 408 } else { | 402 } else { |
| 409 std::unique_ptr<ASTExpression> size(this->expression()); | 403 std::unique_ptr<ASTExpression> size(this->expression()); |
| 410 if (!size) { | 404 if (!size) { |
| 411 return nullptr; | 405 return nullptr; |
| 412 } | 406 } |
| 413 currentVarSizes.push_back(std::move(size)); | 407 currentVarSizes.push_back(std::move(size)); |
| 414 if (!this->expect(Token::RBRACKET, "']'")) { | 408 if (!this->expect(Token::RBRACKET, "']'")) { |
| 415 return nullptr; | 409 return nullptr; |
| 416 } | 410 } |
| 417 } | 411 } |
| 418 } | 412 } |
| 419 sizes.push_back(std::move(currentVarSizes)); | |
| 420 if (this->peek().fKind == Token::EQ) { | 413 if (this->peek().fKind == Token::EQ) { |
| 421 this->nextToken(); | 414 this->nextToken(); |
| 422 std::unique_ptr<ASTExpression> value(this->expression()); | 415 value = this->expression(); |
| 423 if (!value) { | 416 if (!value) { |
| 424 return nullptr; | 417 return nullptr; |
| 425 } | 418 } |
| 426 values.push_back(std::move(value)); | |
| 427 } else { | 419 } else { |
| 428 values.push_back(nullptr); | 420 value.release(); |
|
dogben
2016/09/07 17:35:42
1. This should be reset, not release.
2. nit: move
ethannicholas
2016/09/07 19:46:38
Done.
| |
| 429 } | 421 } |
| 422 vars.emplace_back(std::move(name.fText), std::move(currentVarSizes), std ::move(value)); | |
| 430 } | 423 } |
| 431 if (!this->expect(Token::SEMICOLON, "';'")) { | 424 if (!this->expect(Token::SEMICOLON, "';'")) { |
| 432 return nullptr; | 425 return nullptr; |
| 433 } | 426 } |
| 434 return std::unique_ptr<ASTVarDeclaration>(new ASTVarDeclaration(std::move(mo ds), | 427 return std::unique_ptr<ASTVarDeclarations>(new ASTVarDeclarations(std::move( mods), |
| 435 std::move(ty pe), | 428 std::move( type), |
| 436 std::move(na mes), | 429 std::move( vars))); |
| 437 std::move(si zes), | |
| 438 std::move(va lues))); | |
| 439 } | 430 } |
| 440 | 431 |
| 441 /* modifiers type IDENTIFIER (LBRACKET INT_LITERAL RBRACKET)? */ | 432 /* modifiers type IDENTIFIER (LBRACKET INT_LITERAL RBRACKET)? */ |
| 442 std::unique_ptr<ASTParameter> Parser::parameter() { | 433 std::unique_ptr<ASTParameter> Parser::parameter() { |
| 443 ASTModifiers modifiers = this->modifiersWithDefaults(ASTModifiers::kIn_Flag) ; | 434 ASTModifiers modifiers = this->modifiersWithDefaults(ASTModifiers::kIn_Flag) ; |
| 444 std::unique_ptr<ASTType> type = this->type(); | 435 std::unique_ptr<ASTType> type = this->type(); |
| 445 if (!type) { | 436 if (!type) { |
| 446 return nullptr; | 437 return nullptr; |
| 447 } | 438 } |
| 448 Token name; | 439 Token name; |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 607 case Token::LBRACE: | 598 case Token::LBRACE: |
| 608 return this->block(); | 599 return this->block(); |
| 609 case Token::SEMICOLON: | 600 case Token::SEMICOLON: |
| 610 this->nextToken(); | 601 this->nextToken(); |
| 611 return std::unique_ptr<ASTStatement>(new ASTBlock(start.fPosition, | 602 return std::unique_ptr<ASTStatement>(new ASTBlock(start.fPosition, |
| 612 std::vector<std::unique_ptr <ASTStatement>>())); | 603 std::vector<std::unique_ptr <ASTStatement>>())); |
| 613 case Token::CONST: // fall through | 604 case Token::CONST: // fall through |
| 614 case Token::HIGHP: // fall through | 605 case Token::HIGHP: // fall through |
| 615 case Token::MEDIUMP: // fall through | 606 case Token::MEDIUMP: // fall through |
| 616 case Token::LOWP: { | 607 case Token::LOWP: { |
| 617 auto decl = this->varDeclaration(); | 608 auto decl = this->varDeclarations(); |
| 618 if (!decl) { | 609 if (!decl) { |
| 619 return nullptr; | 610 return nullptr; |
| 620 } | 611 } |
| 621 return std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement( std::move(decl))); | 612 return std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement( std::move(decl))); |
| 622 } | 613 } |
| 623 case Token::IDENTIFIER: | 614 case Token::IDENTIFIER: |
| 624 if (this->isType(start.fText)) { | 615 if (this->isType(start.fText)) { |
| 625 auto decl = this->varDeclaration(); | 616 auto decl = this->varDeclarations(); |
| 626 if (!decl) { | 617 if (!decl) { |
| 627 return nullptr; | 618 return nullptr; |
| 628 } | 619 } |
| 629 return std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatem ent( | 620 return std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatem ent( |
| 630 std::move(decl))); | 621 std::move(decl))); |
| 631 } | 622 } |
| 632 // fall through | 623 // fall through |
| 633 default: | 624 default: |
| 634 return this->expressionStatement(); | 625 return this->expressionStatement(); |
| 635 } | 626 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 656 return nullptr; | 647 return nullptr; |
| 657 } | 648 } |
| 658 if (peek().fKind != Token::LBRACE) { | 649 if (peek().fKind != Token::LBRACE) { |
| 659 // we only get into interfaceBlock if we found a top-level identifier wh ich was not a type. | 650 // we only get into interfaceBlock if we found a top-level identifier wh ich was not a type. |
| 660 // 99% of the time, the user was not actually intending to create an int erface block, so | 651 // 99% of the time, the user was not actually intending to create an int erface block, so |
| 661 // it's better to report it as an unknown type | 652 // it's better to report it as an unknown type |
| 662 this->error(name.fPosition, "no type named '" + name.fText + "'"); | 653 this->error(name.fPosition, "no type named '" + name.fText + "'"); |
| 663 return nullptr; | 654 return nullptr; |
| 664 } | 655 } |
| 665 this->nextToken(); | 656 this->nextToken(); |
| 666 std::vector<std::unique_ptr<ASTVarDeclaration>> decls; | 657 std::vector<std::unique_ptr<ASTVarDeclarations>> decls; |
| 667 while (this->peek().fKind != Token::RBRACE) { | 658 while (this->peek().fKind != Token::RBRACE) { |
| 668 std::unique_ptr<ASTVarDeclaration> decl = this->varDeclaration(); | 659 std::unique_ptr<ASTVarDeclarations> decl = this->varDeclarations(); |
| 669 if (!decl) { | 660 if (!decl) { |
| 670 return nullptr; | 661 return nullptr; |
| 671 } | 662 } |
| 672 decls.push_back(std::move(decl)); | 663 decls.push_back(std::move(decl)); |
| 673 } | 664 } |
| 674 this->nextToken(); | 665 this->nextToken(); |
| 675 std::string valueName; | 666 std::string valueName; |
| 676 if (this->peek().fKind == Token::IDENTIFIER) { | 667 if (this->peek().fKind == Token::IDENTIFIER) { |
| 677 valueName = this->nextToken().fText; | 668 valueName = this->nextToken().fText; |
| 678 } | 669 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 781 if (!this->expect(Token::LPAREN, "'('")) { | 772 if (!this->expect(Token::LPAREN, "'('")) { |
| 782 return nullptr; | 773 return nullptr; |
| 783 } | 774 } |
| 784 std::unique_ptr<ASTStatement> initializer; | 775 std::unique_ptr<ASTStatement> initializer; |
| 785 Token nextToken = this->peek(); | 776 Token nextToken = this->peek(); |
| 786 switch (nextToken.fKind) { | 777 switch (nextToken.fKind) { |
| 787 case Token::SEMICOLON: | 778 case Token::SEMICOLON: |
| 788 break; | 779 break; |
| 789 case Token::CONST: | 780 case Token::CONST: |
| 790 initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationSta tement( | 781 initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationSta tement( |
| 791 this- >varDeclaration())); | 782 this-> varDeclarations())); |
| 792 break; | 783 break; |
| 793 case Token::IDENTIFIER: | 784 case Token::IDENTIFIER: |
| 794 if (this->isType(nextToken.fText)) { | 785 if (this->isType(nextToken.fText)) { |
| 795 initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclaratio nStatement( | 786 initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclaratio nStatement( |
| 796 this- >varDeclaration())); | 787 this-> varDeclarations())); |
| 797 break; | 788 break; |
| 798 } | 789 } |
| 799 // fall through | 790 // fall through |
| 800 default: | 791 default: |
| 801 initializer = this->expressionStatement(); | 792 initializer = this->expressionStatement(); |
| 802 } | 793 } |
| 803 std::unique_ptr<ASTExpression> test; | 794 std::unique_ptr<ASTExpression> test; |
| 804 if (this->peek().fKind != Token::SEMICOLON) { | 795 if (this->peek().fKind != Token::SEMICOLON) { |
| 805 test = this->expression(); | 796 test = this->expression(); |
| 806 if (!test) { | 797 if (!test) { |
| (...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1408 bool Parser::identifier(std::string* dest) { | 1399 bool Parser::identifier(std::string* dest) { |
| 1409 Token t; | 1400 Token t; |
| 1410 if (this->expect(Token::IDENTIFIER, "identifier", &t)) { | 1401 if (this->expect(Token::IDENTIFIER, "identifier", &t)) { |
| 1411 *dest = t.fText; | 1402 *dest = t.fText; |
| 1412 return true; | 1403 return true; |
| 1413 } | 1404 } |
| 1414 return false; | 1405 return false; |
| 1415 } | 1406 } |
| 1416 | 1407 |
| 1417 } // namespace | 1408 } // namespace |
| OLD | NEW |