Before looking at this, you should first read "Macros-1".
Other system variables
Aside from &SYSNDX, there are several other system variables. Here are a few (not all) of them:
This is the date on which the code was assembled, in "MM/DD/YY" format, eight characters.
This is the time of day at which the code was assembled, in "hh.mm" format, five characters.
This is the name of the CSECT in which the macro was used. As a macro might be used in several different CSECTs, the value may vary.
Positional and keyword parameters
Thus far we have been using "positional" parameters. They are listed in order on the prototype statement for the macro, and when it is used, the values listed are assigned to the parameters in order, left to right. Positional parameters do not have default values other than an empty string.
We can also have "keyword" parameters. When we use the macro, we use the keyword in assigning a value to the parameter, and for this reason, the order is much less important.
Examples:
Here are prototype statements for three macros:
&LABEL MAX &A,&B,&C
&LABEL ENTER &BR=12,&SA=YES
&LABEL FILL &DEST,&LEN,&CHAR=C' '
The macro called MAX has three positional parameters. It presumably does something like setting &C = the larger of &A and &B, so the order is important.
The macro called ENTER has two keyword parameters. When we use it, we can accept the existing default values:
ENTER
or we can change one or both of them, in either order:
ENTER BR=11
where &SA still has the value "YES".
ENTER SA=NO,BR=10
Notice that when we use the keyword, we do not include the ampersand.
The macro called FILL has two positional parameters and one keyword parameter. The positional parameters are at the left and the keyword parameter is at the right.
(End of example)
Some high-level languages support keyword parameters (Ada, Python, FORTRAN, LISP, etc) and some do not (C, C++, etc).
Sublists and &SYSLIST
Sometimes it is desirable to have a parameter which is a list. This is called a "sublist".
For instance, we could have
&LABEL ADD &SUM,&LIST
where &SUM is the label or D(B) address of a fullword and &LIST is a list of such. We could call it:
ADD TOTAL,(A,B,C)
When we want to refer to the individual items in &LIST, we can use &LIST(1), &LIST(2) or LIST(3).
More generally, we could use a tool called &SYSLIST:
&SYSLIST(K) = Kth positional parameter (or null = an empty string if K is too large)
&SYSLIST(K,N) = Nth item on a sublist which is the Kth positional parameter (or null if N is too large)
Example (adapted from an IBM manual):
MYLABEL MACALL ONE,TWO,(3,(4,5,6),,8),,TEN
We can use &SYSLIST to get hold of all of this:
If the Kth parameter is not a sublist, then &SYSLIST(K,1) is the same as &SYSLIST(K).
(As we are using ASSIST, it is possible some of the more advanced features here are not implemented, such as 2-level sublists.)
Local variables in a macro
We can have local variables in a macro.
We can have a "Local Arithmetic Variable":
LCLA &N
Here &N is an integer, initially 0. We can change its value:
&N SETA expression
For instance:
&N SETA &N+1
We can have a "Local Boolean Variable":
LCLB &F
Here &F is a boolean variable, initially 0 (or False). We can change its value:
&F SETB expression
where the expression is a logical condition as in an AIF.
(It is possible to use various operators such as AND and OR in an expression, but it is not clear that ASSIST supports this.)
We can have a "Local Character Variable":
LCLC &S
Here &S is a character string, initially empty. We can change its value:
&S SETC expression
where the expression may be:
We can also have global variables in a macro.
These are very similar to local variables, but they retain their values from one call to the macro to the next. We could, for instance, have a counter for how many times we call the macro.
We define these using GBLA, GBLB and GBLC, and modify their values using SETA, SETB and SETC.
Local and global variables in a macro are sometimes called "SET" variables because of the use of "SET".
Attributes
Often it is useful to have some access to various properties of arguments. This is provided by "attributes".
Number attribute: If &Q is a sublist, then
N'&Q
is the number of items on the sublist (including empty strings).
Thus:
Count attribute: The value of any symbolic parameter &B is a character string. The number of characters in the string is
K'&B
Thus if &B = 'Hello', we have K'&B = 5.
Length and Type attributes: Suppose the value of &P is the actual label of a variable, not a D(B) address. Then:
L'&P
is the number of bytes of whatever was defined at that label. This is the length attribute. If we have
PQRS DS F
and the value of &P is 'PQRS', then L'&P = 4.
We also have the type attribute:
T'&P
is one letter which indicates the type of data. Possible values are
and there are some others.
In theory, we could use the attributes to create macros that could adapt to the types of data we provided. For instance, we could have an Add macro which could accept values of various types (binary, zoned decimal, packed decimal) and generate the code needed to add them. (This would be "polymorphic" behavior.)