comparison dmd/parse.c @ 1195:e961851fb8be

Merged DMD 1.042.
author Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
date Fri, 03 Apr 2009 17:59:34 +0200
parents 226c07c71967
children dda95755f63d
comparison
equal deleted inserted replaced
1194:1853dcd9b944 1195:e961851fb8be
1 1
2 // Compiler implementation of the D programming language 2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2008 by Digital Mars 3 // Copyright (c) 1999-2009 by Digital Mars
4 // All Rights Reserved 4 // All Rights Reserved
5 // written by Walter Bright 5 // written by Walter Bright
6 // http://www.digitalmars.com 6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License 7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt. 8 // in artistic.txt, or the GNU General Public License in gnu.txt.
30 #include "declaration.h" 30 #include "declaration.h"
31 #include "aggregate.h" 31 #include "aggregate.h"
32 #include "enum.h" 32 #include "enum.h"
33 #include "id.h" 33 #include "id.h"
34 #include "version.h" 34 #include "version.h"
35 #if DMDV2
36 #include "aliasthis.h"
37 #endif
35 38
36 // How multiple declarations are parsed. 39 // How multiple declarations are parsed.
37 // If 1, treat as C. 40 // If 1, treat as C.
38 // If 0, treat: 41 // If 0, treat:
39 // int *p, i; 42 // int *p, i;
73 if (token.value == TOKmodule) 76 if (token.value == TOKmodule)
74 { 77 {
75 unsigned char *comment = token.blockComment; 78 unsigned char *comment = token.blockComment;
76 79
77 nextToken(); 80 nextToken();
81 #if DMDV2
82 if (token.value == TOKlparen)
83 {
84 nextToken();
85 if (token.value != TOKidentifier)
86 { error("module (system) identifier expected");
87 goto Lerr;
88 }
89 Identifier *id = token.ident;
90
91 if (id == Id::system)
92 safe = TRUE;
93 else
94 error("(safe) expected, not %s", id->toChars());
95 nextToken();
96 check(TOKrparen);
97 }
98 #endif
99
78 if (token.value != TOKidentifier) 100 if (token.value != TOKidentifier)
79 { error("Identifier expected following module"); 101 { error("Identifier expected following module");
80 goto Lerr; 102 goto Lerr;
81 } 103 }
82 else 104 else
257 case TOKscope: stc = STCscope; goto Lstc; 279 case TOKscope: stc = STCscope; goto Lstc;
258 case TOKoverride: stc = STCoverride; goto Lstc; 280 case TOKoverride: stc = STCoverride; goto Lstc;
259 case TOKabstract: stc = STCabstract; goto Lstc; 281 case TOKabstract: stc = STCabstract; goto Lstc;
260 case TOKsynchronized: stc = STCsynchronized; goto Lstc; 282 case TOKsynchronized: stc = STCsynchronized; goto Lstc;
261 case TOKdeprecated: stc = STCdeprecated; goto Lstc; 283 case TOKdeprecated: stc = STCdeprecated; goto Lstc;
284 #if DMDV2
285 case TOKnothrow: stc = STCnothrow; goto Lstc;
286 case TOKpure: stc = STCpure; goto Lstc;
287 case TOKref: stc = STCref; goto Lstc;
288 case TOKtls: stc = STCtls; goto Lstc;
289 //case TOKmanifest: stc = STCmanifest; goto Lstc;
290 #endif
262 291
263 Lstc: 292 Lstc:
264 nextToken(); 293 nextToken();
265 Lstc2: 294 Lstc2:
266 switch (token.value) 295 switch (token.value)
340 case TOKpublic: prot = PROTpublic; goto Lprot; 369 case TOKpublic: prot = PROTpublic; goto Lprot;
341 case TOKexport: prot = PROTexport; goto Lprot; 370 case TOKexport: prot = PROTexport; goto Lprot;
342 371
343 Lprot: 372 Lprot:
344 nextToken(); 373 nextToken();
374 switch (token.value)
375 {
376 case TOKprivate:
377 case TOKpackage:
378 case TOKprotected:
379 case TOKpublic:
380 case TOKexport:
381 error("redundant protection attribute");
382 break;
383 }
345 a = parseBlock(); 384 a = parseBlock();
346 s = new ProtDeclaration(prot, a); 385 s = new ProtDeclaration(prot, a);
347 break; 386 break;
348 387
349 case TOKalign: 388 case TOKalign:
800 return f; 839 return f;
801 } 840 }
802 841
803 /***************************************** 842 /*****************************************
804 * Parse an invariant definition: 843 * Parse an invariant definition:
805 * invariant { body } 844 * invariant() { body }
806 * Current token is 'invariant'. 845 * Current token is 'invariant'.
807 */ 846 */
808 847
809 InvariantDeclaration *Parser::parseInvariant() 848 InvariantDeclaration *Parser::parseInvariant()
810 { 849 {
985 */ 1024 */
986 1025
987 EnumDeclaration *Parser::parseEnum() 1026 EnumDeclaration *Parser::parseEnum()
988 { EnumDeclaration *e; 1027 { EnumDeclaration *e;
989 Identifier *id; 1028 Identifier *id;
990 Type *t; 1029 Type *memtype;
991 Loc loc = this->loc; 1030 Loc loc = this->loc;
992 1031
993 //printf("Parser::parseEnum()\n"); 1032 //printf("Parser::parseEnum()\n");
994 nextToken(); 1033 nextToken();
995 if (token.value == TOKidentifier) 1034 if (token.value == TOKidentifier)
1000 id = NULL; 1039 id = NULL;
1001 1040
1002 if (token.value == TOKcolon) 1041 if (token.value == TOKcolon)
1003 { 1042 {
1004 nextToken(); 1043 nextToken();
1005 t = parseBasicType(); 1044 memtype = parseBasicType();
1006 } 1045 }
1007 else 1046 else
1008 t = NULL; 1047 memtype = NULL;
1009 1048
1010 e = new EnumDeclaration(loc, id, t); 1049 e = new EnumDeclaration(loc, id, memtype);
1011 if (token.value == TOKsemicolon && id) 1050 if (token.value == TOKsemicolon && id)
1012 nextToken(); 1051 nextToken();
1013 else if (token.value == TOKlcurly) 1052 else if (token.value == TOKlcurly)
1014 { 1053 {
1015 //printf("enum definition\n"); 1054 //printf("enum definition\n");
1055 error("enum declaration is invalid"); 1094 error("enum declaration is invalid");
1056 1095
1057 //printf("-parseEnum() %s\n", e->toChars()); 1096 //printf("-parseEnum() %s\n", e->toChars());
1058 return e; 1097 return e;
1059 } 1098 }
1099
1100 /********************************
1101 * Parse struct, union, interface, class.
1102 */
1060 1103
1061 Dsymbol *Parser::parseAggregate() 1104 Dsymbol *Parser::parseAggregate()
1062 { AggregateDeclaration *a = NULL; 1105 { AggregateDeclaration *a = NULL;
1063 int anon = 0; 1106 int anon = 0;
1064 enum TOK tok; 1107 enum TOK tok;
1158 TemplateDeclaration *tempdecl; 1201 TemplateDeclaration *tempdecl;
1159 1202
1160 // Wrap a template around the aggregate declaration 1203 // Wrap a template around the aggregate declaration
1161 decldefs = new Array(); 1204 decldefs = new Array();
1162 decldefs->push(a); 1205 decldefs->push(a);
1163 tempdecl = new TemplateDeclaration(loc, id, tpl, decldefs); 1206 tempdecl = new TemplateDeclaration(loc, id, tpl, NULL, decldefs);
1164 return tempdecl; 1207 return tempdecl;
1165 } 1208 }
1166 1209
1167 return a; 1210 return a;
1168 } 1211 }
1263 goto Lerr; 1306 goto Lerr;
1264 } 1307 }
1265 nextToken(); 1308 nextToken();
1266 } 1309 }
1267 1310
1268 tempdecl = new TemplateDeclaration(loc, id, tpl, decldefs); 1311 tempdecl = new TemplateDeclaration(loc, id, tpl, NULL, decldefs);
1269 return tempdecl; 1312 return tempdecl;
1270 1313
1271 Lerr: 1314 Lerr:
1272 return NULL; 1315 return NULL;
1273 } 1316 }
1647 nextToken(); 1690 nextToken();
1648 } 1691 }
1649 1692
1650 return NULL; 1693 return NULL;
1651 } 1694 }
1695
1696 #if DMDV2
1697 Type *Parser::parseType(Identifier **pident, TemplateParameters **tpl)
1698 { Type *t;
1699
1700 /* Take care of the storage class prefixes that
1701 * serve as type attributes:
1702 * const shared, shared const, const, invariant, shared
1703 */
1704 if (token.value == TOKconst && peekNext() == TOKshared && peekNext2() != TOKlparen ||
1705 token.value == TOKshared && peekNext() == TOKconst && peekNext2() != TOKlparen)
1706 {
1707 nextToken();
1708 nextToken();
1709 /* shared const type
1710 */
1711 t = parseType(pident, tpl);
1712 t = t->makeSharedConst();
1713 return t;
1714 }
1715 else if (token.value == TOKconst && peekNext() != TOKlparen)
1716 {
1717 nextToken();
1718 /* const type
1719 */
1720 t = parseType(pident, tpl);
1721 t = t->makeConst();
1722 return t;
1723 }
1724 else if ((token.value == TOKinvariant || token.value == TOKimmutable) &&
1725 peekNext() != TOKlparen)
1726 {
1727 nextToken();
1728 /* invariant type
1729 */
1730 t = parseType(pident, tpl);
1731 t = t->makeInvariant();
1732 return t;
1733 }
1734 else if (token.value == TOKshared && peekNext() != TOKlparen)
1735 {
1736 nextToken();
1737 /* shared type
1738 */
1739 t = parseType(pident, tpl);
1740 t = t->makeShared();
1741 return t;
1742 }
1743 else
1744 t = parseBasicType();
1745 t = parseDeclarator(t, pident, tpl);
1746 return t;
1747 }
1748 #endif
1652 1749
1653 Type *Parser::parseBasicType() 1750 Type *Parser::parseBasicType()
1654 { Type *t; 1751 { Type *t;
1655 Identifier *id; 1752 Identifier *id;
1656 TypeQualified *tid; 1753 TypeQualified *tid;
1887 default: 1984 default:
1888 ts = t; 1985 ts = t;
1889 break; 1986 break;
1890 } 1987 }
1891 1988
1989 // parse DeclaratorSuffixes
1892 while (1) 1990 while (1)
1893 { 1991 {
1894 switch (token.value) 1992 switch (token.value)
1895 { 1993 {
1896 #if CARRAYDECL 1994 #if CARRAYDECL
1922 //printf("it's [expression]\n"); 2020 //printf("it's [expression]\n");
1923 Expression *e = parseExpression(); // [ expression ] 2021 Expression *e = parseExpression(); // [ expression ]
1924 ta = new TypeSArray(t, e); 2022 ta = new TypeSArray(t, e);
1925 check(TOKrbracket); 2023 check(TOKrbracket);
1926 } 2024 }
2025
1927 /* Insert ta into 2026 /* Insert ta into
1928 * ts -> ... -> t 2027 * ts -> ... -> t
1929 * so that 2028 * so that
1930 * ts -> ... -> ta -> t 2029 * ts -> ... -> ta -> t
1931 */ 2030 */
1984 Type *ts; 2083 Type *ts;
1985 Type *t; 2084 Type *t;
1986 Type *tfirst; 2085 Type *tfirst;
1987 Identifier *ident; 2086 Identifier *ident;
1988 Array *a; 2087 Array *a;
1989 enum TOK tok; 2088 enum TOK tok = TOKreserved;
1990 unsigned char *comment = token.blockComment; 2089 unsigned char *comment = token.blockComment;
1991 enum LINK link = linkage; 2090 enum LINK link = linkage;
1992 2091
1993 //printf("parseDeclarations()\n"); 2092 //printf("parseDeclarations()\n");
1994 switch (token.value) 2093 switch (token.value)
2016 case TOKscope: stc = STCscope; goto L1; 2115 case TOKscope: stc = STCscope; goto L1;
2017 case TOKoverride: stc = STCoverride; goto L1; 2116 case TOKoverride: stc = STCoverride; goto L1;
2018 case TOKabstract: stc = STCabstract; goto L1; 2117 case TOKabstract: stc = STCabstract; goto L1;
2019 case TOKsynchronized: stc = STCsynchronized; goto L1; 2118 case TOKsynchronized: stc = STCsynchronized; goto L1;
2020 case TOKdeprecated: stc = STCdeprecated; goto L1; 2119 case TOKdeprecated: stc = STCdeprecated; goto L1;
2120 #if DMDV2
2121 case TOKnothrow: stc = STCnothrow; goto L1;
2122 case TOKpure: stc = STCpure; goto L1;
2123 case TOKref: stc = STCref; goto L1;
2124 case TOKtls: stc = STCtls; goto L1;
2125 case TOKenum: stc = STCmanifest; goto L1;
2126 #endif
2021 L1: 2127 L1:
2022 if (storage_class & stc) 2128 if (storage_class & stc)
2023 error("redundant storage class '%s'", token.toChars()); 2129 error("redundant storage class '%s'", token.toChars());
2024 storage_class = (STC) (storage_class | stc); 2130 storage_class = (STC) (storage_class | stc);
2025 nextToken(); 2131 nextToken();
2106 if (!ident) 2212 if (!ident)
2107 error("no identifier for declarator %s", t->toChars()); 2213 error("no identifier for declarator %s", t->toChars());
2108 2214
2109 if (tok == TOKtypedef || tok == TOKalias) 2215 if (tok == TOKtypedef || tok == TOKalias)
2110 { Declaration *v; 2216 { Declaration *v;
2111 Initializer *init; 2217 Initializer *init = NULL;
2112 2218
2113 init = NULL;
2114 if (token.value == TOKassign) 2219 if (token.value == TOKassign)
2115 { 2220 {
2116 nextToken(); 2221 nextToken();
2117 init = parseInitializer(); 2222 init = parseInitializer();
2118 } 2223 }
2148 error("semicolon expected to close %s declaration", Token::toChars(tok)); 2253 error("semicolon expected to close %s declaration", Token::toChars(tok));
2149 break; 2254 break;
2150 } 2255 }
2151 } 2256 }
2152 else if (t->ty == Tfunction) 2257 else if (t->ty == Tfunction)
2153 { FuncDeclaration *f; 2258 { FuncDeclaration *f =
2154 Dsymbol *s; 2259 new FuncDeclaration(loc, 0, ident, storage_class, t);
2155
2156 f = new FuncDeclaration(loc, 0, ident, storage_class, t);
2157 addComment(f, comment); 2260 addComment(f, comment);
2158 parseContracts(f); 2261 parseContracts(f);
2159 addComment(f, NULL); 2262 addComment(f, NULL);
2263 Dsymbol *s;
2160 if (link == linkage) 2264 if (link == linkage)
2161 { 2265 {
2162 s = f; 2266 s = f;
2163 } 2267 }
2164 else 2268 else
2172 TemplateDeclaration *tempdecl; 2276 TemplateDeclaration *tempdecl;
2173 2277
2174 // Wrap a template around the aggregate declaration 2278 // Wrap a template around the aggregate declaration
2175 decldefs = new Array(); 2279 decldefs = new Array();
2176 decldefs->push(s); 2280 decldefs->push(s);
2177 tempdecl = new TemplateDeclaration(loc, s->ident, tpl, decldefs); 2281 tempdecl = new TemplateDeclaration(loc, s->ident, tpl, NULL, decldefs);
2178 s = tempdecl; 2282 s = tempdecl;
2179 } 2283 }
2180 addComment(s, comment); 2284 addComment(s, comment);
2181 a->push(s); 2285 a->push(s);
2182 } 2286 }
2183 else 2287 else
2184 { VarDeclaration *v; 2288 {
2185 Initializer *init; 2289 Initializer *init = NULL;
2186
2187 init = NULL;
2188 if (token.value == TOKassign) 2290 if (token.value == TOKassign)
2189 { 2291 {
2190 nextToken(); 2292 nextToken();
2191 init = parseInitializer(); 2293 init = parseInitializer();
2192 } 2294 }
2193 v = new VarDeclaration(loc, t, ident, init); 2295
2296 VarDeclaration *v = new VarDeclaration(loc, t, ident, init);
2194 v->storage_class = storage_class; 2297 v->storage_class = storage_class;
2195 if (link == linkage) 2298 if (link == linkage)
2196 a->push(v); 2299 a->push(v);
2197 else 2300 else
2198 { 2301 {
2361 } 2464 }
2362 linkage = linksave; 2465 linkage = linksave;
2363 } 2466 }
2364 2467
2365 /***************************************** 2468 /*****************************************
2469 * Parse initializer for variable declaration.
2366 */ 2470 */
2367 2471
2368 Initializer *Parser::parseInitializer() 2472 Initializer *Parser::parseInitializer()
2369 { 2473 {
2370 StructInitializer *is; 2474 StructInitializer *is;
2618 error("statement expected to be { }, not %s", token.toChars()); 2722 error("statement expected to be { }, not %s", token.toChars());
2619 2723
2620 switch (token.value) 2724 switch (token.value)
2621 { 2725 {
2622 case TOKidentifier: 2726 case TOKidentifier:
2623 // Need to look ahead to see if it is a declaration, label, or expression 2727 /* A leading identifier can be a declaration, label, or expression.
2728 * The easiest case to check first is label:
2729 */
2624 t = peek(&token); 2730 t = peek(&token);
2625 if (t->value == TOKcolon) 2731 if (t->value == TOKcolon)
2626 { // It's a label 2732 { // It's a label
2627 Identifier *ident; 2733
2628 2734 Identifier *ident = token.ident;
2629 ident = token.ident;
2630 nextToken(); 2735 nextToken();
2631 nextToken(); 2736 nextToken();
2632 s = parseStatement(PSsemi); 2737 s = parseStatement(PSsemi);
2633 s = new LabelStatement(loc, ident, s); 2738 s = new LabelStatement(loc, ident, s);
2634 break; 2739 break;
2716 case TOKconst: 2821 case TOKconst:
2717 case TOKauto: 2822 case TOKauto:
2718 case TOKextern: 2823 case TOKextern:
2719 case TOKfinal: 2824 case TOKfinal:
2720 case TOKinvariant: 2825 case TOKinvariant:
2826 #if DMDV2
2827 case TOKimmutable:
2828 case TOKshared:
2829 #endif
2721 // case TOKtypeof: 2830 // case TOKtypeof:
2722 Ldeclaration: 2831 Ldeclaration:
2723 { Array *a; 2832 { Array *a;
2724 2833
2725 a = parseDeclarations(); 2834 a = parseDeclarations();
2731 { 2840 {
2732 Dsymbol *d = (Dsymbol *)a->data[i]; 2841 Dsymbol *d = (Dsymbol *)a->data[i];
2733 s = new DeclarationStatement(loc, d); 2842 s = new DeclarationStatement(loc, d);
2734 as->push(s); 2843 as->push(s);
2735 } 2844 }
2736 s = new CompoundStatement(loc, as); 2845 s = new CompoundDeclarationStatement(loc, as);
2737 } 2846 }
2738 else if (a->dim == 1) 2847 else if (a->dim == 1)
2739 { 2848 {
2740 Dsymbol *d = (Dsymbol *)a->data[0]; 2849 Dsymbol *d = (Dsymbol *)a->data[0];
2741 s = new DeclarationStatement(loc, d); 2850 s = new DeclarationStatement(loc, d);
3441 if (token.value != value) 3550 if (token.value != value)
3442 error(loc, "found '%s' when expecting '%s'", token.toChars(), Token::toChars(value)); 3551 error(loc, "found '%s' when expecting '%s'", token.toChars(), Token::toChars(value));
3443 nextToken(); 3552 nextToken();
3444 } 3553 }
3445 3554
3446 void Parser::check(enum TOK value, char *string) 3555 void Parser::check(enum TOK value, const char *string)
3447 { 3556 {
3448 if (token.value != value) 3557 if (token.value != value)
3449 error("found '%s' when expecting '%s' following '%s'", 3558 error("found '%s' when expecting '%s' following '%s'",
3450 token.toChars(), Token::toChars(value), string); 3559 token.toChars(), Token::toChars(value), string);
3451 nextToken(); 3560 nextToken();
3459 * 2 must have identifier 3568 * 2 must have identifier
3460 */ 3569 */
3461 3570
3462 int Parser::isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt) 3571 int Parser::isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt)
3463 { 3572 {
3573 //printf("isDeclaration(needId = %d)\n", needId);
3464 int haveId = 0; 3574 int haveId = 0;
3465 3575
3466 #if DMDV2 3576 #if DMDV2
3467 if ((t->value == TOKconst || t->value == TOKinvariant) && 3577 if ((t->value == TOKconst || t->value == TOKinvariant) &&
3468 peek(t)->value != TOKlparen) 3578 peek(t)->value != TOKlparen)
3549 3659
3550 default: 3660 default:
3551 goto Lfalse; 3661 goto Lfalse;
3552 } 3662 }
3553 *pt = t; 3663 *pt = t;
3664 //printf("is\n");
3554 return TRUE; 3665 return TRUE;
3555 3666
3556 Lfalse: 3667 Lfalse:
3668 //printf("is not\n");
3557 return FALSE; 3669 return FALSE;
3558 } 3670 }
3559 3671
3560 int Parser::isDeclarator(Token **pt, int *haveId, enum TOK endtok) 3672 int Parser::isDeclarator(Token **pt, int *haveId, enum TOK endtok)
3561 { // This code parallels parseDeclarator() 3673 { // This code parallels parseDeclarator()
3676 3788
3677 case TOKlparen: 3789 case TOKlparen:
3678 parens = FALSE; 3790 parens = FALSE;
3679 if (!isParameters(&t)) 3791 if (!isParameters(&t))
3680 return FALSE; 3792 return FALSE;
3793 #if DMDV2
3794 while (1)
3795 {
3796 switch (t->value)
3797 {
3798 case TOKconst:
3799 case TOKinvariant:
3800 case TOKimmutable:
3801 case TOKshared:
3802 case TOKpure:
3803 case TOKnothrow:
3804 t = peek(t);
3805 continue;
3806 default:
3807 break;
3808 }
3809 break;
3810 }
3811 #endif
3681 continue; 3812 continue;
3682 3813
3683 // Valid tokens that follow a declaration 3814 // Valid tokens that follow a declaration
3684 case TOKrparen: 3815 case TOKrparen:
3685 case TOKrbracket: 3816 case TOKrbracket:
4201 token.value == TOKunion || 4332 token.value == TOKunion ||
4202 token.value == TOKclass || 4333 token.value == TOKclass ||
4203 token.value == TOKsuper || 4334 token.value == TOKsuper ||
4204 token.value == TOKenum || 4335 token.value == TOKenum ||
4205 token.value == TOKinterface || 4336 token.value == TOKinterface ||
4337 #if DMDV2
4338 token.value == TOKconst && peek(&token)->value == TOKrparen ||
4339 token.value == TOKinvariant && peek(&token)->value == TOKrparen ||
4340 token.value == TOKimmutable && peek(&token)->value == TOKrparen ||
4341 token.value == TOKshared && peek(&token)->value == TOKrparen ||
4342 #endif
4206 token.value == TOKfunction || 4343 token.value == TOKfunction ||
4207 token.value == TOKdelegate || 4344 token.value == TOKdelegate ||
4208 token.value == TOKreturn)) 4345 token.value == TOKreturn))
4209 { 4346 {
4210 tok2 = token.value; 4347 tok2 = token.value;