DEF Verb

Syntax

DEF FNnumname(arglist){=num}
DEF FNstrname(arglist){=string}

Description

For BBj-specific information, see DEF Verb - BBj.

The DEF verb declares a user-defined function. DEF must be the first command on a line and may not be preceded by a label.

Parameter

Description

FNnumname

Numeric function

FNstrname

String function

arglist

Series of simple variables separated by commas

=num

Numeric expression

=string

String expression

If an expression follows the argument list, the function is complete on one line. If there is no expression following the argument list, the function occupies multiple lines and is not complete until the execution of a RETURN. If a multi-line function encounters an FNEND command, an !ERROR=24 is reported.

When PRO/5 encounters any FNnumname or FNstrname in an expression during program execution, it locates the corresponding DEF statement and evaluates the function. The DEF statement can be placed anywhere in the program; however, they are traditionally placed near the top of the program.

A DEF statement is skipped in normal execution, and a multi-line function is skipped by proceeding to the next FNEND command in the program.

The arguments given in the function call must match the corresponding argument list in the DEF by number and type. Unlike many BASICs, arguments listed in the DEF statement are not dummy arguments.

In the following example, when executing FNA(4) in line 20, it assigns the value of 4 to the variable Z:

0010 DEF FNA(Z)=Z*5
0020 LET Y=FNA(4)

Do not define the same function more than once in a program because the result is unpredictable. PRO/5 distinguishes between FNA() and FNA$(), and both can exist in the same program.

Multi-line Functions

If a DEF statement does not contain an "=" followed by an expression, then it is the first line of a multi-line function. The body of the function consists of the following lines until the next FNEND statement. A FNEND statement must be on a line by itself. If a multi-line function is encountered during normal execution, it is skipped just as a normal single-line DEF statement would be.

A function result is returned by a RETURN statement:

RETURN X+4

or

RETURN A$(4,6)

NOTE: The developer must take care not to allow the function logic to flow off the end of the function. It is never valid to execute a FNEND statement.

The TCB(17) function returns the current nested level of multi-line functions.

The following example is a simple multi-line function that returns the greatest common factor of two integers. A test will be made to ensure that the two arguments are valid integers.

100 DEF FNGCF(X,Y)
110 IF FPT(X)<>0 OR FPT(Y)<>0 THEN FNERR 41
120 WHILE X<>0
130 LET TEMP=X, X=MOD(Y,X), Y=TEMP
140 WEND
150 RETURN Y
160 FNEND

1120 A=FNGCF(B,C)

Error Handling in Multi-line Functions

If an untrapped error occurs during a multi-line function, the error is reported at the location where the function was called. Inside a multi-line function, errors may be trapped with the standard ERR=, DOM=, and END= clauses. The global SETERR is ignored during the execution of a multi-line function.

Occasionally it is desirable to generate an error condition to be passed back to the invocation point. This is done with the FNERR statement:

200 IF A<0 THEN FNERR 40

This is analogous to the EXIT ERR statement in a public program.

Restrictions in Multi-line Functions

Generally, multi-line functions are intended to perform some kind of calculation and return. It is legal to perform I/O in a multi-line function, but the developer must exercise caution. If such a function were called from an I/O operation, the results of the I/O operation might not be as expected.

The following operations cannot be performed in a multi-line function:

  • The function cannot attempt to modify the program with verbs such as DELETE, EDIT, EXECUTE, and MERGE.

  • The function cannot perform any kind of reset operation such as BEGIN, CLEAR, RESET, or START.

  • A BACKGROUND, CALL, OPEN, CLOSE, SAVE, or RUN cannot be executed.

  • Console mode cannot be entered with an ESCAPE, END, or STOP.

NOTE: Integer functions, such as DEF FNA%(X), are not supported.

PRO/5 does not permit DEF in console mode, and it cannot be part of a compound statement.

Examples

The example below illustrates declaring a multi-line function that translates global strings:

0100 DEF FNSETPATH$(X1$)
0110 NAME_INSERT_LOOP:
0120 LET P1=POS("("=X1$,-1)
0130 IF P1=0 THEN RETURN X1$
0140 LET P2=POS(")"=X1$(P1))+P1-1
0150 IF P1>=P2 THEN RETURN X1$
0160 LET X2$=$$
0170 LET X2$=STBL(X1$(P1+1,P2-P1-1),ERR=NAME_NOT_THERE)
0180 NAME_NOT_THERE:
0190 LET X1$=X1$(1,P1-1)+X2$+X1$(P2+1);
0190:GOTO NAME_INSERT_LOOP
0200 FNEND

If the global string (DICT) has the value "/basis/taos/datad/", then:

[ A$=STBL("DICT","/BASIS/TAOS/DATAD/") ]
PRINT FNSETPATH$("(DICT)CUSTOMER.DAT")
/BASIS/TAOS/DATAD/CUSTOMER.DAT

See Also

Verbs - Alphabetical Listing