IBM SC34-5764-01 User Manual

CICS Transaction Server fo r VSE/ESA
REXX Guide

SC34-5764-01
CICS Transaction Server fo r VSE/ESA
REXX Guide

SC34-5764-01
Note!
Before using this information and the product it supports, be sure to read the general information under “Notices” on page
443.
Second edition (September 2000)
© Copyright IBM Corporation 1992, 2009.
US Government Users Restricted Rights – Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.

Contents

Preface ....................................xix
What this book is about ..............................xix
Who this book is for ...............................xix
What you need to know to understand this book .....................xix
Prerequisites .................................xix
Part 1. User's Guide..............................1
Chapter 1. Introduction ..............................3
What is REXX?..................................3
Features of REXX.................................3
Ease of use ..................................3
Free format ..................................3
Convenient built-in functions ............................3
Debugging capabilities ..............................3
Interpreted language ...............................3
Extensive parsing capabilities ...........................3
Components of REXX ...............................4
Chapter 2. Writing and Running a REXX Program ....................5
What you need to run a REXX Program? ........................5
What is a REXX Program? .............................5
Syntax of REXX Instructions .............................6
The Format of REXX Instructions ..........................6
The Letter Case of REXX Instructions ........................6
Types of REXX Clauses .............................9
Programs Using Double-Byte Character Set Names ....................10
Typing in a Program ...............................11
Running a Program ...............................11
Interpreting Error Messages ............................12
How to Prevent Translation to Uppercase .......................13
Characters within a program ...........................13
Characters Input to a program ...........................14
Exercises - Running and Modifying the Example Programs ................14
Passing Information to a program ..........................14
Getting Information from the Program Stack or Terminal Input Device ............14
Specifying Values When Calling a program ......................15
Preventing Translation of Input to Uppercase .....................16
Passing Arguments ...............................17
Chapter 3. Using Variables and Expressions .....................19
Program Variables ................................19
Using Variables .................................19
Variable Names ................................19
Variable Values ................................20
Using Expressions ................................21
Arithmetic Operators ..............................21
Comparison Operators .............................23
Logical (Boolean) Operators ...........................25
Concatenation Operators.............................27
Priority of Operators ..............................28
Tracing Expressions with the TRACE Instruction .....................29
Tracing Operations ...............................29
© Copyright IBM Corp. 1992, 2009 iii
Tracing Results ................................30
Exercises - Using the TRACE Instruction .......................30
Chapter 4. Controlling the Flow within a program ...................33
Conditional, Looping, and Interrupt Instructions .....................33
Using Conditional Instructions ............................33
IF...THEN...ELSE Instructions ...........................33
Nested IF...THEN...ELSE Instructions ........................34
SELECT WHEN...OTHERWISE...END Instruction....................37
Using Looping Instructions .............................39
Repetitive Loops ................................39
Conditional Loops ...............................42
Combining Types of Loops ............................46
Nested DO Loops ...............................46
Using Interrupt Instructions .............................48
EXIT Instruction ................................48
CALL and RETURN Instructions ..........................49
SIGNAL Instruction ...............................50
Chapter 5. Using Functions ............................51
What is a Function? ...............................51
Example of a Function .............................51
Built-In Functions ................................52
Arithmetic Functions ..............................53
Comparison Functions..............................53
Conversion Functions ..............................53
Formatting Functions ..............................54
String Manipulating Functions ...........................54
Miscellaneous Functions .............................55
Testing Input with Built-In Functions .........................55
Chapter 6. Writing Subroutines and Functions.....................57
What are Subroutines and Functions? .........................57
When to Write Subroutines Rather Than Functions ...................57
Writing Subroutines and Functions ..........................58
When to Use Internal Versus External Subroutines or Functions ..............60
Passing Information ..............................60
Receiving Information from a Subroutine or Function ..................66
Subroutines and Functions—Similarities and Differences ..................70
Chapter 7. Manipulating Data ...........................71
Using Compound Variables and Stems ........................71
What Is a Compound Variable? ..........................71
Using Stems .................................72
Parsing Data ..................................73
Parsing Instructions...............................73
More about Parsing into Words ..........................75
Parsing with Patterns ..............................75
Parsing Multiple Strings as Arguments ........................78
Chapter 8. Using Commands from a program .....................81
Types of Commands ...............................81
Using Quotations Marks in Commands .......................81
Using Variables in Commands ...........................81
Calling Another REXX Program as a Command ....................82
Issuing Commands from a program
..........................82
iv CICS TS for VSE/ESA: REXX Guide
What is a Host Command Environment? .......................82
How Is a Command Passed to the Host Environment?..................83
Changing the Host Command Environment ......................83
Chapter 9. Diagnosing Problems within a program ...................85
Debugging Programs ...............................85
Tracing Commands with the TRACE Instruction ....................85
Using REXX Special Variables RC and SIGL .....................85
Tracing with the Interactive Debug Facility ......................86
Saving Interactive TRACE Output .........................87
Chapter 10. Programming Style and Techniques ....................89
Consider the Data ................................89
Test Yourself... ................................89
Happy Hour ..................................90
Designing a Program ...............................92
Methods for Designing Loops ...........................93
The Conclusion ................................93
What Do We Have So Far?............................94
Stepwise Refinement: An Example .........................94
Reconsider the Data ..............................95
Correcting Your Program ..............................95
Modifying Your Program .............................95
Tracing Your Program ..............................95
Coding Style ..................................96
Part 2. Reference ..............................101
Chapter 11. Introduction .............................103
Who Should Read This Reference ..........................103
How to Use This Reference ............................103
Overview of Product Features ...........................104
SAA Level 2 REXX Language Support Under REXX/CICS ................104
Support for the Interpretive Execution of REXX Execs .................104
CICS-Based Text Editor for REXX Execs and Data ..................104
VSAM-Based File System for REXX Execs and Data ..................104
VSE Librarian Sublibraries............................104
Dynamic Support for EXEC CICS Commands ....................105
REXX Interface to CEDA and CEMT Transaction Programs ...............105
High-level Client/Server Support .........................105
Support for Commands Written in REXX ......................105
Command Definition of REXX Commands ......................105
Support for System and User Profile Execs .....................105
Shared Execs in Virtual Storage .........................105
SQL Interface ................................106
How to Read the Syntax Diagrams .........................106
Chapter 12. REXX General Concepts ........................109
Structure and General Syntax ...........................109
Characters .................................110
Comments .................................110
Tokens ...................................111
Implied Semicolons ..............................114
Continuations ................................115
Expressions and Operators ............................115
Expressions .................................115
Contents v
Operators ..................................115
Parentheses and Operator Precedence .......................118
Clauses and Instructions .............................120
Null Clauses .................................120
Labels ...................................120
Instructions .................................120
Assignments .................................120
Keyword Instructions ..............................120
Commands .................................120
Assignments and Symbols.............................121
Constant Symbols ...............................121
Simple Symbols ...............................122
Compound Symbols ..............................122
Stems ...................................123
Commands to External Environments ........................124
Environment .................................124
Commands .................................124
Basic Structure of REXX Running Under CICS .....................125
REXX Exec Invocation .............................125
Where Execs Execute .............................126
Locating and Loading Execs ...........................126
Editing Execs ................................126
REXX File System ..............................127
Control of Exec Execution Search Order ......................127
Adding User Written Commands .........................127
Support of Standard REXX Features .........................127
SAY and TRACE Statements...........................127
PULL and PARSE EXTERNAL Statements......................127
REXX Stack Support ..............................127
REXX Function Support ............................127
REXX Command Environment Support ........................128
Adding REXX Host Command Environments .....................128
Support of Standard CICS Features/Facilities......................128
CICS Mapped I/O Support............................128
Dataset I/O Services ..............................128
Interfaces to CICS Facilities and Services ......................128
Issuing User Applications From Execs .......................128
REXX Interfaces to CICS Storage Queues ......................128
Pseudo-conversational Transaction Support .....................129
Interfaces to Other Programming Languages ......................129
DBCS Support ................................129
Miscellaneous Features .............................129
Chapter 13. Keyword Instructions .........................131
ADDRESS ..................................132
ARG.....................................134
CALL ....................................135
DO.....................................138
DROP ....................................142
EXIT.....................................143
IF......................................144
INTERPRET ..................................145
ITERATE ...................................147
LEAVE....................................148
NOP.....................................149
NUMERIC...................................150
vi CICS TS for VSE/ESA: REXX Guide
OPTIONS ...................................151
PARSE ....................................152
PROCEDURE .................................155
PULL ....................................158
PUSH ....................................159
QUEUE ...................................160
RETURN ...................................161
SAY.....................................162
SELECT ...................................163
SIGNAL ...................................164
TRACE....................................166
UPPER....................................170
Chapter 14. Functions ..............................171
Syntax ....................................171
Functions and Subroutines ............................171
Search Order ................................172
Errors During Execution ............................173
Built-in Functions ................................174
ABBREV (Abbreviation) .............................175
ABS (Absolute Value) .............................175
ADDRESS .................................175
ARG (Argument) ...............................175
BITAND (Bit by Bit AND) ............................176
BITOR (Bit by Bit OR) .............................177
BITXOR (Bit by Bit Exclusive OR) .........................177
B2X (Binary to Hexadecimal) ...........................177
CENTER/CENTRE ..............................178
COMPARE .................................178
CONDITION .................................178
COPIES ..................................179
C2D (Character to Decimal) ...........................179
C2X (Character to Hexadecimal) .........................180
DATATYPE .................................180
DATE...................................181
DBCS (Double-Byte Character Set Functions) ....................183
DELSTR (Delete String) ............................183
DELWORD (Delete Word) ............................183
DIGITS ...................................183
D2C (Decimal to Character) ...........................183
D2X (Decimal to Hexadecimal) ..........................184
ERRORTEXT ................................184
EXTERNALS ................................185
FIND ...................................185
FORM ...................................185
FORMAT ..................................185
FUZZ ...................................186
INDEX ...................................187
INSERT ..................................187
JUSTIFY ..................................187
LASTPOS (Last Position) ............................188
LEFT ...................................188
LENGTH ..................................188
LINESIZE
..................................188
MAX (Maximum) ...............................188
MIN (Minimum) ................................189
Contents vii
OVERLAY..................................189
POS (Position) ................................189
QUEUED ..................................190
RANDOM ..................................190
REVERSE .................................191
RIGHT ...................................191
SIGN ...................................191
SOURCELINE ................................191
SPACE...................................191
STORAGE .................................192
STRIP ...................................192
SUBSTR (Substring) ..............................192
SUBWORD .................................193
SYMBOL ..................................193
TIME ...................................193
TRACE...................................195
TRANSLATE.................................195
TRUNC (Truncate) ..............................195
USERID ..................................196
VALUE ...................................196
VERIFY ..................................197
WORD ...................................197
WORDINDEX ................................198
WORDLENGTH ...............................198
WORDPOS (Word Position) ...........................198
WORDS ..................................198
XRANGE (Hexadecimal Range)..........................198
X2B (Hexadecimal to Binary) ...........................199
X2C (Hexadecimal to Character) .........................199
X2D (Hexadecimal to Decimal) ..........................199
External Functions Provided in REXX/CICS ......................200
STORAGE .................................200
SYSSBA ..................................201
Chapter 15. Parsing...............................203
General Description ...............................203
Simple Templates for Parsing into Words ......................203
Templates Containing String Patterns........................205
Templates Containing Positional (Numeric) Patterns ..................206
Parsing with Variable Patterns ..........................209
Using UPPER ................................209
Parsing Instructions Summary ..........................210
Parsing Instructions Examples ..........................210
Advanced Topics in Parsing ............................211
Parsing Multiple Strings .............................211
Combining String and Positional Patterns: A Special Case ................212
Parsing with DBCS Characters ..........................213
Details of Steps in Parsing ...........................213
Chapter 16. Numbers and Arithmetic ........................217
Introduction ..................................217
Definition ...................................218
Numbers ..................................218
Precision
Arithmetic Operators ..............................218
Arithmetic Operation Rules—Basic Operators.....................219
..................................218
viii CICS TS for VSE/ESA: REXX Guide
Arithmetic Operation Rules—Additional Operators ...................220
Numeric Comparisons .............................222
Exponential Notation ..............................222
Numeric Information ..............................224
Whole Numbers ...............................224
Numbers Used Directly by REXX .........................224
Errors ...................................224
Chapter 17. Conditions and Condition Traps .....................225
Action Taken When a Condition Is Not Trapped .....................226
Action Taken When a Condition Is Trapped ......................226
Condition Information ..............................228
Descriptive Strings ..............................228
Special Variables ................................228
The Special Variable RC ............................228
The Special Variable SIGL............................228
Chapter 18. REXX/CICS Text Editor ........................231
Invocation ...................................231
Screen Format .................................232
Prefix Commands ................................232
Individual Line Commands............................232
Consecutive Block Commands ..........................233
Destination Commands .............................233
Macros Under the REXX/CICS Editor ........................233
Command Line Commands ............................234
ARBCHAR .................................234
ARGS ...................................234
BACKWARD.................................235
BOTTOM ..................................235
CANCEL ..................................236
CASE ...................................236
CHANGE ..................................237
CMDLINE ..................................237
CTLCHAR .................................238
CURLINE ..................................238
DISPLAY ..................................239
DOWN ...................................239
EDIT....................................240
EXEC ...................................241
FILE ....................................241
FIND ...................................242
FORWARD.................................243
GET....................................243
GETLIB ..................................243
INPUT ...................................244
JOIN....................................244
LEFT ...................................245
LINEADD ..................................245
LPREFIX ..................................245
MACRO ..................................246
MSGLINE ..................................246
NULLS ...................................247
NUMBERS .................................247
PFKEY
...................................248
PFKLINE ..................................248
Contents ix
QQUIT ...................................249
QUERY ..................................249
QUIT ...................................250
RESERVED .................................251
RESET ...................................251
RIGHT ...................................251
SAVE...................................252
SORT...................................252
SPLIT ...................................253
STRIP ...................................253
SYNONYM .................................254
TOP....................................254
TRUNC...................................254
UP....................................255
Chapter 19. REXX/CICS File System ........................257
File Pools, Directories, and Files ..........................257
Current Directory and Path ............................258
Security ...................................259
RFS commands ................................259
AUTH ...................................259
CKDIR ...................................260
CKFILE ..................................260
COPY ...................................261
DELETE ..................................261
DISKR ...................................261
DISKW ...................................262
GETDIR..................................262
MKDIR ...................................263
RDIR ...................................263
RENAME ..................................264
File List Utility .................................264
Invocation ..................................264
Macros under the REXX/CICS File List Utility......................265
FLST Commands ................................265
CANCEL ..................................265
CD....................................266
COPY ...................................266
DELETE ..................................267
DOWN ...................................267
END....................................267
EXEC ...................................267
FLST ...................................268
MACRO ..................................269
PFKEY ...................................269
REFRESH .................................270
RENAME ..................................270
SORT...................................271
SYNONYM .................................271
UP....................................272
FLST Return Codes ...............................272
Running Execs and Transactions from FLST ......................272
Chapter 20. REXX/CICS List System ........................273
Directories and Lists ...............................273
Current Directory and Path ............................274
x CICS TS for VSE/ESA: REXX Guide
Security ...................................274
RLS commands ................................275
CKDIR ...................................275
DELETE ..................................275
LPULL ...................................275
LPUSH ...................................276
LQUEUE ..................................277
MKDIR ...................................277
READ ...................................277
VARDROP .................................278
VARGET ..................................278
VARPUT ..................................279
WRITE ...................................279
Chapter 21. REXX/CICS Command Definition .....................281
Background ..................................281
Highlights ...................................281
Accomplishing Command Definition .........................281
Command Arguments Passed to REXX Programs ....................282
Command Arguments Passed to Assembler Programs ..................282
CICPARMS Control Block .............................283
Non-REXX Language Interfaces ..........................284
CICGETV - Call to Get, Set, or Drop a REXX Variable ..................284
Operands ..................................284
Notes ...................................284
Chapter 22. REXX/CICS DB2 Interface .......................285
Programming Considerations ............................285
Embedding SQL Statements ............................285
Receiving the Results .............................287
Using the SQL Communications Area .......................288
Example Using SQL Statements .........................288
Chapter 23. REXX/CICS High-level Client/Server Support ................291
Overview ...................................291
High-level, Natural, Transparent REXX Client Interface .................291
Support for REXX-based Application Clients and Servers ................291
Value of REXX in Client/Server Computing.......................291
REXX/CICS Client Exec Example ..........................292
REXX/CICS Server Exec Example..........................293
Chapter 24. REXX/CICS Panel Facility .......................295
Facility ....................................295
Example of Panel Definition ...........................295
Defining Panels.................................296
Defining the Field Control Characters with the '.DEFINE' Verb ...............296
.DEFINE ...................................297
Default field control characters ..........................297
Operands ..................................298
Options...................................298
Defining the Actual PANEL Layout with the '.PANEL' Verb .................299
.PANEL....................................300
Operands ..................................301
Panel Generation and Panel Input/Output .......................301
PANEL RUNTIME
................................302
Operands ..................................303
Contents xi
Options...................................304
PANEL Variables ...............................305
Panel Facility Return Code Information .......................306
Return Codes ................................307
System Error Reason Codes ...........................307
Programmer Introduced Warning/Error Reason Codes .................307
State Codes and Input Codes ..........................308
Location Codes ................................310
Examples of Sample Panels ............................310
Example 1 .................................310
Example 2 .................................311
Example 3 .................................311
Example 4 .................................312
Example 5 .................................312
Example of a REXX Panel Program .........................312
Chapter 25. REXX/CICS Commands ........................319
AUTHUSER ..................................320
Operands ..................................320
Return Codes ................................320
Example ..................................320
Notes ...................................320
CD.....................................321
Operands ..................................321
Return Codes ................................321
Examples ..................................321
Note ....................................321
CEDA ....................................323
Operands ..................................323
Return Codes ................................323
Example ..................................323
CEMT ....................................324
Operands ..................................324
Return Codes ................................324
Example ..................................324
CLD.....................................325
Operands ..................................325
Return Codes ................................325
Examples ..................................325
Notes ...................................325
CONVTMAP ..................................326
Operands ..................................326
Return Codes ................................326
Example ..................................326
COPYR2S ..................................327
Operands ..................................327
Return Codes ................................328
Examples ..................................328
COPYS2R ..................................329
Operands ..................................329
Return Codes ................................330
Example ..................................330
Notes
C2S.....................................331
Operands ..................................331
Return Codes ................................331
...................................330
xii CICS TS for VSE/ESA: REXX Guide
Example ..................................331
Notes ...................................331
DEFCMD ...................................332
Operands ..................................332
Return Codes ................................333
Example ..................................333
Notes ...................................333
DEFSCMD ..................................335
Operands ..................................335
Return Codes ................................336
Example ..................................336
Notes ...................................336
DEFTRNID ..................................338
Operands ..................................338
Return Codes ................................338
Example ..................................338
Notes ...................................338
DIR.....................................339
Operands ..................................339
Return Codes ................................339
Examples ..................................339
Note ....................................339
EDIT.....................................340
Operands ..................................340
Return Codes ................................340
Example ..................................340
Note ....................................340
EXEC ....................................341
Operands ..................................341
Return Codes ................................341
Example ..................................341
EXECDROP ..................................342
Operands ..................................342
Return Codes ................................342
Example ..................................342
Note ....................................343
EXECIO ...................................344
Operands ..................................344
Return Codes ................................344
Examples ..................................344
Notes ...................................344
EXECLOAD ..................................346
Operands ..................................346
Return Codes ................................346
Example ..................................347
Notes ...................................347
EXECMAP ..................................348
Return Codes ................................348
Example ..................................348
EXPORT ...................................349
Operands ..................................349
Return Codes ................................349
Example ..................................349
Notes ...................................349
FILEPOOL ..................................350
Operands ..................................350
Contents xiii
Return Codes ................................350
Example ..................................351
Note ....................................351
FLST ....................................352
Operands ..................................352
Return Codes ................................352
Example ..................................352
Notes ...................................352
GETVERS ..................................353
Return Codes ................................353
Example ..................................353
HELP ....................................354
Operands ..................................354
Return Codes ................................354
IMPORT ...................................355
Operands ..................................355
Return Codes ................................355
Example ..................................355
LISTCMD ...................................356
Operands ..................................356
Return Codes ................................356
Example ..................................356
LISTCLIB ...................................357
Operands ..................................357
Return Codes ................................357
Example ..................................357
LISTELIB ...................................358
Operands ..................................358
Return Codes ................................358
Example ..................................358
LISTPOOL ..................................359
Operands ..................................359
Return Codes ................................359
Example ..................................359
Note ....................................359
LISTTRNID ..................................360
Return Codes ................................360
Example ..................................360
PATH....................................361
Operands ..................................361
Return Codes ................................361
Examples ..................................361
Notes ...................................361
PSEUDO ...................................362
Operands ..................................362
Return Codes ................................362
Example ..................................362
Note ....................................362
RFS.....................................363
Operands ..................................363
Return Codes ................................364
....................................365
Note
RLS.....................................366
Operands ..................................366
Return Codes ................................367
SCRNINFO ..................................368
xiv CICS TS for VSE/ESA: REXX Guide
Return Codes ................................368
Example ..................................368
Notes ...................................368
SET.....................................369
Operands ..................................369
Return Codes ................................370
Example ..................................370
Notes ...................................370
SETSYS ...................................371
Operands ..................................371
Return Codes ................................372
Example ..................................372
S2C.....................................373
Operands ..................................373
Return Codes ................................373
Example ..................................373
Notes ...................................373
TERMID ...................................374
Return Codes ................................374
Example ..................................374
WAITREAD ..................................375
Return Codes ................................375
Example ..................................375
Note ....................................375
WAITREQ...................................376
Return Codes ................................376
Example ..................................376
Part 3. Appendixes .............................377
Appendix A. Error Numbers and Messages .....................379
Appendix B. Return Codes ............................387
Panel Facility .................................387
SQL.....................................387
RFS and FLST .................................387
EDITOR and EDIT ...............................387
DIR.....................................388
SET.....................................388
CD.....................................388
PATH....................................388
RLS.....................................388
LISTCMD ...................................389
CLD.....................................389
DEFCMD ...................................389
DEFSCMD ..................................389
DEFTRNID ..................................390
EXECDROP ..................................390
EXECLOAD ..................................390
EXECMAP ..................................390
EXPORT and IMPORT ..............................390
FILEPOOL ..................................390
LISTCLIB and LISTELIB .............................391
GETVERS ..................................391
COPYR2S ..................................391
COPYS2R ..................................391
Contents xv
LISTPOOL ..................................391
LISTTRNID ..................................392
C2S.....................................392
PSEUDO ...................................392
AUTHUSER ..................................392
SETSYS ...................................392
S2C.....................................392
TERMID ...................................392
WAITREAD ..................................392
WAITREQ...................................393
EXEC ....................................393
CEDA and CEMT ................................393
EXECIO ...................................393
CONVTMAP ..................................393
SCRNINFO ..................................393
CICS ....................................393
Appendix C. Double-Byte Character Set (DBCS) Support ................395
General Description ...............................395
Enabling DBCS Data Operations and Symbol Use ...................396
Symbols and Strings ..............................396
Validation ..................................397
Instruction Examples ..............................397
DBCS Function Handling .............................399
Built-in Function Examples ...........................400
DBCS Processing Functions ............................404
Counting Option ...............................404
Function Descriptions ..............................404
DBADJUST .................................404
DBBRACKET ................................404
DBCENTER .................................405
DBCJUSTIFY ................................405
DBLEFT ..................................405
DBRIGHT ..................................406
DBRLEFT ..................................406
DBRRIGHT .................................406
DBTODBCS .................................407
DBTOSBCS .................................407
DBUNBRACKET ...............................407
DBVALIDATE ................................408
DBWIDTH..................................408
Appendix D. Reserved Keywords and Special Variables ................409
Reserved Keywords ...............................409
Special Variables ................................409
Appendix E. Debug Aids .............................411
Interactive Debugging of Programs .........................411
Interrupting Execution and Controlling Tracing .....................412
Appendix F. REXX/CICS Business Value Discussion ..................413
Business Solutions ...............................413
Product Positioning ...............................415
Appendix G. System Definition/Customization/Administration ..............417
Authorized REXX/CICS Commands/Authorized Command Options ..............417
xvi CICS TS for VSE/ESA: REXX Guide
System Profile Exec ...............................417
Authorized REXX/CICS VSE Librarian sublibraries ....................417
Defining Authorized Users .............................417
Setting System Options ..............................418
Defining and Initializing a REXX File System (RFS) File Pool ................418
Adding Files to a REXX File System (RFS) File Pool ...................418
RFS File Sharing Authorization ...........................418
Creating a PLT Entry for CICSTART .........................418
Security Exit ..................................418
CICSECX2 .................................418
Appendix H. Security ..............................421
REXX/CICS Supports Multiple Transaction Identifiers ...................421
REXX/CICS File Security .............................421
ESA/VSE Command Level Security .........................421
REXX/CICS Authorized Command Support ......................421
Security Definitions ...............................422
REXX/CICS General Users ...........................422
REXX/CICS Authorized Users ..........................422
REXX/CICS Authorized Commands ........................422
REXX/CICS Authorized Execs ..........................422
REXX/CICS System Sublibraries .........................422
Appendix I. Performance Considerations ......................425
Appendix J. Basic Mapping Support Example ....................427
Appendix K. Post-Installation Configuration .....................431
Create the RFS Filepools .............................431
Install Resource Definitions ............................431
Update LSRPOOL Definitions ...........................431
Rename supplied Procedures ...........................431
Update CICSTART.PROC .............................432
Update CICS Initialization JCL ...........................432
Format the RFS Filepools .............................433
Create the Help Files ..............................433
Verify the Installation ...............................434
Configure the REXX DB2 Interface .........................435
Bibliography .................................437
CICS Transaction Server for VSE/ESA Release 1 library .................437
Where to Find More Information ..........................438
Books from VSE/ESA 2.5 base program libraries ....................438
VSE/ESA Version 2 Release 5 ..........................438
High-Level Assembler Language (HLASM) ......................439
Language Environment for VSE/ESA (LE/VSE) ....................439
VSE/ICCF..................................439
VSE/POWER ................................439
VSE/VSAM .................................439
VTAM for VSE/ESA ..............................439
Books from VSE/ESA 2.5 optional program libraries ...................440
C for VSE/ESA (C/VSE) ............................440
COBOL for VSE/ESA (COBOL/VSE) ........................440
DB2 Server for VSE ..............................440
DL/I VSE ..................................441
PL/I for VSE/ESA (PL/I VSE)
...........................441
Contents xvii
Screen Definition Facility II (SDF II) ........................441
Notices ...................................443
Trademarks ..................................445
Index ....................................447
Sending your comments to IBM ..........................455
xviii CICS TS for VSE/ESA: REXX Guide

