root/trunk/docsrc/statement.dd

Revision 2347, 40.9 kB (checked in by Don Clugston, 1 year ago)

spec: can only throw Throwables.

  • Property svn:eol-style set to native
Line 
1 Ddoc
2
3 $(SPEC_S Statements,
4
5 C and C++ programmers will find the D statements very familiar, with a few
6 interesting additions.
7
8 $(GRAMMAR
9 $(GNAME Statement):
10     $(B ;)
11     $(GLINK NonEmptyStatement)
12     $(GLINK ScopeBlockStatement)
13
14 $(GNAME NoScopeNonEmptyStatement):
15     $(GLINK NonEmptyStatement)
16     $(GLINK BlockStatement)
17
18 $(GNAME NoScopeStatement):
19     $(B ;)
20     $(GLINK NonEmptyStatement)
21     $(GLINK BlockStatement)
22
23 $(GNAME NonEmptyOrScopeBlockStatement):
24     $(GLINK NonEmptyStatement)
25     $(GLINK ScopeBlockStatement)
26
27 $(GNAME NonEmptyStatement):
28     $(GLINK NonEmptyStatementNoCaseNoDefault)
29     $(GLINK CaseStatement)
30 $(V2      $(GLINK CaseRangeStatement)
31 )    $(GLINK DefaultStatement)
32
33 $(GNAME NonEmptyStatementNoCaseNoDefault):
34     $(GLINK LabeledStatement)
35     $(GLINK ExpressionStatement)
36     $(GLINK DeclarationStatement)
37     $(GLINK IfStatement)
38     $(GLINK WhileStatement)
39     $(GLINK DoStatement)
40     $(GLINK ForStatement)
41     $(GLINK ForeachStatement)
42     $(GLINK SwitchStatement)
43 $(V2      $(GLINK FinalSwitchStatement)
44 )    $(GLINK ContinueStatement)
45     $(GLINK BreakStatement)
46     $(GLINK ReturnStatement)
47     $(GLINK GotoStatement)
48     $(GLINK WithStatement)
49     $(GLINK SynchronizedStatement)
50     $(GLINK TryStatement)
51     $(GLINK ScopeGuardStatement)
52     $(GLINK ThrowStatement)
53 $(V1    $(GLINK VolatileStatement)
54 )    $(GLINK AsmStatement)
55     $(GLINK PragmaStatement)
56     $(GLINK MixinStatement)
57 $(V2      $(GLINK ForeachRangeStatement))
58     $(LINK2 version.html#ConditionalStatement, $(I ConditionalStatement))
59     $(LINK2 version.html#StaticAssert, $(I StaticAssert))
60     $(LINK2 template-mixin.html#TemplateMixin, $(I TemplateMixin))
61 )
62
63
64     $(P Any ambiguities in the grammar between $(I Statement)s and
65     $(GLINK2 declaration, Declaration)s are
66     resolved by the declarations taking precedence.
67     If a $(I Statement) is desired instead, wrapping it in parentheses will
68     disambiguate it in favor of being a $(I Statement).
69     )
70
71 <h2>$(LNAME2 ScopeStatement, Scope Statements)</h2>
72
73 $(GRAMMAR
74 $(I ScopeStatement):
75     $(GLINK NonEmptyStatement)
76     $(GLINK BlockStatement)
77 )
78
79     $(P A new scope for local symbols
80     is introduced for the $(I NonEmptyStatement)
81     or $(GLINK BlockStatement).
82     )
83
84     $(P Even though a new scope is introduced,
85     local symbol declarations cannot shadow (hide) other
86     local symbol declarations in the same function.
87     )
88
89 --------------
90 void func1(int x)
91 {   int x;  // illegal, x shadows parameter x
92
93     int y;
94
95     { int y; }  // illegal, y shadows enclosing scope's y
96
97     void delegate() dg;
98     dg = { int y; };    // ok, this y is not in the same function
99
100     struct S
101     {
102     int y;      // ok, this y is a member, not a local
103     }
104
105     { int z; }
106     { int z; }  // ok, this z is not shadowing the other z
107
108     { int t; }
109     { t++;   }  // illegal, t is undefined
110 }
111 --------------
112
113 $(P
114     The idea is to avoid bugs in complex functions caused by
115     scoped declarations inadvertently hiding previous ones.
116     Local names should all be unique within a function.
117 )
118
119
120 <h2>$(LNAME2 ScopeBlockStatement, Scope Block Statements)</h2>
121
122 $(GRAMMAR
123 $(I ScopeBlockStatement):
124     $(GLINK BlockStatement)
125 )
126
127     $(P A scope block statement introduces a new scope for the
128     $(GLINK BlockStatement).
129     )
130
131 <h2>$(LNAME2 LabeledStatement, Labeled Statements)</h2>
132
133 $(P Statements can be labeled. A label is an identifier that
134     precedes a statement.
135 )
136
137 $(GRAMMAR
138 $(I LabeledStatement):
139     $(I Identifier) : $(PSSEMI)
140 )
141
142 $(P
143     Any statement can be labeled, including empty statements,
144     and so can serve as the target
145     of a goto statement. Labeled statements can also serve as the
146     target of a break or continue statement.
147 )
148 $(P
149     Labels are in a name space independent of declarations, variables,
150     types, etc.
151     Even so, labels cannot have the same name as local declarations.
152     The label name space is the body of the function
153     they appear in. Label name spaces do not nest, i.e. a label
154     inside a block statement is accessible from outside that block.
155 )
156
157 <h2>$(LNAME2 BlockStatement, Block Statement)</h2>
158
159 $(GRAMMAR
160 $(I BlockStatement):
161     $(B { })
162     $(B {) $(I StatementList) $(B })
163
164 $(GNAME StatementList):
165     $(PSSEMI_PSCURLYSCOPE)
166     $(PSSEMI_PSCURLYSCOPE) $(I StatementList)
167 )
168
169 $(P
170     A block statement is a sequence of statements enclosed
171     by { }. The statements are executed in lexical order.
172 )
173 <h2>$(LNAME2 ExpressionStatement, Expression Statement)</h2>
174
175 $(GRAMMAR
176 $(I ExpressionStatement):
177     $(EXPRESSION) $(B ;)
178 )
179
180     The expression is evaluated.
181     <p>
182
183     Expressions that have no effect, like $(TT (x + x)),
184     are illegal
185     in expression statements.
186     If such an expression is needed, casting it to $(D_KEYWORD void) will
187     make it legal.
188
189 ----
190 int x;
191 x++;                // ok
192 x;                  // illegal
193 1+1;                // illegal
194 cast(void)(x + x);  // ok
195 ----
196
197 <h2>$(LNAME2 DeclarationStatement, Declaration Statement)</h2>
198
199     Declaration statements declare variables and types.
200
201 $(GRAMMAR
202 $(I DeclarationStatement):
203     $(I Declaration)
204 )
205
206     $(P Some declaration statements:)
207
208 ----
209 int a;       // declare a as type int and initialize it to 0
210 struct S { }     // declare struct s
211 alias int myint;
212 ----
213
214 <h2>$(LNAME2 IfStatement, If Statement)</h2>
215
216     If statements provide simple conditional execution of statements.
217
218 $(GRAMMAR
219 $(I IfStatement):
220     $(B if $(LPAREN)) $(I IfCondition) $(B $(RPAREN)) $(I ThenStatement)
221     $(B if $(LPAREN)) $(I IfCondition) $(B $(RPAREN)) $(I ThenStatement) $(B else) $(I ElseStatement)
222
223 $(GNAME IfCondition):
224     $(EXPRESSION)
225     $(B auto) $(I Identifier) $(B =) $(EXPRESSION)
226     $(GLINK2 declaration, BasicType) $(GLINK2 declaration, Declarator) $(B =) $(EXPRESSION)
227
228 $(GNAME ThenStatement):
229     $(PSSCOPE)
230
231 $(GNAME ElseStatement):
232     $(PSSCOPE)
233 )
234
235     $(EXPRESSION) is evaluated and must have a type that
236     can be converted to a boolean. If it's true the
237     $(I ThenStatement) is transferred to, else the $(I ElseStatement)
238     is transferred to.
239     <p>
240
241     The 'dangling else' parsing problem is solved by associating the
242     else with the nearest if statement.
243     <p>
244
245     If an $(B auto) $(I Identifier) is provided, it is declared and
246     initialized
247     to the value
248     and type of the $(EXPRESSION). Its scope extends from when it is
249     initialized to the end of the $(I ThenStatement).
250     <p>
251
252     If a $(I Declarator) is provided, it is declared and
253     initialized
254     to the value
255     of the $(EXPRESSION). Its scope extends from when it is
256     initialized to the end of the $(I ThenStatement).
257
258 ---
259 import std.regexp;
260 ...
261 if (auto m = std.regexp.search("abcdef", "b(c)d"))
262 {
263     writefln("[%s]", m.pre);      // prints [a]
264     writefln("[%s]", m.post);     // prints [ef]
265     writefln("[%s]", m.match(0)); // prints [bcd]
266     writefln("[%s]", m.match(1)); // prints [c]
267     writefln("[%s]", m.match(2)); // prints []
268 }
269 else
270 {
271     writefln(m.post);    // error, m undefined
272 }
273 writefln(m.pre);         // error, m undefined
274 ---
275
276 <h2>$(LNAME2 WhileStatement, While Statement)</h2>
277
278 $(GRAMMAR
279 $(I WhileStatement):
280     $(B while $(LPAREN)) $(EXPRESSION) $(B $(RPAREN)) $(PSSCOPE)
281 )
282
283     While statements implement simple loops.
284
285     $(EXPRESSION) is evaluated and must have a type that
286     can be converted to a boolean. If it's true the
287     $(PSSCOPE) is executed. After the $(PSSCOPE) is executed,
288     the $(EXPRESSION) is evaluated again, and if true the
289     $(PSSCOPE) is executed again. This continues until the
290     $(EXPRESSION) evaluates to false.
291
292 ---
293 int i = 0;
294 while (i < 10)
295 {
296     foo(i);
297     i++;
298 }
299 ---
300
301     A $(GLINK BreakStatement) will exit the loop.
302     A $(GLINK ContinueStatement)
303     will transfer directly to evaluating $(EXPRESSION) again.
304
305 <h2>$(LNAME2 DoStatement, Do Statement)</h2>
306
307 $(GRAMMAR
308 $(I DoStatement):
309     $(B do) $(PSSCOPE) $(B  while $(LPAREN)) $(EXPRESSION) $(B $(RPAREN))
310 )
311
312     Do while statements implement simple loops.
313
314     $(PSSCOPE) is executed. Then
315     $(EXPRESSION) is evaluated and must have a type that
316     can be converted to a boolean. If it's true the
317     loop is iterated again.
318     This continues until the
319     $(EXPRESSION) evaluates to false.
320
321 ---
322 int i = 0;
323 do
324 {
325     foo(i);
326 } while (++i < 10);
327 ---
328
329     A $(GLINK BreakStatement) will exit the loop.
330     A $(GLINK ContinueStatement)
331     will transfer directly to evaluating $(EXPRESSION) again.
332
333 <h2>$(LNAME2 ForStatement, For Statement)</h2>
334
335     For statements implement loops with initialization,
336     test, and increment clauses.
337
338 $(GRAMMAR
339 $(I ForStatement):
340     $(B for $(LPAREN))$(I Initialize) $(I Test)$(OPT) $(B ;) $(I Increment)$(OPT)$(B $(RPAREN)) $(PSSCOPE)
341
342 $(GNAME Initialize):
343     $(B ;)
344     $(PS0)
345
346 $(GNAME Test):
347     $(EXPRESSION)
348
349 $(GNAME Increment):
350     $(EXPRESSION)
351 )
352
353     $(P $(I Initialize) is executed.
354     $(I Test) is evaluated and must have a type that
355     can be converted to a boolean. If it's true the
356     statement is executed. After the statement is executed,
357     the $(I Increment) is executed.
358     Then $(I Test) is evaluated again, and if true the
359     statement is executed again. This continues until the
360     $(I Test) evaluates to false.
361     )
362
363     $(P A $(GLINK BreakStatement) will exit the loop.
364     A $(GLINK ContinueStatement)
365     will transfer directly to the $(I Increment).
366     )
367
368     $(P A $(I ForStatement) creates a new scope.
369     If $(I Initialize) declares a variable, that variable's scope
370     extends through the end of the for statement. For example:
371     )
372
373 --------------
374 for (int i = 0; i < 10; i++)
375     foo(i);
376 --------------
377
378     is equivalent to:
379
380 --------------
381 {   int i;
382     for (i = 0; i < 10; i++)
383     foo(i);
384 }
385 --------------
386
387     Function bodies cannot be empty:
388
389 --------------
390 for (int i = 0; i < 10; i++)
391     ;   // illegal
392 --------------
393
394     Use instead:
395
396 --------------
397 for (int i = 0; i < 10; i++)
398 {
399 }
400 --------------
401
402     The $(I Initialize) may be omitted. $(I Test) may also be
403     omitted, and if so, it is treated as if it evaluated to true.
404
405 <h2>$(LNAME2 ForeachStatement, Foreach Statement)</h2>
406
407     A foreach statement loops over the contents of an aggregate.
408
409 $(GRAMMAR
410 $(I ForeachStatement):
411     $(I Foreach) $(B $(LPAREN))$(I ForeachTypeList) $(B ;) $(I Aggregate)$(B $(RPAREN)) $(PS0)
412
413 $(GNAME Foreach):
414     $(B foreach)
415     $(B foreach_reverse)
416
417 $(GNAME ForeachTypeList):
418     $(I ForeachType)
419     $(I ForeachType) , $(I ForeachTypeList)
420
421 $(GNAME ForeachType):
422     $(B ref) $(GLINK2 declaration, BasicType) $(GLINK2 declaration, Declarator)
423     $(GLINK2 declaration, BasicType) $(GLINK2 declaration, Declarator)
424     $(B ref) $(I Identifier)
425     $(I Identifier)
426
427 $(GNAME Aggregate):
428     $(EXPRESSION)
429 )
430
431 $(P
432     $(I Aggregate) is evaluated. It must evaluate to an expression
433     of type static array, dynamic array, associative array,
434     struct, class, delegate, or tuple.
435     The $(PS0) is executed, once for each element of the
436     aggregate.
437     At the start of each iteration, the variables declared by
438     the $(I ForeachTypeList)
439     are set to be a copy of the elements of the aggregate.
440     If the variable is $(B ref), it is a reference to the
441     contents of that aggregate.
442 )
443 $(P
444     The aggregate must be loop invariant, meaning that
445     elements to the aggregate cannot be added or removed from it
446     in the $(PS0).
447 )
448
449 <h3>Foreach over Arrays</h3>
450
451 $(P
452     If the aggregate is a static or dynamic array, there
453     can be one or two variables declared. If one, then the variable
454     is said to be the $(I value) set to the elements of the array,
455     one by one. The type of the
456     variable must match the type of the array contents, except for the
457     special cases outlined below.
458     If there are
459     two variables declared, the first is said to be the $(I index)
460     and the second is said to be the $(I value). The $(I index)
461     must be of $(B int), $(B uint) or $(B size_t) type,
462     it cannot be $(I ref),
463     and it is set to be the index of the array element.
464 )
465 --------------
466 char[] a;
467 ...
468 foreach (int i, char c; a)
469 {
470     writefln("a[%d] = '%c'", i, c);
471 }
472 --------------
473
474     $(P For $(B foreach), the
475     elements for the array are iterated over starting at index 0
476     and continuing to the maximum of the array.
477     For $(B foreach_reverse), the array elements are visited in the reverse
478     order.
479     )
480
481 <h3>Foreach over Arrays of Characters</h3>
482
483     $(P If the aggregate expression is a static or dynamic array of
484     $(B char)s, $(B wchar)s, or $(B dchar)s, then the $(I Type) of
485     the $(I value)
486     can be any of $(B char), $(B wchar), or $(B dchar).
487     In this manner any UTF array
488     can be decoded into any UTF type:
489     )
490
491 --------------
492 char[] a = "\xE2\x89\xA0";  // \u2260 encoded as 3 UTF-8 bytes
493
494 foreach (dchar c; a)
495 {
496     writefln("a[] = %x", c);    // prints 'a[] = 2260'
497 }
498
499 dchar[] b = "\u2260";
500
501 foreach (char c; b)
502 {
503     writef("%x, ", c);  // prints 'e2, 89, a0, '
504 }
505 --------------
506
507
508     $(P Aggregates can be string literals, which can be accessed
509     as char, wchar, or dchar arrays:
510     )
511
512 --------------
513 void test()
514 {
515     foreach (char c; "ab")
516     {
517     writefln("'%s'", c);
518     }
519     foreach (wchar w; "xy")
520     {
521     writefln("'%s'", w);
522     }
523 }
524 --------------
525
526     $(P which would print:
527     )
528
529 $(CONSOLE
530 'a'
531 'b'
532 'x'
533 'y'
534 )
535
536 <h3>Foreach over Associative Arrays</h3>
537
538     $(P If the aggregate expression is an associative array, there
539     can be one or two variables declared. If one, then the variable
540     is said to be the $(I value) set to the elements of the array,
541     one by one. The type of the
542     variable must match the type of the array contents. If there are
543     two variables declared, the first is said to be the $(I index)
544     and the second is said to be the $(I value). The $(I index)
545     must be of the same type as the indexing type of the associative
546     array. It cannot be $(I ref),
547     and it is set to be the index of the array element.
548     The order in which the elements of the array is unspecified
549     for $(B foreach). $(B foreach_reverse) for associative arrays
550     is illegal.
551     )
552
553 --------------
554 double[char[]] a;   // $(I index) type is char[], $(I value) type is double
555 ...
556 foreach (char[] s, double d; a)
557 {
558     writefln("a['%s'] = %g", s, d);
559 }
560 --------------
561
562 $(V2
563 <h3>$(LNAME2 foreach_with_ranges, Foreach over Structs and Classes with Ranges)</h3>
564
565     $(P Iteration over struct and class objects can be done with
566     ranges, which means the following properties must be defined:
567     )
568
569     $(TABLE2 Foreach Range Properties,
570     $(TR $(TH Property) $(TH Purpose ))
571     $(TR $(TD $(TT .empty)) $(TD returns true if no more elements))
572     $(TR $(TD $(TT .popFront)) $(TD move the left edge of the range right one))
573     $(TR $(TD $(TT .popBack)) $(TD move the right edge of the range left one))
574     $(TR $(TD $(TT .front)) $(TD return the leftmost element of the range))
575     $(TR $(TD $(TT .back)) $(TD return the rightmost element of the range))
576     )
577
578     $(P Meaning:)
579
580 ---
581 foreach (e; range) { ... }
582 ---
583
584     $(P translates to:)
585
586 ---
587 for (auto __r = range; !__r.empty; __r.next)
588 {   auto e = __r.head;
589    ...
590 }
591 ---
592
593     $(P Similarly:)
594
595 ---
596 foreach_reverse (e; range) { ... }
597 ---
598
599     $(P translates to:)
600
601 ---
602 for (auto __r = range; !__r.empty; __r.retreat)
603 {   auto e = __r.toe;
604    ...
605 }
606 ---
607
608     $(P If the foreach range properties do not exist, the $(TT opApply)
609     method will be used instead.
610     )
611 )
612
613 <h3>Foreach over Structs and Classes with opApply</h3>
614
615     $(P
616     If it is a struct or class object, the $(B foreach) is defined by
617     the special $(LNAME2 #opApply, $(I opApply)) member function.
618     The $(B foreach_reverse) behavior is defined by the special
619     $(LNAME2 opApplyReverse, $(I opApplyReverse)) member function.
620     These special functions must be defined by the type in order
621     to use the corresponding foreach statement.
622     The functions have the type:
623     )
624
625 --------------
626 int $(B opApply)(int delegate(ref $(I Type) [, ...]) $(I dg));
627
628 int $(B opApplyReverse)(int delegate(ref $(I Type) [, ...]) $(I dg));
629 --------------
630
631     $(P where $(I Type) matches the $(I Type) used in the $(I ForeachType)
632     declaration of $(I Identifier). Multiple $(I ForeachType)s
633     correspond with multiple $(I Type)'s in the delegate type
634     passed to $(B opApply) or $(B opApplyReverse).
635     There can be multiple $(B opApply) and $(B opApplyReverse) functions,
636     one is selected
637     by matching the type of $(I dg) to the $(I ForeachType)s
638     of the $(I ForeachStatement).
639     The body of the apply
640     function iterates over the elements it aggregates, passing them
641     each to the $(I dg) function. If the $(I dg) returns 0, then
642     apply goes on to the next element.
643     If the $(I dg) returns a nonzero value, apply must cease
644     iterating and return that value. Otherwise, after done iterating
645     across all the elements, apply will return 0.
646     )
647
648     $(P For example, consider a class that is a container for two elements:
649     )
650
651 --------------
652 class Foo
653 {
654     uint array[2];
655
656     int $(B opApply)(int delegate(ref uint) $(I dg))
657     {   int result = 0;
658
659     for (int i = 0; i < array.length; i++)
660     {
661         result = $(I dg)(array[i]);
662         if (result)
663         break;
664     }
665     return result;
666     }
667 }
668 --------------
669
670     An example using this might be:
671
672 --------------
673 void test()
674 {
675     Foo a = new Foo();
676
677     a.array[0] = 73;
678     a.array[1] = 82;
679
680     foreach (uint u; a)
681     {
682     writefln("%d", u);
683     }
684 }
685 --------------
686
687     which would print:
688
689 $(CONSOLE
690 73
691 82
692 )
693
694 <h3>Foreach over Delegates</h3>
695
696     $(P If $(I Aggregate) is a delegate, the type signature of
697     the delegate is of the same as for $(B opApply). This enables
698     many different named looping strategies to coexist in the same
699     class or struct.)
700
701 <h3>Foreach over Tuples</h3>
702
703 $(P
704     If the aggregate expression is a tuple, there
705     can be one or two variables declared. If one, then the variable
706     is said to be the $(I value) set to the elements of the tuple,
707     one by one. If the type of the
708     variable is given, it must match the type of the tuple contents.
709     If it is not given, the type of the variable is set to the type
710     of the tuple element, which may change from iteration to iteration.
711     If there are
712     two variables declared, the first is said to be the $(I index)
713     and the second is said to be the $(I value). The $(I index)
714     must be of $(B int) or $(B uint) type, it cannot be $(I ref),
715     and it is set to be the index of the tuple element.
716 )
717
718 $(P
719     If the tuple is a list of types, then the foreach statement
720     is executed once for each type, and the value is aliased to that
721     type.
722 )
723
724 -----
725 import std.stdio;
726 import std.typetuple;   // for TypeTuple
727
728 void main()
729 {
730     alias TypeTuple!(int, long, double) TL;
731
732     foreach (T; TL)
733     {
734     writefln(typeid(T));
735     }
736 }
737 -----
738
739     $(P Prints:)
740
741 $(CONSOLE
742 int
743 long
744 double
745 )
746
747 <h3>Foreach Ref Parameters</h3>
748
749     $(P $(B ref) can be used to update the original elements:
750     )
751
752 --------------
753 void test()
754 {
755     static uint[2] a = [7, 8];
756
757     foreach (ref uint u; a)
758     {
759     u++;
760     }
761     foreach (uint u; a)
762     {
763     writefln("%d", u);
764     }
765 }
766 --------------
767
768     which would print:
769
770 $(CONSOLE
771 8
772 9
773 )
774     $(P $(B ref) can not be applied to the index values.)
775
776     $(P If not specified, the $(I Type)s in the $(I ForeachType) can be
777     inferred from
778     the type of the $(I Aggregate).
779     )
780
781 <h3>Foreach Restrictions</h3>
782
783     $(P The aggregate itself must not be resized, reallocated, free'd,
784     reassigned or destructed
785     while the foreach is iterating over the elements.
786     )
787
788 --------------
789 int[] a;
790 int[] b;
791 foreach (int i; a)
792 {
793     a = null;           // error
794     a.length = a.length + 10;   // error
795     a = b;          // error
796 }
797 a = null;           // ok
798 --------------
799
800 <h3>Break and Continue out of Foreach</h3>
801
802
803     $(P A $(GLINK BreakStatement) in the body of the foreach will exit the
804     foreach, a $(GLINK ContinueStatement) will immediately start the
805     next iteration.
806     )
807
808 <h2>$(LNAME2 SwitchStatement, Switch Statement)</h2>
809
810     A switch statement goes to one of a collection of case
811     statements depending on the value of the switch
812     expression.
813
814 $(GRAMMAR
815 $(I SwitchStatement):
816     $(B switch $(LPAREN)) $(EXPRESSION) $(B $(RPAREN)) $(PSSCOPE)
817
818 $(GNAME CaseStatement):
819     $(B case) $(LINK2 expression.html#ArgumentList, $(I ArgumentList)) $(B :) $(PSSEMI_PSCURLYSCOPE_LIST)
820
821 $(V2 $(GNAME CaseRangeStatement):
822     $(B case) $(I FirstExp) $(B : .. case) $(I LastExp) $(B :) $(PSSEMI_PSCURLYSCOPE_LIST)
823
824 $(I FirstExp):
825     $(ASSIGNEXPRESSION)
826
827 $(I LastExp):
828     $(ASSIGNEXPRESSION)
829 )
830 $(GNAME DefaultStatement):
831     $(B default :) $(PSSEMI_PSCURLYSCOPE_LIST)
832
833 $(GNAME ScopeStatementList):
834     $(GLINK StatementListNoCaseNoDefault)
835
836 $(GNAME StatementListNoCaseNoDefault):
837     $(GLINK StatementNoCaseNoDefault)
838     $(GLINK StatementNoCaseNoDefault) $(I StatementListNoCaseNoDefault)
839
840 $(GNAME StatementNoCaseNoDefault):
841     $(B ;)
842     $(GLINK NonEmptyStatementNoCaseNoDefault)
843     $(GLINK ScopeBlockStatement)
844 )
845
846     $(P $(EXPRESSION) is evaluated. The result type T must be
847     of integral type or $(CODE char[]), $(CODE wchar[]) or $(CODE dchar[]).
848     The result is
849     compared against each of the case expressions. If there is
850     a match, the corresponding case statement is transferred to.
851     )
852
853     $(P The case expressions, $(LINK2 expression.html#ArgumentList, $(I ArgumentList)),
854     are a comma separated list of expressions.
855     )
856
857 $(V2
858     $(P A $(I CaseRangeStatement) is a shorthand for listing a series
859     of case statements from $(I FirstExp) to $(I LastExp).
860     )
861 )
862
863     $(P If none of the case expressions match, and there is a default
864     statement, the default statement is transferred to.
865     )
866
867     $(P If none of the case expressions match, and there is not a default
868     statement, a
869     $(LINK2 phobos/std_switcherr.html, $(CODE std.switcherr.SwitchError))
870     is thrown.
871     The reason for this is
872     to catch the common programming error of adding a new value to
873     an enum, but failing to account for the extra value in
874     switch statements. This behavior is unlike C or C++.
875     )
876
877     $(P
878 $(V1
879     The case expressions must all evaluate to a constant value
880     or array.
881 )
882 $(V2
883     The case expressions must all evaluate to a constant value
884     or array, or a runtime initialized const or immutable variable of
885     integral type.
886 )
887     They must be implicitly convertible to the type of the
888     switch $(EXPRESSION).
889     )
890
891     $(P Case expressions must all evaluate to distinct values.
892 $(V2
893     Const or immutable variables must all have different names.
894     If they share a value, the first case statement with that value
895     gets control.
896 )
897     There may not be two or more default statements.
898     )
899
900     $(P The $(GLINK ScopeStatementList) introduces a new scope.
901     )
902
903     $(P Case statements and default statements associated with the switch
904     can be nested within block statements; they do not have to be in
905     the outermost block. For example, this is allowed:
906     )
907
908 --------------
909     switch (i)
910     {
911     case 1:
912     {
913         case 2:
914     }
915         break;
916     }
917 --------------
918
919     $(P Case statements 'fall through' to subsequent
920     case values. A break statement will exit the switch $(I BlockStatement).
921     For example:
922     )
923
924 --------------
925 switch (i)
926 {
927     case 1:
928     x = 3;
929     case 2:
930     x = 4;
931     break;
932
933     case 3,4,5:
934     x = 5;
935     break;
936 }
937 --------------
938
939     $(P will set $(CODE x) to $(CODE 4) if $(CODE i) is $(CODE 1).
940     )
941
942     $(P $(LNAME2 string-switch, Strings can be used in switch expressions).
943     For example:
944     )
945
946 --------------
947 char[] name;
948 ...
949 switch (name)
950 {
951     case "fred":
952     case "sally":
953     ...
954 }
955 --------------
956
957     $(P For applications like command line switch processing, this
958     can lead to much more straightforward code, being clearer and
959     less error prone. char, wchar and dchar strings are allowed.
960     )
961
962     $(P $(B Implementation Note:) The compiler's code generator may
963     assume that the case
964     statements are sorted by frequency of use, with the most frequent
965     appearing first and the least frequent last. Although this is
966     irrelevant as far as program correctness is concerned, it is of
967     performance interest.
968     )
969
970 $(V2
971 <h2>$(LNAME2 FinalSwitchStatement, Final Switch Statement)</h2>
972
973 $(GRAMMAR
974 $(I FinalSwitchStatement):
975     $(B final switch $(LPAREN)) $(EXPRESSION) $(B $(RPAREN)) $(PSSCOPE)
976 )
977
978     $(P A final switch statement is just like a switch statement,
979     except that:)
980
981     $(UL
982     $(LI No $(GLINK DefaultStatement) is allowed.)
983     $(LI No $(GLINK CaseRangeStatement)s are allowed.)
984     $(LI If the switch $(EXPRESSION) is of enum type, all
985     the enum members must appear in the $(GLINK CaseStatement)s.)
986     $(LI The case expressions cannot evaluate to a run time
987     initialized value.)
988     )
989
990 )
991
992 <h2>$(LNAME2 ContinueStatement, Continue Statement)</h2>
993
994 $(GRAMMAR
995 $(I ContinueStatement):
996     $(B continue;)
997     $(B continue) $(I Identifier) $(B ;)
998 )
999
1000     A continue aborts the current iteration of its enclosing loop
1001     statement, and starts the next iteration.
1002
1003     continue executes the next iteration of its innermost enclosing
1004     while, for, foreach, or do loop. The increment clause is executed.
1005     <p>
1006
1007     If continue is followed by $(I Identifier), the $(I Identifier)
1008     must be the label of an enclosing while, for, or do
1009     loop, and the next iteration of that loop is executed.
1010     It is an error if
1011     there is no such statement.
1012     <p>
1013
1014     Any intervening finally clauses are executed, and any intervening
1015     synchronization objects are released.
1016     <p>
1017
1018     $(B Note:) If a finally clause executes a return, throw, or goto
1019     out of the finally clause,
1020     the continue target is never reached.
1021
1022 ---
1023 for (i = 0; i < 10; i++)
1024 {
1025     if (foo(i))
1026     continue;
1027     bar();
1028 }
1029 ---
1030
1031 <h2>$(LNAME2 BreakStatement, Break Statement)</h2>
1032
1033 $(GRAMMAR
1034 $(I BreakStatement):
1035     $(B break;)
1036     $(B break) $(I Identifier) $(B ;)
1037 )
1038
1039     A break exits the enclosing statement.
1040
1041     break exits the innermost enclosing while, for, foreach, do, or switch
1042     statement, resuming execution at the statement following it.
1043     <p>
1044
1045     If break is followed by $(I Identifier), the $(I Identifier)
1046     must be the label of an enclosing while, for, do or switch
1047     statement, and that statement is exited. It is an error if
1048     there is no such statement.
1049     <p>
1050
1051     Any intervening finally clauses are executed, and any intervening
1052     synchronization objects are released.
1053     <p>
1054
1055     $(B Note:) If a finally clause executes a return, throw, or goto
1056     out of the finally clause,
1057     the break target is never reached.
1058
1059 ---
1060 for (i = 0; i < 10; i++)
1061 {
1062     if (foo(i))
1063     break;
1064 }
1065 ---
1066
1067 <h2>$(LNAME2 ReturnStatement, Return Statement)</h2>
1068
1069 $(GRAMMAR
1070 $(I ReturnStatement):
1071     $(B return;)
1072     $(B return) $(EXPRESSION) $(B ;)
1073 )
1074
1075     A return exits the current function and supplies its return
1076     value.
1077
1078     $(EXPRESSION) is required if the function specifies
1079     a return type that is not void.
1080     The $(EXPRESSION) is implicitly converted to the
1081     function return type.
1082     <p>
1083
1084     At least one return statement, throw statement, or assert(0) expression
1085     is required if the function specifies a return type that is not void,
1086     unless the function contains inline assembler code.
1087     <p>
1088
1089     $(EXPRESSION) is allowed even if the function specifies
1090     a $(D_KEYWORD void) return type. The $(EXPRESSION) will be evaluated,
1091     but nothing will be returned.
1092     If the $(EXPRESSION) has no side effects, and the return
1093     type is $(D_KEYWORD void), then it is illegal.
1094     <p>
1095
1096     Before the function actually returns,
1097     any objects with scope storage duration are destroyed,
1098     any enclosing finally clauses are executed,
1099     any scope(exit) statements are executed,
1100     any scope(success) statements are executed,
1101     and any enclosing synchronization
1102     objects are released.
1103     <p>
1104
1105     The function will not return if any enclosing finally clause
1106     does a return, goto or throw that exits the finally clause.
1107     <p>
1108
1109     If there is an out postcondition
1110     (see $(LINK2 dbc.html, Contract Programming)),
1111     that postcondition is executed
1112     after the $(EXPRESSION) is evaluated and before the function
1113     actually returns.
1114
1115 ---
1116 int foo(int x)
1117 {
1118     return x + 3;
1119 }
1120 ---
1121
1122 <h2>$(LNAME2 GotoStatement, Goto Statement)</h2>
1123
1124 $(GRAMMAR
1125 $(I GotoStatement):
1126     $(B goto) $(I Identifier) $(B ;)
1127     $(B goto) $(B default) $(B ;)
1128     $(B goto) $(B case) $(B ;)
1129     $(B goto) $(B case) $(EXPRESSION) $(B ;)
1130 )
1131
1132     A goto transfers to the statement labeled with
1133     $(I Identifier).
1134
1135 ---
1136     if (foo)
1137     goto L1;
1138     x = 3;
1139 L1:
1140     x++;
1141 ---
1142
1143     The second form, $(CODE goto default;), transfers to the
1144     innermost $(GLINK DefaultStatement) of an enclosing
1145     $(GLINK SwitchStatement).
1146     <p>
1147
1148     The third form, $(CODE goto case;), transfers to the
1149     next $(GLINK CaseStatement) of the innermost enclosing
1150     $(I SwitchStatement).
1151     <p>
1152
1153     The fourth form, $(CODE goto case $(EXPRESSION);), transfers to the
1154     $(GLINK CaseStatement) of the innermost enclosing
1155     $(GLINK SwitchStatement)
1156     with a matching $(EXPRESSION).
1157
1158 ---
1159 switch (x)
1160 {
1161     case 3:
1162     goto case;
1163     case 4:
1164     goto default;
1165     case 5:
1166     goto case 4;
1167     default:
1168     x = 4;
1169     break;
1170 }
1171 ---
1172     Any intervening finally clauses are executed, along with
1173     releasing any intervening synchronization mutexes.
1174     <p>
1175
1176     It is illegal for a $(I GotoStatement) to be used to skip
1177     initializations.
1178
1179 <h2>$(LNAME2 WithStatement, With Statement)</h2>
1180
1181     The with statement is a way to simplify repeated references
1182     to the same object.
1183
1184 $(GRAMMAR
1185 $(I WithStatement):
1186     $(B with) $(B $(LPAREN)) $(EXPRESSION) $(B $(RPAREN)) $(PSSCOPE)
1187     $(B with) $(B $(LPAREN)) $(LINK2 template.html#Symbol, $(I Symbol)) $(B $(RPAREN)) $(PSSCOPE)
1188     $(B with) $(B $(LPAREN)) $(LINK2 template.html#TemplateInstance, $(I TemplateInstance)) $(B $(RPAREN)) $(PSSCOPE)
1189 )
1190
1191     where $(EXPRESSION) evaluates to a class reference or struct
1192     instance.
1193     Within the with body the referenced object is searched first for
1194     identifier symbols. The $(I WithStatement)
1195
1196 --------------
1197 $(B with) (expression)
1198 {
1199     ...
1200     ident;
1201 }
1202 --------------
1203
1204     is semantically equivalent to:
1205
1206 --------------
1207 {
1208     Object tmp;
1209     tmp = expression;
1210     ...
1211     tmp.ident;
1212 }
1213 --------------
1214
1215     $(P Note that $(EXPRESSION) only gets evaluated once.
1216     The with statement does not change what $(B this) or
1217     $(B super) refer to.
1218     )
1219
1220     $(P For $(I Symbol) which is a scope or $(I TemplateInstance),
1221     the corresponding scope is searched when looking up symbols.
1222     For example:
1223     )
1224
1225 --------------
1226 struct Foo
1227 {
1228     alias int Y;
1229 }
1230 ...
1231 Y y;        // error, Y undefined
1232 with (Foo)
1233 {
1234     Y y;    // same as Foo.Y y;
1235 }
1236 --------------
1237
1238 $(V2
1239     $(P Use of with object symbols that shadow local symbols with
1240     the same identifier are not allowed.
1241     This is to reduce the risk of inadvertant breakage of with
1242     statements when new members are added to the object declaration.
1243     )
1244 ---
1245 struct S
1246 {
1247     float x;
1248 }
1249
1250 void main()
1251 {
1252     int x;
1253     S s;
1254     with (s)
1255     {
1256         x++;  // error, shadows the int x declaration
1257     }
1258 }
1259 ---
1260 )
1261
1262 <h2>$(LNAME2 SynchronizedStatement, Synchronized Statement)</h2>
1263
1264     $(P The synchronized statement wraps a statement with
1265     a mutex to synchronize access among multiple threads.
1266     )
1267
1268 $(GRAMMAR
1269 $(I SynchronizedStatement):
1270     $(B synchronized) $(PSSCOPE)
1271     $(B synchronized $(LPAREN)) $(EXPRESSION) $(B $(RPAREN)) $(PSSCOPE)
1272 )
1273
1274     $(P Synchronized allows only one thread at a time to execute
1275     $(I ScopeStatement) by using a mutex.
1276     )
1277
1278     $(P What mutex is used is determined by the $(EXPRESSION).
1279     If there is no $(EXPRESSION), then a global mutex is created,
1280     one per such synchronized statement.
1281     Different synchronized statements will have different global mutexes.
1282     )
1283
1284     $(P If there is an $(EXPRESSION), it must evaluate to either an
1285     Object or an instance of an $(I Interface), in which case it
1286     is cast to the Object instance that implemented that $(I Interface).
1287     The mutex used is specific to that Object instance, and
1288     is shared by all synchronized statements referring to that instance.
1289     )
1290
1291     $(P The synchronization gets released even if $(I ScopeStatement)
1292     terminates with an exception, goto, or return.
1293     )
1294
1295     $(P Example:
1296     )
1297
1298 --------------
1299 synchronized { ... }
1300 --------------
1301
1302     $(P This implements a standard critical section.
1303     )
1304
1305 <h2>$(LNAME2 TryStatement, Try Statement)</h2>
1306
1307     Exception handling is done with the try-catch-finally statement.
1308
1309 $(GRAMMAR
1310 $(I TryStatement):
1311     $(B try) $(PSSCOPE) $(I Catches)
1312     $(B try) $(PSSCOPE) $(I Catches) $(I FinallyStatement)
1313     $(B try) $(PSSCOPE) $(I FinallyStatement)
1314
1315 $(GNAME Catches):
1316     $(I LastCatch)
1317     $(I Catch)
1318     $(I Catch) $(I Catches)
1319
1320 $(GNAME LastCatch):
1321     $(B catch) $(PS0)
1322
1323 $(GNAME Catch):
1324     $(B catch $(LPAREN)) $(I CatchParameter) $(B $(RPAREN)) $(PS0)
1325
1326 $(GNAME CatchParameter):
1327     $(GLINK2 declaration, BasicType) $(I Identifier)
1328
1329 $(GNAME FinallyStatement):
1330     $(B finally) $(PS0)
1331 )
1332
1333     $(P $(I CatchParameter) declares a variable v of type T, where T is
1334     $(V1 Object or derived from Object.)
1335     $(V2 Throwable or derived from Throwable.)
1336     v is initialized by the throw expression if
1337     T is of the same type or a base class of the throw expression.
1338     The catch clause will be executed if the exception object is of
1339     type T or derived from T.
1340     )
1341
1342     $(P If just type T is given and no variable v, then the catch clause
1343     is still executed.
1344     )
1345
1346     $(P It is an error if any $(I CatchParameter) type T1 hides
1347     a subsequent $(I Catch) with type T2, i.e. it is an error if
1348     T1 is the same type as or a base class of T2.
1349     )
1350
1351     $(P $(I LastCatch) catches all exceptions.
1352     )
1353
1354     $(P The $(I FinallyStatement) is always executed, whether
1355     the $(B try) $(I ScopeStatement) exits with a goto, break,
1356     continue, return, exception, or fall-through.
1357     )
1358 $(V1
1359     $(P If an exception is raised in the $(I FinallyStatement) and
1360     is not caught before the $(I FinallyStatement) is executed,
1361     the new exception replaces any existing exception:
1362     )
1363 )
1364 $(V2
1365     $(P If an exception is raised in the $(I FinallyStatement) and
1366     is not caught before the original exception is caught, it is
1367     chained to the previous exception via the $(I next) member of $(I Throwable).
1368     Note that, in contrast to most other programming languages, the new
1369     exception does not replace the original exception. Instead, later exceptions
1370     are regarded as 'collateral damage' caused by the first exception.
1371     The original exception must be caught, and this results in the capture of
1372     the enture chain.
1373     )
1374
1375     $(P Thrown objects derived from $(I Error) are treated differently. They
1376     bypass the normal chaining mechanism, such that the chain can only be caught
1377     by catching the first $(I Error). In addition to the list of subsequent
1378     exceptions, $(I Error) also contains a pointer to the points to the original
1379     exception (the head of the chain) if a bypass occurred, so that the entire
1380     exception history is retained.
1381     )
1382 )
1383 --------------
1384 import std.stdio;
1385
1386 int main()
1387 {
1388     try
1389     {
1390     try
1391     {
1392         throw new Exception("first");
1393     }
1394     finally
1395     {
1396         writefln("finally");
1397         throw new Exception("second");
1398     }
1399     }
1400     catch(Exception e)
1401     {
1402     writefln("catch %s", e.msg);
1403     }
1404     writefln("done");
1405     return 0;
1406 }
1407 --------------
1408     prints:
1409 $(V1
1410 $(CONSOLE
1411 finally
1412 catch second
1413 done
1414 )
1415 )
1416 $(V2
1417 $(CONSOLE
1418 finally
1419 catch first
1420 done
1421 )
1422 )
1423
1424     $(P A $(I FinallyStatement) may not exit with a goto, break,
1425     continue, or return; nor may it be entered with a goto.
1426     )
1427
1428     $(P A $(I FinallyStatement) may not contain any $(I Catches).
1429     This restriction may be relaxed in future versions.
1430     )
1431
1432 <h2>$(LNAME2 ThrowStatement, Throw Statement)</h2>
1433
1434     Throw an exception.
1435
1436 $(GRAMMAR
1437 $(I ThrowStatement):
1438     $(B throw) $(EXPRESSION) $(B ;)
1439 )
1440
1441     $(EXPRESSION) is evaluated and must be $(V1 an Object) $(V2 a Throwable) reference.
1442     The $(V1 Object) $(V2 Throwable) reference is thrown as an exception.
1443
1444 ---
1445 throw new Exception("message");
1446 ---
1447
1448 <h2>$(LNAME2 ScopeGuardStatement, Scope Guard Statement)</h2>
1449
1450 $(GRAMMAR
1451 $(I ScopeGuardStatement):
1452     $(B scope(exit)) $(PSCURLYSCOPE)
1453     $(B scope(success)) $(PSCURLYSCOPE)
1454     $(B scope(failure)) $(PSCURLYSCOPE)
1455 )
1456
1457     The $(I ScopeGuardStatement) executes $(PSCURLYSCOPE) at the close
1458     of the current scope, rather than at the point where the
1459     $(I ScopeGuardStatement) appears.
1460     $(B scope(exit)) executes $(PSCURLYSCOPE) when the scope
1461     exits normally or when it exits due to exception unwinding.
1462     $(B scope(failure)) executes $(PSCURLYSCOPE) when the scope
1463     exits due to exception unwinding.
1464     $(B scope(success)) executes $(PSCURLYSCOPE) when the scope
1465     exits normally.
1466     <p>
1467
1468     If there are multiple $(I ScopeGuardStatement)s in a scope, they
1469     are executed in the reverse lexical order in which they appear.
1470     If any scope instances are to be destructed upon the close of the
1471     scope, they also are interleaved with the $(I ScopeGuardStatement)s
1472     in the reverse lexical order in which they appear.
1473
1474 ----
1475 writef("1");
1476 {
1477     writef("2");
1478     scope(exit) writef("3");
1479     scope(exit) writef("4");
1480     writef("5");
1481 }
1482 writefln();
1483 ----
1484
1485     writes:
1486
1487 $(CONSOLE
1488 12543
1489 )
1490
1491 ----
1492 {
1493     scope(exit) writef("1");
1494     scope(success) writef("2");
1495     scope(exit) writef("3");
1496     scope(success) writef("4");
1497 }
1498 writefln();
1499 ----
1500
1501     writes:
1502
1503 $(CONSOLE
1504 4321
1505 )
1506
1507 ----
1508 class Foo
1509 {
1510     this() { writef("0"); }
1511     ~this() { writef("1"); }
1512 }
1513
1514 try
1515 {
1516     scope(exit) writef("2");
1517     scope(success) writef("3");
1518     scope Foo f = new Foo();
1519     scope(failure) writef("4");
1520     throw new Exception("msg");
1521     scope(exit) writef("5");
1522     scope(success) writef("6");
1523     scope(failure) writef("7");
1524 }
1525 catch (Exception e)
1526 {
1527 }
1528 writefln();
1529 ----
1530
1531     writes:
1532
1533 $(CONSOLE
1534 0412
1535 )
1536
1537     A $(B scope(exit)) or $(B scope(success)) statement
1538     may not exit with a throw, goto, break, continue, or
1539     return; nor may it be entered with a goto.
1540
1541 $(V1
1542 <h2>$(LNAME2 VolatileStatement, Volatile Statement)</h2>
1543
1544     No code motion occurs across volatile statement boundaries.
1545
1546 $(GRAMMAR
1547 $(I VolatileStatement):
1548     $(B volatile) $(PSSEMI_PSCURLYSCOPE)
1549     $(B volatile) $(B ;)
1550 )
1551
1552     $(PSSEMI_PSCURLYSCOPE) is evaluated.
1553     Memory writes occurring before the $(PSSEMI_PSCURLYSCOPE) are
1554     performed before any reads within or after the $(PSSEMI_PSCURLYSCOPE).
1555     Memory reads occurring after the $(PSSEMI_PSCURLYSCOPE) occur after
1556     any writes before or within $(PSSEMI_PSCURLYSCOPE) are completed.
1557     <p>
1558
1559     A volatile statement does not guarantee atomicity. For that,
1560     use synchronized statements.
1561 )
1562
1563 <h2>$(LNAME2 asm, Asm Statement)</h2>
1564
1565     Inline assembler is supported with the asm statement:
1566
1567 $(GRAMMAR
1568 $(GNAME AsmStatement):
1569     $(B asm { })
1570     $(B asm {) $(I AsmInstructionList) $(B })
1571
1572 $(GNAME AsmInstructionList):
1573     $(I AsmInstruction) $(B ;)
1574     $(I AsmInstruction) $(B ;) $(I AsmInstructionList)
1575 )
1576
1577     An asm statement enables the direct use of assembly language
1578     instructions. This makes it easy to obtain direct access to special
1579     CPU features without resorting to an external assembler. The
1580     D compiler will take care of the function calling conventions,
1581     stack setup, etc.
1582     <p>
1583
1584     The format of the instructions is, of course, highly dependent
1585     on the native instruction set of the target CPU, and so is
1586     $(LINK2 iasm.html, implementation defined).
1587     But, the format will follow the following
1588     conventions:
1589
1590     $(UL
1591     $(LI It must use the same tokens as the D language uses.)
1592     $(LI The comment form must match the D language comments.)
1593     $(LI Asm instructions are terminated by a ;, not by an
1594     end of line.)
1595     )
1596
1597     These rules exist to ensure that D source code can be tokenized
1598     independently of syntactic or semantic analysis.
1599     <p>
1600
1601     For example, for the Intel Pentium:
1602
1603 --------------
1604 int x = 3;
1605 asm
1606 {
1607     mov EAX,x;      // load x and put it in register EAX
1608 }
1609 --------------
1610
1611     Inline assembler can be used to access hardware directly:
1612
1613 --------------
1614 int gethardware()
1615 {
1616     asm
1617     {
1618         mov EAX, dword ptr 0x1234;
1619     }
1620 }
1621 --------------
1622
1623     For some D implementations, such as a translator from D to C, an
1624     inline assembler makes no sense, and need not be implemented.
1625     The version statement can be used to account for this:
1626
1627 --------------
1628 version (D_InlineAsm_X86)
1629 {
1630     asm
1631     {
1632     ...
1633     }
1634 }
1635 else
1636 {
1637     /* ... some workaround ... */
1638 }
1639 --------------
1640
1641     $(P Semantically consecutive $(I AsmStatement)s shall not have
1642     any other instructions (such as register save or restores) inserted
1643     between them by the compiler.
1644     )
1645
1646 <h2>$(LNAME2 PragmaStatement, Pragma Statement)</h2>
1647
1648 $(GRAMMAR
1649 $(I PragmaStatement):
1650     $(LINK2 pragma.html, $(I Pragma)) $(PSSEMI)
1651 )
1652
1653 <h2>$(LNAME2 MixinStatement, Mixin Statement)</h2>
1654
1655 $(GRAMMAR
1656 $(I MixinStatement):
1657     $(B mixin) $(B $(LPAREN)) $(ASSIGNEXPRESSION) $(B $(RPAREN)) $(B ;)
1658 )
1659
1660     $(P The $(ASSIGNEXPRESSION) must evaluate at compile time
1661     to a constant string.
1662     The text contents of the string must be compilable as a valid
1663     $(GLINK StatementList), and is compiled as such.
1664     )
1665
1666 ---
1667 import std.stdio;
1668
1669 void main()
1670 {
1671     int j;
1672     mixin("
1673     int x = 3;
1674     for (int i = 0; i < 3; i++)
1675         writefln(x + i, ++j);
1676     ");    // ok
1677
1678     const char[] s = "int y;";
1679     mixin(s);  // ok
1680     y = 4;     // ok, mixin declared y
1681
1682     char[] t = "y = 3;";
1683     mixin(t);  // error, t is not evaluatable at compile time
1684
1685     mixin("y =") 4; // error, string must be complete statement
1686
1687     mixin("y =" ~ "4;");  // ok
1688 }
1689 ---
1690
1691 $(V2
1692 <h2>$(LNAME2 ForeachRangeStatement, Foreach Range Statement)</h2>
1693
1694     A foreach range statement loops over the specified range.
1695
1696 $(GRAMMAR
1697 $(I ForeachRangeStatement):
1698     $(GLINK Foreach) $(LPAREN)$(GLINK ForeachType) $(B ;) $(I LwrExpression) $(B ..) $(I UprExpression) $(B $(RPAREN)) $(PSSCOPE)
1699
1700 $(GNAME LwrExpression):
1701     $(EXPRESSION)
1702
1703 $(GNAME UprExpression):
1704     $(EXPRESSION)
1705 )
1706
1707     $(P
1708     $(I ForeachType) declares a variable with either an explicit type,
1709     or a type inferred from $(I LwrExpression) and $(I UprExpression).
1710     The $(I ScopeStatement) is then executed $(I n) times, where $(I n)
1711     is the result of $(I UprExpression) - $(I LwrExpression).
1712     If $(I UprExpression) is less than or equal to $(I LwrExpression),
1713     the $(I ScopeStatement) is executed zero times.
1714     If $(I Foreach) is $(B foreach), then the variable is set to
1715     $(I LwrExpression), then incremented at the end of each iteration.
1716     If $(I Foreach) is $(B foreach_reverse), then the variable is set to
1717     $(I UprExpression), then decremented before each iteration.
1718     $(I LwrExpression) and $(I UprExpression) are each evaluated
1719     exactly once, regardless of how many times the $(I ScopeStatement)
1720     is executed.
1721     )
1722
1723 ---
1724 import std.stdio;
1725
1726 int foo()
1727 {
1728     writefln("foo");
1729     return 10;
1730 }
1731
1732 void main()
1733 {
1734     foreach (i; 0 .. foo())
1735     {
1736     writef(i);
1737     }
1738 }
1739 ---
1740
1741     $(P Prints:)
1742
1743 $(CONSOLE
1744 foo0123456789
1745 )
1746 )
1747
1748 )
1749
1750 Macros:
1751     TITLE=Statements
1752     WIKI=Statement
1753     GLINK=$(LINK2 #$0, $(I $0))
1754     GNAME=$(LNAME2 $0, $0)
1755     EXPRESSION=$(LINK2 expression.html#Expression, $(I Expression))
1756     PSSEMI_PSCURLYSCOPE=$(GLINK Statement)
1757     PSSEMI_PSCURLYSCOPE_LIST=$(GLINK ScopeStatementList)
1758     PS0=$(GLINK NoScopeNonEmptyStatement)
1759     PSSCOPE=$(GLINK ScopeStatement)
1760     PSCURLY=$(GLINK BlockStatement)
1761     PSSEMI=$(GLINK NoScopeStatement)
1762     PSCURLY_PSSCOPE=$(GLINK ScopeBlockStatement)
1763     PSCURLYSCOPE=$(GLINK NonEmptyOrScopeBlockStatement)
1764     FOO=
Note: See TracBrowser for help on using the browser.