comparison trunk/src/dil/parser/Parser.d @ 774:846044180d22

Added method skip() to class Parser.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Mon, 18 Feb 2008 20:03:44 +0100
parents 5e3ef1b2011c
children c1d5cfd7aa44
comparison
equal deleted inserted replaced
773:6dbbb403fc58 774:846044180d22
163 bool consumed()(TOK k) // Templatized, so it's inlined. 163 bool consumed()(TOK k) // Templatized, so it's inlined.
164 { 164 {
165 return token.kind == k ? (nT(), true) : false; 165 return token.kind == k ? (nT(), true) : false;
166 } 166 }
167 167
168 /// Asserts that the current token is of kind expectedKind,
169 /// and then moves to the next token.
170 void skip()(TOK expectedKind)
171 {
172 assert(token.kind == expectedKind /+|| *(int*).init+/, token.srcText());
173 nT();
174 }
175
168 /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 176 /+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
169 | Declaration parsing methods | 177 | Declaration parsing methods |
170 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/ 178 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
171 179
172 Declaration parseModuleDeclaration() 180 Declaration parseModuleDeclaration()
173 { 181 {
174 assert(token.kind == T.Module); 182 skip(T.Module);
175 auto begin = token; 183 auto begin = token;
176 ModuleFQN moduleFQN; 184 ModuleFQN moduleFQN;
177 do 185 do
178 {
179 nT();
180 moduleFQN ~= requireIdentifier(MSG.ExpectedModuleIdentifier); 186 moduleFQN ~= requireIdentifier(MSG.ExpectedModuleIdentifier);
181 } while (token.kind == T.Dot) 187 while (consumed(T.Dot))
182 require(T.Semicolon); 188 require(T.Semicolon);
183 return set(new ModuleDeclaration(moduleFQN), begin); 189 return set(new ModuleDeclaration(moduleFQN), begin);
184 } 190 }
185 191
186 /++ 192 /++
447 bool testAutoDeclaration = false, 453 bool testAutoDeclaration = false,
448 bool optionalParameterList = true) 454 bool optionalParameterList = true)
449 { 455 {
450 auto begin = token; 456 auto begin = token;
451 Type type; 457 Type type;
452 Identifier* ident; 458 Identifier* name;
453 459
454 // Check for AutoDeclaration: StorageClasses Identifier = 460 // Check for AutoDeclaration: StorageClasses Identifier =
455 if (testAutoDeclaration && 461 if (testAutoDeclaration &&
456 token.kind == T.Identifier && 462 token.kind == T.Identifier &&
457 peekNext() == T.Assign) 463 peekNext() == T.Assign)
458 { 464 {
459 ident = token.ident; 465 name = token.ident;
460 nT(); 466 skip(T.Identifier);
461 } 467 }
462 else 468 else
463 { 469 {
464 type = parseType(); // VariableType or ReturnType 470 type = parseType(); // VariableType or ReturnType
465 if (token.kind == T.LParen) 471 if (token.kind == T.LParen)
473 // // In the following case precedence is given to a CallExpression. 479 // // In the following case precedence is given to a CallExpression.
474 // something(*p); // 'something' may be a function/method or an object having opCall overloaded. 480 // something(*p); // 'something' may be a function/method or an object having opCall overloaded.
475 // } 481 // }
476 // // A pointer to a function taking no parameters and returning 'something'. 482 // // A pointer to a function taking no parameters and returning 'something'.
477 // something(*p); 483 // something(*p);
478 type = parseCFunctionPointerType(type, ident, optionalParameterList); 484 type = parseCFunctionPointerType(type, name, optionalParameterList);
479 } 485 }
480 else if (peekNext() == T.LParen) 486 else if (peekNext() == T.LParen)
481 { // Type FunctionName ( ParameterList ) FunctionBody 487 { // Type FunctionName ( ParameterList ) FunctionBody
482 ident = requireIdentifier(MSG.ExpectedFunctionName); 488 name = requireIdentifier(MSG.ExpectedFunctionName);
483 ident || nT(); // Skip non-identifier token. 489 name || nT(); // Skip non-identifier token.
484 assert(token.kind == T.LParen); 490 assert(token.kind == T.LParen);
485 // It's a function declaration 491 // It's a function declaration
486 TemplateParameters tparams; 492 TemplateParameters tparams;
487 if (tokenAfterParenIs(T.LParen)) 493 if (tokenAfterParenIs(T.LParen))
488 // ( TemplateParameterList ) ( ParameterList ) 494 // ( TemplateParameterList ) ( ParameterList )
504 default: 510 default:
505 } 511 }
506 } 512 }
507 // ReturnType FunctionName ( ParameterList ) 513 // ReturnType FunctionName ( ParameterList )
508 auto funcBody = parseFunctionBody(); 514 auto funcBody = parseFunctionBody();
509 auto fd = new FunctionDeclaration(type, ident,/+ tparams,+/ params, funcBody); 515 auto fd = new FunctionDeclaration(type, name,/+ tparams,+/ params, funcBody);
510 fd.setStorageClass(stc); 516 fd.setStorageClass(stc);
511 fd.setLinkageType(linkType); 517 fd.setLinkageType(linkType);
512 fd.setProtection(protection); 518 fd.setProtection(protection);
513 if (tparams) 519 if (tparams)
514 { 520 {
515 auto d = putInsideTemplateDeclaration(begin, ident, fd, tparams); 521 auto d = putInsideTemplateDeclaration(begin, name, fd, tparams);
516 d.setStorageClass(stc); 522 d.setStorageClass(stc);
517 d.setProtection(protection); 523 d.setProtection(protection);
518 return set(d, begin); 524 return set(d, begin);
519 } 525 }
520 return set(fd, begin); 526 return set(fd, begin);
521 } 527 }
522 else 528 else
523 { 529 { // Type VariableName DeclaratorSuffix
524 // Type VariableName DeclaratorSuffix 530 name = requireIdentifier(MSG.ExpectedVariableName);
525 ident = requireIdentifier(MSG.ExpectedVariableName);
526 type = parseDeclaratorSuffix(type); 531 type = parseDeclaratorSuffix(type);
527 } 532 }
528 } 533 }
529 534
530 // It's a variable declaration. 535 // It's a variables declaration.
531 Identifier*[] idents = [ident]; 536 Identifier*[] names = [name]; // One identifier has been parsed already.
532 Expression[] values; 537 Expression[] values;
533 goto LenterLoop; // We've already parsed an identifier. Jump to if statement and check for initializer. 538 goto LenterLoop; // Enter the loop and check for an initializer.
534 while (consumed(T.Comma)) 539 while (consumed(T.Comma))
535 { 540 {
536 idents ~= requireIdentifier(MSG.ExpectedVariableName); 541 names ~= requireIdentifier(MSG.ExpectedVariableName);
537 LenterLoop: 542 LenterLoop:
538 if (consumed(T.Assign)) 543 if (consumed(T.Assign))
539 values ~= parseInitializer(); 544 values ~= parseInitializer();
540 else 545 else
541 values ~= null; 546 values ~= null;
542 } 547 }
543 require(T.Semicolon); 548 require(T.Semicolon);
544 auto d = new VariablesDeclaration(type, idents, values); 549 auto d = new VariablesDeclaration(type, names, values);
545 d.setStorageClass(stc); 550 d.setStorageClass(stc);
546 d.setLinkageType(linkType); 551 d.setLinkageType(linkType);
547 d.setProtection(protection); 552 d.setProtection(protection);
548 return set(d, begin); 553 return set(d, begin);
549 } 554 }
554 { 559 {
555 auto begin = token; 560 auto begin = token;
556 auto next = peekNext(); 561 auto next = peekNext();
557 if (next == T.Comma || next == T.Semicolon) 562 if (next == T.Comma || next == T.Semicolon)
558 { 563 {
559 nT(); 564 skip(T.Void);
560 return set(new VoidInitExpression(), begin); 565 return set(new VoidInitExpression(), begin);
561 } 566 }
562 } 567 }
563 return parseNonVoidInitializer(); 568 return parseNonVoidInitializer();
564 } 569 }
574 // [ ] 579 // [ ]
575 // [ ArrayMemberInitializations ] 580 // [ ArrayMemberInitializations ]
576 Expression[] keys; 581 Expression[] keys;
577 Expression[] values; 582 Expression[] values;
578 583
579 nT(); 584 skip(T.LBracket);
580 while (token.kind != T.RBracket) 585 while (token.kind != T.RBracket)
581 { 586 {
582 auto e = parseNonVoidInitializer(); 587 auto e = parseNonVoidInitializer();
583 if (consumed(T.Colon)) 588 if (consumed(T.Colon))
584 { 589 {
589 { 594 {
590 keys ~= null; 595 keys ~= null;
591 values ~= e; 596 values ~= e;
592 } 597 }
593 598
594 if (token.kind != T.Comma) 599 if (!consumed(T.Comma))
595 break; 600 break;
596 nT();
597 } 601 }
598 require(T.RBracket); 602 require(T.RBracket);
599 init = new ArrayInitExpression(keys, values); 603 init = new ArrayInitExpression(keys, values);
600 break; 604 break;
601 case T.LBrace: 605 case T.LBrace:
605 Expression parseStructInitializer() 609 Expression parseStructInitializer()
606 { 610 {
607 Identifier*[] idents; 611 Identifier*[] idents;
608 Expression[] values; 612 Expression[] values;
609 613
610 nT(); 614 skip(T.LBrace);
611 while (token.kind != T.RBrace) 615 while (token.kind != T.RBrace)
612 { 616 {
613 if (token.kind == T.Identifier && 617 if (token.kind == T.Identifier &&
614 // Peek for colon to see if this is a member identifier. 618 // Peek for colon to see if this is a member identifier.
615 peekNext() == T.Colon) 619 peekNext() == T.Colon)
616 { 620 {
617 idents ~= token.ident; 621 idents ~= token.ident;
618 nT(), nT(); // Skip Identifier : 622 skip(T.Identifier), skip(T.Colon);
619 } 623 }
620 else 624 else
621 idents ~= null; 625 idents ~= null;
622 626
623 // NonVoidInitializer 627 // NonVoidInitializer
624 values ~= parseNonVoidInitializer(); 628 values ~= parseNonVoidInitializer();
625 629
626 if (token.kind != T.Comma) 630 if (!consumed(T.Comma))
627 break; 631 break;
628 nT();
629 } 632 }
630 require(T.RBrace); 633 require(T.RBrace);
631 return new StructInitExpression(idents, values); 634 return new StructInitExpression(idents, values);
632 } 635 }
633 636
692 } 695 }
693 696
694 LinkageType parseLinkageType() 697 LinkageType parseLinkageType()
695 { 698 {
696 LinkageType linkageType; 699 LinkageType linkageType;
697 if (token.kind != T.LParen) 700
701 if (!consumed(T.LParen))
698 return linkageType; 702 return linkageType;
699 703
700 nT(); // Skip ( 704 if (consumed(T.RParen))
701 if (token.kind == T.RParen) 705 { // extern()
702 {
703 nT();
704 error(MID.MissingLinkageType); 706 error(MID.MissingLinkageType);
705 return linkageType; 707 return linkageType;
706 } 708 }
707 709
708 auto identTok = requireId(); 710 auto identTok = requireId();
851 return parse(); 853 return parse();
852 } 854 }
853 855
854 uint parseAlignAttribute() 856 uint parseAlignAttribute()
855 { 857 {
856 assert(token.kind == T.Align); 858 skip(T.Align);
857 nT(); // Skip align keyword.
858 uint size = DEFAULT_ALIGN_SIZE; // Global default. 859 uint size = DEFAULT_ALIGN_SIZE; // Global default.
859 if (consumed(T.LParen)) 860 if (consumed(T.LParen))
860 { 861 {
861 if (token.kind == T.Int32) 862 if (token.kind == T.Int32)
862 (size = token.int_), nT(); 863 (size = token.int_), skip(T.Int32);
863 else 864 else
864 expected(T.Int32); 865 expected(T.Int32);
865 require(T.RParen); 866 require(T.RParen);
866 } 867 }
867 return size; 868 return size;
924 return decl; 925 return decl;
925 } 926 }
926 927
927 Declaration parseImportDeclaration() 928 Declaration parseImportDeclaration()
928 { 929 {
929 assert(token.kind == T.Import || token.kind == T.Static);
930 bool isStatic = consumed(T.Static); 930 bool isStatic = consumed(T.Static);
931 assert(token.kind == T.Import); 931 skip(T.Import);
932 nT(); // Skip import keyword.
933 932
934 ModuleFQN[] moduleFQNs; 933 ModuleFQN[] moduleFQNs;
935 Identifier*[] moduleAliases; 934 Identifier*[] moduleAliases;
936 Identifier*[] bindNames; 935 Identifier*[] bindNames;
937 Identifier*[] bindAliases; 936 Identifier*[] bindAliases;
942 Identifier* moduleAlias; 941 Identifier* moduleAlias;
943 // AliasName = ModuleName 942 // AliasName = ModuleName
944 if (peekNext() == T.Assign) 943 if (peekNext() == T.Assign)
945 { 944 {
946 moduleAlias = requireIdentifier(MSG.ExpectedAliasModuleName); 945 moduleAlias = requireIdentifier(MSG.ExpectedAliasModuleName);
947 nT(); // Skip = 946 skip(T.Assign);
948 } 947 }
949 // Identifier ("." Identifier)* 948 // Identifier ("." Identifier)*
950 do 949 do
951 moduleFQN ~= requireIdentifier(MSG.ExpectedModuleIdentifier); 950 moduleFQN ~= requireIdentifier(MSG.ExpectedModuleIdentifier);
952 while (consumed(T.Dot)) 951 while (consumed(T.Dot))
953 // Push identifiers. 952 // Push identifiers.
954 moduleFQNs ~= moduleFQN; 953 moduleFQNs ~= moduleFQN;
955 moduleAliases ~= moduleAlias; 954 moduleAliases ~= moduleAlias;
956 } while (consumed(T.Comma)) 955 } while (consumed(T.Comma))
957 956
958 if (token.kind == T.Colon) 957 if (consumed(T.Colon))
959 { 958 { // BindAlias "=" BindName ("," BindAlias "=" BindName)*;
960 // BindAlias = BindName(, BindAlias = BindName)*; 959 // BindName ("," BindName)*;
961 // BindName(, BindName)*;
962 do 960 do
963 { 961 {
964 nT();
965 Identifier* bindAlias; 962 Identifier* bindAlias;
966 // BindAlias = BindName 963 // BindAlias = BindName
967 if (peekNext() == T.Assign) 964 if (peekNext() == T.Assign)
968 { 965 {
969 bindAlias = requireIdentifier(MSG.ExpectedAliasImportName); 966 bindAlias = requireIdentifier(MSG.ExpectedAliasImportName);
970 nT(); // Skip = 967 skip(T.Assign);
971 } 968 }
972 // Push identifiers. 969 // Push identifiers.
973 bindNames ~= requireIdentifier(MSG.ExpectedImportName); 970 bindNames ~= requireIdentifier(MSG.ExpectedImportName);
974 bindAliases ~= bindAlias; 971 bindAliases ~= bindAlias;
975 } while (token.kind == T.Comma) 972 } while (consumed(T.Comma))
976 } 973 }
977
978 require(T.Semicolon); 974 require(T.Semicolon);
979 975
980 return new ImportDeclaration(moduleFQNs, moduleAliases, bindNames, bindAliases, isStatic); 976 return new ImportDeclaration(moduleFQNs, moduleAliases, bindNames, bindAliases, isStatic);
981 } 977 }
982 978
983 Declaration parseEnumDeclaration() 979 Declaration parseEnumDeclaration()
984 { 980 {
985 assert(token.kind == T.Enum); 981 skip(T.Enum);
986 nT(); // Skip enum keyword.
987 982
988 Identifier* enumName; 983 Identifier* enumName;
989 Type baseType; 984 Type baseType;
990 EnumMemberDeclaration[] members; 985 EnumMemberDeclaration[] members;
991 bool hasBody; 986 bool hasBody;
1011 else 1006 else
1012 value = null; 1007 value = null;
1013 1008
1014 members ~= set(new EnumMemberDeclaration(name, value), begin); 1009 members ~= set(new EnumMemberDeclaration(name, value), begin);
1015 1010
1016 if (token.kind != T.Comma) 1011 if (!consumed(T.Comma))
1017 break; 1012 break;
1018 nT(); // Skip ,
1019 } 1013 }
1020 require(T.RBrace); 1014 require(T.RBrace);
1021 } 1015 }
1022 else 1016 else
1023 error(token, MSG.ExpectedEnumBody, token.srcText); 1017 error(token, MSG.ExpectedEnumBody, token.srcText);
1043 return new TemplateDeclaration(name, tparams, cd); 1037 return new TemplateDeclaration(name, tparams, cd);
1044 } 1038 }
1045 1039
1046 Declaration parseClassDeclaration() 1040 Declaration parseClassDeclaration()
1047 { 1041 {
1048 assert(token.kind == T.Class); 1042 auto begin = token;
1049 auto begin = token; 1043 skip(T.Class);
1050 nT(); // Skip class keyword.
1051 1044
1052 Identifier* className; 1045 Identifier* className;
1053 TemplateParameters tparams; 1046 TemplateParameters tparams;
1054 BaseClassType[] bases; 1047 BaseClassType[] bases;
1055 CompoundDeclaration decls; 1048 CompoundDeclaration decls;
1075 return d; 1068 return d;
1076 } 1069 }
1077 1070
1078 BaseClassType[] parseBaseClasses(bool colonLeadsOff = true) 1071 BaseClassType[] parseBaseClasses(bool colonLeadsOff = true)
1079 { 1072 {
1080 if (colonLeadsOff) 1073 colonLeadsOff && skip(T.Colon);
1081 {
1082 assert(token.kind == T.Colon);
1083 nT(); // Skip colon
1084 }
1085 1074
1086 BaseClassType[] bases; 1075 BaseClassType[] bases;
1087
1088 do 1076 do
1089 { 1077 {
1090 Protection prot = Protection.Public; 1078 Protection prot = Protection.Public;
1091 switch (token.kind) 1079 switch (token.kind)
1092 { 1080 {
1108 return bases; 1096 return bases;
1109 } 1097 }
1110 1098
1111 Declaration parseInterfaceDeclaration() 1099 Declaration parseInterfaceDeclaration()
1112 { 1100 {
1113 assert(token.kind == T.Interface); 1101 auto begin = token;
1114 auto begin = token; 1102 skip(T.Interface);
1115 nT(); // Skip interface keyword.
1116 1103
1117 Identifier* name; 1104 Identifier* name;
1118 TemplateParameters tparams; 1105 TemplateParameters tparams;
1119 BaseClassType[] bases; 1106 BaseClassType[] bases;
1120 CompoundDeclaration decls; 1107 CompoundDeclaration decls;
1142 1129
1143 Declaration parseStructOrUnionDeclaration() 1130 Declaration parseStructOrUnionDeclaration()
1144 { 1131 {
1145 assert(token.kind == T.Struct || token.kind == T.Union); 1132 assert(token.kind == T.Struct || token.kind == T.Union);
1146 auto begin = token; 1133 auto begin = token;
1147 nT(); // Skip struct or union keyword. 1134 skip(token.kind);
1148 1135
1149 Identifier* name; 1136 Identifier* name;
1150 TemplateParameters tparams; 1137 TemplateParameters tparams;
1151 CompoundDeclaration decls; 1138 CompoundDeclaration decls;
1152 1139
1179 return d; 1166 return d;
1180 } 1167 }
1181 1168
1182 Declaration parseConstructorDeclaration() 1169 Declaration parseConstructorDeclaration()
1183 { 1170 {
1184 assert(token.kind == T.This); 1171 skip(T.This);
1185 nT(); // Skip 'this' keyword.
1186 auto parameters = parseParameterList(); 1172 auto parameters = parseParameterList();
1187 auto funcBody = parseFunctionBody(); 1173 auto funcBody = parseFunctionBody();
1188 return new ConstructorDeclaration(parameters, funcBody); 1174 return new ConstructorDeclaration(parameters, funcBody);
1189 } 1175 }
1190 1176
1191 Declaration parseDestructorDeclaration() 1177 Declaration parseDestructorDeclaration()
1192 { 1178 {
1193 assert(token.kind == T.Tilde); 1179 skip(T.Tilde);
1194 nT(); // Skip ~
1195 require(T.This); 1180 require(T.This);
1196 require(T.LParen); 1181 require(T.LParen);
1197 require(T.RParen); 1182 require(T.RParen);
1198 auto funcBody = parseFunctionBody(); 1183 auto funcBody = parseFunctionBody();
1199 return new DestructorDeclaration(funcBody); 1184 return new DestructorDeclaration(funcBody);
1200 } 1185 }
1201 1186
1202 Declaration parseStaticConstructorDeclaration() 1187 Declaration parseStaticConstructorDeclaration()
1203 { 1188 {
1204 assert(token.kind == T.Static); 1189 skip(T.Static);
1205 nT(); // Skip static keyword. 1190 skip(T.This);
1206 nT(); // Skip 'this' keyword.
1207 require(T.LParen); 1191 require(T.LParen);
1208 require(T.RParen); 1192 require(T.RParen);
1209 auto funcBody = parseFunctionBody(); 1193 auto funcBody = parseFunctionBody();
1210 return new StaticConstructorDeclaration(funcBody); 1194 return new StaticConstructorDeclaration(funcBody);
1211 } 1195 }
1212 1196
1213 Declaration parseStaticDestructorDeclaration() 1197 Declaration parseStaticDestructorDeclaration()
1214 { 1198 {
1215 assert(token.kind == T.Static); 1199 skip(T.Static);
1216 nT(); // Skip static keyword. 1200 skip(T.Tilde);
1217 nT(); // Skip ~
1218 require(T.This); 1201 require(T.This);
1219 require(T.LParen); 1202 require(T.LParen);
1220 require(T.RParen); 1203 require(T.RParen);
1221 auto funcBody = parseFunctionBody(); 1204 auto funcBody = parseFunctionBody();
1222 return new StaticDestructorDeclaration(funcBody); 1205 return new StaticDestructorDeclaration(funcBody);
1223 } 1206 }
1224 1207
1225 Declaration parseInvariantDeclaration() 1208 Declaration parseInvariantDeclaration()
1226 { 1209 {
1227 assert(token.kind == T.Invariant); 1210 skip(T.Invariant);
1228 nT(); // Skip invariant keyword.
1229 // Optional () for getting ready porting to D 2.0 1211 // Optional () for getting ready porting to D 2.0
1230 if (token.kind == T.LParen) 1212 if (consumed(T.LParen))
1231 requireNext(T.RParen); 1213 require(T.RParen);
1232 auto funcBody = parseFunctionBody(); 1214 auto funcBody = parseFunctionBody();
1233 return new InvariantDeclaration(funcBody); 1215 return new InvariantDeclaration(funcBody);
1234 } 1216 }
1235 1217
1236 Declaration parseUnittestDeclaration() 1218 Declaration parseUnittestDeclaration()
1237 { 1219 {
1238 assert(token.kind == T.Unittest); 1220 skip(T.Unittest);
1239 nT(); // Skip unittest keyword.
1240 auto funcBody = parseFunctionBody(); 1221 auto funcBody = parseFunctionBody();
1241 return new UnittestDeclaration(funcBody); 1222 return new UnittestDeclaration(funcBody);
1242 } 1223 }
1243 1224
1244 Token* parseIdentOrInt() 1225 Token* parseIdentOrInt()
1249 return null; 1230 return null;
1250 } 1231 }
1251 1232
1252 Declaration parseDebugDeclaration() 1233 Declaration parseDebugDeclaration()
1253 { 1234 {
1254 assert(token.kind == T.Debug); 1235 skip(T.Debug);
1255 nT(); // Skip debug keyword.
1256 1236
1257 Token* spec; 1237 Token* spec;
1258 Token* cond; 1238 Token* cond;
1259 Declaration decls, elseDecls; 1239 Declaration decls, elseDecls;
1260 1240
1282 return new DebugDeclaration(spec, cond, decls, elseDecls); 1262 return new DebugDeclaration(spec, cond, decls, elseDecls);
1283 } 1263 }
1284 1264
1285 Declaration parseVersionDeclaration() 1265 Declaration parseVersionDeclaration()
1286 { 1266 {
1287 assert(token.kind == T.Version); 1267 skip(T.Version);
1288 nT(); // Skip version keyword.
1289 1268
1290 Token* spec; 1269 Token* spec;
1291 Token* cond; 1270 Token* cond;
1292 Declaration decls, elseDecls; 1271 Declaration decls, elseDecls;
1293 1272
1312 return new VersionDeclaration(spec, cond, decls, elseDecls); 1291 return new VersionDeclaration(spec, cond, decls, elseDecls);
1313 } 1292 }
1314 1293
1315 Declaration parseStaticIfDeclaration() 1294 Declaration parseStaticIfDeclaration()
1316 { 1295 {
1317 assert(token.kind == T.Static); 1296 skip(T.Static);
1318 nT(); // Skip static keyword. 1297 skip(T.If);
1319 nT(); // Skip if keyword.
1320 1298
1321 Expression condition; 1299 Expression condition;
1322 Declaration ifDecls, elseDecls; 1300 Declaration ifDecls, elseDecls;
1323 1301
1324 require(T.LParen); 1302 require(T.LParen);
1333 return new StaticIfDeclaration(condition, ifDecls, elseDecls); 1311 return new StaticIfDeclaration(condition, ifDecls, elseDecls);
1334 } 1312 }
1335 1313
1336 Declaration parseStaticAssertDeclaration() 1314 Declaration parseStaticAssertDeclaration()
1337 { 1315 {
1338 assert(token.kind == T.Static); 1316 skip(T.Static);
1339 nT(); // Skip static keyword. 1317 skip(T.Assert);
1340 nT(); // Skip assert keyword.
1341 Expression condition, message; 1318 Expression condition, message;
1342 require(T.LParen); 1319 require(T.LParen);
1343 condition = parseAssignExpression(); 1320 condition = parseAssignExpression();
1344 if (consumed(T.Comma)) 1321 if (consumed(T.Comma))
1345 message = parseAssignExpression(); 1322 message = parseAssignExpression();
1348 return new StaticAssertDeclaration(condition, message); 1325 return new StaticAssertDeclaration(condition, message);
1349 } 1326 }
1350 1327
1351 Declaration parseTemplateDeclaration() 1328 Declaration parseTemplateDeclaration()
1352 { 1329 {
1353 assert(token.kind == T.Template); 1330 skip(T.Template);
1354 nT(); // Skip template keyword.
1355 auto templateName = requireIdentifier(MSG.ExpectedTemplateName); 1331 auto templateName = requireIdentifier(MSG.ExpectedTemplateName);
1356 auto templateParams = parseTemplateParameterList(); 1332 auto templateParams = parseTemplateParameterList();
1357 auto decls = parseDeclarationDefinitionsBody(); 1333 auto decls = parseDeclarationDefinitionsBody();
1358 return new TemplateDeclaration(templateName, templateParams, decls); 1334 return new TemplateDeclaration(templateName, templateParams, decls);
1359 } 1335 }
1360 1336
1361 Declaration parseNewDeclaration() 1337 Declaration parseNewDeclaration()
1362 { 1338 {
1363 assert(token.kind == T.New); 1339 skip(T.New);
1364 nT(); // Skip new keyword.
1365 auto parameters = parseParameterList(); 1340 auto parameters = parseParameterList();
1366 auto funcBody = parseFunctionBody(); 1341 auto funcBody = parseFunctionBody();
1367 return new NewDeclaration(parameters, funcBody); 1342 return new NewDeclaration(parameters, funcBody);
1368 } 1343 }
1369 1344
1370 Declaration parseDeleteDeclaration() 1345 Declaration parseDeleteDeclaration()
1371 { 1346 {
1372 assert(token.kind == T.Delete); 1347 skip(T.Delete);
1373 nT(); // Skip delete keyword.
1374 auto parameters = parseParameterList(); 1348 auto parameters = parseParameterList();
1375 auto funcBody = parseFunctionBody(); 1349 auto funcBody = parseFunctionBody();
1376 return new DeleteDeclaration(parameters, funcBody); 1350 return new DeleteDeclaration(parameters, funcBody);
1377 } 1351 }
1378 1352
1379 Type parseTypeofType() 1353 Type parseTypeofType()
1380 { 1354 {
1381 assert(token.kind == T.Typeof); 1355 auto begin = token;
1382 auto begin = token; 1356 skip(T.Typeof);
1357 require(T.LParen);
1383 Type type; 1358 Type type;
1384 requireNext(T.LParen);
1385 switch (token.kind) 1359 switch (token.kind)
1386 { 1360 {
1387 version(D2) 1361 version(D2)
1388 { 1362 {
1389 case T.Return: 1363 case T.Return:
1408 mixin TemplateIdentifier !( TemplateArguments ) MixinIdentifier ; 1382 mixin TemplateIdentifier !( TemplateArguments ) MixinIdentifier ;
1409 +/ 1383 +/
1410 Class parseMixin(Class)() 1384 Class parseMixin(Class)()
1411 { 1385 {
1412 static assert(is(Class == MixinDeclaration) || is(Class == MixinStatement)); 1386 static assert(is(Class == MixinDeclaration) || is(Class == MixinStatement));
1413 assert(token.kind == T.Mixin); 1387 skip(T.Mixin);
1414 nT(); // Skip mixin keyword.
1415 1388
1416 static if (is(Class == MixinDeclaration)) 1389 static if (is(Class == MixinDeclaration))
1417 { 1390 {
1418 if (consumed(T.LParen)) 1391 if (consumed(T.LParen))
1419 { 1392 {
1501 return s; 1474 return s;
1502 case T.Identifier: 1475 case T.Identifier:
1503 if (peekNext() == T.Colon) 1476 if (peekNext() == T.Colon)
1504 { 1477 {
1505 auto ident = token.ident; 1478 auto ident = token.ident;
1506 nT(), nT(); // Skip Identifier : 1479 skip(T.Identifier); skip(T.Colon);
1507 s = new LabeledStatement(ident, parseNoScopeOrEmptyStatement()); 1480 s = new LabeledStatement(ident, parseNoScopeOrEmptyStatement());
1508 break; 1481 break;
1509 } 1482 }
1510 goto case T.Dot; 1483 goto case T.Dot;
1511 case T.Dot, T.Typeof: 1484 case T.Dot, T.Typeof:
1819 return new DeclarationStatement(parse()); 1792 return new DeclarationStatement(parse());
1820 } 1793 }
1821 1794
1822 Statement parseIfStatement() 1795 Statement parseIfStatement()
1823 { 1796 {
1824 assert(token.kind == T.If); 1797 skip(T.If);
1825 nT();
1826 1798
1827 Statement variable; 1799 Statement variable;
1828 Expression condition; 1800 Expression condition;
1829 Statement ifBody, elseBody; 1801 Statement ifBody, elseBody;
1830 1802
1844 set(d, begin); 1816 set(d, begin);
1845 variable = new DeclarationStatement(d); 1817 variable = new DeclarationStatement(d);
1846 set(variable, begin); 1818 set(variable, begin);
1847 } 1819 }
1848 else 1820 else
1849 { 1821 { // Declarator = Expression
1850 // Declarator = Expression
1851 Type parseDeclaratorAssign() 1822 Type parseDeclaratorAssign()
1852 { 1823 {
1853 auto type = parseDeclarator(ident); 1824 auto type = parseDeclarator(ident);
1854 require(T.Assign); 1825 require(T.Assign);
1855 return type; 1826 return type;
1874 return new IfStatement(variable, condition, ifBody, elseBody); 1845 return new IfStatement(variable, condition, ifBody, elseBody);
1875 } 1846 }
1876 1847
1877 Statement parseWhileStatement() 1848 Statement parseWhileStatement()
1878 { 1849 {
1879 assert(token.kind == T.While); 1850 skip(T.While);
1880 nT();
1881 require(T.LParen); 1851 require(T.LParen);
1882 auto condition = parseExpression(); 1852 auto condition = parseExpression();
1883 require(T.RParen); 1853 require(T.RParen);
1884 return new WhileStatement(condition, parseScopeStatement()); 1854 return new WhileStatement(condition, parseScopeStatement());
1885 } 1855 }
1886 1856
1887 Statement parseDoWhileStatement() 1857 Statement parseDoWhileStatement()
1888 { 1858 {
1889 assert(token.kind == T.Do); 1859 skip(T.Do);
1890 nT();
1891 auto doBody = parseScopeStatement(); 1860 auto doBody = parseScopeStatement();
1892 require(T.While); 1861 require(T.While);
1893 require(T.LParen); 1862 require(T.LParen);
1894 auto condition = parseExpression(); 1863 auto condition = parseExpression();
1895 require(T.RParen); 1864 require(T.RParen);
1896 return new DoWhileStatement(condition, doBody); 1865 return new DoWhileStatement(condition, doBody);
1897 } 1866 }
1898 1867
1899 Statement parseForStatement() 1868 Statement parseForStatement()
1900 { 1869 {
1901 assert(token.kind == T.For); 1870 skip(T.For);
1902 nT();
1903 require(T.LParen);
1904 1871
1905 Statement init, forBody; 1872 Statement init, forBody;
1906 Expression condition, increment; 1873 Expression condition, increment;
1907 1874
1908 if (token.kind != T.Semicolon) 1875 require(T.LParen);
1876 if (!consumed(T.Semicolon))
1909 init = parseNoScopeStatement(); 1877 init = parseNoScopeStatement();
1910 else
1911 nT(); // Skip ;
1912 if (token.kind != T.Semicolon) 1878 if (token.kind != T.Semicolon)
1913 condition = parseExpression(); 1879 condition = parseExpression();
1914 require(T.Semicolon); 1880 require(T.Semicolon);
1915 if (token.kind != T.RParen) 1881 if (token.kind != T.RParen)
1916 increment = parseExpression(); 1882 increment = parseExpression();
1978 return new ForeachStatement(tok, params, e, forBody); 1944 return new ForeachStatement(tok, params, e, forBody);
1979 } 1945 }
1980 1946
1981 Statement parseSwitchStatement() 1947 Statement parseSwitchStatement()
1982 { 1948 {
1983 assert(token.kind == T.Switch); 1949 skip(T.Switch);
1984 nT();
1985 require(T.LParen); 1950 require(T.LParen);
1986 auto condition = parseExpression(); 1951 auto condition = parseExpression();
1987 require(T.RParen); 1952 require(T.RParen);
1988 auto switchBody = parseScopeStatement(); 1953 auto switchBody = parseScopeStatement();
1989 return new SwitchStatement(condition, switchBody); 1954 return new SwitchStatement(condition, switchBody);
1990 } 1955 }
1991 1956
1992 /++ 1957 /// Helper function for parsing the body of a default or case statement.
1993 Helper function for parsing the body of
1994 a default or case statement.
1995 +/
1996 Statement parseCaseOrDefaultBody() 1958 Statement parseCaseOrDefaultBody()
1997 { 1959 {
1998 // This function is similar to parseNoScopeStatement() 1960 // This function is similar to parseNoScopeStatement()
1999 auto begin = token; 1961 auto begin = token;
2000 auto s = new CompoundStatement(); 1962 auto s = new CompoundStatement();
2007 return set(new ScopeStatement(s), begin); 1969 return set(new ScopeStatement(s), begin);
2008 } 1970 }
2009 1971
2010 Statement parseCaseStatement() 1972 Statement parseCaseStatement()
2011 { 1973 {
2012 assert(token.kind == T.Case); 1974 skip(T.Case);
2013 nT();
2014 auto values = parseExpressionList(); 1975 auto values = parseExpressionList();
2015 require(T.Colon); 1976 require(T.Colon);
2016 auto caseBody = parseCaseOrDefaultBody(); 1977 auto caseBody = parseCaseOrDefaultBody();
2017 return new CaseStatement(values, caseBody); 1978 return new CaseStatement(values, caseBody);
2018 } 1979 }
2019 1980
2020 Statement parseDefaultStatement() 1981 Statement parseDefaultStatement()
2021 { 1982 {
2022 assert(token.kind == T.Default); 1983 skip(T.Default);
2023 nT();
2024 require(T.Colon); 1984 require(T.Colon);
2025 auto defaultBody = parseCaseOrDefaultBody(); 1985 auto defaultBody = parseCaseOrDefaultBody();
2026 return new DefaultStatement(defaultBody); 1986 return new DefaultStatement(defaultBody);
2027 } 1987 }
2028 1988
2029 Statement parseContinueStatement() 1989 Statement parseContinueStatement()
2030 { 1990 {
2031 assert(token.kind == T.Continue); 1991 skip(T.Continue);
2032 nT();
2033 auto ident = optionalIdentifier(); 1992 auto ident = optionalIdentifier();
2034 require(T.Semicolon); 1993 require(T.Semicolon);
2035 return new ContinueStatement(ident); 1994 return new ContinueStatement(ident);
2036 } 1995 }
2037 1996
2038 Statement parseBreakStatement() 1997 Statement parseBreakStatement()
2039 { 1998 {
2040 assert(token.kind == T.Break); 1999 skip(T.Break);
2041 nT();
2042 auto ident = optionalIdentifier(); 2000 auto ident = optionalIdentifier();
2043 require(T.Semicolon); 2001 require(T.Semicolon);
2044 return new BreakStatement(ident); 2002 return new BreakStatement(ident);
2045 } 2003 }
2046 2004
2047 Statement parseReturnStatement() 2005 Statement parseReturnStatement()
2048 { 2006 {
2049 assert(token.kind == T.Return); 2007 skip(T.Return);
2050 nT();
2051 Expression expr; 2008 Expression expr;
2052 if (token.kind != T.Semicolon) 2009 if (token.kind != T.Semicolon)
2053 expr = parseExpression(); 2010 expr = parseExpression();
2054 require(T.Semicolon); 2011 require(T.Semicolon);
2055 return new ReturnStatement(expr); 2012 return new ReturnStatement(expr);
2056 } 2013 }
2057 2014
2058 Statement parseGotoStatement() 2015 Statement parseGotoStatement()
2059 { 2016 {
2060 assert(token.kind == T.Goto); 2017 skip(T.Goto);
2061 nT();
2062 Identifier* ident; 2018 Identifier* ident;
2063 Expression caseExpr; 2019 Expression caseExpr;
2064 switch (token.kind) 2020 switch (token.kind)
2065 { 2021 {
2066 case T.Case: 2022 case T.Case:
2023 ident = token.ident;
2067 nT(); 2024 nT();
2068 if (token.kind == T.Semicolon) 2025 if (token.kind == T.Semicolon)
2069 break; 2026 break;
2070 caseExpr = parseExpression(); 2027 caseExpr = parseExpression();
2071 break; 2028 break;
2072 case T.Default: 2029 case T.Default:
2030 ident = token.ident;
2073 nT(); 2031 nT();
2074 break; 2032 break;
2075 default: 2033 default:
2076 ident = requireIdentifier(MSG.ExpectedAnIdentifier); 2034 ident = requireIdentifier(MSG.ExpectedAnIdentifier);
2077 } 2035 }
2079 return new GotoStatement(ident, caseExpr); 2037 return new GotoStatement(ident, caseExpr);
2080 } 2038 }
2081 2039
2082 Statement parseWithStatement() 2040 Statement parseWithStatement()
2083 { 2041 {
2084 assert(token.kind == T.With); 2042 skip(T.With);
2085 nT();
2086 require(T.LParen); 2043 require(T.LParen);
2087 auto expr = parseExpression(); 2044 auto expr = parseExpression();
2088 require(T.RParen); 2045 require(T.RParen);
2089 return new WithStatement(expr, parseScopeStatement()); 2046 return new WithStatement(expr, parseScopeStatement());
2090 } 2047 }
2091 2048
2092 Statement parseSynchronizedStatement() 2049 Statement parseSynchronizedStatement()
2093 { 2050 {
2094 assert(token.kind == T.Synchronized); 2051 skip(T.Synchronized);
2095 nT();
2096 Expression expr; 2052 Expression expr;
2097 if (consumed(T.LParen)) 2053 if (consumed(T.LParen))
2098 { 2054 {
2099 expr = parseExpression(); 2055 expr = parseExpression();
2100 require(T.RParen); 2056 require(T.RParen);
2102 return new SynchronizedStatement(expr, parseScopeStatement()); 2058 return new SynchronizedStatement(expr, parseScopeStatement());
2103 } 2059 }
2104 2060
2105 Statement parseTryStatement() 2061 Statement parseTryStatement()
2106 { 2062 {
2107 assert(token.kind == T.Try); 2063 auto begin = token;
2108 auto begin = token; 2064 skip(T.Try);
2109 nT();
2110 2065
2111 auto tryBody = parseScopeStatement(); 2066 auto tryBody = parseScopeStatement();
2112 CatchStatement[] catchBodies; 2067 CatchStatement[] catchBodies;
2113 FinallyStatement finBody; 2068 FinallyStatement finBody;
2114 2069
2139 return new TryStatement(tryBody, catchBodies, finBody); 2094 return new TryStatement(tryBody, catchBodies, finBody);
2140 } 2095 }
2141 2096
2142 Statement parseThrowStatement() 2097 Statement parseThrowStatement()
2143 { 2098 {
2144 assert(token.kind == T.Throw); 2099 skip(T.Throw);
2145 nT();
2146 auto expr = parseExpression(); 2100 auto expr = parseExpression();
2147 require(T.Semicolon); 2101 require(T.Semicolon);
2148 return new ThrowStatement(expr); 2102 return new ThrowStatement(expr);
2149 } 2103 }
2150 2104
2151 Statement parseScopeGuardStatement() 2105 Statement parseScopeGuardStatement()
2152 { 2106 {
2153 assert(token.kind == T.Scope); 2107 skip(T.Scope);
2154 nT(); 2108 skip(T.LParen);
2155 assert(token.kind == T.LParen);
2156 nT();
2157 auto condition = requireIdentifier(MSG.ExpectedScopeIdentifier); 2109 auto condition = requireIdentifier(MSG.ExpectedScopeIdentifier);
2158 if (condition) 2110 if (condition)
2159 switch (condition.idKind) 2111 switch (condition.idKind)
2160 { 2112 {
2161 case IDK.exit, IDK.success, IDK.failure: 2113 case IDK.exit, IDK.success, IDK.failure:
2172 return new ScopeGuardStatement(condition, scopeBody); 2124 return new ScopeGuardStatement(condition, scopeBody);
2173 } 2125 }
2174 2126
2175 Statement parseVolatileStatement() 2127 Statement parseVolatileStatement()
2176 { 2128 {
2177 assert(token.kind == T.Volatile); 2129 skip(T.Volatile);
2178 nT();
2179 Statement volatileBody; 2130 Statement volatileBody;
2180 if (token.kind == T.Semicolon) 2131 if (token.kind == T.Semicolon)
2181 nT(); 2132 nT();
2182 else if (token.kind == T.LBrace) 2133 else if (token.kind == T.LBrace)
2183 volatileBody = parseScopeStatement(); 2134 volatileBody = parseScopeStatement();
2186 return new VolatileStatement(volatileBody); 2137 return new VolatileStatement(volatileBody);
2187 } 2138 }
2188 2139
2189 Statement parsePragmaStatement() 2140 Statement parsePragmaStatement()
2190 { 2141 {
2191 assert(token.kind == T.Pragma); 2142 skip(T.Pragma);
2192 nT();
2193 2143
2194 Identifier* ident; 2144 Identifier* ident;
2195 Expression[] args; 2145 Expression[] args;
2196 Statement pragmaBody; 2146 Statement pragmaBody;
2197 2147
2207 return new PragmaStatement(ident, args, pragmaBody); 2157 return new PragmaStatement(ident, args, pragmaBody);
2208 } 2158 }
2209 2159
2210 Statement parseStaticIfStatement() 2160 Statement parseStaticIfStatement()
2211 { 2161 {
2212 assert(token.kind == T.Static); 2162 skip(T.Static);
2213 nT(); 2163 skip(T.If);
2214 assert(token.kind == T.If);
2215 nT();
2216 Expression condition; 2164 Expression condition;
2217 Statement ifBody, elseBody; 2165 Statement ifBody, elseBody;
2218 2166
2219 require(T.LParen); 2167 require(T.LParen);
2220 condition = parseExpression(); 2168 condition = parseExpression();
2225 return new StaticIfStatement(condition, ifBody, elseBody); 2173 return new StaticIfStatement(condition, ifBody, elseBody);
2226 } 2174 }
2227 2175
2228 Statement parseStaticAssertStatement() 2176 Statement parseStaticAssertStatement()
2229 { 2177 {
2230 assert(token.kind == T.Static); 2178 skip(T.Static);
2231 nT(); 2179 skip(T.Assert);
2232 assert(token.kind == T.Assert);
2233 nT();
2234 Expression condition, message; 2180 Expression condition, message;
2181
2235 require(T.LParen); 2182 require(T.LParen);
2236 condition = parseAssignExpression(); // Condition. 2183 condition = parseAssignExpression(); // Condition.
2237 if (consumed(T.Comma)) 2184 if (consumed(T.Comma))
2238 message = parseAssignExpression(); // Error message. 2185 message = parseAssignExpression(); // Error message.
2239 require(T.RParen); 2186 require(T.RParen);
2241 return new StaticAssertStatement(condition, message); 2188 return new StaticAssertStatement(condition, message);
2242 } 2189 }
2243 2190
2244 Statement parseDebugStatement() 2191 Statement parseDebugStatement()
2245 { 2192 {
2246 assert(token.kind == T.Debug); 2193 skip(T.Debug);
2247 nT(); // Skip debug keyword.
2248
2249 Token* cond; 2194 Token* cond;
2250 Statement debugBody, elseBody; 2195 Statement debugBody, elseBody;
2251 2196
2252 // ( Condition ) 2197 // ( Condition )
2253 if (consumed(T.LParen)) 2198 if (consumed(T.LParen))
2265 return new DebugStatement(cond, debugBody, elseBody); 2210 return new DebugStatement(cond, debugBody, elseBody);
2266 } 2211 }
2267 2212
2268 Statement parseVersionStatement() 2213 Statement parseVersionStatement()
2269 { 2214 {
2270 assert(token.kind == T.Version); 2215 skip(T.Version);
2271 nT(); // Skip version keyword.
2272
2273 Token* cond; 2216 Token* cond;
2274 Statement versionBody, elseBody; 2217 Statement versionBody, elseBody;
2275 2218
2276 // ( Condition ) 2219 // ( Condition )
2277 require(T.LParen); 2220 require(T.LParen);
2290 | Assembler parsing methods | 2233 | Assembler parsing methods |
2291 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/ 2234 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+/
2292 2235
2293 Statement parseAsmBlockStatement() 2236 Statement parseAsmBlockStatement()
2294 { 2237 {
2295 assert(token.kind == T.Asm); 2238 skip(T.Asm);
2296 nT(); // Skip asm keyword.
2297 require(T.LBrace); 2239 require(T.LBrace);
2298 auto ss = new CompoundStatement; 2240 auto ss = new CompoundStatement;
2299 while (token.kind != T.RBrace && token.kind != T.EOF) 2241 while (token.kind != T.RBrace && token.kind != T.EOF)
2300 ss ~= parseAsmStatement(); 2242 ss ~= parseAsmStatement();
2301 require(T.RBrace); 2243 require(T.RBrace);
2314 ident = token.ident; 2256 ident = token.ident;
2315 nT(); 2257 nT();
2316 goto LOpcode; 2258 goto LOpcode;
2317 case T.Identifier: 2259 case T.Identifier:
2318 ident = token.ident; 2260 ident = token.ident;
2319 nT(); // Skip Identifier 2261 nT();
2320 if (consumed(T.Colon)) 2262 if (consumed(T.Colon))
2321 { // Identifier : AsmStatement 2263 { // Identifier : AsmStatement
2322 s = new LabeledStatement(ident, parseAsmStatement()); 2264 s = new LabeledStatement(ident, parseAsmStatement());
2323 break; 2265 break;
2324 } 2266 }
2339 case T.Align: 2281 case T.Align:
2340 // align Integer; 2282 // align Integer;
2341 nT(); 2283 nT();
2342 int number = -1; 2284 int number = -1;
2343 if (token.kind == T.Int32) 2285 if (token.kind == T.Int32)
2344 (number = token.int_), nT(); 2286 (number = token.int_), skip(T.Int32);
2345 else 2287 else
2346 error(token, MSG.ExpectedIntegerAfterAlign, token.srcText); 2288 error(token, MSG.ExpectedIntegerAfterAlign, token.srcText);
2347 require(T.Semicolon); 2289 require(T.Semicolon);
2348 s = new AsmAlignStatement(number); 2290 s = new AsmAlignStatement(number);
2349 break; 2291 break;
2574 case IDK.near, IDK.far,/* "byte", "short", "int",*/ 2516 case IDK.near, IDK.far,/* "byte", "short", "int",*/
2575 IDK.word, IDK.dword, IDK.qword/*, "float", "double", "real"*/: 2517 IDK.word, IDK.dword, IDK.qword/*, "float", "double", "real"*/:
2576 LAsmTypePrefix: 2518 LAsmTypePrefix:
2577 nT(); 2519 nT();
2578 if (token.kind == T.Identifier && token.ident is Ident.ptr) 2520 if (token.kind == T.Identifier && token.ident is Ident.ptr)
2579 nT(); 2521 skip(T.Identifier);
2580 else 2522 else
2581 error(MID.ExpectedButFound, "ptr", token.srcText); 2523 error(MID.ExpectedButFound, "ptr", token.srcText);
2582 e = new AsmTypeExpression(parseAsmExpression()); 2524 e = new AsmTypeExpression(parseAsmExpression());
2583 break; 2525 break;
2584 case IDK.offset: 2526 case IDK.offset:
2665 // (1) - (7) 2607 // (1) - (7)
2666 int number = -1; 2608 int number = -1;
2667 if (consumed(T.LParen)) 2609 if (consumed(T.LParen))
2668 { 2610 {
2669 if (token.kind == T.Int32) 2611 if (token.kind == T.Int32)
2670 (number = token.int_), nT(); 2612 (number = token.int_), skip(T.Int32);
2671 else 2613 else
2672 expected(T.Int32); 2614 expected(T.Int32);
2673 require(T.RParen); 2615 require(T.RParen);
2674 } 2616 }
2675 e = new AsmRegisterExpression(register, number); 2617 e = new AsmRegisterExpression(register, number);
2680 int number = -1; 2622 int number = -1;
2681 if (consumed(T.Colon)) 2623 if (consumed(T.Colon))
2682 { 2624 {
2683 // :0, :4, :8 2625 // :0, :4, :8
2684 if (token.kind == T.Int32) 2626 if (token.kind == T.Int32)
2685 (number = token.int_), nT(); 2627 (number = token.int_), skip(T.Int32);
2686 if (number != 0 && number != 4 && number != 8) 2628 if (number != 0 && number != 4 && number != 8)
2687 error(MID.ExpectedButFound, "0, 4 or 8", token.srcText); 2629 error(MID.ExpectedButFound, "0, 4 or 8", token.srcText);
2688 } 2630 }
2689 e = new AsmRegisterExpression(register, number); 2631 e = new AsmRegisterExpression(register, number);
2690 break; 2632 break;
3108 break; 3050 break;
3109 case T.LParen: 3051 case T.LParen:
3110 // ( Type ) . Identifier 3052 // ( Type ) . Identifier
3111 Type parseType_() 3053 Type parseType_()
3112 { 3054 {
3113 nT(); 3055 skip(T.LParen);
3114 auto type = parseType(); 3056 auto type = parseType();
3115 require(T.RParen); 3057 require(T.RParen);
3116 require(T.Dot); 3058 require(T.Dot);
3117 return type; 3059 return type;
3118 } 3060 }
3151 auto ident = requireIdentifier(MSG.ExpectedAnIdentifier); 3093 auto ident = requireIdentifier(MSG.ExpectedAnIdentifier);
3152 Expression e; 3094 Expression e;
3153 // Peek for '(' to avoid matching: id !is id 3095 // Peek for '(' to avoid matching: id !is id
3154 if (token.kind == T.Not && peekNext() == T.LParen) 3096 if (token.kind == T.Not && peekNext() == T.LParen)
3155 { // Identifier !( TemplateArguments ) 3097 { // Identifier !( TemplateArguments )
3156 nT(); // Skip !. 3098 skip(T.Not);
3157 auto tparams = parseTemplateArguments(); 3099 auto tparams = parseTemplateArguments();
3158 e = new TemplateInstanceExpression(ident, tparams); 3100 e = new TemplateInstanceExpression(ident, tparams);
3159 } 3101 }
3160 else // Identifier 3102 else // Identifier
3161 e = new IdentifierExpression(ident); 3103 e = new IdentifierExpression(ident);
3369 auto funcBody = parseFunctionBody(); 3311 auto funcBody = parseFunctionBody();
3370 e = new FunctionLiteralExpression(null, parameters, funcBody); 3312 e = new FunctionLiteralExpression(null, parameters, funcBody);
3371 } 3313 }
3372 else 3314 else
3373 { // ( Expression ) 3315 { // ( Expression )
3374 nT(); 3316 skip(T.LParen);
3375 e = parseExpression(); 3317 e = parseExpression();
3376 require(T.RParen); 3318 require(T.RParen);
3377 e = new ParenExpression(e); 3319 e = new ParenExpression(e);
3378 } 3320 }
3379 break; 3321 break;
3380 version(D2) 3322 version(D2)
3381 { 3323 {
3382 case T.Traits: 3324 case T.Traits:
3383 nT(); 3325 requireNext(T.LParen);
3384 require(T.LParen);
3385 auto id = requireIdentifier(MSG.ExpectedAnIdentifier); 3326 auto id = requireIdentifier(MSG.ExpectedAnIdentifier);
3386 TemplateArguments args; 3327 TemplateArguments args;
3387 if (token.kind == T.Comma) 3328 if (token.kind == T.Comma)
3388 args = parseTemplateArguments2(); 3329 args = parseTemplateArguments2();
3389 else 3330 else
3422 } 3363 }
3423 3364
3424 Expression parseNewExpression(/*Expression e*/) 3365 Expression parseNewExpression(/*Expression e*/)
3425 { 3366 {
3426 auto begin = token; 3367 auto begin = token;
3427 assert(token.kind == T.New); 3368 skip(T.New);
3428 nT(); // Skip new keyword.
3429 3369
3430 Expression[] newArguments; 3370 Expression[] newArguments;
3431 Expression[] ctorArguments; 3371 Expression[] ctorArguments;
3432 3372
3433 if (token.kind == T.LParen) 3373 if (token.kind == T.LParen)
3513 return t; 3453 return t;
3514 version(D2) 3454 version(D2)
3515 { 3455 {
3516 case T.Const: 3456 case T.Const:
3517 // const ( Type ) 3457 // const ( Type )
3518 nT(); 3458 requireNext(T.LParen);
3519 require(T.LParen);
3520 t = parseType(); 3459 t = parseType();
3521 require(T.RParen); 3460 require(T.RParen);
3522 t = new ConstType(t); 3461 t = new ConstType(t);
3523 break; 3462 break;
3524 case T.Invariant: 3463 case T.Invariant:
3525 // invariant ( Type ) 3464 // invariant ( Type )
3526 nT(); 3465 requireNext(T.LParen);
3527 require(T.LParen);
3528 t = parseType(); 3466 t = parseType();
3529 require(T.RParen); 3467 require(T.RParen);
3530 t = new InvariantType(t); 3468 t = new InvariantType(t);
3531 break; 3469 break;
3532 } // version(D2) 3470 } // version(D2)
3538 return set(t, begin); 3476 return set(t, begin);
3539 } 3477 }
3540 3478
3541 Type parseBasicType2(Type t) 3479 Type parseBasicType2(Type t)
3542 { 3480 {
3543 typeof(token) begin;
3544 while (1) 3481 while (1)
3545 { 3482 {
3546 begin = token; 3483 auto begin = token;
3547 switch (token.kind) 3484 switch (token.kind)
3548 { 3485 {
3549 case T.Mul: 3486 case T.Mul:
3550 t = new PointerType(t); 3487 t = new PointerType(t);
3551 nT(); 3488 nT();
3570 assert(0); 3507 assert(0);
3571 } 3508 }
3572 3509
3573 bool tokenAfterParenIs(TOK tok) 3510 bool tokenAfterParenIs(TOK tok)
3574 { 3511 {
3575 // We count nested parentheses tokens because template types may appear inside parameter lists; e.g. (int x, Foo!(int) y). 3512 // We count nested parentheses tokens because template types
3513 // may appear inside parameter lists. E.g.: (int x, Foo!(int) y)
3576 assert(token.kind == T.LParen); 3514 assert(token.kind == T.LParen);
3577 Token* next = token; 3515 Token* next = token;
3578 uint level = 1; 3516 uint level = 1;
3579 Loop: 3517 Loop:
3580 while (1) 3518 while (1)
3615 if (token.kind != T.LBracket) 3553 if (token.kind != T.LBracket)
3616 return lhsType; // Break recursion; return Type on the left hand side of the Identifier. 3554 return lhsType; // Break recursion; return Type on the left hand side of the Identifier.
3617 3555
3618 auto begin = token; 3556 auto begin = token;
3619 Type t; 3557 Type t;
3620 nT(); 3558 skip(T.LBracket);
3621 if (consumed(T.RBracket)) 3559 if (consumed(T.RBracket))
3622 t = new ArrayType(parseNext()); // [ ] 3560 t = new ArrayType(parseNext()); // [ ]
3623 else 3561 else
3624 { 3562 {
3625 bool success; 3563 bool success;
3647 return parseNext(); 3585 return parseNext();
3648 } 3586 }
3649 3587
3650 Type parseArrayType(Type t) 3588 Type parseArrayType(Type t)
3651 { 3589 {
3652 assert(token.kind == T.LBracket); 3590 auto begin = token;
3653 auto begin = token; 3591 skip(T.LBracket);
3654 nT();
3655 if (consumed(T.RBracket)) 3592 if (consumed(T.RBracket))
3656 t = new ArrayType(t); 3593 t = new ArrayType(t);
3657 else 3594 else
3658 { 3595 {
3659 bool success; 3596 bool success;
3679 return t; 3616 return t;
3680 } 3617 }
3681 3618
3682 Type parseCFunctionPointerType(Type type, ref Identifier* ident, bool optionalParamList) 3619 Type parseCFunctionPointerType(Type type, ref Identifier* ident, bool optionalParamList)
3683 { 3620 {
3684 assert(token.kind == T.LParen);
3685 assert(type !is null); 3621 assert(type !is null);
3686 auto begin = token; 3622 auto begin = token;
3687 nT(); // Skip ( 3623 skip(T.LParen);
3624
3688 type = parseBasicType2(type); 3625 type = parseBasicType2(type);
3689 if (token.kind == T.LParen) 3626 if (token.kind == T.LParen)
3690 { 3627 { // Can be nested.
3691 // Can be nested.
3692 type = parseCFunctionPointerType(type, ident, true); 3628 type = parseCFunctionPointerType(type, ident, true);
3693 } 3629 }
3694 else if (token.kind == T.Identifier) 3630 else if (token.kind == T.Identifier)
3695 { 3631 { // The identifier of the function pointer and the declaration.
3696 // The identifier of the function pointer and the declaration.
3697 ident = token.ident; 3632 ident = token.ident;
3698 nT(); 3633 nT();
3699 type = parseDeclaratorSuffix(type); 3634 type = parseDeclaratorSuffix(type);
3700 } 3635 }
3701 require(T.RParen); 3636 require(T.RParen);
3749 ( ) 3684 ( )
3750 ( ExpressionList ) 3685 ( ExpressionList )
3751 +/ 3686 +/
3752 Expression[] parseArguments() 3687 Expression[] parseArguments()
3753 { 3688 {
3754 assert(token.kind == T.LParen); 3689 skip(T.LParen);
3755 nT();
3756 Expression[] args; 3690 Expression[] args;
3757 if (token.kind != TOK.RParen) 3691 if (token.kind != T.RParen)
3758 args = parseExpressionList(); 3692 args = parseExpressionList();
3759 require(TOK.RParen); 3693 require(T.RParen);
3760 return args; 3694 return args;
3761 } 3695 }
3762 3696
3763 Parameters parseParameterList() 3697 Parameters parseParameterList()
3764 out(params) 3698 out(params)
3883 3817
3884 version(D2) 3818 version(D2)
3885 { 3819 {
3886 TemplateArguments parseTemplateArguments2() 3820 TemplateArguments parseTemplateArguments2()
3887 { 3821 {
3888 assert(token.kind == T.Comma); 3822 skip(T.Comma);
3889 nT();
3890 TemplateArguments targs; 3823 TemplateArguments targs;
3891 if (token.kind != T.RParen) 3824 if (token.kind != T.RParen)
3892 targs = parseTemplateArguments_(); 3825 targs = parseTemplateArguments_();
3893 else 3826 else
3894 error(token, MSG.ExpectedTypeOrExpression); 3827 error(token, MSG.ExpectedTypeOrExpression);
3906 Type parseType_() 3839 Type parseType_()
3907 { 3840 {
3908 auto type = parseType(); 3841 auto type = parseType();
3909 if (token.kind == T.Comma || token.kind == T.RParen) 3842 if (token.kind == T.Comma || token.kind == T.RParen)
3910 return type; 3843 return type;
3911 ++errorCount; // Cause try_() to fail. 3844 errorCount++; // Cause try_() to fail.
3912 return null; 3845 return null;
3913 } 3846 }
3914 bool success; 3847 bool success;
3915 auto typeArgument = try_(&parseType_, success); 3848 auto typeArgument = try_(&parseType_, success);
3916 if (success) 3849 if (success)
3940 3873
3941 version(D2) 3874 version(D2)
3942 { 3875 {
3943 TemplateParameters parseTemplateParameterList2() 3876 TemplateParameters parseTemplateParameterList2()
3944 { 3877 {
3945 assert(token.kind == T.Comma); 3878 skip(T.Comma);
3946 nT();
3947 auto begin = token; 3879 auto begin = token;
3948 auto tparams = new TemplateParameters; 3880 auto tparams = new TemplateParameters;
3949 if (token.kind != T.RParen) 3881 if (token.kind != T.RParen)
3950 parseTemplateParameterList_(tparams); 3882 parseTemplateParameterList_(tparams);
3951 else 3883 else
3976 switch (token.kind) 3908 switch (token.kind)
3977 { 3909 {
3978 case T.Alias: 3910 case T.Alias:
3979 // TemplateAliasParameter: 3911 // TemplateAliasParameter:
3980 // alias Identifier 3912 // alias Identifier
3981 nT(); // Skip alias keyword. 3913 skip(T.Alias);
3982 ident = requireIdentifier(MSG.ExpectedAliasTemplateParam); 3914 ident = requireIdentifier(MSG.ExpectedAliasTemplateParam);
3983 parseSpecAndOrDefaultType(); 3915 parseSpecAndOrDefaultType();
3984 tp = new TemplateAliasParameter(ident, specType, defType); 3916 tp = new TemplateAliasParameter(ident, specType, defType);
3985 break; 3917 break;
3986 case T.Identifier: 3918 case T.Identifier:
3988 switch (peekNext()) 3920 switch (peekNext())
3989 { 3921 {
3990 case T.Ellipses: 3922 case T.Ellipses:
3991 // TemplateTupleParameter: 3923 // TemplateTupleParameter:
3992 // Identifier ... 3924 // Identifier ...
3993 nT(); // Skip Identifier. 3925 skip(T.Identifier); skip(T.Ellipses);
3994 nT(); // Skip Ellipses.
3995 if (token.kind == T.Comma) 3926 if (token.kind == T.Comma)
3996 error(MID.TemplateTupleParameter); 3927 error(MID.TemplateTupleParameter);
3997 tp = new TemplateTupleParameter(ident); 3928 tp = new TemplateTupleParameter(ident);
3998 break; 3929 break;
3999 case T.Comma, T.RParen, T.Colon, T.Assign: 3930 case T.Comma, T.RParen, T.Colon, T.Assign:
4000 // TemplateTypeParameter: 3931 // TemplateTypeParameter:
4001 // Identifier 3932 // Identifier
4002 nT(); // Skip Identifier. 3933 skip(T.Identifier);
4003 parseSpecAndOrDefaultType(); 3934 parseSpecAndOrDefaultType();
4004 tp = new TemplateTypeParameter(ident, specType, defType); 3935 tp = new TemplateTypeParameter(ident, specType, defType);
4005 break; 3936 break;
4006 default: 3937 default:
4007 // TemplateValueParameter: 3938 // TemplateValueParameter:
4013 version(D2) 3944 version(D2)
4014 { 3945 {
4015 case T.This: 3946 case T.This:
4016 // TemplateThisParameter 3947 // TemplateThisParameter
4017 // this TemplateTypeParameter 3948 // this TemplateTypeParameter
4018 nT(); // Skip 'this' keyword. 3949 skip(T.This);
4019 ident = requireIdentifier(MSG.ExpectedNameForThisTempParam); 3950 ident = requireIdentifier(MSG.ExpectedNameForThisTempParam);
4020 parseSpecAndOrDefaultType(); 3951 parseSpecAndOrDefaultType();
4021 tp = new TemplateThisParameter(ident, specType, defType); 3952 tp = new TemplateThisParameter(ident, specType, defType);
4022 break; 3953 break;
4023 } 3954 }
4064 3995
4065 Identifier* optionalIdentifier() 3996 Identifier* optionalIdentifier()
4066 { 3997 {
4067 Identifier* id; 3998 Identifier* id;
4068 if (token.kind == T.Identifier) 3999 if (token.kind == T.Identifier)
4069 (id = token.ident), nT(); 4000 (id = token.ident), skip(T.Identifier);
4070 return id; 4001 return id;
4071 } 4002 }
4072 4003
4073 Identifier* requireIdentifier() 4004 Identifier* requireIdentifier()
4074 { 4005 {
4075 Identifier* id; 4006 Identifier* id;
4076 if (token.kind == T.Identifier) 4007 if (token.kind == T.Identifier)
4077 (id = token.ident), nT(); 4008 (id = token.ident), skip(T.Identifier);
4078 else 4009 else
4079 error(MID.ExpectedButFound, "Identifier", token.srcText); 4010 error(MID.ExpectedButFound, "Identifier", token.srcText);
4080 return id; 4011 return id;
4081 } 4012 }
4082 4013
4083 /++ 4014 /// Params:
4084 Params: 4015 /// errorMsg = an error that has no message ID yet.
4085 errorMsg = an error that has no message ID yet.
4086 +/
4087 Identifier* requireIdentifier(char[] errorMsg) 4016 Identifier* requireIdentifier(char[] errorMsg)
4088 { 4017 {
4089 Identifier* id; 4018 Identifier* id;
4090 if (token.kind == T.Identifier) 4019 if (token.kind == T.Identifier)
4091 (id = token.ident), nT(); 4020 (id = token.ident), skip(T.Identifier);
4092 else 4021 else
4093 error(token, errorMsg, token.srcText); 4022 error(token, errorMsg, token.srcText);
4094 return id; 4023 return id;
4095 } 4024 }
4096 4025
4097 Identifier* requireIdentifier(MID mid) 4026 Identifier* requireIdentifier(MID mid)
4098 { 4027 {
4099 Identifier* id; 4028 Identifier* id;
4100 if (token.kind == T.Identifier) 4029 if (token.kind == T.Identifier)
4101 (id = token.ident), nT(); 4030 (id = token.ident), skip(T.Identifier);
4102 else 4031 else
4103 error(mid, token.srcText); 4032 error(mid, token.srcText);
4104 return id; 4033 return id;
4105 } 4034 }
4106 4035
4119 4048
4120 Token* requireIdToken(char[] errorMsg) 4049 Token* requireIdToken(char[] errorMsg)
4121 { 4050 {
4122 Token* idtok; 4051 Token* idtok;
4123 if (token.kind == T.Identifier) 4052 if (token.kind == T.Identifier)
4124 (idtok = token), nT(); 4053 (idtok = token), skip(T.Identifier);
4125 else 4054 else
4126 error(token, errorMsg, token.srcText); 4055 error(token, errorMsg, token.srcText);
4127 return idtok; 4056 return idtok;
4128 } 4057 }
4129 4058