Passing Parameters to a Macro
Earlier in this chapter, we discussed the problem of global variables, and how these can sometimes cause harmful side effects. If macros are written as watertight compartments, then the only way to pass information to a macro is by using parameters. As an example, let's rewrite our inner macro, Write_to_file, using parameters.
The variables String_length and First_string are no longer used by Keywords_search, so they have been deleted.
DEFINE Keywords_search
LOCAL File1
LOCAL File2
LOCAL Flag
LOCAL Filestring1
LOCAL First_char
LOCAL Line_pos
{ LOCAL String_length deleted }
{ LOCAL First_string deleted }
LET File1 '\me10\help'
LET File2 '\john\keywords.out'
OPEN_INFILE 1 File1
OPEN_OUTFILE 2 DEL_OLD File2
LET Flag 0

LOOP
READ_FILE 1 Filestring1
EXIT_IF (Filestring1='END-OF-FILE')
LET First_char (SUBSTR Filestring1 1 1)
IF (First_char='^')
IF (Flag = 0)
LET Line_pos (POS Filestring1 ' ')
Write_to_file Line_pos Filestring1 2
END_IF
ELSE
LET Flag 0
END_IF
END_LOOP
CLOSE_FILE 1
CLOSE_FILE 2
END_DEFINE

DEFINE Write_to_file
PARAMETER Column
PARAMETER String
PARAMETER File_descriptor
LOCAL String_length
LOCAL First_string
IF (Column = 0)
LET String_length (LEN String)
LET First_string (SUBSTR String 2 (String_length-1))
WRITE_FILE File_descriptor First_string
LET Flag 1
ELSE
LET First_string (SUBSTR String 2 (Column-2))
WRITE_FILE File_descriptor First_string
LET Flag 1
END_IF
END_DEFINE
Here are some things you should note about the new macros:
Except for Flag, the variables in Write_to_file are different from those in Keywords_search. This is the most common situation if you call a macro from within a macro. The inner macro is likely to be part of a library of macros, and you have used it to avoid writing new code yourself. The specification for the macro will tell you what the macro does and what parameters you have to pass. You have no interest in the internal workings of the macro, or what variables are used.
In Write_to_file, the parameters can be declared in any order. But when Write_to_file is called by Keywords_search, the arguments must be in the correct order. The statement that calls Keywords_search is:
Write_to_file Line_pos Filestring1 2
In this statement, notice the following:
Line_pos corresponds to Column.
Filestring1 corresponds to String.
2 corresponds to File_descriptor.
When you call the macro Write_to_file, the system knows that the first parameter after the macro name represents the first declared parameter in the called macro; the second parameter after the macro name represents the second declared parameter in the called macro, and so on.
Note that you can pass parameters in to a called macro, but you cannot pass parameters out to the calling macro. As in all programming languages, macros are expanded at compile time. This means that the macro code is substituted for the macro name. When one macro calls another macro, the code is substituted inline in the calling macro at compile time. The resulting code is then executed as if there were only one macro.
If Write_to_file were substituted inline without PARAMETER statements, the compiler would complain that some variables were unknown. The PARAMETER statements tell the compiler that some pairs of variables are equivalent. However, PARAMETER variables behave similarly to LOCAL variables: they are only visible in the macro in which they are declared. So a macro is different from functions and subroutines as used in other programming languages such as PL/I or Fortran. In these languages, the program branches to the called function or subroutine, which can then return values to the calling program.
Since you need to know the value of Flag after execution of Write_to_file, Flag has not been declared as a local variable or as a parameter in Write_to_file. We must keep Flag as a global variable so that it is visible to both macros.
The output file, keywords.out, will have the keywords listed in the order that they appear in the help file.
Est-ce que cela a été utile ?