Preface

What this book is about

This book describes REXX/CICS or REXX for CICS Transaction Server for VSE/ESA. This IBM program product provides a native REXX-based application development, customization, prototyping, and procedures language environment for REXX/CICS, along with associated runtime facilities.

Who this book is for

This book is for users who need to refer to CICS Transaction Server for VSE/ESA REXX instructions and functions, and for those who need to learn more details about REXX language items such as parsing. It is also intended for anyone who wants to learn how to write REXX programs. The type of users include: application programmers, system programmers, end users, administrators, developers, testers, and support personnel.

What you need to know to understand this book

Within this book, reference may be made to Release 1. The function described in this book has been added since the release of CICS Transaction Server for VSE/ESA Release 1 and can be identified within the code as 1.1.1.
If you are not an experienced programmer, and are new to REXX, you should read the guide part of this book, see page 1.
The book contains two parts: a user's guide and a reference. The user's guide section will help you become familiar with REXX for CICS Transaction Server for VSE/ESA. The reference section contains the CICS Transaction Server for VSE/ESA REXX instructions, functions, and commands. The instructions, functions, and commands are listed alphabetically in their own sections. Also included are details about general concepts you need to know in order to program in REXX.
The programming language described by this book is called the REstructured eXtended eXecutor language (commonly referred to as REXX). This book also describes how the CICS Transaction Server for VSE/ESA REXX language processor (shortened, hereafter, to the language processor) processes or interprets the REstructured eXtended eXecutor language.

Prerequisites

REXX/CICS runs under CICS Transaction Server for VSE/ESA Version 1 or above. There are no other prerequisites (other than the prerequisites that CICS TS for VSE/ESA requires).
© Copyright IBM Corp. 1992, 2009 xix
xx CICS TS for VSE/ESA: REXX Guide

Part 1. User's Guide

© Copyright IBM Corp. 1992, 2009 1
2 CICS TS for VSE/ESA: REXX Guide

Chapter 1. Introduction

This chapter describes the REXX programming language and some of its features.

What is REXX?

REXX is an extremely versatile programming language. Common programming structure, readability, and free format make it a good language for beginners and general users. REXX is also suitable for more experienced computer professionals because it can be intermixed with commands to host environments, it provides powerful functions, and it has extensive mathematical capabilities.
REXX programs can do many tasks under CICS. These include issuing EXEC CICS commands, SQL statements, as well as commands to the CEDA (Resource Definition Online Transaction) and CEMT (Master Terminal Transaction) utilities.

Features of REXX

In addition to its versatility, REXX has many other features, some of which are:

Ease of use

The REXX language is easy to read and write because many instructions are meaningful English words. Unlike some lower level programming languages that use abbreviations, REXX instructions are common words, such as SAY, PULL, IF...THEN...ELSE..., DO...END, and EXIT.

Free format

There are few rules about REXX format. You need not start an instruction in a particular column. You can skip spaces in a line or skip entire lines. You can have an instruction span of many lines, or have multiple instructions on one line. You need not predefine variables. You can type instructions in upper, lower, or mixed case. The few rules about REXX format are covered in section “Syntax of REXX Instructions” on page 6.

Convenient built-in functions

REXX supplies built-in functions that perform various processing, searching, and comparison operations for both text and numbers. Other built-in functions provide formatting capabilities and arithmetic calculations.

Debugging capabilities

When a REXX program running in REXX/CICS encounters an error, REXX writes messages describing the error. You can also use the REXX TRACE instruction and the interactive debug facility to locate errors in programs.

Interpreted language

The REXX/CICS product includes the REXX/CICS interpreter. When a REXX program runs, the interpreter directly processes each line. Languages that are not interpreted must be compiled into machine language and possibly link-edited before they are run.

Extensive parsing capabilities

REXX includes extensive parsing capabilities for character manipulation. This parsing capability lets you set up a pattern to separate characters, numbers, and mixed input.
© Copyright IBM Corp. 1992, 2009 3
Introduction

Components of REXX

The various components of REXX make it a powerful tool for programmers. REXX is made up of: v Clauses, which can be instructions, null clauses, or labels. Instructions can be:
– Keyword instructions – Assignments – Commands (REXX/CICS and CICS commands and SQL).
The language processor processes keyword instructions and assignments.
v Built-in functions — These functions are built into the language processor and provide convenient
processing options.
v External functions — REXX/CICS provides these functions that interact with the system to do specific
tasks for REXX.
v Data stack functions — A data stack can store data for I/O and other types of processing.
4
CICS TS for VSE/ESA: REXX Guide

Chapter 2. Writing and Running a REXX Program

This chapter introduces programs and their syntax, describes the steps involved in writing and running programs, and explains concepts you need to understand to avoid common problems.

What you need to run a REXX Program?

Before you can run a REXX Program, you must configure the REXX support. Go through the following steps:
1. Create the RFS Filepools
2. Install Resource Definitions
3. Update LSRPOOL Definitions
4. Rename supplied Procedures
5. Update CICSTART.PROC
6. Update CICS Initialization JCL
7. Format the RFS Filepools
8. Create the Help Files
9. Verify the Installation
10. Configure the REXX DB2 Interface
For details on configuration, see Appendix K, “Post-Installation Configuration,” on page 431.

What is a REXX Program?

A REXX program consists of REXX language instructions that the REXX interpreter interprets directly. A program can also contain commands that the host environment executes, such as CICS commands (see page 81).
One advantage of the REXX language is its similarity to ordinary English. This similarity makes it easy to read and write a REXX program. For example, to write a line of output, you use the REXX instruction SAY followed by the text you want written.
/* Sample REXX Program */
SAY 'Hello world!'
Figure 1. Example of a Simple Program
This program starts with a comment line to identify it as a REXX program. A comment begins with /* and ends with */. More about comments and why you might need a REXX program identifier appears later on page 10.
When you run the program, the SAY instruction sends to the terminal output device:
Hello world!
Even in a longer program, the instructions are similar to ordinary English and are easy to understand. For example, you could use the following to call the program ADDTWO, which adds two numbers: From a CICS terminal you would clear the screen and enter:
REXX addtwo
For this example, the first number you will enter is 42, and the second number is 21. Here is the ADDTWO program:
© Copyright IBM Corp. 1992, 2009 5
Writing and Running a REXX Program
/**************************** REXX *********************************/ /* This program adds two numbers and produces their sum. */ /*******************************************************************/ say 'Enter first number.'
PULL number1 /* Assigns: number1=42 */
say 'Enter second number.'
PULL number2 /* Assigns: number2=21 */ sum = number1 + number2 SAY 'The sum of the two numbers is' sum'.'
Figure 2. Example of a Longer Program
When you run the example program, the first PULL instruction assigns the variable number1 the value 42. The second PULL instruction assigns the variable number2 the value 21. The next line contains an assignment. The language processor adds the values in number1 and number2 and assigns the result, 63, to sum. Finally, the SAY instruction displays the output line:
The sum of the two numbers is 63.
Before you try any examples, please read the next two sections, “Syntax of REXX Instructions” and “Typing in a Program” on page 11.

Syntax of REXX Instructions

Some programming languages have rigid rules about how and where you enter characters on each line. For example, assembler statements must begin in a certain column. REXX, on the other hand, has simple syntax rules. You can use upper or lower or mixed case. REXX has no restrictions about the columns in which you can type.
An instruction can begin in any column on any line. The following are all valid instructions.
SAY 'You can type in any column'
SAY 'You can type in any column'
SAY 'You can type in any column'
These instructions are sent to the terminal output device:
You can type in any column You can type in any column You can type in any column

The Format of REXX Instructions

The REXX language has free format. This means you can insert extra spaces between words. For example, the following all mean the same:
total=num1+num2 total =num1+num2 total = num1+num2 total = num1 + num2
You can also insert blank lines throughout a program without causing an error.

The Letter Case of REXX Instructions

