Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/sksl/SkSLParser.cpp

Issue 2312233002: refactored SkSL VarDeclaration handling (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698