Mercurial > projects > ldc
diff 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 |
line wrap: on
line diff
--- a/dmd/parse.c Fri Apr 03 17:02:52 2009 +0200 +++ b/dmd/parse.c Fri Apr 03 17:59:34 2009 +0200 @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2008 by Digital Mars +// Copyright (c) 1999-2009 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -32,6 +32,9 @@ #include "enum.h" #include "id.h" #include "version.h" +#if DMDV2 +#include "aliasthis.h" +#endif // How multiple declarations are parsed. // If 1, treat as C. @@ -75,6 +78,25 @@ unsigned char *comment = token.blockComment; nextToken(); +#if DMDV2 + if (token.value == TOKlparen) + { + nextToken(); + if (token.value != TOKidentifier) + { error("module (system) identifier expected"); + goto Lerr; + } + Identifier *id = token.ident; + + if (id == Id::system) + safe = TRUE; + else + error("(safe) expected, not %s", id->toChars()); + nextToken(); + check(TOKrparen); + } +#endif + if (token.value != TOKidentifier) { error("Identifier expected following module"); goto Lerr; @@ -259,6 +281,13 @@ case TOKabstract: stc = STCabstract; goto Lstc; case TOKsynchronized: stc = STCsynchronized; goto Lstc; case TOKdeprecated: stc = STCdeprecated; goto Lstc; +#if DMDV2 + case TOKnothrow: stc = STCnothrow; goto Lstc; + case TOKpure: stc = STCpure; goto Lstc; + case TOKref: stc = STCref; goto Lstc; + case TOKtls: stc = STCtls; goto Lstc; + //case TOKmanifest: stc = STCmanifest; goto Lstc; +#endif Lstc: nextToken(); @@ -342,6 +371,16 @@ Lprot: nextToken(); + switch (token.value) + { + case TOKprivate: + case TOKpackage: + case TOKprotected: + case TOKpublic: + case TOKexport: + error("redundant protection attribute"); + break; + } a = parseBlock(); s = new ProtDeclaration(prot, a); break; @@ -802,7 +841,7 @@ /***************************************** * Parse an invariant definition: - * invariant { body } + * invariant() { body } * Current token is 'invariant'. */ @@ -987,7 +1026,7 @@ EnumDeclaration *Parser::parseEnum() { EnumDeclaration *e; Identifier *id; - Type *t; + Type *memtype; Loc loc = this->loc; //printf("Parser::parseEnum()\n"); @@ -1002,12 +1041,12 @@ if (token.value == TOKcolon) { nextToken(); - t = parseBasicType(); + memtype = parseBasicType(); } else - t = NULL; - - e = new EnumDeclaration(loc, id, t); + memtype = NULL; + + e = new EnumDeclaration(loc, id, memtype); if (token.value == TOKsemicolon && id) nextToken(); else if (token.value == TOKlcurly) @@ -1058,6 +1097,10 @@ return e; } +/******************************** + * Parse struct, union, interface, class. + */ + Dsymbol *Parser::parseAggregate() { AggregateDeclaration *a = NULL; int anon = 0; @@ -1160,7 +1203,7 @@ // Wrap a template around the aggregate declaration decldefs = new Array(); decldefs->push(a); - tempdecl = new TemplateDeclaration(loc, id, tpl, decldefs); + tempdecl = new TemplateDeclaration(loc, id, tpl, NULL, decldefs); return tempdecl; } @@ -1265,7 +1308,7 @@ nextToken(); } - tempdecl = new TemplateDeclaration(loc, id, tpl, decldefs); + tempdecl = new TemplateDeclaration(loc, id, tpl, NULL, decldefs); return tempdecl; Lerr: @@ -1650,6 +1693,60 @@ return NULL; } +#if DMDV2 +Type *Parser::parseType(Identifier **pident, TemplateParameters **tpl) +{ Type *t; + + /* Take care of the storage class prefixes that + * serve as type attributes: + * const shared, shared const, const, invariant, shared + */ + if (token.value == TOKconst && peekNext() == TOKshared && peekNext2() != TOKlparen || + token.value == TOKshared && peekNext() == TOKconst && peekNext2() != TOKlparen) + { + nextToken(); + nextToken(); + /* shared const type + */ + t = parseType(pident, tpl); + t = t->makeSharedConst(); + return t; + } + else if (token.value == TOKconst && peekNext() != TOKlparen) + { + nextToken(); + /* const type + */ + t = parseType(pident, tpl); + t = t->makeConst(); + return t; + } + else if ((token.value == TOKinvariant || token.value == TOKimmutable) && + peekNext() != TOKlparen) + { + nextToken(); + /* invariant type + */ + t = parseType(pident, tpl); + t = t->makeInvariant(); + return t; + } + else if (token.value == TOKshared && peekNext() != TOKlparen) + { + nextToken(); + /* shared type + */ + t = parseType(pident, tpl); + t = t->makeShared(); + return t; + } + else + t = parseBasicType(); + t = parseDeclarator(t, pident, tpl); + return t; +} +#endif + Type *Parser::parseBasicType() { Type *t; Identifier *id; @@ -1889,6 +1986,7 @@ break; } + // parse DeclaratorSuffixes while (1) { switch (token.value) @@ -1924,6 +2022,7 @@ ta = new TypeSArray(t, e); check(TOKrbracket); } + /* Insert ta into * ts -> ... -> t * so that @@ -1986,7 +2085,7 @@ Type *tfirst; Identifier *ident; Array *a; - enum TOK tok; + enum TOK tok = TOKreserved; unsigned char *comment = token.blockComment; enum LINK link = linkage; @@ -2018,6 +2117,13 @@ case TOKabstract: stc = STCabstract; goto L1; case TOKsynchronized: stc = STCsynchronized; goto L1; case TOKdeprecated: stc = STCdeprecated; goto L1; +#if DMDV2 + case TOKnothrow: stc = STCnothrow; goto L1; + case TOKpure: stc = STCpure; goto L1; + case TOKref: stc = STCref; goto L1; + case TOKtls: stc = STCtls; goto L1; + case TOKenum: stc = STCmanifest; goto L1; +#endif L1: if (storage_class & stc) error("redundant storage class '%s'", token.toChars()); @@ -2108,9 +2214,8 @@ if (tok == TOKtypedef || tok == TOKalias) { Declaration *v; - Initializer *init; - - init = NULL; + Initializer *init = NULL; + if (token.value == TOKassign) { nextToken(); @@ -2150,13 +2255,12 @@ } } else if (t->ty == Tfunction) - { FuncDeclaration *f; - Dsymbol *s; - - f = new FuncDeclaration(loc, 0, ident, storage_class, t); + { FuncDeclaration *f = + new FuncDeclaration(loc, 0, ident, storage_class, t); addComment(f, comment); parseContracts(f); addComment(f, NULL); + Dsymbol *s; if (link == linkage) { s = f; @@ -2174,23 +2278,22 @@ // Wrap a template around the aggregate declaration decldefs = new Array(); decldefs->push(s); - tempdecl = new TemplateDeclaration(loc, s->ident, tpl, decldefs); + tempdecl = new TemplateDeclaration(loc, s->ident, tpl, NULL, decldefs); s = tempdecl; } addComment(s, comment); a->push(s); } else - { VarDeclaration *v; - Initializer *init; - - init = NULL; + { + Initializer *init = NULL; if (token.value == TOKassign) { nextToken(); init = parseInitializer(); } - v = new VarDeclaration(loc, t, ident, init); + + VarDeclaration *v = new VarDeclaration(loc, t, ident, init); v->storage_class = storage_class; if (link == linkage) a->push(v); @@ -2363,6 +2466,7 @@ } /***************************************** + * Parse initializer for variable declaration. */ Initializer *Parser::parseInitializer() @@ -2620,13 +2724,14 @@ switch (token.value) { case TOKidentifier: - // Need to look ahead to see if it is a declaration, label, or expression + /* A leading identifier can be a declaration, label, or expression. + * The easiest case to check first is label: + */ t = peek(&token); if (t->value == TOKcolon) { // It's a label - Identifier *ident; - - ident = token.ident; + + Identifier *ident = token.ident; nextToken(); nextToken(); s = parseStatement(PSsemi); @@ -2718,6 +2823,10 @@ case TOKextern: case TOKfinal: case TOKinvariant: +#if DMDV2 + case TOKimmutable: + case TOKshared: +#endif // case TOKtypeof: Ldeclaration: { Array *a; @@ -2733,7 +2842,7 @@ s = new DeclarationStatement(loc, d); as->push(s); } - s = new CompoundStatement(loc, as); + s = new CompoundDeclarationStatement(loc, as); } else if (a->dim == 1) { @@ -3443,7 +3552,7 @@ nextToken(); } -void Parser::check(enum TOK value, char *string) +void Parser::check(enum TOK value, const char *string) { if (token.value != value) error("found '%s' when expecting '%s' following '%s'", @@ -3461,6 +3570,7 @@ int Parser::isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt) { + //printf("isDeclaration(needId = %d)\n", needId); int haveId = 0; #if DMDV2 @@ -3551,9 +3661,11 @@ goto Lfalse; } *pt = t; + //printf("is\n"); return TRUE; Lfalse: + //printf("is not\n"); return FALSE; } @@ -3678,6 +3790,25 @@ parens = FALSE; if (!isParameters(&t)) return FALSE; +#if DMDV2 + while (1) + { + switch (t->value) + { + case TOKconst: + case TOKinvariant: + case TOKimmutable: + case TOKshared: + case TOKpure: + case TOKnothrow: + t = peek(t); + continue; + default: + break; + } + break; + } +#endif continue; // Valid tokens that follow a declaration @@ -4203,6 +4334,12 @@ token.value == TOKsuper || token.value == TOKenum || token.value == TOKinterface || +#if DMDV2 + token.value == TOKconst && peek(&token)->value == TOKrparen || + token.value == TOKinvariant && peek(&token)->value == TOKrparen || + token.value == TOKimmutable && peek(&token)->value == TOKrparen || + token.value == TOKshared && peek(&token)->value == TOKrparen || +#endif token.value == TOKfunction || token.value == TOKdelegate || token.value == TOKreturn))