Control Structures

FPP provides you with a full range of control structures.

Instructions

An instruction is the most basic control structure. It is something we ask the GPU to perform during script execution. An instruction can be composed of multiple statements, such as variables assignments and it can use multiple operators.

a = 5 // Assign 5 to the variable a

Blocks

A block is a named list of instructions. A variable defined inside a block is not visible outside it.

If/Else Conditional Structures

Conditional structures work the same way they do in C++ or JAVA. The condition in the if must be a Boolean. There is no automatic translation from floating value to Boolean like in C. Note that there is no need for brackets if your block contains only one instruction (like the third one in this example).

b = false
c = true
if (b){
    return 1
} else if (c) {
    return 2
} else
    return 3

Switch/Case Statements

Switch/case statements allow to perform particular actions depending on the value of a variable:

def a = 15
switch(a){
    case 15 :
        return 25
    case 13 :
    case 16 :
        return 42
    default :
        return -1
}

Switch cases can be done on the following types: String, Date, Boolean, Floating point value. Case values must be mutually exclusive (i.e. there cannot be two cases with the value 42) and variable scopes are shared among cases. Note that in the case of floating point value, the checked value will be rounded to the nearest integer value because of C99 switch case limitations.

Loops

Loops can be of three forms:

  • A C-like for loop that is defined by an initialization instruction, a break instruction and a post loop instruction:
def sum = 0
for (def i = 0 ; i < 10 ; ++i)
    sum += i
return sum
  • A C-like while loop that is defined by a break instruction:
def sum = 0
while(sum < 10)
    sum += 1
return sum
  • An iteration over a collection that is defined in the document:
def sum = 0
for (def cf in cashFlows) // cashFlows is defined in the document
    sum += cf.value
return sum
  • An iteration over an array:
def a = array(10)
for (def x in a)
    sum += x
return sum

Any variable defined in the loop cannot be accessed outside the loop, since a new scope is created for the loop block. Note that in the three cases, a check is made to ensure that the loop is not infinite. Any loop cannot have more than the maximum iterations defined with the configuration parameter MAX_LOOP_ITERATIONS.

Loops on ranges (i.e. for (i in 1..42) ) are not supported yet.

Break Statements

The break statement allows you to cancel the execution of certain scopes, such as loops or switch/cases. It works as its C/JAVA counterparts:

sum = 0
for (i = 0 ; i < 10 ; i++){
    if (sum > 10)
        break;
    sum += i
}
return sum // will return 15

Continue Statements

The continue statement allows you to keep on executing a loop, but breaks the current iteration:

sum = 0
for (i = 0 ; i < 10 ; i++){
    if (i > 5)
        continue;
    sum += i
}
return sum // will return 15

Unary Expressions (Prefix/Postfix)

Prefix and post-fix operators apply to some particular variables in particular cases. There are only a few of them:

  • ++ and --, prefix and post-fix. Applied on floating point values, they work exactly as their C / Java counterparts.
def i = 0
def a = i++ // a == 0
def b = ++i // b == 2
def c = --i // c == 1
def d = i-- // d == 1
  • The not ( ! ) operator. Applicable as prefix on boolean expressions only:
def b = false
if (!b)
    return 42

Binary Expressions

Binary expressions are composed of two expressions linked by a token. Any combination of token / expressions can be made as long as they all follow these rules:

Left expression Right expression Allowed tokens Results in
Floating point Floating point + - / * -= += *= /= = Floating point
Floating point Floating point != < > <= >= == Boolean
Date Date != < > <= >= == Boolean
Boolean Boolean && || == Boolean
String String != == Boolean