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); |
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(); |
| 397 value.reset(); |
403 while (this->peek().fKind == Token::LBRACKET) { | 398 while (this->peek().fKind == Token::LBRACKET) { |
404 this->nextToken(); | 399 this->nextToken(); |
405 if (this->peek().fKind == Token::RBRACKET) { | 400 if (this->peek().fKind == Token::RBRACKET) { |
406 this->nextToken(); | 401 this->nextToken(); |
407 currentVarSizes.push_back(nullptr); | 402 currentVarSizes.push_back(nullptr); |
408 } else { | 403 } else { |
409 std::unique_ptr<ASTExpression> size(this->expression()); | 404 std::unique_ptr<ASTExpression> size(this->expression()); |
410 if (!size) { | 405 if (!size) { |
411 return nullptr; | 406 return nullptr; |
412 } | 407 } |
413 currentVarSizes.push_back(std::move(size)); | 408 currentVarSizes.push_back(std::move(size)); |
414 if (!this->expect(Token::RBRACKET, "']'")) { | 409 if (!this->expect(Token::RBRACKET, "']'")) { |
415 return nullptr; | 410 return nullptr; |
416 } | 411 } |
417 } | 412 } |
418 } | 413 } |
419 sizes.push_back(std::move(currentVarSizes)); | |
420 if (this->peek().fKind == Token::EQ) { | 414 if (this->peek().fKind == Token::EQ) { |
421 this->nextToken(); | 415 this->nextToken(); |
422 std::unique_ptr<ASTExpression> value(this->expression()); | 416 value = this->expression(); |
423 if (!value) { | 417 if (!value) { |
424 return nullptr; | 418 return nullptr; |
425 } | 419 } |
426 values.push_back(std::move(value)); | |
427 } else { | |
428 values.push_back(nullptr); | |
429 } | 420 } |
| 421 vars.emplace_back(std::move(name.fText), std::move(currentVarSizes), std
::move(value)); |
430 } | 422 } |
431 if (!this->expect(Token::SEMICOLON, "';'")) { | 423 if (!this->expect(Token::SEMICOLON, "';'")) { |
432 return nullptr; | 424 return nullptr; |
433 } | 425 } |
434 return std::unique_ptr<ASTVarDeclaration>(new ASTVarDeclaration(std::move(mo
ds), | 426 return std::unique_ptr<ASTVarDeclarations>(new ASTVarDeclarations(std::move(
mods), |
435 std::move(ty
pe), | 427 std::move(
type), |
436 std::move(na
mes), | 428 std::move(
vars))); |
437 std::move(si
zes), | |
438 std::move(va
lues))); | |
439 } | 429 } |
440 | 430 |
441 /* modifiers type IDENTIFIER (LBRACKET INT_LITERAL RBRACKET)? */ | 431 /* modifiers type IDENTIFIER (LBRACKET INT_LITERAL RBRACKET)? */ |
442 std::unique_ptr<ASTParameter> Parser::parameter() { | 432 std::unique_ptr<ASTParameter> Parser::parameter() { |
443 ASTModifiers modifiers = this->modifiersWithDefaults(ASTModifiers::kIn_Flag)
; | 433 ASTModifiers modifiers = this->modifiersWithDefaults(ASTModifiers::kIn_Flag)
; |
444 std::unique_ptr<ASTType> type = this->type(); | 434 std::unique_ptr<ASTType> type = this->type(); |
445 if (!type) { | 435 if (!type) { |
446 return nullptr; | 436 return nullptr; |
447 } | 437 } |
448 Token name; | 438 Token name; |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 case Token::LBRACE: | 597 case Token::LBRACE: |
608 return this->block(); | 598 return this->block(); |
609 case Token::SEMICOLON: | 599 case Token::SEMICOLON: |
610 this->nextToken(); | 600 this->nextToken(); |
611 return std::unique_ptr<ASTStatement>(new ASTBlock(start.fPosition, | 601 return std::unique_ptr<ASTStatement>(new ASTBlock(start.fPosition, |
612 std::vector<std::unique_ptr
<ASTStatement>>())); | 602 std::vector<std::unique_ptr
<ASTStatement>>())); |
613 case Token::CONST: // fall through | 603 case Token::CONST: // fall through |
614 case Token::HIGHP: // fall through | 604 case Token::HIGHP: // fall through |
615 case Token::MEDIUMP: // fall through | 605 case Token::MEDIUMP: // fall through |
616 case Token::LOWP: { | 606 case Token::LOWP: { |
617 auto decl = this->varDeclaration(); | 607 auto decl = this->varDeclarations(); |
618 if (!decl) { | 608 if (!decl) { |
619 return nullptr; | 609 return nullptr; |
620 } | 610 } |
621 return std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
std::move(decl))); | 611 return std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
std::move(decl))); |
622 } | 612 } |
623 case Token::IDENTIFIER: | 613 case Token::IDENTIFIER: |
624 if (this->isType(start.fText)) { | 614 if (this->isType(start.fText)) { |
625 auto decl = this->varDeclaration(); | 615 auto decl = this->varDeclarations(); |
626 if (!decl) { | 616 if (!decl) { |
627 return nullptr; | 617 return nullptr; |
628 } | 618 } |
629 return std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatem
ent( | 619 return std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatem
ent( |
630
std::move(decl))); | 620
std::move(decl))); |
631 } | 621 } |
632 // fall through | 622 // fall through |
633 default: | 623 default: |
634 return this->expressionStatement(); | 624 return this->expressionStatement(); |
635 } | 625 } |
(...skipping 20 matching lines...) Expand all Loading... |
656 return nullptr; | 646 return nullptr; |
657 } | 647 } |
658 if (peek().fKind != Token::LBRACE) { | 648 if (peek().fKind != Token::LBRACE) { |
659 // we only get into interfaceBlock if we found a top-level identifier wh
ich was not a type. | 649 // 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 | 650 // 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 | 651 // it's better to report it as an unknown type |
662 this->error(name.fPosition, "no type named '" + name.fText + "'"); | 652 this->error(name.fPosition, "no type named '" + name.fText + "'"); |
663 return nullptr; | 653 return nullptr; |
664 } | 654 } |
665 this->nextToken(); | 655 this->nextToken(); |
666 std::vector<std::unique_ptr<ASTVarDeclaration>> decls; | 656 std::vector<std::unique_ptr<ASTVarDeclarations>> decls; |
667 while (this->peek().fKind != Token::RBRACE) { | 657 while (this->peek().fKind != Token::RBRACE) { |
668 std::unique_ptr<ASTVarDeclaration> decl = this->varDeclaration(); | 658 std::unique_ptr<ASTVarDeclarations> decl = this->varDeclarations(); |
669 if (!decl) { | 659 if (!decl) { |
670 return nullptr; | 660 return nullptr; |
671 } | 661 } |
672 decls.push_back(std::move(decl)); | 662 decls.push_back(std::move(decl)); |
673 } | 663 } |
674 this->nextToken(); | 664 this->nextToken(); |
675 std::string valueName; | 665 std::string valueName; |
676 if (this->peek().fKind == Token::IDENTIFIER) { | 666 if (this->peek().fKind == Token::IDENTIFIER) { |
677 valueName = this->nextToken().fText; | 667 valueName = this->nextToken().fText; |
678 } | 668 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
781 if (!this->expect(Token::LPAREN, "'('")) { | 771 if (!this->expect(Token::LPAREN, "'('")) { |
782 return nullptr; | 772 return nullptr; |
783 } | 773 } |
784 std::unique_ptr<ASTStatement> initializer; | 774 std::unique_ptr<ASTStatement> initializer; |
785 Token nextToken = this->peek(); | 775 Token nextToken = this->peek(); |
786 switch (nextToken.fKind) { | 776 switch (nextToken.fKind) { |
787 case Token::SEMICOLON: | 777 case Token::SEMICOLON: |
788 break; | 778 break; |
789 case Token::CONST: | 779 case Token::CONST: |
790 initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationSta
tement( | 780 initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationSta
tement( |
791 this-
>varDeclaration())); | 781 this->
varDeclarations())); |
792 break; | 782 break; |
793 case Token::IDENTIFIER: | 783 case Token::IDENTIFIER: |
794 if (this->isType(nextToken.fText)) { | 784 if (this->isType(nextToken.fText)) { |
795 initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclaratio
nStatement( | 785 initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclaratio
nStatement( |
796 this-
>varDeclaration())); | 786 this->
varDeclarations())); |
797 break; | 787 break; |
798 } | 788 } |
799 // fall through | 789 // fall through |
800 default: | 790 default: |
801 initializer = this->expressionStatement(); | 791 initializer = this->expressionStatement(); |
802 } | 792 } |
803 std::unique_ptr<ASTExpression> test; | 793 std::unique_ptr<ASTExpression> test; |
804 if (this->peek().fKind != Token::SEMICOLON) { | 794 if (this->peek().fKind != Token::SEMICOLON) { |
805 test = this->expression(); | 795 test = this->expression(); |
806 if (!test) { | 796 if (!test) { |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1408 bool Parser::identifier(std::string* dest) { | 1398 bool Parser::identifier(std::string* dest) { |
1409 Token t; | 1399 Token t; |
1410 if (this->expect(Token::IDENTIFIER, "identifier", &t)) { | 1400 if (this->expect(Token::IDENTIFIER, "identifier", &t)) { |
1411 *dest = t.fText; | 1401 *dest = t.fText; |
1412 return true; | 1402 return true; |
1413 } | 1403 } |
1414 return false; | 1404 return false; |
1415 } | 1405 } |
1416 | 1406 |
1417 } // namespace | 1407 } // namespace |
OLD | NEW |