Mercurial > projects > dil
comparison trunk/src/dil/parser/Parser.d @ 679:ff6971637f88
Renamed Token member type to kind.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Fri, 18 Jan 2008 23:40:12 +0100 |
parents | 118971211c4c |
children | 6b3e397229c5 |
comparison
equal
deleted
inserted
replaced
678:cedfc67faabf | 679:ff6971637f88 |
---|---|
76 Declarations start() | 76 Declarations start() |
77 { | 77 { |
78 init(); | 78 init(); |
79 auto begin = token; | 79 auto begin = token; |
80 auto decls = new Declarations; | 80 auto decls = new Declarations; |
81 if (token.type == T.Module) | 81 if (token.kind == T.Module) |
82 decls ~= parseModuleDeclaration(); | 82 decls ~= parseModuleDeclaration(); |
83 decls.addOptChildren(parseDeclarationDefinitions()); | 83 decls.addOptChildren(parseDeclarationDefinitions()); |
84 set(decls, begin); | 84 set(decls, begin); |
85 return decls; | 85 return decls; |
86 } | 86 } |
146 { | 146 { |
147 Token* next = token; | 147 Token* next = token; |
148 do | 148 do |
149 lexer.peek(next); | 149 lexer.peek(next); |
150 while (next.isWhitespace) // Skip whitespace | 150 while (next.isWhitespace) // Skip whitespace |
151 return next.type; | 151 return next.kind; |
152 } | 152 } |
153 | 153 |
154 TOK peekAfter(ref Token* next) | 154 TOK peekAfter(ref Token* next) |
155 { | 155 { |
156 assert(next !is null); | 156 assert(next !is null); |
157 do | 157 do |
158 lexer.peek(next); | 158 lexer.peek(next); |
159 while (next.isWhitespace) // Skip whitespace | 159 while (next.isWhitespace) // Skip whitespace |
160 return next.type; | 160 return next.kind; |
161 } | 161 } |
162 | 162 |
163 /// Skips the current token if its type matches tok and returns true. | 163 /// Skips the current token if its type matches tok and returns true. |
164 bool skipped()(TOK tok) // Templatized, so it's inlined. | 164 bool skipped()(TOK tok) // Templatized, so it's inlined. |
165 { | 165 { |
166 return token.type == tok ? (nT(), true) : false; | 166 return token.kind == tok ? (nT(), true) : false; |
167 } | 167 } |
168 | 168 |
169 /++++++++++++++++++++++++++++++ | 169 /++++++++++++++++++++++++++++++ |
170 + Declaration parsing methods + | 170 + Declaration parsing methods + |
171 ++++++++++++++++++++++++++++++/ | 171 ++++++++++++++++++++++++++++++/ |
172 | 172 |
173 Declaration parseModuleDeclaration() | 173 Declaration parseModuleDeclaration() |
174 { | 174 { |
175 assert(token.type == T.Module); | 175 assert(token.kind == T.Module); |
176 auto begin = token; | 176 auto begin = token; |
177 ModuleFQN moduleFQN; | 177 ModuleFQN moduleFQN; |
178 do | 178 do |
179 { | 179 { |
180 nT(); | 180 nT(); |
181 moduleFQN ~= requireIdentifier(MSG.ExpectedModuleIdentifier); | 181 moduleFQN ~= requireIdentifier(MSG.ExpectedModuleIdentifier); |
182 } while (token.type == T.Dot) | 182 } while (token.kind == T.Dot) |
183 require(T.Semicolon); | 183 require(T.Semicolon); |
184 return set(new ModuleDeclaration(moduleFQN), begin); | 184 return set(new ModuleDeclaration(moduleFQN), begin); |
185 } | 185 } |
186 | 186 |
187 /++ | 187 /++ |
191 DeclDefs | 191 DeclDefs |
192 +/ | 192 +/ |
193 Declaration[] parseDeclarationDefinitions() | 193 Declaration[] parseDeclarationDefinitions() |
194 { | 194 { |
195 Declaration[] decls; | 195 Declaration[] decls; |
196 while (token.type != T.EOF) | 196 while (token.kind != T.EOF) |
197 decls ~= parseDeclarationDefinition(); | 197 decls ~= parseDeclarationDefinition(); |
198 return decls; | 198 return decls; |
199 } | 199 } |
200 | 200 |
201 /++ | 201 /++ |
217 | 217 |
218 // Parse body. | 218 // Parse body. |
219 auto begin = token; | 219 auto begin = token; |
220 auto decls = new Declarations; | 220 auto decls = new Declarations; |
221 require(T.LBrace); | 221 require(T.LBrace); |
222 while (token.type != T.RBrace && token.type != T.EOF) | 222 while (token.kind != T.RBrace && token.kind != T.EOF) |
223 decls ~= parseDeclarationDefinition(); | 223 decls ~= parseDeclarationDefinition(); |
224 require(T.RBrace); | 224 require(T.RBrace); |
225 set(decls, begin); | 225 set(decls, begin); |
226 | 226 |
227 // Restore original values. | 227 // Restore original values. |
237 { assert(isNodeSet(decl)); } | 237 { assert(isNodeSet(decl)); } |
238 body | 238 body |
239 { | 239 { |
240 auto begin = token; | 240 auto begin = token; |
241 Declaration decl; | 241 Declaration decl; |
242 switch (token.type) | 242 switch (token.kind) |
243 { | 243 { |
244 case T.Align, | 244 case T.Align, |
245 T.Pragma, | 245 T.Pragma, |
246 // Protection attributes | 246 // Protection attributes |
247 T.Export, | 247 T.Export, |
364 case_Declaration: | 364 case_Declaration: |
365 return parseVariableOrFunction(this.storageClass, this.protection, this.linkageType); | 365 return parseVariableOrFunction(this.storageClass, this.protection, this.linkageType); |
366 default: | 366 default: |
367 if (token.isIntegralType) | 367 if (token.isIntegralType) |
368 goto case_Declaration; | 368 goto case_Declaration; |
369 else if (token.type == T.Module) | 369 else if (token.kind == T.Module) |
370 { | 370 { |
371 decl = parseModuleDeclaration(); | 371 decl = parseModuleDeclaration(); |
372 error(begin, MSG.ModuleDeclarationNotFirst); | 372 error(begin, MSG.ModuleDeclarationNotFirst); |
373 return decl; | 373 return decl; |
374 } | 374 } |
376 decl = new IllegalDeclaration(); | 376 decl = new IllegalDeclaration(); |
377 // Skip to next valid token. | 377 // Skip to next valid token. |
378 do | 378 do |
379 nT(); | 379 nT(); |
380 while (!token.isDeclDefStart && | 380 while (!token.isDeclDefStart && |
381 token.type != T.RBrace && | 381 token.kind != T.RBrace && |
382 token.type != T.EOF) | 382 token.kind != T.EOF) |
383 auto text = Token.textSpan(begin, this.prevToken); | 383 auto text = Token.textSpan(begin, this.prevToken); |
384 error(begin, MSG.IllegalDeclaration, text); | 384 error(begin, MSG.IllegalDeclaration, text); |
385 } | 385 } |
386 decl.setProtection(this.protection); | 386 decl.setProtection(this.protection); |
387 decl.setStorageClass(this.storageClass); | 387 decl.setStorageClass(this.storageClass); |
398 DeclDef | 398 DeclDef |
399 +/ | 399 +/ |
400 Declaration parseDeclarationsBlock(bool noColon = false) | 400 Declaration parseDeclarationsBlock(bool noColon = false) |
401 { | 401 { |
402 Declaration d; | 402 Declaration d; |
403 switch (token.type) | 403 switch (token.kind) |
404 { | 404 { |
405 case T.LBrace: | 405 case T.LBrace: |
406 auto begin = token; | 406 auto begin = token; |
407 nT(); | 407 nT(); |
408 auto decls = new Declarations; | 408 auto decls = new Declarations; |
409 while (token.type != T.RBrace && token.type != T.EOF) | 409 while (token.kind != T.RBrace && token.kind != T.EOF) |
410 decls ~= parseDeclarationDefinition(); | 410 decls ~= parseDeclarationDefinition(); |
411 require(T.RBrace); | 411 require(T.RBrace); |
412 d = set(decls, begin); | 412 d = set(decls, begin); |
413 break; | 413 break; |
414 case T.Colon: | 414 case T.Colon: |
415 if (noColon == true) | 415 if (noColon == true) |
416 goto default; | 416 goto default; |
417 nT(); | 417 nT(); |
418 auto begin = token; | 418 auto begin = token; |
419 auto decls = new Declarations; | 419 auto decls = new Declarations; |
420 while (token.type != T.RBrace && token.type != T.EOF) | 420 while (token.kind != T.RBrace && token.kind != T.EOF) |
421 decls ~= parseDeclarationDefinition(); | 421 decls ~= parseDeclarationDefinition(); |
422 d = set(decls, begin); | 422 d = set(decls, begin); |
423 break; | 423 break; |
424 default: | 424 default: |
425 d = parseDeclarationDefinition(); | 425 d = parseDeclarationDefinition(); |
452 Type type; | 452 Type type; |
453 Identifier* ident; | 453 Identifier* ident; |
454 | 454 |
455 // Check for AutoDeclaration: StorageClasses Identifier = | 455 // Check for AutoDeclaration: StorageClasses Identifier = |
456 if (testAutoDeclaration && | 456 if (testAutoDeclaration && |
457 token.type == T.Identifier && | 457 token.kind == T.Identifier && |
458 peekNext() == T.Assign) | 458 peekNext() == T.Assign) |
459 { | 459 { |
460 ident = token.ident; | 460 ident = token.ident; |
461 nT(); | 461 nT(); |
462 } | 462 } |
463 else | 463 else |
464 { | 464 { |
465 type = parseType(); // VariableType or ReturnType | 465 type = parseType(); // VariableType or ReturnType |
466 if (token.type == T.LParen) | 466 if (token.kind == T.LParen) |
467 { | 467 { |
468 // C-style function pointers make the grammar ambiguous. | 468 // C-style function pointers make the grammar ambiguous. |
469 // We have to treat them specially at function scope. | 469 // We have to treat them specially at function scope. |
470 // Example: | 470 // Example: |
471 // void foo() { | 471 // void foo() { |
480 } | 480 } |
481 else if (peekNext() == T.LParen) | 481 else if (peekNext() == T.LParen) |
482 { // Type FunctionName ( ParameterList ) FunctionBody | 482 { // Type FunctionName ( ParameterList ) FunctionBody |
483 ident = requireIdentifier(MSG.ExpectedFunctionName); | 483 ident = requireIdentifier(MSG.ExpectedFunctionName); |
484 ident || nT(); // Skip non-identifier token. | 484 ident || nT(); // Skip non-identifier token. |
485 assert(token.type == T.LParen); | 485 assert(token.kind == T.LParen); |
486 // It's a function declaration | 486 // It's a function declaration |
487 TemplateParameters tparams; | 487 TemplateParameters tparams; |
488 if (tokenAfterParenIs(T.LParen)) | 488 if (tokenAfterParenIs(T.LParen)) |
489 { | 489 { |
490 // ( TemplateParameterList ) ( ParameterList ) | 490 // ( TemplateParameterList ) ( ParameterList ) |
492 } | 492 } |
493 | 493 |
494 auto params = parseParameterList(); | 494 auto params = parseParameterList(); |
495 version(D2) | 495 version(D2) |
496 { | 496 { |
497 switch (token.type) | 497 switch (token.kind) |
498 { | 498 { |
499 case T.Const: | 499 case T.Const: |
500 stc |= StorageClass.Const; | 500 stc |= StorageClass.Const; |
501 nT(); | 501 nT(); |
502 break; | 502 break; |
525 | 525 |
526 // It's a variable declaration. | 526 // It's a variable declaration. |
527 Identifier*[] idents = [ident]; | 527 Identifier*[] idents = [ident]; |
528 Expression[] values; | 528 Expression[] values; |
529 goto LenterLoop; // We've already parsed an identifier. Jump to if statement and check for initializer. | 529 goto LenterLoop; // We've already parsed an identifier. Jump to if statement and check for initializer. |
530 while (token.type == T.Comma) | 530 while (token.kind == T.Comma) |
531 { | 531 { |
532 nT(); | 532 nT(); |
533 idents ~= requireIdentifier(MSG.ExpectedVariableName); | 533 idents ~= requireIdentifier(MSG.ExpectedVariableName); |
534 LenterLoop: | 534 LenterLoop: |
535 if (skipped(T.Assign)) | 535 if (skipped(T.Assign)) |
545 return set(d, begin); | 545 return set(d, begin); |
546 } | 546 } |
547 | 547 |
548 Expression parseInitializer() | 548 Expression parseInitializer() |
549 { | 549 { |
550 if (token.type == T.Void) | 550 if (token.kind == T.Void) |
551 { | 551 { |
552 auto begin = token; | 552 auto begin = token; |
553 auto next = peekNext(); | 553 auto next = peekNext(); |
554 if (next == T.Comma || next == T.Semicolon) | 554 if (next == T.Comma || next == T.Semicolon) |
555 { | 555 { |
562 | 562 |
563 Expression parseNonVoidInitializer() | 563 Expression parseNonVoidInitializer() |
564 { | 564 { |
565 auto begin = token; | 565 auto begin = token; |
566 Expression init; | 566 Expression init; |
567 switch (token.type) | 567 switch (token.kind) |
568 { | 568 { |
569 case T.LBracket: | 569 case T.LBracket: |
570 // ArrayInitializer: | 570 // ArrayInitializer: |
571 // [ ] | 571 // [ ] |
572 // [ ArrayMemberInitializations ] | 572 // [ ArrayMemberInitializations ] |
573 Expression[] keys; | 573 Expression[] keys; |
574 Expression[] values; | 574 Expression[] values; |
575 | 575 |
576 nT(); | 576 nT(); |
577 while (token.type != T.RBracket) | 577 while (token.kind != T.RBracket) |
578 { | 578 { |
579 auto e = parseNonVoidInitializer(); | 579 auto e = parseNonVoidInitializer(); |
580 if (skipped(T.Colon)) | 580 if (skipped(T.Colon)) |
581 { | 581 { |
582 keys ~= e; | 582 keys ~= e; |
586 { | 586 { |
587 keys ~= null; | 587 keys ~= null; |
588 values ~= e; | 588 values ~= e; |
589 } | 589 } |
590 | 590 |
591 if (token.type != T.Comma) | 591 if (token.kind != T.Comma) |
592 break; | 592 break; |
593 nT(); | 593 nT(); |
594 } | 594 } |
595 require(T.RBracket); | 595 require(T.RBracket); |
596 init = new ArrayInitializer(keys, values); | 596 init = new ArrayInitializer(keys, values); |
603 { | 603 { |
604 Identifier*[] idents; | 604 Identifier*[] idents; |
605 Expression[] values; | 605 Expression[] values; |
606 | 606 |
607 nT(); | 607 nT(); |
608 while (token.type != T.RBrace) | 608 while (token.kind != T.RBrace) |
609 { | 609 { |
610 if (token.type == T.Identifier && | 610 if (token.kind == T.Identifier && |
611 // Peek for colon to see if this is a member identifier. | 611 // Peek for colon to see if this is a member identifier. |
612 peekNext() == T.Colon) | 612 peekNext() == T.Colon) |
613 { | 613 { |
614 idents ~= token.ident; | 614 idents ~= token.ident; |
615 nT(), nT(); // Skip Identifier : | 615 nT(), nT(); // Skip Identifier : |
618 idents ~= null; | 618 idents ~= null; |
619 | 619 |
620 // NonVoidInitializer | 620 // NonVoidInitializer |
621 values ~= parseNonVoidInitializer(); | 621 values ~= parseNonVoidInitializer(); |
622 | 622 |
623 if (token.type != T.Comma) | 623 if (token.kind != T.Comma) |
624 break; | 624 break; |
625 nT(); | 625 nT(); |
626 } | 626 } |
627 require(T.RBrace); | 627 require(T.RBrace); |
628 return new StructInitializer(idents, values); | 628 return new StructInitializer(idents, values); |
633 if (success) | 633 if (success) |
634 { | 634 { |
635 init = si; | 635 init = si; |
636 break; | 636 break; |
637 } | 637 } |
638 assert(token.type == T.LBrace); | 638 assert(token.kind == T.LBrace); |
639 //goto default; | 639 //goto default; |
640 default: | 640 default: |
641 init = parseAssignExpression(); | 641 init = parseAssignExpression(); |
642 } | 642 } |
643 set(init, begin); | 643 set(init, begin); |
648 { | 648 { |
649 auto begin = token; | 649 auto begin = token; |
650 auto func = new FunctionBody; | 650 auto func = new FunctionBody; |
651 while (1) | 651 while (1) |
652 { | 652 { |
653 switch (token.type) | 653 switch (token.kind) |
654 { | 654 { |
655 case T.LBrace: | 655 case T.LBrace: |
656 func.funcBody = parseStatements(); | 656 func.funcBody = parseStatements(); |
657 break; | 657 break; |
658 case T.Semicolon: | 658 case T.Semicolon: |
689 } | 689 } |
690 | 690 |
691 LinkageType parseLinkageType() | 691 LinkageType parseLinkageType() |
692 { | 692 { |
693 LinkageType linkageType; | 693 LinkageType linkageType; |
694 if (token.type != T.LParen) | 694 if (token.kind != T.LParen) |
695 return linkageType; | 695 return linkageType; |
696 | 696 |
697 nT(); // Skip ( | 697 nT(); // Skip ( |
698 if (token.type == T.RParen) | 698 if (token.kind == T.RParen) |
699 { | 699 { |
700 nT(); | 700 nT(); |
701 error(MID.MissingLinkageType); | 701 error(MID.MissingLinkageType); |
702 return linkageType; | 702 return linkageType; |
703 } | 703 } |
752 // Nested function. | 752 // Nested function. |
753 Declaration parse() | 753 Declaration parse() |
754 { | 754 { |
755 Declaration decl; | 755 Declaration decl; |
756 auto begin = token; | 756 auto begin = token; |
757 switch (token.type) | 757 switch (token.kind) |
758 { | 758 { |
759 case T.Extern: | 759 case T.Extern: |
760 if (peekNext() != T.LParen) | 760 if (peekNext() != T.LParen) |
761 { | 761 { |
762 stc_tmp = StorageClass.Extern; | 762 stc_tmp = StorageClass.Extern; |
848 return parse(); | 848 return parse(); |
849 } | 849 } |
850 | 850 |
851 uint parseAlignAttribute() | 851 uint parseAlignAttribute() |
852 { | 852 { |
853 assert(token.type == T.Align); | 853 assert(token.kind == T.Align); |
854 nT(); // Skip align keyword. | 854 nT(); // Skip align keyword. |
855 uint size = DEFAULT_ALIGN_SIZE; // Global default. | 855 uint size = DEFAULT_ALIGN_SIZE; // Global default. |
856 if (skipped(T.LParen)) | 856 if (skipped(T.LParen)) |
857 { | 857 { |
858 if (token.type == T.Int32) | 858 if (token.kind == T.Int32) |
859 (size = token.int_), nT(); | 859 (size = token.int_), nT(); |
860 else | 860 else |
861 expected(T.Int32); | 861 expected(T.Int32); |
862 require(T.RParen); | 862 require(T.RParen); |
863 } | 863 } |
866 | 866 |
867 Declaration parseAttributeSpecifier() | 867 Declaration parseAttributeSpecifier() |
868 { | 868 { |
869 Declaration decl; | 869 Declaration decl; |
870 | 870 |
871 switch (token.type) | 871 switch (token.kind) |
872 { | 872 { |
873 case T.Align: | 873 case T.Align: |
874 uint alignSize = parseAlignAttribute(); | 874 uint alignSize = parseAlignAttribute(); |
875 auto saved = this.alignSize; // Save. | 875 auto saved = this.alignSize; // Save. |
876 this.alignSize = alignSize; // Set. | 876 this.alignSize = alignSize; // Set. |
895 decl = new PragmaDeclaration(ident, args, parseDeclarationsBlock()); | 895 decl = new PragmaDeclaration(ident, args, parseDeclarationsBlock()); |
896 break; | 896 break; |
897 default: | 897 default: |
898 // Protection attributes | 898 // Protection attributes |
899 Protection prot; | 899 Protection prot; |
900 switch (token.type) | 900 switch (token.kind) |
901 { | 901 { |
902 case T.Private: | 902 case T.Private: |
903 prot = Protection.Private; break; | 903 prot = Protection.Private; break; |
904 case T.Package: | 904 case T.Package: |
905 prot = Protection.Package; break; | 905 prot = Protection.Package; break; |
921 return decl; | 921 return decl; |
922 } | 922 } |
923 | 923 |
924 Declaration parseImportDeclaration() | 924 Declaration parseImportDeclaration() |
925 { | 925 { |
926 assert(token.type == T.Import || token.type == T.Static); | 926 assert(token.kind == T.Import || token.kind == T.Static); |
927 bool isStatic = skipped(T.Static); | 927 bool isStatic = skipped(T.Static); |
928 assert(token.type == T.Import); | 928 assert(token.kind == T.Import); |
929 nT(); // Skip import keyword. | 929 nT(); // Skip import keyword. |
930 | 930 |
931 ModuleFQN[] moduleFQNs; | 931 ModuleFQN[] moduleFQNs; |
932 Identifier*[] moduleAliases; | 932 Identifier*[] moduleAliases; |
933 Identifier*[] bindNames; | 933 Identifier*[] bindNames; |
947 | 947 |
948 // Identifier(.Identifier)* | 948 // Identifier(.Identifier)* |
949 while (1) | 949 while (1) |
950 { | 950 { |
951 moduleFQN ~= requireIdentifier(MSG.ExpectedModuleIdentifier); | 951 moduleFQN ~= requireIdentifier(MSG.ExpectedModuleIdentifier); |
952 if (token.type != T.Dot) | 952 if (token.kind != T.Dot) |
953 break; | 953 break; |
954 nT(); | 954 nT(); |
955 } | 955 } |
956 | 956 |
957 // Push identifiers. | 957 // Push identifiers. |
958 moduleFQNs ~= moduleFQN; | 958 moduleFQNs ~= moduleFQN; |
959 moduleAliases ~= moduleAlias; | 959 moduleAliases ~= moduleAlias; |
960 | 960 |
961 if (token.type != T.Comma) | 961 if (token.kind != T.Comma) |
962 break; | 962 break; |
963 nT(); | 963 nT(); |
964 } | 964 } |
965 | 965 |
966 if (token.type == T.Colon) | 966 if (token.kind == T.Colon) |
967 { | 967 { |
968 // BindAlias = BindName(, BindAlias = BindName)*; | 968 // BindAlias = BindName(, BindAlias = BindName)*; |
969 // BindName(, BindName)*; | 969 // BindName(, BindName)*; |
970 do | 970 do |
971 { | 971 { |
978 nT(); // Skip = | 978 nT(); // Skip = |
979 } | 979 } |
980 // Push identifiers. | 980 // Push identifiers. |
981 bindNames ~= requireIdentifier(MSG.ExpectedImportName); | 981 bindNames ~= requireIdentifier(MSG.ExpectedImportName); |
982 bindAliases ~= bindAlias; | 982 bindAliases ~= bindAlias; |
983 } while (token.type == T.Comma) | 983 } while (token.kind == T.Comma) |
984 } | 984 } |
985 | 985 |
986 require(T.Semicolon); | 986 require(T.Semicolon); |
987 | 987 |
988 return new ImportDeclaration(moduleFQNs, moduleAliases, bindNames, bindAliases, isStatic); | 988 return new ImportDeclaration(moduleFQNs, moduleAliases, bindNames, bindAliases, isStatic); |
989 } | 989 } |
990 | 990 |
991 Declaration parseEnumDeclaration() | 991 Declaration parseEnumDeclaration() |
992 { | 992 { |
993 assert(token.type == T.Enum); | 993 assert(token.kind == T.Enum); |
994 nT(); // Skip enum keyword. | 994 nT(); // Skip enum keyword. |
995 | 995 |
996 Identifier* enumName; | 996 Identifier* enumName; |
997 Type baseType; | 997 Type baseType; |
998 EnumMember[] members; | 998 EnumMember[] members; |
1006 if (enumName && skipped(T.Semicolon)) | 1006 if (enumName && skipped(T.Semicolon)) |
1007 {} | 1007 {} |
1008 else if (skipped(T.LBrace)) | 1008 else if (skipped(T.LBrace)) |
1009 { | 1009 { |
1010 hasBody = true; | 1010 hasBody = true; |
1011 while (token.type != T.RBrace) | 1011 while (token.kind != T.RBrace) |
1012 { | 1012 { |
1013 auto begin = token; | 1013 auto begin = token; |
1014 auto name = requireIdentifier(MSG.ExpectedEnumMember); | 1014 auto name = requireIdentifier(MSG.ExpectedEnumMember); |
1015 Expression value; | 1015 Expression value; |
1016 | 1016 |
1019 else | 1019 else |
1020 value = null; | 1020 value = null; |
1021 | 1021 |
1022 members ~= set(new EnumMember(name, value), begin); | 1022 members ~= set(new EnumMember(name, value), begin); |
1023 | 1023 |
1024 if (token.type != T.Comma) | 1024 if (token.kind != T.Comma) |
1025 break; | 1025 break; |
1026 nT(); // Skip , | 1026 nT(); // Skip , |
1027 } | 1027 } |
1028 require(T.RBrace); | 1028 require(T.RBrace); |
1029 } | 1029 } |
1033 return new EnumDeclaration(enumName, baseType, members, hasBody); | 1033 return new EnumDeclaration(enumName, baseType, members, hasBody); |
1034 } | 1034 } |
1035 | 1035 |
1036 Declaration parseClassDeclaration() | 1036 Declaration parseClassDeclaration() |
1037 { | 1037 { |
1038 assert(token.type == T.Class); | 1038 assert(token.kind == T.Class); |
1039 nT(); // Skip class keyword. | 1039 nT(); // Skip class keyword. |
1040 | 1040 |
1041 Identifier* className; | 1041 Identifier* className; |
1042 TemplateParameters tparams; | 1042 TemplateParameters tparams; |
1043 BaseClassType[] bases; | 1043 BaseClassType[] bases; |
1044 Declarations decls; | 1044 Declarations decls; |
1045 | 1045 |
1046 className = requireIdentifier(MSG.ExpectedClassName); | 1046 className = requireIdentifier(MSG.ExpectedClassName); |
1047 | 1047 |
1048 if (token.type == T.LParen) | 1048 if (token.kind == T.LParen) |
1049 tparams = parseTemplateParameterList(); | 1049 tparams = parseTemplateParameterList(); |
1050 | 1050 |
1051 if (token.type == T.Colon) | 1051 if (token.kind == T.Colon) |
1052 bases = parseBaseClasses(); | 1052 bases = parseBaseClasses(); |
1053 | 1053 |
1054 if (bases.length == 0 && skipped(T.Semicolon)) | 1054 if (bases.length == 0 && skipped(T.Semicolon)) |
1055 {} | 1055 {} |
1056 else if (token.type == T.LBrace) | 1056 else if (token.kind == T.LBrace) |
1057 decls = parseDeclarationDefinitionsBody(); | 1057 decls = parseDeclarationDefinitionsBody(); |
1058 else | 1058 else |
1059 error(token, MSG.ExpectedClassBody, token.srcText); | 1059 error(token, MSG.ExpectedClassBody, token.srcText); |
1060 | 1060 |
1061 return new ClassDeclaration(className, tparams, bases, decls); | 1061 return new ClassDeclaration(className, tparams, bases, decls); |
1063 | 1063 |
1064 BaseClassType[] parseBaseClasses(bool colonLeadsOff = true) | 1064 BaseClassType[] parseBaseClasses(bool colonLeadsOff = true) |
1065 { | 1065 { |
1066 if (colonLeadsOff) | 1066 if (colonLeadsOff) |
1067 { | 1067 { |
1068 assert(token.type == T.Colon); | 1068 assert(token.kind == T.Colon); |
1069 nT(); // Skip colon | 1069 nT(); // Skip colon |
1070 } | 1070 } |
1071 | 1071 |
1072 BaseClassType[] bases; | 1072 BaseClassType[] bases; |
1073 | 1073 |
1074 do | 1074 do |
1075 { | 1075 { |
1076 Protection prot = Protection.Public; | 1076 Protection prot = Protection.Public; |
1077 switch (token.type) | 1077 switch (token.kind) |
1078 { | 1078 { |
1079 case T.Identifier, T.Dot, T.Typeof: goto LparseBasicType; | 1079 case T.Identifier, T.Dot, T.Typeof: goto LparseBasicType; |
1080 case T.Private: prot = Protection.Private; break; | 1080 case T.Private: prot = Protection.Private; break; |
1081 case T.Protected: prot = Protection.Protected; break; | 1081 case T.Protected: prot = Protection.Protected; break; |
1082 case T.Package: prot = Protection.Package; break; | 1082 case T.Package: prot = Protection.Package; break; |
1094 return bases; | 1094 return bases; |
1095 } | 1095 } |
1096 | 1096 |
1097 Declaration parseInterfaceDeclaration() | 1097 Declaration parseInterfaceDeclaration() |
1098 { | 1098 { |
1099 assert(token.type == T.Interface); | 1099 assert(token.kind == T.Interface); |
1100 nT(); // Skip interface keyword. | 1100 nT(); // Skip interface keyword. |
1101 | 1101 |
1102 Identifier* name; | 1102 Identifier* name; |
1103 TemplateParameters tparams; | 1103 TemplateParameters tparams; |
1104 BaseClassType[] bases; | 1104 BaseClassType[] bases; |
1105 Declarations decls; | 1105 Declarations decls; |
1106 | 1106 |
1107 name = requireIdentifier(MSG.ExpectedInterfaceName); | 1107 name = requireIdentifier(MSG.ExpectedInterfaceName); |
1108 | 1108 |
1109 if (token.type == T.LParen) | 1109 if (token.kind == T.LParen) |
1110 tparams = parseTemplateParameterList(); | 1110 tparams = parseTemplateParameterList(); |
1111 | 1111 |
1112 if (token.type == T.Colon) | 1112 if (token.kind == T.Colon) |
1113 bases = parseBaseClasses(); | 1113 bases = parseBaseClasses(); |
1114 | 1114 |
1115 if (bases.length == 0 && skipped(T.Semicolon)) | 1115 if (bases.length == 0 && skipped(T.Semicolon)) |
1116 {} | 1116 {} |
1117 else if (token.type == T.LBrace) | 1117 else if (token.kind == T.LBrace) |
1118 decls = parseDeclarationDefinitionsBody(); | 1118 decls = parseDeclarationDefinitionsBody(); |
1119 else | 1119 else |
1120 error(token, MSG.ExpectedInterfaceBody, token.srcText); | 1120 error(token, MSG.ExpectedInterfaceBody, token.srcText); |
1121 | 1121 |
1122 return new InterfaceDeclaration(name, tparams, bases, decls); | 1122 return new InterfaceDeclaration(name, tparams, bases, decls); |
1123 } | 1123 } |
1124 | 1124 |
1125 Declaration parseStructOrUnionDeclaration() | 1125 Declaration parseStructOrUnionDeclaration() |
1126 { | 1126 { |
1127 assert(token.type == T.Struct || token.type == T.Union); | 1127 assert(token.kind == T.Struct || token.kind == T.Union); |
1128 TOK tok = token.type; | 1128 TOK tok = token.kind; |
1129 nT(); // Skip struct or union keyword. | 1129 nT(); // Skip struct or union keyword. |
1130 | 1130 |
1131 Identifier* name; | 1131 Identifier* name; |
1132 TemplateParameters tparams; | 1132 TemplateParameters tparams; |
1133 Declarations decls; | 1133 Declarations decls; |
1134 | 1134 |
1135 name = optionalIdentifier(); | 1135 name = optionalIdentifier(); |
1136 | 1136 |
1137 if (name && token.type == T.LParen) | 1137 if (name && token.kind == T.LParen) |
1138 tparams = parseTemplateParameterList(); | 1138 tparams = parseTemplateParameterList(); |
1139 | 1139 |
1140 if (name && skipped(T.Semicolon)) | 1140 if (name && skipped(T.Semicolon)) |
1141 {} | 1141 {} |
1142 else if (token.type == T.LBrace) | 1142 else if (token.kind == T.LBrace) |
1143 decls = parseDeclarationDefinitionsBody(); | 1143 decls = parseDeclarationDefinitionsBody(); |
1144 else | 1144 else |
1145 error(token, tok == T.Struct ? | 1145 error(token, tok == T.Struct ? |
1146 MSG.ExpectedStructBody : | 1146 MSG.ExpectedStructBody : |
1147 MSG.ExpectedUnionBody, token.srcText); | 1147 MSG.ExpectedUnionBody, token.srcText); |
1156 return new UnionDeclaration(name, tparams, decls); | 1156 return new UnionDeclaration(name, tparams, decls); |
1157 } | 1157 } |
1158 | 1158 |
1159 Declaration parseConstructorDeclaration() | 1159 Declaration parseConstructorDeclaration() |
1160 { | 1160 { |
1161 assert(token.type == T.This); | 1161 assert(token.kind == T.This); |
1162 nT(); // Skip 'this' keyword. | 1162 nT(); // Skip 'this' keyword. |
1163 auto parameters = parseParameterList(); | 1163 auto parameters = parseParameterList(); |
1164 auto funcBody = parseFunctionBody(); | 1164 auto funcBody = parseFunctionBody(); |
1165 return new ConstructorDeclaration(parameters, funcBody); | 1165 return new ConstructorDeclaration(parameters, funcBody); |
1166 } | 1166 } |
1167 | 1167 |
1168 Declaration parseDestructorDeclaration() | 1168 Declaration parseDestructorDeclaration() |
1169 { | 1169 { |
1170 assert(token.type == T.Tilde); | 1170 assert(token.kind == T.Tilde); |
1171 nT(); // Skip ~ | 1171 nT(); // Skip ~ |
1172 require(T.This); | 1172 require(T.This); |
1173 require(T.LParen); | 1173 require(T.LParen); |
1174 require(T.RParen); | 1174 require(T.RParen); |
1175 auto funcBody = parseFunctionBody(); | 1175 auto funcBody = parseFunctionBody(); |
1176 return new DestructorDeclaration(funcBody); | 1176 return new DestructorDeclaration(funcBody); |
1177 } | 1177 } |
1178 | 1178 |
1179 Declaration parseStaticConstructorDeclaration() | 1179 Declaration parseStaticConstructorDeclaration() |
1180 { | 1180 { |
1181 assert(token.type == T.Static); | 1181 assert(token.kind == T.Static); |
1182 nT(); // Skip static keyword. | 1182 nT(); // Skip static keyword. |
1183 nT(); // Skip 'this' keyword. | 1183 nT(); // Skip 'this' keyword. |
1184 require(T.LParen); | 1184 require(T.LParen); |
1185 require(T.RParen); | 1185 require(T.RParen); |
1186 auto funcBody = parseFunctionBody(); | 1186 auto funcBody = parseFunctionBody(); |
1187 return new StaticConstructorDeclaration(funcBody); | 1187 return new StaticConstructorDeclaration(funcBody); |
1188 } | 1188 } |
1189 | 1189 |
1190 Declaration parseStaticDestructorDeclaration() | 1190 Declaration parseStaticDestructorDeclaration() |
1191 { | 1191 { |
1192 assert(token.type == T.Static); | 1192 assert(token.kind == T.Static); |
1193 nT(); // Skip static keyword. | 1193 nT(); // Skip static keyword. |
1194 nT(); // Skip ~ | 1194 nT(); // Skip ~ |
1195 require(T.This); | 1195 require(T.This); |
1196 require(T.LParen); | 1196 require(T.LParen); |
1197 require(T.RParen); | 1197 require(T.RParen); |
1199 return new StaticDestructorDeclaration(funcBody); | 1199 return new StaticDestructorDeclaration(funcBody); |
1200 } | 1200 } |
1201 | 1201 |
1202 Declaration parseInvariantDeclaration() | 1202 Declaration parseInvariantDeclaration() |
1203 { | 1203 { |
1204 assert(token.type == T.Invariant); | 1204 assert(token.kind == T.Invariant); |
1205 nT(); // Skip invariant keyword. | 1205 nT(); // Skip invariant keyword. |
1206 // Optional () for getting ready porting to D 2.0 | 1206 // Optional () for getting ready porting to D 2.0 |
1207 if (token.type == T.LParen) | 1207 if (token.kind == T.LParen) |
1208 requireNext(T.RParen); | 1208 requireNext(T.RParen); |
1209 auto funcBody = parseFunctionBody(); | 1209 auto funcBody = parseFunctionBody(); |
1210 return new InvariantDeclaration(funcBody); | 1210 return new InvariantDeclaration(funcBody); |
1211 } | 1211 } |
1212 | 1212 |
1213 Declaration parseUnittestDeclaration() | 1213 Declaration parseUnittestDeclaration() |
1214 { | 1214 { |
1215 assert(token.type == T.Unittest); | 1215 assert(token.kind == T.Unittest); |
1216 nT(); // Skip unittest keyword. | 1216 nT(); // Skip unittest keyword. |
1217 auto funcBody = parseFunctionBody(); | 1217 auto funcBody = parseFunctionBody(); |
1218 return new UnittestDeclaration(funcBody); | 1218 return new UnittestDeclaration(funcBody); |
1219 } | 1219 } |
1220 | 1220 |
1226 return null; | 1226 return null; |
1227 } | 1227 } |
1228 | 1228 |
1229 Declaration parseDebugDeclaration() | 1229 Declaration parseDebugDeclaration() |
1230 { | 1230 { |
1231 assert(token.type == T.Debug); | 1231 assert(token.kind == T.Debug); |
1232 nT(); // Skip debug keyword. | 1232 nT(); // Skip debug keyword. |
1233 | 1233 |
1234 Token* spec; | 1234 Token* spec; |
1235 Token* cond; | 1235 Token* cond; |
1236 Declaration decls, elseDecls; | 1236 Declaration decls, elseDecls; |
1259 return new DebugDeclaration(spec, cond, decls, elseDecls); | 1259 return new DebugDeclaration(spec, cond, decls, elseDecls); |
1260 } | 1260 } |
1261 | 1261 |
1262 Declaration parseVersionDeclaration() | 1262 Declaration parseVersionDeclaration() |
1263 { | 1263 { |
1264 assert(token.type == T.Version); | 1264 assert(token.kind == T.Version); |
1265 nT(); // Skip version keyword. | 1265 nT(); // Skip version keyword. |
1266 | 1266 |
1267 Token* spec; | 1267 Token* spec; |
1268 Token* cond; | 1268 Token* cond; |
1269 Declaration decls, elseDecls; | 1269 Declaration decls, elseDecls; |
1289 return new VersionDeclaration(spec, cond, decls, elseDecls); | 1289 return new VersionDeclaration(spec, cond, decls, elseDecls); |
1290 } | 1290 } |
1291 | 1291 |
1292 Declaration parseStaticIfDeclaration() | 1292 Declaration parseStaticIfDeclaration() |
1293 { | 1293 { |
1294 assert(token.type == T.Static); | 1294 assert(token.kind == T.Static); |
1295 nT(); // Skip static keyword. | 1295 nT(); // Skip static keyword. |
1296 nT(); // Skip if keyword. | 1296 nT(); // Skip if keyword. |
1297 | 1297 |
1298 Expression condition; | 1298 Expression condition; |
1299 Declaration ifDecls, elseDecls; | 1299 Declaration ifDecls, elseDecls; |
1310 return new StaticIfDeclaration(condition, ifDecls, elseDecls); | 1310 return new StaticIfDeclaration(condition, ifDecls, elseDecls); |
1311 } | 1311 } |
1312 | 1312 |
1313 Declaration parseStaticAssertDeclaration() | 1313 Declaration parseStaticAssertDeclaration() |
1314 { | 1314 { |
1315 assert(token.type == T.Static); | 1315 assert(token.kind == T.Static); |
1316 nT(); // Skip static keyword. | 1316 nT(); // Skip static keyword. |
1317 nT(); // Skip assert keyword. | 1317 nT(); // Skip assert keyword. |
1318 Expression condition, message; | 1318 Expression condition, message; |
1319 require(T.LParen); | 1319 require(T.LParen); |
1320 condition = parseAssignExpression(); | 1320 condition = parseAssignExpression(); |
1325 return new StaticAssertDeclaration(condition, message); | 1325 return new StaticAssertDeclaration(condition, message); |
1326 } | 1326 } |
1327 | 1327 |
1328 Declaration parseTemplateDeclaration() | 1328 Declaration parseTemplateDeclaration() |
1329 { | 1329 { |
1330 assert(token.type == T.Template); | 1330 assert(token.kind == T.Template); |
1331 nT(); // Skip template keyword. | 1331 nT(); // Skip template keyword. |
1332 auto templateName = requireIdentifier(MSG.ExpectedTemplateName); | 1332 auto templateName = requireIdentifier(MSG.ExpectedTemplateName); |
1333 auto templateParams = parseTemplateParameterList(); | 1333 auto templateParams = parseTemplateParameterList(); |
1334 auto decls = parseDeclarationDefinitionsBody(); | 1334 auto decls = parseDeclarationDefinitionsBody(); |
1335 return new TemplateDeclaration(templateName, templateParams, decls); | 1335 return new TemplateDeclaration(templateName, templateParams, decls); |
1336 } | 1336 } |
1337 | 1337 |
1338 Declaration parseNewDeclaration() | 1338 Declaration parseNewDeclaration() |
1339 { | 1339 { |
1340 assert(token.type == T.New); | 1340 assert(token.kind == T.New); |
1341 nT(); // Skip new keyword. | 1341 nT(); // Skip new keyword. |
1342 auto parameters = parseParameterList(); | 1342 auto parameters = parseParameterList(); |
1343 auto funcBody = parseFunctionBody(); | 1343 auto funcBody = parseFunctionBody(); |
1344 return new NewDeclaration(parameters, funcBody); | 1344 return new NewDeclaration(parameters, funcBody); |
1345 } | 1345 } |
1346 | 1346 |
1347 Declaration parseDeleteDeclaration() | 1347 Declaration parseDeleteDeclaration() |
1348 { | 1348 { |
1349 assert(token.type == T.Delete); | 1349 assert(token.kind == T.Delete); |
1350 nT(); // Skip delete keyword. | 1350 nT(); // Skip delete keyword. |
1351 auto parameters = parseParameterList(); | 1351 auto parameters = parseParameterList(); |
1352 auto funcBody = parseFunctionBody(); | 1352 auto funcBody = parseFunctionBody(); |
1353 return new DeleteDeclaration(parameters, funcBody); | 1353 return new DeleteDeclaration(parameters, funcBody); |
1354 } | 1354 } |
1355 | 1355 |
1356 Type parseTypeofType() | 1356 Type parseTypeofType() |
1357 { | 1357 { |
1358 assert(token.type == T.Typeof); | 1358 assert(token.kind == T.Typeof); |
1359 auto begin = token; | 1359 auto begin = token; |
1360 Type type; | 1360 Type type; |
1361 requireNext(T.LParen); | 1361 requireNext(T.LParen); |
1362 switch (token.type) | 1362 switch (token.kind) |
1363 { | 1363 { |
1364 version(D2) | 1364 version(D2) |
1365 { | 1365 { |
1366 case T.Return: | 1366 case T.Return: |
1367 nT(); | 1367 nT(); |
1384 mixin TemplateIdentifier !( TemplateArguments ) ; | 1384 mixin TemplateIdentifier !( TemplateArguments ) ; |
1385 mixin TemplateIdentifier !( TemplateArguments ) MixinIdentifier ; | 1385 mixin TemplateIdentifier !( TemplateArguments ) MixinIdentifier ; |
1386 */ | 1386 */ |
1387 Class parseMixin(Class)() | 1387 Class parseMixin(Class)() |
1388 { | 1388 { |
1389 assert(token.type == T.Mixin); | 1389 assert(token.kind == T.Mixin); |
1390 nT(); // Skip mixin keyword. | 1390 nT(); // Skip mixin keyword. |
1391 | 1391 |
1392 static if (is(Class == MixinDeclaration)) | 1392 static if (is(Class == MixinDeclaration)) |
1393 { | 1393 { |
1394 if (skipped(T.LParen)) | 1394 if (skipped(T.LParen)) |
1425 Statements parseStatements() | 1425 Statements parseStatements() |
1426 { | 1426 { |
1427 auto begin = token; | 1427 auto begin = token; |
1428 require(T.LBrace); | 1428 require(T.LBrace); |
1429 auto statements = new Statements(); | 1429 auto statements = new Statements(); |
1430 while (token.type != T.RBrace && token.type != T.EOF) | 1430 while (token.kind != T.RBrace && token.kind != T.EOF) |
1431 statements ~= parseStatement(); | 1431 statements ~= parseStatement(); |
1432 require(T.RBrace); | 1432 require(T.RBrace); |
1433 return set(statements, begin); | 1433 return set(statements, begin); |
1434 } | 1434 } |
1435 | 1435 |
1443 { | 1443 { |
1444 d = parseVariableOrFunction(); | 1444 d = parseVariableOrFunction(); |
1445 goto LreturnDeclarationStatement; | 1445 goto LreturnDeclarationStatement; |
1446 } | 1446 } |
1447 | 1447 |
1448 switch (token.type) | 1448 switch (token.kind) |
1449 { | 1449 { |
1450 case T.Align: | 1450 case T.Align: |
1451 uint size = parseAlignAttribute(); | 1451 uint size = parseAlignAttribute(); |
1452 // Restrict align attribute to structs in parsing phase. | 1452 // Restrict align attribute to structs in parsing phase. |
1453 StructDeclaration structDecl; | 1453 StructDeclaration structDecl; |
1454 if (token.type == T.Struct) | 1454 if (token.kind == T.Struct) |
1455 { | 1455 { |
1456 auto begin2 = token; | 1456 auto begin2 = token; |
1457 structDecl = parseStructOrUnionDeclaration().to!(StructDeclaration); | 1457 structDecl = parseStructOrUnionDeclaration().to!(StructDeclaration); |
1458 structDecl.setAlignSize(size); | 1458 structDecl.setAlignSize(size); |
1459 set(structDecl, begin2); | 1459 set(structDecl, begin2); |
1644 break; | 1644 break; |
1645 default: | 1645 default: |
1646 if (token.isSpecialToken) | 1646 if (token.isSpecialToken) |
1647 goto case_parseExpressionStatement; | 1647 goto case_parseExpressionStatement; |
1648 | 1648 |
1649 if (token.type != T.Dollar) | 1649 if (token.kind != T.Dollar) |
1650 // Assert that this isn't a valid expression. | 1650 // Assert that this isn't a valid expression. |
1651 assert(delegate bool(){ | 1651 assert(delegate bool(){ |
1652 bool success; | 1652 bool success; |
1653 auto expression = try_(&parseExpression, success); | 1653 auto expression = try_(&parseExpression, success); |
1654 return success; | 1654 return success; |
1659 s = new IllegalStatement(); | 1659 s = new IllegalStatement(); |
1660 // Skip to next valid token. | 1660 // Skip to next valid token. |
1661 do | 1661 do |
1662 nT(); | 1662 nT(); |
1663 while (!token.isStatementStart && | 1663 while (!token.isStatementStart && |
1664 token.type != T.RBrace && | 1664 token.kind != T.RBrace && |
1665 token.type != T.EOF) | 1665 token.kind != T.EOF) |
1666 auto text = Token.textSpan(begin, this.prevToken); | 1666 auto text = Token.textSpan(begin, this.prevToken); |
1667 error(begin, MSG.IllegalStatement, text); | 1667 error(begin, MSG.IllegalStatement, text); |
1668 } | 1668 } |
1669 assert(s !is null); | 1669 assert(s !is null); |
1670 set(s, begin); | 1670 set(s, begin); |
1693 auto begin = token; | 1693 auto begin = token; |
1694 Statement s; | 1694 Statement s; |
1695 if (skipped(T.LBrace)) | 1695 if (skipped(T.LBrace)) |
1696 { | 1696 { |
1697 auto ss = new Statements(); | 1697 auto ss = new Statements(); |
1698 while (token.type != T.RBrace && token.type != T.EOF) | 1698 while (token.kind != T.RBrace && token.kind != T.EOF) |
1699 ss ~= parseStatement(); | 1699 ss ~= parseStatement(); |
1700 require(T.RBrace); | 1700 require(T.RBrace); |
1701 s = set(ss, begin); | 1701 s = set(ss, begin); |
1702 } | 1702 } |
1703 else if (token.type == T.Semicolon) | 1703 else if (token.kind == T.Semicolon) |
1704 { | 1704 { |
1705 error(token, MSG.ExpectedNonEmptyStatement); | 1705 error(token, MSG.ExpectedNonEmptyStatement); |
1706 nT(); | 1706 nT(); |
1707 s = set(new EmptyStatement(), begin); | 1707 s = set(new EmptyStatement(), begin); |
1708 } | 1708 } |
1732 // Nested function. | 1732 // Nested function. |
1733 Declaration parse() | 1733 Declaration parse() |
1734 { | 1734 { |
1735 auto begin = token; | 1735 auto begin = token; |
1736 Declaration d; | 1736 Declaration d; |
1737 switch (token.type) | 1737 switch (token.kind) |
1738 { | 1738 { |
1739 case T.Extern: | 1739 case T.Extern: |
1740 if (peekNext() != T.LParen) | 1740 if (peekNext() != T.LParen) |
1741 { | 1741 { |
1742 stc_tmp = StorageClass.Extern; | 1742 stc_tmp = StorageClass.Extern; |
1798 return new DeclarationStatement(parse()); | 1798 return new DeclarationStatement(parse()); |
1799 } | 1799 } |
1800 | 1800 |
1801 Statement parseIfStatement() | 1801 Statement parseIfStatement() |
1802 { | 1802 { |
1803 assert(token.type == T.If); | 1803 assert(token.kind == T.If); |
1804 nT(); | 1804 nT(); |
1805 | 1805 |
1806 Statement variable; | 1806 Statement variable; |
1807 Expression condition; | 1807 Expression condition; |
1808 Statement ifBody, elseBody; | 1808 Statement ifBody, elseBody; |
1853 return new IfStatement(variable, condition, ifBody, elseBody); | 1853 return new IfStatement(variable, condition, ifBody, elseBody); |
1854 } | 1854 } |
1855 | 1855 |
1856 Statement parseWhileStatement() | 1856 Statement parseWhileStatement() |
1857 { | 1857 { |
1858 assert(token.type == T.While); | 1858 assert(token.kind == T.While); |
1859 nT(); | 1859 nT(); |
1860 require(T.LParen); | 1860 require(T.LParen); |
1861 auto condition = parseExpression(); | 1861 auto condition = parseExpression(); |
1862 require(T.RParen); | 1862 require(T.RParen); |
1863 return new WhileStatement(condition, parseScopeStatement()); | 1863 return new WhileStatement(condition, parseScopeStatement()); |
1864 } | 1864 } |
1865 | 1865 |
1866 Statement parseDoWhileStatement() | 1866 Statement parseDoWhileStatement() |
1867 { | 1867 { |
1868 assert(token.type == T.Do); | 1868 assert(token.kind == T.Do); |
1869 nT(); | 1869 nT(); |
1870 auto doBody = parseScopeStatement(); | 1870 auto doBody = parseScopeStatement(); |
1871 require(T.While); | 1871 require(T.While); |
1872 require(T.LParen); | 1872 require(T.LParen); |
1873 auto condition = parseExpression(); | 1873 auto condition = parseExpression(); |
1875 return new DoWhileStatement(condition, doBody); | 1875 return new DoWhileStatement(condition, doBody); |
1876 } | 1876 } |
1877 | 1877 |
1878 Statement parseForStatement() | 1878 Statement parseForStatement() |
1879 { | 1879 { |
1880 assert(token.type == T.For); | 1880 assert(token.kind == T.For); |
1881 nT(); | 1881 nT(); |
1882 require(T.LParen); | 1882 require(T.LParen); |
1883 | 1883 |
1884 Statement init, forBody; | 1884 Statement init, forBody; |
1885 Expression condition, increment; | 1885 Expression condition, increment; |
1886 | 1886 |
1887 if (token.type != T.Semicolon) | 1887 if (token.kind != T.Semicolon) |
1888 init = parseNoScopeStatement(); | 1888 init = parseNoScopeStatement(); |
1889 else | 1889 else |
1890 nT(); // Skip ; | 1890 nT(); // Skip ; |
1891 if (token.type != T.Semicolon) | 1891 if (token.kind != T.Semicolon) |
1892 condition = parseExpression(); | 1892 condition = parseExpression(); |
1893 require(T.Semicolon); | 1893 require(T.Semicolon); |
1894 if (token.type != T.RParen) | 1894 if (token.kind != T.RParen) |
1895 increment = parseExpression(); | 1895 increment = parseExpression(); |
1896 require(T.RParen); | 1896 require(T.RParen); |
1897 forBody = parseScopeStatement(); | 1897 forBody = parseScopeStatement(); |
1898 return new ForStatement(init, condition, increment, forBody); | 1898 return new ForStatement(init, condition, increment, forBody); |
1899 } | 1899 } |
1900 | 1900 |
1901 Statement parseForeachStatement() | 1901 Statement parseForeachStatement() |
1902 { | 1902 { |
1903 assert(token.type == T.Foreach || token.type == T.Foreach_reverse); | 1903 assert(token.kind == T.Foreach || token.kind == T.Foreach_reverse); |
1904 TOK tok = token.type; | 1904 TOK tok = token.kind; |
1905 nT(); | 1905 nT(); |
1906 | 1906 |
1907 auto params = new Parameters; | 1907 auto params = new Parameters; |
1908 Expression e; // Aggregate or LwrExpression | 1908 Expression e; // Aggregate or LwrExpression |
1909 | 1909 |
1913 auto paramBegin = token; | 1913 auto paramBegin = token; |
1914 StorageClass stc; | 1914 StorageClass stc; |
1915 Type type; | 1915 Type type; |
1916 Identifier* ident; | 1916 Identifier* ident; |
1917 | 1917 |
1918 switch (token.type) | 1918 switch (token.kind) |
1919 { | 1919 { |
1920 case T.Ref, T.Inout: | 1920 case T.Ref, T.Inout: |
1921 stc = StorageClass.Ref; | 1921 stc = StorageClass.Ref; |
1922 nT(); | 1922 nT(); |
1923 // fall through | 1923 // fall through |
1933 type = parseDeclarator(ident); | 1933 type = parseDeclarator(ident); |
1934 } | 1934 } |
1935 | 1935 |
1936 params ~= set(new Parameter(stc, type, ident, null), paramBegin); | 1936 params ~= set(new Parameter(stc, type, ident, null), paramBegin); |
1937 | 1937 |
1938 if (token.type != T.Comma) | 1938 if (token.kind != T.Comma) |
1939 break; | 1939 break; |
1940 nT(); | 1940 nT(); |
1941 } | 1941 } |
1942 require(T.Semicolon); | 1942 require(T.Semicolon); |
1943 e = parseExpression(); | 1943 e = parseExpression(); |
1959 return new ForeachStatement(tok, params, e, forBody); | 1959 return new ForeachStatement(tok, params, e, forBody); |
1960 } | 1960 } |
1961 | 1961 |
1962 Statement parseSwitchStatement() | 1962 Statement parseSwitchStatement() |
1963 { | 1963 { |
1964 assert(token.type == T.Switch); | 1964 assert(token.kind == T.Switch); |
1965 nT(); | 1965 nT(); |
1966 require(T.LParen); | 1966 require(T.LParen); |
1967 auto condition = parseExpression(); | 1967 auto condition = parseExpression(); |
1968 require(T.RParen); | 1968 require(T.RParen); |
1969 auto switchBody = parseScopeStatement(); | 1969 auto switchBody = parseScopeStatement(); |
1977 Statement parseCaseOrDefaultBody() | 1977 Statement parseCaseOrDefaultBody() |
1978 { | 1978 { |
1979 // This function is similar to parseNoScopeStatement() | 1979 // This function is similar to parseNoScopeStatement() |
1980 auto begin = token; | 1980 auto begin = token; |
1981 auto s = new Statements(); | 1981 auto s = new Statements(); |
1982 while (token.type != T.Case && | 1982 while (token.kind != T.Case && |
1983 token.type != T.Default && | 1983 token.kind != T.Default && |
1984 token.type != T.RBrace && | 1984 token.kind != T.RBrace && |
1985 token.type != T.EOF) | 1985 token.kind != T.EOF) |
1986 s ~= parseStatement(); | 1986 s ~= parseStatement(); |
1987 return set(new ScopeStatement(s), begin); | 1987 return set(new ScopeStatement(s), begin); |
1988 } | 1988 } |
1989 | 1989 |
1990 Statement parseCaseStatement() | 1990 Statement parseCaseStatement() |
1991 { | 1991 { |
1992 assert(token.type == T.Case); | 1992 assert(token.kind == T.Case); |
1993 nT(); | 1993 nT(); |
1994 auto values = parseExpressionList(); | 1994 auto values = parseExpressionList(); |
1995 require(T.Colon); | 1995 require(T.Colon); |
1996 auto caseBody = parseCaseOrDefaultBody(); | 1996 auto caseBody = parseCaseOrDefaultBody(); |
1997 return new CaseStatement(values, caseBody); | 1997 return new CaseStatement(values, caseBody); |
1998 } | 1998 } |
1999 | 1999 |
2000 Statement parseDefaultStatement() | 2000 Statement parseDefaultStatement() |
2001 { | 2001 { |
2002 assert(token.type == T.Default); | 2002 assert(token.kind == T.Default); |
2003 nT(); | 2003 nT(); |
2004 require(T.Colon); | 2004 require(T.Colon); |
2005 auto defaultBody = parseCaseOrDefaultBody(); | 2005 auto defaultBody = parseCaseOrDefaultBody(); |
2006 return new DefaultStatement(defaultBody); | 2006 return new DefaultStatement(defaultBody); |
2007 } | 2007 } |
2008 | 2008 |
2009 Statement parseContinueStatement() | 2009 Statement parseContinueStatement() |
2010 { | 2010 { |
2011 assert(token.type == T.Continue); | 2011 assert(token.kind == T.Continue); |
2012 nT(); | 2012 nT(); |
2013 auto ident = optionalIdentifier(); | 2013 auto ident = optionalIdentifier(); |
2014 require(T.Semicolon); | 2014 require(T.Semicolon); |
2015 return new ContinueStatement(ident); | 2015 return new ContinueStatement(ident); |
2016 } | 2016 } |
2017 | 2017 |
2018 Statement parseBreakStatement() | 2018 Statement parseBreakStatement() |
2019 { | 2019 { |
2020 assert(token.type == T.Break); | 2020 assert(token.kind == T.Break); |
2021 nT(); | 2021 nT(); |
2022 auto ident = optionalIdentifier(); | 2022 auto ident = optionalIdentifier(); |
2023 require(T.Semicolon); | 2023 require(T.Semicolon); |
2024 return new BreakStatement(ident); | 2024 return new BreakStatement(ident); |
2025 } | 2025 } |
2026 | 2026 |
2027 Statement parseReturnStatement() | 2027 Statement parseReturnStatement() |
2028 { | 2028 { |
2029 assert(token.type == T.Return); | 2029 assert(token.kind == T.Return); |
2030 nT(); | 2030 nT(); |
2031 Expression expr; | 2031 Expression expr; |
2032 if (token.type != T.Semicolon) | 2032 if (token.kind != T.Semicolon) |
2033 expr = parseExpression(); | 2033 expr = parseExpression(); |
2034 require(T.Semicolon); | 2034 require(T.Semicolon); |
2035 return new ReturnStatement(expr); | 2035 return new ReturnStatement(expr); |
2036 } | 2036 } |
2037 | 2037 |
2038 Statement parseGotoStatement() | 2038 Statement parseGotoStatement() |
2039 { | 2039 { |
2040 assert(token.type == T.Goto); | 2040 assert(token.kind == T.Goto); |
2041 nT(); | 2041 nT(); |
2042 Identifier* ident; | 2042 Identifier* ident; |
2043 Expression caseExpr; | 2043 Expression caseExpr; |
2044 switch (token.type) | 2044 switch (token.kind) |
2045 { | 2045 { |
2046 case T.Case: | 2046 case T.Case: |
2047 nT(); | 2047 nT(); |
2048 if (token.type == T.Semicolon) | 2048 if (token.kind == T.Semicolon) |
2049 break; | 2049 break; |
2050 caseExpr = parseExpression(); | 2050 caseExpr = parseExpression(); |
2051 break; | 2051 break; |
2052 case T.Default: | 2052 case T.Default: |
2053 nT(); | 2053 nT(); |
2059 return new GotoStatement(ident, caseExpr); | 2059 return new GotoStatement(ident, caseExpr); |
2060 } | 2060 } |
2061 | 2061 |
2062 Statement parseWithStatement() | 2062 Statement parseWithStatement() |
2063 { | 2063 { |
2064 assert(token.type == T.With); | 2064 assert(token.kind == T.With); |
2065 nT(); | 2065 nT(); |
2066 require(T.LParen); | 2066 require(T.LParen); |
2067 auto expr = parseExpression(); | 2067 auto expr = parseExpression(); |
2068 require(T.RParen); | 2068 require(T.RParen); |
2069 return new WithStatement(expr, parseScopeStatement()); | 2069 return new WithStatement(expr, parseScopeStatement()); |
2070 } | 2070 } |
2071 | 2071 |
2072 Statement parseSynchronizedStatement() | 2072 Statement parseSynchronizedStatement() |
2073 { | 2073 { |
2074 assert(token.type == T.Synchronized); | 2074 assert(token.kind == T.Synchronized); |
2075 nT(); | 2075 nT(); |
2076 Expression expr; | 2076 Expression expr; |
2077 if (skipped(T.LParen)) | 2077 if (skipped(T.LParen)) |
2078 { | 2078 { |
2079 expr = parseExpression(); | 2079 expr = parseExpression(); |
2082 return new SynchronizedStatement(expr, parseScopeStatement()); | 2082 return new SynchronizedStatement(expr, parseScopeStatement()); |
2083 } | 2083 } |
2084 | 2084 |
2085 Statement parseTryStatement() | 2085 Statement parseTryStatement() |
2086 { | 2086 { |
2087 assert(token.type == T.Try); | 2087 assert(token.kind == T.Try); |
2088 auto begin = token; | 2088 auto begin = token; |
2089 nT(); | 2089 nT(); |
2090 | 2090 |
2091 auto tryBody = parseScopeStatement(); | 2091 auto tryBody = parseScopeStatement(); |
2092 CatchBody[] catchBodies; | 2092 CatchBody[] catchBodies; |
2112 | 2112 |
2113 if (skipped(T.Finally)) | 2113 if (skipped(T.Finally)) |
2114 finBody = set(new FinallyBody(parseNoScopeStatement()), prevToken); | 2114 finBody = set(new FinallyBody(parseNoScopeStatement()), prevToken); |
2115 | 2115 |
2116 if (catchBodies.length == 0 && finBody is null) | 2116 if (catchBodies.length == 0 && finBody is null) |
2117 assert(begin.type == T.Try), error(begin, MSG.MissingCatchOrFinally); | 2117 assert(begin.kind == T.Try), error(begin, MSG.MissingCatchOrFinally); |
2118 | 2118 |
2119 return new TryStatement(tryBody, catchBodies, finBody); | 2119 return new TryStatement(tryBody, catchBodies, finBody); |
2120 } | 2120 } |
2121 | 2121 |
2122 Statement parseThrowStatement() | 2122 Statement parseThrowStatement() |
2123 { | 2123 { |
2124 assert(token.type == T.Throw); | 2124 assert(token.kind == T.Throw); |
2125 nT(); | 2125 nT(); |
2126 auto expr = parseExpression(); | 2126 auto expr = parseExpression(); |
2127 require(T.Semicolon); | 2127 require(T.Semicolon); |
2128 return new ThrowStatement(expr); | 2128 return new ThrowStatement(expr); |
2129 } | 2129 } |
2130 | 2130 |
2131 Statement parseScopeGuardStatement() | 2131 Statement parseScopeGuardStatement() |
2132 { | 2132 { |
2133 assert(token.type == T.Scope); | 2133 assert(token.kind == T.Scope); |
2134 nT(); | 2134 nT(); |
2135 assert(token.type == T.LParen); | 2135 assert(token.kind == T.LParen); |
2136 nT(); | 2136 nT(); |
2137 auto condition = requireIdentifier(MSG.ExpectedScopeIdentifier); | 2137 auto condition = requireIdentifier(MSG.ExpectedScopeIdentifier); |
2138 if (condition) | 2138 if (condition) |
2139 switch (condition.identID) | 2139 switch (condition.identID) |
2140 { | 2140 { |
2143 default: | 2143 default: |
2144 error(this.prevToken, MSG.InvalidScopeIdentifier, this.prevToken.srcText); | 2144 error(this.prevToken, MSG.InvalidScopeIdentifier, this.prevToken.srcText); |
2145 } | 2145 } |
2146 require(T.RParen); | 2146 require(T.RParen); |
2147 Statement scopeBody; | 2147 Statement scopeBody; |
2148 if (token.type == T.LBrace) | 2148 if (token.kind == T.LBrace) |
2149 scopeBody = parseScopeStatement(); | 2149 scopeBody = parseScopeStatement(); |
2150 else | 2150 else |
2151 scopeBody = parseNoScopeStatement(); | 2151 scopeBody = parseNoScopeStatement(); |
2152 return new ScopeGuardStatement(condition, scopeBody); | 2152 return new ScopeGuardStatement(condition, scopeBody); |
2153 } | 2153 } |
2154 | 2154 |
2155 Statement parseVolatileStatement() | 2155 Statement parseVolatileStatement() |
2156 { | 2156 { |
2157 assert(token.type == T.Volatile); | 2157 assert(token.kind == T.Volatile); |
2158 nT(); | 2158 nT(); |
2159 Statement volatileBody; | 2159 Statement volatileBody; |
2160 if (token.type == T.Semicolon) | 2160 if (token.kind == T.Semicolon) |
2161 nT(); | 2161 nT(); |
2162 else if (token.type == T.LBrace) | 2162 else if (token.kind == T.LBrace) |
2163 volatileBody = parseScopeStatement(); | 2163 volatileBody = parseScopeStatement(); |
2164 else | 2164 else |
2165 volatileBody = parseStatement(); | 2165 volatileBody = parseStatement(); |
2166 return new VolatileStatement(volatileBody); | 2166 return new VolatileStatement(volatileBody); |
2167 } | 2167 } |
2168 | 2168 |
2169 Statement parsePragmaStatement() | 2169 Statement parsePragmaStatement() |
2170 { | 2170 { |
2171 assert(token.type == T.Pragma); | 2171 assert(token.kind == T.Pragma); |
2172 nT(); | 2172 nT(); |
2173 | 2173 |
2174 Identifier* ident; | 2174 Identifier* ident; |
2175 Expression[] args; | 2175 Expression[] args; |
2176 Statement pragmaBody; | 2176 Statement pragmaBody; |
2187 return new PragmaStatement(ident, args, pragmaBody); | 2187 return new PragmaStatement(ident, args, pragmaBody); |
2188 } | 2188 } |
2189 | 2189 |
2190 Statement parseStaticIfStatement() | 2190 Statement parseStaticIfStatement() |
2191 { | 2191 { |
2192 assert(token.type == T.Static); | 2192 assert(token.kind == T.Static); |
2193 nT(); | 2193 nT(); |
2194 assert(token.type == T.If); | 2194 assert(token.kind == T.If); |
2195 nT(); | 2195 nT(); |
2196 Expression condition; | 2196 Expression condition; |
2197 Statement ifBody, elseBody; | 2197 Statement ifBody, elseBody; |
2198 | 2198 |
2199 require(T.LParen); | 2199 require(T.LParen); |
2205 return new StaticIfStatement(condition, ifBody, elseBody); | 2205 return new StaticIfStatement(condition, ifBody, elseBody); |
2206 } | 2206 } |
2207 | 2207 |
2208 Statement parseStaticAssertStatement() | 2208 Statement parseStaticAssertStatement() |
2209 { | 2209 { |
2210 assert(token.type == T.Static); | 2210 assert(token.kind == T.Static); |
2211 nT(); | 2211 nT(); |
2212 assert(token.type == T.Assert); | 2212 assert(token.kind == T.Assert); |
2213 nT(); | 2213 nT(); |
2214 Expression condition, message; | 2214 Expression condition, message; |
2215 require(T.LParen); | 2215 require(T.LParen); |
2216 condition = parseAssignExpression(); // Condition. | 2216 condition = parseAssignExpression(); // Condition. |
2217 if (skipped(T.Comma)) | 2217 if (skipped(T.Comma)) |
2221 return new StaticAssertStatement(condition, message); | 2221 return new StaticAssertStatement(condition, message); |
2222 } | 2222 } |
2223 | 2223 |
2224 Statement parseDebugStatement() | 2224 Statement parseDebugStatement() |
2225 { | 2225 { |
2226 assert(token.type == T.Debug); | 2226 assert(token.kind == T.Debug); |
2227 nT(); // Skip debug keyword. | 2227 nT(); // Skip debug keyword. |
2228 | 2228 |
2229 Token* cond; | 2229 Token* cond; |
2230 Statement debugBody, elseBody; | 2230 Statement debugBody, elseBody; |
2231 | 2231 |
2245 return new DebugStatement(cond, debugBody, elseBody); | 2245 return new DebugStatement(cond, debugBody, elseBody); |
2246 } | 2246 } |
2247 | 2247 |
2248 Statement parseVersionStatement() | 2248 Statement parseVersionStatement() |
2249 { | 2249 { |
2250 assert(token.type == T.Version); | 2250 assert(token.kind == T.Version); |
2251 nT(); // Skip version keyword. | 2251 nT(); // Skip version keyword. |
2252 | 2252 |
2253 Token* cond; | 2253 Token* cond; |
2254 Statement versionBody, elseBody; | 2254 Statement versionBody, elseBody; |
2255 | 2255 |
2270 + Assembler parsing methods + | 2270 + Assembler parsing methods + |
2271 +++++++++++++++++++++++++++++/ | 2271 +++++++++++++++++++++++++++++/ |
2272 | 2272 |
2273 Statement parseAsmStatement() | 2273 Statement parseAsmStatement() |
2274 { | 2274 { |
2275 assert(token.type == T.Asm); | 2275 assert(token.kind == T.Asm); |
2276 nT(); // Skip asm keyword. | 2276 nT(); // Skip asm keyword. |
2277 require(T.LBrace); | 2277 require(T.LBrace); |
2278 auto ss = new Statements; | 2278 auto ss = new Statements; |
2279 while (token.type != T.RBrace && token.type != T.EOF) | 2279 while (token.kind != T.RBrace && token.kind != T.EOF) |
2280 ss ~= parseAsmInstruction(); | 2280 ss ~= parseAsmInstruction(); |
2281 require(T.RBrace); | 2281 require(T.RBrace); |
2282 return new AsmStatement(ss); | 2282 return new AsmStatement(ss); |
2283 } | 2283 } |
2284 | 2284 |
2285 Statement parseAsmInstruction() | 2285 Statement parseAsmInstruction() |
2286 { | 2286 { |
2287 auto begin = token; | 2287 auto begin = token; |
2288 Statement s; | 2288 Statement s; |
2289 Identifier* ident; | 2289 Identifier* ident; |
2290 switch (token.type) | 2290 switch (token.kind) |
2291 { | 2291 { |
2292 // Keywords that are valid opcodes. | 2292 // Keywords that are valid opcodes. |
2293 case T.In, T.Int, T.Out: | 2293 case T.In, T.Int, T.Out: |
2294 ident = token.ident; | 2294 ident = token.ident; |
2295 nT(); | 2295 nT(); |
2308 // Opcode ; | 2308 // Opcode ; |
2309 // Opcode Operands ; | 2309 // Opcode Operands ; |
2310 // Opcode | 2310 // Opcode |
2311 // Identifier | 2311 // Identifier |
2312 Expression[] es; | 2312 Expression[] es; |
2313 if (token.type != T.Semicolon) | 2313 if (token.kind != T.Semicolon) |
2314 do | 2314 do |
2315 es ~= parseAsmExpression(); | 2315 es ~= parseAsmExpression(); |
2316 while (skipped(T.Comma)) | 2316 while (skipped(T.Comma)) |
2317 require(T.Semicolon); | 2317 require(T.Semicolon); |
2318 s = new AsmInstruction(ident, es); | 2318 s = new AsmInstruction(ident, es); |
2319 break; | 2319 break; |
2320 case T.Align: | 2320 case T.Align: |
2321 // align Integer; | 2321 // align Integer; |
2322 nT(); | 2322 nT(); |
2323 int number = -1; | 2323 int number = -1; |
2324 if (token.type == T.Int32) | 2324 if (token.kind == T.Int32) |
2325 (number = token.int_), nT(); | 2325 (number = token.int_), nT(); |
2326 else | 2326 else |
2327 error(token, MSG.ExpectedIntegerAfterAlign, token.srcText); | 2327 error(token, MSG.ExpectedIntegerAfterAlign, token.srcText); |
2328 require(T.Semicolon); | 2328 require(T.Semicolon); |
2329 s = new AsmAlignStatement(number); | 2329 s = new AsmAlignStatement(number); |
2336 s = new IllegalAsmInstruction(); | 2336 s = new IllegalAsmInstruction(); |
2337 // Skip to next valid token. | 2337 // Skip to next valid token. |
2338 do | 2338 do |
2339 nT(); | 2339 nT(); |
2340 while (!token.isAsmInstructionStart && | 2340 while (!token.isAsmInstructionStart && |
2341 token.type != T.RBrace && | 2341 token.kind != T.RBrace && |
2342 token.type != T.EOF) | 2342 token.kind != T.EOF) |
2343 auto text = Token.textSpan(begin, this.prevToken); | 2343 auto text = Token.textSpan(begin, this.prevToken); |
2344 error(begin, MSG.IllegalAsmInstruction, text); | 2344 error(begin, MSG.IllegalAsmInstruction, text); |
2345 } | 2345 } |
2346 set(s, begin); | 2346 set(s, begin); |
2347 return s; | 2347 return s; |
2367 Expression parseAsmOrOrExpression() | 2367 Expression parseAsmOrOrExpression() |
2368 { | 2368 { |
2369 alias parseAsmAndAndExpression parseNext; | 2369 alias parseAsmAndAndExpression parseNext; |
2370 auto begin = token; | 2370 auto begin = token; |
2371 auto e = parseNext(); | 2371 auto e = parseNext(); |
2372 while (token.type == T.OrLogical) | 2372 while (token.kind == T.OrLogical) |
2373 { | 2373 { |
2374 auto tok = token; | 2374 auto tok = token; |
2375 nT(); | 2375 nT(); |
2376 e = new OrOrExpression(e, parseNext(), tok); | 2376 e = new OrOrExpression(e, parseNext(), tok); |
2377 set(e, begin); | 2377 set(e, begin); |
2382 Expression parseAsmAndAndExpression() | 2382 Expression parseAsmAndAndExpression() |
2383 { | 2383 { |
2384 alias parseAsmOrExpression parseNext; | 2384 alias parseAsmOrExpression parseNext; |
2385 auto begin = token; | 2385 auto begin = token; |
2386 auto e = parseNext(); | 2386 auto e = parseNext(); |
2387 while (token.type == T.AndLogical) | 2387 while (token.kind == T.AndLogical) |
2388 { | 2388 { |
2389 auto tok = token; | 2389 auto tok = token; |
2390 nT(); | 2390 nT(); |
2391 e = new AndAndExpression(e, parseNext(), tok); | 2391 e = new AndAndExpression(e, parseNext(), tok); |
2392 set(e, begin); | 2392 set(e, begin); |
2397 Expression parseAsmOrExpression() | 2397 Expression parseAsmOrExpression() |
2398 { | 2398 { |
2399 alias parseAsmXorExpression parseNext; | 2399 alias parseAsmXorExpression parseNext; |
2400 auto begin = token; | 2400 auto begin = token; |
2401 auto e = parseNext(); | 2401 auto e = parseNext(); |
2402 while (token.type == T.OrBinary) | 2402 while (token.kind == T.OrBinary) |
2403 { | 2403 { |
2404 auto tok = token; | 2404 auto tok = token; |
2405 nT(); | 2405 nT(); |
2406 e = new OrExpression(e, parseNext(), tok); | 2406 e = new OrExpression(e, parseNext(), tok); |
2407 set(e, begin); | 2407 set(e, begin); |
2412 Expression parseAsmXorExpression() | 2412 Expression parseAsmXorExpression() |
2413 { | 2413 { |
2414 alias parseAsmAndExpression parseNext; | 2414 alias parseAsmAndExpression parseNext; |
2415 auto begin = token; | 2415 auto begin = token; |
2416 auto e = parseNext(); | 2416 auto e = parseNext(); |
2417 while (token.type == T.Xor) | 2417 while (token.kind == T.Xor) |
2418 { | 2418 { |
2419 auto tok = token; | 2419 auto tok = token; |
2420 nT(); | 2420 nT(); |
2421 e = new XorExpression(e, parseNext(), tok); | 2421 e = new XorExpression(e, parseNext(), tok); |
2422 set(e, begin); | 2422 set(e, begin); |
2427 Expression parseAsmAndExpression() | 2427 Expression parseAsmAndExpression() |
2428 { | 2428 { |
2429 alias parseAsmCmpExpression parseNext; | 2429 alias parseAsmCmpExpression parseNext; |
2430 auto begin = token; | 2430 auto begin = token; |
2431 auto e = parseNext(); | 2431 auto e = parseNext(); |
2432 while (token.type == T.AndBinary) | 2432 while (token.kind == T.AndBinary) |
2433 { | 2433 { |
2434 auto tok = token; | 2434 auto tok = token; |
2435 nT(); | 2435 nT(); |
2436 e = new AndExpression(e, parseNext(), tok); | 2436 e = new AndExpression(e, parseNext(), tok); |
2437 set(e, begin); | 2437 set(e, begin); |
2444 alias parseAsmShiftExpression parseNext; | 2444 alias parseAsmShiftExpression parseNext; |
2445 auto begin = token; | 2445 auto begin = token; |
2446 auto e = parseNext(); | 2446 auto e = parseNext(); |
2447 | 2447 |
2448 auto operator = token; | 2448 auto operator = token; |
2449 switch (operator.type) | 2449 switch (operator.kind) |
2450 { | 2450 { |
2451 case T.Equal, T.NotEqual: | 2451 case T.Equal, T.NotEqual: |
2452 nT(); | 2452 nT(); |
2453 e = new EqualExpression(e, parseNext(), operator); | 2453 e = new EqualExpression(e, parseNext(), operator); |
2454 break; | 2454 break; |
2469 auto begin = token; | 2469 auto begin = token; |
2470 auto e = parseNext(); | 2470 auto e = parseNext(); |
2471 while (1) | 2471 while (1) |
2472 { | 2472 { |
2473 auto operator = token; | 2473 auto operator = token; |
2474 switch (operator.type) | 2474 switch (operator.kind) |
2475 { | 2475 { |
2476 case T.LShift: nT(); e = new LShiftExpression(e, parseNext(), operator); break; | 2476 case T.LShift: nT(); e = new LShiftExpression(e, parseNext(), operator); break; |
2477 case T.RShift: nT(); e = new RShiftExpression(e, parseNext(), operator); break; | 2477 case T.RShift: nT(); e = new RShiftExpression(e, parseNext(), operator); break; |
2478 case T.URShift: nT(); e = new URShiftExpression(e, parseNext(), operator); break; | 2478 case T.URShift: nT(); e = new URShiftExpression(e, parseNext(), operator); break; |
2479 default: | 2479 default: |
2490 auto begin = token; | 2490 auto begin = token; |
2491 auto e = parseNext(); | 2491 auto e = parseNext(); |
2492 while (1) | 2492 while (1) |
2493 { | 2493 { |
2494 auto operator = token; | 2494 auto operator = token; |
2495 switch (operator.type) | 2495 switch (operator.kind) |
2496 { | 2496 { |
2497 case T.Plus: nT(); e = new PlusExpression(e, parseNext(), operator); break; | 2497 case T.Plus: nT(); e = new PlusExpression(e, parseNext(), operator); break; |
2498 case T.Minus: nT(); e = new MinusExpression(e, parseNext(), operator); break; | 2498 case T.Minus: nT(); e = new MinusExpression(e, parseNext(), operator); break; |
2499 // Not allowed in asm | 2499 // Not allowed in asm |
2500 //case T.Tilde: nT(); e = new CatExpression(e, parseNext(), operator); break; | 2500 //case T.Tilde: nT(); e = new CatExpression(e, parseNext(), operator); break; |
2512 auto begin = token; | 2512 auto begin = token; |
2513 auto e = parseNext(); | 2513 auto e = parseNext(); |
2514 while (1) | 2514 while (1) |
2515 { | 2515 { |
2516 auto operator = token; | 2516 auto operator = token; |
2517 switch (operator.type) | 2517 switch (operator.kind) |
2518 { | 2518 { |
2519 case T.Mul: nT(); e = new MulExpression(e, parseNext(), operator); break; | 2519 case T.Mul: nT(); e = new MulExpression(e, parseNext(), operator); break; |
2520 case T.Div: nT(); e = new DivExpression(e, parseNext(), operator); break; | 2520 case T.Div: nT(); e = new DivExpression(e, parseNext(), operator); break; |
2521 case T.Mod: nT(); e = new ModExpression(e, parseNext(), operator); break; | 2521 case T.Mod: nT(); e = new ModExpression(e, parseNext(), operator); break; |
2522 default: | 2522 default: |
2542 | 2542 |
2543 Expression parseAsmUnaryExpression() | 2543 Expression parseAsmUnaryExpression() |
2544 { | 2544 { |
2545 auto begin = token; | 2545 auto begin = token; |
2546 Expression e; | 2546 Expression e; |
2547 switch (token.type) | 2547 switch (token.kind) |
2548 { | 2548 { |
2549 case T.Byte, T.Short, T.Int, | 2549 case T.Byte, T.Short, T.Int, |
2550 T.Float, T.Double, T.Real: | 2550 T.Float, T.Double, T.Real: |
2551 goto LAsmTypePrefix; | 2551 goto LAsmTypePrefix; |
2552 case T.Identifier: | 2552 case T.Identifier: |
2554 { | 2554 { |
2555 case ID.near, ID.far,/* "byte", "short", "int",*/ | 2555 case ID.near, ID.far,/* "byte", "short", "int",*/ |
2556 ID.word, ID.dword, ID.qword/*, "float", "double", "real"*/: | 2556 ID.word, ID.dword, ID.qword/*, "float", "double", "real"*/: |
2557 LAsmTypePrefix: | 2557 LAsmTypePrefix: |
2558 nT(); | 2558 nT(); |
2559 if (token.type == T.Identifier && token.ident is Ident.ptr) | 2559 if (token.kind == T.Identifier && token.ident is Ident.ptr) |
2560 nT(); | 2560 nT(); |
2561 else | 2561 else |
2562 error(MID.ExpectedButFound, "ptr", token.srcText); | 2562 error(MID.ExpectedButFound, "ptr", token.srcText); |
2563 e = new AsmTypeExpression(parseAsmExpression()); | 2563 e = new AsmTypeExpression(parseAsmExpression()); |
2564 break; | 2564 break; |
2607 | 2607 |
2608 Expression parseAsmPrimaryExpression() | 2608 Expression parseAsmPrimaryExpression() |
2609 { | 2609 { |
2610 auto begin = token; | 2610 auto begin = token; |
2611 Expression e; | 2611 Expression e; |
2612 switch (token.type) | 2612 switch (token.kind) |
2613 { | 2613 { |
2614 case T.Int32, T.Int64, T.Uint32, T.Uint64: | 2614 case T.Int32, T.Int64, T.Uint32, T.Uint64: |
2615 e = new IntExpression(token); | 2615 e = new IntExpression(token); |
2616 nT(); | 2616 nT(); |
2617 break; | 2617 break; |
2645 nT(); | 2645 nT(); |
2646 // (1) - (7) | 2646 // (1) - (7) |
2647 int number = -1; | 2647 int number = -1; |
2648 if (skipped(T.LParen)) | 2648 if (skipped(T.LParen)) |
2649 { | 2649 { |
2650 if (token.type == T.Int32) | 2650 if (token.kind == T.Int32) |
2651 (number = token.int_), nT(); | 2651 (number = token.int_), nT(); |
2652 else | 2652 else |
2653 expected(T.Int32); | 2653 expected(T.Int32); |
2654 require(T.RParen); | 2654 require(T.RParen); |
2655 } | 2655 } |
2660 // TODO: is the colon-number part optional? | 2660 // TODO: is the colon-number part optional? |
2661 int number = -1; | 2661 int number = -1; |
2662 if (skipped(T.Colon)) | 2662 if (skipped(T.Colon)) |
2663 { | 2663 { |
2664 // :0, :4, :8 | 2664 // :0, :4, :8 |
2665 if (token.type == T.Int32) | 2665 if (token.kind == T.Int32) |
2666 (number = token.int_), nT(); | 2666 (number = token.int_), nT(); |
2667 if (number != 0 && number != 4 && number != 8) | 2667 if (number != 0 && number != 4 && number != 8) |
2668 error(MID.ExpectedButFound, "0, 4 or 8", token.srcText); | 2668 error(MID.ExpectedButFound, "0, 4 or 8", token.srcText); |
2669 } | 2669 } |
2670 e = new AsmRegisterExpression(register, number); | 2670 e = new AsmRegisterExpression(register, number); |
2715 Expression parseExpression() | 2715 Expression parseExpression() |
2716 { | 2716 { |
2717 alias parseAssignExpression parseNext; | 2717 alias parseAssignExpression parseNext; |
2718 auto begin = token; | 2718 auto begin = token; |
2719 auto e = parseNext(); | 2719 auto e = parseNext(); |
2720 while (token.type == T.Comma) | 2720 while (token.kind == T.Comma) |
2721 { | 2721 { |
2722 auto comma = token; | 2722 auto comma = token; |
2723 nT(); | 2723 nT(); |
2724 e = new CommaExpression(e, parseNext(), comma); | 2724 e = new CommaExpression(e, parseNext(), comma); |
2725 set(e, begin); | 2725 set(e, begin); |
2730 Expression parseAssignExpression() | 2730 Expression parseAssignExpression() |
2731 { | 2731 { |
2732 alias parseAssignExpression parseNext; | 2732 alias parseAssignExpression parseNext; |
2733 auto begin = token; | 2733 auto begin = token; |
2734 auto e = parseCondExpression(); | 2734 auto e = parseCondExpression(); |
2735 switch (token.type) | 2735 switch (token.kind) |
2736 { | 2736 { |
2737 case T.Assign: | 2737 case T.Assign: |
2738 nT(); e = new AssignExpression(e, parseNext()); break; | 2738 nT(); e = new AssignExpression(e, parseNext()); break; |
2739 case T.LShiftAssign: | 2739 case T.LShiftAssign: |
2740 nT(); e = new LShiftAssignExpression(e, parseNext()); break; | 2740 nT(); e = new LShiftAssignExpression(e, parseNext()); break; |
2769 | 2769 |
2770 Expression parseCondExpression() | 2770 Expression parseCondExpression() |
2771 { | 2771 { |
2772 auto begin = token; | 2772 auto begin = token; |
2773 auto e = parseOrOrExpression(); | 2773 auto e = parseOrOrExpression(); |
2774 if (token.type == T.Question) | 2774 if (token.kind == T.Question) |
2775 { | 2775 { |
2776 auto tok = token; | 2776 auto tok = token; |
2777 nT(); | 2777 nT(); |
2778 auto iftrue = parseExpression(); | 2778 auto iftrue = parseExpression(); |
2779 require(T.Colon); | 2779 require(T.Colon); |
2787 Expression parseOrOrExpression() | 2787 Expression parseOrOrExpression() |
2788 { | 2788 { |
2789 alias parseAndAndExpression parseNext; | 2789 alias parseAndAndExpression parseNext; |
2790 auto begin = token; | 2790 auto begin = token; |
2791 auto e = parseNext(); | 2791 auto e = parseNext(); |
2792 while (token.type == T.OrLogical) | 2792 while (token.kind == T.OrLogical) |
2793 { | 2793 { |
2794 auto tok = token; | 2794 auto tok = token; |
2795 nT(); | 2795 nT(); |
2796 e = new OrOrExpression(e, parseNext(), tok); | 2796 e = new OrOrExpression(e, parseNext(), tok); |
2797 set(e, begin); | 2797 set(e, begin); |
2802 Expression parseAndAndExpression() | 2802 Expression parseAndAndExpression() |
2803 { | 2803 { |
2804 alias parseOrExpression parseNext; | 2804 alias parseOrExpression parseNext; |
2805 auto begin = token; | 2805 auto begin = token; |
2806 auto e = parseNext(); | 2806 auto e = parseNext(); |
2807 while (token.type == T.AndLogical) | 2807 while (token.kind == T.AndLogical) |
2808 { | 2808 { |
2809 auto tok = token; | 2809 auto tok = token; |
2810 nT(); | 2810 nT(); |
2811 e = new AndAndExpression(e, parseNext(), tok); | 2811 e = new AndAndExpression(e, parseNext(), tok); |
2812 set(e, begin); | 2812 set(e, begin); |
2817 Expression parseOrExpression() | 2817 Expression parseOrExpression() |
2818 { | 2818 { |
2819 alias parseXorExpression parseNext; | 2819 alias parseXorExpression parseNext; |
2820 auto begin = token; | 2820 auto begin = token; |
2821 auto e = parseNext(); | 2821 auto e = parseNext(); |
2822 while (token.type == T.OrBinary) | 2822 while (token.kind == T.OrBinary) |
2823 { | 2823 { |
2824 auto tok = token; | 2824 auto tok = token; |
2825 nT(); | 2825 nT(); |
2826 e = new OrExpression(e, parseNext(), tok); | 2826 e = new OrExpression(e, parseNext(), tok); |
2827 set(e, begin); | 2827 set(e, begin); |
2832 Expression parseXorExpression() | 2832 Expression parseXorExpression() |
2833 { | 2833 { |
2834 alias parseAndExpression parseNext; | 2834 alias parseAndExpression parseNext; |
2835 auto begin = token; | 2835 auto begin = token; |
2836 auto e = parseNext(); | 2836 auto e = parseNext(); |
2837 while (token.type == T.Xor) | 2837 while (token.kind == T.Xor) |
2838 { | 2838 { |
2839 auto tok = token; | 2839 auto tok = token; |
2840 nT(); | 2840 nT(); |
2841 e = new XorExpression(e, parseNext(), tok); | 2841 e = new XorExpression(e, parseNext(), tok); |
2842 set(e, begin); | 2842 set(e, begin); |
2847 Expression parseAndExpression() | 2847 Expression parseAndExpression() |
2848 { | 2848 { |
2849 alias parseCmpExpression parseNext; | 2849 alias parseCmpExpression parseNext; |
2850 auto begin = token; | 2850 auto begin = token; |
2851 auto e = parseNext(); | 2851 auto e = parseNext(); |
2852 while (token.type == T.AndBinary) | 2852 while (token.kind == T.AndBinary) |
2853 { | 2853 { |
2854 auto tok = token; | 2854 auto tok = token; |
2855 nT(); | 2855 nT(); |
2856 e = new AndExpression(e, parseNext(), tok); | 2856 e = new AndExpression(e, parseNext(), tok); |
2857 set(e, begin); | 2857 set(e, begin); |
2864 alias parseShiftExpression parseNext; | 2864 alias parseShiftExpression parseNext; |
2865 auto begin = token; | 2865 auto begin = token; |
2866 auto e = parseShiftExpression(); | 2866 auto e = parseShiftExpression(); |
2867 | 2867 |
2868 auto operator = token; | 2868 auto operator = token; |
2869 switch (operator.type) | 2869 switch (operator.kind) |
2870 { | 2870 { |
2871 case T.Equal, T.NotEqual: | 2871 case T.Equal, T.NotEqual: |
2872 nT(); | 2872 nT(); |
2873 e = new EqualExpression(e, parseNext(), operator); | 2873 e = new EqualExpression(e, parseNext(), operator); |
2874 break; | 2874 break; |
2904 auto begin = token; | 2904 auto begin = token; |
2905 auto e = parseNext(); | 2905 auto e = parseNext(); |
2906 while (1) | 2906 while (1) |
2907 { | 2907 { |
2908 auto operator = token; | 2908 auto operator = token; |
2909 switch (operator.type) | 2909 switch (operator.kind) |
2910 { | 2910 { |
2911 case T.LShift: nT(); e = new LShiftExpression(e, parseNext(), operator); break; | 2911 case T.LShift: nT(); e = new LShiftExpression(e, parseNext(), operator); break; |
2912 case T.RShift: nT(); e = new RShiftExpression(e, parseNext(), operator); break; | 2912 case T.RShift: nT(); e = new RShiftExpression(e, parseNext(), operator); break; |
2913 case T.URShift: nT(); e = new URShiftExpression(e, parseNext(), operator); break; | 2913 case T.URShift: nT(); e = new URShiftExpression(e, parseNext(), operator); break; |
2914 default: | 2914 default: |
2925 auto begin = token; | 2925 auto begin = token; |
2926 auto e = parseNext(); | 2926 auto e = parseNext(); |
2927 while (1) | 2927 while (1) |
2928 { | 2928 { |
2929 auto operator = token; | 2929 auto operator = token; |
2930 switch (operator.type) | 2930 switch (operator.kind) |
2931 { | 2931 { |
2932 case T.Plus: nT(); e = new PlusExpression(e, parseNext(), operator); break; | 2932 case T.Plus: nT(); e = new PlusExpression(e, parseNext(), operator); break; |
2933 case T.Minus: nT(); e = new MinusExpression(e, parseNext(), operator); break; | 2933 case T.Minus: nT(); e = new MinusExpression(e, parseNext(), operator); break; |
2934 case T.Tilde: nT(); e = new CatExpression(e, parseNext(), operator); break; | 2934 case T.Tilde: nT(); e = new CatExpression(e, parseNext(), operator); break; |
2935 default: | 2935 default: |
2946 auto begin = token; | 2946 auto begin = token; |
2947 auto e = parseNext(); | 2947 auto e = parseNext(); |
2948 while (1) | 2948 while (1) |
2949 { | 2949 { |
2950 auto operator = token; | 2950 auto operator = token; |
2951 switch (operator.type) | 2951 switch (operator.kind) |
2952 { | 2952 { |
2953 case T.Mul: nT(); e = new MulExpression(e, parseNext(), operator); break; | 2953 case T.Mul: nT(); e = new MulExpression(e, parseNext(), operator); break; |
2954 case T.Div: nT(); e = new DivExpression(e, parseNext(), operator); break; | 2954 case T.Div: nT(); e = new DivExpression(e, parseNext(), operator); break; |
2955 case T.Mod: nT(); e = new ModExpression(e, parseNext(), operator); break; | 2955 case T.Mod: nT(); e = new ModExpression(e, parseNext(), operator); break; |
2956 default: | 2956 default: |
2971 { | 2971 { |
2972 e = new DotExpression(e, parseNewOrIdentifierExpression()); | 2972 e = new DotExpression(e, parseNewOrIdentifierExpression()); |
2973 set(e, begin); | 2973 set(e, begin); |
2974 } | 2974 } |
2975 | 2975 |
2976 switch (token.type) | 2976 switch (token.kind) |
2977 { | 2977 { |
2978 case T.PlusPlus: | 2978 case T.PlusPlus: |
2979 e = new PostIncrExpression(e); | 2979 e = new PostIncrExpression(e); |
2980 break; | 2980 break; |
2981 case T.MinusMinus: | 2981 case T.MinusMinus: |
2986 goto Lset; | 2986 goto Lset; |
2987 case T.LBracket: | 2987 case T.LBracket: |
2988 // parse Slice- and IndexExpression | 2988 // parse Slice- and IndexExpression |
2989 nT(); | 2989 nT(); |
2990 // [] is a SliceExpression | 2990 // [] is a SliceExpression |
2991 if (token.type == T.RBracket) | 2991 if (token.kind == T.RBracket) |
2992 { | 2992 { |
2993 e = new SliceExpression(e, null, null); | 2993 e = new SliceExpression(e, null, null); |
2994 break; | 2994 break; |
2995 } | 2995 } |
2996 | 2996 |
3023 | 3023 |
3024 Expression parseUnaryExpression() | 3024 Expression parseUnaryExpression() |
3025 { | 3025 { |
3026 auto begin = token; | 3026 auto begin = token; |
3027 Expression e; | 3027 Expression e; |
3028 switch (token.type) | 3028 switch (token.kind) |
3029 { | 3029 { |
3030 case T.AndBinary: | 3030 case T.AndBinary: |
3031 nT(); | 3031 nT(); |
3032 e = new AddressExpression(parseUnaryExpression()); | 3032 e = new AddressExpression(parseUnaryExpression()); |
3033 break; | 3033 break; |
3064 e = new DeleteExpression(parseUnaryExpression()); | 3064 e = new DeleteExpression(parseUnaryExpression()); |
3065 break; | 3065 break; |
3066 case T.Cast: | 3066 case T.Cast: |
3067 requireNext(T.LParen); | 3067 requireNext(T.LParen); |
3068 Type type; | 3068 Type type; |
3069 switch (token.type) | 3069 switch (token.kind) |
3070 { | 3070 { |
3071 version(D2) | 3071 version(D2) |
3072 { | 3072 { |
3073 auto begin2 = token; | 3073 auto begin2 = token; |
3074 case T.Const: | 3074 case T.Const: |
3130 { | 3130 { |
3131 auto begin = token; | 3131 auto begin = token; |
3132 auto ident = requireIdentifier(MSG.ExpectedAnIdentifier); | 3132 auto ident = requireIdentifier(MSG.ExpectedAnIdentifier); |
3133 Expression e; | 3133 Expression e; |
3134 // Peek for '(' to avoid matching: id !is id | 3134 // Peek for '(' to avoid matching: id !is id |
3135 if (token.type == T.Not && peekNext() == T.LParen) | 3135 if (token.kind == T.Not && peekNext() == T.LParen) |
3136 { // Identifier !( TemplateArguments ) | 3136 { // Identifier !( TemplateArguments ) |
3137 nT(); // Skip !. | 3137 nT(); // Skip !. |
3138 auto tparams = parseTemplateArguments(); | 3138 auto tparams = parseTemplateArguments(); |
3139 e = new TemplateInstanceExpression(ident, tparams); | 3139 e = new TemplateInstanceExpression(ident, tparams); |
3140 } | 3140 } |
3143 return set(e, begin); | 3143 return set(e, begin); |
3144 } | 3144 } |
3145 | 3145 |
3146 Expression parseNewOrIdentifierExpression() | 3146 Expression parseNewOrIdentifierExpression() |
3147 { | 3147 { |
3148 return token.type == T.New ? parseNewExpression() : parseIdentifierExpression(); | 3148 return token.kind == T.New ? parseNewExpression() : parseIdentifierExpression(); |
3149 } | 3149 } |
3150 | 3150 |
3151 Expression parsePrimaryExpression() | 3151 Expression parsePrimaryExpression() |
3152 { | 3152 { |
3153 auto begin = token; | 3153 auto begin = token; |
3154 Expression e; | 3154 Expression e; |
3155 switch (token.type) | 3155 switch (token.kind) |
3156 { | 3156 { |
3157 case T.Identifier: | 3157 case T.Identifier: |
3158 e = parseIdentifierExpression(); | 3158 e = parseIdentifierExpression(); |
3159 return e; | 3159 return e; |
3160 case T.Typeof: | 3160 case T.Typeof: |
3195 break; | 3195 break; |
3196 case T.String: | 3196 case T.String: |
3197 char[] str = token.str; | 3197 char[] str = token.str; |
3198 char postfix = token.pf; | 3198 char postfix = token.pf; |
3199 nT(); | 3199 nT(); |
3200 while (token.type == T.String) | 3200 while (token.kind == T.String) |
3201 { | 3201 { |
3202 if (postfix == '\0') | 3202 if (postfix == '\0') |
3203 postfix = token.pf; | 3203 postfix = token.pf; |
3204 else if (token.pf && token.pf != postfix) | 3204 else if (token.pf && token.pf != postfix) |
3205 error(token, MSG.StringPostfixMismatch); | 3205 error(token, MSG.StringPostfixMismatch); |
3219 | 3219 |
3220 nT(); | 3220 nT(); |
3221 if (!skipped(T.RBracket)) | 3221 if (!skipped(T.RBracket)) |
3222 { | 3222 { |
3223 e = parseAssignExpression(); | 3223 e = parseAssignExpression(); |
3224 if (token.type == T.Colon) | 3224 if (token.kind == T.Colon) |
3225 goto LparseAssocArray; | 3225 goto LparseAssocArray; |
3226 if (skipped(T.Comma)) | 3226 if (skipped(T.Comma)) |
3227 values = [e] ~ parseExpressionList(); | 3227 values = [e] ~ parseExpressionList(); |
3228 require(T.RBracket); | 3228 require(T.RBracket); |
3229 } | 3229 } |
3242 { | 3242 { |
3243 keys ~= parseAssignExpression(); | 3243 keys ~= parseAssignExpression(); |
3244 require(T.Colon); | 3244 require(T.Colon); |
3245 LenterLoop: | 3245 LenterLoop: |
3246 values ~= parseAssignExpression(); | 3246 values ~= parseAssignExpression(); |
3247 if (token.type != T.Comma) | 3247 if (token.kind != T.Comma) |
3248 break; | 3248 break; |
3249 nT(); | 3249 nT(); |
3250 } | 3250 } |
3251 require(T.RBracket); | 3251 require(T.RBracket); |
3252 e = new AArrayLiteralExpression(keys, values); | 3252 e = new AArrayLiteralExpression(keys, values); |
3259 case T.Function, T.Delegate: | 3259 case T.Function, T.Delegate: |
3260 // FunctionLiteral := (function|delegate) Type? '(' ArgumentList ')' '{' Statements '}' | 3260 // FunctionLiteral := (function|delegate) Type? '(' ArgumentList ')' '{' Statements '}' |
3261 nT(); // Skip function|delegate token. | 3261 nT(); // Skip function|delegate token. |
3262 Type returnType; | 3262 Type returnType; |
3263 Parameters parameters; | 3263 Parameters parameters; |
3264 if (token.type != T.LBrace) | 3264 if (token.kind != T.LBrace) |
3265 { | 3265 { |
3266 if (token.type != T.LParen) // Optional return type | 3266 if (token.kind != T.LParen) // Optional return type |
3267 returnType = parseType(); | 3267 returnType = parseType(); |
3268 parameters = parseParameterList(); | 3268 parameters = parseParameterList(); |
3269 } | 3269 } |
3270 auto funcBody = parseFunctionBody(); | 3270 auto funcBody = parseFunctionBody(); |
3271 e = new FunctionLiteralExpression(returnType, parameters, funcBody); | 3271 e = new FunctionLiteralExpression(returnType, parameters, funcBody); |
3304 Identifier* ident; // optional Identifier | 3304 Identifier* ident; // optional Identifier |
3305 Token* opTok, specTok; | 3305 Token* opTok, specTok; |
3306 | 3306 |
3307 type = parseDeclarator(ident, true); | 3307 type = parseDeclarator(ident, true); |
3308 | 3308 |
3309 switch (token.type) | 3309 switch (token.kind) |
3310 { | 3310 { |
3311 case T.Colon, T.Equal: | 3311 case T.Colon, T.Equal: |
3312 opTok = token; | 3312 opTok = token; |
3313 nT(); | 3313 nT(); |
3314 switch (token.type) | 3314 switch (token.kind) |
3315 { | 3315 { |
3316 case T.Typedef, | 3316 case T.Typedef, |
3317 T.Struct, | 3317 T.Struct, |
3318 T.Union, | 3318 T.Union, |
3319 T.Class, | 3319 T.Class, |
3340 TemplateParameters tparams; | 3340 TemplateParameters tparams; |
3341 version(D2) | 3341 version(D2) |
3342 { | 3342 { |
3343 // is ( Type Identifier : TypeSpecialization , TemplateParameterList ) | 3343 // is ( Type Identifier : TypeSpecialization , TemplateParameterList ) |
3344 // is ( Type Identifier == TypeSpecialization , TemplateParameterList ) | 3344 // is ( Type Identifier == TypeSpecialization , TemplateParameterList ) |
3345 if (ident && specType && token.type == T.Comma) | 3345 if (ident && specType && token.kind == T.Comma) |
3346 tparams = parseTemplateParameterList2(); | 3346 tparams = parseTemplateParameterList2(); |
3347 } | 3347 } |
3348 require(T.RParen); | 3348 require(T.RParen); |
3349 e = new IsExpression(type, ident, opTok, specTok, specType, tparams); | 3349 e = new IsExpression(type, ident, opTok, specTok, specType, tparams); |
3350 break; | 3350 break; |
3368 case T.Traits: | 3368 case T.Traits: |
3369 nT(); | 3369 nT(); |
3370 require(T.LParen); | 3370 require(T.LParen); |
3371 auto id = requireIdentifier(MSG.ExpectedAnIdentifier); | 3371 auto id = requireIdentifier(MSG.ExpectedAnIdentifier); |
3372 TemplateArguments args; | 3372 TemplateArguments args; |
3373 if (token.type == T.Comma) | 3373 if (token.kind == T.Comma) |
3374 args = parseTemplateArguments2(); | 3374 args = parseTemplateArguments2(); |
3375 else | 3375 else |
3376 require(T.RParen); | 3376 require(T.RParen); |
3377 e = new TraitsExpression(id, args); | 3377 e = new TraitsExpression(id, args); |
3378 break; | 3378 break; |
3379 } | 3379 } |
3380 default: | 3380 default: |
3381 if (token.isIntegralType) | 3381 if (token.isIntegralType) |
3382 { // IntegralType . Identifier | 3382 { // IntegralType . Identifier |
3383 auto type = new IntegralType(token.type); | 3383 auto type = new IntegralType(token.kind); |
3384 nT(); | 3384 nT(); |
3385 set(type, begin); | 3385 set(type, begin); |
3386 require(T.Dot); | 3386 require(T.Dot); |
3387 auto ident = requireIdentifier(MSG.ExpectedIdAfterTypeDot); | 3387 auto ident = requireIdentifier(MSG.ExpectedIdAfterTypeDot); |
3388 e = new TypeDotIdExpression(type, ident); | 3388 e = new TypeDotIdExpression(type, ident); |
3408 } | 3408 } |
3409 | 3409 |
3410 Expression parseNewExpression(/*Expression e*/) | 3410 Expression parseNewExpression(/*Expression e*/) |
3411 { | 3411 { |
3412 auto begin = token; | 3412 auto begin = token; |
3413 assert(token.type == T.New); | 3413 assert(token.kind == T.New); |
3414 nT(); // Skip new keyword. | 3414 nT(); // Skip new keyword. |
3415 | 3415 |
3416 Expression[] newArguments; | 3416 Expression[] newArguments; |
3417 Expression[] ctorArguments; | 3417 Expression[] ctorArguments; |
3418 | 3418 |
3419 if (token.type == T.LParen) | 3419 if (token.kind == T.LParen) |
3420 newArguments = parseArguments(); | 3420 newArguments = parseArguments(); |
3421 | 3421 |
3422 // NewAnonClassExpression: | 3422 // NewAnonClassExpression: |
3423 // new (ArgumentList)opt class (ArgumentList)opt SuperClassopt InterfaceClassesopt ClassBody | 3423 // new (ArgumentList)opt class (ArgumentList)opt SuperClassopt InterfaceClassesopt ClassBody |
3424 if (skipped(T.Class)) | 3424 if (skipped(T.Class)) |
3425 { | 3425 { |
3426 if (token.type == T.LParen) | 3426 if (token.kind == T.LParen) |
3427 ctorArguments = parseArguments(); | 3427 ctorArguments = parseArguments(); |
3428 | 3428 |
3429 BaseClassType[] bases = token.type != T.LBrace ? parseBaseClasses(false) : null ; | 3429 BaseClassType[] bases = token.kind != T.LBrace ? parseBaseClasses(false) : null ; |
3430 | 3430 |
3431 auto decls = parseDeclarationDefinitionsBody(); | 3431 auto decls = parseDeclarationDefinitionsBody(); |
3432 return set(new NewAnonClassExpression(/*e, */newArguments, bases, ctorArguments, decls), begin); | 3432 return set(new NewAnonClassExpression(/*e, */newArguments, bases, ctorArguments, decls), begin); |
3433 } | 3433 } |
3434 | 3434 |
3436 // NewArguments Type [ AssignExpression ] | 3436 // NewArguments Type [ AssignExpression ] |
3437 // NewArguments Type ( ArgumentList ) | 3437 // NewArguments Type ( ArgumentList ) |
3438 // NewArguments Type | 3438 // NewArguments Type |
3439 auto type = parseType(); | 3439 auto type = parseType(); |
3440 | 3440 |
3441 if (token.type == T.LParen) | 3441 if (token.kind == T.LParen) |
3442 ctorArguments = parseArguments(); | 3442 ctorArguments = parseArguments(); |
3443 | 3443 |
3444 return set(new NewExpression(/*e, */newArguments, type, ctorArguments), begin); | 3444 return set(new NewExpression(/*e, */newArguments, type, ctorArguments), begin); |
3445 } | 3445 } |
3446 | 3446 |
3465 { | 3465 { |
3466 auto begin = token; | 3466 auto begin = token; |
3467 Type type; | 3467 Type type; |
3468 if (skipped(T.Dot)) | 3468 if (skipped(T.Dot)) |
3469 type = set(new ModuleScopeType(parseIdentifierType()), begin); | 3469 type = set(new ModuleScopeType(parseIdentifierType()), begin); |
3470 else if (token.type == T.Typeof) | 3470 else if (token.kind == T.Typeof) |
3471 { | 3471 { |
3472 type = parseTypeofType(); | 3472 type = parseTypeofType(); |
3473 if (token.type != T.Dot) | 3473 if (token.kind != T.Dot) |
3474 return type; | 3474 return type; |
3475 } | 3475 } |
3476 else | 3476 else |
3477 type = parseIdentifierType(); | 3477 type = parseIdentifierType(); |
3478 | 3478 |
3486 auto begin = token; | 3486 auto begin = token; |
3487 Type t; | 3487 Type t; |
3488 | 3488 |
3489 if (token.isIntegralType) | 3489 if (token.isIntegralType) |
3490 { | 3490 { |
3491 t = new IntegralType(token.type); | 3491 t = new IntegralType(token.kind); |
3492 nT(); | 3492 nT(); |
3493 } | 3493 } |
3494 else | 3494 else |
3495 switch (token.type) | 3495 switch (token.kind) |
3496 { | 3496 { |
3497 case T.Identifier, T.Typeof, T.Dot: | 3497 case T.Identifier, T.Typeof, T.Dot: |
3498 t = parseQualifiedType(); | 3498 t = parseQualifiedType(); |
3499 return t; | 3499 return t; |
3500 version(D2) | 3500 version(D2) |
3528 { | 3528 { |
3529 typeof(token) begin; | 3529 typeof(token) begin; |
3530 while (1) | 3530 while (1) |
3531 { | 3531 { |
3532 begin = token; | 3532 begin = token; |
3533 switch (token.type) | 3533 switch (token.kind) |
3534 { | 3534 { |
3535 case T.Mul: | 3535 case T.Mul: |
3536 t = new PointerType(t); | 3536 t = new PointerType(t); |
3537 nT(); | 3537 nT(); |
3538 break; | 3538 break; |
3539 case T.LBracket: | 3539 case T.LBracket: |
3540 t = parseArrayType(t); | 3540 t = parseArrayType(t); |
3541 continue; | 3541 continue; |
3542 case T.Function, T.Delegate: | 3542 case T.Function, T.Delegate: |
3543 TOK tok = token.type; | 3543 TOK tok = token.kind; |
3544 nT(); | 3544 nT(); |
3545 auto parameters = parseParameterList(); | 3545 auto parameters = parseParameterList(); |
3546 if (tok == T.Function) | 3546 if (tok == T.Function) |
3547 t = new FunctionType(t, parameters); | 3547 t = new FunctionType(t, parameters); |
3548 else | 3548 else |
3557 } | 3557 } |
3558 | 3558 |
3559 bool tokenAfterParenIs(TOK tok) | 3559 bool tokenAfterParenIs(TOK tok) |
3560 { | 3560 { |
3561 // We count nested parentheses tokens because template types may appear inside parameter lists; e.g. (int x, Foo!(int) y). | 3561 // We count nested parentheses tokens because template types may appear inside parameter lists; e.g. (int x, Foo!(int) y). |
3562 assert(token.type == T.LParen); | 3562 assert(token.kind == T.LParen); |
3563 Token* next = token; | 3563 Token* next = token; |
3564 uint level = 1; | 3564 uint level = 1; |
3565 Loop: | 3565 Loop: |
3566 while (1) | 3566 while (1) |
3567 { | 3567 { |
3568 lexer.peek(next); | 3568 lexer.peek(next); |
3569 switch (next.type) | 3569 switch (next.kind) |
3570 { | 3570 { |
3571 case T.RParen: | 3571 case T.RParen: |
3572 if (--level == 0) | 3572 if (--level == 0) |
3573 { // Last, closing parentheses found. | 3573 { // Last, closing parentheses found. |
3574 do | 3574 do |
3583 case T.EOF: | 3583 case T.EOF: |
3584 break Loop; | 3584 break Loop; |
3585 default: | 3585 default: |
3586 } | 3586 } |
3587 } | 3587 } |
3588 return next.type == tok; | 3588 return next.kind == tok; |
3589 } | 3589 } |
3590 | 3590 |
3591 /// Parse the C-style array types after the declarator. | 3591 /// Parse the C-style array types after the declarator. |
3592 Type parseDeclaratorSuffix(Type lhsType) | 3592 Type parseDeclaratorSuffix(Type lhsType) |
3593 { | 3593 { |
3596 // <- <- -> -. | 3596 // <- <- -> -. |
3597 // ^------------------´ | 3597 // ^------------------´ |
3598 // Resulting chain: [][32]*[3]int | 3598 // Resulting chain: [][32]*[3]int |
3599 Type parseNext() // Nested function required to accomplish this. | 3599 Type parseNext() // Nested function required to accomplish this. |
3600 { | 3600 { |
3601 if (token.type != T.LBracket) | 3601 if (token.kind != T.LBracket) |
3602 return lhsType; // Break recursion; return Type on the left hand side of the Identifier. | 3602 return lhsType; // Break recursion; return Type on the left hand side of the Identifier. |
3603 | 3603 |
3604 auto begin = token; | 3604 auto begin = token; |
3605 Type t; | 3605 Type t; |
3606 nT(); | 3606 nT(); |
3633 return parseNext(); | 3633 return parseNext(); |
3634 } | 3634 } |
3635 | 3635 |
3636 Type parseArrayType(Type t) | 3636 Type parseArrayType(Type t) |
3637 { | 3637 { |
3638 assert(token.type == T.LBracket); | 3638 assert(token.kind == T.LBracket); |
3639 auto begin = token; | 3639 auto begin = token; |
3640 nT(); | 3640 nT(); |
3641 if (skipped(T.RBracket)) | 3641 if (skipped(T.RBracket)) |
3642 t = new ArrayType(t); | 3642 t = new ArrayType(t); |
3643 else | 3643 else |
3665 return t; | 3665 return t; |
3666 } | 3666 } |
3667 | 3667 |
3668 Type parseCFunctionPointerType(Type type, ref Identifier* ident, bool optionalParamList) | 3668 Type parseCFunctionPointerType(Type type, ref Identifier* ident, bool optionalParamList) |
3669 { | 3669 { |
3670 assert(token.type == T.LParen); | 3670 assert(token.kind == T.LParen); |
3671 assert(type !is null); | 3671 assert(type !is null); |
3672 auto begin = token; | 3672 auto begin = token; |
3673 nT(); // Skip ( | 3673 nT(); // Skip ( |
3674 type = parseBasicType2(type); | 3674 type = parseBasicType2(type); |
3675 if (token.type == T.LParen) | 3675 if (token.kind == T.LParen) |
3676 { | 3676 { |
3677 // Can be nested. | 3677 // Can be nested. |
3678 type = parseCFunctionPointerType(type, ident, true); | 3678 type = parseCFunctionPointerType(type, ident, true); |
3679 } | 3679 } |
3680 else if (token.type == T.Identifier) | 3680 else if (token.kind == T.Identifier) |
3681 { | 3681 { |
3682 // The identifier of the function pointer and the declaration. | 3682 // The identifier of the function pointer and the declaration. |
3683 ident = token.ident; | 3683 ident = token.ident; |
3684 nT(); | 3684 nT(); |
3685 type = parseDeclaratorSuffix(type); | 3685 type = parseDeclaratorSuffix(type); |
3686 } | 3686 } |
3687 require(T.RParen); | 3687 require(T.RParen); |
3688 | 3688 |
3689 Parameters params; | 3689 Parameters params; |
3690 if (optionalParamList) | 3690 if (optionalParamList) |
3691 params = token.type == T.LParen ? parseParameterList() : null; | 3691 params = token.kind == T.LParen ? parseParameterList() : null; |
3692 else | 3692 else |
3693 params = parseParameterList(); | 3693 params = parseParameterList(); |
3694 | 3694 |
3695 type = new CFuncPointerType(type, params); | 3695 type = new CFuncPointerType(type, params); |
3696 return set(type, begin); | 3696 return set(type, begin); |
3698 | 3698 |
3699 Type parseDeclarator(ref Identifier* ident, bool identOptional = false) | 3699 Type parseDeclarator(ref Identifier* ident, bool identOptional = false) |
3700 { | 3700 { |
3701 auto t = parseType(); | 3701 auto t = parseType(); |
3702 | 3702 |
3703 if (token.type == T.LParen) | 3703 if (token.kind == T.LParen) |
3704 t = parseCFunctionPointerType(t, ident, true); | 3704 t = parseCFunctionPointerType(t, ident, true); |
3705 else if (token.type == T.Identifier) | 3705 else if (token.kind == T.Identifier) |
3706 { | 3706 { |
3707 ident = token.ident; | 3707 ident = token.ident; |
3708 nT(); | 3708 nT(); |
3709 t = parseDeclaratorSuffix(t); | 3709 t = parseDeclaratorSuffix(t); |
3710 } | 3710 } |
3735 ( ) | 3735 ( ) |
3736 ( ExpressionList ) | 3736 ( ExpressionList ) |
3737 +/ | 3737 +/ |
3738 Expression[] parseArguments() | 3738 Expression[] parseArguments() |
3739 { | 3739 { |
3740 assert(token.type == T.LParen); | 3740 assert(token.kind == T.LParen); |
3741 nT(); | 3741 nT(); |
3742 Expression[] args; | 3742 Expression[] args; |
3743 if (token.type != TOK.RParen) | 3743 if (token.kind != TOK.RParen) |
3744 args = parseExpressionList(); | 3744 args = parseExpressionList(); |
3745 require(TOK.RParen); | 3745 require(TOK.RParen); |
3746 return args; | 3746 return args; |
3747 } | 3747 } |
3748 | 3748 |
3786 pushParameter(); // type, ident and defValue will be null. | 3786 pushParameter(); // type, ident and defValue will be null. |
3787 break Loop; | 3787 break Loop; |
3788 } | 3788 } |
3789 | 3789 |
3790 Lstc_loop: | 3790 Lstc_loop: |
3791 switch (token.type) | 3791 switch (token.kind) |
3792 { | 3792 { |
3793 version(D2) | 3793 version(D2) |
3794 { | 3794 { |
3795 case T.Invariant: // D2.0 | 3795 case T.Invariant: // D2.0 |
3796 if (peekNext() == T.LParen) | 3796 if (peekNext() == T.LParen) |
3848 break Loop; | 3848 break Loop; |
3849 } | 3849 } |
3850 | 3850 |
3851 pushParameter(); | 3851 pushParameter(); |
3852 | 3852 |
3853 if (token.type != T.Comma) | 3853 if (token.kind != T.Comma) |
3854 break Loop; | 3854 break Loop; |
3855 nT(); | 3855 nT(); |
3856 } | 3856 } |
3857 } | 3857 } |
3858 require(T.RParen); | 3858 require(T.RParen); |
3861 | 3861 |
3862 TemplateArguments parseTemplateArguments() | 3862 TemplateArguments parseTemplateArguments() |
3863 { | 3863 { |
3864 TemplateArguments targs; | 3864 TemplateArguments targs; |
3865 require(T.LParen); | 3865 require(T.LParen); |
3866 if (token.type != T.RParen) | 3866 if (token.kind != T.RParen) |
3867 targs = parseTemplateArguments_(); | 3867 targs = parseTemplateArguments_(); |
3868 require(T.RParen); | 3868 require(T.RParen); |
3869 return targs; | 3869 return targs; |
3870 } | 3870 } |
3871 | 3871 |
3872 version(D2) | 3872 version(D2) |
3873 { | 3873 { |
3874 TemplateArguments parseTemplateArguments2() | 3874 TemplateArguments parseTemplateArguments2() |
3875 { | 3875 { |
3876 assert(token.type == T.Comma); | 3876 assert(token.kind == T.Comma); |
3877 nT(); | 3877 nT(); |
3878 TemplateArguments targs; | 3878 TemplateArguments targs; |
3879 if (token.type != T.RParen) | 3879 if (token.kind != T.RParen) |
3880 targs = parseTemplateArguments_(); | 3880 targs = parseTemplateArguments_(); |
3881 else | 3881 else |
3882 error(token, MSG.ExpectedTypeOrExpression); | 3882 error(token, MSG.ExpectedTypeOrExpression); |
3883 require(T.RParen); | 3883 require(T.RParen); |
3884 return targs; | 3884 return targs; |
3892 while (1) | 3892 while (1) |
3893 { | 3893 { |
3894 Type parseType_() | 3894 Type parseType_() |
3895 { | 3895 { |
3896 auto type = parseType(); | 3896 auto type = parseType(); |
3897 if (token.type == T.Comma || token.type == T.RParen) | 3897 if (token.kind == T.Comma || token.kind == T.RParen) |
3898 return type; | 3898 return type; |
3899 ++errorCount; // Cause try_() to fail. | 3899 ++errorCount; // Cause try_() to fail. |
3900 return null; | 3900 return null; |
3901 } | 3901 } |
3902 bool success; | 3902 bool success; |
3908 targs ~= typeArgument; | 3908 targs ~= typeArgument; |
3909 else | 3909 else |
3910 // TemplateArgument: | 3910 // TemplateArgument: |
3911 // AssignExpression | 3911 // AssignExpression |
3912 targs ~= parseAssignExpression(); | 3912 targs ~= parseAssignExpression(); |
3913 if (token.type != T.Comma) | 3913 if (token.kind != T.Comma) |
3914 break; // Exit loop. | 3914 break; // Exit loop. |
3915 nT(); | 3915 nT(); |
3916 } | 3916 } |
3917 set(targs, begin); | 3917 set(targs, begin); |
3918 return targs; | 3918 return targs; |
3920 | 3920 |
3921 TemplateParameters parseTemplateParameterList() | 3921 TemplateParameters parseTemplateParameterList() |
3922 { | 3922 { |
3923 TemplateParameters tparams; | 3923 TemplateParameters tparams; |
3924 require(T.LParen); | 3924 require(T.LParen); |
3925 if (token.type != T.RParen) | 3925 if (token.kind != T.RParen) |
3926 tparams = parseTemplateParameterList_(); | 3926 tparams = parseTemplateParameterList_(); |
3927 require(T.RParen); | 3927 require(T.RParen); |
3928 return tparams; | 3928 return tparams; |
3929 } | 3929 } |
3930 | 3930 |
3931 version(D2) | 3931 version(D2) |
3932 { | 3932 { |
3933 TemplateParameters parseTemplateParameterList2() | 3933 TemplateParameters parseTemplateParameterList2() |
3934 { | 3934 { |
3935 assert(token.type == T.Comma); | 3935 assert(token.kind == T.Comma); |
3936 nT(); | 3936 nT(); |
3937 TemplateParameters tparams; | 3937 TemplateParameters tparams; |
3938 if (token.type != T.RParen) | 3938 if (token.kind != T.RParen) |
3939 tparams = parseTemplateParameterList_(); | 3939 tparams = parseTemplateParameterList_(); |
3940 else | 3940 else |
3941 error(token, MSG.ExpectedTemplateParameters); | 3941 error(token, MSG.ExpectedTemplateParameters); |
3942 return tparams; | 3942 return tparams; |
3943 } | 3943 } |
3963 // = DefaultType | 3963 // = DefaultType |
3964 if (skipped(T.Assign)) | 3964 if (skipped(T.Assign)) |
3965 defType = parseType(); | 3965 defType = parseType(); |
3966 } | 3966 } |
3967 | 3967 |
3968 switch (token.type) | 3968 switch (token.kind) |
3969 { | 3969 { |
3970 case T.Alias: | 3970 case T.Alias: |
3971 // TemplateAliasParameter: | 3971 // TemplateAliasParameter: |
3972 // alias Identifier | 3972 // alias Identifier |
3973 nT(); // Skip alias keyword. | 3973 nT(); // Skip alias keyword. |
3982 case T.Ellipses: | 3982 case T.Ellipses: |
3983 // TemplateTupleParameter: | 3983 // TemplateTupleParameter: |
3984 // Identifier ... | 3984 // Identifier ... |
3985 nT(); // Skip Identifier. | 3985 nT(); // Skip Identifier. |
3986 nT(); // Skip Ellipses. | 3986 nT(); // Skip Ellipses. |
3987 if (token.type == T.Comma) | 3987 if (token.kind == T.Comma) |
3988 error(MID.TemplateTupleParameter); | 3988 error(MID.TemplateTupleParameter); |
3989 tp = new TemplateTupleParameter(ident); | 3989 tp = new TemplateTupleParameter(ident); |
3990 break; | 3990 break; |
3991 case T.Comma, T.RParen, T.Colon, T.Assign: | 3991 case T.Comma, T.RParen, T.Colon, T.Assign: |
3992 // TemplateTypeParameter: | 3992 // TemplateTypeParameter: |
4029 } | 4029 } |
4030 | 4030 |
4031 // Push template parameter. | 4031 // Push template parameter. |
4032 tparams ~= set(tp, paramBegin); | 4032 tparams ~= set(tp, paramBegin); |
4033 | 4033 |
4034 if (token.type != T.Comma) | 4034 if (token.kind != T.Comma) |
4035 break; | 4035 break; |
4036 nT(); | 4036 nT(); |
4037 } | 4037 } |
4038 set(tparams, begin); | 4038 set(tparams, begin); |
4039 return tparams; | 4039 return tparams; |
4040 } | 4040 } |
4041 | 4041 |
4042 void expected(TOK tok) | 4042 void expected(TOK tok) |
4043 { | 4043 { |
4044 if (token.type != tok) | 4044 if (token.kind != tok) |
4045 error(MID.ExpectedButFound, Token.toString(tok), token.srcText); | 4045 error(MID.ExpectedButFound, Token.toString(tok), token.srcText); |
4046 } | 4046 } |
4047 | 4047 |
4048 void require(TOK tok) | 4048 void require(TOK tok) |
4049 { | 4049 { |
4050 if (token.type == tok) | 4050 if (token.kind == tok) |
4051 nT(); | 4051 nT(); |
4052 else | 4052 else |
4053 error(MID.ExpectedButFound, Token.toString(tok), token.srcText); | 4053 error(MID.ExpectedButFound, Token.toString(tok), token.srcText); |
4054 } | 4054 } |
4055 | 4055 |
4060 } | 4060 } |
4061 | 4061 |
4062 Identifier* optionalIdentifier() | 4062 Identifier* optionalIdentifier() |
4063 { | 4063 { |
4064 Identifier* id; | 4064 Identifier* id; |
4065 if (token.type == T.Identifier) | 4065 if (token.kind == T.Identifier) |
4066 (id = token.ident), nT(); | 4066 (id = token.ident), nT(); |
4067 return id; | 4067 return id; |
4068 } | 4068 } |
4069 | 4069 |
4070 Identifier* requireIdentifier() | 4070 Identifier* requireIdentifier() |
4071 { | 4071 { |
4072 Identifier* id; | 4072 Identifier* id; |
4073 if (token.type == T.Identifier) | 4073 if (token.kind == T.Identifier) |
4074 (id = token.ident), nT(); | 4074 (id = token.ident), nT(); |
4075 else | 4075 else |
4076 error(MID.ExpectedButFound, "Identifier", token.srcText); | 4076 error(MID.ExpectedButFound, "Identifier", token.srcText); |
4077 return id; | 4077 return id; |
4078 } | 4078 } |
4082 errorMsg = an error that has no message ID yet. | 4082 errorMsg = an error that has no message ID yet. |
4083 +/ | 4083 +/ |
4084 Identifier* requireIdentifier(char[] errorMsg) | 4084 Identifier* requireIdentifier(char[] errorMsg) |
4085 { | 4085 { |
4086 Identifier* id; | 4086 Identifier* id; |
4087 if (token.type == T.Identifier) | 4087 if (token.kind == T.Identifier) |
4088 (id = token.ident), nT(); | 4088 (id = token.ident), nT(); |
4089 else | 4089 else |
4090 error(token, errorMsg, token.srcText); | 4090 error(token, errorMsg, token.srcText); |
4091 return id; | 4091 return id; |
4092 } | 4092 } |
4093 | 4093 |
4094 Identifier* requireIdentifier(MID mid) | 4094 Identifier* requireIdentifier(MID mid) |
4095 { | 4095 { |
4096 Identifier* id; | 4096 Identifier* id; |
4097 if (token.type == T.Identifier) | 4097 if (token.kind == T.Identifier) |
4098 (id = token.ident), nT(); | 4098 (id = token.ident), nT(); |
4099 else | 4099 else |
4100 error(mid, token.srcText); | 4100 error(mid, token.srcText); |
4101 return id; | 4101 return id; |
4102 } | 4102 } |
4103 | 4103 |
4104 Token* requireId() | 4104 Token* requireId() |
4105 { | 4105 { |
4106 if (token.type == T.Identifier) | 4106 if (token.kind == T.Identifier) |
4107 { | 4107 { |
4108 auto id = token; | 4108 auto id = token; |
4109 nT(); | 4109 nT(); |
4110 return id; | 4110 return id; |
4111 } | 4111 } |
4115 } | 4115 } |
4116 | 4116 |
4117 Token* requireIdToken(char[] errorMsg) | 4117 Token* requireIdToken(char[] errorMsg) |
4118 { | 4118 { |
4119 Token* idtok; | 4119 Token* idtok; |
4120 if (token.type == T.Identifier) | 4120 if (token.kind == T.Identifier) |
4121 (idtok = token), nT(); | 4121 (idtok = token), nT(); |
4122 else | 4122 else |
4123 error(token, errorMsg, token.srcText); | 4123 error(token, errorMsg, token.srcText); |
4124 return idtok; | 4124 return idtok; |
4125 } | 4125 } |