Mercurial > projects > ldc
diff dmd2/statement.c @ 847:356e65836fb5
Merged DMD 2.021 frontend.
Removed generated files from dmd/dmd2 dirs.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Sat, 13 Dec 2008 16:14:37 +0100 |
parents | f08e0ff8d28c |
children | 03d7c4aac654 |
line wrap: on
line diff
--- a/dmd2/statement.c Sat Dec 13 13:15:31 2008 +0100 +++ b/dmd2/statement.c Sat Dec 13 16:14:37 2008 +0100 @@ -1116,7 +1116,9 @@ condition = condition->checkToBoolean(); } if (increment) - increment = increment->semantic(sc); + { increment = increment->semantic(sc); + increment = resolveProperties(sc, increment); + } sc->sbreak = this; sc->scontinue = this; @@ -1261,8 +1263,7 @@ //printf("ForeachStatement::semantic() %p\n", this); ScopeDsymbol *sym; Statement *s = this; - int dim = arguments->dim; - int i; + size_t dim = arguments->dim; TypeAArray *taa = NULL; Type *tn = NULL; @@ -1391,15 +1392,6 @@ return s; } - for (i = 0; i < dim; i++) - { Argument *arg = (Argument *)arguments->data[i]; - if (!arg->type) - { - error("cannot infer type for %s", arg->ident->toChars()); - return this; - } - } - sym = new ScopeDsymbol(); sym->parent = sc->scopesym; sc = sc->push(sym); @@ -1410,6 +1402,9 @@ { case Tarray: case Tsarray: + if (!checkForArgTypes()) + return this; + if (dim < 1 || dim > 2) { error("only one or two arguments for array foreach"); @@ -1423,7 +1418,7 @@ if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) { Argument *arg; - i = (dim == 1) ? 0 : 1; // index of value + int i = (dim == 1) ? 0 : 1; // index of value arg = (Argument *)arguments->data[i]; arg->type = arg->type->semantic(loc, sc); tnv = arg->type->toBasetype(); @@ -1441,7 +1436,7 @@ } } - for (i = 0; i < dim; i++) + for (size_t i = 0; i < dim; i++) { // Declare args Argument *arg = (Argument *)arguments->data[i]; VarDeclaration *var; @@ -1506,6 +1501,9 @@ break; case Taarray: + if (!checkForArgTypes()) + return this; + taa = (TypeAArray *)tab; if (dim < 1 || dim > 2) { @@ -1520,6 +1518,72 @@ case Tclass: case Tstruct: +#if DMDV2 + { /* Look for range iteration, i.e. the properties + * .empty, .next, .retreat, .head and .rear + * foreach (e; range) { ... } + * translates to: + * for (auto __r = range; !__r.empty; __r.next) + * { auto e = __r.head; + * ... + * } + */ + if (dim != 1) // only one argument allowed with ranges + goto Lapply; + AggregateDeclaration *ad = (tab->ty == Tclass) + ? (AggregateDeclaration *)((TypeClass *)tab)->sym + : (AggregateDeclaration *)((TypeStruct *)tab)->sym; + Identifier *idhead; + Identifier *idnext; + if (op == TOKforeach) + { idhead = Id::Fhead; + idnext = Id::Fnext; + } + else + { idhead = Id::Ftoe; + idnext = Id::Fretreat; + } + Dsymbol *shead = search_function(ad, idhead); + if (!shead) + goto Lapply; + + /* Generate a temporary __r and initialize it with the aggregate. + */ + Identifier *id = Identifier::generateId("__r"); + VarDeclaration *r = new VarDeclaration(loc, NULL, id, new ExpInitializer(loc, aggr)); + r->semantic(sc); + Statement *init = new DeclarationStatement(loc, r); + + // !__r.empty + Expression *e = new VarExp(loc, r); + e = new DotIdExp(loc, e, Id::Fempty); + Expression *condition = new NotExp(loc, e); + + // __r.next + e = new VarExp(loc, r); + Expression *increment = new DotIdExp(loc, e, idnext); + + /* Declaration statement for e: + * auto e = __r.idhead; + */ + e = new VarExp(loc, r); + Expression *einit = new DotIdExp(loc, e, idhead); + einit = einit->semantic(sc); + Argument *arg = (Argument *)arguments->data[0]; + VarDeclaration *ve = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, einit)); + ve->storage_class |= STCforeach; + ve->storage_class |= arg->storageClass & (STCin | STCout | STCref | STCconst | STCinvariant); + + DeclarationExp *de = new DeclarationExp(loc, ve); + + Statement *body = new CompoundStatement(loc, + new DeclarationStatement(loc, de), this->body); + + s = new ForStatement(loc, init, condition, increment, body); + s = s->semantic(sc); + break; + } +#endif case Tdelegate: Lapply: { FuncDeclaration *fdapply; @@ -1536,6 +1600,9 @@ TypeDelegate* dgty2; TypeDelegate* fldeTy; + if (!checkForArgTypes()) + return this; + tret = func->type->nextOf(); // Need a variable to hold value from any return statements in body. @@ -1555,7 +1622,7 @@ * int delegate(ref T arg) { body } */ args = new Arguments(); - for (i = 0; i < dim; i++) + for (size_t i = 0; i < dim; i++) { Argument *arg = (Argument *)arguments->data[i]; arg->type = arg->type->semantic(loc, sc); @@ -1815,6 +1882,19 @@ return s; } +bool ForeachStatement::checkForArgTypes() +{ + for (size_t i = 0; i < arguments->dim; i++) + { Argument *arg = (Argument *)arguments->data[i]; + if (!arg->type) + { + error("cannot infer type for %s", arg->ident->toChars()); + return FALSE; + } + } + return TRUE; +} + int ForeachStatement::hasBreak() { return TRUE; @@ -1888,6 +1968,8 @@ /**************************** ForeachRangeStatement ***************************/ +#if DMDV2 + ForeachRangeStatement::ForeachRangeStatement(Loc loc, enum TOK op, Argument *arg, Expression *lwr, Expression *upr, Statement *body) : Statement(loc) @@ -2047,6 +2129,8 @@ buf->writenl(); } +#endif + /******************************** IfStatement ***************************/ IfStatement::IfStatement(Loc loc, Argument *arg, Expression *condition, Statement *ifbody, Statement *elsebody) @@ -2339,6 +2423,11 @@ } else if (ident == Id::lib) { +#if 1 + /* Should this be allowed? + */ + error("pragma(lib) not allowed as statement"); +#else if (!args || args->dim != 1) error("string expected for library name"); else @@ -2360,6 +2449,7 @@ mem.free(name); } } +#endif } else if (ident == Id::startaddress) {