Control structures

The extension function language provides the usual statements to control program execution.

  • If Then Else
  • While Do and Repeat Until
  • Numeric For
  • Break
  • Goto

If Then Else

If statements select blocks of statements to execute based on one or more conditions. There are three forms:

If then Form

if expression then statements to execute if expression is not false or nil end

If then else Form

if expression then statements to execute if expression is not false or nil else statements to execute if expression is false or nil end

If then elseif else Form

if expression1 then statements to execute if expression1 is not false or nil elseif expression2 then statements to execute if expression2 is not false or nil . . . else statements to execute if all expressions are false or nil end

Example:

if headers[name] then local next_value_index = #(headers[name]) + 1 headers[name][next_value_index] = value else headers[name] = {name .. ":" .. value} end

Note:

  • The expression is not enclosed in parentheses as is the case in C and Java.
  • There is no equivalent to the C/Java switch statement. You have to use a series of if elseif statements to do the equivalent.

While Do and Repeat Until

The while and repeat statements provide loops controlled by an expression.

while expression do statements to execute while expression is not false or nil end repeat statements to execute until expression is not false or nil until expression

Example for while:

local a = {1, 2, 3, 4} local sum, i = 0, 1 -- multiple assignment initializing sum and i while i <= #a do -- check if at the end of the array sum = sum + a[i] -- add array element with index i to sum i = i + 1 -- move to the next element end

Example for repeat:

sum, i = 0, 1 -- multiple assignment initializing sum and i repeat sum = sum + a[i] -- add array element with index i to sum i = i + 1 -- move to the next element until i > #a -- check if past the end of the array

Of course it is possible to write a loop that does not terminate, for example, if you omit the i = i + 1 statement in either of these examples. When such a function is executed, Citrix ADC will detect that the function did not complete in a reasonable time and will kill it with a runtime error:

Cpu limit reached. Terminating extension execution in [[string "function extension function..."]]: line line-number.

will be reported in /var/log/ns.log.

Numeric For

There are two types of for loops. The first is the numeric for, which is similar to the usual use of the for statement in C and Java. The numeric for statement initializes a variable, tests if the variable has passed a final value, and if not executes a block of statements, increments the variable, and repeats. The syntax for the numerical for loop is:

for variable = initial, final, increment do statements in the loop body end

where initial, final, and increment are all expressions that yield (or can be converted to) numbers. variable is considered to be local to the for loop statement block; it cannot be used outside of the loop. increment can be omitted; the default is 1. The expressions are evaluated once at the beginning of the loop. The terminating condition is variable > final if the increment is positive and variable < final if the increment is negative. The loop terminates immediately if the increment is 0.

Example (equivalent to the while and repeat loops in the preceding section):

sum = 0 for i = 1, #a do -- increment defaults to 1 sum = sum + a[i] end

The second type of for loop is the generic for, which can be used for more flexible types of loops. It involves the use of functions, so will be discussed later after functions have been introduced.

Break

The break statement is used inside a while, repeat, or for loop. It will terminate the loop and resume execution at the first statement after the loop. Example (also equivalent to the preceding while, repeat, and for loops):

sum, i = 0, 1 while true do if i > #a then break end sum = sum + a[i] i = i + 1 end

Goto

The goto statement can be used to jump forward or backward to a label. The label is an identifier, and its syntax is ::label::. The goto statement is goto label. Example (once again equivalent to the preceding loops):

sum, i = 0, 1 ::start_loop:: if i > #a then goto end_loop -- forward jump end sum = sum + a[i] i = i + 1 goto start_loop -- backwards jump ::end_loop:: . . .

There has been a long running controversy over using gotos in programming. In general, you should try to use the other control structures to make your functions more readable and reliable. But occasional judicious use of gotos may lead to better programs. In particular, gotos may be useful in handling errors.

Control structures