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;