You can enter a REXX instruction in lowercase, uppercase, or mixed case. For example, SAY, Say, and say all have the same meaning. The language processor translates alphabetic characters to uppercase, unless you enclose them in single or double quotation marks.
Using Quotation Marks in an Instruction
A series of characters within matching quotation marks is a literal string. The following examples contain literal strings.
6
CICS TS for VSE/ESA: REXX Guide
Writing and Running a REXX Program
SAY 'This is a REXX literal string.' /* Using single quotation marks */
SAY "This is a REXX literal string." /* Using double quotation marks */
Do not enclose a literal string with one each of the two different types of quotation marks. For example, the following is incorrect:
SAY 'This is a REXX literal string." /* Using mismatched quotation marks */
If you omit the quotation marks around a literal string in a SAY instruction, the language processor usually translates the statement to uppercase. For example,
SAY This is a REXX string.
results in:
THIS IS A REXX STRING.
(This assumes none of the words is the name of a variable that you have already assigned a value. In REXX, the default value of a variable is its own name in uppercase.)
If a string contains an apostrophe, you can enclose the literal string in double quotation marks.
SAY "This isn't difficult!"
You can also use two single quotation marks in place of the apostrophe, because a pair of single quotation marks is processed as one.
SAY 'This isn''t difficult!'
Either way, the outcome is the same.
This isn't difficult!
Ending an instruction
A line usually contains one instruction except when it contains a semicolon (;) or ends with a comma (,).
The end of the line or a semicolon indicates the end of an instruction. If you put one instruction on a line, the end of the line delineates the end of the instruction. If you put multiple instructions on one line, you must separate adjacent instructions with a semicolon.
SAY 'Hi!'; say 'Hi again!'; say 'Hi for the last time!'
This example would result in three lines.
Hi! Hi again! Hi for the last time!
Continuing an instruction
A comma is the continuation character. It indicates that the instruction continues to the next line. The comma, when used in this manner, also adds a space when the lines are concatenated. Here is how the comma continuation character works when a literal string is being continued on the next line.
SAY 'This is an extended',
'REXX literal string.'
The comma at the end of the first line adds a space (between extended and REXX when the two lines are concatenated for output. A single line results:
This is an extended REXX literal string.
The following two instructions are identical and yield the same result:
SAY 'This is',
'a string.'
Chapter 2. Writing and Running a REXX Program 7
Writing and Running a REXX Program
SAY 'This is' 'a string.'
The space between the two separate strings is preserved:
This is a string.
Continuing a literal string without adding a space
If you need to continue an instruction to a second or more lines, but do not want REXX to add spaces in the line, use the concatenation operand (two single OR bars, ||).
SAY 'This is an extended literal string that is bro'||,
'ken in an awkward place.'
This example results in one line no space in the word “broken”.
This is an extended literal string that is broken in an awkward place.
Also note that the following two instructions are identical and yield the same result:
SAY 'This is' ||,
'a string.'
SAY 'This is' || 'a string.'
These examples result in:
This isa string.
In both examples, the concatenation operator deletes spaces between the two strings.
The following example demonstrates the free format of REXX.
/************************* REXX *****************************/ SAY 'This is a REXX literal string.' SAY 'This is a REXX literal string.'
SAY 'This is a REXX literal string.' SAY, 'This', 'is', 'a', 'REXX', 'literal', 'string.'
SAY'This is a REXX literal string.';SAY'This is a REXX literal string.' SAY ' This is a REXX literal string.'
Figure 3. Example of Free Format
Running this example results in six lines of identical output, followed by one indented line.
This is a REXX literal string. This is a REXX literal string. This is a REXX literal string. This is a REXX literal string. This is a REXX literal string. This is a REXX literal string.
This is a REXX literal string.
Thus, you can begin an instruction anywhere on a line, you can insert blank lines, and you can insert extra spaces between words in an instruction. The language processor ignores blank lines, and it ignores spaces that are greater than one. This flexibility of format lets you insert blank lines and spaces to make a program easier to read.
Blanks and spaces are only significant during parsing, see section “Parsing Data” on page 73.
8
CICS TS for VSE/ESA: REXX Guide
Writing and Running a REXX Program

Types of REXX Clauses

REXX clauses can be: instructions, null clauses, and labels. Instructions can be keyword instructions, assignments, or commands. The following example shows a program with these types of clauses. A description of each type of clause follows the example.
/* QUOTA REXX program. Two car dealerships are competing to */ /* sell the most cars in 30 days. Who will win? */
store_a=0; store_b=0 DO 30
CALL sub END IF store_a>store_b THEN SAY "Store_a wins!"
ELSE IF store_b>store_a THEN SAY "Store_b wins!"
ELSE SAY "It's a tie!"
EXIT
sub: store_a=store_a+RANDOM(0,20) /* RANDOM returns a random number in */ store_b=store_b+RANDOM(0,20) /* in specified range, here 0 to 20 */ RETURN
Keyword Instructions
A keyword instruction tells the language processor to do something. It begins with a REXX keyword that identifies what the language processor is to do. For example, DO can group instructions and execute them repetitively, and IF tests whether a condition is met. SAY writes to the current terminal output device.
IF, THEN and ELSE are three keywords that work together in one instruction. Each keyword forms a clause, which is a subset of an instruction. If the expression that follows the IF keyword is true, the instruction that follows the THEN keyword is processed. Otherwise, the instruction that follows the ELSE keyword is processed. (Note that a semicolon is needed before the ELSE if you are putting an ELSE clause on the same line with a THEN.) If you want to put more than one instruction after a THEN or ELSE, use a DO before the group of instructions and an END after them. More information about the IF instruction appears in section “Using Conditional Instructions” on page 33.
The EXIT keyword tells the language processor to end the program. Using EXIT in the preceding example is necessary because, otherwise, the language processor would execute the code in the subroutine after the label sub:. EXIT is not necessary in some programs (such as those without subroutines), but it is good programming practice to include it. More about EXIT appears in section “EXIT Instruction” on page 48.
Assignment
An assignment gives a value to a variable or changes the current value of a variable. A simple assignment instruction is:
number = 4
In the preceding program, a simple assignment instruction is: store_a=0. The left side of the assignment (before the equal sign) contains the name of the variable to receive a value from the right side (after the equal sign). The right side can be an actual value (such as 4) or an expression. An expression is something that needs to be evaluated, such as an arithmetic expression. The expression can contain numbers, variables, or both.
number=4+4
number = number + 4
In the first example, the value of number is 8. If the second example directly followed the first in a program, the value of number would become 12. More about expressions is in section “Using Expressions” on page
21.
Chapter 2. Writing and Running a REXX Program 9
Writing and Running a REXX Program
Label
A label, such as sub: is a symbolic name followed by a colon. A label can contain either single- or double-byte characters or a combination of single- and double-byte characters. (Double-byte characters are valid only if OPTIONS ETMODE is the first instruction in your program.) A label identifies a portion of the program and is commonly used in subroutines and functions, and with the SIGNAL instruction. (Note that you need to include a RETURN instruction at the end of a subroutine to transfer control back to the main program.) More about the use of labels appears in Chapter 6, “Writing Subroutines and Functions,” on page 57 and section “SIGNAL Instruction” on page 50.
Null Clause
A null clause consists of only blanks or comments or both. The language processor ignores null clauses, but they make a program easier to read.
Comments
A comment begins with /* and ends with */. Comments can be on one or more lines or on part of a line. You can put information in a comment that might not be obvious to a person reading the REXX instructions. Comments at the beginning of a program can describe the overall purpose of the program and perhaps list special considerations. A comment next to an individual instruction can clarify its purpose.
Note: REXX/CICS does not require that a REXX program begin with a comment. However, for
portability reasons, you may want to start each REXX program with a comment that includes the word REXX.
Not every language processor requires this program identifier. However, to run the same exec on MVS TSO and CICS, you should include the /* REXX */ program identifier to satisfy TSO requirements.
Blank lines
Blank lines separate groups of instructions and aid readability. The more readable a program is, the easier it is to understand and maintain.
Commands
A command is a clause consisting of only an expression. Commands are sent to a previously defined environment for processing. (You should enclose in quotation marks any part of the expression not to be evaluated.) The example program did not include any commands. The following example includes a command in an ADDRESS instruction:
/* REXX program including a command */ ADDRESS REXXCICS 'DIR'
ADDRESS is a keyword instruction. When you specify an environment and a command on an ADDRESS instruction, a single command is sent to the environment you specify. In this case, the environment is
REXXCICS. The command is the expression that follows the environment:
'DIR'
The DIR command lists the files in your current file system directory. For more details about changing the host command environment, see section “Changing the Host Command Environment” on page 83.
More information about issuing commands appears in Chapter 8, “Using Commands from a program,” on page 81.

Programs Using Double-Byte Character Set Names

You can use double-byte character set (DBCS) names in your REXX programs for literal strings, symbols, and comments. Such character strings can be single-byte, double-byte, or a combination of both. To use DBCS names, OPTIONS ETMODE must be the first instruction in the program. This specifies that the language processor should check strings containing DBCS characters for validity. You must enclose DBCS characters within shift-out (SO) and shift-in (SI) delimiters. (The SO character is X'0E', and the SI
10
CICS TS for VSE/ESA: REXX Guide
Writing and Running a REXX Program
character is X'0F') The SO and SI characters are non-printable. In the following example, the less than (<) and greater than (>) symbols represent shift-out (SO) and shift-in (SI), respectively. For example, <.S.Y.M.D> and <.D.B.C.S.R.T.N> represent DBCS symbols in the following example.
Example
The following is an example of a program using a DBCS variable name and a DBCS subroutine label.
/* REXX */ OPTIONS 'ETMODE' /* ETMODE to enable DBCS variable names */ <.S.Y.M.D> = 10 /* Variable with DBCS characters between */
y.<.S.Y.M.D> = JUNK CALL <.D.B.C.S.R.T.N> /* Call subroutine with DBCS name */ EXIT <.D.B.C.S.R.T.N>: /* Subroutine with DBCS name */ DOi=1TO10
IF y.i = JUNK THEN /* Does y.i match the DBCS variable's
SAY 'Value of the DBCS variable is : ' <.S.Y.M.D> END RETURN
/* shift-out (<) and shift-in (>) */
value? */

Typing in a Program

When you type in the following program, use the REXX/CICS editor for files that reside in the REXX File System (RFS).
The name of the program is HELLO EXEC (for now, assume that the file type is exec).
1. Sign on to a CICS Transaction Server for VSE/ESA terminal by entering CESN and supplying your user
ID and password when it is requested.
2. Clear the screen.
3. Type:
edit hello.exec
4. Type in the program, exactly as it is shown in Figure 4, beginning with /* REXX HELLO EXEC */. Then
file it using the EDIT command:
====> file
Now your program is ready to run.
/* REXX HELLO EXEC */
/* A conversation */ say "Hello! What is your name?" pull who if who = "" then say "Hello stranger!" else say "Hello" who
Figure 4. HELLO EXEC

Running a Program

Clear the screen before running an exec. If you want to run a program that has a file type of EXEC, you type in REXX followed by its file name. In this case, type rexx hello on the command line and press Enter. Try it!
Suppose your name is Sam. Type sam and press Enter. Hello SAM is displayed.
Chapter 2. Writing and Running a REXX Program 11
Writing and Running a REXX Program
rexx hello Hello! What is your name? sam Hello SAM
Here is what happens:
1. The SAY instruction displays Hello! What is your name?
2. The PULL instruction pauses the program, waiting for a reply.
3. You type sam on the command line and then press Enter.
4. The PULL instruction puts the word SAM into the variable (the place in the computer's storage) called
who.
5. The IF instruction asks, Is who equal to nothing?
who=""
This means, “is the value stored in who equal to nothing?” To find out, REXX substitutes that stored value for the variable name. So the question now is: Is SAM equal to nothing?
"SAM" = ""
6. Not true. The instruction after then is not processed. Instead, REXX processes the instruction after else.
7. The SAY instruction displays "Hello" who, which is evaluated as
Hello SAM
Now, here is what happens if you press Enter without typing a response first.
hello Hello! What is your name?
Hello stranger!
Then again, maybe you did not understand that you had to type in your name. (Perhaps the program should make your part clearer.) Anyhow, if you just press Enter instead of typing a name:
1. The PULL instruction puts "" (nothing) into the place in the computer's storage called who.
2. Again, the IF instruction tests the variable
who=""
meaning: Is the value of who equal to nothing? When the value of who is substituted, this scans as:
""=""
And this time, it is true.
3. So the instruction after then is processed, and the instruction after else is not.

Interpreting Error Messages

When you run a program that contains an error, an error message often includes the line on which the error occurred and gives an explanation of the error. Error messages can result from syntax errors and from computational errors. For example, the following program has a syntax error.
12
CICS TS for VSE/ESA: REXX Guide
Writing and Running a REXX Program
/************************** REXX **********************************/ /* This REXX program contains a deliberate error of not closing */ /* a comment. Without the error, it would pull input to produce */ /* a greeting. */ /******************************************************************/
PULL who /* Get the person's name. IF who = '' THEN
SAY 'Hello, stranger'
ELSE
SAY 'Hello,' who
Figure 5. Example of a program with a Syntax Error
When the program runs, the language processor sends the following lines of output.
7 +++ PULL who /* Get the person's name.IF who = '' THEN SAY 'Hello, stranger'ELSE SAY 'Hello,' who CICREX453E Error 6 running HELLO EXEC, line 7: Unmatched "/*" or quote
The program runs until the language processor detects the error, the missing */ at the end of the comment. The PULL instruction does not use the data from the data stack or terminal because this line contains the syntax error. The program ends, and the language processor sends the error messages.
The first error message begins with the line number of the statement where the language processor detected the error. Three pluses (+++) and the contents of the statement follow this.
7 +++ PULL who /* Get the person's name.IF who = '' THEN SAY 'Hello, stranger' ELSE SAY 'Hello,' who
The second error message begins with the message number. A message containing the program name, the line where the language processor found the error, and an explanation of the error follow this.
CICREX453E Error 6 running HELLO EXEC, line 7: Unmatched "/*" or quote
For more information about the error, you can go to the message explanations in Appendix A, “Error Numbers and Messages,” on page 379.
To fix the syntax error in this program, add */ to the end of the comment on line 7.
PULL who /* Get the person's name. */

How to Prevent Translation to Uppercase

The language processor generally translates alphabetic characters to uppercase before processing them. The alphabetic characters can be within a program, such as words in a REXX instruction, or they can be external to a program and processed as input. You can prevent the translation to uppercase as follows:

Characters within a program

To prevent translation of alphabetic characters in a program to uppercase, simply enclose the characters in single or double quotation marks. The language processor does not change numbers and special characters, regardless of whether they are in quotation marks. Suppose you use a SAY instruction with a phrase containing a mixture of alphabetic characters, numbers, and special characters; the language processor changes only the alphabetic characters.
SAY The bill for lunch comes to £123.51!
results in:
THE BILL FOR LUNCH COMES TO £123.51!
(This example assumes none of the words are the names of variables that have been assigned other values.)
Chapter 2. Writing and Running a REXX Program 13
Writing and Running a REXX Program
Quotation marks ensure that information in a program is processed exactly as typed. This is important in the following situations:
v For output that must be lowercase or a mixture of uppercase and lowercase. v To ensure that commands are processed correctly. For example, if a variable name in a program is the
same as a command name, the program can end in error when the command is issued. It is a good programming practice to avoid using variable names that are the same as commands and to enclose all commands in quotation marks.

Characters Input to a program

When reading input or passing input from another program, the language processor also changes alphabetic characters to uppercase before processing them. To prevent translation to uppercase, use the PARSE instruction.
For example, the following program reads input from the terminal and sends this information to the terminal output device.
/************************** REXX ***********************************/ /* This REXX program gets the name of an animal from the input */ /* stream and sends it to the terminal. */ /*******************************************************************/
PULL animal /* Get the animal name.*/ SAY animal
Figure 6. Example of Reading Input and Writing Output
If the input is tyrannosaurus, the language processor produces the output:
TYRANNOSAURUS
To cause the language processor to read input exactly as it is presented, use the PARSE PULL instruction instead of the PULL instruction.
PARSE PULL animal
Now if the input is TyRannOsauRus, the output is:
TyRannOsauRus

Exercises - Running and Modifying the Example Programs

You can write and run the preceding example. Now change the PULL instruction to a PARSE PULL instruction and note the difference.

Passing Information to a program

When a program runs, you can pass information to it in several ways:
v By using PULL to get information from the program stack or terminal input device. v By specifying input when calling the program.

Getting Information from the Program Stack or Terminal Input Device

The PULL instruction is one way for a program to receive input. Repeating an earlier example shows this. Here is how to call the ADDTWO program:
REXX addtwo
Here is the ADDTWO program.
14
CICS TS for VSE/ESA: REXX Guide
Writing and Running a REXX Program
/**************************** REXX ******************************/ /* This program adds two numbers and produces their sum. */ /****************************************************************/
PULL number1 PULL number2 sum = number1 + number2 SAY 'The sum of the two numbers is' sum'.'
Figure 7. Example of a program That Uses PULL
The PULL instruction can extract more than one value at a time from the terminal by separating a line of input. The following variation of the example shows this.
REXX addtwo 42 21
The PULL instruction extracts the numbers 42 and 21 from the terminal.
/**************************** REXX ******************************/ /* This program adds two numbers and says their sum */ /****************************************************************/
PULL number1 number2 sum = number1 + number2 SAY 'The sum of the two numbers is' sum'.'
Figure 8. Variation of an Example that Uses PULL

Specifying Values When Calling a program

Another way for a program to receive input is through values you specify when you call the program. For example to pass the two numbers 42 and 21 to a program named ADD, you could use the CICS command:
REXX add 42 21
The program ADD uses the ARG instruction to assign the input to variables as shown in the following example.
/**************************** REXX ******************************/ /* This program receives two numbers as input, adds them, and */ /* produces their sum. */ /****************************************************************/
ARG number1 number2 sum = number1 + number2 SAY 'The sum of the two numbers is' sum'.'
Figure 9. Example of a program That Uses the ARG Instruction
ARG assigns the first number 42,tonumber1, and the second number 21,tonumber2.
If the number of values is fewer or more than the number of variable names after ARG or PULL, errors can occur, as the following sections describe.
Specifying Too Few Values
If you specify fewer values than the number of variables after PULL or ARG, the extra variables are set to the null string. Here is an example in which you pass only one number to the program:
REXX add 42
The language processor assigns the value 42 to number1, the first variable following ARG. It assigns the null string to number2, the second variable. In this situation, the program ends with an error when it tries to add the two variables. In other situations, the program might not end in error.
Specifying Too Many Values
When you specify more values than the number of variables following PULL or ARG, the last variable gets the remaining values. For example, you pass three numbers to the program ADD:
Chapter 2. Writing and Running a REXX Program 15
Writing and Running a REXX Program
REXX add 42 21 10
The language processor assigns the value 42 to number1, the first variable following ARG. It assigns the value 21 10 to number2, the second variable. In this situation, the program ends with an error when it tries to add the two variables. In other situations, the program might not end in error.
To prevent the last variable from getting the remaining values, use a period (.) at the end of the PULL or ARG instruction.
ARG number1 number2 .
The period acts as a dummy variable to collect unwanted extra information. (In this case, number1 receives 42, number2 receives 21, and the period ensures the 10 is discarded. If there is no extra information, the
period is ignored. You can also use a period as a placeholder within the PULL or ARG instruction as follows:
ARG . number1 number2
In this case, the first value, 42, is discarded and number1 and number2 get the next two values, 21 and 10.

Preventing Translation of Input to Uppercase

Like the PULL instruction, the ARG instruction changes alphabetic characters to uppercase. To prevent translation to uppercase, use PARSE ARG as in the following example.
/**************************** REXX ********************************/ /* This program receives the last name, first name, and score of */ /* a student and reports the name and score. */ /******************************************************************/
PARSE ARG lastname firstname score SAY firstname lastname 'received a score of' score'.'
Figure 10. Example of a program That Uses PARSE ARG
Exercises - Using the ARG Instruction
The left column shows the input values sent to a program. The right column is the ARG instruction within the program that receives the input. What value does each variable receive?
Input Variables Receiving Input
1. 115 -23 66 5.8
ARG first second third
2. .2 0 569 2E6
ARG first second third fourth
3. 13 13 13 13
ARG first second third fourth fifth
4. Weber Joe 91
ARG lastname firstname score
5. Baker Amanda Marie 95
PARSE ARG lastname firstname score
6. Callahan Eunice 88 62
PARSE ARG lastname firstname score .
ANSWERS
1. first = 115, second = -23, third = 66 5.8
2. first = .2, second = 0, third = 569, fourth = 2E6
3. first = 13, second = 13, third = 13, fourth = 13, fifth = null
16
CICS TS for VSE/ESA: REXX Guide
Writing and Running a REXX Program
4. lastname = WEBER, firstname = JOE, score = 91
5. lastname = Baker, firstname = Amanda, score = Marie 95
6. lastname = Callahan, firstname = Eunice, score = 88

Passing Arguments

Values passed to a program are usually called arguments. An argument can consist of one word or a string of words. Blanks separate words within an argument from each other. The number of arguments passed depends on how the program is called.
Using the CALL Instruction or a REXX Function Call
When you call a REXX program using either the CALL instruction or a REXX function call, you can pass up to 20 arguments to the program. Separate each argument from the next with a comma.
For more information about functions and subroutines, see Chapter 6, “Writing Subroutines and Functions,” on page 57. For more information about arguments, see section “Parsing Multiple Strings as Arguments” on page 78.
Chapter 2. Writing and Running a REXX Program 17
18 CICS TS for VSE/ESA: REXX Guide

Chapter 3. Using Variables and Expressions

This chapter describes variables, expressions, and operators, and explains how to use them in REXX programs.

Program Variables

One of the most powerful aspects of computer programming is the ability to process variable data to achieve a result. Regardless of the complexity of a process, when data is unknown or varies, you substitute a symbol for the data. This is much like substituting x and y in an algebraic equation.
x=y+29
The symbol, when its value can vary, is called a variable. A group of symbols or numbers that must be calculated to be resolved is called an expression.

Using Variables

A variable is a character or group of characters representing a value. A variable can contain either single­or double-byte characters or both. (Double-byte characters are valid only if OPTIONS ETMODE is the first instruction of your program.) The following variable big represents the value one million or 1,000,000.
big = 1000000
Variables can refer to different values at different times. If you assign a different value to big, it gets the value of the new assignment, until it is changed again.
big = 999999999
Variables can also represent a value that is unknown when the program is written. In the following example, the user's name is unknown, so it is represented by the variable who.
PARSE PULL who /* and puts it in variable "who" */
/* Gets name from current input stream */

Variable Names

A variable name, the part that represents the value, is always on the left of the assignment statement and the value itself is on the right. In the following example, the variable name is variable1.
variable1 = 5 SAY variable1
As a result of the preceding assignment statement, the language processor assigns variable1 the value 5, and the SAY produces:
5
Variable names can consist of:
A–Z uppercase alphabetic
a–z lowercase alphabetic
0–9 numbers
?!._ special characters
X'41'–X'FE'
double-byte character set (DBCS) characters. (OPTIONS ETMODE must be the first instruction in your program for these characters to be valid in a variable name.)
Restrictions on the variable name are:
© Copyright IBM Corp. 1992, 2009 19
Using Variables and Expressions
v The first character cannot be 0 through 9 or a period (.) v The variable name cannot exceed 250 bytes. For names containing DBCS characters, count each
DBCS character as 2 bytes, and count the shift-out (SO) and shift-in (SI) as 1 byte each.
v SO (X'0E') and SI (X'0F') must delimit DBCS characters within a DBCS name. Also note that:
– SO and SI cannot be contiguous. – Nesting of SO / SI is not permitted. – A DBCS name cannot contain a DBCS blank (X'4040').
v The variable name should not be RC, SIGL, or RESULT, which are REXX special variables. More about
special variables appears later in this book.
Examples of acceptable variable names are:
ANSWER ?98B A Word3 number the_ultimate_value
Also, if OPTIONS ETMODE is the first instruction in your program, the following are valid DBCS variable names, where < represents shift-out, > represents shift-in, X, Y, and Z represent DBCS characters, and lowercase letters and numbers represent themselves.
<.X.Y.Z> number_<.X.Y.Z> <.X.Y>1234<.Z>

Variable Values

The value of the variable, which is the value the variable name represents, might be categorized as follows:
v A constant, which is a number that is expressed as:
An integer (12) A decimal (12.5) A floating point number (1.25E2) A signed number (-12) A string constant (' 12')
v A string, which is one or more words that may or may not be within quotation marks, such as:
This value can be a string. 'This value is a literal string.'
v The value from another variable, such as:
variable1 = variable2
In the preceding example, variable1 changes to the value of variable2, but variable2 remains the same.
v An expression, which is something that needs to be calculated, such as:
variable2 = 12 + 12 - .6 /* variable2 becomes 23.4 */
Before a variable is assigned a value, its value is the value of its own name translated to uppercase. For example, if the variable new has not been assigned a value, then
SAY new
produces
NEW
Exercises - Identifying Valid Variable Names
Which of the following are valid REXX variable names?
1. 8eight
2. £25.00
3. MixedCase
4. nine_to_five
5. result
20
CICS TS for VSE/ESA: REXX Guide
Using Variables and Expressions
ANSWERS
1. Incorrect, because the first character is a number.
2. Incorrect, because the first character is a “£”.
3. Valid
4. Valid
5. Valid, but it is a special variable name that you should use only to receive results from a subroutine.

Using Expressions

An expression is something that needs to be evaluated and consists of numbers, variables, or strings, and zero or more operators. The operators determine the kind of evaluation to do on the numbers, variables, and strings. There are four types of operators: arithmetic, comparison, logical, and concatenation.

Arithmetic Operators

Arithmetic operators work on valid numeric constants or on variables that represent valid numeric constants.
Types of Numeric Constants
12 A whole number has no decimal point or commas. Results of arithmetic operations with whole
numbers can contain a maximum of nine digits unless you override this default by using the NUMERIC DIGITS instruction. For information about the NUMERIC DIGITS instruction, see section section “NUMERIC” on page 150. Examples of whole numbers are:
123456789 0 91221 999
12.5 A decimal number includes a decimal point. Results of arithmetic operations with decimal
numbers are limited to a total maximum of nine digits (NUMERIC DIGITS default) before and after the decimal. Examples of decimal numbers are:
123456.789 0.888888888
1.25E2
A floating point number in exponential notation, is said to be in scientific notation. The number after the "E" represents the number of places the decimal point moves. Thus 1.25E2 (also written as 1.25E+2) moves the decimal point to the right two places and results in 125. When an "E" is followed by a minus (-), the decimal point moves to the left. For example, 1.25E-2 is .0125.
You can use floating point numbers to represent very large or very small numbers. For more information about scientific notation (floating point numbers), see section “Exponential Notation” on page 222.
-12 A signed number with a minus (-) next to the number represents a negative value. A signed
number with a plus (+) next to the number represents a positive value. When a number has no sign, it is processed as if it has a positive value.
The arithmetic operators you can use are:
Operator
Meaning
+ Add
Subtract
* Multiply
/ Divide
% Divide and return a whole number without a remainder
// Divide and return the remainder only
Chapter 3. Using Variables and Expressions 21
Using Variables and Expressions
** Raise a number to a whole number power
number
(Prefix −) Same as the subtraction 0 - number
+number
(Prefix +) Same as the addition 0 + number
Using numeric constants and arithmetic operators, you can write arithmetic expressions such as:
7 + 2 /* result is 9 */ 7 - 2 /* result is 5 */ 7 * 2 /* result is 14 */ 7 ** 2 /* result is 49 */ 7 ** 2.5 /* result is an error */
Division
Notice that three operators represent division. Each operator computes the result of a division expression in a different way.
/ Divide and express the answer possibly as a decimal number. For example:
7 / 2 /* result is 3.5 */ 6 / 2 /* result is 3 */
% Divide and express the answer as a whole number. The remainder is ignored. For example:
7 % 2 /* result is 3 */
// Divide and express the answer as the remainder only. For example:
7 // 2 /* result is 1 */
Order of Evaluation
When you have more than one operator in an arithmetic expression, the order of numbers and operators can be critical. For example, in the following expression, which operation does the language processor perform first?
7+2*(9/3)-1
Proceeding from left to right, the language processor evaluates the expression as follows:
v First it evaluates expressions within parentheses. v Then it evaluates expressions with operators of higher priority before expressions with operators of
lower priority.
Arithmetic operator priority is as follows, with the highest first:
Table 1. Arithmetic Operator Priority
- + Prefix operators
** Power (exponential)
*/%// Multiplication and division
+ - Addition and subtraction
Thus, the preceding example would be evaluated in the following order:
1. Expression in parentheses
7+2*(9/3)-1
\___/
3
2. Multiplication
22
CICS TS for VSE/ESA: REXX Guide
Using Variables and Expressions
7+2*3-1
\___/
6
3. Addition and subtraction from left to right
7+6-1=12
Using Arithmetic Expressions
You can use arithmetic expressions in a program many different ways. The following example uses several arithmetic operators to round and remove extra decimal places from a dollar and cents value.
/****************************** REXX *********************************/ /* This program computes the total price of an item including sales */ /* tax, rounded to two decimal places. The cost and percent of the */ /* tax (expressed as a decimal number) are passed to the program */ /* when you run it. */ /*********************************************************************/
PARSE ARG cost percent_tax
total = cost + (cost * percent_tax) /* Add tax to cost. */ price = ((total * 100 + .5) % 1) / 100 /* Round and remove extra */
SAY 'Your total cost is £'price'.'
Figure 11. Example Using Arithmetic Expressions
/* decimal places. */
Exercises—Calculating Arithmetic Expressions
1. What line of output does the following program produce?
/****************************** REXX ******************************/
pa=1 ma=1 kids = 3 SAY "There are" pa + ma + kids "people in this family."
2. What is the value of:
a. 6-4+1 b. 6-(4+1) c. 6*4+2 d. 6*(4+2) e. 24%5/2
ANSWERS
1. There are 5 people in this family.
2. The values are as follows:
a. 3 b. 1 c. 26 d. 36 e. 2

Comparison Operators

Expressions that use comparison operators do not return a number value as do arithmetic expressions. Comparison expressions return either 1, which represents true, or 0, which represents false.
Comparison operators can compare numbers or strings and perform evaluations, such as:
Are the terms equal? (A=Z) Is the first term greater than the second? (A>Z) Is the first term less than the second? (A<Z)
Chapter 3. Using Variables and Expressions 23
Using Variables and Expressions
For example, if A=4and Z=3, then the results of the previous comparison questions are:
(A=Z) Does4=3? 0 (False) (A>Z) Is4>3? 1 (True) (A<Z) Is4<3? 0 (False)
The more commonly used comparison operators are as follows:
Operator
Meaning
= Equal
== Strictly Equal
\= Not equal
\== Not strictly equal
> Greater than
< Less than
>< Greater than or less than (same as not equal)
>= Greater than or equal to
\< Not less than
<= Less than or equal to
\> Not greater than
Note: The NOT character (¬) is synonymous with the backslash (\). You can use the two characters
interchangeably according to availability and personal preference. This book uses the backslash (\) character.
The Strictly Equal and Equal Operators
When two expressions are strictly equal, everything including the blanks and case (when the expressions are characters) is exactly the same.
When two expressions are equal, they are resolved to be the same. The following expressions are all true.
'WORD' = word /* returns 1 */ 'word ' \== word /* returns 1 */ 'word' == 'word' /* returns 1 */
4e2 \== 400 /* returns 1 */ 4e2 \= 100 /* returns 1 */
Using Comparison Expressions
You often use a comparison expression in an IF...THEN...ELSE instruction. The following example uses an IF...THEN...ELSE instruction to compare two values. For more information about this instruction, see section “IF...THEN...ELSE Instructions” on page 33.
24
CICS TS for VSE/ESA: REXX Guide
Using Variables and Expressions
/****************************** REXX *********************************/ /* This program compares what you paid for lunch for two */ /* days in a row and then comments on the comparison. */ /*********************************************************************/
PARSE PULL yesterday /* Gets yesterday's price from input stream */
PARSE PULL today /* Gets today's price */
IF today > yesterday THEN /* lunch cost increased */
SAY "Today's lunch cost more than yesterday's."
ELSE /* lunch cost remained the same or decreased */
SAY "Today's lunch cost the same or less than yesterday's."
Figure 12. Example Using a Comparison Expression
Exercises - Using Comparison Expressions
1. Based on the preceding example of using a comparison expression, what result does the language
processor produce from the following lunch costs?
Yesterday's Lunch
Today's Lunch
4.42 3.75
3.50 3.50
3.75 4.42
2. What is the result (0 or 1) of the following expressions?
a. "Apples" = "Oranges" b. " Apples" = "Apples" c. " Apples" == "Apples" d. 100 = 1E2 e. 100 \= 1E2 f. 100 \== 1E2
ANSWERS
1. The language processor produces the following sentences:
a. Today's lunch cost the same or less than yesterday's. b. Today's lunch cost the same or less than yesterday's. c. Today's lunch cost more than yesterday's.
2. The expressions result in the following. Remember 0 is false and 1 is true.
a. 0 b. 1 c. 0 (The first " Apples" has a space.) d. 1 e. 0 f. 1

Logical (Boolean) Operators

Logical expressions, like comparison expressions, return 1 (true) or 0 (false) when processed. Logical operators combine two comparisons and return 1 or 0 depending on the results of the comparisons.
The logical operators are:
Chapter 3. Using Variables and Expressions 25
Using Variables and Expressions
Operator
Meaning
& AND
Returns 1 if both comparisons are true. For example:
(4 > 2) & (a = a) /* true, so result is 1 */
(2 > 4) & (a = a) /* false, so result is 0 */
| Inclusive OR
Returns 1 if at least one comparison is true. For example:
(4 > 2) | (5 = 3) /* at least one is true, so result is 1 */
(2 > 4) | (5 = 3) /* neither one is true, so result is 0 */
&& Exclusive OR
Returns 1 if only one comparison (but not both) is true. For example:
(4 > 2) && (5 = 3) /* only one is true, so result is 1 */
(4 > 2) && (5 = 5) /* both are true, so result is 0 */
(2 > 4) && (5 = 3) /* neither one is true, so result is 0 */
Prefix \,¬
Logical NOT
Negates—returning the opposite response. For example:
\ 0 /* opposite of 0, so result is 1 */
\ (4 > 2) /* opposite of true, so result is 0 */
Using Logical Expressions
You can use logical expressions in complex conditional instructions and as checkpoints to screen unwanted conditions. When you have a series of logical expressions, for clarification, use one or more sets of parentheses to enclose each expression.
IF ((A < B) | (J < D)) & ((M = Q) | (M = D)) THEN ....
The following example uses logical operators to make a decision.
/****************************** REXX ********************************/ /* This program receives arguments for a complex logical expression */ /* that determines whether a person should go skiing. The first */ /* argument is a season and the other two can be 'yes' or 'no'. */ /********************************************************************/
PARSE ARG season snowing broken_leg
IF ((season = 'WINTER') | (snowing ='YES')) & (broken_leg ='NO')
THEN SAY 'Go skiing.'
ELSE
SAY 'Stay home.'
Figure 13. Example Using Logical Expressions
When arguments passed to this example are SPRING YES NO, the IF clause translates as follows:
IF ((season = 'WINTER') | (snowing ='YES')) & (broken_leg ='NO') THEN
\______________/ \____________/ \_____________/
false true true
26
CICS TS for VSE/ESA: REXX Guide
Using Variables and Expressions
\___________________/ /
true /
\_____________________________/
true
As a result, when you run the program, it produces the result:
Go skiing.
Exercises - Using Logical Expressions
A student applying to colleges has decided to evaluate them according to the following specifications:
IF (inexpensive | scholarship) & (reputable | nearby) THEN
SAY "I'll consider it."
ELSE
SAY "Forget it!"
A college is inexpensive, did not offer a scholarship, is reputable, but is more than 1000 miles away. Should the student apply?
ANSWER
Yes. The conditional instruction works out as follows:
IF (inexpensive | scholarship) & (reputable | nearby) THEN ...
\__________/ \___________/ \_________/ \______/
true false true false
\___________/ \_________/
true true
\_________________________/
true

Concatenation Operators

Concatenation operators combine two terms into one. The terms can be strings, variables, expressions, or constants. Concatenation can be significant in formatting output.
The operators that indicate how to join two terms are as follows:
Operator
Meaning
blank Concatenates terms and places one blank between them. If more than one blank separates terms,
this becomes a single blank. For example:
SAY true blue /* result is TRUE BLUE */
|| Concatenates terms with no blanks between them. For example:
(8 / 2)||(3 * 3) /* result is 49 */
abuttal
Concatenates terms with no blanks between them. For example:
per_cent'%' /* if per_cent = 50, result
You can use abuttal only with terms that are of different types, such as a literal string and a symbol, or when only a comment separates two terms.
Using Concatenation Operators
One way to format output is to use variables and concatenation operators as in the following example.
is 50% */
Chapter 3. Using Variables and Expressions 27
Using Variables and Expressions
/****************************** REXX *********************************/ /* This program formats data into columns for output. */ /*********************************************************************/
sport = 'base' equipment = 'ball' column = ' ' cost = 5
SAY sport||equipment column '£' cost
Figure 14. Example Using Concatenation Operators
The result of this example is:
baseball £ 5
A more sophisticated way to format information is with parsing and templates. Information about parsing appears in section “Parsing Data” on page 73.

Priority of Operators

When more than one type of operator appears in an expression, what operation does the language processor do first?
IF (A > 7**B) & (B < 3)
Like the priority of operators for the arithmetic operators, there is an overall priority that includes all operators. The priority of operators is as follows with the highest first.
Table 2. Overall Operator Priority
\or¬ - + Prefix operators
** Power (exponential)
*/%// Multiply and divide
+ - Add and subtract
blank || abuttal Concatenation operators
== = >< and so on Comparison operators
& Logical AND
| && Inclusive OR and exclusive OR
Thus, given the following values
A=8 B=2 C=10
the language processor would evaluate the previous example
IF (A > 7**B) & (B < 3)
as follows:
1. Evaluate what is inside the first set of parentheses. a. Evaluate A to 8. b. Evaluate B to 2. c. Evaluate 7**2. d. Evaluate8>49isfalse (0).
2. Evaluate what is inside the next set of parentheses. a. Evaluate B to 2. b. Evaluate2<3istrue (1).
28
CICS TS for VSE/ESA: REXX Guide
Using Variables and Expressions
3. Evaluate 0&1is 0
Exercises - Priority of Operators
1. What are the answers to the following examples? a. 22 + (12 * 1) b. -6/-2>(45%7/2)-1 c. 10*2-(5+1)//5*2+15-1
2. In the example of the student and the college from the previous exercise on page “Exercises - Using Logical Expressions” on page 27, if the parentheses were removed from the student's formula, what would be the outcome for the college?
IF inexpensive | scholarship & reputable | nearby THEN
SAY "I'll consider it."
ELSE
SAY "Forget it!"
Remember the college is inexpensive, did not offer a scholarship, is reputable, but is 1000 miles away.
ANSWERS
1. The results are as follows: a. 34 (22 + 12 = 34) b. 1 (true) (3>3-1) c. 32(20-2+15-1)
2. I'll consider it. The & operator has priority, as follows, but the outcome is the same as the previous version with the
parentheses.
IF inexpensive | scholarship & reputable | nearby THEN
\_________/ \_________/ \_______/ \____/
true false true false
\ \___________/ /
\ false /
\_________________/ /
true /
\____________________/
true

Tracing Expressions with the TRACE Instruction

You can use the TRACE instruction to show how the language processor evaluates each operation of an expression as it reads it, or to show the final result of an expression. These two types of tracing are useful for debugging programs.

Tracing Operations

To trace operations within an expression, use the TRACE I (TRACE Intermediates) form of the TRACE instruction. The language processor breaks down all expressions that follow the instruction and analyzes them as:
>V> - Variable value - The data traced is the contents
>L> - Literal value - The data traced is a literal
>O> - Operation result - The data traced is the result
The following example uses the TRACE I instruction. (The line numbers are not part of the program. They facilitate the discussion of the example that follows it.)
of a variable.
(string, uninitialized variable, or constant).
of an operation on two terms.
Chapter 3. Using Variables and Expressions 29
Using Variables and Expressions
1 /************************* REXX ***************************/ 2 /* This program uses the TRACE instruction to show how */ 3 /* an expression is evaluated, operation by operation. */ 4 /**********************************************************/ 5 a=9 6 y=2 7 TRACE I 8
9 IFa+1>5*yTHEN 10 SAY 'a is big enough.' 11 ELSE NOP /* No operation on the ELSE path */
Figure 15. TRACE Shows How REXX Evaluates an Expression
When you run the example, the SAY instruction produces:
9*-*IFa+1>5*y
>V> "9" >L> "1" >O> "10" >L> "5" >V> "2" >O> "10" >O> "0"
The 9 is the line number. The *-* indicates that what follows is the data from the program, IFa+1<5*y. The remaining lines break down all the expressions.

Tracing Results

To trace only the final result of an expression, use the TRACE R (TRACE Results) form of the TRACE instruction. The language processor analyzes all expressions that follow the instruction as follows:
>>> Final result of an expression
If you changed the TRACE instruction operand in the previous example from an I to an R, you would see the following results.
9*-*IFa+1>5*y
>>> "0"
In addition to tracing operations and results, the TRACE instruction offers other types of tracing, see section “TRACE” on page 166.

Exercises - Using the TRACE Instruction

Write a program with a complex expression, such as:
IF(a>z)|(c<2*d)THEN ....
Define a, z, c, and d in the program and use the TRACE I instruction.
ANSWER
30
CICS TS for VSE/ESA: REXX Guide
Using Variables and Expressions
/****************************** REXX ********************************/ /* This program uses the TRACE instruction to show how the language */ /* processor evaluates an expression, operation by operation. */ /********************************************************************/
a=1 z=2 c=3 d=4
TRACE I
IF(a>z)|(c<2*d)THEN
SAY 'At least one expression was true.'
ELSE
SAY 'Neither expression was true.'
Figure 16. Possible Solution
When you run this program, it produces:
12*-*IF(a>z)|(c<2*d)
>V> "1" >V> "2" >O> "0" >V> "3" >L> "2" >V> "4" >O> "8" >O> "1" >O> "1" *-* THEN
13 *-* SAY 'At least one expression was true.'
>L> "At least one expression was true."
At least one expression was true.
Chapter 3. Using Variables and Expressions 31
Using Variables and Expressions
32
CICS TS for VSE/ESA: REXX Guide

Chapter 4. Controlling the Flow within a program

This chapter introduces instructions that alter the sequential execution of a program and demonstrates how to use those instructions.

Conditional, Looping, and Interrupt Instructions

Generally, when a program runs, one instruction after another executes, starting with the first and ending with the last. The language processor, unless told otherwise, executes instructions sequentially.
You can change the order of execution within a program by using REXX instructions that cause the language processor to skip some instructions, repeat others, or transfer control to another part of the program. These REXX instructions can be classified as follows:
v Conditional instructions set up at least one condition in the form of an expression. If the condition is
true, the language processor selects the path following that condition. Otherwise the language processor selects another path. The REXX conditional instructions are:
IF expression THEN...ELSE SELECT WHEN expression...OTHERWISE...END
v Looping instructions tell the language processor to repeat a set of instructions. A loop can repeat a
specified number of times or it can use a condition to control repeating. REXX looping instructions are:
DO repetitor...END DO WHILE expression...END DO UNTIL expression...END
v Interrupt instructions tell the language processor to leave the program entirely or leave one part of the
program and go to another part, either permanently or temporarily. The REXX interrupt instructions are:
EXIT SIGNAL label CALL label...RETURN

Using Conditional Instructions

There are two types of conditional instructions:
v IF...THEN...ELSE can direct the execution of a program to one of two choices. v SELECT WHEN...OTHERWISE...END can direct the execution to one of many choices.

IF...THEN...ELSE Instructions

The examples of IF...THEN...ELSE instructions in previous chapters demonstrate the two-choice selection. In a flow chart, this appears as follows:
expression
ELSE THEN
instruction instruction
Tr ueFalse
© Copyright IBM Corp. 1992, 2009 33
Control Flow within a Program
As a REXX instruction, the flowchart example looks like:
IF expression THEN instruction
You can also arrange the clauses in one of the following ways to enhance readability:
IF expression THEN
instruction
ELSE
instruction
or
IF expression
THEN
ELSE
When you put the entire instruction on one line, you must use a semicolon before the ELSE to separate the THEN clause from the ELSE clause.
IF expression THEN instruction; ELSE instruction
Generally, at least one instruction should follow the THEN and ELSE clauses. When either clause has no instructions, it is good programming practice to include NOP (no operation) next to the clause.
IF expression THEN
instruction
ELSE NOP
ELSE instruction
instruction
instruction
If you have more than one instruction for a condition, begin the set of instructions with a DO and end them with an END.
IF weather = rainy THEN
SAY 'Find a good book.'
ELSE
DO
PULL playgolf /* Gets data from input stream */ If playgolf='YES' THEN SAY 'Fore!'
END
Without the enclosing DO and END, the language processor assumes only one instruction for the ELSE clause.

Nested IF...THEN...ELSE Instructions

Sometimes it is necessary to have one or more IF...THEN...ELSE instructions within other IF...THEN...ELSE instructions. Having one type of instruction within another is called nesting. With nested IF instructions, it is important to match each IF with an ELSE and each DO with an END.
IF weather = fine THEN
DO
SAY 'What a lovely day!' IF tenniscourt = free THEN
SAY 'Let''s play tennis!'
ELSE NOP
END
ELSE
SAY 'We should take our raincoats!'
Not matching nested IFs to ELSEs and DOs to ENDs can have some surprising results. If you eliminate the DOs and ENDs and the ELSE NOP, as in the following example, what is the outcome?
34
CICS TS for VSE/ESA: REXX Guide
Control Flow within a Program
/******************************** REXX *******************************/ /* This program demonstrates what can happen when you do not include */ /* DOs, ENDs, and ELSEs in nested IF...THEN...ELSE instructions. */ /*********************************************************************/
weather = 'fine' tenniscourt = 'occupied'
IF weather = 'fine' THEN
SAY 'What a lovely day!' IF tenniscourt = 'free' THEN
SAY 'Let''s play tennis!'
ELSE
SAY 'We should take our raincoats!'
Figure 17. Example of Missing Instructions
Looking at the program you might assume the ELSE belongs to the first IF. However, the language processor associates an ELSE with the nearest unpaired IF. The outcome is as follows:
What a lovely day! We should take our raincoats!
Chapter 4. Controlling the Flow within a program 35
Control Flow within a Program
Exercise - Using the IF...THEN...ELSE Instruction
Write the REXX instructions for the following flowchart:
Z=2
A=3
Tr ueFalse
C=3
A=0
Tr ueFalse
Tr ueFalse
Tr ueFalse
C=2
Z=1
A=1
ANSWER
IFa=0THEN
IFc=2THEN
z=1
ELSE NOP
ELSE
IFz=2THEN
IFc=3THEN
a=1
ELSE
a=3
ELSE NOP
36
CICS TS for VSE/ESA: REXX Guide
Control Flow within a Program

SELECT WHEN...OTHERWISE...END Instruction

To select one of any number of choices, use the SELECT WHEN...OTHERWISE...END instruction. In a flowchart it appears as follows:
SELECT
THEN
WHEN
WHEN
WHEN
expression
False
expression
False
expression
Tr ue
Tr ue
Tr ue
instruction
THEN
instruction
THEN
instruction
OTHERWISE
instruction(s)
END
As a REXX instruction, the flowchart example looks like:
SELECT
WHEN expression THEN instruction WHEN expression THEN instruction WHEN expression THEN instruction : : OTHERWISE
instruction(s)
END
The language processor scans the WHEN clauses starting at the beginning until it finds a true expression. After it finds a true expression, it ignores all other possibilities, even though they might also be true. If no WHEN expressions are true, it processes the instructions following the OTHERWISE clause.
As with IF...THEN...ELSE, when you have more than one instruction for a possible path, begin the set of instructions with a DO and end them with an END. However, if more than one instruction follows the OTHERWISE keyword, DO and END are not necessary.
Chapter 4. Controlling the Flow within a program 37
Control Flow within a Program
/******************************** REXX *******************************/ /* This program receives input with a person's age and sex. In */ /* reply, it produces a person's status as follows: */ /* BABIES - under 5 */ /* GIRLS - female 5 to 12 */ /* BOYS - male 5 to 12 */ /* TEENAGERS - 13 through 19 */ /* WOMEN - female 20 and up */ /* MEN - male 20 and up */ /*********************************************************************/
PARSE ARG age sex .
SELECT
WHEN age < 5 THEN /* person younger than 5 */
status = 'BABY'
WHEN age < 13 THEN /* person between 5 and 12 */
DO
IF sex = 'M' THEN /* boy between 5 and 12 */
status = 'BOY'
ELSE /* girl between 5 and 12 */
status = 'GIRL'
END
WHEN age < 20 THEN /* person between 13 and 19 */
status = 'TEENAGER'
OTHERWISE
IF sex = 'M' THEN /* man 20 or older */
status = 'MAN'
ELSE /* woman 20 or older */
status = 'WOMAN'
END
SAY 'This person should be counted as a' status'.'
Figure 18. Example Using SELECT WHEN...OTHERWISE...END
Each SELECT must end with an END. Indenting each WHEN makes a program easier to read.
Exercises - Using SELECT WHEN...OTHERWISE...END
"Thirty days hath September, April, June, and November; all the rest have thirty-one, save February alone ..."
Write a program that uses the input of a number from 1 to 12, representing the month, and produces the number of days in that month. Assume the user specifies the month number as an argument when calling the program. (Include in the program an ARG instruction to assign the month number into the variable month). Then have the program produce the number of days. For month 2, this can be 28 or 29.
ANSWER
38
CICS TS for VSE/ESA: REXX Guide
/******************************** REXX *******************************/ /* This program uses the input of a whole number from 1 to 12 that */ /* represents a month. It produces the number of days in that */ /* month. */ /*********************************************************************/
ARG month
SELECT
WHEN month = 9 THEN
days = 30
WHEN month = 4 THEN
days = 30
WHEN month = 6 THEN
days = 30
WHEN month = 11 THEN
days = 30
WHEN month = 2 THEN
days = '28 or 29'
OTHERWISE
days = 31
END
SAY 'There are' days 'days in Month' month'.'
Figure 19. Possible Solution
Control Flow within a Program

Using Looping Instructions

There are two types of looping instructions, repetitive loops and conditional loops. Repetitive loops let you repeat instructions a certain number of times. Conditional loops use a condition to control repeating. All loops, regardless of the type, begin with the DO keyword and end with the END keyword.

Repetitive Loops

The simplest loop tells the language processor to repeat a group of instructions a specific number of times. It uses a constant after the keyword DO.
DO 5
SAY 'Hello!'
END
When you run this example, it produces five lines of Hello!:
Hello! Hello! Hello! Hello! Hello!
You can also use a variable in place of a constant, as in the following example, which gives you the same results.
number = 5 DO number
SAY 'Hello!'
END
A variable that controls the number of times a loop repeats is called a control variable. Unless you specify otherwise, the control variable increases by 1 each time the loop repeats.
Chapter 4. Controlling the Flow within a program 39
Control Flow within a Program
DO number=1TO5
SAY 'Loop' number SAY 'Hello!'
END
SAY 'Dropped out of the loop when number reached' number
This example results in five lines of Hello! preceded by the number of the loop. The number increases at the bottom of the loop and is tested at the top.
Loop 1 Hello! Loop 2 Hello! Loop 3 Hello! Loop 4 Hello! Loop 5 Hello! Dropped out of the loop when number reached 6
You can change the increment of the control variable with the keyword BY as follows:
DO number=1TO10BY2
SAY 'Loop' number SAY 'Hello!'
END
SAY 'Dropped out of the loop when number reached' number
This example has results similar to the previous example except the loops are numbered in increments of two.
Loop 1 Hello! Loop 3 Hello! Loop 5 Hello! Loop 7 Hello! Loop 9 Hello! Dropped out of the loop when number reached 11
Infinite Loops
What happens when the control variable of a loop cannot attain the last number? For example, in the following program segment, count does not increase beyond 1.
DO count=1to10
SAY 'Number' count count = count - 1
END
The result is called an infinite loop because count alternates between 1 and 0, producing an endless number of lines saying Number 1.
If your program is in an infinite loop, contact the operator to cancel it. An authorized user can issue the CEMT SET TASK PURGE command to halt an exec.
DO FOREVER Loops
Sometimes you might want to write an infinite loop purposely; for instance, in a program that reads records from a file until it reaches the end of the file. You can use the EXIT instruction to end an infinite loop when a condition is met, as in the following example. More about the EXIT instruction appears in section “EXIT Instruction” on page 48.
40
CICS TS for VSE/ESA: REXX Guide
Control Flow within a Program
/******************************* REXX ********************************/ /* This program processes strings until the value of a string is */ /* a null string. */ /*********************************************************************/
DO FOREVER
PULL string /* Gets string from input stream */ IF string = '' THEN PULL file_name IF file_name = '' THEN
EXIT
ELSE
DO
result = process(string) /* Calls a user-written function */
IF result = 0 THEN SAY "Processing complete for string:" string ELSE SAY "Processing failed for string:" string
END
END
Figure 20. Example Using a DO FOREVER Loop
This example sends strings to a user-written function for processing and then issues a message that the processing completed successfully or failed. When the input string is a blank, the loop ends and so does the program. You can also end the loop without ending the program by using the LEAVE instruction. The following topic describes this.
/* to do processing on string. */
LEAVE Instruction
The LEAVE instruction causes an immediate exit from a repetitive loop. Control goes to the instruction following the END keyword of the loop. An example of using the LEAVE instruction follows:
/******************************** REXX *******************************/ /* This program uses the LEAVE instruction to exit from a DO */ /* FOREVER loop. */ /*********************************************************************/
DO FOREVER
PULL string /* Gets string from input stream */ IF string = 'QUIT' then
LEAVE
ELSE
DO result = process(string) /* Calls a user-written function */
IF result = 0 THEN SAY "Processing complete for string:" string ELSE SAY "Processing failed for string:" string
END END SAY 'Program run complete.'
Figure 21. Example Using the LEAVE Instruction
/* to do processing on string. */
ITERATE Instruction
The ITERATE instruction stops execution from within the loop and passes control to the DO instruction at the top of the loop. Depending on the type of DO instruction, the language processor increases and tests a control variable or tests a condition to determine whether to repeat the loop. Like LEAVE, ITERATE is used within the loop.
DO count=1TO10
IF count = 8
THEN
ITERATE
ELSE
SAY 'Number' count
END
This example results in a list of numbers from 1 to 10 with the exception of number 8.
Chapter 4. Controlling the Flow within a program 41
Control Flow within a Program
Number 1 Number 2 Number 3 Number 4 Number 5 Number 6 Number 7 Number 9 Number 10
Exercises - Using Loops
1. What are the results of the following loops?
DO digit=1TO3
a.
SAY digit END SAY 'Digit is now' digit
b. DO count = 10 BY -2 TO 6
SAY count END SAY 'Count is now' count
c. DO index = 10 TO 8
SAY 'Hup! Hup! Hup!' END SAY 'Index is now' index
2. Sometimes an infinite loop can occur when input to end the loop does not match what is expected. For instance, in the example of using the LEAVE Instruction on page 41, what happens when the input is
Quit and a PARSE PULL instruction replaces the PULL instruction?
PARSE PULL file_name
ANSWERS
1. The results of the repetitive loops are as follows: a. 1
2 3 Digit is now 4
b. 10
8 6 Count is now 4
c. Index is now 10
2. The program would be unable to leave the loop because Quit is not equal to QUIT. In this case, omitting the PARSE keyword is preferred because regardless of whether the input is quit, QUIT,or Quit, the language processor translates the input to uppercase before comparing it to QUIT.

Conditional Loops

There are two types of conditional loops, DO WHILE and DO UNTIL. One or more expressions control both types of loops. However, DO WHILE loops test the expression before the loop executes the first time and repeat only when the expression is true. DO UNTIL loops test the expression after the loop executes at least once and repeat only when the expression is false.
42
CICS TS for VSE/ESA: REXX Guide
DO WHILE Loops
DO WHILE loops in a flowchart appear as follows:
DO WHILE
Control Flow within a Program
expression
Tr ue
instruction(s)
False
END
As REXX instructions, the flowchart example looks like:
DO WHILE expression /* expression must be true */
instruction(s)
END
Use a DO WHILE loop when you want to execute the loop while a condition is true. DO WHILE tests the condition at the top of the loop. If the condition is initially false, the language processor never executes the loop.
You can use a DO WHILE loop instead of the DO FOREVER loop in the example of using the LEAVE instruction on page 41. However, you need to initialize the loop with a first case so the condition can be tested before you get into the loop. Notice the first case initialization in the first PULL of the following example.
/******************************** REXX *******************************/ /* This program uses a DO WHILE loop to send a string to a */ /* user-written function for processing. */ /*********************************************************************/
PULL string /* Gets string from input stream */ DO WHILE string \= 'QUIT'
result = process(string) /* Calls a user-written function */
IF result = 0 THEN SAY "Processing complete for string:" string ELSE SAY "Processing failed for string:" string
PULL string END SAY 'Program run complete.'
/* to do processing on string. */
Figure 22. Example Using DO WHILE
Exercise - Using a DO WHILE Loop
Write a program with a DO WHILE loop that uses as input a list of responses about whether passengers on a commuter airline want a window seat. The flight has 8 passengers and 4 window seats. Discontinue the loop when all the window seats are taken. After the loop ends, produce the number of window seats taken and the number of responses processed.
ANSWER
Chapter 4. Controlling the Flow within a program 43
Control Flow within a Program
/******************************** REXX *******************************/ /* This program uses a DO WHILE loop to keep track of window seats */ /* in an 8-seat commuter airline. */ /*********************************************************************/
window_seats = 0 /* Initialize window seats to 0 */ passenger = 0 /* Initialize passengers to 0 */
DO WHILE (passenger < 8) & (window_seats \= 4)
/******************************************************************/ /* Continue while the program has not yet read the responses of */ /* all 8 passengers and while all the window seats are not taken. */ /******************************************************************/
PULL window /* Gets "Y" or "N" from input stream */ passenger = passenger + 1 /* Increase number of passengers by 1 */ IF window = 'Y' THEN
window_seats = window_seats+1/*Increase window seats by 1 */
ELSE NOP
END
SAY window_seats 'window seats were assigned.' SAY passenger 'passengers were questioned.'
Figure 23. Possible Solution
DO UNTIL Loops
DO UNTIL loops in a flowchart appear as follows:
DO UNTIL
instruction(s)
expression
False
Tr ue
END
As REXX instructions, the flowchart example looks like:
DO UNTIL expression /* expression must be false */
instruction(s)
END
Use DO UNTIL loops when a condition is not true and you want to execute the loop until the condition is true. The DO UNTIL loop tests the condition at the end of the loop and repeats only when the condition is false. Otherwise, the loop executes once and ends. For example:
44
CICS TS for VSE/ESA: REXX Guide
Control Flow within a Program
/******************************** REXX ******************************/ /* This program uses a DO UNTIL loop to ask for a password. If the */ /* password is incorrect three times, the loop ends. */ /********************************************************************/
password = 'abracadabra' time = 0 DO UNTIL (answer = password) | (time = 3)
PULL answer /* Gets ANSWER from input stream */ time = time + 1
END
Figure 24. Example Using DO UNTIL
Exercise - Using a DO UNTIL Loop
Change the program in the previous exercise on page “Exercise - Using a DO WHILE Loop” on page 43 from a DO WHILE to a DO UNTIL loop and achieve the same results. Remember that DO WHILE loops check for true expressions and DO UNTIL loops check for false expressions, which means their logical operators are often reversed.
Chapter 4. Controlling the Flow within a program 45
Control Flow within a Program
ANSWER
/******************************** REXX *******************************/ /* This program uses a DO UNTIL loop to keep track of window seats */ /* in an 8-seat commuter airline. */ /*********************************************************************/
window_seats = 0 /* Initialize window seats to 0 */ passenger = 0 /* Initialize passengers to 0 */
DO UNTIL (passenger >= 8) | (window_seats = 4)
/******************************************************************/ /* Continue while the program has not yet read the responses of */ /* all 8 passengers and while all the window seats are not taken. */ /******************************************************************/
PULL window /* Gets "Y" or "N" from input stream */ passenger = passenger + 1 /* Increase number of passengers by 1 */ IF window = 'Y' THEN
window_seats = window_seats+1/*Increase window seats by 1 */
ELSE NOP END SAY window_seats 'window seats were assigned.' SAY passenger 'passengers were questioned.'
Figure 25. Possible Solution

Combining Types of Loops

You can combine repetitive and conditional loops to create a compound loop. The following loop is set to repeat 10 times while the quantity is less than 50, at which point it stops.
quantity = 20 DO number=1TO10WHILE quantity < 50
quantity = quantity + number SAY 'Quantity = 'quantity ' (Loop 'number')'
END
The result of this example is as follows:
Quantity = 21 (Loop 1) Quantity = 23 (Loop 2) Quantity = 26 (Loop 3) Quantity = 30 (Loop 4) Quantity = 35 (Loop 5) Quantity = 41 (Loop 6) Quantity = 48 (Loop 7) Quantity = 56 (Loop 8)
You can substitute a DO UNTIL loop, change the comparison operator from < to >, and get the same results.
quantity = 20 DO number=1TO10UNTIL quantity > 50
quantity = quantity + number SAY 'Quantity = 'quantity ' (Loop 'number')'
END

Nested DO Loops

Like nested IF...THEN...ELSE instructions, DO loops can contain other DO loops. A simple example follows:
46
CICS TS for VSE/ESA: REXX Guide
Control Flow within a Program
DO outer=1TO2
DO inner=1TO2
SAY 'HIP' END SAY 'HURRAH'
END
The output from this example is:
HIP HIP HURRAH HIP HIP HURRAH
If you need to leave a loop when a certain condition arises, use the LEAVE instruction followed by the name of the control variable of the loop. If the LEAVE instruction is for the inner loop, processing leaves the inner loop and goes to the outer loop. If the LEAVE instruction is for the outer loop, processing leaves both loops.
To leave the inner loop in the preceding example, add an IF...THEN...ELSE instruction that includes a LEAVE instruction after the IF instruction.
DO outer=1TO2
DO inner=1TO2
IF inner > 1 THEN
LEAVE inner
ELSE
SAY 'HIP' END SAY 'HURRAH'
END
The result is as follows:
HIP HURRAH HIP HURRAH
Exercises - Combining Loops
1. What happens when the following program runs?
DO outer=1TO3
SAY /* Produces a blank line */ DO inner=1TO3
SAY 'Outer' outer 'Inner' inner
END
END
2. Now what happens when the LEAVE instruction is added?
DO outer=1TO3
SAY /* Produces a blank line */ DO inner=1TO3
IF inner = 2 THEN
LEAVE inner
ELSE
SAY 'Outer' outer 'Inner' inner
END
END
ANSWERS
1. When this example runs, it produces the following:
Chapter 4. Controlling the Flow within a program 47
Control Flow within a Program
Outer 1 Inner 1 Outer 1 Inner 2 Outer 1 Inner 3
Outer 2 Inner 1 Outer 2 Inner 2 Outer 2 Inner 3
Outer 3 Inner 1 Outer 3 Inner 2 Outer 3 Inner 3
2. The result is one line of output for each of the inner loops.
Outer 1 Inner 1
Outer 2 Inner 1
Outer 3 Inner 1

Using Interrupt Instructions

Instructions that interrupt the flow of a program can cause the program to:
v End (EXIT) v Skip to another part of the program marked by a label (SIGNAL) v Go temporarily to a subroutine either within the program or outside the program (CALL or RETURN).

EXIT Instruction

The EXIT instruction causes a REXX program to unconditionally end and return to where the program was called. If another program called the REXX program, EXIT returns to that calling program. More about calling external routines appears later in this chapter and in Chapter 6, “Writing Subroutines and Functions,” on page 57. For more detailed information on the EXIT instruction, see section “EXIT” on page
143.
Besides ending a program, EXIT can also return a value to the caller of the program. If the program was called as a subroutine from another REXX program, the value is received in the REXX special variable RESULT. If the program was called as a function, the value is received in the original expression at the point where the function was called. Otherwise, the value is received in the REXX special variable RC. The value can represent a return code and can be in the form of a constant or an expression that is computed.
/******************************** REXX ****************************/ /* This program uses the EXIT instruction to end the program and */ /* return a value indicating whether a job applicant gets the */ /* job. A value of 0 means the applicant does not qualify for */ /* the job, but a value of 1 means the applicant gets the job. */ /* The value is placed in the REXX special variable RESULT. */ /******************************************************************/ PULL months_experience /* Gets number from input stream */ PULL references /* Gets "Y" or "N" from input stream */ PULL start_tomorrow /* Gets "Y" or "N" from input stream */
IF (months_experience > 24) & (references = 'Y') & (start_tomorrow= 'Y') THEN job = 1 /* person gets the job */ ELSE job = 0 /* person does not get the job */
EXIT job
Figure 26. Example Using the EXIT Instruction
48
CICS TS for VSE/ESA: REXX Guide
Control Flow within a Program

CALL and RETURN Instructions

The CALL instruction interrupts the flow of a program by passing control to an internal or external subroutine. An internal subroutine is part of the calling program. An external subroutine is another program. The RETURN instruction returns control from a subroutine back to the calling program and optionally returns a value. For more detailed information on the CALL and RETURN instructions, see sections “CALL” on page 135 and “RETURN” on page 161.
When calling an internal subroutine, CALL passes control to a label specified after the CALL keyword. When the subroutine ends with the RETURN instruction, the instructions following CALL are processed.
instruction(s) CALL sub1
instruction(s) EXIT
sub1: instruction(s) RETURN
When calling an external subroutine, CALL passes control to the program name that is specified after the CALL keyword. When the external subroutine completes, you can use the RETURN instruction to return to where you left off in the calling program.
MAIN
instruction(s) CALL sub2
instruction(s) … … ...
sub2:
instruction(s) RETURN
For more information about calling subroutines, see Chapter 6, “Writing Subroutines and Functions,” on page 57.
Chapter 4. Controlling the Flow within a program 49
Control Flow within a Program

SIGNAL Instruction

The SIGNAL instruction, like CALL, interrupts the usual flow of a program and causes control to pass to a specified label. The label to which control passes can be before or after the SIGNAL instruction. Unlike CALL, SIGNAL does not return to a specific instruction to resume execution. When you use SIGNAL from within a loop, the loop automatically ends. When you use SIGNAL from an internal routine, the internal routine does not return to its caller. For more detailed information on the SIGNAL instruction, see section “SIGNAL” on page 164.
In the following example, if the expression is true, then the language processor goes to the label Emergency: and skips all instructions in between.
IF expression THEN
SIGNAL Emergency
ELSE
instruction(s)
Emergency: instruction(s)
SIGNAL is useful for testing programs or providing an emergency course of action. It should not be used as a convenient way to move from one place in a program to another. SIGNAL does not provide a way to return as does the CALL instruction described in the previous topic.
For more information about the SIGNAL instruction, see page 86 and section “SIGNAL” on page 164.
50
CICS TS for VSE/ESA: REXX Guide

Chapter 5. Using Functions

This chapter defines what a function is and describes how to use the built-in functions.

What is a Function?

A function is a sequence of instructions that can receive data, process it, and return a value. In REXX, there are several kinds of functions:
v Built-in functions are built into the language processor. More about built-in functions appears later in this
chapter.
v User-written functions are those an individual user writes or an installation supplies. These can be
internal or external. An internal function is part of the current program that starts at a label. An external function is a self-contained program or program outside the calling program. More information about user-written functions appears in section “Writing Subroutines and Functions” on page 58.
Regardless of the kind of function, all functions return a value to the program that issued the function call. To call a function, type the function name immediately followed by parentheses enclosing arguments to the function (if any). There can be no space between the function name and the left parenthesis.
function(arguments)
A function call can contain up to 20 arguments separated by commas. Arguments can be: v Constant
function(55)
v Symbol
function(symbol_name)
v Option that the function recognizes
function(option)
v Literal string
function('With a literal string')
v Unspecified or omitted
function()
v Another function
function(function(arguments))
v Combination of argument types
function('With literal string', 55, option) function('With literal string',, option) /* Second argument omitted */
All functions must return values. When the function returns a value, the value replaces the function call. In the following example, the language processor adds the value the function returns to 7 and produces the sum.
SAY 7 + function(arguments)
A function call generally appears in an expression. Therefore a function call, like an expression, does not usually appear in an instruction by itself.

Example of a Function

Calculations that functions represent often require many instructions. For instance, the simple calculation for finding the highest number in a group of three numbers, might be written as follows:
© Copyright IBM Corp. 1992, 2009 51
Using Functions
/***************************** REXX **********************************/ /* This program receives three numbers as arguments and analyzes */ /* which number is the greatest. */ /*********************************************************************/
PARSE ARG number1, number2, number3 .
IF number1 > number2 THEN
IF number1 > number3 THEN
greatest = number1
ELSE
greatest = number3
ELSE
IF number2 > number3 THEN
greatest = number2
ELSE
greatest = number3
RETURN greatest
Figure 27. Finding a Maximum Number
Rather than writing multiple instructions every time you want to find the maximum of a group of three numbers, you can use a built-in function that does the calculation for you and returns the maximum number. The function is called MAX, and you can use it as follows:
MAX(number1,number2,number3,....)
To find the maximum of 45, -2, number, and 199 and put the maximum into the symbol biggest, write the following instruction:
biggest = MAX(45,-2,number,199)

Built-In Functions

More than 50 functions are built into the language processor. The built-in functions fall into the following categories:
v Arithmetic functions
Evaluate numbers from the argument and return a particular value.
v Comparison functions
Compare numbers, or strings, or both and return a value.
v Conversion functions
Convert one type of data representation to another type of data representation.
v Formatting functions
Manipulate the characters and spacing in strings supplied in the argument.
v String manipulating functions
Analyze a string supplied in the argument (or a variable representing a string) and return a particular value.
v Miscellaneous functions
Do not clearly fit into any of the other categories.
The following tables briefly describe the functions in each category. For a complete description of these functions, see Chapter 14, “Functions,” on page 171.
52
CICS TS for VSE/ESA: REXX Guide
Using Functions

Arithmetic Functions

Function Description
ABS Returns the absolute value of the input number.
DIGITS Returns the current setting of NUMERIC DIGITS.
FORM Returns the current setting of NUMERIC FORM.
FUZZ Returns the current setting of NUMERIC FUZZ.
MAX Returns the largest number from the list specified, formatted according to the current NUMERIC
settings.
MIN Returns the smallest number from the list specified, formatted according to the current
NUMERIC settings.
RANDOM Returns a quasi-random, non-negative whole number in the range specified.
SIGN Returns a number that indicates the sign of the input number.
TRUNC Returns the integer part of the input number and optionally a specified number of decimal
places.

Comparison Functions

Function Description
COMPARE Returns 0 if the two input strings are identical. Otherwise, returns the position of the first
character that does not match.
DATATYPE Returns a string indicating the input string is a particular data type, such as a number or
character.
SYMBOL Returns VAR, LIT,orBAD to indicate the state of the symbol (variable, literal, or bad).

Conversion Functions

Function Description
B2X Returns the hexadecimal representation of the input binary string. (Binary to Hexadecimal).
C2D Returns the decimal representation of the input character string. (Character to Decimal).
C2X Returns the hexadecimal representation of the input character string. (Character to
Hexadecimal).
D2C Returns the character representation of the input decimal string. (Decimal to Character).
D2X Returns the hexadecimal representation of the input decimal string. (Decimal to Hexadecimal).
X2B Returns the binary representation of the input hexadecimal string. (Hexadecimal to Binary).
X2C Returns the character representation of the input hexadecimal string. (Hexadecimal to
Character).
X2D Returns the decimal representation of the input hexadecimal string. (Hexadecimal to Decimal).
Chapter 5. Using Functions 53
Using Functions

Formatting Functions

Function Description
CENTER or CENTRE
COPIES Returns the specified number of concatenated copies of the input string.
FORMAT Returns the input number, rounded and formatted.
JUSTIFY
LEFT Returns a string of the specified length, truncated or padded on the right as needed.
RIGHT Returns a string of the specified length, truncated or padded on the left as needed.
SPACE Returns the words in the input string with a specified number of pad characters between each
1
Returns a string of a specified length with the input string centered in it, with pad characters added as necessary to make up the length.
Returns a specified string formatted by adding pad characters between words to justify to both margins.
word.

String Manipulating Functions

Function Description
ABBREV Returns a string indicating if one string is equal to the specified number of leading characters of
another string.
DELSTR Returns a string after deleting a specified number of characters, starting at a specified point in
the input string.
DELWORD Returns a string after deleting a specified number of words, starting at a specified word in the
input string.
1
FIND
1
INDEX
INSERT Returns a character string after inserting another input string into it from a specified character
LASTPOS Returns the starting character position of the last occurrence of one string in another.
LENGTH Returns the length of the input string.
OVERLAY Returns a string that is the target string overlaid by a second input string.
POS Returns the character position of one string in another.
REVERSE Returns a character string that is the reverse of the original.
STRIP Returns a character string after removing leading or trailing characters or both from the input
SUBSTR Returns a portion of the input string beginning at a specified character position.
SUBWORD Returns a portion of the input string starting at a specified word number.
TRANSLATE Returns a character string with each character of the input string translated to another character
VERIFY Returns a number indicating whether an input string is composed only of characters from
WORD Returns a word from an input string as a specified number indicates.
WORDINDEX Returns the character position in an input string of the first character in the specified word.
WORDLENGTH Returns the length of a specified word in the input string.
Returns the word number of the first word of a specified phrase found within the input string.
Returns the character position of the first character of a specified string found in the input string.
position.
string.
or unchanged.
another input string or returns the character position of the first unmatched character.
1. Is a non-SAA built-in function REXX/CICS provides.
54
CICS TS for VSE/ESA: REXX Guide
Using Functions
Function Description
WORDPOS Returns the word number of the first word of a specified phrase in the input string.
WORDS Returns the number of words in the input string.

Miscellaneous Functions

Function Description
ADDRESS Returns the name of the environment to which commands are currently being sent.
ARG Returns an argument string or information about the argument strings to a program or internal
routine.
BITAND Returns a string composed of the two input strings logically ANDed together, bit by bit.
BITOR Returns a string composed of the two input strings logically ORed together, bit by bit.
BITXOR Returns a string composed of the two input strings eXclusive ORed together, bit by bit.
CONDITION Returns the condition information, such as name and status, associated with the current trapped
condition.
DATE Returns the date in the default format (dd mon yyyy) or in one of various optional formats.
ERRORTEXT Returns the error message associated with the specified error number.
EXTERNALS This function always returns a 0.
LINESIZE Returns the width of the current output device.
QUEUED Returns the number of lines remaining in the external data queue at the time when the function
is called.
SOURCELINE Returns either the line number of the last line in the source file or the source line a number
specifies.
TIME Returns the local time in the default 24-hour clock format (hh:mm:ss) or in one of various
optional formats.
TRACE Returns the trace actions currently in effect.
USERID
VALUE Returns the value of a specified symbol and optionally assigns it a new value.
XRANGE Returns a string of all 1-byte codes (in ascending order) between and including specified starting
1
Returns the current user ID. This is the last user ID specified on the SETUID command, the user ID of the calling REXX program if one program calls another, the user ID under which the job is running, or the job name.
and ending values.

Testing Input with Built-In Functions

Some of the built-in functions provide a convenient way to test input. When a program uses input, the user might provide input that is not valid. For instance, in the example of using comparison expressions on page 24, the program uses a dollar amount in the following instruction.
PARSE PULL yesterday /* Gets yesterday's price from input stream */
If the program pulls only a number, the program processes that information correctly. However, if the program pulls a number preceded by a dollar sign or pulls a word, such as nothing, the program returns an error. To avoid getting an error, you can check the input with the DATATYPE function as follows.
IF DATATYPE(yesterday) \= 'NUM' THEN DO
SAY 'The input amount was in the wrong format.'
EXIT
END
Chapter 5. Using Functions 55
Using Functions
Other useful built-in functions to test input are WORDS, VERIFY, LENGTH, and SIGN.
Exercise - Writing a program with Built-In Functions
Write a program that checks a file name for a length of 8 characters. If the name is longer than 8 characters, the program truncates it to 8 and sends a message indicating the shortened name. Use the built-in functions LENGTH, see page 188, and SUBSTR, see page 192.
ANSWER
/***************************** REXX *********************************/ /* This program tests the length of a file name. */ /* If the name is longer than 8 characters, the program truncates */ /* extra characters and sends a message indicating the shortened */ /* name. */ /********************************************************************/ PULL name /* Gets name from input stream */
IF LENGTH(name) > 8 THEN /* Name is longer than 8 characters */
DO
name = SUBSTR(name,1,8) /* Shorten name to first 8 characters */ SAY 'The name you specified was too long.' SAY name 'will be used.'
END
ELSE NOP
Figure 28. Possible Solution
56
CICS TS for VSE/ESA: REXX Guide

Chapter 6. Writing Subroutines and Functions

This chapter shows how to write subroutines and functions and discusses their differences and similarities.

What are Subroutines and Functions?

Subroutines and functions are routines made up of a sequence of instructions that can receive data, process it, and return a value. The routines can be:
Internal
The routine is within the current program, marked by a label, and only that program uses the routine.
External
A REXX subroutine that exists as a separate file.
In many aspects, subroutines and functions are the same. However, they are different in a few major aspects, such as how to call them and the way they return values.
v Calling a subroutine
To call a subroutine, use the CALL instruction followed by the subroutine name (label or program member name). You can optionally follow this with up to 20 arguments separated by commas. The subroutine call is an entire instruction.
CALL subroutine_name argument1, argument2,...
v Calling a function
To call a function, use the function name (label or program member name) immediately followed by parentheses that can contain arguments. There can be no space between the function name and the left parentheses. The function call is part of an instruction, for example, an assignment instruction.
z = function(argument1, argument2,...)
v Returning a value from a subroutine
A subroutine does not have to return a value, but when it does, it sends back the value with the RETURN instruction.
RETURN value
The calling program receives the value in the REXX special variable named RESULT.
SAY 'The answer is' RESULT
v Returning a value from a function
A function must return a value. When the function is a REXX program, the value is returned with either the RETURN or EXIT instruction.
RETURN value
The calling program receives the value at the function call. The value replaces the function call, so that in the following example, z = value.
z = function(argument1, argument2,...)

When to Write Subroutines Rather Than Functions

The actual instructions that make up a subroutine or a function can be identical. It is the way you want to use them in a program that turns them into either a subroutine or a function. For example, you can call the built-in function SUBSTR as either a function or a subroutine. This is how to call SUBSTR as a function to shorten a word to its first eight characters:
a = SUBSTR('verylongword',1,8) /* a is set to 'verylong' */
You get the same results if you call SUBSTR as a subroutine.
© Copyright IBM Corp. 1992, 2009 57

Writing Subroutines and Functions

CALL SUBSTR 'verylongword', 1, 8 a = RESULT /* a is set to 'verylong' */
When deciding whether to write a subroutine or a function, ask yourself the following questions:
v Is a returned value optional? If so, write a subroutine. v Do I need a value returned as an expression within an instruction? If so, write a function.
The rest of this chapter describes how to write subroutines and functions and finally summarizes the differences and similarities between the two.
Writing Subroutines and Functions
A subroutine is a series of instructions that a program calls to perform a specific task. The instruction that calls the subroutine is the CALL instruction. You can use the CALL instruction several times in a program to call the same subroutine.
When the subroutine ends, it can return control to the instruction that directly follows the subroutine call. The instruction that returns control is the RETURN instruction.
instruction(s) CALL sub1
instruction(s) EXIT
sub1: instruction(s) RETURN
A function is a series of instructions that a program calls to perform a specific task and return a value. As Chapter 5, “Using Functions,” on page 51 describes, a function can be built-in or user-written. Call a user-written function the same way as a built-in function: specify the function name immediately followed by parentheses that can contain arguments. There can be no blanks between the function name and the left parenthesis. The parentheses can contain up to 20 arguments or no arguments at all.
function(argument1, argument2,...)
or
function()
A function requires a return value because the function call generally appears in an expression.
z = function(arguments1, argument2,...)
When the function ends, it can use the RETURN instruction to send back a value to replace the function call.
58
CICS TS for VSE/ESA: REXX Guide
Writing Subroutines and Functions
instruction(s)
z=func1(arg1, arg2)
instruction(s) EXIT
instruction(s) RETURN
Both subroutines and functions can be internal (designated by a label) or external (designated by the subroutine or function in the REXX File System/VSE Librarian sublibrary member name). The two preceding examples illustrate an internal subroutine named sub1 and an internal function named func1.
IMPORTANT NOTE
Because internal subroutines and functions generally appear after the main part of the program, when you have an internal subroutine or function, it is important to end the main part of the program with the EXIT instruction.
The following illustrates an external subroutine named sub2.
MAIN
instruction(s) CALL sub2
instruction(s) … … ...
sub2:
instruction(s) RETURN
The following illustrates an external function named func2.
Chapter 6. Writing Subroutines and Functions 59
Writing Subroutines and Functions
MAIN
instruction(s)
z=func2(arg1)
instruction(s) … … … exit
FUNC2
ARG var1 instruction(s) RETURN value

When to Use Internal Versus External Subroutines or Functions

To determine whether to make a subroutine or function internal or external, you might consider factors, such as:
v Size of the subroutine or function. Very large subroutines and functions often are external, whereas
small ones fit easily within the calling program.
v How you want to pass information. It is quicker to pass information through variables in an internal
subroutine or function. The next topic describes passing information this way.
v Whether the subroutine or function might be of value to more than one program or user. If so, an
external subroutine or function is preferable.
v Performance. For functions, the language processor searches for an internal function before it searches
for an external function.

Passing Information

A program and its internal subroutine or function can share the same variables. Therefore, you can use commonly shared variables to pass information between caller and internal subroutine or function. You can also use arguments to pass information to and from an internal subroutine or an internal function. External subroutines, however, cannot share variables with the caller. To pass information to them, you need to use arguments or some other external way, such as the data stack. (Remember: An internal function does not need to pass arguments within the parentheses that follow the function call. However, all functions, both internal and external, must return a value.)
Passing Information by Using Variables
When a program and its internal subroutine or function share the same variables, the value of a variable is what was last assigned. This is regardless of whether the assignment was in the main part of the program or in the subroutine or function.
The following example shows passing information to a subroutine. The variables number1, number2, and answer are shared. The value of answer is assigned in the subroutine and used in the main part of the program.
60
CICS TS for VSE/ESA: REXX Guide
Writing Subroutines and Functions
/******************************* REXX ********************************/ /* This program receives a calculated value from an internal */ /* subroutine and uses that value in a SAY instruction. */ /*********************************************************************/
number1 = 5 number2 = 10 CALL subroutine SAY answer /* Produces 15 */ EXIT
subroutine: answer = number1 + number2 RETURN
Figure 29. Example of Passing Information in a Variable Using a Subroutine
The next example is the same, except it passes information to a function rather than a subroutine. The subroutine includes the variable answer on the RETURN instruction. The language processor replaces the function call with the value in answer.
/******************************* REXX ********************************/ /* This program receives a calculated value from an internal */ /* function and uses SAY to produce that value. */ /*********************************************************************/
number1 = 5 number2 = 10 SAY add() /* Produces 15 */ SAY answer /* Also produces 15 */ EXIT
add: answer = number1 + number2 RETURN answer
Figure 30. Example of Passing Information in a Variable Using a Function
Using the same variables in a program and its internal subroutine or function can sometimes create problems. In the next example, the main part of the program and the subroutine use the same control variable, i, for their DO loops. As a result, the DO loop runs only once in the main program because the subroutine returns to the main program with i=6.
Chapter 6. Writing Subroutines and Functions 61
Writing Subroutines and Functions
/******************************* REXX ********************************/ /* NOTE: This program contains an error. */ /* It uses a DO loop to call an internal subroutine, and the */ /* subroutine uses a DO loop with the same control variable as the */ /* main program. The DO loop in the main program runs only once. */ /*********************************************************************/
number1 = 5 number2 = 10 DOi=1TO5
CALL subroutine
SAY answer /* Produces 105 */ END EXIT
subroutine: DOi=1TO5
answer = number1 + number2
number1 = number2
number2 = answer END RETURN
Figure 31. Example of a Problem Caused by Passing Information in a Variable Using a Subroutine
The next example is the same, except it passes information using a function instead of a subroutine.
/******************************* REXX ********************************/ /* NOTE: This program contains an error. */ /* It uses a DO loop to call an internal function, and the */ /* function uses a DO loop with the same control variable as the */ /* main program. The DO loop in the main program runs only once. */ /*********************************************************************/
number1 = 5 number2 = 10 DOi=1TO5
SAY add() /* Produces 105 */ END EXIT
add: DOi=1TO5
answer = number1 + number2
number1 = number2
number2 = answer END RETURN answer
Figure 32. Example of a Problem Caused by Passing Information in a Variable Using a Function
To avoid this kind of problem in an internal subroutine or function, you can use:
v The PROCEDURE instruction, as the next topic describes. v Different variable names in a subroutine or function than in the main part of the program. For a
subroutine, you can pass arguments on the CALL instruction; section “Passing Information by Using Arguments” on page 64 describes this.
Protecting Variables with the PROCEDURE Instruction: When you use the PROCEDURE instruction immediately after the subroutine or function label, all variables in the subroutine or function become local to the subroutine or function; they are shielded from the main part of the program. You can also use the PROCEDURE EXPOSE instruction to protect all but a few specified variables.
62
CICS TS for VSE/ESA: REXX Guide
Writing Subroutines and Functions
The following examples show how results differ when a subroutine or function uses or does not use PROCEDURE.
/******************************* REXX ********************************/ /* This program uses a PROCEDURE instruction to protect the */ /* variables within its subroutine. */ /*********************************************************************/
number1 = 10 CALL subroutine SAY number1 number2 /* Produces 10 NUMBER2 */ EXIT
subroutine: PROCEDURE number1 = 7 number2 = 5 RETURN
Figure 33. Example of Subroutine Using the PROCEDURE Instruction
/******************************* REXX ********************************/ /* This program does not use a PROCEDURE instruction to protect the */ /* variables within its subroutine. */ /*********************************************************************/
number1 = 10 CALL subroutine SAY number1 number2 /* Produces 7 5 */ EXIT
subroutine: number1 = 7 number2 = 5 RETURN
Figure 34. Example of Subroutine without the PROCEDURE Instruction
The next two examples are the same, except they use functions rather than subroutines.
/******************************* REXX ********************************/ /* This program uses a PROCEDURE instruction to protect the */ /* variables within its function. */ /*********************************************************************/
number1 = 10 SAY pass() number2 /* Produces 7 NUMBER2 */ EXIT
pass: PROCEDURE number1 = 7 number2 = 5 RETURN number1
Figure 35. Example of Function Using the PROCEDURE Instruction
Chapter 6. Writing Subroutines and Functions 63
Writing Subroutines and Functions
/******************************* REXX ********************************/ /* This program does not use a PROCEDURE instruction to protect the */ /* variables within its function. */ /*********************************************************************/
number1 = 10 SAY pass() number2 /* Produces 7 5 */ EXIT
pass: number1 = 7 number2 = 5 RETURN number1
Figure 36. Example of Function without the PROCEDURE Instruction
Exposing Variables with PROCEDURE EXPOSE: To protect all but specific variables, use the EXPOSE option with the PROCEDURE instruction, followed by the variables that are to remain exposed to the subroutine or function.
The next example uses PROCEDURE EXPOSE in a subroutine.
/******************************* REXX ********************************/ /* This program uses a PROCEDURE instruction with the EXPOSE option */ /* to expose one variable, number1, in its subroutine. The other */ /* variable, number2, is set to null and the SAY instruction */ /* produces this name in uppercase. */ /*********************************************************************/
number1 = 10 CALL subroutine SAY number1 number2 /* produces 7 NUMBER2 */ EXIT
subroutine: PROCEDURE EXPOSE number1 number1 = 7 number2 = 5 RETURN
Figure 37. Example Using PROCEDURE EXPOSE in Subroutine
The next example is the same except PROCEDURE EXPOSE is in a function instead of a subroutine.
/******************************* REXX ********************************/ /* This program uses a PROCEDURE instruction with the EXPOSE option */ /* to expose one variable, number1, in its function. */ /*********************************************************************/
number1 = 10 SAY pass() number1 /* Produces 5 7 */ EXIT
pass: PROCEDURE EXPOSE number1 number1 = 7 number2 = 5 RETURN number2
Figure 38. Example Using PROCEDURE EXPOSE in a Function
For more information about the PROCEDURE instruction, see section “PROCEDURE” on page 155.
Passing Information by Using Arguments
A way to pass information to either internal or external subroutines or functions is through arguments. When calling a subroutine, you can pass up to 20 arguments separated by commas on the CALL instruction as follows:
CALL subroutine_name argument1, argument2, argument3,...
64
CICS TS for VSE/ESA: REXX Guide
Writing Subroutines and Functions
In a function call, you can pass up to 20 arguments separated by commas.
function(argument1,argument2,argument3,...)
Using the ARG Instruction: A subroutine or function can receive the arguments with the ARG instruction. In the ARG instruction, commas also separate arguments.
ARG arg1, arg2, arg3, ...
The names of the arguments that are passed do not have to be the same as those on the ARG instruction because information is passed by position rather than by argument name. The first argument sent is the first argument received and so forth. You can also set up a template in the CALL instruction or function call. The language processor then uses this template in the corresponding ARG instruction. For information about parsing with templates, see section “Parsing Data” on page 73.
In the following example, the main routine sends information to a subroutine that computes the perimeter of a rectangle. The subroutine returns a value in the variable perim by specifying the value in the RETURN instruction. The main program receives the value in the special variable RESULT.
/***********************************REXX***********************************/
This program receives as arguments the length and width of a
/* */
rectangle and passes that information to an internal subroutine.
/* */
The subroutine then calculates the perimeter of the rectangle.
/* */ /*****************************************************************************/
PARSE ARG long wide CALL perimeter long, wide SAY ‘The perimeter is’ RESULT ‘inches.’ EXIT
perimeter: ARG length, width perim = 2 * length + 2 * width RETURN perim
Figure 39. Example of Passing Arguments on the CALL Instruction
The next example is the same except it uses ARG in a function instead of a subroutine.
Chapter 6. Writing Subroutines and Functions 65
Writing Subroutines and Functions
/***********************************REXX***********************************/
This program receives as arguments the length and width of a
/* */
rectangle and passes that information to an internal function,
/* */
named perimeter. The function then calculates the perimeter of
/* */
the rectangle.
/* */ /*****************************************************************************/
PARSE ARG long wide SAY ‘The perimeter is’ perimeter (long,wide) ‘inches.’ EXIT
perimeter: ARG length, width perim = 2 * length + 2 * width RETURN perim
Figure 40. Example of Passing Arguments on the Call to an Internal Routine
In the two preceding examples, notice the positional relationships between long and length, and wide and width. Also notice how information is received from variable perim. Both programs include perim on a
RETURN instruction. For the program with a subroutine, the language processor assigns the value in perim to the special variable RESULT. For the program using a function, the language processor replaces the function call perimeter(long,wide) with the value in perim.
Using the ARG Built-in Function: Another way for a subroutine or function to receive arguments is with the ARG built-in function. This function returns the value of a particular argument. A number represents the argument position.
For instance, in the previous example, instead of the ARG instruction:
ARG length, width
you can use the ARG function as follows:
length = ARG(1) /* puts the first argument into length */ width = ARG(2) /* puts the second argument into width */
For more information about the ARG function see section “ARG” on page 134.

Receiving Information from a Subroutine or Function

Although a subroutine or function can receive up to 20 arguments, it can specify only one expression on the RETURN instruction. That expression can be:
v A number
RETURN 55
v One or more variables whose values are substituted (or their names if no values have been assigned).
RETURN value1 value2 value3
v A literal string
RETURN 'Work complete.'
v An arithmetic, comparison, or logical expression whose value is substituted.
RETURN 5 * number
66
CICS TS for VSE/ESA: REXX Guide
Writing Subroutines and Functions
Exercise - Writing an Internal and an External Subroutine
Write a program that plays a simulated coin toss game and produces the accumulated scores.
There should be four possible inputs:
v 'HEADS' v 'TAILS' v '' (Null—to quit the game) v None of these three (incorrect response).
Write an internal subroutine without arguments to check for valid input. Send valid input to an external subroutine that uses the RANDOM built-in function to generate random outcomes. Assume HEADS = 0 and TAILS = 1, and use RANDOM as follows:
RANDOM(0,1)
Compare the valid input with the value from RANDOM. If they are the same, the user wins one point; if they are different, the computer wins one point. Return the result to the main program where results are tallied.
ANSWER
/***************************** REXX ********************************/ /* This program plays a simulated coin toss game. */ /* The input can be heads, tails, or null ("") to quit the game. */ /* First an internal subroutine checks input for validity. */ /* An external subroutine uses the RANDOM built-in function to */ /* obtain a simulation of a throw of dice and compares the user */ /* input to the random outcome. The main program receives */ /* notification of who won the round. It maintains and produces */ /* scores after each round. */ /*******************************************************************/
PULL flip /* Gets "HEADS", "TAILS", or "" */
computer = 0; user = 0 /* Initializes scores to zero */ CALL check /* Calls internal subroutine, check */ DO FOREVER
CALL throw /* Calls external subroutine, throw */
/* from input stream. */
IF RESULT = 'machine' THEN /* The computer won */
computer = computer + 1 /* Increase the computer score */
ELSE /* The user won */
user = user + 1 /* Increase the user score */
SAY 'Computer score = ' computer ' Your score = ' user PULL flip
CALL check /* Call internal subroutine, check */ END EXIT
Figure 41. Possible Solution (Main Program)
Chapter 6. Writing Subroutines and Functions 67
Writing Subroutines and Functions
/*************************** REXX ************************************/ /* This internal subroutine checks for valid input of "HEADS", */ /* "TAILS", or "" (to quit). If the input is anything else, the */ /* subroutine says the input is not valid and gets the next input. */ /* The subroutine keeps repeating until the input is valid. */ /* Commonly used variables return information to the main program */ /*********************************************************************/ check:
DO UNTIL outcome = 'correct'
SELECT
WHEN flip = 'HEADS' THEN
outcome = 'correct'
WHEN flip = 'TAILS' THEN
outcome = 'correct'
WHEN flip = '' THEN
EXIT
OTHERWISE
outcome = 'incorrect' PULL flip
END END RETURN
Figure 42. Possible Solution (Internal Subroutine Named CHECK)
/******************************* REXX ********************************/ /* This external subroutine receives the valid input, analyzes it, */ /* gets a random "flip" from the computer, and compares the two. */ /* If they are the same, the user wins. If they are different, */ /* the computer wins. The routine returns the outcome to the */ /* calling program. */ /*********************************************************************/ throw:
ARG input IF input = 'HEADS' THEN
userthrow = 0 /* heads = 0 */ ELSE
userthrow = 1 /* tails = 1 */
compthrow = RANDOM(0,1) /* choose a random number */
IF compthrow = userthrow THEN
outcome = 'human' /* user chose correctly */ ELSE
outcome = 'machine' /* user chose incorrectly */
RETURN outcome
Figure 43. Possible Solution (External Subroutine named THROW)
/* between 0 and 1 */
Exercise - Writing a Function
Write a function named AVG that receives a list of numbers separated by blanks and computes their average. The final answer can be a decimal number. To call this function, you would use:
AVG(number1 number2 number3...)
Use the WORDS (see section “WORDS” on page 198) and WORD (see section “WORD” on page 197) built-in functions.
ANSWER
68
CICS TS for VSE/ESA: REXX Guide
Writing Subroutines and Functions
/******************************* REXX ********************************/ /* This function receives a list of numbers, adds them, computes */ /* their average, and returns the average to the calling program. */ /*********************************************************************/
ARG numlist /* receive the numbers in a single variable */
sum = 0 /* initialize sum to zero */
DOn=1TOWORDS(numlist) /* Repeat for as many times as there */
number = WORD(numlist,n) /* Word #n goes to number */ sum = sum + number /* Sum increases by number */
END
average = sum / WORDS(numlist) /* Compute the average */
RETURN average
Figure 44. Possible Solution
/* are numbers */
Chapter 6. Writing Subroutines and Functions 69
Writing Subroutines and Functions

Subroutines and Functions—Similarities and Differences

The following tables highlight similarities and differences between subroutines and functions:
Similarities between Subroutines and Functions
Can be internal or external.
Internal – Can pass information by using common variables – Can protect variables with the PROCEDURE instruction – Can pass information by using arguments.
External – Must pass information by using arguments – Can use the ARG instruction or the ARG built-in function to receive arguments.
Uses the RETURN instruction to return to the caller.
Differences between Subroutines and Functions
Subroutines Functions
Calling Call by using the CALL instruction, followed
by the subroutine name and, optionally, up to 20 arguments.
Returning a Value Might return a value to the caller. If you
include a value on the RETURN instruction, the language processor assigns this value to the REXX special variable RESULT.
Call by specifying the function's name, immediately followed by parentheses that optionally contain up to 20 arguments.
Must return a value. Specify a value on the RETURN instruction; the language processor replaces the function call with this value.
70
CICS TS for VSE/ESA: REXX Guide

Chapter 7. Manipulating Data

This chapter describes how to use compound variables and stems and explains parsing.

Using Compound Variables and Stems

Sometimes it is useful to store groups of related data in a way that makes data retrieval easy. For example, you could store a list of employee names in an array and retrieve them by number. An array is an arrangement of elements in one or more dimensions, identified by a single name. An array called
employee could contain names as follows:
EMPLOYEE
(1) Adams, Joe (2) Crandall, Amy (3) Devon, David (4) Garrison, Donna (5) Leone, Mary (6) Sebastian, Isaac
In some computer languages, you use the number of the element to access an element in an array. For example, employee(1) would retrieve Adams, Joe. In REXX, you use compound variables.

What Is a Compound Variable?

You can use compound variables to create an array or a list of variables in REXX. A compound variable, for example: employee.1, consists of a stem and a tail. A stem is a symbol with a period at the end. Here are some examples of stems:
FRED. Array. employee.
A tail is similar to a subscript. It follows the stem and consists of additional parts of the name that can be constant symbols (as in employee.1), simple symbols (as in employee.n), or null. Thus, in REXX, subscripts need not necessarily be numeric. A compound variable contains at least one period with characters on both sides of it. Here are some more examples of compound variables:
FRED.5 Array.Row.Col employee.name.phone
You cannot do any substitution for the name of the stem but you can use substitution for the tail. For example:
employee.7='Amy Martin' new=7 employee.new='May Davis' say employee.7 /* Produces: May Davis */
As with other REXX variables, if you have not previously assigned a value to a variable in a tail, it takes on the value of its own name in uppercase.
first = 'Fred' last = 'Higgins' name = first.last /* NAME is assigned FIRST.Higgins */
SAY name.first.middle.last /* Produces NAME.Fred.MIDDLE.Higgins */
/* The value FIRST appears because the */ /* variable FIRST is a stem, which */ /* cannot change. */
You can use a DO loop to initialize a group of compound variables and set up an array.
© Copyright IBM Corp. 1992, 2009 71
Manipulating Data
DOi=1TO6
PARSE PULL employee.i
END
If you use the same names used in the example of the employee array, you have a group of compound variables as follows:
employee.1 = 'Adams, Joe' employee.2 = 'Crandall, Amy' employee.3 = 'Devon, David' employee.4 = 'Garrison, Donna' employee.5 = 'Leone, Mary' employee.6 = 'Sebastian, Isaac'
After the names are in the group of compound variables, you can easily access a name by its number or by a variable that represents its number.
name = 3 SAY employee.name /* Produces 'Devon, David' */
For more information about compound variables, see section “Compound Symbols” on page 122.

Using Stems

When working with compound variables, it is often useful to initialize an entire collection of variables to the same value. You can do this easily by using an assignment that includes a stem. For example, number.=0 initializes all array elements in the array named number. to 0.
You can change the values of all compound variables in an array the same way. For example, to change all employee names to Nobody, use the following assignment instruction:
employee. = 'Nobody'
As a result, all compound variables beginning with the stem employee., previously assigned or not, have the value Nobody. After a stem assignment, you can assign individual compound variables new values.
employee.='Nobody' SAY employee.5 /* Produces 'Nobody' */ SAY employee.10 /* Produces 'Nobody' */ SAY employee.oldest /* Produces 'Nobody' */
employee.new = 'Clark, Evans' SAY employee.new /* Produces 'Clark, Evans' */
You can use stems with the EXECIO and RFS commands when reading to and writing from a file. See section “EXECIO” on page 344 for information about EXECIO. See section “RFS” on page 363 for information about RFS. RFS is the preferred I/O method under CICS.
Exercises - Using Compound Variables and Stems
1. After these assignment instructions, what do the following SAY instructions produce?
a = 3 /* assigns '3' to variable 'A' */ d = 4 /* '4' to 'D' */ c = 'last' /* 'last' to 'C' */ a.d = 2 /* '2' to 'A.4' */ a.c = 5 /* '5' to 'A.last' */ z.a.d = 'cv3d' /* 'cv3d' to 'Z.3.4' */
a. SAY a b. SAY D c. SAY c d. SAY a.a e. SAY A.D f. SAY d.c g. SAY c.a
72
CICS TS for VSE/ESA: REXX Guide
h. SAY a.first i. SAY z.a.4
2. After these assignment instructions, what output do the SAY instructions produce?
hole.1 = 'full' hole. = 'empty' hole.s = 'full'
a. SAY hole.1 b. SAY hole.s c. SAY hole.mouse
ANSWERS
1. a. 3 b. 4 c. last d. A.3 e. 2 f. D.last g. C.3 h. A.FIRST i. cv3d
2. a. empty b. full c. empty
Manipulating Data

Parsing Data

Parsing is separating data and assigning parts of it into one or more variables. Parsing can assign each word in the data into a variable or can divide the data into smaller parts. Parsing is also useful to format data into columns.
The variables to receive data are named in a template. A template is a model telling how to split the data. It can be as simple as a list of variables to receive data. More complex templates can contain patterns; section “Parsing with Patterns” on page 75 explains patterns.

Parsing Instructions

The REXX parsing instructions are PULL, ARG, and PARSE. (PARSE has several variants.)
PULL Instruction
Other chapters show PULL as an instruction that reads input and assigns it to one or more variables. If the program stack contains information, the PULL instruction takes information from the program stack. When the program stack is empty, PULL takes information from the current terminal input device. See section “Getting Information from the Program Stack or Terminal Input Device” on page 14 for information about the data stack.
/* This REXX program parses the string "Knowledge is power." */
PULL word1 word2 word3
/* word1 contains 'KNOWLEDGE' */ /* word2 contains 'IS' */ /* word3 contains 'POWER.' */
PULL uppercases character information before assigning it into variables. If you do not want uppercase translation, use the PARSE PULL instruction.
Chapter 7. Manipulating Data 73
Manipulating Data
/* This REXX program parses the string: "Knowledge is power." */
PARSE PULL word1 word2 word3
/* word1 contains 'Knowledge' */ /* word2 contains 'is' */ /* word3 contains 'power.' */
You can include the optional keyword UPPER on any variant of the PARSE instruction.This causes the language processor to uppercase character information before assigning it into variables. For example, using PARSE UPPER PULL... gives the same result as using PULL.
ARG Instruction
The ARG instruction takes information passed as arguments to a program, function, or subroutine, and puts it into one or more variables. To pass the three arguments Knowledge is power. to a REXX program named sample:
1. Call the program and pass the arguments as a string following the exec name:
REXX sample Knowledge is power.
2. Use the ARG instruction to receive the three arguments into variables.
/* SAMPLE -- A REXX program using ARG */
ARG word1 word2 word3
/* word1 contains 'KNOWLEDGE' */ /* word2 contains 'IS' */ /* word3 contains 'POWER.' */
ARG uppercases the character information before assigning the arguments into variables.
If you do not want uppercase translation, use the PARSE ARG instruction instead of ARG.
/* REXX program using PARSE ARG */
PARSE ARG word1 word2 word3
/* word1 contains 'Knowledge' */ /* word2 contains 'is' */ /* word3 contains 'power.' */
PARSE UPPER ARG has the same result as ARG. It uppercases character information before assigning it into variables.
PARSE VALUE ... WITH Instruction
The PARSE VALUE...WITH instruction parses a specified expression, such as a literal string, into one or more variables whose names follow the WITH subkeyword.
PARSE VALUE 'Knowledge is power.' WITH word1 word2 word3
/* word1 contains 'Knowledge' */ /* word2 contains 'is' */ /* word3 contains 'power.' */
PARSE VALUE does not uppercase character information before assigning it into variables. If you want uppercase translation, use PARSE UPPER VALUE. You could use a variable instead of a string in PARSE VALUE (you would first assign the variable the value):
string='Knowledge is power.' PARSE VALUE string WITH word1 word2 word3
/* word1 contains 'Knowledge' */ /* word2 contains 'is' */ /* word3 contains 'power.' */
Or you can use PARSE VAR to parse a variable.
PARSE VAR Instruction
The PARSE VAR instruction parses a specified variable into one or more variables.
74
CICS TS for VSE/ESA: REXX Guide
Manipulating Data
quote = 'Knowledge is power.' PARSE VAR quote word1 word2 word3
/* word1 contains 'Knowledge' */ /* word2 contains 'is' */ /* word3 contains 'power.' */
PARSE VAR does not uppercase character information before assigning it into variables. If you want uppercase translation, use PARSE UPPER VAR.

More about Parsing into Words

In the preceding examples, the number of words in the data to parse is always the same as the number of variables in the template. Parsing always assigns new values to all variables named in the template. If there are more variable names than words in the data to parse, the leftover variables receive null (empty) values. If there are more words in the data to parse than variable names in the template, each variable gets one word of data in sequence except the last variable, which gets the remainder of the data.
In the next example, there are more variable names in the template than words of data; the leftover variable receives a null value.
PARSE VALUE 'Extra variables' WITH word1 word2 word3
/* word1 contains 'Extra' */ /* word2 contains 'variables' */ /* word3 contains '' */
In the next example there are more words in the data than variable names in the template; the last variable gets the remainder of the data. The last variable name can contain several words and possibly leading and trailing blanks.
PARSE VALUE 'More words in data' WITH var1 var2 var3
/* var1 contains 'More' */ /* var2 contains 'words' */ /* var3 contains ' in data' */
Parsing into words generally removes leading and trailing blanks from each word before putting it into a variable. However, when putting data into the last variable, parsing removes one word-separator blank but retains any extra leading or trailing blanks. There are two leading blanks before words. Parsing removes both the word-separator blank and the extra leading blank before putting 'words' into var2. There are four leading blanks before in. Because var3 is the last variable, parsing removes the word-separator blank but keeps the extra leading blanks. Thus, var3 receives ' in data' (with three leading blanks).
A period in a template acts as a placeholder. It receives no data. You can use a period as a "dummy variable" within a group of variables or at the end of a template to collect unwanted information.
string='Example of using placeholders to discard junk' PARSE VAR string var1 . var2 var3 .
/* var1 contains 'Example' */ /* var2 contains 'using' */ /* var3 contains 'placeholders' */ /* The periods collect the words 'of' and 'to discard junk' */
For more information about parsing instructions, see section “PARSE” on page 152.

Parsing with Patterns

The simplest template is a group of blank-separated variable names. This parses data into blank-delimited words. The preceding examples all use this kind of template. Templates can also contain patterns. A pattern can be a string, a number, or a variable representing either of these.
Chapter 7. Manipulating Data 75
Manipulating Data
String
If you use a string in a template, parsing checks the input data for a matching string. When assigning data into variables, parsing generally skips over the part of the input string that matches the string in the template.
phrase = 'To be, or not to be?' /* phrase containing comma */ PARSE VAR phrase part1 ',' part2 /* template containing comma */
/* part1 contains 'To be' */ /* part2 contains ' or not to be?' */
/* as string separator */
In this example, notice that the comma is not included with 'To be' because the comma is the string separator. (Notice also that part2 contains a value that begins with a blank. Parsing splits the input string at the matching text. It puts data up to the start of the match in one variable and data starting after the match in the next variable.
Variable
When you do not know in advance what string to specify as separator in a template, you can use a variable enclosed in parentheses.
separator = ',' phrase = 'To be, or not to be?' PARSE VAR phrase part1 (separator) part2
/* part1 contains 'To be' */ /* part2 contains ' or not to be?' */
Again, in this example, notice that the comma is not included with 'To be' because the comma is the string separator.
Number
You can use numbers in a template to indicate the column at which to separate data. An unsigned integer indicates an absolute column position. A signed integer indicates a relative column position.
An unsigned integer or an integer with the prefix of an equal sign (=) separates the data according to absolute column position. The first segment starts at column 1 and goes up to, but does not include, the information in the column number specified. Subsequent segments start at the column numbers specified.
quote = 'Ignorance is bliss.'
PARSE VAR quote part1 5 part2
The following code has the same result:
quote = 'Ignorance is bliss.'
PARSE VAR quote 1 part1 =5 part2
Specifying the numeric pattern 1 is optional. If you do not use a numeric pattern to indicate a starting point for parsing, this defaults to 1. The example also shows that the numeric pattern 5 is the same as =5.
....+....1....+....2
/* part1 contains 'Igno' */ /* part2 contains 'rance is bliss.' */
....+....1....+....2
/* part1 contains 'Igno' */ /* part2 contains 'rance is bliss.' */
If a template has several numeric patterns and a later one is lower than a preceding one, parsing loops back to the column the lower number specifies.
quote = 'Ignorance is bliss.'
PARSE VAR quote part1 5 part2 10 part3 1 part4
76
....+....1....+....2
CICS TS for VSE/ESA: REXX Guide
Manipulating Data
/* part1 contains 'Igno' */ /* part2 contains 'rance' */ /* part3 contains ' is bliss.' */ /* part4 contains 'Ignorance is bliss.' */
When each variable in a template has column numbers both before and after it, the two numbers indicate the beginning and the end of the data for the variable.
quote = 'Ignorance is bliss.'
....+....1....+....2
PARSE VAR quote 1 part1 10 11 part2 13 14 part3 19 1 part4 20
/* part1 contains 'Ignorance' */ /* part2 contains 'is' */ /* part3 contains 'bliss' */ /* part4 contains 'Ignorance is bliss.' */
Thus, you could use numeric patterns to skip over part of the data:
quote = 'Ignorance is bliss.'
PARSE VAR quote 2 var1 35var2 78var3 var 4 var5 SAY var1||var2||var3 var4 var5 /* || means concatenate */
....+....1....+....2
/* Says: grace is bliss. */
A signed integer in a template separates the data according to relative column position. The plus or minus sign indicates movement right or left, respectively, from the starting position. In the next example, remember that part1 starts at column 1 (by default because there is no number to indicate a starting point).
quote = 'Ignorance is bliss.'
PARSE VAR quote part1 +5 part2 +5 part3 +5 part4
....+....1....+....2
/* part1 contains 'Ignor' */ /* part2 contains 'ance ' */ /* part3 contains 'is bl' */ /* part4 contains 'iss.' */
+5 part2 means parsing puts into part2 data starting in column 6 (1+5=6). +5 part3 means data put into part3 starts with column 11 (6+5=11), and so on. The use of the minus sign is similar to the use of the
plus sign. It identifies a relative position in the data string. The minus sign “backs up” (moves to the left) in the data string.
quote = 'Ignorance is bliss.'
PARSE VAR quote part1 +10 part2 +3 part3 -3 part4
....+....1....+....2
/* part1 contains 'Ignorance ' */ /* part2 contains 'is ' */ /* part3 contains 'bliss.' */ /* part4 contains 'is bliss.' */
In this example, part1 receives characters starting at column 1 (by default). +10 part2 receives characters starting in column 11 (1+10=11). +3 part3 receives characters starting in column 14 (11+3=14). -3 part4 receives characters starting in column 11 (14-3=11).
To provide more flexibility, you can define and use variable numeric patterns in a parsing instruction. To do this, first define the variable as an unsigned integer before the parsing instruction. Then, in the parsing instruction, enclose the variable in parentheses and specify one of the following before the left parenthesis:
v A plus sign (+) to indicate column movement to the right v A minus sign (-) to indicate column movement to the left v An equal sign (=) to indicate an absolute column position.
Chapter 7. Manipulating Data 77
Manipulating Data
(Without +, ,or= before the left parenthesis, the language processor would consider the variable to be a string pattern.) The following example uses the variable numeric pattern movex.
quote = 'Ignorance is bliss.'
movex = 3 /* variable position */ PARSE VAR quote part5 +10 part6 +3 part7 -(movex) part8
....+....1....+....2
/* part5 contains 'Ignorance ' */ /* part6 contains 'is ' */ /* part7 contains 'bliss.' */ /* part8 contains 'is bliss.' */
For more information about parsing, see Chapter 15, “Parsing,” on page 203.

Parsing Multiple Strings as Arguments

When passing arguments to a function or a subroutine, you can specify multiple strings to be parsed. The ARG, PARSE ARG, and PARSE UPPER ARG instructions parse arguments. These are the only parsing instructions that work on multiple strings.
To pass multiple strings, use commas to separate adjacent strings.
The next example passes three arguments to an internal subroutine.
CALL sub2 'String One', 'String Two', 'String Three'
: :
EXIT
sub2: PARSE ARG word1 word2 word3, string2, string3
/* word1 contains 'String' */ /* word2 contains 'One' */ /* word3 contains '' */ /* string2 contains 'String Two' */ /* string3 contains 'String Three' */
The first argument is two words "String One" to parse into three variable names, word1, word2, and word3. The third variable, word3, is set to null because there is no third word. The second and third arguments are parsed entirely into variable names string2 and string3.
For more information about parsing multiple arguments that have been passed to a program or subroutine, see section “Parsing Multiple Strings” on page 211.
Exercise - Practice with Parsing
What are the results of the following parsing examples?
quote = 'Experience is the best teacher.'
1.
PARSE VAR quote word1 word2 word3
a) word1 = b) word2 = c) word3 =
quote = 'Experience is the best teacher.'
2.
PARSE VAR quote word1 word2 word3 word4 word5 word6
a) word1 = b) word2 = c) word3 = d) word4 = e) word5 = f) word6 =
PARSE VALUE 'Experience is the best teacher.' WITH word1 word2 . . word3
3. a) word1 = b) word2 =
78
CICS TS for VSE/ESA: REXX Guide
Loading...