Mercurial > projects > ddmd
comparison dmd/Parser.d @ 130:60bb0fe4563e
dmdfe 2.037 first main iteration
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Thu, 09 Sep 2010 22:51:44 +0100 |
parents | e6e542f37b94 |
children | 206db751bd4c |
comparison
equal
deleted
inserted
replaced
129:010eb8f0e18d | 130:60bb0fe4563e |
---|---|
136 import dmd.ForeachStatement; | 136 import dmd.ForeachStatement; |
137 import dmd.CompileStatement; | 137 import dmd.CompileStatement; |
138 import dmd.CompoundStatement; | 138 import dmd.CompoundStatement; |
139 import dmd.ConditionalStatement; | 139 import dmd.ConditionalStatement; |
140 import dmd.CompoundDeclarationStatement; | 140 import dmd.CompoundDeclarationStatement; |
141 import dmd.Argument; | 141 import dmd.Parameter; |
142 import dmd.ParseStatementFlags; | 142 import dmd.ParseStatementFlags; |
143 import dmd.TypeNewArray; | 143 import dmd.TypeNewArray; |
144 import dmd.TypeNext; | 144 import dmd.TypeNext; |
145 import dmd.TypeInstance; | 145 import dmd.TypeInstance; |
146 import dmd.TypePointer; | 146 import dmd.TypePointer; |
233 { | 233 { |
234 string comment = token.blockComment; | 234 string comment = token.blockComment; |
235 bool safe = false; | 235 bool safe = false; |
236 | 236 |
237 nextToken(); | 237 nextToken(); |
238 static if(false) { | |
238 version (DMDV2) { | 239 version (DMDV2) { |
239 if (token.value == TOK.TOKlparen) | 240 if (token.value == TOK.TOKlparen) |
240 { | 241 { |
241 nextToken(); | 242 nextToken(); |
242 if (token.value != TOK.TOKidentifier) | 243 if (token.value != TOK.TOKidentifier) |
251 else | 252 else |
252 error("(safe) expected, not %s", id.toChars()); | 253 error("(safe) expected, not %s", id.toChars()); |
253 nextToken(); | 254 nextToken(); |
254 check(TOK.TOKrparen); | 255 check(TOK.TOKrparen); |
255 } | 256 } |
257 } | |
256 } | 258 } |
257 | 259 |
258 if (token.value != TOK.TOKidentifier) | 260 if (token.value != TOK.TOKidentifier) |
259 { | 261 { |
260 error("Identifier expected following module"); | 262 error("Identifier expected following module"); |
505 case TOK.TOKref: stc = STC.STCref; goto Lstc; | 507 case TOK.TOKref: stc = STC.STCref; goto Lstc; |
506 case TOK.TOKtls: stc = STC.STCtls; goto Lstc; | 508 case TOK.TOKtls: stc = STC.STCtls; goto Lstc; |
507 case TOK.TOKgshared: | 509 case TOK.TOKgshared: |
508 stc = STC.STCgshared; goto Lstc; | 510 stc = STC.STCgshared; goto Lstc; |
509 //case TOK.TOKmanifest: stc = STC.STCmanifest; goto Lstc; | 511 //case TOK.TOKmanifest: stc = STC.STCmanifest; goto Lstc; |
512 case TOK.TOKat: stc = parseAttribute(); goto Lstc; | |
510 } | 513 } |
511 | 514 |
512 Lstc: | 515 Lstc: |
513 if (storageClass & stc) | 516 if (storageClass & stc) |
514 error("redundant storage class %s", Token.toChars(token.value)); | 517 error("redundant storage class %s", Token.toChars(token.value)); |
543 case TOK.TOKpure: stc = STC.STCpure; goto Lstc; | 546 case TOK.TOKpure: stc = STC.STCpure; goto Lstc; |
544 case TOK.TOKref: stc = STC.STCref; goto Lstc; | 547 case TOK.TOKref: stc = STC.STCref; goto Lstc; |
545 case TOK.TOKtls: stc = STC.STCtls; goto Lstc; | 548 case TOK.TOKtls: stc = STC.STCtls; goto Lstc; |
546 case TOK.TOKgshared: stc = STC.STCgshared; goto Lstc; | 549 case TOK.TOKgshared: stc = STC.STCgshared; goto Lstc; |
547 //case TOK.TOKmanifest: stc = STC.STCmanifest; goto Lstc; | 550 //case TOK.TOKmanifest: stc = STC.STCmanifest; goto Lstc; |
551 case TOK.TOKat: stc = parseAttribute(); goto Lstc; | |
548 default: | 552 default: |
549 break; | 553 break; |
550 } | 554 } |
551 | 555 |
552 /* Look for auto initializers: | 556 /* Look for auto initializers: |
833 a = parseDeclDefs(1); | 837 a = parseDeclDefs(1); |
834 break; | 838 break; |
835 } | 839 } |
836 return a; | 840 return a; |
837 } | 841 } |
838 | 842 version(DMDV2) { |
839 void composeStorageClass(STC stc) | 843 void composeStorageClass(STC stc) |
840 { | 844 { |
841 STC u = stc; | 845 STC u = stc; |
842 u &= STC.STCconst | STC.STCimmutable | STC.STCmanifest; | 846 u &= STC.STCconst | STC.STCimmutable | STC.STCmanifest; |
843 if (u & (u - 1)) | 847 if (u & (u - 1)) |
845 | 849 |
846 u = stc; | 850 u = stc; |
847 u &= STC.STCgshared | STC.STCshared | STC.STCtls; | 851 u &= STC.STCgshared | STC.STCshared | STC.STCtls; |
848 if (u & (u - 1)) | 852 if (u & (u - 1)) |
849 error("conflicting storage class %s", Token.toChars(token.value)); | 853 error("conflicting storage class %s", Token.toChars(token.value)); |
850 } | 854 u = stc; |
851 | 855 u &= STCsafe | STCsystem | STCtrusted; |
856 if (u & (u - 1)) | |
857 error("conflicting attribute @%s", token.toChars()); | |
858 } | |
859 } | |
860 | |
861 /*********************************************** | |
862 * Parse storage class, lexer is on '@' | |
863 */ | |
864 | |
865 version(DMDV2) { | |
866 STC parseAttribute() | |
867 { | |
868 nextToken(); | |
869 STC stc = STCundefined; | |
870 if (token.value != TOKidentifier) | |
871 { | |
872 error("identifier expected after @, not %s", token.toChars()); | |
873 } | |
874 else if (token.ident == Id.property) | |
875 stc = STCproperty; | |
876 else if (token.ident == Id.safe) | |
877 stc = STCsafe; | |
878 else if (token.ident == Id.trusted) | |
879 stc = STCtrusted; | |
880 else if (token.ident == Id.system) | |
881 stc = STCsystem; | |
882 else | |
883 error("valid attribute identifiers are @property, @safe, @trusted, @system, not @%s", token.toChars()); | |
884 return stc; | |
885 } | |
886 } | |
852 /************************************** | 887 /************************************** |
853 * Parse constraint. | 888 * Parse constraint. |
854 * Constraint is of the form: | 889 * Constraint is of the form: |
855 * if ( ConstraintExpression ) | 890 * if ( ConstraintExpression ) |
856 */ | 891 */ |
1573 if (token.value == TOK.TOKlparen && peek(&token).value == TOK.TOKthis) | 1608 if (token.value == TOK.TOKlparen && peek(&token).value == TOK.TOKthis) |
1574 { // this(this) { ... } | 1609 { // this(this) { ... } |
1575 nextToken(); | 1610 nextToken(); |
1576 nextToken(); | 1611 nextToken(); |
1577 check(TOK.TOKrparen); | 1612 check(TOK.TOKrparen); |
1578 PostBlitDeclaration f = new PostBlitDeclaration(loc, Loc(0)); | 1613 auto f = new PostBlitDeclaration(loc, Loc(0)); |
1579 parseContracts(f); | 1614 parseContracts(f); |
1580 return f; | 1615 return f; |
1581 } | 1616 } |
1582 | 1617 |
1583 /* Look ahead to see if: | 1618 /* Look ahead to see if: |
1587 TemplateParameters tpl = null; | 1622 TemplateParameters tpl = null; |
1588 if (token.value == TOK.TOKlparen && peekPastParen(&token).value == TOK.TOKlparen) | 1623 if (token.value == TOK.TOKlparen && peekPastParen(&token).value == TOK.TOKlparen) |
1589 { tpl = parseTemplateParameterList(); | 1624 { tpl = parseTemplateParameterList(); |
1590 | 1625 |
1591 int varargs; | 1626 int varargs; |
1592 Arguments arguments = parseParameters(&varargs); | 1627 auto arguments = parseParameters(&varargs); |
1593 | 1628 |
1594 Expression constraint = null; | 1629 Expression constraint = null; |
1595 if (tpl) | 1630 if (tpl) |
1596 constraint = parseConstraint(); | 1631 constraint = parseConstraint(); |
1597 | 1632 |
1606 } | 1641 } |
1607 | 1642 |
1608 /* Just a regular constructor | 1643 /* Just a regular constructor |
1609 */ | 1644 */ |
1610 int varargs; | 1645 int varargs; |
1611 Arguments arguments = parseParameters(&varargs); | 1646 auto arguments = parseParameters(&varargs); |
1612 CtorDeclaration f = new CtorDeclaration(loc, Loc(0), arguments, varargs); | 1647 CtorDeclaration f = new CtorDeclaration(loc, Loc(0), arguments, varargs); |
1613 parseContracts(f); | 1648 parseContracts(f); |
1614 return f; | 1649 return f; |
1615 } | 1650 } |
1616 | 1651 |
1723 * Current token is 'new'. | 1758 * Current token is 'new'. |
1724 */ | 1759 */ |
1725 NewDeclaration parseNew() | 1760 NewDeclaration parseNew() |
1726 { | 1761 { |
1727 NewDeclaration f; | 1762 NewDeclaration f; |
1728 scope Arguments arguments = new Arguments(); | 1763 scope arguments = new Parameters(); |
1729 int varargs; | 1764 int varargs; |
1730 Loc loc = this.loc; | 1765 Loc loc = this.loc; |
1731 | 1766 |
1732 nextToken(); | 1767 nextToken(); |
1733 arguments = parseParameters(&varargs); | 1768 arguments = parseParameters(&varargs); |
1742 * Current token is 'delete'. | 1777 * Current token is 'delete'. |
1743 */ | 1778 */ |
1744 DeleteDeclaration parseDelete() | 1779 DeleteDeclaration parseDelete() |
1745 { | 1780 { |
1746 DeleteDeclaration f; | 1781 DeleteDeclaration f; |
1747 scope Arguments arguments; | 1782 scope Parameters arguments; |
1748 int varargs; | 1783 int varargs; |
1749 Loc loc = this.loc; | 1784 Loc loc = this.loc; |
1750 | 1785 |
1751 nextToken(); | 1786 nextToken(); |
1752 arguments = parseParameters(&varargs); | 1787 arguments = parseParameters(&varargs); |
1755 f = new DeleteDeclaration(loc, Loc(0), arguments); | 1790 f = new DeleteDeclaration(loc, Loc(0), arguments); |
1756 parseContracts(f); | 1791 parseContracts(f); |
1757 return f; | 1792 return f; |
1758 } | 1793 } |
1759 | 1794 |
1760 Arguments parseParameters(int* pvarargs) | 1795 Parameters parseParameters(int* pvarargs) |
1761 { | 1796 { |
1762 Arguments arguments = new Arguments(); | 1797 auto arguments = new Parameters(); |
1763 int varargs = 0; | 1798 int varargs = 0; |
1764 int hasdefault = 0; | 1799 int hasdefault = 0; |
1765 | 1800 |
1766 check(TOK.TOKlparen); | 1801 check(TOK.TOKlparen); |
1767 while (1) | 1802 while (1) |
1768 { Type *tb; | 1803 { Type *tb; |
1769 Identifier ai = null; | 1804 Identifier ai = null; |
1770 Type at; | 1805 Type at; |
1771 Argument a; | 1806 Parameter a; |
1772 STC storageClass = STC.STCundefined; | 1807 STC storageClass = STC.STCundefined; |
1773 STC stc; | 1808 STC stc; |
1774 Expression ae; | 1809 Expression ae; |
1775 | 1810 |
1776 for ( ;1; nextToken()) | 1811 for ( ;1; nextToken()) |
1878 */ | 1913 */ |
1879 | 1914 |
1880 if (storageClass & (STC.STCout | STC.STCref)) | 1915 if (storageClass & (STC.STCout | STC.STCref)) |
1881 error("variadic argument cannot be out or ref"); | 1916 error("variadic argument cannot be out or ref"); |
1882 varargs = 2; | 1917 varargs = 2; |
1883 a = new Argument(storageClass, at, ai, ae); | 1918 a = new Parameter(storageClass, at, ai, ae); |
1884 arguments.push(a); | 1919 arguments.push(a); |
1885 nextToken(); | 1920 nextToken(); |
1886 break; | 1921 break; |
1887 } | 1922 } |
1888 L3: | 1923 L3: |
1889 a = new Argument(storageClass, at, ai, ae); | 1924 a = new Parameter(storageClass, at, ai, ae); |
1890 arguments.push(a); | 1925 arguments.push(a); |
1891 if (token.value == TOK.TOKcomma) | 1926 if (token.value == TOK.TOKcomma) |
1892 { nextToken(); | 1927 { nextToken(); |
1893 goto L1; | 1928 goto L1; |
1894 } | 1929 } |
2484 } | 2519 } |
2485 else | 2520 else |
2486 { | 2521 { |
2487 //printf("it's type[expression]\n"); | 2522 //printf("it's type[expression]\n"); |
2488 inBrackets++; | 2523 inBrackets++; |
2489 Expression e = parseExpression(); // [ expression ] | 2524 Expression e = parseAssignExp(); // [ expression ] |
2490 if (token.value == TOK.TOKslice) | 2525 if (token.value == TOK.TOKslice) |
2491 { | 2526 { |
2492 nextToken(); | 2527 nextToken(); |
2493 Expression e2 = parseExpression(); // [ exp .. exp ] | 2528 Expression e2 = parseAssignExp(); // [ exp .. exp ] |
2494 t = new TypeSlice(t, e, e2); | 2529 t = new TypeSlice(t, e, e2); |
2495 } | 2530 } |
2496 else | 2531 else |
2497 t = new TypeSArray(t,e); | 2532 t = new TypeSArray(t,e); |
2498 inBrackets--; | 2533 inBrackets--; |
2503 case TOK.TOKdelegate: | 2538 case TOK.TOKdelegate: |
2504 case TOK.TOKfunction: | 2539 case TOK.TOKfunction: |
2505 { // Handle delegate declaration: | 2540 { // Handle delegate declaration: |
2506 // t delegate(parameter list) nothrow pure | 2541 // t delegate(parameter list) nothrow pure |
2507 // t function(parameter list) nothrow pure | 2542 // t function(parameter list) nothrow pure |
2508 Arguments arguments; | 2543 Parameters arguments; |
2509 int varargs; | 2544 int varargs; |
2510 bool ispure = false; | 2545 bool ispure = false; |
2511 bool isnothrow = false; | 2546 bool isnothrow = false; |
2547 bool isproperty = false; | |
2512 TOK save = token.value; | 2548 TOK save = token.value; |
2549 TRUST trust = TRUSTdefault; | |
2513 | 2550 |
2514 nextToken(); | 2551 nextToken(); |
2515 arguments = parseParameters(&varargs); | 2552 arguments = parseParameters(&varargs); |
2516 while (1) | 2553 while (1) |
2517 { // Postfixes | 2554 { // Postfixes |
2518 if (token.value == TOK.TOKpure) | 2555 if (token.value == TOK.TOKpure) |
2519 ispure = true; | 2556 ispure = true; |
2520 else if (token.value == TOK.TOKnothrow) | 2557 else if (token.value == TOK.TOKnothrow) |
2521 isnothrow = true; | 2558 isnothrow = true; |
2559 else if (token.value == TOKat) | |
2560 { STC stc = parseAttribute(); | |
2561 switch (cast(uint)(stc >> 32)) | |
2562 { case STCproperty >> 32: | |
2563 isproperty = true; | |
2564 break; | |
2565 case STCsafe >> 32: | |
2566 trust = TRUSTsafe; | |
2567 break; | |
2568 case STCsystem >> 32: | |
2569 trust = TRUSTsystem; | |
2570 break; | |
2571 case STCtrusted >> 32: | |
2572 trust = TRUSTtrusted; | |
2573 break; | |
2574 case 0: | |
2575 break; | |
2576 default: | |
2577 assert(0); | |
2578 } | |
2579 } | |
2522 else | 2580 else |
2523 break; | 2581 break; |
2524 nextToken(); | 2582 nextToken(); |
2525 } | 2583 } |
2526 TypeFunction tf = new TypeFunction(arguments, t, varargs, linkage); | 2584 TypeFunction tf = new TypeFunction(arguments, t, varargs, linkage); |
2527 tf.ispure = ispure; | 2585 tf.ispure = ispure; |
2528 tf.isnothrow = isnothrow; | 2586 tf.isnothrow = isnothrow; |
2587 tf.isproperty = isproperty; | |
2588 tf.trust = trust; | |
2529 if (save == TOK.TOKdelegate) | 2589 if (save == TOK.TOKdelegate) |
2530 t = new TypeDelegate(tf); | 2590 t = new TypeDelegate(tf); |
2531 else | 2591 else |
2532 t = new TypePointer(tf); // pointer to function | 2592 t = new TypePointer(tf); // pointer to function |
2533 continue; | 2593 continue; |
2612 ta = new TypeAArray(t, index); | 2672 ta = new TypeAArray(t, index); |
2613 } | 2673 } |
2614 else | 2674 else |
2615 { | 2675 { |
2616 //printf("It's a static array\n"); | 2676 //printf("It's a static array\n"); |
2617 Expression e = parseExpression(); // [ expression ] | 2677 Expression e = parseAssignExp(); // [ expression ] |
2618 ta = new TypeSArray(t, e); | 2678 ta = new TypeSArray(t, e); |
2619 check(TOK.TOKrbracket); | 2679 check(TOK.TOKrbracket); |
2620 } | 2680 } |
2621 | 2681 |
2622 /* Insert ta into | 2682 /* Insert ta into |
2647 *tpl = parseTemplateParameterList(); | 2707 *tpl = parseTemplateParameterList(); |
2648 } | 2708 } |
2649 } | 2709 } |
2650 | 2710 |
2651 int varargs; | 2711 int varargs; |
2652 Arguments arguments = parseParameters(&varargs); | 2712 auto arguments = parseParameters(&varargs); |
2653 Type tf = new TypeFunction(arguments, t, varargs, linkage); | 2713 Type tf = new TypeFunction(arguments, t, varargs, linkage); |
2654 | 2714 |
2655 /* Parse const/invariant/nothrow/pure postfix | 2715 /* Parse const/invariant/nothrow/pure postfix |
2656 */ | 2716 */ |
2657 while (1) | 2717 while (1) |
2689 (cast(TypeFunction)tf).ispure = 1; | 2749 (cast(TypeFunction)tf).ispure = 1; |
2690 nextToken(); | 2750 nextToken(); |
2691 continue; | 2751 continue; |
2692 | 2752 |
2693 case TOK.TOKat: | 2753 case TOK.TOKat: |
2694 nextToken(); | 2754 { |
2695 if (token.value != TOK.TOKidentifier) | 2755 STC stc = parseAttribute(); |
2696 { error("attribute identifier expected"); | 2756 auto tfunc = cast(TypeFunction)tf; |
2697 nextToken(); | 2757 switch (cast(uint)(stc >> 32)) |
2698 continue; | 2758 { |
2699 } | 2759 case STCproperty >> 32: |
2700 Identifier id = token.ident; | 2760 tfunc.isproperty = 1; |
2701 if (id is Id.property) | 2761 break; |
2702 (cast(TypeFunction)tf).isproperty = 1; | 2762 case STCsafe >> 32: |
2703 else | 2763 tfunc.trust = TRUSTsafe; |
2704 error("valid attribute identifiers are @property, not @%s", id.toChars()); | 2764 break; |
2705 nextToken(); | 2765 case STCsystem >> 32: |
2706 continue; | 2766 tfunc.trust = TRUSTsystem; |
2767 break; | |
2768 case STCtrusted >> 32: | |
2769 tfunc.trust = TRUSTtrusted; | |
2770 break; | |
2771 case 0: | |
2772 break; | |
2773 default: | |
2774 assert(0); | |
2775 } | |
2776 nextToken(); | |
2777 continue; | |
2778 } | |
2707 default: | 2779 default: |
2708 break; /// | 2780 break; /// |
2709 } | 2781 } |
2710 break; | 2782 break; |
2711 } | 2783 } |
2815 case TOK.TOKpure: stc = STC.STCpure; goto L1; | 2887 case TOK.TOKpure: stc = STC.STCpure; goto L1; |
2816 case TOK.TOKref: stc = STC.STCref; goto L1; | 2888 case TOK.TOKref: stc = STC.STCref; goto L1; |
2817 case TOK.TOKtls: stc = STC.STCtls; goto L1; | 2889 case TOK.TOKtls: stc = STC.STCtls; goto L1; |
2818 case TOK.TOKgshared: stc = STC.STCgshared; goto L1; | 2890 case TOK.TOKgshared: stc = STC.STCgshared; goto L1; |
2819 case TOK.TOKenum: stc = STC.STCmanifest; goto L1; | 2891 case TOK.TOKenum: stc = STC.STCmanifest; goto L1; |
2892 case TOK.TOKat: stc = parseAttribute(); goto L1; | |
2820 } | 2893 } |
2821 L1: | 2894 L1: |
2822 if (storage_class & stc) | 2895 if (storage_class & stc) |
2823 error("redundant storage class '%s'", token.toChars()); | 2896 error("redundant storage class '%s'", token.toChars()); |
2824 storage_class = (storage_class | stc); | 2897 storage_class = (storage_class | stc); |
2945 else if (t.ty == TY.Tfunction) | 3018 else if (t.ty == TY.Tfunction) |
2946 { | 3019 { |
2947 auto tf = cast(TypeFunction)t; | 3020 auto tf = cast(TypeFunction)t; |
2948 Expression constraint = null; | 3021 Expression constraint = null; |
2949 static if (false) { | 3022 static if (false) { |
2950 if (Argument.isTPL(tf.parameters)) | 3023 if (Parameter.isTPL(tf.parameters)) |
2951 { | 3024 { |
2952 if (!tpl) | 3025 if (!tpl) |
2953 tpl = new TemplateParameters(); | 3026 tpl = new TemplateParameters(); |
2954 } | 3027 } |
2955 } | 3028 } |
3026 return a; | 3099 return a; |
3027 } | 3100 } |
3028 | 3101 |
3029 void parseContracts(FuncDeclaration f) | 3102 void parseContracts(FuncDeclaration f) |
3030 { | 3103 { |
3031 Type tb; | |
3032 LINK linksave = linkage; | 3104 LINK linksave = linkage; |
3033 | 3105 |
3034 // The following is irrelevant, as it is overridden by sc.linkage in | 3106 // The following is irrelevant, as it is overridden by sc.linkage in |
3035 // TypeFunction.semantic | 3107 // TypeFunction.semantic |
3036 linkage = LINK.LINKd; // nested functions have D linkage | 3108 linkage = LINK.LINKd; // nested functions have D linkage |
3069 f.fthrows = new Array(); | 3141 f.fthrows = new Array(); |
3070 nextToken(); | 3142 nextToken(); |
3071 check(TOK.TOKlparen); | 3143 check(TOK.TOKlparen); |
3072 while (1) | 3144 while (1) |
3073 { | 3145 { |
3074 tb = parseBasicType(); | 3146 Type tb = parseBasicType(); |
3075 f.fthrows.push(tb); | 3147 f.fthrows.push(tb); |
3076 if (token.value == TOK.TOKcomma) | 3148 if (token.value == TOK.TOKcomma) |
3077 { nextToken(); | 3149 { nextToken(); |
3078 continue; | 3150 continue; |
3079 } | 3151 } |
3193 case TOK.TOKtraits: | 3265 case TOK.TOKtraits: |
3194 case TOK.TOKfile: | 3266 case TOK.TOKfile: |
3195 case TOK.TOKline: | 3267 case TOK.TOKline: |
3196 } | 3268 } |
3197 Lexp: | 3269 Lexp: |
3198 { Expression exp; | 3270 { |
3199 | 3271 auto exp = parseExpression(); |
3200 exp = parseExpression(); | |
3201 check(TOK.TOKsemicolon, "statement"); | 3272 check(TOK.TOKsemicolon, "statement"); |
3202 s = new ExpStatement(loc, exp); | 3273 s = new ExpStatement(loc, exp); |
3203 break; | 3274 break; |
3204 } | 3275 } |
3205 | 3276 |
3218 { | 3289 { |
3219 nextToken(); | 3290 nextToken(); |
3220 condition = parseStaticIfCondition(); | 3291 condition = parseStaticIfCondition(); |
3221 goto Lcondition; | 3292 goto Lcondition; |
3222 } | 3293 } |
3294 if (t.value == TOK.TOKstruct || t.value == TOK.TOKunion || t.value == TOK.TOKclass) | |
3295 { | |
3296 nextToken(); | |
3297 auto a = parseBlock(); | |
3298 Dsymbol d = new StorageClassDeclaration(STCstatic, a); | |
3299 s = new DeclarationStatement(loc, d); | |
3300 if (flags & PSscope) | |
3301 s = new ScopeStatement(loc, s); | |
3302 break; | |
3303 } | |
3223 goto Ldeclaration; | 3304 goto Ldeclaration; |
3224 } | 3305 } |
3225 | 3306 |
3226 case TOK.TOKfinal: | 3307 case TOK.TOKfinal: |
3227 if (peekNext() == TOK.TOKswitch) | 3308 if (peekNext() == TOK.TOKswitch) |
3253 case TOK.TOKshared: | 3334 case TOK.TOKshared: |
3254 case TOK.TOKnothrow: | 3335 case TOK.TOKnothrow: |
3255 case TOK.TOKpure: | 3336 case TOK.TOKpure: |
3256 case TOK.TOKtls: | 3337 case TOK.TOKtls: |
3257 case TOK.TOKgshared: | 3338 case TOK.TOKgshared: |
3339 case TOK.TOKat: | |
3258 } | 3340 } |
3259 // case TOK.TOKtypeof: | 3341 // case TOK.TOKtypeof: |
3260 Ldeclaration: | 3342 Ldeclaration: |
3261 { Dsymbols a; | 3343 { Dsymbols a; |
3262 | 3344 |
3428 | 3510 |
3429 case TOK.TOKforeach: | 3511 case TOK.TOKforeach: |
3430 case TOK.TOKforeach_reverse: | 3512 case TOK.TOKforeach_reverse: |
3431 { | 3513 { |
3432 TOK op = token.value; | 3514 TOK op = token.value; |
3433 Arguments arguments; | |
3434 | |
3435 Statement d; | |
3436 Statement body_; | |
3437 Expression aggr; | |
3438 | 3515 |
3439 nextToken(); | 3516 nextToken(); |
3440 check(TOK.TOKlparen); | 3517 check(TOK.TOKlparen); |
3441 | 3518 |
3442 arguments = new Arguments(); | 3519 auto arguments = new Parameters(); |
3443 | 3520 |
3444 while (1) | 3521 while (1) |
3445 { | 3522 { |
3446 Type tb; | |
3447 Identifier ai = null; | 3523 Identifier ai = null; |
3448 Type at; | 3524 Type at; |
3449 STC storageClass = STC.STCundefined; | 3525 STC storageClass = STC.STCundefined; |
3450 Argument a; | |
3451 | 3526 |
3452 if (token.value == TOK.TOKinout || token.value == TOK.TOKref) | 3527 if (token.value == TOK.TOKinout || token.value == TOK.TOKref) |
3453 { storageClass = STC.STCref; | 3528 { storageClass = STC.STCref; |
3454 nextToken(); | 3529 nextToken(); |
3455 } | 3530 } |
3465 } | 3540 } |
3466 at = parseType(&ai); | 3541 at = parseType(&ai); |
3467 if (!ai) | 3542 if (!ai) |
3468 error("no identifier for declarator %s", at.toChars()); | 3543 error("no identifier for declarator %s", at.toChars()); |
3469 Larg: | 3544 Larg: |
3470 a = new Argument(storageClass, at, ai, null); | 3545 auto a = new Parameter(storageClass, at, ai, null); |
3471 arguments.push(a); | 3546 arguments.push(a); |
3472 if (token.value == TOK.TOKcomma) | 3547 if (token.value == TOK.TOKcomma) |
3473 { nextToken(); | 3548 { nextToken(); |
3474 continue; | 3549 continue; |
3475 } | 3550 } |
3476 break; | 3551 break; |
3477 } | 3552 } |
3478 check(TOK.TOKsemicolon); | 3553 check(TOK.TOKsemicolon); |
3479 | 3554 |
3480 aggr = parseExpression(); | 3555 Expression aggr = parseExpression(); |
3481 if (token.value == TOK.TOKslice && arguments.dim == 1) | 3556 if (token.value == TOK.TOKslice && arguments.dim == 1) |
3482 { | 3557 { |
3483 auto a = arguments[0]; | 3558 auto a = arguments[0]; |
3484 delete arguments; | 3559 delete arguments; |
3485 nextToken(); | 3560 nextToken(); |
3486 Expression upr = parseExpression(); | 3561 Expression upr = parseExpression(); |
3487 check(TOK.TOKrparen); | 3562 check(TOK.TOKrparen); |
3488 body_ = parseStatement(cast(ParseStatementFlags)0); | 3563 auto body_ = parseStatement(cast(ParseStatementFlags)0); |
3489 s = new ForeachRangeStatement(loc, op, a, aggr, upr, body_); | 3564 s = new ForeachRangeStatement(loc, op, a, aggr, upr, body_); |
3490 } | 3565 } |
3491 else | 3566 else |
3492 { | 3567 { |
3493 check(TOK.TOKrparen); | 3568 check(TOK.TOKrparen); |
3494 body_ = parseStatement(cast(ParseStatementFlags)0); | 3569 auto body_ = parseStatement(cast(ParseStatementFlags)0); |
3495 s = new ForeachStatement(loc, op, arguments, aggr, body_); | 3570 s = new ForeachStatement(loc, op, arguments, aggr, body_); |
3496 } | 3571 } |
3497 break; | 3572 break; |
3498 } | 3573 } |
3499 | 3574 |
3500 case TOK.TOKif: | 3575 case TOK.TOKif: |
3501 { Argument arg = null; | 3576 { Parameter arg = null; |
3502 Expression condition2; | 3577 Expression condition2; |
3503 Statement ifbody2; | 3578 Statement ifbody2; |
3504 Statement elsebody2; | 3579 Statement elsebody2; |
3505 | 3580 |
3506 nextToken(); | 3581 nextToken(); |
3512 if (token.value == TOK.TOKidentifier) | 3587 if (token.value == TOK.TOKidentifier) |
3513 { | 3588 { |
3514 Token *tt = peek(&token); | 3589 Token *tt = peek(&token); |
3515 if (tt.value == TOK.TOKassign) | 3590 if (tt.value == TOK.TOKassign) |
3516 { | 3591 { |
3517 arg = new Argument(STC.STCundefined, null, token.ident, null); | 3592 arg = new Parameter(STC.STCundefined, null, token.ident, null); |
3518 nextToken(); | 3593 nextToken(); |
3519 nextToken(); | 3594 nextToken(); |
3520 } | 3595 } |
3521 else | 3596 else |
3522 { error("= expected following auto identifier"); | 3597 { error("= expected following auto identifier"); |
3533 Type at; | 3608 Type at; |
3534 Identifier ai; | 3609 Identifier ai; |
3535 | 3610 |
3536 at = parseType(&ai); | 3611 at = parseType(&ai); |
3537 check(TOK.TOKassign); | 3612 check(TOK.TOKassign); |
3538 arg = new Argument(STC.STCundefined, at, ai, null); | 3613 arg = new Parameter(STC.STCundefined, at, ai, null); |
3539 } | 3614 } |
3540 | 3615 |
3541 // Check for " ident;" | 3616 // Check for " ident;" |
3542 else if (token.value == TOK.TOKidentifier) | 3617 else if (token.value == TOK.TOKidentifier) |
3543 { | 3618 { |
3544 Token *tt = peek(&token); | 3619 Token *tt = peek(&token); |
3545 if (tt.value == TOK.TOKcomma || tt.value == TOK.TOKsemicolon) | 3620 if (tt.value == TOK.TOKcomma || tt.value == TOK.TOKsemicolon) |
3546 { | 3621 { |
3547 arg = new Argument(STC.STCundefined, null, token.ident, null); | 3622 arg = new Parameter(STC.STCundefined, null, token.ident, null); |
3548 nextToken(); | 3623 nextToken(); |
3549 nextToken(); | 3624 nextToken(); |
3550 if (1 || !global.params.useDeprecated) | 3625 if (1 || !global.params.useDeprecated) |
3551 error("if (v; e) is deprecated, use if (auto v = e)"); | 3626 error("if (v; e) is deprecated, use if (auto v = e)"); |
3552 } | 3627 } |
5135 e = new TypeExp(loc, t); | 5210 e = new TypeExp(loc, t); |
5136 break; | 5211 break; |
5137 } | 5212 } |
5138 | 5213 |
5139 case TOK.TOKtypeid: | 5214 case TOK.TOKtypeid: |
5140 { Type tt; | 5215 { |
5141 | |
5142 nextToken(); | 5216 nextToken(); |
5143 check(TOK.TOKlparen, "typeid"); | 5217 check(TOK.TOKlparen, "typeid"); |
5144 tt = parseType(); // ( type ) | 5218 Object o; |
5219 if (isDeclaration(&token, 0, TOKreserved, NULL)) | |
5220 { // argument is a type | |
5221 o = parseType(); | |
5222 } | |
5223 else | |
5224 { // argument is an expression | |
5225 o = parseAssignExp(); | |
5226 } | |
5145 check(TOK.TOKrparen); | 5227 check(TOK.TOKrparen); |
5146 e = new TypeidExp(loc, tt); | 5228 e = new TypeidExp(loc, o); |
5147 break; | 5229 break; |
5148 } | 5230 } |
5149 | 5231 |
5150 version (DMDV2) { | 5232 version (DMDV2) { |
5151 case TOK.TOKtraits: | 5233 case TOK.TOKtraits: |
5343 /* function type(parameters) { body } pure nothrow | 5425 /* function type(parameters) { body } pure nothrow |
5344 * delegate type(parameters) { body } pure nothrow | 5426 * delegate type(parameters) { body } pure nothrow |
5345 * (parameters) { body } | 5427 * (parameters) { body } |
5346 * { body } | 5428 * { body } |
5347 */ | 5429 */ |
5348 Arguments arguments; | 5430 Parameters arguments; |
5349 int varargs; | 5431 int varargs; |
5350 FuncLiteralDeclaration fd; | 5432 FuncLiteralDeclaration fd; |
5351 Type tt; | 5433 Type tt; |
5352 bool isnothrow = false; | 5434 bool isnothrow = false; |
5353 bool ispure = false; | 5435 bool ispure = false; |
5354 | 5436 bool isproperty = false; |
5437 TRUST trust = TRUSTdefault; | |
5438 | |
5355 if (token.value == TOK.TOKlcurly) | 5439 if (token.value == TOK.TOKlcurly) |
5356 { | 5440 { |
5357 tt = null; | 5441 tt = null; |
5358 varargs = 0; | 5442 varargs = 0; |
5359 arguments = new Arguments(); | 5443 arguments = new Parameters(); |
5360 } | 5444 } |
5361 else | 5445 else |
5362 { | 5446 { |
5363 if (token.value == TOK.TOKlparen) | 5447 if (token.value == TOK.TOKlparen) |
5364 tt = null; | 5448 tt = null; |
5372 { | 5456 { |
5373 if (token.value == TOK.TOKpure) | 5457 if (token.value == TOK.TOKpure) |
5374 ispure = true; | 5458 ispure = true; |
5375 else if (token.value == TOK.TOKnothrow) | 5459 else if (token.value == TOK.TOKnothrow) |
5376 isnothrow = true; | 5460 isnothrow = true; |
5461 else if (token.value == TOKat) | |
5462 { | |
5463 STC stc = parseAttribute(); | |
5464 switch (cast(uint)(stc >> 32)) | |
5465 { | |
5466 case STCproperty >> 32: | |
5467 isproperty = true; | |
5468 break; | |
5469 case STCsafe >> 32: | |
5470 trust = TRUSTsafe; | |
5471 break; | |
5472 case STCsystem >> 32: | |
5473 trust = TRUSTsystem; | |
5474 break; | |
5475 case STCtrusted >> 32: | |
5476 trust = TRUSTtrusted; | |
5477 break; | |
5478 case 0: | |
5479 break; | |
5480 default: | |
5481 assert(0); | |
5482 } | |
5483 } | |
5377 else | 5484 else |
5378 break; | 5485 break; |
5379 nextToken(); | 5486 nextToken(); |
5380 } | 5487 } |
5381 } | 5488 } |
5382 | 5489 |
5383 TypeFunction tf = new TypeFunction(arguments, tt, varargs, linkage); | 5490 TypeFunction tf = new TypeFunction(arguments, tt, varargs, linkage); |
5384 tf.ispure = ispure; | 5491 tf.ispure = ispure; |
5385 tf.isnothrow = isnothrow; | 5492 tf.isnothrow = isnothrow; |
5493 tf.isproperty = isproperty; | |
5494 tf.trust = trust; | |
5386 fd = new FuncLiteralDeclaration(loc, Loc(0), tf, save, null); | 5495 fd = new FuncLiteralDeclaration(loc, Loc(0), tf, save, null); |
5387 parseContracts(fd); | 5496 parseContracts(fd); |
5388 e = new FuncExp(loc, fd); | 5497 e = new FuncExp(loc, fd); |
5389 break; | 5498 break; |
5390 } | 5499 } |
5642 | 5751 |
5643 nextToken(); | 5752 nextToken(); |
5644 if (token.value == TOK.TOKnot && peekNext() != TOK.TOKis) | 5753 if (token.value == TOK.TOKnot && peekNext() != TOK.TOKis) |
5645 { // identifier!(template-argument-list) | 5754 { // identifier!(template-argument-list) |
5646 TemplateInstance tempinst = new TemplateInstance(loc, id); | 5755 TemplateInstance tempinst = new TemplateInstance(loc, id); |
5756 Objects tiargs; | |
5647 nextToken(); | 5757 nextToken(); |
5648 if (token.value == TOK.TOKlparen) | 5758 if (token.value == TOK.TOKlparen) |
5649 // ident!(template_arguments) | 5759 // ident!(template_arguments) |
5650 tempinst.tiargs = parseTemplateArgumentList(); | 5760 tiargs = parseTemplateArgumentList(); |
5651 else | 5761 else |
5652 // ident!template_argument | 5762 // ident!template_argument |
5653 tempinst.tiargs = parseTemplateArgument(); | 5763 tiargs = parseTemplateArgument(); |
5654 e = new DotTemplateInstanceExp(loc, e, tempinst); | 5764 e = new DotTemplateInstanceExp(loc, e, tiargs); |
5655 } | 5765 } |
5656 else | 5766 else |
5657 e = new DotIdExp(loc, e, id); | 5767 e = new DotIdExp(loc, e, id); |
5658 continue; | 5768 continue; |
5659 } | 5769 } |
5746 while (1) | 5856 while (1) |
5747 { | 5857 { |
5748 switch (token.value) | 5858 switch (token.value) |
5749 { | 5859 { |
5750 case TOK.TOKmul: nextToken(); e2 = parseUnaryExp(); e = new MulExp(loc,e,e2); continue; | 5860 case TOK.TOKmul: nextToken(); e2 = parseUnaryExp(); e = new MulExp(loc,e,e2); continue; |
5751 case TOK.TOKdiv: nextToken(); e2 = parseUnaryExp(); e = new DivExp(loc,e,e2); continue; | 5861 case TOK.TOKdiv: nextToken(); e2 = parseUnaryExp(); e = new DivExp(loc,e,e2); continue; |
5752 case TOK.TOKmod: nextToken(); e2 = parseUnaryExp(); e = new ModExp(loc,e,e2); continue; | 5862 case TOK.TOKmod: nextToken(); e2 = parseUnaryExp(); e = new ModExp(loc,e,e2); continue; |
5863 case TOK.TOKpow: nextToken(); e2 = parseUnaryExp(); e = new PowExp(loc,e,e2); continue; | |
5753 | 5864 |
5754 default: | 5865 default: |
5755 break; | 5866 break; |
5756 } | 5867 } |
5757 break; | 5868 break; |
6014 case TOK.TOKaddass: nextToken(); e2 = parseAssignExp(); e = new AddAssignExp(loc,e,e2); continue; | 6125 case TOK.TOKaddass: nextToken(); e2 = parseAssignExp(); e = new AddAssignExp(loc,e,e2); continue; |
6015 case TOK.TOKminass: nextToken(); e2 = parseAssignExp(); e = new MinAssignExp(loc,e,e2); continue; | 6126 case TOK.TOKminass: nextToken(); e2 = parseAssignExp(); e = new MinAssignExp(loc,e,e2); continue; |
6016 case TOK.TOKmulass: nextToken(); e2 = parseAssignExp(); e = new MulAssignExp(loc,e,e2); continue; | 6127 case TOK.TOKmulass: nextToken(); e2 = parseAssignExp(); e = new MulAssignExp(loc,e,e2); continue; |
6017 case TOK.TOKdivass: nextToken(); e2 = parseAssignExp(); e = new DivAssignExp(loc,e,e2); continue; | 6128 case TOK.TOKdivass: nextToken(); e2 = parseAssignExp(); e = new DivAssignExp(loc,e,e2); continue; |
6018 case TOK.TOKmodass: nextToken(); e2 = parseAssignExp(); e = new ModAssignExp(loc,e,e2); continue; | 6129 case TOK.TOKmodass: nextToken(); e2 = parseAssignExp(); e = new ModAssignExp(loc,e,e2); continue; |
6130 // case TOK.TOKpowass: nextToken(); e2 = parseAssignExp(); e = new PowAssignExp(loc,e,e2); continue; | |
6019 case TOK.TOKandass: nextToken(); e2 = parseAssignExp(); e = new AndAssignExp(loc,e,e2); continue; | 6131 case TOK.TOKandass: nextToken(); e2 = parseAssignExp(); e = new AndAssignExp(loc,e,e2); continue; |
6020 case TOK.TOKorass: nextToken(); e2 = parseAssignExp(); e = new OrAssignExp(loc,e,e2); continue; | 6132 case TOK.TOKorass: nextToken(); e2 = parseAssignExp(); e = new OrAssignExp(loc,e,e2); continue; |
6021 case TOK.TOKxorass: nextToken(); e2 = parseAssignExp(); e = new XorAssignExp(loc,e,e2); continue; | 6133 case TOK.TOKxorass: nextToken(); e2 = parseAssignExp(); e = new XorAssignExp(loc,e,e2); continue; |
6022 case TOK.TOKshlass: nextToken(); e2 = parseAssignExp(); e = new ShlAssignExp(loc,e,e2); continue; | 6134 case TOK.TOKshlass: nextToken(); e2 = parseAssignExp(); e = new ShlAssignExp(loc,e,e2); continue; |
6023 case TOK.TOKshrass: nextToken(); e2 = parseAssignExp(); e = new ShrAssignExp(loc,e,e2); continue; | 6135 case TOK.TOKshrass: nextToken(); e2 = parseAssignExp(); e = new ShrAssignExp(loc,e,e2); continue; |