comparison dmd/ForeachStatement.d @ 130:60bb0fe4563e

dmdfe 2.037 first main iteration
author Eldar Insafutdinov <e.insafutdinov@gmail.com>
date Thu, 09 Sep 2010 22:51:44 +0100
parents 1765f3ef917d
children af1bebfd96a4
comparison
equal deleted inserted replaced
129:010eb8f0e18d 130:60bb0fe4563e
62 import dmd.DotIdExp; 62 import dmd.DotIdExp;
63 import dmd.PostExp; 63 import dmd.PostExp;
64 import dmd.AddAssignExp; 64 import dmd.AddAssignExp;
65 import dmd.CmpExp; 65 import dmd.CmpExp;
66 import dmd.Id; 66 import dmd.Id;
67 import dmd.Argument; 67 import dmd.Parameter;
68 import dmd.STC; 68 import dmd.STC;
69 69
70 import dmd.expression.Util; 70 import dmd.expression.Util;
71 71
72 import core.stdc.stdio; 72 import core.stdc.stdio;
73 73
74 class ForeachStatement : Statement 74 class ForeachStatement : Statement
75 { 75 {
76 TOK op; // TOKforeach or TOKforeach_reverse 76 TOK op; // TOKforeach or TOKforeach_reverse
77 Arguments arguments; // array of Argument*'s 77 Parameters arguments; // array of Argument*'s
78 Expression aggr; 78 Expression aggr;
79 Statement body_; 79 Statement body_;
80 80
81 VarDeclaration key; 81 VarDeclaration key;
82 VarDeclaration value; 82 VarDeclaration value;
84 FuncDeclaration func; // function we're lexically in 84 FuncDeclaration func; // function we're lexically in
85 85
86 Array cases; // put breaks, continues, gotos and returns here 86 Array cases; // put breaks, continues, gotos and returns here
87 Array gotos; // forward referenced goto's go here 87 Array gotos; // forward referenced goto's go here
88 88
89 this(Loc loc, TOK op, Arguments arguments, Expression aggr, Statement body_) 89 this(Loc loc, TOK op, Parameters arguments, Expression aggr, Statement body_)
90 { 90 {
91 super(loc); 91 super(loc);
92 92
93 this.op = op; 93 this.op = op;
94 this.arguments = arguments; 94 this.arguments = arguments;
99 cases = new Array(); 99 cases = new Array();
100 } 100 }
101 101
102 override Statement syntaxCopy() 102 override Statement syntaxCopy()
103 { 103 {
104 Arguments args = Argument.arraySyntaxCopy(arguments); 104 auto args = Parameter.arraySyntaxCopy(arguments);
105 Expression exp = aggr.syntaxCopy(); 105 Expression exp = aggr.syntaxCopy();
106 ForeachStatement s = new ForeachStatement(loc, op, args, exp, 106 auto s = new ForeachStatement(loc, op, args, exp,
107 body_ ? body_.syntaxCopy() : null); 107 body_ ? body_.syntaxCopy() : null);
108 return s; 108 return s;
109 } 109 }
110 110
111 override Statement semantic(Scope sc) 111 override Statement semantic(Scope sc)
151 { 151 {
152 error("only one (value) or two (key,value) arguments for tuple foreach"); 152 error("only one (value) or two (key,value) arguments for tuple foreach");
153 return s; 153 return s;
154 } 154 }
155 155
156 TypeTuple tuple = cast(TypeTuple)tab; 156 auto tuple = cast(TypeTuple)tab;
157 Statements statements = new Statements(); 157 Statements statements = new Statements();
158 //printf("aggr: op = %d, %s\n", aggr.op, aggr.toChars()); 158 //printf("aggr: op = %d, %s\n", aggr.op, aggr.toChars());
159 size_t n; 159 size_t n;
160 TupleExp te = null; 160 TupleExp te = null;
161 if (aggr.op == TOK.TOKtuple) // expression tuple 161 if (aggr.op == TOK.TOKtuple) // expression tuple
163 te = cast(TupleExp)aggr; 163 te = cast(TupleExp)aggr;
164 n = te.exps.dim; 164 n = te.exps.dim;
165 } 165 }
166 else if (aggr.op == TOK.TOKtype) // type tuple 166 else if (aggr.op == TOK.TOKtype) // type tuple
167 { 167 {
168 n = Argument.dim(tuple.arguments); 168 n = Parameter.dim(tuple.arguments);
169 } 169 }
170 else 170 else
171 assert(0); 171 assert(0);
172 172
173 for (size_t j = 0; j < n; j++) 173 for (size_t j = 0; j < n; j++)
176 Expression e; 176 Expression e;
177 Type t; 177 Type t;
178 if (te) 178 if (te)
179 e = te.exps[k]; 179 e = te.exps[k];
180 else 180 else
181 t = Argument.getNth(tuple.arguments, k).type; 181 t = Parameter.getNth(tuple.arguments, k).type;
182 182
183 auto arg = arguments[0]; 183 auto arg = arguments[0];
184 auto st = new Statements(); 184 auto st = new Statements();
185 185
186 if (dim == 2) 186 if (dim == 2)
272 * array. 272 * array.
273 */ 273 */
274 tn = tab.nextOf().toBasetype(); 274 tn = tab.nextOf().toBasetype();
275 if (tn.ty == TY.Tchar || tn.ty == TY.Twchar || tn.ty == TY.Tdchar) 275 if (tn.ty == TY.Tchar || tn.ty == TY.Twchar || tn.ty == TY.Tdchar)
276 { 276 {
277 Argument arg; 277 Parameter arg;
278 278
279 int i = (dim == 1) ? 0 : 1; // index of value 279 int i = (dim == 1) ? 0 : 1; // index of value
280 arg = arguments[i]; 280 arg = arguments[i];
281 arg.type = arg.type.semantic(loc, sc); 281 arg.type = arg.type.semantic(loc, sc);
282 tnv = arg.type.toBasetype(); 282 tnv = arg.type.toBasetype();
530 } 530 }
531 case TY.Tdelegate: 531 case TY.Tdelegate:
532 Lapply: 532 Lapply:
533 { 533 {
534 FuncDeclaration fdapply; 534 FuncDeclaration fdapply;
535 Arguments args; 535 Parameters args;
536 Expression ec; 536 Expression ec;
537 Expression e; 537 Expression e;
538 FuncLiteralDeclaration fld; 538 FuncLiteralDeclaration fld;
539 Argument a; 539 Parameter a;
540 Type t; 540 Type t;
541 Expression flde; 541 Expression flde;
542 Identifier id; 542 Identifier id;
543 Type tret; 543 Type tret;
544 544
551 tret = func.type.nextOf(); 551 tret = func.type.nextOf();
552 552
553 // Need a variable to hold value from any return statements in body. 553 // Need a variable to hold value from any return statements in body.
554 if (!sc.func.vresult && tret && tret != Type.tvoid) 554 if (!sc.func.vresult && tret && tret != Type.tvoid)
555 { 555 {
556 VarDeclaration v = new VarDeclaration(loc, tret, Id.result, null); 556 auto v = new VarDeclaration(loc, tret, Id.result, null);
557 v.noauto = true; 557 v.noauto = true;
558 v.semantic(sc); 558 v.semantic(sc);
559 if (!sc.insert(v)) 559 if (!sc.insert(v))
560 assert(0); 560 assert(0);
561 561
564 } 564 }
565 565
566 /* Turn body into the function literal: 566 /* Turn body into the function literal:
567 * int delegate(ref T arg) { body } 567 * int delegate(ref T arg) { body }
568 */ 568 */
569 args = new Arguments(); 569 args = new Parameters();
570 for (size_t i = 0; i < dim; i++) 570 for (size_t i = 0; i < dim; i++)
571 { 571 {
572 auto arg = arguments[i]; 572 auto arg = arguments[i];
573 573
574 arg.type = arg.type.semantic(loc, sc); 574 arg.type = arg.type.semantic(loc, sc);
585 ie = new ExpInitializer(Loc(0), new IdentifierExp(Loc(0), id)); 585 ie = new ExpInitializer(Loc(0), new IdentifierExp(Loc(0), id));
586 v = new VarDeclaration(Loc(0), arg.type, arg.ident, ie); 586 v = new VarDeclaration(Loc(0), arg.type, arg.ident, ie);
587 s = new DeclarationStatement(Loc(0), v); 587 s = new DeclarationStatement(Loc(0), v);
588 body_ = new CompoundStatement(loc, s, body_); 588 body_ = new CompoundStatement(loc, s, body_);
589 } 589 }
590 a = new Argument(STC.STCref, arg.type, id, null); 590 a = new Parameter(STC.STCref, arg.type, id, null);
591 args.push(a); 591 args.push(a);
592 } 592 }
593 t = new TypeFunction(args, Type.tint32, 0, LINK.LINKd); 593 t = new TypeFunction(args, Type.tint32, 0, LINK.LINKd);
594 fld = new FuncLiteralDeclaration(loc, Loc(0), t, TOK.TOKdelegate, this); 594 fld = new FuncLiteralDeclaration(loc, Loc(0), t, TOK.TOKdelegate, this);
595 fld.fbody = body_; 595 fld.fbody = body_;
709 if (sapply && (td = sapply.isTemplateDeclaration()) !is null) 709 if (sapply && (td = sapply.isTemplateDeclaration()) !is null)
710 { 710 {
711 /* Call: 711 /* Call:
712 * aggr.apply!(fld)() 712 * aggr.apply!(fld)()
713 */ 713 */
714 TemplateInstance ti = new TemplateInstance(loc, idapply);
715 Objects tiargs = new Objects(); 714 Objects tiargs = new Objects();
716 tiargs.push(cast(void*)fld); 715 tiargs.push(cast(void*)fld);
717 ti.tiargs = tiargs; 716 ec = new DotTemplateInstanceExp(loc, aggr, idapply, tiargs);
718 ec = new DotTemplateInstanceExp(loc, aggr, ti);
719 } 717 }
720 else 718 else
721 { 719 {
722 /* Call: 720 /* Call:
723 * aggr.apply(flde) 721 * aggr.apply(flde)