Skip to content
John Horigan edited this page Mar 17, 2015 · 1 revision

A variable declaration binds a value to a name for a particular scope of the CFDG file: name = expression. A variable has three components: its name; its value; and its scope, the portion of the CFDG file where the variable binding is valid.

phi = (1 + sqrt(5)) / 2

Variable Scope

A variable can be declared up at the top level (called a global variable), between the shape definitions, or it can be declared within a shape or path (called a local variable). The scope of global variables is from right after the point of declaration until the end of the CFDG file. A global variable declared inside an imported CFDG file has scope that continues after the import statement until the end of the CFDG file.

Local variables have scope starting right after the expression until the end of the block that they are declared in. If a local variable is declared among the replacements in a shape then its scope is until the end of the shape. If a local variable is declared inside a block within a shape (or path); the body of a loop for example; then its scope is until the end of the block.

provide example code

Overlapping Scope

Variables cannot be modified. If a variable is declared within the scope of another variable with the same name then the new variable hides the old variable until the new variable goes out of scope. In this code

count = 5
count = count - 1

The second count declaration does not modify the first count variable. Instead it declares a new count variable that renders the first one invisible. If the first count variable was global and the second count variable was local then the global count would be invisible until the local count went out of scope. Note that the scope of the second count variable begins after the count - 1 expression, which means that the count in the count - 1 expression refers to the first count variable.

Overlapping variables with the same name will generate warning messages unless the CF::AllowOverlap configuration declaration is set.

CF::AllowOverlap = 1

Named Loop Index Variable

When you use the named variant of the loop construct the loop index variable is declared and contains the loop index for each iteration of the loop. The scope of the loop index variable is the loop body and the finally body (if there is one).

loop i = 10 [x 1] {
    loop i+1 [y 1] {
      CIRCLE []
    }
  }

In this example, the outer loop iterates from 0 to 9, placing the loop index in the variable i. The inner loop (which is anonymous) iterates from 0 to i. The end-result is a right triangle of circles.

Variable Types

There are four types of variables: numeric, vector, shape adjustment, and shape.

Numeric Variables

A numeric variable is declared with the syntax name = numeric expression. The resulting variable can be used anywhere that a number can be used (except for rule weights).

Vector Variables

A vector variable is declared with the syntax name = vector expression. A vector expression is an expression that returns a vector, either using the vector operator or a function that returns vectors. The resulting variable can be used anywhere that a vector can be used.

Shape Adjustment Variables

A shape adjustment variable is declared with the syntax name = [adjustments] or name = adjustments, the first declares a basic shape adjustment and the second declares an ordered shape adjustment. A shape adjustment variable can be inserted into another shape adjustment using the trans adjustment keyword:

shape foo {
    adj = [x 0.5 r 56]
    SQUARE [trans adj]
}

Shape Variables

A shape variable is declared by assigning a shape specification. This has the syntax name = shape_name or name = shape_name(parameters), if the shape has parameters; or name1 = name2, is name2 names another shape variable. A shape variable can be used as if it were the name of a shape:

draw = CIRCLE
 
shape test2 
{
  loop i = 10 [x 1] {
    loop i+1 [y 1] {
      draw []
    }
  }
}

If the shape has parameters then they must be provided in the declaration, they cannot be bound to the shape variable later. If you use a parameterized shape with the same parameters multiple times it may be more clear to declare a shape variable with the shape and parameters and then use the variable instead.

shape curve(number shrink, number turn)
{
  SQUARE []
  curve(=) [[y 0.5 r turn s shrink y 0.5]]
}
 
stem = curve(0.97, 1)