Calling functions
Functions can be invoked, to execute the code they define.
How can functions be invoked?
- with the
CALL
instruction, - in an expression,
- in a callback mechanism.
The symbol used to identify the function to be called can be a static function name, or a variable referencing a function.
Typical function invocation with CALL
CALL
instruction:FUNCTION open_database(dbname STRING)
...
END FUNCTION
...
CALL open_database("stock")
Function invoked as part of an expression
MAIN
DEFINE r INTEGER
LET r = 500 + add(50,5)
END MAIN
FUNCTION add(x,y) RETURNS INTEGER
DEFINE x, y INTEGER
RETURN (x + y)
END FUNCTION
Callback mechanisms
- the
WHENEVER ERROR CALL
instruction, - the
INITIALIZER
form field attribute, - the
ui.Form.setDefaultInitializerFunction()
method, - ...
Recursion
MAIN
CALL recursive(1)
END MAIN
FUNCTION recursive(x)
DEFINE x INTEGER
DISPLAY "x = ", x
IF x<10 THEN
CALL recursive(x+1)
END IF
END FUNCTION
Each time a function calls itself, parameters are pushed on the stack. A deep level of recursion can result in out of memory errors.
Calling a function from its reference variable
CALL
instruction, or in an
expression:TYPE t_func_ref FUNCTION (p1 INT, p2 INT) RETURNS INT
DEFINE fr t_func_ref
LET fr = FUNCTION add -- Function with the same signature as t_func_ref
DISPLAY fr(100,200)
Naming parameters in a function call
MAIN
CALL cleanup( mode: "full", verbose: TRUE )
END MAIN
FUNCTION cleanup( mode STRING, verbose BOOLEAN )
IF verbose THEN
DISPLAY "Cleanup mode: ", mode
END IF
END FUNCTION
DEFINE s STRING
DISPLAY s.subString(startIndex: 1, endIndex: 3)
...
DEFINE io base.Channel
LET io = base.Channel.create()
CALL io.openClientSocket(host: "localhost", port: 4711, mode: "u", timeout: 0)
If the parameter name in the function call does not match the parameter in the function definition, the compiler will produce error -8420.
Named function call parameters does not imply free ordering, nor does it allow you to omit parameters. All parameters must be specified, in the same order as in the function declaration.
In order to check the parameter names, fglcomp needs to know the function
definition. When the called function is defined in another module, use IMPORT FGL
to let the compiler know
the function definition.
Named function parameters are provided by the source code completer.