Skip to content

Commit

Permalink
merge pull 320
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Aug 26, 2011
2 parents e3f1fa2 + 2dff8f3 commit 4eddacc
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 10 deletions.
75 changes: 65 additions & 10 deletions src/statement.c
Expand Up @@ -1789,10 +1789,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
if (!rinit) // if application of [] failed
rinit = aggr;
VarDeclaration *r = new VarDeclaration(loc, NULL, id, new ExpInitializer(loc, rinit));
// r->semantic(sc);
//printf("r: %s, init: %s\n", r->toChars(), r->init->toChars());
Statement *init = new ExpStatement(loc, r);
//printf("init: %s\n", init->toChars());

// !__r.empty
Expression *e = new VarExp(loc, r);
Expand All @@ -1808,16 +1805,70 @@ Statement *ForeachStatement::semantic(Scope *sc)
*/
e = new VarExp(loc, r);
Expression *einit = new DotIdExp(loc, e, idhead);
// einit = einit->semantic(sc);
Parameter *arg = arguments->tdata()[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 | STC_TYPECTOR);
Statement *makeargs;
if (dim == 1)
{
Parameter *arg = arguments->tdata()[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 | STC_TYPECTOR);

DeclarationExp *de = new DeclarationExp(loc, ve);
makeargs = new ExpStatement(loc, de);
}
else
{
Identifier *id = Lexer::uniqueId("__front");
ExpInitializer *ei = new ExpInitializer(loc, einit);
VarDeclaration *vd = new VarDeclaration(loc, NULL, id, ei);
vd->storage_class |= STCctfe | STCref | STCforeach;

Expression *de = new DeclarationExp(loc, vd);
makeargs = new ExpStatement(loc, de);

Expression *ve = new VarExp(loc, vd);
ve->type = shead->isDeclaration()->type;
if (ve->type->toBasetype()->ty == Tfunction)
ve->type = ve->type->toBasetype()->nextOf();
if (!ve->type || ve->type->ty == Terror)
goto Lrangeerr;

Expressions *exps = new Expressions();
exps->push(ve);
int pos = 0;
while (exps->dim < dim)
{
pos = expandAliasThisTuples(exps, pos);
if (pos == -1)
break;
}
if (exps->dim > dim)
goto Lrangeerr;

for (size_t i = 0; i < dim; i++)
{
Parameter *arg = arguments->tdata()[i];
Expression *exp = exps->tdata()[i];
#if 0
printf("[%d] arg = %s %s, exp = %s %s\n", i,
arg->type ? arg->type->toChars() : "?", arg->ident->toChars(),
exp->type->toChars(), exp->toChars());
#endif
if (arg->type && !exp->implicitConvTo(arg->type))
goto Lrangeerr;
if (!arg->type)
arg->type = exp->type;

VarDeclaration *var = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, exp));
var->storage_class |= STCctfe | STCref | STCforeach;
DeclarationExp *de = new DeclarationExp(loc, var);
makeargs = new CompoundStatement(loc, makeargs, new ExpStatement(loc, de));
}

DeclarationExp *de = new DeclarationExp(loc, ve);
}

Statement *body = new CompoundStatement(loc,
new ExpStatement(loc, de), this->body);
makeargs, this->body);

s = new ForStatement(loc, init, condition, increment, body);
#if 0
Expand All @@ -1828,6 +1879,10 @@ Statement *ForeachStatement::semantic(Scope *sc)
#endif
s = s->semantic(sc);
break;

Lrangeerr:
error("cannot infer argument types");
break;
}
#endif
case Tdelegate:
Expand Down
76 changes: 76 additions & 0 deletions test/runnable/aliasthis.d
Expand Up @@ -496,6 +496,81 @@ void test6434()
}

/**************************************/
// 6366

void test6366()
{
struct Zip
{
string str;
size_t i;
this(string s)
{
str = s;
}
@property const bool empty()
{
return i == str.length;
}
@property Tup!(size_t, char) front()
{
return typeof(return)(i, str[i]);
}
void popFront()
{
++i;
}
}

foreach (i, c; Zip("hello"))
{
switch (i)
{
case 0: assert(c == 'h'); break;
case 1: assert(c == 'e'); break;
case 2: assert(c == 'l'); break;
case 3: assert(c == 'l'); break;
case 4: assert(c == 'o'); break;
default:assert(0);
}
}

auto range(F...)(F field)
{
static struct Range {
F field;
bool empty = false;
Tup!F front() { return typeof(return)(field); }
void popFront(){ empty = true; }
}
return Range(field);
}

foreach (i, t; range(10, tup("str", [1,2]))){
static assert(is(typeof(i) == int));
static assert(is(typeof(t) == Tup!(string, int[])));
assert(i == 10);
assert(t == tup("str", [1,2]));
}
auto r1 = range(10, "str", [1,2]);
auto r2 = range(tup(10, "str"), [1,2]);
auto r3 = range(10, tup("str", [1,2]));
auto r4 = range(tup(10, "str", [1,2]));
alias Seq!(r1, r2, r3, r4) ranges;
foreach (n, _; ranges)
{
foreach (i, s, a; ranges[n]){
static assert(is(typeof(i) == int));
static assert(is(typeof(s) == string));
static assert(is(typeof(a) == int[]));
assert(i == 10);
assert(s == "str");
assert(a == [1,2]);
}
}
}

/**********************************************/

int main()
{
Expand All @@ -517,6 +592,7 @@ int main()
test6369c();
test6369d();
test6434();
test6366();

printf("Success\n");
return 0;
Expand Down

0 comments on commit 4eddacc

Please sign in to comment.