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 |