Function parameters
Functions can take parameters, to specialize their behavior.
Purpose of function parameters
The function declaration specifies the name of the function and the identifiers of its formal arguments (if any).
Function parameters hold values passed by the caller, to be used in the body of the function.
Function parameter specification with legacy syntax
DEFINE
statement that immediately follows the argument
list.FUNCTION check_address(zipcode, street, city)
DEFINE zipcode CHAR(5),
street VARCHAR(100),
city VARCHAR(50)
DEFINE found BOOLEAN -- local function variable
...
END FUNCTION
Function parameter specification with fully-typed syntax
FUNCTION check_address(zipcode CHAR(5), street VARCHAR(100), city VARCHAR(50))
DEFINE found BOOLEAN -- local function variable
...
END FUNCTION
Function without parameters
FUNCTION begin_work()
...
END FUNCTION
Passing primitive type values as parameters
Function arguments using simple data types such as INTEGER
are passed by value (the values are copied on the stack).
In the following code example, the variable x
defined in the
MAIN
block will not be modified by the function:
MAIN
DEFINE x INTEGER
LET x = 123
CALL myfunc(x)
DISPLAY x -- displays 123
END MAIN
FUNCTION myfunc(x)
DEFINE x INTEGER
LET x = x + 1
END FUNCTION
Type conversions
The actual argument in a call to the function need not be of the declared data type of the formal argument. The runtime system will do the appropriate data type conversions when needed. If the data type conversion is not possible, a runtime error occurs.
NULL
INTEGER
:MAIN
CALL add("aaaaa")
END MAIN
FUNCTION add(x)
DEFINE x INTEGER
DISPLAY "x = ", x
END FUNCTION
Passing complex objects as parameters
MAIN
DEFINE ch base.Channel
LET ch = base.Channel.create()
CALL ch.openFile(arg_val(1), "r")
CALL read_lines(ch)
END MAIN
FUNCTION read_lines(ch base.Channel)
DEFINE s STRING
WHILE TRUE
LET s = ch.readLine()
IF ch.isEOF() THEN EXIT WHILE END IF
DISPLAY s
END WHILE
END FUNCTION
Passing records by reference
.*
(dot star) notation, records are expanded on the stack: Each field of the record is
passed by value like a primitive data
type:CALL show_cust_info( r_cust.* )
INOUT
keyword in the
function
definition:FUNCTION init_cust(r CustRec INOUT)
LET r.cust_id = 0
LET r.cust_name = "<undefined>"
LET r.cust_addr = "<undefined>"
LET r.cust_crea = CURRENT
END FUNCTION
INOUT
is only supported
when the called function is defined locally, or is known by the compiler because it was imported
with IMPORT FGL
.For more details, see Passing records as parameter.