Changeset 14
- Timestamp:
- 01/12/05 04:48:37 (7 years ago)
- Files:
-
- trunk/demangle.d (added)
- trunk/dlexer.d (modified) (38 diffs)
- trunk/dparse.d (modified) (153 diffs)
- trunk/dsymextract.d (added)
- trunk/dtags.d (deleted)
- trunk/id3tag.d (added)
- trunk/phobos-0.110-nogc-binaries.zip (added)
- trunk/phobos-0.110-nogc-src.zip (added)
- trunk/phobos-0.110-nogc.patch.bz2 (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/dlexer.d
r13 r14 11 11 import std.string; 12 12 import std.ctype; 13 14 private import std.c.stdlib; // for strtod and strtold 13 15 14 16 alias std.ctype.isdigit isdigit; … … 289 291 290 292 // A language token: 291 structToken {293 class Token { 292 294 // The kind of token: 293 295 uint value; 296 Token next; 294 297 295 298 // The value for the token: 296 299 union { 297 300 // The identifier or value of the token: 298 Identifier *ident;301 Identifier ident; 299 302 300 303 char[] ustring; … … 311 314 312 315 char[] toString() { 313 return toktostr[token]; 316 return toktostr[value]; 317 }; 318 319 static char[] toChars(uint value) { 320 return toktostr[value]; 314 321 }; 315 322 } … … 328 335 if (!isdigit(x) || (x == '8') || (x == '9')) return 0; 329 336 return -1; 337 } 338 339 class Loc { 340 public: 341 int linnum; 342 343 this() { 344 } 330 345 } 331 346 … … 443 458 protected: 444 459 Token token; 445 Identifier*[char[]] identifiers; 460 Identifier[char[]] identifiers; 461 Loc loc; 446 462 447 463 private: … … 472 488 473 489 case 0x1A: 474 error( format("unterminated string constant starting at %s", s));490 error("unterminated string constant starting at %s", s); 475 491 return null; 476 492 … … 517 533 518 534 case 0x1A: 519 error( format("unterminated string constant starting at %s", s));535 error("unterminated string constant starting at %s", s); 520 536 return null; 521 537 522 538 case '"': 523 539 if (n & 1) { 524 error( format("odd number (%d) of hex characters in hex string", n));540 error("odd number (%d) of hex characters in hex string", n); 525 541 return null; 526 542 } … … 536 552 c -= 'A' - 10; 537 553 else 538 error( format("non-hex character '%c'", c));554 error("non-hex character '%c'", c); 539 555 if (n & 1) { 540 556 v = (v << 4) | c; … … 562 578 563 579 // Possible to buffer up errors until some limit n. 564 void error(char[] msg ) {565 throw new DLexerException(this, msg);580 void error(char[] msg, ...) { 581 throw new DLexerException(this, format(msg, _arguments)); 566 582 } 567 583 568 584 // This function consumes a full D language token and returns it in the structure Token: 569 585 // null is returned if the end of the file is reached. 570 uint nextToken() {586 uint scan(Token t) { 571 587 uint start; 572 588 573 t oken.ident = null;574 t oken.uns64value = 0;575 t oken.value = TOKidentifier;589 t.ident = null; 590 t.uns64value = 0; 591 t.value = TOKidentifier; 576 592 577 593 // Past the end of file? Return an EOF token: 578 594 if (p >= file.length) { 579 t oken.value = TOKeof;580 return t oken.value;595 t.value = TOKeof; 596 return t.value; 581 597 } 582 598 … … 595 611 if (file[p] == '.') { 596 612 ++p; 597 t oken.value = TOKdotdotdot;613 t.value = TOKdotdotdot; 598 614 } else 599 t oken.value = TOKslice;615 t.value = TOKslice; 600 616 } else 601 t oken.value = TOKdot;602 return t oken.value;617 t.value = TOKdot; 618 return t.value; 603 619 604 620 case '&': … … 606 622 if (file[p] == '=') { 607 623 ++p; 608 t oken.value = TOKandass;624 t.value = TOKandass; 609 625 } else if (file[p] == '&') { 610 626 ++p; 611 t oken.value = TOKandand;627 t.value = TOKandand; 612 628 } else 613 t oken.value = TOKand;614 return t oken.value;629 t.value = TOKand; 630 return t.value; 615 631 616 632 case '|': … … 618 634 if (file[p] == '=') { 619 635 ++p; 620 t oken.value = TOKorass;636 t.value = TOKorass; 621 637 } else if (file[p] == '|') { 622 638 ++p; 623 t oken.value = TOKoror;639 t.value = TOKoror; 624 640 } else 625 t oken.value = TOKor;626 return t oken.value;641 t.value = TOKor; 642 return t.value; 627 643 628 644 case '-': … … 630 646 if (file[p] == '=') { 631 647 ++p; 632 t oken.value = TOKminass;648 t.value = TOKminass; 633 649 } else if (file[p] == '-') { 634 650 ++p; 635 t oken.value = TOKminusminus;651 t.value = TOKminusminus; 636 652 } else 637 t oken.value = TOKmin;638 return t oken.value;653 t.value = TOKmin; 654 return t.value; 639 655 640 656 case '+': … … 642 658 if (file[p] == '=') { 643 659 ++p; 644 t oken.value = TOKaddass;660 t.value = TOKaddass; 645 661 } else if (file[p] == '+') { 646 662 ++p; 647 t oken.value = TOKplusplus;663 t.value = TOKplusplus; 648 664 } else 649 t oken.value = TOKadd;650 return t oken.value;665 t.value = TOKadd; 666 return t.value; 651 667 652 668 case '=': … … 656 672 if (file[p] == '=') { 657 673 ++p; 658 t oken.value = TOKidentity;674 t.value = TOKidentity; 659 675 } else 660 t oken.value = TOKequal;676 t.value = TOKequal; 661 677 } else 662 t oken.value = TOKassign;663 return t oken.value;678 t.value = TOKassign; 679 return t.value; 664 680 665 681 case '<': … … 667 683 if (file[p] == '=') { 668 684 ++p; 669 t oken.value = TOKle; // <=685 t.value = TOKle; // <= 670 686 } else if (file[p] == '<') { 671 687 ++p; 672 688 if (file[p] == '=') { 673 689 ++p; 674 t oken.value = TOKshlass; // <<=690 t.value = TOKshlass; // <<= 675 691 } else 676 t oken.value = TOKshl; // <<692 t.value = TOKshl; // << 677 693 } else if (file[p] == '>') { 678 694 ++p; 679 695 if (file[p] == '=') { 680 696 ++p; 681 t oken.value = TOKleg; // <>=697 t.value = TOKleg; // <>= 682 698 } else 683 t oken.value = TOKlg; // <>699 t.value = TOKlg; // <> 684 700 } else 685 t oken.value = TOKlt; // <686 return t oken.value;701 t.value = TOKlt; // < 702 return t.value; 687 703 688 704 case '>': … … 690 706 if (file[p] == '=') { 691 707 ++p; 692 t oken.value = TOKge; // >=708 t.value = TOKge; // >= 693 709 } else if (file[p] == '>') { 694 710 ++p; 695 711 if (file[p] == '=') { 696 712 ++p; 697 t oken.value = TOKshrass; // >>=713 t.value = TOKshrass; // >>= 698 714 } else if (file[p] == '>') { 699 715 ++p; 700 716 if (file[p] == '=') { 701 717 ++p; 702 t oken.value = TOKushrass; // >>>=718 t.value = TOKushrass; // >>>= 703 719 } else 704 t oken.value = TOKushr; // >>>720 t.value = TOKushr; // >>> 705 721 } else 706 t oken.value = TOKshr; // >>722 t.value = TOKshr; // >> 707 723 } else 708 t oken.value = TOKgt; // >709 return t oken.value;724 t.value = TOKgt; // > 725 return t.value; 710 726 711 727 case '!': … … 715 731 if (file[p] == '=') { 716 732 ++p; 717 t oken.value = TOKnotidentity; // !==733 t.value = TOKnotidentity; // !== 718 734 } else 719 t oken.value = TOKnotequal; // !=735 t.value = TOKnotequal; // != 720 736 } else if (file[p] == '<') { 721 737 ++p; … … 724 740 if (file[p] == '=') { 725 741 ++p; 726 t oken.value = TOKunord; // !<>=742 t.value = TOKunord; // !<>= 727 743 } else 728 t oken.value = TOKue; // !<>744 t.value = TOKue; // !<> 729 745 } else if (file[p] == '=') { 730 746 ++p; 731 t oken.value = TOKug; // !<=747 t.value = TOKug; // !<= 732 748 } else 733 t oken.value = TOKuge; // !<749 t.value = TOKuge; // !< 734 750 } else if (file[p] == '>') { 735 751 ++p; 736 752 if (file[p] == '=') { 737 753 ++p; 738 t oken.value = TOKul; // !>=754 t.value = TOKul; // !>= 739 755 } else 740 t oken.value = TOKule; // !>756 t.value = TOKule; // !> 741 757 } else 742 t oken.value = TOKnot; // !743 return t oken.value;758 t.value = TOKnot; // ! 759 return t.value; 744 760 745 761 case '*': … … 747 763 if (file[p] == '=') { 748 764 ++p; 749 t oken.value = TOKmulass;765 t.value = TOKmulass; 750 766 } else 751 t oken.value = TOKmul;752 return t oken.value;767 t.value = TOKmul; 768 return t.value; 753 769 case '%': 754 770 ++p; 755 771 if (file[p] == '=') { 756 772 ++p; 757 t oken.value = TOKmodass;773 t.value = TOKmodass; 758 774 } else 759 t oken.value = TOKmod;760 return t oken.value;775 t.value = TOKmod; 776 return t.value; 761 777 case '^': 762 778 ++p; 763 779 if (file[p] == '=') { 764 780 ++p; 765 t oken.value = TOKxorass;781 t.value = TOKxorass; 766 782 } else 767 t oken.value = TOKxor;768 return t oken.value;783 t.value = TOKxor; 784 return t.value; 769 785 case '~': 770 786 ++p; 771 787 if (file[p] == '=') { 772 788 ++p; 773 t oken.value = TOKcatass;789 t.value = TOKcatass; 774 790 } else 775 t oken.value = TOKtilde;776 return t oken.value;777 778 case '(': ++p; t oken.value = TOKlparen; return token.value;779 case ')': ++p; t oken.value = TOKrparen; return token.value;791 t.value = TOKtilde; 792 return t.value; 793 794 case '(': ++p; t.value = TOKlparen; return t.value; 795 case ')': ++p; t.value = TOKrparen; return t.value; 780 796 case '[': 781 797 ++p; 782 798 if (file[p] == ']') { 783 799 ++p; 784 t oken.value = TOKarray;800 t.value = TOKarray; 785 801 } else 786 t oken.value = TOKlbracket;787 return t oken.value;788 case ']': ++p; t oken.value = TOKrbracket; return token.value;789 case '{': ++p; t oken.value = TOKlcurly; return token.value;790 case '}': ++p; t oken.value = TOKrcurly; return token.value;791 case ':': ++p; t oken.value = TOKcolon; return token.value;792 case ';': ++p; t oken.value = TOKsemicolon; return token.value;793 case '?': ++p; t oken.value = TOKquestion; return token.value;794 case ',': ++p; t oken.value = TOKcomma; return token.value;802 t.value = TOKlbracket; 803 return t.value; 804 case ']': ++p; t.value = TOKrbracket; return t.value; 805 case '{': ++p; t.value = TOKlcurly; return t.value; 806 case '}': ++p; t.value = TOKrcurly; return t.value; 807 case ':': ++p; t.value = TOKcolon; return t.value; 808 case ';': ++p; t.value = TOKsemicolon; return t.value; 809 case '?': ++p; t.value = TOKquestion; return t.value; 810 case ',': ++p; t.value = TOKcomma; return t.value; 795 811 796 812 case '/': … … 798 814 switch (file[p]) { 799 815 case '=': 800 t oken.value = TOKdivass;801 return t oken.value;816 t.value = TOKdivass; 817 return t.value; 802 818 803 819 case '/': … … 856 872 857 873 default: 858 t oken.value = TOKdiv;859 return t oken.value;874 t.value = TOKdiv; 875 return t.value; 860 876 } 861 877 break; … … 882 898 ++p; 883 899 ++p; 884 t oken.value = TOKcharv;885 t oken.ustring = tok;886 return t oken.value;900 t.value = TOKcharv; 901 t.ustring = tok; 902 return t.value; 887 903 } else { 888 904 tok.length = 1; … … 890 906 ++p; 891 907 ++p; 892 t oken.value = TOKcharv;893 t oken.ustring = tok;894 return t oken.value;908 t.value = TOKcharv; 909 t.ustring = tok; 910 return t.value; 895 911 } 896 912 } else { … … 906 922 ++p; 907 923 } 908 t oken.ustring = file[start .. p];909 t oken.value = TOKcharv;910 ++p; 911 return t oken.value;924 t.ustring = file[start .. p]; 925 t.value = TOKcharv; 926 ++p; 927 return t.value; 912 928 } 913 929 } … … 947 963 } 948 964 } 949 t oken.value = TOKstring;965 t.value = TOKstring; 950 966 tok.length = l; 951 t oken.ustring = tok;952 ++p; 953 return t oken.value;967 t.ustring = tok; 968 ++p; 969 return t.value; 954 970 } else { 955 971 // Just copy over the escape strings: … … 964 980 ++p; 965 981 } 966 t oken.value = TOKstring;967 t oken.ustring = file[start .. p];968 ++p; 969 return t oken.value;982 t.value = TOKstring; 983 t.ustring = file[start .. p]; 984 ++p; 985 return t.value; 970 986 } 971 987 } … … 980 996 } 981 997 case '`': 982 t oken.value = TOKstring;983 t oken.ustring = wysiwygString(file[p]);984 return t oken.value;998 t.value = TOKstring; 999 t.ustring = wysiwygString(file[p]); 1000 return t.value; 985 1001 986 1002 case 'x': … … 991 1007 goto case_ident; 992 1008 } 993 t oken.value = TOKstring;994 t oken.ustring = hexString();995 return t oken.value;1009 t.value = TOKstring; 1010 t.ustring = hexString(); 1011 return t.value; 996 1012 997 1013 // Identifier start with _ or a-z,A-Z: … … 1015 1031 char[] tok = file[start .. p]; 1016 1032 if (tok in keywords) { 1017 t oken.value = keywords[tok];1033 t.value = keywords[tok]; 1018 1034 } else { 1019 t oken.value = TOKidentifier;1035 t.value = TOKidentifier; 1020 1036 // Check for the identifier in the list: 1021 1037 if (tok in identifiers) { 1022 1038 // Use that. 1023 t oken.ident = identifiers[tok];1039 t.ident = identifiers[tok]; 1024 1040 } else { 1025 1041 // Make a new one. 1026 t oken.ident = new Identifier(tok, 0);1027 identifiers[tok] = t oken.ident;1042 t.ident = new Identifier(tok, 0); 1043 identifiers[tok] = t.ident; 1028 1044 } 1029 1045 } 1030 return t oken.value;1046 return t.value; 1031 1047 1032 1048 // Numeric literal: 1033 1049 case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': { 1034 number(); 1035 return token.value; 1050 return number(t); 1036 1051 } 1037 1052 … … 1045 1060 1046 1061 // Parse a real number: 1047 uint inreal( ) {1062 uint inreal(Token t) { 1048 1063 printf("inreal\n"); 1049 return TOKfloat80v; 1064 1065 int dblstate, i; 1066 char[] s; 1067 char c; 1068 char hex; // is this a hexadecimal-floating-constant? 1069 uint result; 1070 1071 //printf("Lexer::inreal()\n"); 1072 i = 0; 1073 s.length = 16; 1074 dblstate = 0; 1075 hex = 0; 1076 Lnext: 1077 while (p < file.length) { 1078 // Get next char from input 1079 c = file[p++]; 1080 while (1) { 1081 switch (dblstate) { 1082 case 0: // opening state 1083 if (c == '0') 1084 dblstate = 9; 1085 else 1086 dblstate = 1; 1087 break; 1088 1089 case 9: 1090 dblstate = 1; 1091 if (c == 'X' || c == 'x') { 1092 hex++; 1093 break; 1094 } 1095 case 1: // digits to left of . 1096 case 3: // digits to right of . 1097 case 7: // continuing exponent digits 1098 if (!isdigit(c) && !(hex && isxdigit(c))) { 1099 if (c == '_') 1100 goto Lnext; // ignore embedded '_' 1101 dblstate++; 1102 continue; 1103 } 1104 break; 1105 1106 case 2: // no more digits to left of . 1107 if (c == '.') { 1108 dblstate++; 1109 break; 1110 } 1111 case 4: // no more digits to right of . 1112 if ((c == 'E' || c == 'e') || hex && (c == 'P' || c == 'p')) { 1113 dblstate = 5; 1114 hex = 0; // exponent is always decimal 1115 break; 1116 } 1117 if (hex) 1118 error("binary-exponent-part required"); 1119 goto done; 1120 1121 case 5: // looking immediately to right of E 1122 dblstate++; 1123 if (c == '-' || c == '+') 1124 break; 1125 case 6: // 1st exponent digit expected 1126 if (!isdigit(c)) 1127 error("exponent expected"); 1128 dblstate++; 1129 break; 1130 1131 case 8: // past end of exponent digits 1132 goto done; 1133 } 1134 break; 1135 } 1136 if (i == s.length) s.length = s.length * 2; 1137 s[i++] = c; 1138 } 1139 done: 1140 p--; 1141 s.length = i; 1142 1143 setErrno(0); 1144 1145 switch (file[p]) { 1146 case 'F': 1147 case 'f': 1148 t.float80value = strtod(s.ptr, null); 1149 result = TOKfloat32v; 1150 p++; 1151 break; 1152 1153 default: 1154 t.float80value = strtod(s.ptr, null); 1155 result = TOKfloat64v; 1156 break; 1157 1158 case 'L': 1159 case 'l': 1160 t.float80value = strtold(s.ptr, null); 1161 result = TOKfloat80v; 1162 p++; 1163 break; 1164 } 1165 // Imaginary value: 1166 if (file[p] == 'i' || file[p] == 'I') { 1167 p++; 1168 switch (result) 1169 { 1170 case TOKfloat32v: 1171 result = TOKimaginary32v; 1172 break; 1173 case TOKfloat64v: 1174 result = TOKimaginary64v; 1175 break; 1176 case TOKfloat80v: 1177 result = TOKimaginary80v; 1178 break; 1179 } 1180 } 1181 // Standard C: 1182 if (getErrno() != 0) // == ERANGE 1183 error("number is not representable"); 1184 return result; 1050 1185 } 1051 1186 1052 1187 // Parse a number and return the associated value: 1053 uint number( ) {1188 uint number(Token t) { 1054 1189 // We use a state machine to collect numbers 1055 1190 enum : uint { STATE_initial, STATE_0, STATE_decimal, STATE_octal, STATE_octale, … … 1136 1271 realnum: // It's a real number. Back up and rescan as a real 1137 1272 p = start; 1138 return inreal( );1273 return inreal(t); 1139 1274 } 1140 1275 goto done; … … 1154 1289 goto realnum; 1155 1290 if (state == STATE_hex0) 1156 error( format("Hex digit expected, not '%c'", c));1291 error("Hex digit expected, not '%c'", c); 1157 1292 goto done; 1158 1293 } … … 1281 1416 case 0: 1282 1417 if (n & 0x8000000000000000L) 1283 t oken.value = TOKuns64v;1418 t.value = TOKuns64v; 1284 1419 else if (n & 0xFFFFFFFF00000000L) 1285 t oken.value = TOKint64v;1420 t.value = TOKint64v; 1286 1421 else if (n & 0x80000000) 1287 t oken.value = TOKuns32v;1422 t.value = TOKuns32v; 1288 1423 else 1289 t oken.value = TOKint32v;1424 t.value = TOKint32v; 1290 1425 break; 1291 1426 … … 1293 1428 if (n & 0x8000000000000000L) { 1294 1429 error("signed integer overflow"); 1295 t oken.value = TOKuns64v;1430 t.value = TOKuns64v; 1296 1431 } 1297 1432 else if (n & 0xFFFFFFFF80000000L) 1298 t oken.value = TOKint64v;1433 t.value = TOKint64v; 1299 1434 else 1300 t oken.value = TOKint32v;1435 t.value = TOKint32v; 1301 1436 break; 1302 1437 … … 1304 1439 case FLAGS_decimal | FLAGS_unsigned: 1305 1440 if (n & 0xFFFFFFFF00000000L) 1306 t oken.value = TOKuns64v;1441 t.value = TOKuns64v; 1307 1442 else 1308 t oken.value = TOKuns32v;1443 t.value = TOKuns32v; 1309 1444 break; 1310 1445 … … 1312 1447 if (n & 0x8000000000000000L) { 1313 1448 error("signed integer overflow"); 1314 t oken.value = TOKuns64v;1449 t.value = TOKuns64v; 1315 1450 } else 1316 t oken.value = TOKint64v;1451 t.value = TOKint64v; 1317 1452 break; 1318 1453 1319 1454 case FLAGS_long: 1320 1455 if (n & 0x8000000000000000L) 1321 t oken.value = TOKuns64v;1456 t.value = TOKuns64v; 1322 1457 else 1323 t oken.value = TOKint64v;1458 t.value = TOKint64v; 1324 1459 break; 1325 1460 1326 1461 case FLAGS_unsigned | FLAGS_long: 1327 1462 case FLAGS_decimal | FLAGS_unsigned | FLAGS_long: 1328 t oken.value = TOKuns64v;1463 t.value = TOKuns64v; 1329 1464 break; 1330 1465 … … 1333 1468 } 1334 1469 1335 token.uns64value = n; 1470 t.uns64value = n; 1471 return t.value; 1472 } 1473 1474 uint nextToken() { 1475 Token t; 1476 1477 if (token.next) { 1478 t = token.next; 1479 token = t; 1480 t.next = null; 1481 } else 1482 scan(token); 1483 1336 1484 return token.value; 1337 1485 } 1338 1486 1339 1487 // Only peek at the next token, don't consume it: 1340 uint peekToken() { 1341 uint savep = p, saveline = line; 1342 uint tok = nextToken(); 1343 p = savep; 1344 line = saveline; 1345 1346 return tok; 1488 Token peek(Token ct) { 1489 Token t; 1490 1491 if (ct.next) { 1492 t = ct.next; 1493 } else { 1494 t = new Token(); 1495 scan(t); 1496 t.next = null; 1497 ct.next = t; 1498 } 1499 1500 return t; 1347 1501 } 1348 1502 trunk/dparse.d
r13 r14 1 // d tags- D module parser1 // dparse - D module parser 2 2 // (C) Copyright 2004-2005 James Dunne 3 3 … … 6 6 // so, you may provide your modifications publicly, but you are not required to. 7 7 8 // TODO list: 9 // - correct parsing of type declarations in identifiers and functions 10 // - interface parsing 11 // - version {} blocks 12 // - correct extern (type) { } blocks, "extern (type):" and "extern (type) decl" work. 13 // - complete access modifiers on functions 8 // A minimal parser that skips over actual code. Only concerned with parsing for declarations. 14 9 15 10 module dparse; … … 20 15 21 16 import dlexer; 22 23 class Type; 24 class Expression; 25 class Declaration; 26 class Statement; 27 class Import; 28 class Initializer; 29 class FuncDeclaration; 30 class CtorDeclaration; 31 class DtorDeclaration; 32 class StaticCtorDeclaration; 33 class StaticDtorDeclaration; 34 class InvariantDeclaration; 35 class UnitTestDeclaration; 36 class NewDeclaration; 37 class DeleteDeclaration; 38 class DebugCondition; 39 class VersionCondition; 40 class Module; 41 class ModuleDeclaration; 42 class TemplateDeclaration; 43 class TemplateInstance; 44 class StaticAssert; 45 46 class EnumDeclaration; 47 class Dsymbol; 48 49 // A dynamically growing array with some stack properties: 50 class Array { 51 void*[] p; 52 int count; 53 54 this() { 55 count = 0; 56 p.length = 0; 57 } 58 59 int dim() { 60 return p.length; 61 } 62 63 void dim(int i) { 64 p.length = i; 65 } 66 67 void reserve(int i) { 68 if (p.length - count < i) 69 p.length = count + i; 70 } 71 72 void *pop() { 73 return p[--count]; 74 } 75 76 void push(void *s) { 77 reserve(1); 78 p[count++] = s; 79 } 80 81 void append(Array* a) { 82 p.length = count; 83 p ~= a; 84 count = p.length; 85 } 86 } 17 import dtypes; 18 19 const int TRUE = 1; 20 const int FALSE = 0; 87 21 88 22 class DParse : DLexer { 89 public:90 ModuleDeclaration* md;91 92 // Load up the module source code:93 this(char[] filename, char[] src) {94 // Load up the source for the lexer:95 super(filename, src);96 nextToken(); // start the scanner97 }98 99 23 private: 100 // Is this token a basic type?101 bool isType(uint value) {102 switch (value) {103 case TOKwchar: case TOKdchar:104 case TOKbit: case TOKchar:105 case TOKint8: case TOKuns8:106 case TOKint16: case TOKuns16:107 case TOKint32: case TOKuns32:108 case TOKint64: case TOKuns64:109 case TOKfloat32: case TOKfloat64: case TOKfloat80:110 case TOKimaginary32: case TOKimaginary64: case TOKimaginary80:111 case TOKcomplex32: case TOKcomplex64: case TOKcomplex80:112 case TOKvoid:113 return true;114 default:115 return false;116 }117 return false;118 }119 120 24 // Check for a certain token: 121 25 void check(uint value) { … … 131 35 } 132 36 37 uint linkage; 38 133 39 public: 40 ArrayT!(Identifier) moduleident; 41 42 // Load up the module source code: 43 this(char[] filename, char[] src) { 44 // Load up the source for the lexer: 45 super(filename, src); 46 linkage = LINKd; 47 nextToken(); // start the scanner 48 } 134 49 135 50 Array parseModule() { … … 143 58 goto Lerr; 144 59 } else { 145 Array a = null;146 Identifier *id;60 ArrayT!(Identifier) a = null; 61 Identifier id; 147 62 148 63 id = token.ident; 149 64 while (nextToken() == TOKdot) { 150 65 if (!a) 151 a = new Array ();66 a = new ArrayT!(Identifier); 152 67 a.push(id); 153 68 nextToken(); … … 159 74 } 160 75 161 m d = new ModuleDeclaration(a, id);76 moduleident = a; 162 77 163 78 if (token.value != TOKsemicolon) 164 error( "';' expected following module declaration instead of %s", token.toString());79 error(format("';' expected following module declaration instead of %s", token.toString())); 165 80 nextToken(); 166 81 } … … 181 96 } 182 97 183 Array parseDeclDefs(int once) 184 { 185 Dsymbol *s; 98 Array parseDeclDefs(int once) { 99 Dsymbol s; 186 100 Array decldefs; 187 101 Array a; … … 198 112 199 113 case TOKstruct: 114 s = parseAggregate(); 115 break; 116 200 117 case TOKunion: 118 s = parseAggregate(); 119 break; 120 201 121 case TOKclass: 122 s = parseAggregate(); 123 break; 124 202 125 case TOKinterface: 203 126 s = parseAggregate(); … … 209 132 210 133 case TOKtemplate: 211 s = cast(Dsymbol *) parseTemplateDeclaration();212 break; 213 134 s = cast(Dsymbol) parseTemplateDeclaration(); 135 break; 136 214 137 case TOKmixin: 215 138 s = parseMixin(); 216 139 break; 217 140 218 141 case TOKinstance: // Deprecated 219 if (isDeclaration( &token, 2, TOKreserved, null)) {142 if (isDeclaration(token, 2, TOKreserved, null)) { 220 143 //printf("it's a declaration\n"); 221 144 goto Ldeclaration; … … 227 150 //printf("it's an alias\n"); 228 151 ti = parseTemplateInstance(); 229 s = cast(Dsymbol *) ti;152 s = cast(Dsymbol) ti; 230 153 if (ti) { 231 154 if (token.value == TOKidentifier) { 232 s = cast(Dsymbol *)new AliasDeclaration(loc, token.ident, ti);233 155 s = new AliasDeclaration(loc, token.ident, ti); 156 234 157 nextToken(); 235 158 } … … 239 162 } 240 163 break; 241 164 242 165 case TOKwchar: case TOKdchar: 243 166 case TOKbit: case TOKchar: … … 260 183 decldefs.append(a); 261 184 continue; 262 185 263 186 case TOKthis: 264 187 s = parseCtor(); 265 188 break; 266 189 267 190 case TOKtilde: 268 191 s = parseDtor(); 269 192 break; 270 193 271 194 case TOKinvariant: 272 s = parseInvariant(); 273 break; 274 195 parseInvariant(); 196 s = null; 197 break; 198 275 199 case TOKunittest: 276 s = parseUnitTest(); 277 break; 278 200 parseUnitTest(); 201 s = null; 202 break; 203 279 204 case TOKnew: 280 205 s = parseNew(); 281 206 break; 282 207 283 208 case TOKdelete: 284 209 s = parseDelete(); 285 210 break; 286 211 287 212 case TOKeof: 288 213 case TOKrcurly: 289 214 return decldefs; 290 215 291 216 case TOKstatic: 292 217 nextToken(); … … 302 227 } 303 228 break; 304 229 305 230 case TOKconst: 306 231 stc = STCconst; … … 324 249 stc = STCdeprecated; 325 250 goto Lstc; 326 251 327 252 Lstc: 328 253 nextToken(); … … 354 279 s = new StorageClassDeclaration(stc, a); 355 280 break; 356 357 281 358 282 case TOKprivate: 359 283 prot = PROTprivate; … … 371 295 prot = PROTexport; 372 296 goto Lprot; 373 297 374 298 Lprot: 375 299 nextToken(); … … 377 301 s = new ProtDeclaration(prot, a); 378 302 break; 379 303 380 304 case TOKalign: 381 305 { 382 306 uint n; 383 307 384 308 s = null; 385 309 nextToken(); … … 395 319 check(TOKrparen); 396 320 } else 397 n = global.structalign; // default398 321 n = 4; //global.structalign; // default 322 399 323 a = parseBlock(); 400 324 s = new AlignDeclaration(n, a); 401 325 break; 402 326 } 403 327 404 328 case TOKpragma: 405 329 { 406 Identifier *ident;330 Identifier ident; 407 331 Array args = null; 408 332 409 333 nextToken(); 410 334 check(TOKlparen); … … 419 343 else 420 344 check(TOKrparen); // pragma(identifier) 421 345 422 346 if (token.value == TOKsemicolon) 423 347 a = null; 424 348 else 425 349 a = parseBlock(); 426 s = new PragmaDeclaration(ident, args, a); 350 /+s = new PragmaDeclaration(ident, args, a);+/ 351 s = null; 427 352 break; 428 353 } 429 354 430 355 case TOKextern: 431 356 { 432 357 uint link = LINKdefault; 433 358 uint linksave; 434 359 435 360 s = null; 436 361 nextToken(); … … 438 363 nextToken(); 439 364 if (token.value == TOKidentifier) { 440 Identifier *id = token.ident;365 Identifier id = token.ident; 441 366 442 367 nextToken(); … … 473 398 break; 474 399 } 475 400 476 401 case TOKdebug: 477 402 { 478 DebugCondition *condition;479 Array *aelse;480 403 DebugCondition condition; 404 Array aelse; 405 481 406 nextToken(); 482 407 if (token.value == TOKassign) { … … 496 421 break; 497 422 } 498 423 499 424 if (token.value == TOKlparen) { 500 425 nextToken(); … … 502 427 check(TOKrparen); 503 428 } else 504 condition = new DebugCondition( mod,1, null);429 condition = new DebugCondition(1, null); 505 430 a = parseBlock(); 506 431 aelse = null; … … 512 437 break; 513 438 } 514 439 515 440 case TOKversion: 516 441 { 517 VersionCondition *condition;518 Array *aelse;519 442 VersionCondition condition; 443 Array aelse; 444 520 445 nextToken(); 521 446 if (token.value == TOKassign) { … … 535 460 break; 536 461 } 537 462 538 463 if (token.value == TOKlparen) { 539 464 nextToken(); … … 553 478 break; 554 479 } 555 480 556 481 case TOKsemicolon: // empty declaration 557 482 nextToken(); 558 483 continue; 559 484 560 485 default: 561 486 error("Declaration expected, not '%s'\n", token.toString()); … … 572 497 return decldefs; 573 498 } 574 499 575 500 /******************************************** 576 501 * Parse declarations after an align, protection, or extern decl. 577 502 */ 578 579 Array * 580 parseBlock() 581 { 582 Array *a = null; 583 Dsymbol *s; 584 503 504 Array parseBlock() { 505 Array a = null; 506 Dsymbol s; 507 585 508 //printf("parseBlock()\n"); 586 509 switch (token.value) { … … 589 512 nextToken(); 590 513 break; 591 514 592 515 case TOKlcurly: 593 516 nextToken(); … … 598 521 nextToken(); 599 522 break; 600 523 601 524 case TOKcolon: 602 525 nextToken(); … … 606 529 #endif+/ 607 530 break; 608 531 609 532 default: 610 533 a = parseDeclDefs(1); … … 613 536 return a; 614 537 } 615 538 616 539 /********************************** 617 540 * Parse a static assertion. 618 541 */ 619 542 620 StaticAssert *parseStaticAssert() {543 StaticAssert parseStaticAssert() { 621 544 Loc loc = this.loc; 622 Expression *exp;623 545 Expression exp; 546 624 547 //printf("parseStaticAssert()\n"); 625 548 nextToken(); … … 635 558 */ 636 559 637 DebugCondition * 638 parseDebugCondition() 639 { 560 DebugCondition parseDebugCondition() { 640 561 uint level = 1; 641 Identifier *id = null;642 562 Identifier id = null; 563 643 564 if (token.value == TOKidentifier) 644 565 id = token.ident; … … 648 569 error("identifier or integer expected, not %s", token.toString()); 649 570 nextToken(); 650 651 return new DebugCondition( mod,level, id);652 } 653 571 572 return new DebugCondition(level, id); 573 } 574 654 575 /************************************** 655 576 * Parse a version conditional 656 577 */ 657 658 VersionCondition *parseVersionCondition() 659 { 578 579 VersionCondition parseVersionCondition() { 660 580 uint level = 1; 661 Identifier *id = null;662 581 Identifier id = null; 582 663 583 if (token.value == TOKidentifier) 664 584 id = token.ident; … … 668 588 error("identifier or integer expected, not %s", token.toString()); 669 589 nextToken(); 670 671 return new VersionCondition( mod,level, id);672 } 673 590 591 return new VersionCondition(level, id); 592 } 593 674 594 /***************************************** 675 595 * Parse a constructor definition: … … 677 597 * Current token is 'this'. 678 598 */ 679 680 CtorDeclaration *parseCtor() 681 { 682 CtorDeclaration *f; 683 Array *arguments; 599 600 CtorDeclaration parseCtor() { 601 CtorDeclaration f; 602 Array arguments; 684 603 int varargs; 685 604 Loc loc = this.loc; 686 605 687 606 nextToken(); 688 arguments = parseParameters( &varargs);607 arguments = parseParameters(varargs); 689 608 f = new CtorDeclaration(loc, 0, arguments, varargs); 690 609 parseContracts(f); 691 610 return f; 692 611 } 693 612 694 613 /***************************************** 695 614 * Parse a destructor definition: … … 697 616 * Current token is '~'. 698 617 */ 699 700 DtorDeclaration *parseDtor() 701 { 702 DtorDeclaration *f; 618 619 DtorDeclaration parseDtor() { 620 DtorDeclaration f; 703 621 Loc loc = this.loc; 704 622 705 623 nextToken(); 706 624 check(TOKthis); 707 625 check(TOKlparen); 708 626 check(TOKrparen); 709 627 710 628 f = new DtorDeclaration(loc, 0); 711 629 parseContracts(f); 712 630 return f; 713 631 } 714 632 715 633 /***************************************** 716 634 * Parse a static constructor definition: … … 718 636 * Current token is 'this'. 719 637 */ 720 721 StaticCtorDeclaration * 722 parseStaticCtor() 723 { 724 StaticCtorDeclaration *f; 638 639 StaticCtorDeclaration parseStaticCtor() { 640 StaticCtorDeclaration f; 725 641 Loc loc = this.loc; 726 642 727 643 nextToken(); 728 644 check(TOKlparen); 729 645 check(TOKrparen); 730 646 731 647 f = new StaticCtorDeclaration(loc, 0); 732 648 parseContracts(f); 733 649 return f; 734 650 } 735 651 736 652 /***************************************** 737 653 * Parse a static destructor definition: … … 739 655 * Current token is '~'. 740 656 */ 741 742 StaticDtorDeclaration * 743 parseStaticDtor() 744 { 745 StaticDtorDeclaration *f; 657 658 StaticDtorDeclaration parseStaticDtor() { 659 StaticDtorDeclaration f; 746 660 Loc loc = this.loc; 747 661 748 662 nextToken(); 749 663 check(TOKthis); 750 664 check(TOKlparen); 751 665 check(TOKrparen); 752 666 753 667 f = new StaticDtorDeclaration(loc, 0); 754 668 parseContracts(f); 755 669 return f; 756 670 } 757 671 758 672 /***************************************** 759 673 * Parse an invariant definition: … … 761 675 * Current token is 'invariant'. 762 676 */ 763 764 InvariantDeclaration * 765 parseInvariant() 766 { 767 InvariantDeclaration *f; 677 678 InvariantDeclaration parseInvariant() { 679 InvariantDeclaration f; 768 680 Loc loc = this.loc; 769 681 770 682 nextToken(); 771 683 //check(TOKlparen); // don't require () 772 684 //check(TOKrparen); 773 685 774 686 f = new InvariantDeclaration(loc, 0); 775 687 f.fbody = parseStatement(PScurly); 776 688 return f; 777 689 } 778 690 779 691 /***************************************** 780 692 * Parse a unittest definition: … … 782 694 * Current token is 'unittest'. 783 695 */ 784 785 UnitTestDeclaration * 786 parseUnitTest() 787 { 788 UnitTestDeclaration *f; 789 Statement *sbody; 696 697 UnitTestDeclaration parseUnitTest() { 698 UnitTestDeclaration f; 699 Statement sbody; 790 700 Loc loc = this.loc; 791 701 792 702 nextToken(); 793 703 794 704 sbody = parseStatement(PScurly); 795 705 796 706 f = new UnitTestDeclaration(loc, this.loc); 797 707 f.fbody = sbody; … … 805 715 */ 806 716 807 NewDeclaration * 808 parseNew() 809 { 810 NewDeclaration *f; 811 Array *arguments; 717 NewDeclaration parseNew() { 718 NewDeclaration f; 719 Array arguments; 812 720 int varargs; 813 721 Loc loc = this.loc; 814 722 815 723 nextToken(); 816 arguments = parseParameters( &varargs);724 arguments = parseParameters(varargs); 817 725 f = new NewDeclaration(loc, 0, arguments, varargs); 818 726 parseContracts(f); … … 826 734 */ 827 735 828 DeleteDeclaration * 829 parseDelete() 830 { 831 DeleteDeclaration *f; 832 Array *arguments; 736 DeleteDeclaration parseDelete() { 737 DeleteDeclaration f; 738 Array arguments; 833 739 int varargs; 834 740 Loc loc = this.loc; 835 741 836 742 nextToken(); 837 arguments = parseParameters( &varargs);743 arguments = parseParameters(varargs); 838 744 if (varargs) 839 745 error("... not allowed in delete function parameter list"); … … 842 748 return f; 843 749 } 844 750 845 751 /********************************************** 846 752 * Parse parameter list. 847 753 */ 848 849 Array * 850 parseParameters(int *pvarargs) 851 { 852 Array *arguments = new Array; 754 755 Array parseParameters(out int pvarargs) { 756 Array arguments = new Array; 853 757 int varargs = 0; 854 758 int hasdefault = 0; 855 759 856 760 check(TOKlparen); 857 761 while (1) { 858 Type *tb;859 Identifier *ai;860 Type *at;861 Argument *a;762 Type tb; 763 Identifier ai; 764 Type at; 765 Argument a; 862 766 uint inoutt; 863 Expression *ae;864 767 Expression ae; 768 865 769 ai = null; 866 770 inoutt = In; // parameter is "in" by default … … 868 772 case TOKrparen: 869 773 break; 870 774 871 775 case TOKdotdotdot: 872 776 varargs = 1; 873 777 nextToken(); 874 778 break; 875 779 876 780 case TOKin: 877 781 inoutt = In; 878 782 nextToken(); 879 783 goto L1; 880 784 881 785 case TOKout: 882 786 inoutt = Out; 883 787 nextToken(); 884 788 goto L1; 885 789 886 790 case TOKinout: 887 791 inoutt = InOut; 888 792 nextToken(); 889 793 goto L1; 890 794 891 795 default: 892 796 L1: … … 914 818 } 915 819 check(TOKrparen); 916 *pvarargs = varargs;820 pvarargs = varargs; 917 821 return arguments; 918 822 } 919 823 920 824 /************************************* 921 825 */ 922 923 EnumDeclaration * 924 parseEnum() 925 { 926 EnumDeclaration *e; 927 Identifier *id; 928 Type *t; 929 826 827 EnumDeclaration parseEnum() { 828 EnumDeclaration e; 829 Identifier id; 830 Type t; 831 930 832 //printf("parseEnum()\n"); 931 833 nextToken(); … … 935 837 } else 936 838 id = null; 937 839 938 840 if (token.value == TOKcolon) { 939 841 nextToken(); … … 941 843 } else 942 844 t = null; 943 845 944 846 e = new EnumDeclaration(id, t); 945 847 if (token.value == TOKsemicolon && id) … … 947 849 else if (token.value == TOKlcurly) { 948 850 //printf("enum definition\n"); 949 e.members = new Array ;851 e.members = new ArrayT!(EnumMember); 950 852 nextToken(); 951 853 while (token.value != TOKrcurly) { 952 854 if (token.value == TOKidentifier) { 953 EnumMember *em;954 Expression *value;955 Identifier *ident;956 855 EnumMember em; 856 Expression value; 857 Identifier ident; 858 957 859 ident = token.ident; 958 860 value = null; … … 975 877 } else 976 878 error("enum declaration is invalid"); 977 879 978 880 return e; 979 881 } 980 981 Dsymbol * 982 parseAggregate() 983 { 984 AggregateDeclaration *a = null; 882 883 Dsymbol parseAggregate() { 884 AggregateDeclaration a = null; 985 885 int anon = 0; 986 886 uint tok; 987 Identifier *id;988 Array *tpl = null;989 887 Identifier id; 888 Array tpl = null; 889 990 890 //printf("parseAggregate()\n"); 991 891 tok = token.value; … … 996 896 id = token.ident; 997 897 nextToken(); 998 898 999 899 if (token.value == TOKlparen) { // Class template declaration. 1000 900 1001 901 // Gather template parameter list 1002 902 tpl = parseTemplateParameterList(); 1003 903 } 1004 904 } 1005 905 1006 906 switch (tok) { 1007 907 case TOKclass: 1008 908 case TOKinterface: 1009 909 { 1010 Array *baseclasses = null;1011 BaseClass *b;1012 910 Array baseclasses = null; 911 BaseClass b; 912 1013 913 if (!id) 1014 914 error("anonymous classes not allowed"); 1015 915 1016 916 // Collect base class(es) 1017 917 b = null; 1018 918 if (token.value == TOKcolon) { 1019 919 uint protection = PROTpublic; 1020 920 1021 921 baseclasses = new Array; 1022 922 while (1) { … … 1051 951 error("members expected"); 1052 952 } 1053 953 1054 954 if (tok == TOKclass) 1055 955 a = new ClassDeclaration(loc, id, baseclasses); … … 1058 958 break; 1059 959 } 1060 960 1061 961 case TOKstruct: 1062 962 if (id) … … 1065 965 anon = 1; 1066 966 break; 1067 967 1068 968 case TOKunion: 1069 969 if (id) … … 1072 972 anon = 2; 1073 973 break; 1074 974 1075 975 default: 1076 976 assert(0); 1077 977 break; 1078 978 } 979 1079 980 if (a && token.value == TOKsemicolon) { 1080 981 nextToken(); … … 1082 983 //printf("aggregate definition\n"); 1083 984 nextToken(); 1084 Array *decl = parseDeclDefs(0);1085 985 Array decl = parseDeclDefs(0); 986 1086 987 if (token.value != TOKrcurly) 1087 988 error("struct member expected"); … … 1097 998 a = new StructDeclaration(loc, null); 1098 999 } 1099 1000 1100 1001 if (tpl) { 1101 Array *decldefs;1102 TemplateDeclaration *tempdecl;1103 1002 Array decldefs; 1003 TemplateDeclaration tempdecl; 1004 1104 1005 // Wrap a template around the aggregate declaration 1105 1006 decldefs = new Array; … … 1108 1009 return tempdecl; 1109 1010 } 1110 1011 1111 1012 return a; 1112 1013 } 1113 1014 1114 1015 /************************************** 1115 1016 * Parse a TemplateDeclaration. 1116 1017 */ 1117 1118 TemplateDeclaration * 1119 parseTemplateDeclaration() 1120 { 1121 TemplateDeclaration *tempdecl; 1122 Identifier *id; 1123 Array *tpl; 1124 Array *decldefs; 1018 1019 TemplateDeclaration parseTemplateDeclaration() { 1020 TemplateDeclaration tempdecl; 1021 Identifier id; 1022 Array tpl; 1023 Array decldefs; 1125 1024 Loc loc = this.loc; 1126 1025 1127 1026 nextToken(); 1128 1027 if (token.value != TOKidentifier) { … … 1135 1034 if (!tpl) 1136 1035 goto Lerr; 1137 1036 1138 1037 if (token.value != TOKlcurly) { 1139 1038 error("members of template declaration expected"); … … 1148 1047 nextToken(); 1149 1048 } 1150 1049 1151 1050 tempdecl = new TemplateDeclaration(loc, id, tpl, decldefs); 1152 1051 return tempdecl; 1153 1052 1154 1053 Lerr: 1155 1054 return null; 1156 1055 } 1157 1056 1158 1057 /****************************************** 1159 1058 * Parse template parameter list. 1160 1059 */ 1161 1162 Array * 1163 parseTemplateParameterList() 1164 { 1165 Array *tpl; 1166 1060 1061 Array parseTemplateParameterList() { 1062 Array tpl; 1063 1167 1064 if (token.value != TOKlparen) { 1168 1065 error("parenthesized TemplateParameterList expected following TemplateIdentifier"); … … 1171 1068 tpl = new Array; 1172 1069 nextToken(); 1173 1070 1174 1071 // Get TemplateParameterList 1175 1072 if (token.value != TOKrparen) { 1176 1073 while (1) { 1177 TemplateParameter *tp;1178 Identifier *tp_ident = null;1179 Type *tp_spectype = null;1180 Type *tp_valtype = null;1181 Type *tp_defaulttype = null;1182 Expression *tp_specvalue = null;1183 Expression *tp_defaultvalue = null;1184 Token *t;1185 1074 TemplateParameter tp; 1075 Identifier tp_ident; 1076 Type tp_spectype; 1077 Type tp_valtype; 1078 Type tp_defaulttype; 1079 Expression tp_specvalue; 1080 Expression tp_defaultvalue; 1081 Token t; 1082 1186 1083 // Get TemplateParameter 1187 1084 1188 1085 // First, look ahead to see if it is a TypeParameter or a ValueParameter 1189 t = peek( &token);1086 t = peek(token); 1190 1087 if (token.value == TOKalias) { // AliasParameter 1191 1088 nextToken(); … … 1250 1147 check(TOKrparen); 1251 1148 return tpl; 1252 1149 1253 1150 Lerr: 1254 1151 return null; 1255 1152 } 1256 1153 1257 1154 /************************************** 1258 1155 * Parse a TemplateInstance. 1259 1156 */ 1260 1261 TemplateInstance * 1262 parseTemplateInstance() 1263 { 1264 TemplateInstance *tempinst; 1265 Identifier *id; 1157 1158 TemplateInstance parseTemplateInstance() { 1159 TemplateInstance tempinst; 1160 Identifier id; 1266 1161 1267 1162 //printf("parseTemplateInstance()\n"); 1268 1163 nextToken(); 1269 1164 if (token.value == TOKdot) { 1270 id = Id empty;1165 id = Id.empty; 1271 1166 } else if (token.value == TOKidentifier) { 1272 1167 id = token.ident; … … 1287 1182 nextToken(); 1288 1183 } 1289 tempinst.tiargs =parseTemplateArgumentList();1290 1291 if (!global.params.useDeprecated)1292 error("instance is deprecated, use %s", tempinst.toString());1184 /+tempinst.tiargs = +/parseTemplateArgumentList(); 1185 1186 //if (!global.params.useDeprecated) 1187 // error("instance is deprecated, use %s", tempinst.toString()); 1293 1188 return tempinst; 1294 1189 1295 1190 Lerr: 1296 1191 return null; 1297 1192 } 1298 1193 1299 1194 /****************************************** 1300 1195 * Parse template mixin. … … 1304 1199 * mixin Foo!(args) identifier; 1305 1200 */ 1306 1307 Dsymbol * 1308 parseMixin() 1309 { 1310 TemplateMixin *tm; 1311 Identifier *id; 1312 TypeTypeof *tqual; 1313 Array *tiargs; 1314 Array *idents; 1315 1201 1202 TemplateMixin parseMixin() { 1203 TemplateMixin tm; 1204 Identifier id; 1205 TypeTypeof tqual; 1206 Array tiargs; 1207 ArrayT!(Identifier) idents; 1208 1316 1209 //printf("parseMixin()\n"); 1317 1210 nextToken(); 1318 1211 1319 1212 tqual = null; 1320 1213 if (token.value == TOKdot) { 1321 id = Id empty;1214 id = Id.empty; 1322 1215 } else { 1323 1216 if (token.value == TOKtypeof) { 1324 Expression *exp;1325 1217 Expression exp; 1218 1326 1219 nextToken(); 1327 1220 check(TOKlparen); … … 1337 1230 id = token.ident; 1338 1231 } 1339 1340 idents = new Array ;1232 1233 idents = new ArrayT!(Identifier); 1341 1234 while (1) { 1342 1235 nextToken(); … … 1344 1237 if (token.value == TOKnot) { 1345 1238 nextToken(); 1346 tiargs =parseTemplateArgumentList();1347 } 1348 1239 /+tiargs = +/parseTemplateArgumentList(); 1240 } 1241 1349 1242 if (token.value != TOKdot) 1350 1243 break; 1351 1244 1352 1245 if (tiargs) { 1353 TemplateInstance *tempinst = new TemplateInstance(loc, id);1246 TemplateInstance tempinst = new TemplateInstance(loc, id); 1354 1247 1355 1248 tempinst.tiargs = tiargs; 1356 id = cast(Identifier *) tempinst;1249 id = cast(Identifier) tempinst; 1357 1250 tiargs = null; 1358 1251 } 1359 1252 idents.push(id); 1360 1253 1361 1254 nextToken(); 1362 1255 if (token.value != TOKidentifier) { … … 1367 1260 } 1368 1261 idents.push(id); 1369 1262 1370 1263 if (token.value == TOKidentifier) { 1371 1264 id = token.ident; … … 1373 1266 } else 1374 1267 id = null; 1375 1268 1376 1269 tm = new TemplateMixin(loc, id, tqual, idents, tiargs); 1377 1270 if (token.value != TOKsemicolon) 1378 1271 error("';' expected after mixin"); 1379 1272 nextToken(); 1380 1273 1381 1274 return tm; 1382 1275 1383 1276 Lerr: 1384 1277 return null; 1385 1278 } 1386 1279 1387 1280 /****************************************** 1388 1281 * Parse template argument list. … … 1392 1285 * current token is one after closing ')' 1393 1286 */ 1394 1395 Array * 1396 parseTemplateArgumentList() 1397 { 1398 Array *tiargs = new Array; 1399 1287 1288 void parseTemplateArgumentList() { 1289 /+ArrayT!(Object) tiargs = new Array;+/ 1290 1400 1291 if (token.value != TOKlparen) { 1401 1292 error("!(TemplateArgumentList) expected following TemplateIdentifier"); 1402 return tiargs;1293 return/+ tiargs+/; 1403 1294 } 1404 1295 nextToken(); 1405 1296 1406 1297 // Get TemplateArgumentList 1407 1298 if (token.value != TOKrparen) { 1408 1299 while (1) { 1409 1300 // See if it is an Expression or a Type 1410 if (isDeclaration(&token, 0, TOKreserved, null)) { // Type1411 Type *ta;1412 1301 /+if (isDeclaration(&token, 0, TOKreserved, null)) { // Type 1302 Type ta; 1303 1413 1304 // Get TemplateArgument 1414 1305 ta = parseBasicType(); … … 1416 1307 tiargs.push(ta); 1417 1308 } else { // Expression 1418 Expression *ea;1419 1309 Expression ea; 1310 1420 1311 ea = parseAssignExp(); 1421 1312 tiargs.push(ea); 1422 } 1313 }+/ 1423 1314 if (token.value != TOKcomma) 1424 1315 break; … … 1427 1318 } 1428 1319 check(TOKrparen, "template argument list"); 1429 return tiargs; 1430 } 1431 1432 Import * 1433 parseImport(Array * decldefs) 1434 { 1435 Import *s; 1436 Identifier *id; 1437 Array *a; 1320 return/+ tiargs+/; 1321 } 1322 1323 Import parseImport(Array decldefs) { 1324 Import s; 1325 Identifier id; 1326 ArrayT!(Identifier) a; 1438 1327 Loc loc; 1439 1328 1440 1329 //printf("parseImport()\n"); 1441 1330 do { … … 1445 1334 break; 1446 1335 } 1447 1336 1448 1337 loc = this.loc; 1449 1338 a = null; … … 1451 1340 while (nextToken() == TOKdot) { 1452 1341 if (!a) 1453 a = new Array ;1342 a = new ArrayT!(Identifier); 1454 1343 a.push(id); 1455 1344 nextToken(); … … 1460 1349 id = token.ident; 1461 1350 } 1462 1351 1463 1352 s = new Import(loc, a, token.ident); 1464 1353 decldefs.push(s); 1465 1354 } while (token.value == TOKcomma); 1466 1355 1467 1356 if (token.value == TOKsemicolon) 1468 1357 nextToken(); … … 1471 1360 nextToken(); 1472 1361 } 1473 1362 1474 1363 return null; 1475 1364 } 1476 1477 Type *parseBasicType() 1478 { 1479 Type *t; 1480 Identifier *id; 1481 TypeQualified *tid; 1482 TemplateInstance *tempinst; 1365 1366 Type parseBasicType() { 1367 Type t; 1368 Identifier id; 1369 TypeQualified tid; 1370 TemplateInstance tempinst; 1483 1371 1484 1372 //printf("parseBasicType()\n"); … … 1509 1397 nextToken(); 1510 1398 break; 1511 1399 1512 1400 case TOKidentifier: 1513 1401 id = token.ident; … … 1516 1404 nextToken(); 1517 1405 tempinst = new TemplateInstance(loc, id); 1518 tempinst.tiargs =parseTemplateArgumentList();1406 /+tempinst.tiargs = +/parseTemplateArgumentList(); 1519 1407 tid = new TypeInstance(loc, tempinst); 1520 1408 goto Lident2; … … 1534 1422 nextToken(); 1535 1423 tempinst = new TemplateInstance(loc, id); 1536 tempinst.tiargs =parseTemplateArgumentList();1537 tid.addIdent(cast(Identifier *) tempinst);1424 /+tempinst.tiargs = +/parseTemplateArgumentList(); 1425 /+tid.addIdent(cast(Identifier) tempinst);+/ 1538 1426 } else 1539 tid.addIdent(id);1427 /+tid.addIdent(id);+/ { } 1540 1428 } 1541 1429 t = tid; 1542 1430 break; 1543 1431 1544 1432 case TOKdot: 1545 id = Id empty;1433 id = Id.empty; 1546 1434 goto Lident; 1547 1435 1548 1436 case TOKinstance: 1549 1437 { // Deprecated … … 1554 1442 break; 1555 1443 } 1556 1444 1557 1445 tid = new TypeInstance(loc, tempinst); 1558 1446 goto Lident2; 1559 1447 } 1560 1448 1561 1449 case TOKtypeof: 1562 1450 { 1563 Expression *exp;1564 1451 Expression exp; 1452 1565 1453 nextToken(); 1566 1454 check(TOKlparen); … … 1570 1458 goto Lident2; 1571 1459 } 1572 1460 1573 1461 default: 1574 1462 error("basic type expected, not %s", token.toString()); … … 1578 1466 return t; 1579 1467 } 1580 1581 Type * 1582 parseBasicType2(Type * t) 1583 { 1584 Expression *e; 1585 Type *ts; 1586 Type *ta; 1587 1468 1469 Type parseBasicType2(Type t) { 1470 Expression e; 1471 Type ts; 1472 Type ta; 1473 1588 1474 //printf("parseBasicType2()\n"); 1589 1475 while (1) { … … 1602 1488 t = new TypeDArray(t); // [] 1603 1489 nextToken(); 1604 } else if (isDeclaration( &token, 0, TOKrbracket, null)) { // It's an associative array declaration1605 Type *index;1606 1490 } else if (isDeclaration(token, 0, TOKrbracket, null)) { // It's an associative array declaration 1491 Type index; 1492 1607 1493 //printf("it's an associative array\n"); 1608 1494 index = parseBasicType(); … … 1617 1503 } 1618 1504 continue; 1619 1505 1620 1506 case TOKdelegate: 1621 1507 case TOKfunction: … … 1623 1509 // t delegate(parameter list) 1624 1510 // t function(parameter list) 1625 Array *arguments;1511 Array arguments; 1626 1512 int varargs; 1627 1513 uint save = token.value; 1628 1629 nextToken(); 1630 arguments = parseParameters( &varargs);1514 1515 nextToken(); 1516 arguments = parseParameters(varargs); 1631 1517 t = new TypeFunction(arguments, t, varargs, linkage); 1632 1518 if (save == TOKdelegate) … … 1636 1522 continue; 1637 1523 } 1638 1524 1639 1525 default: 1640 1526 ts = t; … … 1645 1531 return ts; 1646 1532 } 1647 1648 Type * 1649 parseDeclarator(Type * t, Identifier ** pident) 1650 { 1651 Expression *e; 1652 Type *ts; 1653 Type *ta; 1654 Type **pt; 1655 1533 1534 Type parseDeclarator(Type t, Identifier *pident) { 1535 Expression e; 1536 Type ts; 1537 Type ta; 1538 Type *pt; 1539 1656 1540 //printf("parseDeclarator(t = %p)\n", t); 1657 1541 while (1) { … … 1670 1554 t = new TypeDArray(t); // [] 1671 1555 nextToken(); 1672 } else if (isDeclaration( &token, 0, TOKrbracket, null)) { // It's an associative array declaration1673 Type *index;1674 1556 } else if (isDeclaration(token, 0, TOKrbracket, null)) { // It's an associative array declaration 1557 Type index; 1558 1675 1559 //printf("it's an associative array\n"); 1676 1560 index = parseBasicType(); … … 1685 1569 } 1686 1570 continue; 1687 1571 1688 1572 case TOKidentifier: 1689 1573 if (pident) … … 1694 1578 nextToken(); 1695 1579 break; 1696 1580 1697 1581 case TOKlparen: 1698 1582 nextToken(); … … 1700 1584 check(TOKrparen); 1701 1585 break; 1702 1586 1703 1587 case TOKdelegate: 1704 1588 case TOKfunction: … … 1706 1590 // t delegate(parameter list) 1707 1591 // t function(parameter list) 1708 Array *arguments;1592 Array arguments; 1709 1593 int varargs; 1710 1594 uint save = token.value; 1711 1712 nextToken(); 1713 arguments = parseParameters( &varargs);1595 1596 nextToken(); 1597 arguments = parseParameters(varargs); 1714 1598 t = new TypeFunction(arguments, t, varargs, linkage); 1715 1599 if (save == TOKdelegate) … … 1725 1609 break; 1726 1610 } 1727 1611 1728 1612 while (1) { 1729 1613 switch (token.value) { … … 1735 1619 ta = new TypeDArray(t); // [] 1736 1620 nextToken(); 1737 } else if (isDeclaration( &token, 0, TOKrbracket, null)) { // It's an associative array declaration1738 Type *index;1739 1621 } else if (isDeclaration(token, 0, TOKrbracket, null)) { // It's an associative array declaration 1622 Type index; 1623 1740 1624 //printf("it's an associative array\n"); 1741 1625 index = parseBasicType(); … … 1749 1633 check(TOKrbracket); 1750 1634 } 1751 for (pt = &ts; *pt != t; pt = &( *pt).next) {}1635 for (pt = &ts; *pt != t; pt = &((*pt).next)) {} 1752 1636 *pt = ta; 1753 1637 continue; 1754 1638 case TOKlparen: 1755 1639 { 1756 Array *arguments;1640 Array arguments; 1757 1641 int varargs; 1758 1759 arguments = parseParameters( &varargs);1642 1643 arguments = parseParameters(varargs); 1760 1644 ta = new TypeFunction(arguments, t, varargs, linkage); 1761 for (pt = &ts; *pt != t; pt = &( *pt).next) {}1645 for (pt = &ts; *pt != t; pt = &((*pt).next)) {} 1762 1646 *pt = ta; 1763 1647 continue; … … 1766 1650 break; 1767 1651 } 1768 1652 1769 1653 return ts; 1770 1654 } … … 1774 1658 */ 1775 1659 1776 Array * 1777 parseDeclaration() 1778 { 1660 Array parseDeclaration() { 1779 1661 uint storage_class; 1780 1662 uint sc; 1781 Type *ts;1782 Type *t;1783 Type *tfirst;1784 Identifier *ident;1785 Array *a;1663 Type ts; 1664 Type t; 1665 Type tfirst; 1666 Identifier ident; 1667 Array a; 1786 1668 uint tok; 1787 1669 1788 1670 //printf("parseDeclaration()\n"); 1789 1671 switch (token.value) { … … 1793 1675 nextToken(); 1794 1676 break; 1795 1677 1796 1678 default: 1797 1679 tok = TOKreserved; 1798 1680 break; 1799 1681 } 1800 1682 1801 1683 storage_class = STCundefined; 1802 1684 while (1) { … … 1829 1711 if (storage_class & sc) 1830 1712 error("redundant storage class '%s'", token.toString()); 1831 storage_class = cast(STC)(storage_class | sc);1713 storage_class = (storage_class | sc); 1832 1714 nextToken(); 1833 1715 continue; … … 1835 1717 break; 1836 1718 } 1837 1719 1838 1720 a = new Array; 1839 1721 ts = parseBasicType(); 1840 1722 ts = parseBasicType2(ts); 1841 1723 tfirst = null; 1842 1724 1843 1725 while (1) { 1844 1726 Loc loc = this.loc; 1845 1727 1846 1728 ident = null; 1847 1729 t = parseDeclarator(ts, &ident); … … 1853 1735 if (!ident) 1854 1736 error("no identifier for declarator"); 1855 1737 1856 1738 if (tok == TOKtypedef || tok == TOKalias) { 1857 Declaration *v;1858 Initializer *init;1859 1739 Declaration v; 1740 Initializer init; 1741 1860 1742 init = null; 1861 1743 if (token.value == TOKassign) { … … 1876 1758 nextToken(); 1877 1759 break; 1878 1760 1879 1761 case TOKcomma: 1880 1762 nextToken(); 1881 1763 continue; 1882 1764 1883 1765 default: 1884 1766 error("semicolon expected to close %s declaration", Token.toChars(tok)); … … 1886 1768 } 1887 1769 } else if (t.ty == Tfunction) { 1888 FuncDeclaration *f;1889 1770 FuncDeclaration f; 1771 1890 1772 f = new FuncDeclaration(loc, 0, ident, storage_class, t); 1891 1773 a.push(f); 1892 1774 parseContracts(f); 1893 1775 } else { 1894 VarDeclaration *v;1895 Initializer *init;1896 1776 VarDeclaration v; 1777 Initializer init; 1778 1897 1779 init = null; 1898 1780 if (token.value == TOKassign) { … … 1907 1789 nextToken(); 1908 1790 break; 1909 1791 1910 1792 case TOKcomma: 1911 1793 nextToken(); 1912 1794 continue; 1913 1795 1914 1796 default: 1915 1797 error("semicolon expected, not '%s'", token.toString()); … … 1921 1803 return a; 1922 1804 } 1923 1805 1924 1806 /***************************************** 1925 1807 * Parse contracts following function declaration. 1926 1808 */ 1927 1928 void 1929 parseContracts(FuncDeclaration * f) 1930 { 1931 Type *tb; 1809 1810 void parseContracts(FuncDeclaration f) { 1811 Type tb; 1932 1812 uint linksave = linkage; 1933 1813 1934 1814 // The following is irrelevant, as it is overridden by sc.linkage in 1935 1815 // TypeFunction.semantic … … 1941 1821 error("missing body { ... } after in or out"); 1942 1822 f.fbody = parseStatement(PSsemi); 1943 f.endloc = endloc;1823 /+f.endloc = endloc;+/ 1944 1824 break; 1945 1825 … … 1947 1827 nextToken(); 1948 1828 f.fbody = parseStatement(PScurly); 1949 f.endloc = endloc;1829 /+f.endloc = endloc;+/ 1950 1830 break; 1951 1831 … … 1989 1869 */ 1990 1870 1991 Initializer * 1992 parseInitializer() 1993 { 1994 StructInitializer *ist; 1995 ArrayInitializer *ia; 1996 ExpInitializer *ie; 1997 Expression *e; 1998 Identifier *id; 1999 Initializer *value; 1871 Initializer parseInitializer() { 1872 StructInitializer ist; 1873 ArrayInitializer ia; 1874 ExpInitializer ie; 1875 Expression e; 1876 Identifier id; 1877 Initializer value; 2000 1878 int comma; 2001 1879 Loc loc = this.loc; 2002 Token *t;1880 Token t; 2003 1881 2004 1882 switch (token.value) { … … 2012 1890 if (comma == 1) 2013 1891 error("comma expected separating field initializers"); 2014 t = peek( &token);1892 t = peek(token); 2015 1893 if (t.value == TOKcolon) { 2016 1894 id = token.ident; … … 2097 1975 } 2098 1976 return ia; 2099 1977 2100 1978 default: 2101 1979 e = parseAssignExp(); … … 2104 1982 } 2105 1983 } 2106 2107 1984 1985 2108 1986 /***************************************** 2109 1987 * Input: 2110 1988 * flags PSxxxx 2111 1989 */ 2112 2113 Statement *parseStatement(int flags)1990 1991 Statement parseStatement(int flags) 2114 1992 { 2115 Statement *s;2116 Token *t;1993 Statement s; 1994 Token t; 2117 1995 Loc loc = this.loc; 2118 1996 2119 1997 //printf("parseStatement()\n"); 2120 1998 … … 2125 2003 case TOKidentifier: 2126 2004 // Need to look ahead to see if it is a declaration, label, or expression 2127 t = peek( &token);2005 t = peek(token); 2128 2006 if (t.value == TOKcolon) { // It's a label 2129 Identifier *ident;2007 Identifier ident; 2130 2008 2131 2009 ident = token.ident; 2132 2010 nextToken(); 2133 2011 nextToken(); 2134 s = parseStatement(PSsemi); 2135 s = new LabelStatement(loc, ident, s); 2012 /+s = +/parseStatement(PSsemi); 2013 /+s = new LabelStatement(loc, ident, s);+/ 2014 s = null; 2136 2015 break; 2137 2016 } … … 2139 2018 case TOKdot: 2140 2019 case TOKtypeof: 2141 if (isDeclaration( &token, 2, TOKreserved, null))2020 if (isDeclaration(token, 2, TOKreserved, null)) 2142 2021 goto Ldeclaration; 2143 2022 else … … 2179 2058 Lexp: 2180 2059 { 2181 Expression *exp;2060 Expression exp; 2182 2061 2183 2062 exp = parseExpression(); 2184 2063 check(TOKsemicolon, "statement"); 2185 s = new ExpStatement(loc, exp);2064 /+s = new ExpStatement(loc, exp);+/ 2186 2065 break; 2187 2066 } … … 2193 2072 * 3) Expression 2194 2073 */ 2195 if (isDeclaration( &token, 2, TOKreserved, null)) {2074 if (isDeclaration(token, 2, TOKreserved, null)) { 2196 2075 //printf("it's a declaration\n"); 2197 2076 goto Ldeclaration; 2198 2077 } else { 2199 if (isTemplateInstance( &token, &t) && t.value == TOKidentifier) { // case 22200 TemplateInstance *ti;2201 AliasDeclaration *a;2078 if (isTemplateInstance(token, &t) && t.value == TOKidentifier) { // case 2 2079 TemplateInstance ti; 2080 AliasDeclaration a; 2202 2081 2203 2082 ti = parseTemplateInstance(); … … 2217 2096 case TOKstatic: 2218 2097 { // Look ahead to see if it's static assert() 2219 Token *t;2220 2221 t = peek( &token);2098 Token t; 2099 2100 t = peek(token); 2222 2101 if (t.value == TOKassert) { 2223 2102 nextToken(); 2224 s = new StaticAssertStatement(parseStaticAssert()); 2103 /+s = new StaticAssertStatement(parseStaticAssert());+/ 2104 s = null; 2225 2105 break; 2226 2106 } … … 2246 2126 Ldeclaration: 2247 2127 { 2248 Array *a;2128 Array a; 2249 2129 2250 2130 a = parseDeclaration(); 2251 2131 if (a.dim > 1) { 2252 Array *as = new Array;2132 ArrayT!(Statement) as = new ArrayT!(Statement)(); 2253 2133 2254 2134 as.reserve(a.dim); 2255 2135 for (int i = 0; i < a.dim; i++) { 2256 Dsymbol *d = cast(Dsymbol *) a.data[i];2136 Dsymbol d = cast(Dsymbol) a.data[i]; 2257 2137 2258 2138 s = new DeclarationStatement(loc, d); … … 2261 2141 s = new CompoundStatement(loc, as); 2262 2142 } else if (a.dim == 1) { 2263 Dsymbol *d = cast(Dsymbol *) a.data[0];2143 Dsymbol d = cast(Dsymbol) a.data[0]; 2264 2144 2265 2145 s = new DeclarationStatement(loc, d); 2266 2146 } else 2267 2147 assert(0); 2268 if (flags & PSscope)2269 s = new ScopeStatement(loc, s);2270 2148 break; 2271 2149 } … … 2276 2154 case TOKinterface: 2277 2155 { 2278 Dsymbol *d;2156 Dsymbol d; 2279 2157 2280 2158 d = parseAggregate(); … … 2285 2163 case TOKenum: 2286 2164 { 2287 Dsymbol *d;2165 Dsymbol d; 2288 2166 2289 2167 d = parseEnum(); … … 2294 2172 case TOKmixin: 2295 2173 { 2296 Dsymbol *d;2174 Dsymbol d; 2297 2175 2298 2176 d = parseMixin(); … … 2303 2181 case TOKlcurly: 2304 2182 { 2305 Array *statements; 2306 2307 nextToken(); 2308 statements = new Array; 2183 nextToken(); 2309 2184 while (token.value != TOKrcurly) { 2310 statements.push(parseStatement(PSsemi | PScurlyscope)); 2311 } 2312 endloc = this.loc; 2313 s = new CompoundStatement(loc, statements); 2314 if (flags & (PSscope | PScurlyscope)) 2315 s = new ScopeStatement(loc, s); 2185 parseStatement(PSsemi | PScurlyscope); 2186 } 2316 2187 nextToken(); 2317 2188 break; … … 2320 2191 case TOKwhile: 2321 2192 { 2322 Expression *condition;2323 Statement *sbody;2324 2325 2193 nextToken(); 2326 2194 check(TOKlparen); 2327 condition =parseExpression();2195 parseExpression(); 2328 2196 check(TOKrparen); 2329 sbody =parseStatement(PSscope);2330 s = n ew WhileStatement(loc, condition, sbody);2197 parseStatement(PSscope); 2198 s = null; 2331 2199 break; 2332 2200 } … … 2341 2209 case TOKdo: 2342 2210 { 2343 Statement *sbody; 2344 Expression *condition; 2345 2346 nextToken(); 2347 sbody = parseStatement(PSscope); 2211 nextToken(); 2212 parseStatement(PSscope); 2348 2213 check(TOKwhile); 2349 2214 check(TOKlparen); 2350 condition =parseExpression();2215 parseExpression(); 2351 2216 check(TOKrparen); 2352 s = n ew DoStatement(loc, sbody, condition);2217 s = null; 2353 2218 break; 2354 2219 } … … 2356 2221 case TOKfor: 2357 2222 { 2358 Statement *init;2359 Expression *condition;2360 Expression *increment;2361 Statement *sbody;2362 2363 2223 nextToken(); 2364 2224 check(TOKlparen); 2365 2225 if (token.value == TOKsemicolon) { 2366 init = null;2367 2226 nextToken(); 2368 2227 } else { 2369 init =parseStatement(0);2228 parseStatement(0); 2370 2229 } 2371 2230 if (token.value == TOKsemicolon) { 2372 condition = null;2373 2231 nextToken(); 2374 2232 } else { 2375 condition =parseExpression();2233 parseExpression(); 2376 2234 check(TOKsemicolon, "for condition"); 2377 2235 } 2378 2236 if (token.value == TOKrparen) { 2379 increment = null;2380 2237 nextToken(); 2381 2238 } else { 2382 increment =parseExpression();2239 parseExpression(); 2383 2240 check(TOKrparen); 2384 2241 } 2385 sbody =parseStatement(0);2386 s = n ew ForStatement(loc, init, condition, increment, sbody);2242 parseStatement(0); 2243 s = null; 2387 2244 break; 2388 2245 } … … 2390 2247 case TOKforeach: 2391 2248 { 2392 Array *arguments;2393 2394 Statement *d;2395 Statement *sbody;2396 Expression *aggr;2397 2398 2249 nextToken(); 2399 2250 check(TOKlparen); 2400 2251 2401 arguments = new Array;2402 2403 2252 while (1) { 2404 Type *tb;2405 Identifier *ai = null;2406 Type *at;2253 Type tb; 2254 Identifier ai = null; 2255 Type at; 2407 2256 uint inoutt; 2408 Argument *a;2257 Argument a; 2409 2258 2410 2259 inoutt = In; … … 2417 2266 if (!ai) 2418 2267 error("no identifier for declarator"); 2419 a = new Argument(inoutt, at, ai, null);2420 arguments.push(a);2421 2268 if (token.value == TOKcomma) { 2422 2269 nextToken(); … … 2427 2274 check(TOKsemicolon); 2428 2275 2429 aggr =parseExpression();2276 parseExpression(); 2430 2277 check(TOKrparen); 2431 sbody =parseStatement(0);2432 s = n ew ForeachStatement(loc, arguments, aggr, sbody);2278 parseStatement(0); 2279 s = null; 2433 2280 break; 2434 2281 } … … 2436 2283 case TOKif: 2437 2284 { 2438 Expression *condition;2439 Statement *ifbody;2440 Statement *elsebody;2441 2442 2285 nextToken(); 2443 2286 check(TOKlparen); 2444 condition =parseExpression();2287 parseExpression(); 2445 2288 check(TOKrparen); 2446 ifbody =parseStatement(PSscope);2289 parseStatement(PSscope); 2447 2290 if (token.value == TOKelse) { 2448 2291 nextToken(); 2449 elsebody = parseStatement(PSscope); 2450 } else 2451 elsebody = null; 2452 s = new IfStatement(loc, condition, ifbody, elsebody); 2292 parseStatement(PSscope); 2293 } 2294 s = null; 2453 2295 break; 2454 2296 } … … 2456 2298 case TOKdebug: 2457 2299 { 2458 Condition *condition;2459 Statement *ifbody;2460 Statement *elsebody;2461 2462 2300 nextToken(); 2463 2301 if (token.value == TOKlparen) { 2464 2302 nextToken(); 2465 condition =parseDebugCondition();2303 parseDebugCondition(); 2466 2304 check(TOKrparen); 2467 } else 2468 condition = new DebugCondition(mod, 1, null); 2469 ifbody = parseStatement(PSsemi); 2305 } 2306 parseStatement(PSsemi); 2470 2307 if (token.value == TOKelse) { 2471 2308 nextToken(); 2472 elsebody = parseStatement(PSsemi); 2473 } else 2474 elsebody = null; 2475 s = new ConditionalStatement(loc, condition, ifbody, elsebody); 2309 parseStatement(PSsemi); 2310 } 2311 s = null; 2476 2312 break; 2477 2313 } … … 2479 2315 case TOKversion: 2480 2316 { 2481 Condition *condition;2482 Statement *ifbody;2483 Statement *elsebody;2484 2317 /+ Condition condition; 2318 Statement ifbody; 2319 Statement elsebody; 2320 +/ 2485 2321 nextToken(); 2486 2322 if (token.value == TOKlparen) { 2487 2323 nextToken(); 2488 condition =parseVersionCondition();2324 /+condition = +/parseVersionCondition(); 2489 2325 check(TOKrparen); 2490 2326 } else { 2491 2327 error("(condition) expected after version"); 2492 condition = null;2493 } 2494 ifbody =parseStatement(PSsemi);2328 /+condition = null;+/ 2329 } 2330 /+ifbody = +/parseStatement(PSsemi); 2495 2331 if (token.value == TOKelse) { 2496 2332 nextToken(); 2497 elsebody = parseStatement(PSsemi); 2498 } else 2499 elsebody = null; 2500 s = new ConditionalStatement(loc, condition, ifbody, elsebody); 2333 /+elsebody = +/parseStatement(PSsemi); 2334 }/+ else 2335 elsebody = null;+/ 2336 /+s = new ConditionalStatement(loc, condition, ifbody, elsebody);+/ 2337 s = null; 2501 2338 break; 2502 2339 } … … 2504 2341 case TOKpragma: 2505 2342 { 2506 Identifier *ident;2507 Array *args = null;2508 Statement *sbody;2509 2510 2343 nextToken(); 2511 2344 check(TOKlparen); … … 2514 2347 goto Lerror; 2515 2348 } 2516 ident = token.ident;2517 2349 nextToken(); 2518 2350 if (token.value == TOKcomma) 2519 args =parseArguments(); // pragma(identifier, args...);2351 parseArguments(); // pragma(identifier, args...); 2520 2352 else 2521 2353 check(TOKrparen); // pragma(identifier); 2522 sbody =parseStatement(PSsemi);2523 s = n ew PragmaStatement(loc, ident, args, sbody);2354 parseStatement(PSsemi); 2355 s = null; 2524 2356 break; 2525 2357 } … … 2527 2359 case TOKswitch: 2528 2360 { 2529 Expression *condition;2530 Statement *sbody;2531 2361 2532 2362 nextToken(); 2533 2363 check(TOKlparen); 2534 condition =parseExpression();2364 parseExpression(); 2535 2365 check(TOKrparen); 2536 sbody =parseStatement(PSscope);2537 s = n ew SwitchStatement(loc, condition, sbody);2366 parseStatement(PSscope); 2367 s = null; 2538 2368 break; 2539 2369 } … … 2541 2371 case TOKcase: 2542 2372 { 2543 Expression *exp; 2544 Array *statements; 2545 Array cases; // array of Expression's 2373 Expression exp; 2374 Array statements; 2546 2375 2547 2376 while (1) { 2548 2377 nextToken(); 2549 2378 exp = parseAssignExp(); 2550 cases.push(exp);2551 2379 if (token.value != TOKcomma) 2552 2380 break; … … 2554 2382 check(TOKcolon); 2555 2383 2556 statements = new Array;2557 2384 while (token.value != TOKcase && token.value != TOKdefault && token.value != TOKrcurly) { 2558 statements.push(parseStatement(PSsemi | PScurlyscope)); 2559 } 2560 s = new CompoundStatement(loc, statements); 2561 s = new ScopeStatement(loc, s); 2562 2563 // Keep cases in order by building the case statements backwards 2564 for (int i = cases.dim; i; i--) { 2565 exp = cast(Expression *) cases.data[i - 1]; 2566 s = new CaseStatement(loc, exp, s); 2567 } 2385 parseStatement(PSsemi | PScurlyscope); 2386 } 2387 s = null; 2568 2388 break; 2569 2389 } … … 2571 2391 case TOKdefault: 2572 2392 { 2573 Array *statements;2393 Array statements; 2574 2394 2575 2395 nextToken(); 2576 2396 check(TOKcolon); 2577 2397 2578 statements = new Array;2579 2398 while (token.value != TOKcase && token.value != TOKdefault && token.value != TOKrcurly) { 2580 statements.push(parseStatement(PSsemi | PScurlyscope)); 2581 } 2582 s = new CompoundStatement(loc, statements); 2583 s = new ScopeStatement(loc, s); 2584 s = new DefaultStatement(loc, s); 2399 parseStatement(PSsemi | PScurlyscope); 2400 } 2401 s = null; 2585 2402 break; 2586 2403 } … … 2588 2405 case TOKreturn: 2589 2406 { 2590 Expression *exp;2407 Expression exp; 2591 2408 2592 2409 nextToken(); … … 2596 2413 exp = parseExpression(); 2597 2414 check(TOKsemicolon, "return statement"); 2598 s = n ew ReturnStatement(loc, exp);2415 s = null; 2599 2416 break; 2600 2417 } … … 2602 2419 case TOKbreak: 2603 2420 { 2604 Identifier *ident;2421 Identifier ident; 2605 2422 2606 2423 nextToken(); … … 2611 2428 ident = null; 2612 2429 check(TOKsemicolon, "break statement"); 2613 s = n ew BreakStatement(loc, ident);2430 s = null; 2614 2431 break; 2615 2432 } … … 2617 2434 case TOKcontinue: 2618 2435 { 2619 Identifier *ident;2436 Identifier ident; 2620 2437 2621 2438 nextToken(); … … 2626 2443 ident = null; 2627 2444 check(TOKsemicolon, "continue statement"); 2628 s = n ew ContinueStatement(loc, ident);2445 s = null; 2629 2446 break; 2630 2447 } … … 2632 2449 case TOKgoto: 2633 2450 { 2634 Identifier *ident;2451 Identifier ident; 2635 2452 2636 2453 nextToken(); 2637 2454 if (token.value == TOKdefault) { 2638 2455 nextToken(); 2639 s = n ew GotoDefaultStatement(loc);2456 s = null; 2640 2457 } else if (token.value == TOKcase) { 2641 2458 Expression *exp = null; … … 2643 2460 nextToken(); 2644 2461 if (token.value != TOKsemicolon) 2645 exp =parseExpression();2646 s = n ew GotoCaseStatement(loc, exp);2462 parseExpression(); 2463 s = null; 2647 2464 } else { 2648 2465 if (token.value != TOKidentifier) { 2649 2466 error("Identifier expected following goto"); 2650 ident = null;2651 2467 } else { 2652 ident = token.ident;2653 2468 nextToken(); 2654 2469 } 2655 s = n ew GotoStatement(loc, ident);2470 s = null; 2656 2471 } 2657 2472 check(TOKsemicolon, "goto statement"); … … 2661 2476 case TOKsynchronized: 2662 2477 { 2663 Expression *exp;2664 Statement *sbody;2478 Expression exp; 2479 Statement sbody; 2665 2480 2666 2481 nextToken(); 2667 2482 if (token.value == TOKlparen) { 2668 2483 nextToken(); 2669 exp =parseExpression();2484 parseExpression(); 2670 2485 check(TOKrparen); 2671 2486 } else 2672 2487 exp = null; 2673 sbody =parseStatement(PSscope);2674 s = n ew SynchronizedStatement(loc, exp, sbody);2488 parseStatement(PSscope); 2489 s = null; 2675 2490 break; 2676 2491 } … … 2678 2493 case TOKwith: 2679 2494 { 2680 Expression *exp;2681 Statement *sbody;2682 2683 2495 nextToken(); 2684 2496 check(TOKlparen); 2685 exp =parseExpression();2497 parseExpression(); 2686 2498 check(TOKrparen); 2687 sbody =parseStatement(PSscope);2688 s = n ew WithStatement(loc, exp, sbody);2499 parseStatement(PSscope); 2500 s = null; 2689 2501 break; 2690 2502 } … … 2692 2504 case TOKtry: 2693 2505 { 2694 Statement *sbody; 2695 Array *catches = null; 2696 Statement *finalbody = null; 2697 2698 nextToken(); 2699 sbody = parseStatement(PSscope); 2506 2507 nextToken(); 2508 parseStatement(PSscope); 2700 2509 while (token.value == TOKcatch) { 2701 Statement *handler; 2702 Catch *c; 2703 Type *t; 2704 Identifier *id; 2510 Statement handler; 2511 Type t; 2512 Identifier id; 2705 2513 2706 2514 nextToken(); … … 2715 2523 check(TOKrparen); 2716 2524 } 2717 handler = parseStatement(0); 2718 c = new Catch(loc, t, id, handler); 2719 if (!catches) 2720 catches = new Array; 2721 catches.push(c); 2525 parseStatement(0); 2722 2526 } 2723 2527 2724 2528 if (token.value == TOKfinally) { 2725 2529 nextToken(); 2726 finalbody = parseStatement(0); 2727 } 2728 2729 s = sbody; 2730 if (!catches && !finalbody) 2731 error("catch or finally expected following try"); 2732 else { 2733 if (catches) 2734 s = new TryCatchStatement(loc, sbody, catches); 2735 if (finalbody) 2736 s = new TryFinallyStatement(loc, s, finalbody); 2530 parseStatement(0); 2737 2531 } 2738 2532 break; … … 2741 2535 case TOKthrow: 2742 2536 { 2743 Expression *exp; 2744 2745 nextToken(); 2746 exp = parseExpression(); 2537 nextToken(); 2538 parseExpression(); 2747 2539 check(TOKsemicolon, "throw statement"); 2748 s = n ew ThrowStatement(loc, exp);2540 s = null; 2749 2541 break; 2750 2542 } … … 2752 2544 case TOKvolatile: 2753 2545 nextToken(); 2754 s =parseStatement(PSsemi | PSscope);2755 s = n ew VolatileStatement(loc, s);2546 parseStatement(PSsemi | PSscope); 2547 s = null; 2756 2548 break; 2757 2549 2758 2550 case TOKasm: 2759 2551 { 2760 Array *statements;2761 Identifier *label;2762 Loc labelloc;2763 Token *toklist;2764 Token **ptoklist;2765 2766 2552 // Parse the asm block into a sequence of AsmStatements, 2767 2553 // each AsmStatement is one instruction. … … 2771 2557 nextToken(); 2772 2558 check(TOKlcurly); 2773 toklist = null;2774 ptoklist = &toklist;2775 label = null;2776 statements = new Array;2777 2559 while (1) { 2778 2560 switch (token.value) { 2779 2561 case TOKidentifier: 2780 if (!toklist) { 2781 // Look ahead to see if it is a label 2782 t = peek(&token); 2783 if (t.value == TOKcolon) { // It's a label 2784 label = token.ident; 2785 labelloc = this.loc; 2786 nextToken(); 2787 nextToken(); 2788 continue; 2789 } 2562 // Look ahead to see if it is a label 2563 t = peek(token); 2564 if (t.value == TOKcolon) { // It's a label 2565 nextToken(); 2566 nextToken(); 2567 continue; 2790 2568 } 2791 2569 goto Ldefault; 2792 2570 2793 2571 case TOKrcurly: 2794 if (toklist || label) {2795 error("asm statements must end in ';'");2796 }2797 2572 break; 2798 2573 2799 2574 case TOKsemicolon: 2800 2575 s = null; 2801 if (toklist || label) { // Create AsmStatement from list of tokens we've saved2802 s = new AsmStatement(this.loc, toklist);2803 toklist = null;2804 ptoklist = &toklist;2805 if (label) {2806 s = new LabelStatement(labelloc, label, s);2807 label = null;2808 }2809 statements.push(s);2810 }2811 2576 nextToken(); 2812 2577 continue; … … 2818 2583 default: 2819 2584 Ldefault: 2820 *ptoklist = new Token();2821 memcpy(*ptoklist, &token, sizeof(Token));2822 ptoklist = &(*ptoklist).next;2823 *ptoklist = null;2824 2825 2585 nextToken(); 2826 2586 continue; … … 2828 2588 break; 2829 2589 } 2830 s = n ew CompoundStatement(loc, statements);2590 s = null; 2831 2591 nextToken(); 2832 2592 break; … … 2846 2606 } 2847 2607 2608 /************************************ 2609 * Determine if the scanner is sitting on the start of a declaration. 2610 * Input: 2611 * needId 0 no identifier 2612 * 1 identifier optional 2613 * 2 must have identifier 2614 */ 2615 2616 bool isDeclaration(Token t, int needId, uint endtok, Token *pt) { 2617 bool haveId = 0; 2618 2619 if (!isBasicType(&t)) 2620 return false; 2621 if (!isDeclarator(&t, haveId, endtok)) 2622 return false; 2623 if ( needId == 1 || 2624 (needId == 0 && !haveId) || 2625 (needId == 2 && haveId)) 2626 { if (pt) 2627 *pt = t; 2628 return true; 2629 } 2630 else 2631 return false; 2632 } 2633 2634 int isBasicType(Token *pt) 2635 { 2636 // This code parallels parseBasicType() 2637 Token t = *pt; 2638 Token t2; 2639 int parens; 2640 2641 switch (t.value) { 2642 case TOKwchar: case TOKdchar: 2643 case TOKbit: case TOKchar: 2644 case TOKint8: case TOKuns8: 2645 case TOKint16: case TOKuns16: 2646 case TOKint32: case TOKuns32: 2647 case TOKint64: case TOKuns64: 2648 case TOKfloat32: case TOKfloat64: case TOKfloat80: 2649 case TOKimaginary32: case TOKimaginary64: case TOKimaginary80: 2650 case TOKcomplex32: case TOKcomplex64: case TOKcomplex80: 2651 case TOKvoid: 2652 t = peek(t); 2653 break; 2654 2655 case TOKidentifier: 2656 t = peek(t); 2657 if (t.value == TOKnot) 2658 { 2659 goto L4; 2660 } 2661 goto L3; 2662 while (1) 2663 { 2664 L2: 2665 t = peek(t); 2666 L3: 2667 if (t.value == TOKdot) 2668 { 2669 Ldot: 2670 &nbs
