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 }