Mercurial > projects > ldc
diff dmd/statement.c @ 846:bc982f1ad106
Merged DMD 1.037 frontend
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Sat, 13 Dec 2008 13:15:31 +0100 |
parents | 661384d6a936 |
children | 330f999ade44 |
line wrap: on
line diff
--- a/dmd/statement.c Sat Dec 13 06:48:00 2008 +0100 +++ b/dmd/statement.c Sat Dec 13 13:15:31 2008 +0100 @@ -26,6 +26,7 @@ #include "id.h" #include "hdrgen.h" #include "parse.h" +#include "template.h" /******************************** Statement ***************************/ @@ -451,10 +452,7 @@ body = new CompoundStatement(0, a); body = new ScopeStatement(0, body); - static int num; - char name[3 + sizeof(num) * 3 + 1]; - sprintf(name, "__o%d", ++num); - Identifier *id = Lexer::idPool(name); + Identifier *id = Lexer::uniqueId("__o"); Statement *handler = new ThrowStatement(0, new IdentifierExp(0, id)); handler = new CompoundStatement(0, sexception, handler); @@ -1107,12 +1105,17 @@ // Use a default value condition = new IntegerExp(loc, 1, Type::tboolean); sc->noctor++; - condition = condition->semantic(sc); - condition = resolveProperties(sc, condition); - condition = condition->optimize(WANTvalue); - condition = condition->checkToBoolean(); + if (condition) + { + condition = condition->semantic(sc); + condition = resolveProperties(sc, condition); + condition = condition->optimize(WANTvalue); + condition = condition->checkToBoolean(); + } if (increment) - increment = increment->semantic(sc); + { increment = increment->semantic(sc); + increment = resolveProperties(sc, increment); + } sc->sbreak = this; sc->scontinue = this; @@ -1257,8 +1260,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; @@ -1272,6 +1274,7 @@ aggr = aggr->semantic(sc); aggr = resolveProperties(sc, aggr); + aggr = aggr->optimize(WANTvalue); if (!aggr->type) { error("invalid foreach aggregate %s", aggr->toChars()); @@ -1387,7 +1390,7 @@ return s; } - for (i = 0; i < dim; i++) + for (size_t i = 0; i < dim; i++) { Argument *arg = (Argument *)arguments->data[i]; if (!arg->type) { @@ -1419,7 +1422,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(); @@ -1437,7 +1440,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; @@ -1468,7 +1471,8 @@ if (aggr->op == TOKstring) aggr = aggr->implicitCastTo(sc, value->type->arrayOf()); else - error("foreach: %s is not an array of %s", tab->toChars(), value->type->toChars()); + error("foreach: %s is not an array of %s", + tab->toChars(), value->type->toChars()); } if (key) @@ -1505,6 +1509,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::Frear; + 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; @@ -1540,7 +1610,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); @@ -1551,10 +1621,8 @@ // a reference. VarDeclaration *v; Initializer *ie; - char applyArg[10 + sizeof(i)*3 + 1]; - - sprintf(applyArg, "__applyArg%d", i); - id = Lexer::idPool(applyArg); + + id = Lexer::uniqueId("__applyArg", i); ie = new ExpInitializer(0, new IdentifierExp(0, id)); v = new VarDeclaration(0, arg->type, arg->ident, ie); @@ -2145,6 +2213,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 @@ -2166,6 +2239,7 @@ mem.free(name); } } +#endif } else error("unrecognized pragma(%s)", ident->toChars()); @@ -2454,8 +2528,7 @@ //printf("CaseStatement::semantic() %s\n", toChars()); exp = exp->semantic(sc); if (sw) - { int i; - + { exp = exp->implicitCastTo(sc, sw->condition->type); exp = exp->optimize(WANTvalue | WANTinterpret); if (exp->op != TOKstring && exp->op != TOKint64) @@ -2464,7 +2537,7 @@ exp = new IntegerExp(0); } - for (i = 0; i < sw->cases->dim; i++) + for (int i = 0; i < sw->cases->dim; i++) { CaseStatement *cs = (CaseStatement *)sw->cases->data[i]; @@ -2478,7 +2551,7 @@ sw->cases->push(this); // Resolve any goto case's with no exp to this case statement - for (i = 0; i < sw->gotoCases.dim; i++) + for (size_t i = 0; i < sw->gotoCases.dim; i++) { GotoCaseStatement *gcs = (GotoCaseStatement *)sw->gotoCases.data[i]; @@ -2875,32 +2948,25 @@ exp->op == TOKstring) { sc->fes->cases.push(this); + // Construct: return cases.dim+1; s = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1)); } else if (fd->type->nextOf()->toBasetype() == Type::tvoid) { - Statement *s1; - Statement *s2; - s = new ReturnStatement(0, NULL); sc->fes->cases.push(s); // Construct: { exp; return cases.dim + 1; } - s1 = new ExpStatement(loc, exp); - s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1)); + Statement *s1 = new ExpStatement(loc, exp); + Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1)); s = new CompoundStatement(loc, s1, s2); } else { - VarExp *v; - Statement *s1; - Statement *s2; - // Construct: return vresult; if (!fd->vresult) - { VarDeclaration *v; - - v = new VarDeclaration(loc, tret, Id::result, NULL); + { // Declare vresult + VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL); v->noauto = 1; v->semantic(scx); if (!scx->insert(v)) @@ -2909,16 +2975,14 @@ fd->vresult = v; } - v = new VarExp(0, fd->vresult); - s = new ReturnStatement(0, v); + s = new ReturnStatement(0, new VarExp(0, fd->vresult)); sc->fes->cases.push(s); // Construct: { vresult = exp; return cases.dim + 1; } - v = new VarExp(0, fd->vresult); - exp = new AssignExp(loc, v, exp); + exp = new AssignExp(loc, new VarExp(0, fd->vresult), exp); exp = exp->semantic(sc); - s1 = new ExpStatement(loc, exp); - s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1)); + Statement *s1 = new ExpStatement(loc, exp); + Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1)); s = new CompoundStatement(loc, s1, s2); } return s; @@ -2959,9 +3023,10 @@ gs->label = fd->returnLabel; if (exp) - { Statement *s; - - s = new ExpStatement(0, exp); + { /* Replace: return exp; + * with: exp; goto returnLabel; + */ + Statement *s = new ExpStatement(0, exp); return new CompoundStatement(loc, s, gs); } return gs; @@ -3739,10 +3804,7 @@ * sexception: x = 1; * sfinally: if (!x) statement; */ - static int num; - char name[5 + sizeof(num) * 3 + 1]; - sprintf(name, "__osf%d", ++num); - Identifier *id = Lexer::idPool(name); + Identifier *id = Lexer::uniqueId("__os"); ExpInitializer *ie = new ExpInitializer(loc, new IntegerExp(0)); VarDeclaration *v = new VarDeclaration(loc, Type::tint32, id, ie);