Preprocessor Examples
Example 1
%DECLARE A CHARACTER, B FIXED;
%A = 'B+C';
%B = 2;
X = A;
the following is inserted into the preprocessor
output: X = 2+C;
The preprocessor statements activate A and B with the default RESCAN, assign the character string 'B+C' to A, and assign the constant 2 to B.
The fourth line is input text. The current value of A, which is 'B+C', replaces A in the preprocessor output. But this string contains the preprocessor variable B. Upon rescanning B, the preprocessor finds that it has been activated. Hence, the value 2 replaces B in the preprocessor output. The preprocessor variable B has a default precision of (5,0) and, therefore, actually contains 2 preceded by four zeros. When this value replaces B in the string 'B+C' it is converted to a character string and becomes 2 preceded by seven blanks.
Further rescanning shows that 2 cannot be replaced; scanning resumes with +C which, again, cannot be replaced.
%ACTIVATE A NORESCAN;
the preprocessor output would be: X = B+C;
Example 2
%DECLARE I FIXED, T CHARACTER;
%DEACTIVATE I;
%I = 15;
%T = 'A(I)';
S = I*T*3;
%I = I+5;
%ACTIVATE I;
%DEACTIVATE T;
R = I*T*2
the preprocessor output would be as follows
(replacement blanks are not shown): S = I*A(I)*3;
R = 20*T*2;
Example 3
DO I=1 TO 10;
Z(I)=X(I)+Y(I);
END;
%DECLARE I FIXED;
%DO I = 1 TO 10;
Z(I)=X(I)+Y(I);
%END;
%DEACTIVATE I;
Z( 1)=X( 1)+Y( 1);
Each 1 is preceded by seven blanks.
Z( 1)=X( 1)+Y( 1);
Z( 2)=X( 2)+Y( 2);
.
.
.
Z( 10)=X( 10)+Y( 10);
When the value of I reaches 11, control falls through to the %DEACTIVATE statement.
Example 4
DECLARE (Z(10), Q) FIXED;
%A='Z';
%ACTIVATE A, VALUE;
Q = 6 + VALUE(A,3);
%DECLARE A CHARACTER;
%VALUE: PROC(ARG1,ARG2) RETURNS(CHAR);
DCL ARG1 CHAR, ARG2 FIXED;
RETURN(ARG1∥'('∥ARG2∥')');
%END VALUE;
When the scan encounters the fourth line, A is active and is thus eligible for replacement. Since VALUE is also active, the reference to it in the fourth line invokes the preprocessor function procedure of that name.
DECLARE (Z(10),Q) FIXED;
Q = 6+Z( 3);
Example 5
%DCL GEN ENTRY;
DCL A GEN (A,2,5,FIXED);
%GEN: PROC(NAME,LOW,HIGH,ATTR) RETURNS (CHAR);
DCL (NAME, SUFFIX, ATTR, STRING) CHAR, (LOW, HIGH, I, J) FIXED;
STRING='GENERIC(';
DO I=LOW TO HIGH; /* ENTRY NAME LOOP*/
IF I>9 THEN
SUFFIX=SUBSTR(I, 7, 2);
/* 2 DIGIT SUFFIX*/
ELSE SUFFIX=SUBSTR(I, 8, 1);
/* 1 DIGIT SUFFIX*/
STRING=STRING∥NAME∥SUFFIX∥' WHEN (';
DO J=1 TO I; /* DESCRIPTOR LIST*/
STRING=STRING∥ATTR;
IF J<I /* ATTRIBUTE SEPARATOR*/
THEN STRING=STRING∥',';
ELSE STRING=STRING∥')';
/* LIST SEPARATOR */
END;
IF I<HIGH THEN /* ENTRY NAME SEPARATOR*/
STRING=STRING∥',';
ELSE STRING=STRING∥')';
/* END OF LIST /*
END;
RETURN (STRING)
% END;
DCL A GENERIC(A2 WHEN (FIXED,FIXED),
A3 WHEN (FIXED, FIXED, FIXED),
A4 WHEN (FIXED, FIXED, FIXED, FIXED),
A5 WHEN (FIXED, FIXED, FIXED, FIXED, FIXED));
Example 6
SEARCH TABLE(array) FOR(value)
USING(variable) AND(variable);
This statement searches a specified two-dimensional array for a specified value, using specified or default variables for the array subscripts. After execution of the statement, the array subscript variables identify an element that contains the specified value. If no element contains the specified value, both subscript variables are set to -22222.
%SEARCH:
PROC(TABLE,FOR,USING,AND) STATEMENT RETURNS(CHARACTER);
DECLARE(TABLE,FOR,USING,AND,LABL, DO1,DO2) CHARACTER,
(PARMSET,COUNTER) BUILTIN;
IF PARMSET(TABLE) & PARMSET(FOR) THEN;
ELSE SERR:DO;
NOTE ('MISSING OR INVALID ARGUMENT(S)'∥'FOR ''SEARCH''',4);
RETURN ('/*INVALID SEARCH STATEMENT*/');
END;
IF ¬PARMSET(USING) THEN
USING='I';
IF ¬PARMSET(AND) THEN
AND='J';
IF USING = AND THEN
GO TO SERR;
LABL='SL'∥COUNTER;
DO1=LABL∥': DO '∥USING∥'=LBOUND('∥TABLE∥',1)
TO HBOUND('∥TABLE∥',1);';
DO2='DO '∥AND∥'=LBOUND('∥TABLE∥',2)
TO HBOUND ('∥TABLE∥',2);';
RETURN(DO1∥DO2∥'SELECT('∥TABLE
∥'('∥USING∥','∥AND∥'));
WHEN('∥FOR∥') LEAVE '∥LABL∥';
OTHER;
END '∥LABL∥';
IF '∥AND∥' > H BOUND('∥TABLE∥',2) THEN
'∥USING∥','∥AND∥.' = -22222;');
%END SEARCH;
The PARMSET built-in function is used to determine which parameters are set when the procedure is invoked. If USING is not set, the default array subscript variable I is used. If AND is not set, J is used. If TABLE or FOR is not set, or if the invocation results in the same variable being used for both subscripts, a preprocessor diagnostic message is issued and a comment is returned in the preprocessor output.
The COUNTER built-in function is used to generate unique labels for the preprocessor output returned by the procedure.
SEARCH TABLE(LIST.NAME)
FOR('J.DOE') USING(I) AND(J);
SEARCH TABLE(LIST.NAME) FOR('J.DOE');
SEARCH(LIST.NAME) FOR('J.DOE');
SEARCH(LIST.NAME,'J.DOE');
SEARCH(,'J.DOE') TABLE(LIST.NAME);
SL00001:
DO I=LBOUND(LIST.NAME,1) TO HBOUND(LIST.NAME,1);
DO J=LBOUND(LIST.NAME,2) TO HBOUND(LIST.NAME,2);
SELECT(LIST.NAME(I,J));
WHEN('J.DOE') LEAVE SL00001;
OTHER;
END SL00001;
IF J > HBOUND(LIST.NAME,2) THEN
I,J = -22222;
The label SL00001 is returned only for the first invocation. A new unique label is returned for each subsequent invocation.