Control flow elements

In a shape rule it is possible to put a control structure anywhere that it is legal to have a shape replacement. In a path it is possible to put a control structure anywhere that it is legal to have a path operation or a path command. The list of supported control structure are: loops, if statements, transform statements, and switch statements.

=Loops= A loop structure takes a block of code (shape replacements, path operations, or path commands) and iterates over it several times. A loop consists of a loop header, a loop body, and an optional finally body. A loop header has an optional loop variable, the loop count, and the loop transform. If a loop index variable is declared in the loop header then the current loop value is made available through that variable inside the loop body (and finally body). These kinds of loops are called named loops. If no loop index variable is declared in the loop header then the loop is an anonymous loop and the current loop value is not available. After each iteration of the loop the current world state is adjusted by the loop transform. is equivalent to

Loop Index Variable
The example has the outer loop declaring a loop index variable by putting i = before the loop count. The inner loop does not have a variable = before the loop count, so it is anonymous. Note that the outer loop's variable is used in the loop count for the inner loop. We could even use it in the loop transform of the inner loop. The only place that we cannot use the loop variable is in the loop transform for the outer loop. The scope for the loop index variable is the loop transform and the body of the loop.

Loop Count
The loop count is an expression of one, two, or three numbers. If all three numbers are specified then they are the initial loop value, the terminal loop value, and the loop step. The loop value starts with the initial value for the first iteration. The loop step is added to the loop value after each iteration. The loop terminates when the loop value is &ge; the terminal value (or &le; the terminal value if step < 0). If two numbers are specified then they are the initial value and the terminal value, the loop step defaults to 1. If only one number is specified then it is the terminal value, the initial value defaults to zero and the loop step defaults to 1.

Loop Transform
The body of the loop inherits the world state for the shape or path that contains the loop. After each loop iteration the loop's world state is adjusted using the loop transform.

Finally Body
If the loop has a finally body then the code in the finally body will execute once after the last iteration of the loop. The world state for the finally body is the world state for the loop with one last adjustment by the loop transform. If the loop is a named loop then the loop index variable has scope inside the finally body.

=If Statements= An if statement evaluates an expression and executes some code (replacements, path elements, other control structures) if the expression value is non-zero. An is statement can also have an else clause that is executed if the expression value is zero. The syntax for an if statement is if (expression) then-body or if (expression) then-body else else-body. then-body and else-body can be simple bodies or compound bodies.

=Switch Statements=

A switch statement allows one of several blocks of code to be executed based on the evaluation of of a selector expression. The switch statement contains one or more case elements. Each case element contains a constant case integer and a case body, which is a simple or compound statement. The case integer is derived from a constant case expression, which is evaluated and rounded to the next lowest integer. There may also be an else element which also has a case body, but no expression. When a switch statement is executed the selector expression is evaluated and rounded to the next lowest integer. If there is a case element with a case integer matching this integer then the corresponding case body is executed. If there is no matching case element then the else body is executed, if there is one.

=Transform Statements= A transform statement has a list of adjustments and a body. The transform body is executed once for each adjustment in the adjustment list in the context of that adjustment. The transform body can be simple or compound. The adjustment list must have at least one adjustment and they are separated by commas. It has the same syntax as the CF::Symmetry configuration variable, except that the only symmetry operations that are allowed are CF::Cyclic and CF::Dihedral.

In this example the designer wanted to knock-out a hexagonal hole in a path. Figuring out exactly how to position the hexagon path points is tricky. The transform statement allows the designer to plug in simple code for a hexagon and then tweak the entire hexagon path to achieve the desired effect.

=Clone Statements= A clone statement has the same syntax and behavior as a transform statement except that all of the shapes executed inside a clone statement look the same, even if they are random. This is a violation of context-free purity, so you must set CF::Impure to 1.

=Simple vs. Compound Bodies= The body of a control structure (loop-main, loop-finally, if, else, switch-case, transform, or clone) can have one of two forms: simple or compound. A simple loop body is a single shape replacement, path operation, path command, or another control structure. A compound loop body has an open curly brace {; any number of replacements, path elements, or control structures; and then a closing curly brace }.