Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
100 views

Basic Pl/1 Built-In Functions

This document provides information about basic PL/1 built-in functions. It discusses string handling and arithmetic built-in functions. It explains that built-in functions must be declared before use and provides examples of declaring SUBSTR and INDEX. The document describes the SUBSTR and INDEX functions in detail, including their arguments and return values. It provides additional examples of using SUBSTR and INDEX to manipulate strings.

Uploaded by

ArvindUpadhyay
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
100 views

Basic Pl/1 Built-In Functions

This document provides information about basic PL/1 built-in functions. It discusses string handling and arithmetic built-in functions. It explains that built-in functions must be declared before use and provides examples of declaring SUBSTR and INDEX. The document describes the SUBSTR and INDEX functions in detail, including their arguments and return values. It provides additional examples of using SUBSTR and INDEX to manipulate strings.

Uploaded by

ArvindUpadhyay
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 18

BASIC PL/1 BUILT-IN FUNCTIONS

MODULE 09 Page 0 of 16
MODULE 09
Built-in Functions
BASIC PL/1 BUILT-IN FUNCTIONS
BUILT-IN FUNCTION CONCEPTS
The basic assignment statement that we've seen, in conjunction with the
various operators that we use to build up expressions, allow us to do the
majority of the processing that the program specifcation demands. There
are certain basic processing tools, however, that are either very
cumbersome or even impossible using these facilities.
Example:
If the variable YR FIXED DEC(5) contains the number of the year
between 1950 and 1999, check to see if it is a leap year.
DCL WK FIXED DEC(5);
WK = YR/4;
IF WK*4 = YR
THEN /*LEAP */
ELSE /*NOT LEAP*/
Given X CHAR(5), put into Y CHAR(2) the last 2 characters of X.
DCL 1 WK DEF(X),
3 WK2 CHAR(3),
3 WK3 CHAR(2);
or
DCL WK3 CHAR(2)DEF(X) POS(4);
Y = WK3;
Given X CHAR(5), put into Y CHAR(2) the 2 characters of X starting in
position J (BIN FIXED(15)).
/* HELP */
Given TODAY CHAR(8), put into it today's date in the format DD/MM/YY.
/* HELP */
PL/1 provides a wide range of Built-in Functions to do jobs like this for us.
In each case we supply one or more values, and the function then works
out an answer which is returned to us for us to use as we wish.
MODULE 09 Page 1 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
CLASSES OF BUILT-IN FUNCTION
The functions are divided up into various categories, depending on their
use and the data type on which they operate. For example - there is a set
of Built-In Functions called the "String Handling Built-In Functions",
because they deal with CHARACTER and BIT strings. Another class is
referred to as the "Arithmetic Built-In Functions", because, obviously, they
perform arithmetic tasks for us. No matter to which class a Built-In
Function belongs, it operates in the same way. So once we have covered
the principle then we can rapidly pick up new functions.
MODULE 09 Page 2 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
DECLARING BUILT-IN FUNCTIONS
Before a Built-in Function can be used it must be declared.
Format:
DCL built-in function BUILTIN;
Thus, each Built-in Function that is used must be declared.
e.g.
DCL SUBSTR BUILTIN;
DCL INDEX BUILTIN;
MODULE 09 Page 3 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
SOME STRING-HANDLING FUNCTIONS
Here is an example of a statement using the built-in function SUBSTR:
OU_STRING = SUBSTR (IN_STRING, 7, 3)
This illustrates a typical use of a Built-In Function. We code the Built-In
Function name, in this case SUBSTR, and follow it with, in parentheses, a
list of values - the arguments. The function takes those argument values,
performs some processing, and then returns a value to us. The value is
returned in such a way that we use the Built-In Function in the same way
as we would have done if the whole reference to the Built-In Function - i.e.
name and list of arguments - had been an expression.
For any new function we learn, we need to ask the following questions:
How many arguments does it require?
How does the function work out the Returned Value from the
values of the arguments?
What are the preferred data types for those arguments?
What are the attributes of the Returned Value?
If we give the answers to these questions for SUBSTR, then we can see
how a Built-In Function is defned:
MODULE 09 Page 4 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
SUBSTR
How many arguments does it require?
3
How does the function work out the returned value from the values of
the arguments?
It calculates the returned value by starting with a string which is the
frst argument value, uses the second argument value to determine a
starting position in the string, and uses the third argument value as the
number of characters to be used from the string. The resulting sub-
string is the returned value.
What are the preferred data types for those arguments?
First argument - CHAR
Second Argument - BIN FIXED
Third argument - integer constant
What are the attributes of the Returned Value?
A string, of the same type as the fst argument, whose length is given
by the value of the third argument.
The efect can probably be most easily be seen by example:
DCL STRIN1 CHAR (2!);
DCL POSN "IN FIXED (15);
POSN = 5;
STRIN1 = #HERE IS $Y TEST DATA#;
SUBSTR(STRING1,1,2) %&'' ()*+(, - .-'+) %/&0/ &1
- 1+231*(&,4 56 STRIN1 %&*/ 1*-(*&,4 751&*&5, 1
-,8 '),4*/ 2, &9)9 'HE'9
SUBSTR(STRING1,10,10) %&'' ()*+(, - 1+231*(&,4
751&*&5, 1! '),4*/ 1!, &9)9 'Y TEST DAT'
SUBSTR(STRING1,POSN,3) %&'' ()*+(, ' IS'
MODULE 09 Page 5 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
SUBSTR(STRING1,POSN+2,2) %&'' ()*+(, 'S '
SUBSTR('ABCD',POSN-3,2) %&'' ()*+(, 'BC'
SUBSTR(STRING1 || 'FOR SUBSTR',17,10) %&''
()*+(, 'DATA FOR S'
One point to note about the above references - you can see that we can
put constants, variables and expressions as arguments to our Built-In
Functions. You will also note that in all of the above references the third
argument has been specifed as a constant. In fact that is not a PL/1 rule,
but a good guideline. We can put a variable or expression as the third
argument to SUBSTR, but it's much less efcient.
So far we have only coded the reference to the Built-In Function, but that's
of no use by itself in our program. What we need to do is incorporate that
reference into a PL/1 statement.
Examples:
DCL S1 CHAR(1!);
DCL S2 CHAR(5);
DCL S3 CHAR(2);
DCL PN1 "IN FIXED(15);
PN1 = 5;
S1 = #A"CDEFHI:K#;
S2 = S;"STR(S1,4,5);
S3 = S;"STR(S1,PN1,2);
IF S;"STR(S1,3,2) = #PP#
THEN999999999
S2 = S;"STR(S1,<,4) == S;"STR(S3,2,1);
SELECT(S;"STR(S1,5,2));
WHEN(#AA#,S3) 99999999
MODULE 09 Page 6 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
INDEX BUILT-IN FUNCTION
This is a string Built-In Function, like SUBSTR, but instead of returning a
CHAR value it returns a number. This number has attributes BIN
FIXED(15), and tells us the result of searching for one string value within
another. This illustrates the importance of knowing the data type of the
returned value, as we will want to set up the assignment, or comparison,
to ft in with the data type.
Arguments: 2
Data types: Argument 1 - CHAR
Argument 2 - CHAR
Returned value: BINARY FIXED(15)
Operation: The frst argument value is searched for the
frst occurrence of the second argument
value.If it cannot be found, then the returned
value is 0. If it is found, then the returned value
is the position in argument 1 where the value
of argument 2 was found.
E>-?7')1@
I = INDEX(#A"CDE#,#D#);
I &1 4
I = INDEX(#A"CDE#,#DE#);
I &1 4
I = INDEX (#A"CDE#,#D E#)
I &1 !
Uses for INDEX
As long as the value being searched for is of fxed length and less than
256 bytes long, INDEX is very efcient. We will use it for obvious cases
when we have to search one string for another.
MODULE 09 Page 7 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
E>-?7')@
DCL INTEXT CHAR(5!);
DCL I "IN FIXED(15);
DCL : "IN FIXED(15);
I = INDEX(INTEXT,#,#);
: = INDEX(INTEXT,#9#);
IF IA:
THEN9999999
would be the coding to see if the frst comma in a string came before the
frst full stop.
It's also useful for other purposes. Suppose an INPUT fle has 5 diferent
record types. We need to look at the code in the record which
distinguishes between them. Although it might be easiest for us if the
record codes were something simple like 1, 2, 3, 4 and 5, the designers
have said that the record codes should be 'A', 'F', 'L', 'P' and 'Z'. We can
use INDEX to convert from the unwieldy letters to simple numbers, and do
a validation on the code at the same time. Instead of-
SELECT(R:S9RECBCODE);
WHEN(#A#) TYPE = 1;
WHEN(#F#) TYPE = 2;
WHEN(#L#) TYPE = 3;
WHEN(#P#) TYPE = 4;
WHEN(#C#) TYPE = 5;
OTHER DO;
TYPE = !;
$ESSAE = #INDALID CODE#;
END;
END; /*OF SELECT*/
we simply need to code:
TYPE = INDEX(#AFLPC#, R:S9RECBCODE);
IF TYPE = !
THEN $ESSAE = #INDALIDBCODE#;
As with SUBSTR, remember that the arguments are values, and so we
are allowed to use constants, variables or expressions. We can even use
the value returned by a Built-In Function as the argument to another.
MODULE 09 Page 8 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
Example:
Given INSTRING CHAR(50), put into ANS CHAR(3) the three characters
of INSTRING which follow the frst X.
ANS = SUBSTR (INSTRING, INDEX (INSTRING, 'X') + 1, 3);
Given INSTRING CHAR(50), fnd the position where the frst character
occurs a second time- the following code is nearly right:
I = INDEX(INSTRING,SUBSTR(INSTRING, 1, 1));
but the problem is that the frst character of INSTRING will of course be
found in the frst position. We need to ensure that we don't look in the frst
position in INSTRING - this means changing the frst argument to INDEX:
I=INDEX(S;"STR(INSTRIN,2,4E),S;"STR(INSTRIN,1,1))
;
We'll now look at several more Built-In Functions, and the details of
arguments and returned values will be found on the Student Reference
Sheets. We'll look only at examples of use.
MODULE 09 Page 9 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
STRING
This takes a structure of CHAR-type data (CHAR and PIC) and concatenates
the elements together to form a single string. It can also be used with BIT data
type.
Suppose that in one input record there is a minor structure PLC.ACC with the
elements:
3 AREA CHAR(4),
3 SEF PIC #EEE#,
and in another input record there is a minor structure LBS.AC_NO also with
elements:
3 AREA CHAR(4),
3 SEF PIC #EEE#,
to see if the value of PLC.ACC is the same as the value of LBS.AC_NO, we
must not code:
IF PLC9ACC = L"S9ACBNO
because comparing two structures gives a structure of BIT results, and we
cannot have a structure between IF and THEN. We need to be able to take the
two 7-character areas and consider them as single strings we can compare.
The following would be valid:
IF STRIN(PLC9ACC) = STRIN(L"S9ACBNO)
and is easier and neater that the alternative, which is to DEFINE a new
CHAR(7) variable onto each minor structure.
MODULE 09 Page 10 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
CHAR
At frst sight, this Built-In Function is not a lot of use, because it converts things
to CHARACTER, and we could do that quite easily by assignment if we wanted
to. It does have one very important use, which is why it has been included
here.
Suppose we have:
.................
3 INPIC PIC #CCE#
..................
within our input record. Most of the time we'll want to use its numeric value, so
the defnition as PIC is fne. However, there will be times (the specifcation says)
when the value in that part of the record will be 'AAA'. We need therefore to
check for 'AAA' before using the arithmetic value. If we coded:
IF INPIC = #AAA#
we would have a problem. INPIC is an arithmetic variable - and so PL/1 sees a
comparison between arithmetic and character. This is something we would
normally avoid, but it is legal in PL/1. Trouble is, the comparison will be an
arithmetic comparison. So not only will we not succeed in avoiding converting
INPIC to FIXED DEC, we will also try to convert 'AAA' to FIXED DEC. Result -
an error. To do the comparison as a CHAR comparison, which is what we want,
we need to convert the PIC variable to CHAR, and that is where the Built-In
Function CHAR comes in.
Whereas:
IF INPIC = #AAA#
is an arithmetic comparison,:
IF CHAR(INPIC) = #AAA#
is a character comparison.
MODULE 09 Page 11 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
VERIFY
This is one of the more complicated Built-In Functions, but as it is so
useful in validation programs, we will cover it.
Uses:
Validation of character strings
In a simple case, we might have an incoming variable INPIC PIC '999' to
validate. We can code:
I = VERIFY(INPIC, '0123456789');
If I is 0, then every character in INPIC could be found in the string of
digits. So INPIC contains data suitable for PIC '999' and we can go
ahead and use it arithmetically.
If I had been non-zero, then at least one character in INPIC was not a
digit. Usually when we are validating, we don't bother to see which
character it was that was invalid, we only respond to the returned value
being greater than zero.
We don't need to assign the result of VERIFY to a variable and then test
the variable. We can use the returned value directly in our IF statement:
IF DERIFY(INPIC, #!12345G<HE#) = !
THEN /* DALID */
ELSE /*INDALID*/
Reminder on performance:
There is a big diference in the efciency of VERIFY used with a constant
and variable second argument. Always try to use it with a constant.
MODULE 09 Page 12 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
TRANSLATE
At frst sight this might seem not to be very useful, but with a little thought on the
way in which it is applied it can be widely used in commercial work.
Uses:
Conversion from one set of codes to another
Multi-feld validation
Editing and reformatting
The bare description of TRANSLATE leads to the thought that it is useful for
simple translation from one character set to another (ASCII to EBCDIC for
example), but it is more useful as a "quick and dirty" alternative to VERIFY
Example:
DCL 1 INR,
3 FLIHTBDETS,
5 N;$"ER CHAR(H),
5 F;AL CHAR(1),
5 CAPY CHAR(3),
3 DATE,
5 DAY CHAR(2),
5 $ONTH CHAR(2),
5 YEAR CHAR(2);
In this incoming record, the data has not yet been validated, which is why all the
felds are declared as CHAR. We need to validate it according to the following:
NUMBER Numeric
QUAL Letter A - G
CAPY Numeric
DAY Numeric
MONTH Numeric
YEAR Numeric
we can do this as follows:
IF TRANSLATE(STRIN(INR),#AAAAAAEEEEEEEEE#,
#"CDEF!12345G<H#)
MODULE 09 Page 13 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
= #EEEEEEEEAEEEEEEEEE#
THEN /*DALID*/
The translation has converted all numerics in the range 0-8 into 9, and left
9 alone. It has also translated letters in the range B-G into A, and left A
alone. If the data was valid, then the result of translating it would be
#EEEEEEEEAEEEEEEEEE#9
Note that we need to use STRING to produce a single CHAR value which
we can compare in the IF. The advantage of this technique is that the
hardware is able to do the TRANSLATE very efciently - with a single
instruction as long as we have fully defned the translation at compile
time. This means using constants for both the second and third
arguments. In fact this is not a very arduous requirement, as the
specifcation would determine the form of the TRANSLATE.
MODULE 09 Page 14 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
PSEUDO-VARIABLES
All the Built-In Functions we've seen have worked in the same way. We
have supplied the function with a set of arguments, and the function has
returned to us a value we can use. Pseudo-variables in PL/1 look like
functions, but used in the wrong way. It's important not to think of them
like this - because they really are something totally diferent. There are
two of them we need to look at the moment - SUBSTR and STRING
SUBSTR Pseudo-variable
When we assign a value to a CHAR variable - it flls it. If we assigned 2
characters to a 10 character variable, then the 2 characters would go into
the frst two positions, and PL/1 would automatically fll the rest with
spaces. If we had wanted to leave the last 8 characters untouched, then
we would have to declare another variable DEF on our original one and
assign to that:
DCL C1! CHAR(1!);
DCL C2DEF CHAR(2) DEF(C1!);
C2DEF = #A"#;
Here the 'AB' goes into the frst two characters of C10, and the other 8 are
untouched. If we'd wanted to put those two characters into a variable
position in C10, then we'd have ended up with a lot of DEF variables. We
achieve the same result using the SUBSTR pseudo-variable:
DCL C1! CHAR(1!);
S;"STR(C'!,1,2) = #A"#;
DCL I "IN FIXED(15);
S;"STR(C1!,1,2) = #A"#;
As with the Built-In Function SUBSTR, we must make sure that the
reference we use is valid. In the above example, if I had been less than 1
or greater than 9 then the fnal statement would have been invalid -
because we'd have "fallen of the end" of C10.
MODULE 09 Page 15 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
Remember that the SUBSTR pseudo-variable is just like the Built-In
Function of the same name as regards the rules, but we have to look on it
as, literally, a "pseudo" variable.
MODULE 09 Page 16 of 16
BASIC PL/1 BUILT-IN FUNCTIONS
STRING Pseudo-variable
The function this performs is the reverse of that done by the Built-In Function.
Take this example:
DCL 1 ABSTR;C,
3 EL1 CHAR(1!),
3 EL2 CHAR(G),
3 EL3 CHAR(3);
ABSTR;C = #THE F;ICK "ROWN FOX#;
The result of this would be to put 'THE QUICK' into EL1, 'THE Q' into EL2 and
'THE' into EL3. If we use the STRING Pseudo-variable, we get this:
STRING(A_STRUC) = 'THE QUICK BROWN FOX';
and EL1 gets 'THE QUICK ', EL2 gets 'BROWN' and EL3 gets 'FOX'. PL/1 has
abandoned the structuring for the moment, and treated the whole of
A_STRUC's storage as a CHAR receiving feld for the duration of the
assignment.
MODULE 09 Page 17 of 16

You might also like