In classic REXX it is not possible to use a variable as parameter for the call statement (in Object-Oriented REXX it is; see New features in Object REXX that are useful in Classic REXX programs also)
To get around this you can use either the interpret statement or a combination of the call and the signal statement.
The following code is an example for the usage of the interpret statement. This code works for all type of functions and subroutines:
/* example using the interpret statement */ /* ------------- example for calling a sub routine ------------------ */ '@cls' /* name of the routine to call */ funcName = 'proc1' /* names of the global variables used by the */ /* function */ exposeList = '' /* parameter for the routine */ parameter1 = '11' parameter2 = '22' say '' say '[main] Now calling the routine "' || funcName || '" ...' say '[main] The parameter are "' || parameter1 || '" and "'|| parameter2 || '"' /* now call the routine */ interpret call funcName parameter1 ',' parameter2 /* ------------- example for calling a function --------------------- */ /* name of the function to call */ funcName = 'Func2' /* names of the global variables used by the */ /* function */ exposeList = '' /* parameter for the function */ parameter1 = '33' parameter2 = '44' say '' say '[main] Now calling the function "' || funcName || '" ...' say '[main] The parameter are "' || parameter1 || '" and "'|| parameter2 || '"' /* now call the function */ interpret 'thisResult = ' funcName || '(' parameter1 ',' parameter2 ')' say '[main] The function "' || funcName || '" returned: "' || thisResult || '".' /* ------------- example for calling a DLL function ----------------- */ /* name of the function to call */ funcName = 'SysCurPos' /* name of the global variables used by the */ /* function */ exposeList = '' /* parameter for the DLL function */ parameter1 = '21' parameter2 = '0' say '' say '[main] Now calling the DLL function "' || funcName || '" ...' say '[main] The parameter are "' || parameter1 || '" and "'|| parameter2 || '"' /* now call the DLL function */ interpret 'thisResult = ' funcName || '(' parameter1 ',' parameter2 ')' say '[main] The function "' || funcName || '" returned: "' || thisResult || '".' /* ------------- example for calling a builtin function ------------- */ /* name of the function to call */ funcName = 'abs' /* names of the global variables used by the */ /* function */ exposeList = '' /* parameter for the builtin function */ parameter1 = '-2.121' say '' say '[main] Now calling the builtin function "' || funcName || '" ...' say '[main] The parameter is "' || parameter1 || '"' /* now call the DLL function */ interpret 'thisResult = ' funcName || '(' parameter1 ')' say '[main] The function "' || funcName || '" returned: "' || thisResult || '".' exit /* ------------------------------------------------------------------ */ /* sample subroutine */ /* */ /* Note: The first parameter is the name of the function */ /* */ proc1: PROCEDURE expose (exposeList) parse arg arg1, arg2 say '[proc1] This is proc1' say '[proc1] The first parameter is "' || arg1 || '"' say '[proc1] The second parameter is "' || arg2 || '"' return /* ------------------------------------------------------------------ */ /* sample function */ /* */ /* Note: The first parameter is the name of the function */ /* */ FUNC2: PROCEDURE expose (exposeList) parse arg arg1, arg2 say '[func2] This is func2' say '[func2] The first parameter is "' || arg1 || '"' say '[func2] The second parameter is "' || arg2 || '"' return 2
The following code is an example for the usage of the combination of the call and the signal statement. This code works only for functions and sub routines in the program, for builtin functions and for functions from a DLL (see also Redefinition of functions from a DLL and Redefinition of internal functions):
/* example using the combination of the call and the signal statement */ /* (based on code found in a public newsgroup) */ /* ------------- example for calling a sub routine ------------------ */ '@cls' /* name of the routine to call */ funcName = 'proc1' /* names of the global variables used by the */ /* called routine */ exposeList = '' /* parameter for the routine */ parameter1 = '11' parameter2 = '22' say '' say '[main] Now calling the routine "' || funcName || '" ...' say '[main] The parameter are "' || parameter1 || '" and "'|| parameter2 || '"' /* now call the routine */ call Dispatcher funcName , parameter1 , parameter2 /* ------------- example for calling a function --------------------- */ /* name of the function to call */ funcName = 'func2' /* names of the global variables used by the */ /* function */ exposeList = '' /* parameter for the function */ parameter1 = '33' parameter2 = '44' say '' say '[main] Now calling the function "' || funcName || '" ...' say '[main] The parameter are "' || parameter1 || '" and "'|| parameter2 || '"' /* now call the function */ thisResult = Dispatcher( funcName , parameter1, parameter2 ) say '[main] The function "' || funcName || '" returned: "' || thisResult || '".' /* ------------- example for calling a DLL function ----------------- */ /* name of the function to call */ funcName = 'SysCurPos' /* names of the global variables used by the */ /* function */ exposeList = '' /* parameter for the DLL function */ parameter1 = '21' parameter2 = '0' say '' say '[main] Now calling the DLL function "' || funcName || '" ...' say '[main] The parameter are "' || parameter1 || '" and "'|| parameter2 || '"' /* now call the DLL function */ thisResult = Dispatcher( funcName , parameter1, parameter2 ) say '[main] The function "' || funcName || '" returned: "' || thisResult || '".' /* ------------- example for calling a builtin function ------------- */ /* name of the function to call */ funcName = 'abs' /* names of the global variables used by the */ /* function */ exposeList = '' /* parameter for the builtin function */ parameter1 = '-2.121' say '' say '[main] Now calling the builtin function "' || funcName || '" ...' say '[main] The parameter is "' || parameter1 || '"' /* now call the builtin function */ thisResult = Dispatcher( funcName , parameter1, parameter2 ) say '[main] The function "' || funcName || '" returned: "' || thisResult || '".' exit /* ------------------------------------------------------------------ */ /* help routine */ /* */ /* usage: Dispatcher name_of_the_routine {parameter_for_the_routine} */ /* */ /* Note: The parameter for the signal statement must be in UPPERCASE! */ /* */ Dispatcher: PROCEDURE expose (exposeList) parse upper arg label signal value label /* ------------------------------------------------------------------ */ /* sample subroutine */ /* */ /* Note: The first parameter is the name of the function */ /* You can not use PROCEDUE here! */ /* */ proc1: parse arg , arg1, arg2 say '[proc1] This is "' || arg(1) || '".' say '[proc1] The first parameter is "' || arg1 || '"' say '[proc1] The second parameter is "' || arg2 || '"' return /* ------------------------------------------------------------------ */ /* sample function */ /* */ /* Note: The first parameter is the name of the function */ /* You can not use PROCEDUE here! */ /* */ FUNC2: parse arg , arg1, arg2 say '[func2] This is "' || arg(1) || '".' say '[func2] The first parameter is "' || arg1 || '"' say '[func2] The second parameter is "' || arg2 || '"' return 2 /* ------------------------------------------------------------------ */ /* sample placeholder for builtin function */ /* */ /* Note: The first parameter is the name of the function */ /* You can not use PROCEDUE here! */ /* */ /* new SysCurPos function */ SysCurPos: parse arg , p1,p2 say '[SysCurPos] This is "' || arg(1) || '".' say '[SysCurPos] The first parameter is "' || p1 || '"' say '[SysCurPos] The second parameter is "' || p2 || '"' /* check the type of the parameter */ if datatype( p1 ) <> "NUM" | datatype( p2 ) <> "NUM" then thisRC = "Invalid parameter!" else do /* load the original function if not already */ /* loaded */ if RxFuncQuery( "SysCurPos" ) then call RxFuncAdd "SysCurPos", "REXXUTIL", "SysCurPos" /* call the original function */ thisRC = "SYSCURPOS"( p1,p2 ) end /* else */ RETURN thisRC /* ------------------------------------------------------------------ */ /* sample placeholder for a builtin function */ /* */ /* Note: The first parameter is the name of the function */ /* You can not use PROCEDUE here! */ /* */ /* new abs function */ abs: parse arg , p1 say '[abs] This is "' || arg(1) || '".' say '[abs] The first parameter is "' || p1 || '"' /* note: The name of the builtin functio must */ /* be in uppercase! */ return "ABS"(p1)