home *** CD-ROM | disk | FTP | other *** search
Text File | 1978-01-15 | 285.0 KB | 6,600 lines |
-
- TABLE OF CONTENTS
-
- AREXX USER'S REFERENCE MANUAL
-
- INTRODUCTION....................................................1
- 1. Organization of this Document...............................1
- 1 Using this Manual.........................................2
- 2 Typographic Conventions...................................2
- 2. Future Directions...........................................2
- CHAPTER 1. WHAT IS AREXX?.......................................3
- 1. Language Features...........................................3
- 2. ARexx on the Amiga..........................................4
- 3. Further Information.........................................4
- CHAPTER 2. GETTING ACQUAINTED...................................5
- 1. Installing ARexx............................................5
- 1 ARexx and Workbench.......................................5
- 2 Installation..............................................5
- 3 Starting the Resident Process.............................6
- 4 Naming Conventions........................................6
- 5 The REXX: Directory.......................................6
- 2. Program Examples............................................7
- CHAPTER 3. ELEMENTS OF THE LANGUAGE............................11
- 1. Format.....................................................11
- 2. Tokens.....................................................11
- 1 Comment Tokens...........................................11
- 2 Symbol Tokens............................................11
- 3 String Tokens............................................12
- 4 Operators................................................12
- 5 Special Character Tokens.................................13
- 3. Clauses....................................................14
- 1 Null Clauses.............................................14
- 2 Label Clauses............................................14
- 3 Assignment Clauses.......................................14
- 4 Instruction Clauses......................................15
- 5 Command Clauses..........................................15
- 6 Clause Classification....................................15
- 4. Expressions................................................16
- 1 Symbol Resolution........................................16
- 2 Order of Evaluation......................................16
- 5. Numbers and Numeric Precision..............................17
- 1 Boolean Values...........................................17
- 2 Numeric Precision........................................17
- 6. Operators..................................................18
- 1 Arithmetic Operators.....................................18
- 2 Concatenation Operators..................................20
- 3 Comparison Operators.....................................20
- 4 Logical (Boolean) Operators..............................21
- 7. Stems and Compound Symbols.................................21
-
- i
-
- CHAPTER 3. ELEMENTS OF THE LANGUAGE (CONT).....................11
- 8. The Execution Environment..................................22
- 1 The External Environment.................................22
- 2 The Internal Environment.................................22
- 3 Input and Output.........................................23
- 4 Resource Tracking........................................24
- CHAPTER 4. INSTRUCTIONS........................................25
- 1. ADDRESS....................................................25
- 2. ARG........................................................25
- 3. BREAK......................................................26
- 4. CALL.......................................................26
- 5. DO.........................................................27
- 6. DROP.......................................................28
- 7. ECHO.......................................................28
- 8. ELSE.......................................................28
- 9. END........................................................29
- 10. EXIT......................................................29
- 11. IF........................................................29
- 12. INTERPRET.................................................30
- 13. ITERATE...................................................30
- 14. LEAVE.....................................................31
- 15. NOP.......................................................31
- 16. NUMERIC...................................................31
- 17. OPTIONS...................................................32
- 18. OTHERWISE.................................................32
- 19. PARSE.....................................................33
- 1 Input Sources...........................................33
- 2 Templates...............................................34
- 20. PROCEDURE.................................................35
- 21. PULL......................................................35
- 22. PUSH......................................................36
- 23. QUEUE.....................................................37
- 24. RETURN....................................................37
- 25. SAY.......................................................38
- 26. SELECT....................................................38
- 27. SHELL.....................................................38
- 28. SIGNAL....................................................38
- 29. THEN......................................................39
- 30. TRACE.....................................................40
- 31. UPPER.....................................................40
- 32. WHEN......................................................41
- CHAPTER 5. COMMANDS............................................43
- 1. Command Clauses............................................43
- 2. The Host Address...........................................44
- 3. The Command Interface......................................44
- 4. Using Commands in Macro Programs...........................45
- 5. Using ARexx with Command Shells............................45
- 6. Command Inhibition.........................................46
-
- ii
-
- CHAPTER 6. FUNCTIONS...........................................47
- 1. Syntax and Search Order....................................47
- 1 Search Order.............................................47
- 2 Internal Functions.......................................48
- 3 Built-In Functions.......................................49
- 4 External Function Libraries..............................49
- 5 Function Hosts...........................................50
- 2. The Built-In Function Library..............................50
- 1 ABBREV().................................................51
- 2 ABS()....................................................51
- 3 ADDLIB().................................................51
- 4 ADDRESS()................................................51
- 5 ARG()....................................................52
- 6 B2C()....................................................52
- 7 BITAND().................................................52
- 8 BITCHG().................................................52
- 9 BITCLR().................................................53
- 10 BITCOMP()...............................................53
- 11 BITOR().................................................53
- 12 BITSET()................................................53
- 13 BITTST()................................................53
- 14 BITXOR()................................................54
- 15 C2B()...................................................54
- 16 C2D()...................................................54
- 17 C2X()...................................................54
- 18 CENTER() OR CENTRE()....................................55
- 19 CLOSE().................................................55
- 20 COMPRESS()..............................................55
- 21 COMPARE()...............................................55
- 22 COPIES()................................................55
- 23 D2C()...................................................56
- 24 DATATYPE()..............................................56
- 25 DELSTR()................................................56
- 26 DELWORD()...............................................57
- 27 EOF()...................................................57
- 28 ERRORTEXT().............................................57
- 29 EXISTS()................................................57
- 30 EXPORT()................................................57
- 31 FREESPACE().............................................58
- 32 GETCLIP()...............................................58
- 33 GETSPACE()..............................................58
- 34 HASH()..................................................58
- 35 IMPORT()................................................59
- 36 INDEX().................................................59
- 37 INSERT()................................................59
- 38 LASTPOS()...............................................59
- 39 LEFT()..................................................60
- 40 LENGTH()................................................60
-
- iii
-
- 41 MAX()...................................................60
- 42 MIN()...................................................60
- 43 OPEN()..................................................60
- 44 OVERLAY()...............................................61
- 45 POS()...................................................61
- 46 PRAGMA()................................................61
- 47 RANDOM()................................................62
- 48 RANDU().................................................62
- 49 READCH()................................................62
- 50 READLN()................................................63
- 51 REMLIB()................................................63
- 52 REVERSE()...............................................63
- 53 RIGHT().................................................63
- 54 SEEK()..................................................63
- 55 SETCLIP()...............................................64
- 56 SHOW()..................................................64
- 57 SIGN()..................................................64
- 58 SPACE().................................................64
- 59 STORAGE()...............................................65
- 60 STRIP().................................................65
- 61 SUBSTR()................................................65
- 62 SUBWORD()...............................................66
- 63 SYMBOL()................................................66
- 64 TIME()..................................................66
- 65 TRACE().................................................67
- 66 TRANSLATE().............................................67
- 67 TRIM()..................................................67
- 68 UPPER().................................................67
- 69 VALUE().................................................68
- 70 VERIFY()................................................68
- 71 WORD()..................................................68
- 72 WORDINDEX().............................................68
- 73 WORDLENGTH()............................................68
- 74 WORDS().................................................69
- 75 WRITECH()...............................................69
- 76 WRITELN()...............................................69
- 77 X2C()...................................................69
- 78 XRANGE()................................................69
- CHAPTER 7. TRACING AND INTERRUPTS..............................71
- 1. Tracing Options............................................71
- 2. Display Formatting.........................................72
- 1 Tracing Output...........................................72
- 2 Command Inhibition.......................................73
- 3. Interactive Tracing........................................73
- 1 Error Processing.........................................74
- 2 The External Tracing Flag................................74
- 4. Interrupts.................................................74
-
- iv
-
- CHAPTER I. PARSING AND TEMPLATES...............................77
- 1. Template Structure.........................................77
- 1 Template Objects.........................................78
- 2 The Scanning Process.....................................78
- 2. Templates in Action........................................79
- 1 Parsing by Tokenization..................................79
- 2 Pattern Parsing..........................................80
- 3 Positional Markers.......................................80
- 4 Multiple Templates.......................................80
- CHAPTER 9. THE RESIDENT PROCESS................................83
- 1. Command Utilities..........................................83
- 1 HI.......................................................83
- 2 RX.......................................................84
- 3 RXSET....................................................84
- 4 RXC......................................................84
- 5 TCC......................................................84
- 6 TCO......................................................84
- 7 TE.......................................................84
- 8 TS.......................................................84
- 2. Resource Management........................................85
- 1 The Global Tracing Console...............................85
- 2 The Library List.........................................85
- 3 The Clip List............................................86
- CHAPTER 10. INTERFACING TO AREXX...............................89
- 1. Basic Structers............................................90
- 2. Designing a Command Interface..............................91
- 1 Receiving Command Messages...............................92
- 2 Result Fields............................................92
- 3 Multiple Host Processes..................................92
- 3. Invoking ARexx Programs....................................93
- 1 Message Packets..........................................93
- 2 Command Invocations......................................94
- 3 Function Invocations.....................................95
- 4 Search Order.............................................95
- 5 Extension Fields.........................................96
- 6 Interpreting the Result Fields...........................97
- 4. Communicating with the Resident Process....................97
- 1 Command (Action) Codes...................................97
- 2 Modifier Flags...........................................99
- 3 Result Fields...........................................100
- 5. External Function Libraries...............................100
- 1 Design Considerations...................................100
- 2 Calling Convention......................................101
- 3 Parameter Conversion....................................101
- 4 Returned Values.........................................101
- 6. Direct Manipulation of Data Structures....................102
-
- v
-
- APPENDIX A. ERROR MESSAGES....................................103
- APPENDIX B. LIMITS AND COMPATIBILITY..........................109
- 1 Limits.....................................................109
- 2 Compatibility..............................................109
- APPENDIX C. THE AREXX SYSTEMS LIBRARY.........................111
- 1 Functional Groups..........................................111
- 2 Library Functions..........................................113
- APPENDIX D. THE AREXX SUPPORT LIBRARY.........................127
- 1 ALLOCMEM()...............................................127
- 2 CLOSEPORT()..............................................127
- 3 FREEMEM()................................................128
- 4 GETARG().................................................128
- 5 GETPKT().................................................128
- 6 OPENPORT()...............................................128
- 7 REPLY()..................................................129
- 8 SHOWDIR()................................................129
- 9 SHOWLIST()...............................................129
- 10 STATEF()................................................130
- 11 WAITPKT()...............................................130
- APPENDIX E. DISTRIBUTION FILES................................131
- 1 Directories................................................131
- 1 The :C Directory.........................................131
- 2 The :INCLUDE Directory...................................131
- 3 The :LIBS Directory......................................132
- 4 The :REXX Directory......................................132
- 5 The :TOOLS Directory.....................................132
- 6 Miscellaneous Files......................................132
- 2 Listings of Header Files...................................133
- 1 storage.h................................................133
- 2 rxslib.h.................................................139
- 3 rexxio.h.................................................142
- 4 errors.h.................................................144
- GLOSSARY......................................................147
- INDEX.........................................................151
-
- vi
-
- INTRODUCTION
-
- Welcome to ARexx,an implementation of the REXX language for the Amiga computer.
- ARexx is a powerful programming took,but one which by virtue of its clean
- syntax and sparse vocabulary is also easy to learn and easy to use.
-
- 1 ORGANIZATION OF THIS DOCUMENT
-
- This document will attempt to fill the roles of User's Manual,Language
- Reference,and Programmer's Guide. The chapters that follow have been organized
- to provide a gently introduction to the language.
-
- Chapter 1,What is ARexx?,gives an overview of the ARexx language and its
- implementation of the Amiga.
-
- Chapter 2,Getting Acquainted,tells how to install ARexx on your Amiga and
- presents several example programs to illustrate the features of the language.
-
- Chapter 3,Elements of the Language,introduces the language structure and
- syntax.
-
- Chapter 4,Instructions,describes the action statements of ARexx.
-
- Chapter 5,Commands,describes the program statements used to communicate with
- external programs.
-
- Chapter 6,Functions,explains how functions are called and documents the Built-
- In Function library.
-
- Chapter 7,Tracing and Interrupts,describes the source level debugging features
- useful for developing and testing programs.
-
- Chapter 8,Parsing and Templates,describes the instructions used to extract
- words or fields from strings.
-
- Chapter 9,The Resident Process,describes the capabilities of the global
- communications and resources manager.
-
- Chapter 10,Interfacing to ARexx,describes how to design and implement an
- interface between ARexx and an external program.
-
- Appendix A,Error Messages,lists the error messages issued by the interpreter.
-
- Appendix B,Limits and Compatibility,discusses the compatibility of ARexx with
- the language standard.
-
- Appendix C,The ARexx Systems Library,documents the functions of ARexx systems
- library.
-
- Appendix D,The Support Library,documents the library of Amiga specific
- functions.
-
- Appendix E,Distribution Files,lists the files on the distribution disk.
-
- Finally,a Glossary and an Index are provided.
-
- 1
-
- USING THIS MANUAL
-
- If you are new to the REXX language,or perhaps to programming itself,you should
- review chapters 1 through 4 and then play with ARexx by running some of the
- sample programs given in chapter 2. Further examples are available in the :rexx
- directory of the distribution disk.
-
- If you are already familiar with REXX you may wish to skip directly to chapter
- 5,which begins to present some of the system-dependent features of this
- implementation. A summary of the compatibility of ARexx with the language
- definition is contained in Appendix B.
-
- TYPOGRAPHIC CONVENTIONS
-
- Describing a language is sometimes difficult because of the multiple and
- changing contexts involved. To help clarify the presentation here,a simply
- typographic convention has been adopted throughout the document. All of the
- terms and words specific to the REXX language,as well as the program examples
- and computer input and output,have been set in typewriter font like this. This
- should help to distinguish the language keywords and examples from the
- surrounding text.
-
- 2 FUTURE DIRECTIONS
-
- ARexx,like most software products,will probably envolve somewhat over the next
- few years as new features are added,old bugs are removed,and market imperatives
- become more apparant. While the core language will probably undergo few
- modifications,many capabilities will be added to the function libraries
- supported by ARexx. Your comments and suggestions for improvements to ARexx are
- most welcome.
-
- The author sincerely hopes that other software developers will consider using
- ARexx with their products. The advantages of having a rich variety of software
- products sharing a common user interface and a common procedural interface
- cannot be overstated. This is the underlying promise of the Amiga's
- multitasking capability,and that which most sets it apart from other
- inexpensive computers.
-
- Example Programs. One of the best ways to learn a computer language is to study
- examples written by more experienced programmers. The ARexx distribution disk
- includes a few example programs in the :rexx directory,and more programs will
- be added in future releases.
-
- If you have written REXX language program(for any computer)that you think would
- be of interest to a more general audience,please send it to the author for
- consideration. Programs should be of interest either in terms of their specific
- funtionality or as an example of programming technique. Each program submitted
- should include an author credit and a few lines of commentary on its intended
- fuction.
-
- 2
-
- ARexx is a high-level language useful for prototyping,software integration,and
- general programming tasks. It is an implementation of the REXX language
- described by M.F. Cowlishaw in The REXX Language:A Practical Approach to
- Programming(Prentice-Hall,1985),and follow the language definition closely.
- ARexx is particularly well suited as a command language. Command programs,
- sometimes called "scripts" or "macros",are widely used to extend the predefined
- commands of an operating system or to customize an applications program.
-
- As a programming language,ARexx can be useful to a wide cross section of users.
- For the novice programmer,ARexx is an easy-to-learn yet powerful language that
- serves as a good introduction to programming techniques. Its source-level
- debugging facilities will help take some of the mystery out of how programs
- work(or don't work,as is more frequently the case.)
-
- For the more sophisticated user,ARexx provides the means to build fully
- integrated software packages,combining different applications programs into an
- environment tailored to their needs. A common command language among
- applications that support ARexx will bring uniformity to procedural interfaces,
- much as the Amiga's Intuition provides uniformity in the graphical interface.
-
- Finally,for the software developer,ARexx offers a straightforward way to build
- fully programmable applications programs. Developers can concentrate their
- efforts on making the basic operations of their programs fast and efficient,and
- let the end user add the frills and custom features.
-
- 1-1 LANGUAGE FEATURES
-
- Some of the important features of the language are:
-
- TYPELESS DATA. Data are treated as typeless character strings. Variables do not
- have to be declared before being used,and all operations dynamically check the
- validity of the operands.
-
- COMMAND INTERFACE. ARexx programs can issue commands to external programs that
- provide a suitable command interface. Any software package that implements the
- command interface is then fully programmable using ARexx,and can be extended
- and customized by the end user.
-
- TRACING AND DEBUGGING. ARexx includes source-level debugging facilities that
- allow the programmer to see the step-by-step actions of a program as it runs,
- thereby reducing the time required to develop and test programs. An internal
- interrupt system permits special handling of errors that would otherwise cause
- the program to terminate.
-
- 3
-
- INTERPRETED EXECUTION. ARexx programs are run by an interpreter,so separate
- compilation and linking steps are not required. This makes it especially useful
- for prototyping and as a learning tool.
-
- FUNCTION LIBRARIES. External function libraries can be used to extend the
- capabilities of the language or as bridges to other programs. Libraries also
- allow ARexx programs to be used as "test drivers" for software development and
- testing.
-
- AUTOMATIC RESOURCE MANAGEMENT. Internal memory allocation related to the
- creation and destruction of strings and other data structures is handled
- automatically.
-
- 1-2 AREXX ON THE AMIGA
-
- ARexx was designed to run on the Amiga,and makes use of many of the features of
- its multitasking operating system. ARexx programs run as separate tasks and
- may communicate with each other or with external programs. The interpreter
- follows the design guidelines expected of well-behaved programs in a
- multitasking environment: specifcally,it uses as little memory as possible and
- is careful to reutrn resources to the operating system when they are no longer
- needed. Memory requirements were minimized by implementing the entire ARexx
- system as a shared library,so that only one copy of the program code must be
- loaded.
-
- 1-3 FURTHER INFORMATION
-
- The aforementioned book by M.F. Cowlishaw is highly recommended to those
- interested in further information about REXX. It presents an interesting
- discussion of the design and development of the language.
-
- 4
-
- CHAPTER 2 GETTING ACQUAINTED
-
- This chapter explains how to install ARexx on your Amiga computer and shows
- some example programs.
-
- 2-1 INSTALLING AREXX
-
- ARexx requires an Amiga computer with at least 256k of memory,and will operate
- under V1.1 or V1.2 of the operating system. It uses the double-precision math
- library called "mathieeedoubbas.library" that is supplied with the Amiga
- WorkBench disk,so make sure that this file is present in your LIBS: directory.
- The distribution disk includes the language system,some example programs,and a
- set of the INCLUDE files required for integrating ARexx with other software
- packages. The distribution files are listed in Appendix E.
-
- AREXX AND WORKBENCH
-
- ARexx can be installed and loaded from within the icon-based environment
- provided by the Amiga WorkBench. However,it is a primarily a text-oriented
- language system and requires a good text editor and file management environment
- to be most effective. Unless you purchased ARexx as part of an applications
- package that includes an integrated editor,you'll probably find it useful to
- become familiar with the Commmand Line Interface (CLI)environment on the Amiga.
-
- INSTALLATION
-
- The ARexx language system consists of a shared library,a resident program,and
- several command utilities. All of the required files are contained in the :c
- and :libs directories of the distribution disk. ARexx may be installed on any
- of the system disks with which it will be used,but first check the :c and :libs
- directores of each disk to make sure that there are no naming conflicts. The
- following steps will then install ARexx on the system disk,provided that two
- disk drives are available:
-
- 1. Activate a CLI window.
- 2. Copy the ARexx :libs directory to the system LIBS: directory with the
- command "copy df1:libs to libs:".
- 3. Copy the ARexx :c directory to the system C: directory with the command
- "copy df1:C to c:".
-
- SINGLE DRIVE SYSTEMS. Installing software in a single-drive system can be very
- confusing,so an installation utility has been provided with the ARexx
- distribution disk. It copies the :c and :libs directories of the distribution
- disk into memory,and then prompts the user to insert each disk that is to
- receive the files. Follow these steps to run the installation utility:
-
- 5
-
- 1. Activate a CLI window.
- 2. Insert the distribution disk into drive 0 and type "df0:rxinstall".
- 3. At the program prompt,insert the system disk on which ARexx is to be
- installed into drive 0.
- 4. Repeat step 3 as required.
-
- STARTING THE RESIDENT PROCESS
-
- ARexx programs are launched by a background program called the resident
- process. It can be started by issuing the command rexxmast and must be active
- before any ARexx programs can be run. The rexxmast program briefly displays a
- small window to announce itself,and then disappears into the background to
- await your next request. If you will be using ARexx frequently,you can place
- the rexxmast command in the "startup-sequence" file that resides in the system
- S: directory. This will start the resident process automatically when you
- reboot the computer.
-
- After the resident process has been loaded,ARexx programs can be run from the
- CLI by typing the command rx followed by the program name and any arguments.
- For example,the sample program calc.rexx,which evaluates an expression,could be
- run by typeing "rx :rexx/calc 1+1."
-
- You may not need to start up the resident process if you are using a software
- package that starts it automatically. Applications that use ARexx can test
- whether the resident process is active by checking for a public message port
- named "REXX." If the port hasn't been opened,the program can issue the rexxmast
- command directly.
-
- The resident process can be closed using the command rxc;it will then exit as
- soon as the last ARexx program finishes execution. Unless you are very short on
- memory space,there is usually no reason to close ARexx,as it simply waits in
- the background for the next program to run.
-
- NAMING CONVENTIONS
-
- ARexx programs can be named anything,but adopting a simple naming convention
- will make managing the programs much easier. Programs to be run from the CLI
- are usually given the file extention .rexx to distinguish them from programs
- written in other languages. Programs written as "macros" or "scripts" for a
- particular applications program should be given a file extension specific to
- that program. For example,a macro written for a communications program called
- "MyComm" might be named "download.myc". ARexx uses this file extention when it
- searches for a program file to be executed.
-
- THE REXX: DIRECTORY
-
- You can designate one directory as the system-wide source for ARexx programs by
- defining a REXX: "device" with the assign command. This directory should reside
- on a volume that is usually mounted,such as SYS: or a hard disk. For example,
- the command "assign rexx: sys:rexx" defines the REXX: device as the :rexx
- directory on the system disk. Once defined,the REXX: device is searched after
- the current directory when looking for an ARexx program.
-
- 6
-
- 2-2 PROGRAM EXAMPLES
-
- Before introducing the structure and syntax of the language,let's look at a few
- examples of ARexx programs. Readers familiar with other high-level programming
- languages should find many points of similarity between ARexx and other
- languages. In the examples that follow,new terms are highlighted in the text as
- they are introduced,and will be convered in depth in the next few chapters.
-
- These short programs can be created using any text editor and then run from the
- Command Line Interface (CLI),or may simply be read as samples of the language.
- If the examples are to be run,first complete the installation procedures
- outlined in the previous section,and then start the ARexx resident process.
- Example programs can then be run by entering,for example,"rx age" at the CLI
- prompt.
-
- We'll begin with a "Hello,World" program that simply displays a message on the
- console screen.
-
- /* A simple program */
- say 'Hello,World'
-
- This program consists of a comment line that describes the program and an
- instruction that displays text on the console. For historical reasons, ARexx
- programs begin with a comment line;the initial "/*" says "I'm an ARexx program"
- to the interpreter when it searches for a program.
-
- Instructions are language statements that denote a certain action to be
- performed,and always start with a symbol,in this case the word say. Symbols are
- translated to uppercase when the program is run,so the symbol say here is
- equivalent to SAY. Following say is an example of a string,which is a series of
- characters surrounded by quotes ('). Double quotes (") could also have been
- used to define the string.
-
- In the next program we'll display a prompt for input and then read some
- information from the user.
-
- /* Calculate age in days */
- say 'Please enter your age'
- pull age
- say 'You are about' age*365 'days old'
-
- This program uses the pull instruction to read a line of input into a variable
- called age,which is then used with a say instuction. Variables are symbols that
- may be assigned a value. The words following say form an expression in which
- strings are joined and an arithmetic calculation is performed.
-
- Note that the variable age did not have to be declared as a number;instead,its
- value was checked when it was actually used in the expression. To see what
- would happen if age wasn't a number,try rerunning the program with a
- non-numeric entry for the age. The resulting error message shows the line
- number and type of error that occurred,after which the program ends.
-
- 7
-
- The next program introduces the do instruction,which allows program statements
- to be executed repeatedly. It also illustrates the exponentiation operator,
- which is used to raise a number to an integral power.
-
- /* Calculate some squares and cubes */
- do i = 1 to 10 /* 10 interations */
- say i i**2 i**3 /* calculations */
- end
- say ' all done '
-
- The do instruction causes the statements between the do and end instructions to
- be executed 10 times. The variable i is the index variable for the loop,and is
- incremented by 1 for each iteration. The number following the symbol to is the
- limit for the do instruction,and could have been a full expression rather than
- just the constant 10. Note that the statements within the loop have been
- indented. This is not required by the language,but it makes the program more
- readable and is therefore good programming practice.
-
- The subject of the next example is the if instruction,a often-used control
- statement that allows statements to be conditionally executed. The numbers from
- 1 to 10 are classified as even or odd by dividing them by 2 and then checking
- the remainder.
-
- /* Even or odd? */
- do i = 1 to 10
- if i//2 = 0 then type = 'even'
- else type = 'odd'
- say i 'is' type
- end
-
- This example intoduces the // arithmetic operator,which calculates the
- remainder after a division operation. The if instruction tests whether the
- remainder is 0 and executes the then branch if it is,thereby setting the
- variable type to "even." If the remainder was not 0,the alternative else branch
- is executed and type is set to "odd."
-
- The next example introduces the concept of a function,which is a group of
- statements that can be executed by mentioning the function name in a suitable
- context. Functions are an important part of most programming languages,as they
- allow large,complex programs to be built from smaller modules. Functions are
- specified in an expression as a name followed by an open parenthesis. One or
- more expressions called arguments may follow the parenthesis;these are used to
- pass information to the function for processing.
-
- 8
-
- /* Defining and calling a function */
- do i = 1 to 5
- say i square(i) /* call square */
- end
- exit /* all done */
- square: /* function name */
- arg x /* get the "argument" */
- return x**2 /* square it and return*/
-
- The function square is defined in the lines followed the label square: up
- through the return instruction. Two new instructions are introduced here: arg
- retrieves the value of the argument string,and return passes the functon's
- result back to the point where the function was called.
-
- One final example will suffice for now. A new instruction called trace is used
- here to activate the tracing features of ARexx.
-
- /* Demonstrate "results" tracing */
- trace results
- sum=0;sumsq=0;
- do i = 1 to 5
- sum = sum + i
- sumsq = sumsq + i**2
- end
- say 'sum=' sum 'sumsq=' sumsq
-
- When this program is run,the console displays the source lines as they are
- excuted,and shows the final results of expressions. This makes it easy to tell
- what the program is really doing,and helps reduce the time required to develop
- and test a new program. One minor point is illustrated here: the third line
- shows two distinct statements separated by a semicolon (;). The semicolon is an
- example of a special character,characters that have particular meanings within
- ARexx programs.
-
- The following chapters will present further information on the language
- statements illustrated here and will introduce others that have not been shown.
- Take heart,though;ARexx is a "small" language and there are relatively few
- words and rules to learn.
-
- 9
-
- THERE WAS NO PAGE 10
-
- ELEMENTS OF THE LANGUAGE
-
- This chapter introduces the rules and concepts that make up the REXX language.
- The intent is not to present a formalized definition,but rather to convey a
- practical understanding of how the language elements "fit together" to form
- programs.
-
- 3-1 FORMAT
-
- ARexx programs are compossed of ASCII characters and may be created using any
- text editor. No special formatting of the program statements is required or
- imposed on the programmer.
-
- 3-2 TOKENS
-
- The smallest distinct entities or "words" of the language are called tokens. A
- token may be series of characters,as in the symbol MyName,or just a single
- character like the "+" operator. Tokens can be categorized into comments,
- symbols,strings,operators,and special characters. Each of these groups are
- described below.
-
- COMMENT TOKENS
-
- Any group of characters beginning with the sequence "/*" and ending with "*/"
- defines a comment token. Comments may be placed anywhere in a program and cost
- little in terms of execution speed,since they are stripped(removed)when the
- program is first scanned by the interpreter. Comments may be "nested" within
- one another,but each "/*" must have a matching "*/" in the program.
- Examples:
-
- /* Your basic comment */
- /* a /* nested! */ comment */
-
- SYMBOL TOKENS
-
- Any group of the characters a-z,A-Z,0-9,and .!?$_defines a symbol token.
- Symbols are translated to uppercase as the program is scanned by the
- interpreter,so the symbol MyName is equivalent to MYNAME. Four types of symbols
- are recognized:
-
- Fixed symbols begin with a digit (0-9) or a period(.).
- Simple symbols do not begin with a digit,and do not contain any
- periods.
- Stem symbols have exactly one period at the end of the symbol name.
- Compound symbols include one or more periods in the interior of the
- name.
-
- Stems and compound symbols have special properties that make them useful for
- building arrays and lists.
-
- 11
-
- SYMBOLS VALUES. The value used for a fixed symbol is always the symbol name
- itself(as translated to uppercase.) Simple,stem,and compound symbols are called
- variables and may be assigned a value;the value used for an uninitialized
- variable is just the variable name itself.
- Examples:
-
- 123.45 /*a fixed symbol */
- MyName /*same as MyName */
- a. /*a stem symbol */
- a.1.Index /*a compound symbol */
-
- STRING TOKENS
-
- A group of characters beginning and ending with a quote (')or double quote(")
- delimiter defines a string token. The delimiter character itself may be
- included within the string by a double-delimiter sequence (" or ""). The number
- of characters in the string is called its length,and a string of length zero is
- called a null string. A string is treated as a literal in an expression;that
- is,its value is just the string itself.
-
- Strings followed immediately by an "X" or "B" character that is not part of a
- longer symbol are classified as hex or binary strings,respectively,and must be
- composed of hexadecimal digits(0-9,A-F) or binary digits(0,1). Blanks are
- permitted at byte boundaries for added readability. Hex and binary strings are
- convenient for specifying non-ASCII characters and for machine-specific
- information like addresses in a program. They are converted immediately to the
- "packed" internal form.
- Examples:
- "Now is the time" /*a simple example */
- "" /*a null string */
- 'Can't you see??' /*Can't you see?? */
- '4A 3B CO'X /*a hex string */
- '00110111'b /*binary for '7' */
-
- OPERATORS
-
- The characters +-*/=><*| may be combined in the sequences shown in Table 3.1
- to form operator tokens. Operator sequences may include leading,trailing,and
- embedded blanks,all of which are removed when the program is scanned. In
- addition to the above characters,the blank character as a concatenation
- operator if it follows a symbol or string and is not adjacent to an operator or
- special character.
-
- Each operator has an associated priority that determines the order in which
- operations will be performed in an expression. Operators with higher priorities
- before those with lower priorities.
-
- 12
-
- TABLE 3.1 OPERATOR SEQUENCES
-
- SEQUENCE PRIORITY OPERATOR DEFINITION
-
- 8 Logical NOT
- + 8 Prefix Conversion
- - 8 Prefix Negation
- ** 7 Exponentiation
- * 6 Multiplication
- / 6 Division
- % 6 Integer Division
- // 6 Remainder
- + 5 Addition
- - 5 Subtration
- || 4 Concatenation
- (blank) 4 Blank Concatenation
- == 3 Exact Equality
- ~== 3 Exact Inequality
- = 3 Equality
- ~= 3 Inequality
- > 3 Greater Than
- >=,~< 3 Greater Than or Equal To
- < 3 Less Than
- <=,~> 3 Less Than or Equal To
- & 2 Logical AND
- | 1 Logical Inclusive OR
- ^,&& 1 Logical Exclusive OR
-
- SPECIAL CHARACTER TOKENS
-
- The characters :():,are each treated as a separate special character token and
- have particular meanings within an ARexx program. Blanks adjacent to these
- special characters are removed,except for those preceding an open parenthesis
- or following a close parenthesis.
-
- COLON (:). A colon,if preceded by a symbol token,defines a label within the
- program. Lavels are locations in the program to which control may be
- transferred under various conditions.
-
- OPENING AND CLOSING PARENTHESES (()). Parentheses are used in expressions to
- group operators and operands into subexpressions,in order to override the
- normal operator primorities. An open parenthesis also serves to identify a
- function call within an expression;a symbol or string followed immediately by
- an open parenthesis defines a function name. Parentheses must always be
- balanced within a statement.
-
- SEMICOLON (;). The semicolon acts as a program statement terminator. Several
- statements may be placed on a single source line if separated by semicolons.
-
- 13
-
- COMMA (,). A comma token acs as the continuation character for statements that
- must be entered on several source lines. It is also used to separate the
- argument expressions in a function call.
-
- 3-3 CLAUSES
-
- Tokens are grouped together to form clauses,the smallest language unit that can
- be executed as a statement. Every clause in ARexx can be classified as either a
- null,label,assignment,instruction,or command clause. The classification process
- is very simple,since no more than two tokens are required to classify any
- clause. Assignment,instruction,and command clauses are jointly termed
- statements.
-
- CLAUSE CONTINUATION. The end of a source line normally acts as the implicit end
- of a clause. A clause can be continued on the next source line by ending the
- line with a comma (,). The commas is then removed,and the next line is
- considered as a continuation of the clause. There is no limit to the number of
- continuations that may occur. String and comment tokens are automatically
- continued if a line end before the closing delimiter has been found,and the
- "newline" character is not considered to be part of the token.
-
- MULTIPLE CLAUSES. Several clauses can be placed on a single line by separating
- them with semicolons(;).
-
- NULL CLAUSES
-
- Lines consisting only of blanks or comments are called null clauses. They have
- no function in the execution of a program,except to aid its readability and to
- increment the source line count. Null clauses may appear anywhere in a program.
- Example:
-
- /* perform annuity calculations */
-
- LABEL CLAUSES
-
- A symbol followed immediately by a colon defines a label clause. A label acts
- as a placemarker in the program,but no action occurs with the "execution" of a
- label. The colon is considered as an implicit clause terminator,so each label
- stands as a separate clause. Label clauses may appear anywhere in a program.
- Examples:
-
- start: /* begin execution */
- syntax: /* error processing */
-
- ASSIGNMENT CLAUSES
-
- Assignments are identified by a variable symbol followed by an "=" operator. In
- this context the operator's normal definition(an equality comparison)is
- overridden,and it becomes an assignment operator. The tokens to the right of
- the "=" are evaluated as an expression,and the result is assigned to(becomes
- the value of)the variable symbol.
-
- 14
-
- Examples:
-
- when= 'Now is the time'
- answ= 3.14 * fact(5)
-
- INSTRUCTION CLAUSES
-
- Instructions begin with certain keyword symbols,each of which denotes a
- particular action to be performed. Instruction keywords are recognized as such
- only at the beginning of a clause,and may otherwise be used freely as symbols
- (although such use may become confusing at times.) The ARexx instructions are
- described in detail in Chapter 4.
- Examples:
-
- drop a b c /* reset variables */
- say 'please' /* a polite program */
- if j > 5 then leave; /* several instructions */
-
- COMMAND CLAUSES
-
- Commands are any ARexx expression that can't be classified as one of the
- preceding types of clauses. The expression is evaluated and the result is
- issued as a command to an external host,which might be the native operating
- system or an application program. Commands are discussed in Chapter 5,and the
- details of the host command interface are given in Chapter 10.
- Examples:
-
- 'delete' 'myfile' /* a DOS command */
- 'jump' current+10 /* an editor command? */
-
- CLAUSE CLASSIFICATION
-
- The process by which program lines are divided into clauses and then classified
- is important in understanding the operation of an ARexx program. The language
- interpreter splits the program source into groups of clauses as the program is
- read,using the end of each line as a clause separator and applying the
- continuation rule as required. These groups of one or more clauses are then
- tokenized,and each clause is classified into one of the above types. Note that
- seemingly small syntactic differences may completely change the semantic
- content of a statement. For example,
-
- SAY 'Hello, Bill'
-
- is an instruction clause and will display "Hello, Bill" on the console,but
-
- ""SAY 'Hello, Bill'
-
- is a command clause,and will issue "SAY Hello, Bill" as a command to an
- external program. The presence of the leading null string changes the
- classification from an instruction clause to a command clause.
-
- 15
-
- 3-4 EXPRESSIONS
-
- Expression evaluation is an important part of ARexx programs,since most
- statements include at least one expression. Expressions are composed of
- strings,symbols,operators,and parentheses. Strings are used as literals in an
- expression;their value in an operation is just the string itself. Fixed symbols
- are also literals(remember that symbols are always translated to uppercase,)
- but variable symbols may have an assigned value. Operator tokens represent the
- predefined operations of ARexx;each operator has an associated priority that
- determines the order in which operations will be performed. Parentheses may be
- used to alter the normal order of evaluation in the expression,or to identify
- function calls. A symbol or string followed immediately by an open parenthesis
- defines the function name,and the tokens between the opening and(final)closing
- parenthesis form the argument list for the function.
-
- For example,the expression "J 'fractorial is' fact(J)" is composed of a symbol
- J,a blank operator,the string 'factorial is',another blank,the symbol fact,an
- open parenthesis,the symbol J again,and a closing parenthesis. FACT is a
- function name and (J) is its argument list,in this case the single expression
- J.
-
- SYMBOL RESOLUTION
-
- Before the evaluation of an expression can proceed,the interpreter must obtain
- a value for each symbol in the expression. For fixed symbols the value is just
- the symbol name itself,but variable symbols must be looked up in the current
- symbol table. In the example above,the expression after symbol resolution would
- be "3 'factorial is' FACT(3)," assuming that the symbol J had the value 3.
-
- Suppose that the example above had been "FACT(J) 'is' J 'factorial'." Would the
- second occurrence of symbol J still resolve to 3 in this case? In general,
- function calls may have "side effects" that include altering the values of
- variables,so the value of J might have been changed by the call to FACT. In
- order to avoid ambiguities in the values assigned to symbols during the
- resolution process, ARexx guarantees a strict left-to-right resolution order.
- Symbol resolution proceeds irrespective of operator priority or parenthetical
- grouping;if a function call is found,the resolution is suspended while the
- function is evaluated. Note that it is possible for the same symbol to have
- more than one value in an expression.
-
- ORDER OF EVALUATION
-
- After all symbol values have been resolved,the expression is evaluated based on
- operator priority and subexpression grouping. Operators of higher priority are
- evaluated first. ARexx does not guarantee an order of evaluation among
- operators of equal priority,and does not employ a "fast path" evaluation of
- boolean operators. For example,in the expression
-
- (1 = 2) & (FACT(3) = 6)
-
- the call to the FACT function will be made,although it is clear that the final
- result will be 0,since the first term of the AND operation is 0.
-
- 16
-
- 3-5 NUMBERS AND NUMERIC PRECISION
-
- An important class of operands are those representing numbers. Numbers consist
- of the characters 0-9,.+-,and blanks;an e or E may follow a number to indicate
- exponential notation,in which case it must be followed by a (signed) integer).
-
- Both string tokens and symbol tokens may be used to specify numbers. Since the
- language is typeless,variables do not have to be declared as "numeric" before
- being used in an arithmetic operation. Instead,each value string is examined
- when it is used to verify that it represents a number. The following examples
- are all valid numbers:
-
- 33
- " 12.3 "
- 0.321e12
- ' + 15.'
-
- Note that leading and trailing blanks are permitted,and that blanks may be
- embedded between a "+" or "-" sign and the number body(but not within the
- body.)
-
- BOOLEAN VALUES
-
- The numbers 0 and 1 are used to represent the boolean values False and True,
- respectively. The use of a value other than 0 or 1 when a boolean operand is
- expected will generate an error. Any number equivalent to 0 or 1,for example
- "0.000" or "0.1E1," is also acceptable as a boolean value.
-
- NUMERIC PRECISION
-
- ARexx allows the basic precision used for arithmetic calculations to be
- modified while a program is executing. The number of significant figures used
- in arithmetic operations is determined by the Numeric Digits environment
- variable, and may be modified using the NUMERIC instruction.
-
- The number of decimal places used for a result depends on the operation
- performed and the number of decimal places in the operands. Unlike many
- languages,ARexx preserves trailing zeroes to indicate the precision of the
- result. If the total number of digits required to express a value exceeds the
- current Numeric Digits setting,the number is formatted in exponential notation.
- Two such formats are provided:
-
- In SCIENTIFIC notation,the exponent is adjusted so that a single digit is
- placed to the left of the decimal point.
-
- in ENGINEERING notation,the number is scaled so that the exponent is a multiple
- of 3 and the digits to the left of the decimal point range from 1 to 999.
-
- The numeric precision and format can be set using the NUMERIC instruction.
-
- 17
-
- 3-6 OPERATORS
-
- Operators can be grouped into four categories:
-
- Arithmetic operators require one or two numeric operands,and produce a numeric
- result.
- Concatenation operators join two strings into a single string.
- Comparison operators require two operands,and produce a boolean(0 or 1) result.
- Logical Operators require one or two boolean operands,and produce a boolean
- result.
-
- ARITHMETIC OPERATORS
-
- The aritmetic operators are listed in Table 3.2 below. Note the inclusion of
- the integer division(%)and remainder(//)operators,along with the usual
- arithmetic operations. The result of an arithmetic operation is always foratted
- based on the current Numeric Digits setting,and will never have leading or
- trailing blanks.
-
- TABLE 3.2 ARITHMETIC OPERATORS
- SEQUENCE PRIORITY OPERATION
- + 8 Prefix Conversion
- - 8 Prefix Negation
- ** 7 Exponentiation
- * 6 Multiplication
- / 6 Division
- % 6 Integer Division
- // 6 Remainder
- + 5 Addition
- - 5 Subtraction
-
- PREFIX CONVERSION(+). This unary operator converts the operand to and internal
- numeric form and formats the result based on the current Numeric Digits
- settings. This causes any leading and trailing blanks to be removed,and may
- result in a loss of precision.
- Examples:
-
- ' 3.12 ' ==> 3.12
- 1.5001 ==> 1.500 /* If digits = 3 */
-
- PREFIX NEGATION(-). This unary operator negates the operand. The result is
- formatted based on the current Numeric Digits setting.
-
- 18
-
- Examples:
-
- -' 3.12 ' ==> -3.12
- 1.5E2 ==>-150
-
- EXPONENTIATION(**). The left operand is raised to the power specified by the
- right operand,which must be an integer. The number of decimal places for the
- result is the product of the exponent and the number of decimal places in the
- base.
- Examples:
-
- 2**3 ==>8
- 3**-1 ==>.333333333
- 0.5**3 ==>0.125
-
- MULTIPLICATION(*). The product of two numbers is computed. The number of
- decimal places for the result is the sum of the decimal places of the operands.
- Examples:
-
- 12 * 3 ==>36
- 1.5 * 1.50 ==>2.250
-
- DIVISION(/). The quotient of two numbers is computed. The number of decimal
- places for the result depends on the current setting of the numeric DIGITS
- variable;the nuber is formatted to the maximum precision required.
- Examples:
-
- 6 / 3 ==>2
- 8 / 3 ==>2.66666667
-
- INTEGER DIVISION(%). The quotient of two numbers is computed,and the integer
- part of the quotient is used as the result.
- Examples:
-
- 5 % 3 ==>1
- -8 % 3 ==>-2
-
- REMAINDER(//). The result is the remainder after the two operands are divided.
- The remainder for "a//b" is calculated as "a-(a%b)*b." If both operands are
- positive integers,this operation yields the usual "modulo" result.
-
- 19
-
- Examples:
-
- 5 // 3 ==>2
- -5 // 3 ==>-2
- 5.1 // 0.2 ==>0.1
-
- ADDITION(+). The sum of two numbers is computed. The number of decimal places
- for the result is the larger of the decimal places of the operands.
- Examples:
-
- 12 + 3 ==>15
- 3.1 + 4.05 ==>7.15
-
- SUBTRATION(-). The difference of two numbers is computed. As in the case of
- addition,the number of decimals places for the result is the larger of the
- decimal places of the operands.
- Examples:
-
- 12 - 3 ==>9
- 5.55 - 1.55 ==>4.00
-
- CONCATENATION OPERATORS
-
- ARexx defines two concatenation operators,both of which require two operands.
- The first,identified by the operator sequence "||",joins two strings into a
- single string with no intervening blank. The second concatenation operation is
- identified by the blank operator,and joins the two operand strings with one
- intervening blank.
-
- An implicit concatenation operator is recognized when a symbol and a string are
- directly abutted in an expression. Concatenation by abuttal uses the "||"
- operator,and behaves exactly as though the operator had been provided
- explicitly.
- Examples:
-
- 'why me,' || 'Mom?' ==>why me,Mom?
- 'good' 'times' ==>good times
- one'two'three ==>ONEtwoTHREE
-
- COMPARISON OPERATORS
-
- Comparisons are performed in one of three modes,and always result in a boolean
- value(0 or 1.)
-
- Exact comparisons proceed character-by-character,including any leading blanks
- that may be present.
- String comparisons ignore leading blanks,and pad the shorter string with blanks
- if necessary.
-
- 20
-
- Numeric comparisons first convert the operands to an internal numeric form
- using the current Numeric Digits setting,and then perform a standard arithmetic
- comparison.
-
- Except for the exact equality and exact inequality operators,all comparison
- operators dynamically determine whether a string of numeric comparison is to be
- performed. A numeric comparison is performed if both operands are valid numbers
- otherwise,the operands are compared as strings.
-
- TABLE 3.3 COMPARISON OPERATORS
-
- SEQUENCE PRIORITY OPERATION MODE
-
- == 3 Exact Equality Exact
- ~== 3 Exact Inequality Exact
- = 3 Equality String/Numeric
- ~= 3 Inequality String/Numeric
- > 3 Greater Than String/Numeric
- >=,~< 3 Greater Than or Equal String/Numeric
- < 3 Less Than String/Numeric
- <=,~> 3 Less Than or Equal String/Numeric
-
- LOGICAL (BOOLEAN) OPERATORS
-
- ARexx defines the four logical operations NOT,AND,OR,and Exclusive OR,all of
- which require boolean operands and produce a boolean result. Boolean operands
- must have values of either 0(False)or 1(True.) An attempt to perform a logical
- operation on a non-boolean operand will generate an error.
-
- TABLE 3.4 LOGICAL OPERATORS
-
- SEQUENCE PRIORITY OPERATION
-
- ~ 8 NOT(Inversion)
- & 2 AND
- | 1 OR
- ^,&& 1 Exclusive OR
-
- 3-7 STEMS AND COMPOUND SYMBOLS
-
- Stems and compound symbols have special properties that allow for some
- interesting and unusual programming. A compound symbol can be regarded as
- having the structure stem.n1.n2.n3...nk where the leading name is a stem symbol
- and each node n1...nk is a fixed or simple symbol. Whenever a compound symbol
- appears in a program,its name is expanded by replacing each node with its
- current value as a (simple) symbol. The value string may consist of any
- characters,including embedded blanks,and is not converted to uppercase. The
- result of the expansion is a new name that is used in place of the compound
- symbol. For example if j has the value of 3 and k has the value 7,then the
- compound symbol a.j.k will expand to A.3.7.
-
- Stem symbols provide a way to initialize a whole class of compound symbols.
- When an assignment is made to a stem symbol,it assigns that value to all
- possible compound symbols derived from the stem. Thus,the value of a compound
- symbol depends on the prior assignments made to itself or its associated stem.
-
- 21
-
- Compound symbols can be regarded as a form of "associative" or "content-
- addressable" memory. For example,suppose that you needed to store and retrieve
- a set of names and telephone numbers. The conventional approach would be to set
- up two arrays NAME and NUMBER,each indexed by an integer running from one to
- the number of entries. A number would be "looked up" by scanning the name array
- until the given name was found,say in NAME.12,and then retrieving NUMBER.12.
- With compound symbols,the symbol NAME could hold the name to be looked-up,and
- NUMBER.NAME would then expand to NUMBER.Bill(for example),which be the
- corresponding number.
-
- Of course,compound symbols can also be used as conventional indexed arrays,with
- the added convenience that only a single assignment(to the stem)is required to
- initialize the entire array.
-
- 3-8 THE EXECUTION ENVIRONMENT
-
- The ARexx interpreter provides a uniform environment by running each program as
- a separate task(actually,as a DOS process)in the Amiga's multitasking operating
- system. This allows for a flexible interface between an external host program
- and the interpreter,as the host can either proceed concurrently with its
- operations or can simply wait for the interpreted program to finish.
-
- THE EXTERNAL ENVIRONMENT
-
- The external environment of a program includes its task(process)structure,
- input and output streams,and current directory. When each ARexx task is
- created,it inherits the input and output streams and current directory from its
- client,the external program that invoked the ARexx program. The current
- directory is used as the starting point in a search for a program or data file.
-
- EXTERNAL PROGRAMS. The external environment usually includes one or more
- external programs with which the ARexx program may communicate. Any program
- that supports a suitable interface can receive commands from ARexx programs.
- The command interface is discussed in Chapter 5.
-
- THE INTERNAL ENVIRONMENT
-
- The internal environment of an ARexx program consists of a static global
- structure and one or more storage environments. The global data values are
- fixed at a time the program is invoked,and include the argument strings,program
- source code,and static data strings. The storage environment includes the
- symbol table used for variable values,the numeric options,trace options,and
- host address strings. While the global environment is unique,there may be many
- storage environments during the course of the program execution. Each time an
- internal function is called a new storage environment is activated and
- initialized. The initial values for most fields are inherited from the previous
- environment,but values may be changed afterwards without affecting the caller's
- environment. The new environment persists until control returns from the
- function.
-
- 22
-
- ARGUMENT STRINGS. A program may receive one or more argument strings when it is
- first invoked. These arguments persist for the duration of the program and are
- never altered. The number of arguments a program receives depends in part on
- the mode of invocation. ARexx programs invoked as commands normally have only
- one argument string,although the "command tokenization" option may provide more
- than one. A program invoked as a function can have any number of arguments if
- called as an internal function,but external functions are limited to a maximum
- of 15 arguments.
-
- The argument strings can be retrieved using either the ARG instruction or the
- ARG() Built-In function. ARG() can also return the total number of arguments,or
- the status(as "exists" or "omitted")of a particular argument.
-
- THE SYMBOL TABLE. Every storage environment includes a symbol table to store
- the value strings that have been assigned to variables. This symbol table is
- organized as a two-level stores entries for simple and stem symbols,and the
- secondary level is used for compound symbols. All of the compound symbols
- associated with a particular stem are stored in one tree,with the root of the
- tree held by the entry for the stem.
-
- Symbols are not entered into the table until an assignment is made to the
- symbol. Once created,entries at the primary level are never removed,even if the
- symbol subsequently becomes uninitialized. Secondary trees are released
- whenever an assignment is made to the stem associated with the tree.
-
- For the most part ARexx programmers need not be concerned with the details of
- storage environments except to understand what values are saved when a function
- is called. Applications developers who need to manipulate environment values
- should refer to the structure definitions in the INCLUDE files provided on the
- ARexx distribution disk.
-
- INPUT AND OUTPUT
-
- Most computer programs require some means of communicating with the outside
- world,either to accept input data or to pass along results. The REXX language
- includes only a minimal specification of input and output (I/O)operations,
- leaving the choice of additional functionality to the language implementor.
- This is in keeping with the design of many computer languages. For instance,the
- "C" language has no statements dedicated to I/O,but instead relies on a
- standardized set of I/O functions.
-
- ARexx extends the I/O facilities fo REXX by providing Built-In functions to
- manipulate external files. Files are referenced by a logical name associated
- with the file when it is first opened. The initial input and output streams are
- given the names STDIN and STDOUT.
-
- ARexx maintains a list of all of the files opened by a program and
- automatically closes them when the program finishes. There is no limit to the
- number of files that may be open simultaneously.
-
- 23
-
- RESOURCE TRACKING
-
- ARexx provides complete tracking for all of the dynamically-allocated resources
- that it uses to execute a program. These resources include memory space,DOS
- files and related structures,and the message port structures supported by
- ARexx. The tracking system was designed to allow a program to "bail out" at any
- point(perhaps due to an execution error)without leaving any hanging resources.
-
- It is possible to go outside of the interpreter's resource tracking net by
- making calls directly to the Amiga's operating system from within an ARexx
- program. In these cases it is the programer's responsibility to track and
- return all of the allocated resources. ARexx provides a special interrupt
- facility so that a program can retain control after an execution error,perform
- the required cleanup,and then make an orderly exit. Chapter 7 has information
- on the ARexx interrupt system.
-
- 24
-
- CHAPTER 4 INSTRUCTIONS
-
- Instruction clauses are identified by an initial keyword symbol that is not
- followed by a colon(:)or an equals(=)operator. Each instruction signifies a
- specific action,and may be followed by one or more subkeywords,expressions,or
- other instruction-specific information. Instruction keywords and subkeywords
- are recognized only in this specific context,and are therefore not "reserved
- words" in the usual sense of the term. Keywords may be used freely as variables
- or function names,although such usage may become confusing at times.
-
- In the descriptions that follow,keywords are shown in uppercase and optional
- parts of the instruction are enclosed in brackets. Alternative selections are
- separated by a vertical bar(|),and required alternative are enclosed in braces
- ({}).
-
- 4-1 ADDRESS
-
- Usage: ADDRESS [Symbol|string|VALUE] [expression]]
- This instruction specifies a host address for commands issued by the
- interpreter. A host address is the name associated with an external program to
- which commands can be sent;external hosts are described in Chapter 5. ARexx
- maintains two host addresses:a "current" and a "previous"address is lost,and
- the "current" and a "previous" value. Whenever a new host address is supplied,
- the "previous" address is lost,and the "current" address becomes the "previous"
- one. These host addresses are part of a program's storage environment and are
- preserved across internal function calls. The current address can be retrieved
- with the Built-In function ADDRESS(). There are four distinct forms for the
- ADDRESS instruction:
-
- ADDRESS {string | symbol} expression. The expression is evaluated and the
- result is issued to the host specified by the string or symbol,which is taken
- as a literal. No changes are made to the current or previous address strings.
- This provides a convenient way to issue a single command to an external host
- without disturbing the current host addresses. The return code from the command
- is treated as it would be from a command clause.
-
- ADDRESS {string | symbol}. The string or symbol,taken as a literal,specifies
- the new host address. The current host address becomes the previous address.
-
- ADDRESS [VALUE] expression. The result of the expression specifies the new host
- address,and the current address becomes the previous address. The VALUE keyword
- may be omitted if the first token of the expression is not a symbol or string.
-
- ADDRESS. This form interchanges the current and previous hosts. Repeated
- execution will therefore "toggle" between the two host addresses.
-
- Examples:
-
- address edit /* set an new host address */
- address edit 'top' /* move to the top */
- address VALUE edit n /* compute a new host address */
- address /* swap current and previous */
-
- 25
-
- Usage: ARG [template] [,template...]
- ARG is shorthand form for the PARSE UPPER ARG instruction. It retrieves one or
- more of the argument strings available to the program,and assigns values to the
- variables in the template. The number of argument strings available depends on
- the whether the program was invoked as a command or a function. Command
- invocations normally have only one argument string,but functions may have up to
- 15. The argument strings are not altered by the ARG instruction.
-
- The structure and processing of templates is described briefly with the PARSE
- instruction,and in greater depth in Chapter 8.
- Example:
-
- arg first,second /* fetch arguments */
-
- 4-3 BREAK
-
- Usuage: BREAK
- The BREAK instruction is used to exit from the range of a DO instruction or
- from within an INTERPRETed string,and is valid only in these contexts. If used
- within a DO statement,BREAK exits from the innermost DO statement containing
- the BREAK. This contrasts with the otherwise similar LEAVE instruction,which
- exits only from an interative DO.
- Example:
-
- do /* begin block */
- if i>3 then break /* all done? */
- a = a + 1
- y.a = name
- end /* end block */
-
- 4-4 CALL
-
- Usage: CALL {symbol | string} [expression] [,expression,...]
- The CALL instruction is used to invoke an internal or external function. The
- function name is specified by the symbol or string token,which is taken as a
- literal. Any expressions that follow are evaluated and become the arguments to
- the called function. The value returned by the function is assigned to the
- special variable RESULT. It is not an error if a result string is not returned;
- in this case the variable RESULT is DROPed(becomes uninitialized.)
-
- The linkage to the function is established dynamically at the time of the call.
- ARexx follows a specific search order in attempting to locate the called
- function;this process is described in Chapter 6.
- Example:
-
- call center name,length+4,'+'
-
- 26
-
- Usage: DO [var=exp] [To exp] [BY exp]] [FOR exp] [FOREVER] [WHILE exp | UNTIL
- exp]
- The DO instruction begins a group of instructions to be executed as a block.
- The range of the DO instruction includes all statements up to and including an
- eventual END instruction. There are two basic forms of the instruction:
-
- The DO keyword by itself defines a block of instructions to be executed once.
-
- If any iteration specifiers follow the DO keyword,the block of instructions is
- executed repeatedly until a termination condition occurs.
-
- An interative DO instruction is sometimes called a "loop",since the interpreter
- "loops back" to perform the instruction repeatedly. The various parts of the DO
- instruction are described below.
-
- Initializer expression. An initializer expression of the form "variable=
- expression" defines the index variable of the loop. The expression is evaluated
- when the DO range is first activated,and the result is assigned to the index
- variable. On subsequent iterations an expression of the form "variable =
- variable + increment" is evaluated,where the increment is the result of the BY
- expression. If specified, the initializer expression must precede any of the
- other subkeywords.
-
- BY expression. The expression following a BY symbol defines the increment to be
- added to the index variable in each subsequent iteration. The expression must
- yield a numeric result,which may be positive or negative and need not be an
- integer. The default increment is 1.
-
- TO expression. The result of the TO expression specifies the upper(or lower)
- limit for the index variable. At each iteration the index variable is compared
- to the TO result. If the increment(BY result)is positive and the variable is
- greater than the limit,the DO instruction terminates and control passes to the
- statement following the END instruction. Similarly,the loop terminates if the
- increment is negative and the index variable is less than the limit.
-
- FOR expression. The FOR expression must yield a positive whole number when
- evaluated,and specifies the maximum number of iterations to be performed. The
- loop terminates when this limit is reached irrespective of the value of the
- index variable.
-
- FOREVER. The FOREVER keyword can be used if an iterative DO instruction is
- required but no index variable is necessary. Presumably the loop will be
- terminated by a LEAVE or BREAK instruction contained within the loop body.
-
- WHILE expression. The WHILE expression is evaluated at the beginning of each
- iteration and must result in a boolean value. The iteration proceeds if the
- result is 1;otherwise,the loop terminates.
-
- 27
-
- UNTIL expression. The UNTIL expression is evaluated at the end of each
- iteration and must result in a boolean value. The instruction continues with
- the next iteration if the result is 0,and terminates otherwise.
-
- The initializer,BY,TO,and FOR expressions are evaluated only when the
- instruction is first activated,so the increment and limits are fixed throughout
- the execution. Note that a limit need not be supplied;for example,the
- instruction "DO i=1" will simply count away forever. Note also that only one of
- the WHILE or UNTIL keywords can be specified.
- Example:
-
- do i=1 to limit for 5 while time <50
- y.1=i*time
- end
-
- 4-6 DROP
-
- Usage: DROP variable [variable...]
- The specified variable symbols are reset to their uninitialized state,in which
- the value of the variable is the variable name itself. It is not an error to
- DROP a variable that is already uninitialized. DROPping a stem symbol is
- equivalent to DROPping the values of all possible compound symbols derived from
- that stem.
- Example:
-
- a=123 /* assign a value */
- drop a b /* drop some */
- say a b /* ==>A B */
-
- 4-7 ECHO
-
- Usage: ECHO [expression]
- The ECHO instruction is a synonym for the SAY instruction. It displays the
- expression result on the console.
- Example:
-
- echo "You don't SAY!"
-
- 4-8 ELSE
-
- Usage: ELSE [;] [conditional statement]
- The ELSE instruction provides the alternative conditional branch for an IF
- statement. It is valid only within the range of an IF instruction,and must
- follow the conditional statement of the THEN branch. If the THEN branch wasn't
- executed,the statement following the ELSE clause is performed.
-
- Binding. ELSE clauses always bind to the nearest(preceding)IF statement. It may
- be necessary to provide "dummy" ELSE clauses for the inner IF ranges of a
- compound IF statement in order to allow alternative branches for the outer IF
- statements. In this case it is not sufficient to follow the else with a
- semicolon or a null clause. Instead,the NOP(no-operation)instruction can be
- used for this purpose.
-
- 28
-
- Example:
-
- if 1 > 2 then say 'really?'
- else say 'I thought so'
-
- 4-9 END
-
- Usage: END [variable]
- The END instruction terminates the range of a DO or SELECT instruction. If the
- optional variable symbol is supplied,it is compared to the index variable of
- the DO statement(which must therefore be iterative). An error is generated if
- the symbols do not match,so this provides a simple mechanism for matching the
- DO and END statements.
- Example:
-
- do i=1 to 5 /* index variable is I */
- say i
- end i /* end "I" loop */
-
- 4-10 EXIT
-
- Usage: EXIT [expression]
- The EXIT instruction terminates the execution of a program,and is valid
- anywhere within a program. The evaluated expression is passed back to the
- caller as the function or command result.
-
- Results Processing. The processing of the EXIT result depends on whether a
- result string was requested by the calling program,and whether the current
- invocation resulted from a command or function call. If a result string was
- requested,the expression result is copied to a block of allocated memory and a
- pointer to the block is returned as the secondary result of the call.
-
- If the caller did not request a result string,and the program was invoked as a
- command,then an attempt is made to convert the expression result to an
- integer. This value is then returned as the primary result,with 0 as the
- secondary result. This allows the EXIT expression to be interpreted as a
- "return code" by the caller. Refer to Chapter 10 for further information on
- the data structures used to return the result string.
- Examples:
-
- exit /* no result needed */
- exit 12 /* an error return? */
-
- 4-11 IF
-
- Usage: IF expression [THEN] [;] [conditional statement]
- The IF instruction is used in conjunction with THEN and ELSE instruction to
- conditionally execute a statement. The result of the expression must be a
- boolean value. If the result is 1 (True),the statement following the THEN
- symbol is executed;otherwise,control passes to the next statement(which might
- be an ELSE clause.) The THEN keyword need not immediately follow the IF
- expression,but may appear as a separate clause. The instruction
-
- 29
-
- is actually analyzed as "IF expression; THEN; statement;." In essence,the IF
- statement begins a syntactic range and establishes the test condition that
- determines whether subsequent THEN or ELSE clauses will be performed.
-
- Any valid statement may follow the THEN symbol;in particular,a "DO; ... END;"
- group allows a series of statements to be performed conditionally.
- Examples:
-
- if result < 0 then exit /* all done? */
-
- 4-12 INTERPRET
-
- Usage: INTERPRET expression
- The expression is evaluated and the result is executed as one or more program
- statements. The statements are considered as a group,as though surrounded by a
- "DO; ...;END" combination. Any statements can be included in the INTERPRETed
- source,including DO or SELECT instruction.
-
- An INTERPRET instruction activates a control range when it is executed,which
- serves as a "fence" for LEAVE and ITERATE instructions. These instructions can
- therefore be used only with DO-loops defined within the INTERPRET. The BREAK
- instuction can be used to terminate the processing of INTERPRETed statements.
- While it is not an error to include label clauses within the interpreted
- string,only those labels defined in the original source code are searched
- during a transfer of control.
-
- The INTERPRET instruction can be used to solve programming problems in
- interesting and novel ways. Programs can be constructed dynamically and then
- executed using this instruction,or program fragments may be passed as arguments
- to functions,which then INTERPRET them.
- Example:
-
- inst = 'say' /* an instruction */
- interpret inst hello /* ..."say HELLO" */
-
- 4-13 ITERATE
-
- Usage: ITERATE [variable]
- The ITERATE instruction terminates the current iteration of a DO instruction
- and begins the next iteration. Effectively,control passes to the END statement
- and then(depending on the outcome of the UNTIL expression)back to the DO
- statement. The instruction normally acts on the innermost iterative DO range
- containing the instruction. An error results if the LEAVE instruction is not
- contained within an iterative DO instruction.
-
- The optional variable symbol specifies which DO range is to be exited,in the
- event that several nested ranges exist. The variable is taken as a literal and
- must match the index variable of a currently active DO instruction. An error
- results if no such matching DO instruction is found.
-
- 30
-
- Example:
-
- do i=1 to 3
- if i=j then iterate i
- end
-
- 4-14 LEAVE
-
- Usage:LEAVE [variable]
- LEAVE forces an immediate exit from the iterative DO range containing the
- instruction. An error results if the LEAVE instruction is not contained within
- an iterative DO instruction.
-
- The optional variable symbol specifies which DO range is to be exited,in the
- event that several nested ranges exist. The variable is taken as a literal and
- must match the index variable of a currently active DO instruction. An error
- results if no such matching DO instruction is found.
- Example:
-
- do i=1 to limit
- if i > 5 then leave /* maximum iterations */
- end
-
- 4-15 NOP
-
- Usage: NOP
- The NOP or "no-operation" instruction does just that:nothing. It is provided to
- control the binding of ELSE clauses in compound IF statements.
- Example:
-
- if i=j then /* first (outer) IF */
- if j=k then a=o /* inner IF */
- else nop /* binds to inner IF */
- else a=a+1 /* binds to outer IF */
-
- 4-16 NUMERIC
-
- Usage: NUMERIC {DIGITS | FUZZ} expression
- or: NUMERIC FORM {SCIENTIFIC | ENGINEERING}
- This instruction sets options relating to the numeric precision and format. The
- valid forms of the NUMERIC instruction are:
-
- NUMERIC DIGITS expression. Specifies the number of digits of precision for
- arithmetic calculations. The expression must evaluate to a positive whole
- number.
-
- NUMERIC FUZZ expression. Specifies the number of digits to be ignored in
- numeric comparison operations. This must be a positive whole number that is
- less than the current DIGITS setting.
-
- NUMERIC FORM SCIENTIFIC. Specifies that numbers that require exponential
- notation be expressed in SCIENTIFIC notation. The exponent is adjusted so that
- the mantissa (for non-zero) numbers) is between 1 and 10. This is the default
- format.
-
- 31
-
- NUMERIC FORM ENGINEERING. Selects ENGINEERING format for numbers that require
- exponential notation. ENGINEERING format normalizes a number so that its
- exponent is a multiple of three and the mantissa(if not 0)is between 1 and
- 1000.
-
- The numberic options are preserved when an internal function is called.
- Examples:
-
- numeric digits 12 /* precision */
- numeric form scientific /* format */
-
- 4-17 OPTIONS
-
- Usage: OPTIONS [FAILAT expression]
- or: OPTIONS [PROMPT expression]
- or: OPTIONS [RESULTS]
- The OPTIONS instruction is used to set various internal defaults. The FAILAT
- expression sets the limit at or above which command return codes will be
- signalled as errors,and must evaluate to an integer value. The PROMPT
- expression provides a string to be used as the prompt with the PULL (or PARSE
- PULL)instruction. The RESULTS keyword indicates that the interpreter should
- request a result string when it issues commands to an external host.
-
- The internal options controlled by this instruction are preserved across
- function calls,so an OPTIONS instruction can be issued within an internal
- function without affecting the callers environment. If no keyword is specified
- with the OPTIONS instuction,all controlled options revert to their default
- settings.
- Example:
-
- options failat 10
- options prompt "Yes Boss?"
- options results
-
- 4-18 OTHERWISE
-
- Usage: OTHERWISE [;] [conditional statement]
- This instruction is valid only within the range of a SELECT instruction,and
- must follow the "WHEN ... THEN" statements. If none of the preceding WHEN
- clauses have succeeded,the statement following the OTHERWISE instruction is
- executed. An OTHERWISE is not mandatory within a SELECT range. However,an error
- will result if the OTHERWISE clause is omitted and none of the WHEN
- instructions succeed.
- Example:
-
- select
- when i=1 then say 'one'
- when i=2 then say 'two'
- otherwise say 'other'
- end
-
- 32
-
- 4-19 PARSE
-
- Usage: PARSE [UPPER] inputsorce [template] [,template...]
- The PARSE instruction provides a mechanism to extract one or more substrings
- from a string and assign them to variables. The input string can come from a
- variety of sources,including argument strings,an expression,or from the
- console. The template provides both the variables to be given values and the
- way to determine the value strings. The template may be omitted if the
- instruction is intended only to create the input string. The different options
- of the instruction are described below.
-
- INPUT SOURCES
-
- The sources for the input strings are specified by the keyword symbols listed
- below. When multiple templates are supplied,each template receives a new input
- string, although for some source options the new string will be identical to
- the previous one. The input source string is copied before being parsed,so the
- original strings are never altered by the parsing process.
-
- UPPER. This optional keyword may be used with any of the input sources,and
- specifies that the input string is to be translated to uppercase before being
- parsed. It must be the first token following PARSE.
-
- ARG. This input option retrieves the argument strings supplied when the program
- was invoked. Command invocations normally have only a single argument string,
- but functions may have up to 15 argument strings. Multiple templates may be
- given to retrieve successive argument strings.
-
- EXTERNAL. The input strings is read from the console. If multiple templates are
- supplied,each template will read a new string. This source option is the same
- as PULL.
-
- NUMERIC. The current numeric options are placed in a string in the order
- DIGITS,FUZZ,and FORM,separated by a single space.
-
- PULL. Reads a string from the input console. If multiple templates are
- supplied,each template will read a new string.
-
- SOURCE. The "source" string for the program is retrieved. This string is
- formatted as "{COMMAND | FUNCTION} {0 | 1} called resolved ext host." The first
- token indicates whether the program was invoked as a command or as a function.
- The second token is a boolean flag indicating whether a result string was
- requested by the caller. The called token is the name used to invoke this
- program,while the resolved token is the final resolved name of the program. The
- ext token is the file extension to be used for searching(the default is
- "REXX"). Finally,the host token is the initial host address for commands.
-
- VALUE expression WITH. The input string is the result of the supplied
- expression. The WITH keyword is required to separate the expression from the
- template. The expression result may be parsed repeatedly by using multiple
- templates,but the expression is not reevaluated.
-
- VAR variable. The value of the specified variable is used as the input string.
- When multiple templates are provided,each template uses the current value of
- the variable.
-
- 33
-
- This value may change if the variable is included as an assignment target in
- any of the templates.
-
- VERSION. The current configuation of the ARexx interpreter is supplied in the
- form "ARexx version cpu mpu video freq". The version toekn is the release level
- of the interpreter,formatted as V1.0. The cpu token indicates the processor
- currently running the program,and will be one of the values 68000,68010,or
- 68020. The mpu token will be either NONE or 68881 depending on whether a math
- coprocessor is available on the system. The video token will indicate either
- NTSC or PAL,and the freq token gives the clock(line)frequency as either 60HZ or
- 50 HZ.
-
- TEMPLATES
-
- Parsing is controlled by a template,which may consist of symbols,strings,
- operators,and parentheses. During the parsing operation the input string is
- split into substrings that are assigned to the variable symbols in the
- template. The process continues until all of the variables in the template have
- been assigned a value;if the input string is "used up",any remaining variables
- are given null values.
-
- Templates are described in depth in Chapter 8,so only a simplified description
- is presented here. The goal of the parsing operation is to associate a
- "current" and "next" position with each variable symbol in the template. The
- substring between these positions is then assigned as the value to the
- variable. There are three basic methods used to determine the value strings.
-
- PARSING BY TOKENIZATION. When a variable in the template is followed
- immediately by another variable,the value string is determined by breaking the
- input string into words separated by blanks. Each word is assigned to a
- variable in the template.
-
- Values determined by tokenization will never have leading or trailing blanks.
- Normally the last variable in the template receives the untokenized remainder
- of the input string,since it is not followed by a symbol. A "placeholder"
- symbol,signified by a period(.),may be used to force tokenization. Placeholders
- behave like variables in the template except that they are never actually
- assigned a value.
- Example:
-
- /* Numeric string is: "9 0 SCIENTIFIC" */
- parse numberic digits fuzz form .
- say digits /* =>9 */
- say fuzz /* =>0 */
- say from /*=> SCEIENTIFIC */
-
- PARSING BY POSITION. If the fields in the input string have known positions,
- value strings can be specified by absolute or relative positions. Relative
- positions are indicated by a number preceded by a "+" or "-" operator. Each
- positional marker updates the scan position in the string. The value assigned
- to a variable is the string from the current position up to,but not including,
- the next position in the string.
-
- 34
-
- Example:
-
- /* assume argument is "1234567890" */
- parse arg 1 a 3 b +2 1 c
- say a b c /* ==> 12 34 1234567890 */
-
- PARSING WITH PATTERNS. Fields in the input string separated by specific
- characters or strings can be parsed using a pattern,which is matched against
- the input string. A pattern is specified in the template as a string token,or
- alternatively as a symbol enclosed in parentheses. The position in the parse
- string matched by the pattern determines the value strings. The pattern is
- removed from the input string when a match is found;this is the only parsing
- operation that modifies the input string.
- Example:
-
- check = 'one,two,three'
- parse var check a ',' b ',' c
- say a b c /* ==> one two three */
-
- 4-20 PROCEDURE
-
- Usage:PROCEDURE [EXPOSE variable [variable...]]
- The PROCEDURE instruction is used within an internal function to create a new
- symbol table. This protects the symbols defined in the caller's environment
- from being altered by the execution of the function. PROCEDURE is usually the
- first statement within the function,although it is valid anywhere withing the
- function body. It is an error to execute two PROCEDURE statements within the
- function.
-
- EXPOSING VARIABLES. The EXPOSE subkeyword provides a selective mechanism for
- accessing the caller's symbol table,and for passing global variables to a
- function. The variables following the EXPOSE keyword are taken to refer to
- symbols in the caller's table. Any subsequent changes made to these variables
- will be reflected in the caller's environment.
-
- The variables in the EXPOSE list may include stems or compound symbols,in which
- case the ordering of the variables becomes significant. The EXPOSE list is
- processed from left to right,and compound symbols are expanded based on the
- values in effect in the new generation. For example,suppose that the value of
- the symbol J in the previous gneration is 123,and that J is unitialized in the
- new generation. Then PROCEDURE EXPOSE J A.J will expose J and A.123,whereas
- PROCEDURE EXPOSE A.J J will expose A. J. and J. Exposing a stem has the effect
- of exposing all possible compound symbols derived from that stem.
- Example:
-
- fact: procedure /* a recursive function */
- arg i
- if i <=1
- then return 1
- else return i*fact(i-1)
-
- 35
-
- Usage:PULL [template] [,template...]
- This is a shorthand form of the PARSE UPPER PULL instruction. It reads a string
- from the input console,translates it to uppercase,and parses it using the
- template. Multiple strings can be ready by supplying additional templates. The
- instruction will read from the console even if no template is given.
-
- Templates are described briefly with the PARSE instruction and in greater depth
- in Chapter 8.
- Example:
-
- pull first last. /* read names */
-
- 4-22 PUSH
-
- Usage: PUSH [expression]
- The PUSH instruction is used to prepare a stream of data to be ready by a
- command shell or other program. It appends a "newline" to the result of the
- expression and then stacks or "pushes" it into the STDIN stream. Stacked lines
- are placed in the stream in "last-in, first-out" order,and are then available
- to be ready just as though they had been entered interactively. For example,
- after issuing the instructions
-
- push line 1
- push line 2
- push line 3
-
- the steam would be read in the order "line 3," "line 2" and "line 1."
-
- There are several restrictions governing the use of the PUSH instruction and
- its alter ego QUEUE. These instructions use a special I/O mechanism to
- accomplish their task,and as a result can be used only with an interactive
- (stream-model) I/O device like a console or pipe. The stream must be managed by
- with a DOS handler that supports the special ACTION_STACK (for PUSH) or
- ACTION_QUEUE (for QUEUE) command.
-
- PUSH allows the STDIN stream to be used as a private scratchpad to prepare data
- for subsequent processing. For example,several files could be concatenated with
- delimiters between them by simply reading the input files,PUSHing the lines
- into the stream,and inserting a delimiter where required. Once the stacked
- lines are exhausted,the stream reverts to its normal source of data.
- Example:
-
- /* Stack commands for compile and link*/
- push "blink c.o+main.o library amiga.lib to myprog"
- push "cc main"
-
- 36
-
- 4-23 QUEUE
-
- Usage:QUEUE [expression]
- The QUEUE instruction is used to prepare a stream of data to be read by a
- command shell or other program. It is very similar to the preceding PUSH
- instruction,and differs only that the data lines are placed in the STDIN stream
- in "first-in,first-out" order. In this case the instruction
-
- queue line 1
- queue line 2
- queue line 3
-
- would be read in the order "line 1," "line 2," and "line 3." The QUEUEd lines
- always precede all interactivly-entered lines,and always follow any PUSHed
- (stacked)lines.
-
- The same restriction noted with the use of the PUSH instruction apply to the
- QUEUE instruction. The queueing mechanism uses the ACTION_QUEUE command,so the
- DOS handler associated with the STDIN stream must support this command.
-
- In most cases the choice of whether to use PUSH or QUEUE is just a matter of
- convenience or personal preference. Each of them provides a "scratch pad"
- facility similar to that provided by an I/O pipe,but useful within one program
- or task rather than just for interprocess communications.
- Example:
-
- /* Queue commands for compile and link */
- queue "cc main"
- queue "blink c.o+main.o library amiga.lib to myprog"
-
- 4-24 RETURN
- RETURN is used to leave a function and return control to the point of the
- previous function invocation. The evaluated expression is returned as the
- function result. If an expression is not supplied,an error may result in the
- caller's environment. Functions called from within an expression must return a
- result string,and will generate an error if no result is available. Function
- invoked by the CALL instruction need not return a result.
-
- A RETURN issued from the base environment of a program is not an error,and is
- equivalent to an EXIT instruction. Refer to the EXIT instruction for a
- description of how result strings are passed back to an external caller.
- Example:
-
- return 6*7 /*the answer */
-
- 37
-
- 4-25 SAY
-
- Usage:SAY [expression]
- The result of the evaluated expression is written to the output console,with a
- "newline" character appended. If the expression is omitted,a null string is
- sent to the console.
- Example:
-
- say 'The anwer is ' value
-
- 4-26 SELECT
-
- Usage:SELECT
- This instruction begins a group of instructions containing one or more WHEN
- clauses and possibly a single OTHERWISE clause,each followed by a conditional
- statement.
-
- Only one of the conditional statements within the SELECT group will be
- executed. Each WHEN statement is executed in succession until one succeeds;if
- none succeeds,the OTHERWISE statement is executed. The SELECT range must be
- terminated by an eventual END statement.
- Example:
-
- select
- when i=1 then say 'one'
- when i=2 then say 'two'
- otherwise say 'other'
- end
-
- 4-27 SHELL
-
- Usage:SHELL [symbol | string] [expression]
- The SHELL instruction is a synonym for the ADDRESS instruction.
- Example:
-
- shell edit /* set host to 'EDIT' */
-
- 4-28 SIGNAL
-
- Usage: SIGNAL {ON |OFF} condition
- or: SIGNAL [VALUE] expression
- There are two forms of the SIGNAL instruction. The first form illustrated
- controls the state of the internal interrupt flags. Interrupts allow a program
- to detect and retain control when certain errors occur,and are discussed in
- Chapter 7. In this form SIGNAL must be followed by one of the keywords ON or
- OFF and one of the condition keywords listed below. The interrupt flag
- specified by the condition symbol is then set to the indicated state. The valid
- signal conditions are:
-
- BREAK_C A "control-C" break was detected.
- BREAK_D A "control-D" break was detected.
- BREAK_E A "control-E" break was detected.
-
- 38
-
- BREAK_F A "control-F" break was detected.
- ERROR A Host command returned a non-zero code.
- HALT An external HALT request was detected.
- IOERR An error was detected by the I/O system.
- NOVALUE An uninitialized variable was used.
- SYNTAX A syntax or execution error was detected.
-
- The condition keywords are interpreted as labels to which control will
- transferred if the selected condition occurs. For example,if the ERROR
- interrupt is enabled and a command returns a non-zero code,the interpreter will
- transfer control to the label ERROR:. The condition label must of course be
- defined in the program;otherwise,an immediate SYNTAX error results and the
- program exits.
-
- In the second form of the instruction,the tokens following SIGNAL are evaluated
- as an expression. An immediate interrupt is generated that transfers control to
- the label specified by the expression result. The instruction thus acts as a
- "computed goto."
-
- INTERRUPTS. Whenever an interrupt occurs,all currently active control ranges
- (IF,DO,SELECT,INTERPRET,or interactive TRACE) are dismantled before the
- transfer of control. Thus,the transfer cannot be used to jump into the range of
- a DO-loop or other control structure. Only the control structures in the
- current environment are affected by a SIGNAL condition,so it is safe to SIGNAL
- from within an internal function without affecting the state of the caller's
- environment.
-
- SPECIAL VARIABLES. The special variable SIGL is set to the current line number
- whenever a transfer of control occurs. The program can inspect SIGL to
- determine which line was being executed before the transfer. If an ERROR or
- SYNTAX condition causes an interrupt,the special variable RC is set to the
- error code that triggered the interrupt. For the ERROR condition,this code is
- usually an error secerity level. The SYNTAX condition will always indicate an
- ARexx error code.
- Examples:
-
- signal on error /* enable interrupt */
- signal off syntax /* disable SYNTAX */
- signal start /* goto START */
-
- 4-29 THEN
-
- Usage:THEN[;] [conditional statement]
- The THEN instruction must be the next statement following an IF or WHEN
- instruction,and is valid only in that context. It tests whether the preceding
- expression evaluated to 1(True),in which case the conditional statement
- following the THEN is performed. If the expression result was a 0(False),the
- conditional statement is skipped.
-
- 39
-
- Example:
-
- if i=j
- then say 'equal'
- else say 'not equal'
-
- 4-30 TRACE
-
- Usage:TRACE [symbol|string|[[VALUE] expression]]
- The TRACE instruction is used to set the internal tracing mode. If a symbol or
- string is supplied,it is taken as a literal. Otherwise,the tokens following the
- VALUE keyword are evaluated as an expression. The VALUE keyword can be omitted
- if the expression doesn't start with a symbol or string token.
-
- In either case the result string is converted to uppercase and checked first
- for one of the "alphabetic" options. The valid alphabetic options are ALL,
- COMMANDS,ERRORS,INTERMEDIATES,LABELS,RESULTS,and SCAN. These can be spelled out
- in full or shortened to the initial character,and are described in Chapter 7.
- If the result doesn't match any of these options,the interpreter attempts to
- convert it to an integer. A conversion failure here will be reported as an
- error.
-
- PREFIX CHARACTERS. Two special symbol characters may precede any of the
- alphabetic keywords. The "?" character interactive tracing,and the "!"
- character controls command inhibition. These characters act as "toggles" to
- alternatively select and de-select the respective modes. Any number of prefix
- characters may precede an alphabetic option. Interactive tracing and command
- inhibition are described in Chapter 7.
-
- NUMERIC OPTION. If the specified trace option is a negative whole number,it is
- accepted as a trace suppression count. The suppression count is the number of
- clauses(that would otherwise be traced)to be passed over before resuming the
- tracing display. Suppression counts are ignored execept during interactive
- tracing.
- Examples:
-
- trace ?r /* interactive RESULTS */
- trace off
- trace -20 /* skip 20 clauses */
-
- 4-31 UPPER
-
- Usage:UPPER variable [variable...]
- The values of the variables in the list are converted to uppercase. It is not
- an error to include an uninitialized variable in the list,but it will be
- trapped if the NOVALUE interrupt has been enabled.
-
- The TRANSLATE() or UPPER() Built-In functions could also be used to convert
- variables to uppercase,but the instruction form is more concise(and faster) if
- several variables are being converted.
-
- 40
-
- Example:
-
- when='Now is the time'
- upper when
- say when /* NOW IS THE TIME */
-
- 4-32 WHEN
-
- Usage:WHEN expression [THEN [;] [conditional statement]]
- The WHEN instruction is similar to the IF instruction,but is valid only within
- a SELECT range. Each WHEN expression is evaluated in turn and must result in a
- boolean value. If the result is a 1,the conditional statement is executed and
- control passes to the END statement that terminates the SELECT. As in the case
- of the IF instruction,the THEN need not be part of the same clause.
- Example:
-
- select;
- when i<j thn say 'less'
- when i=j then say 'equal'
- otherwise say 'greater'
- end
-
- 41
-
- CHAPTER 5 COMMANDS
-
- The REXX language is unusual in that an entire syntactic class of program
- statements are reserved for cmmands,statements that have meaning not within the
- language itself but rather to an external program. When a command clause is
- found in a program,it is evaluated as an expression and then sent through the
- command interface to an explicit or implicit host application,an external
- program that has announced its ability to receive commands. The host
- application then processes the command and returns a result code that indicates
- whether the command was performed successfully. In this manner every host
- program becomes fully programmable,and with even a limited set of predefined
- operations can be customized by the end user.
-
- This chapter discusses the ARexx command interface and examines some of the
- ways in which commands can be used to build programs for an external program.
- Such programs are ofter called "macro programs" because they implement a
- complex ("macro") action from a series of simpler "micro" commands.
-
- Chapter 10 has detailed information on the data structers required to implement
- a command interface for an applications program.
-
- 5-1 COMMAND CLAUSES
-
- Syntactically,a command clause is just an expression that can't be classified
- as another type of clause. The actual structure of the command is dictated by
- the external host to which it is intended,but in most cases will follow the
- model of a name or letter followed by parameter data. Command names can be
- given as either a symbol or a string. However,it is generally safer to use a
- string for the name,since it can't be assigned a value or be mistaken for an
- instruction keyword. For example,the following might be commands for a text
- editor:
-
- JUMP current+10 /* advance to next */
- 'insert' newstring /* blast it in */
- 'TOP' /* back to the top */
-
- Since command clauses are expressions,they are fully evaluated before being
- sent to the host. Any part of the final command string can be computed within
- the program,so virtually any sort of command structure can be created.
-
- The interpretation of the received commands depends entirely on the host
- application. In the simplest case the command strings will correspond exactly
- to commands that could be entered directly by a user. For instance,positional
- control(up/down)commands for a text editor would probably have identical
- interpretations whether issued by the user or from a program. Other commands
- may be valid only when issued from a macro program;a command to simulate a menu
- operation would probably not be entered by the user.
-
- 43
-
- 5-2 THE HOST ADDRESS
-
- The destination for a command is determined by the current host address,which
- is the name of the public message port managed by an external program. ARexx
- maintains two implicit host addresses,a "current" and a "previous" value,as
- part of the program's storage environment. These values can be changed at any
- time using the ADDRESS instruction(or its synonym,SHELL,)and the current host
- address can be inspected with the ADDRESS()Built-In fuction. The default host
- address string is "REXX",but this can be overridden when a program is invoked.
- In particular,most host applications will supply the name of their public port
- when they invoke a macro program,so that the macro can automatically issue
- commands back to the host.
-
- One special host address is recognized: the string COMMAND indicates that the
- command should be issued directly to the underlying DOS. All other host
- addresses are assumed to refer to a public message port. An attempt to send a
- commmand to a non-existent message port will generate the syntax error "Host
- environment not found."
-
- Single commands can be sent to a specific host without disturbing the host
- address settings. This is done using the ADDRESS instruction,as the following
- example illustrates:
-
- ADDRESS MYEDIT 'jump top'
-
- This example would send the command "jump top" to an external host named
- "MYEDIT."
-
- It is important to note that you cannot send commands to a host application
- without knowing the name of its public message port. Writing macro programs to
- communicate with two or more hosts may require some clever programming to
- determine whether both hosts are active and what their respective host
- addresses are.
-
- 5-3 THE COMMAND INTERFACE
-
- ARexx implements its command interface using the message-passing facilities
- provided by the EXEC operating system. Each host application must provide a
- public message port,the name of which is referred to as the host address. ARexx
- programs issue commands by placing the command string in a message packet and
- sending the packet to the host's message port. The program "sleeps" while the
- host processes the command,and awakens when the message packet returns. The
- entire process can be regarded as a dialogue between the host application and a
- macro program:the host initiates the dialogue by invoking the macro,and the
- macro program replies with one or more command strings. The commands that can
- be sent are not limited to simple text strings,but might be address pointers or
- even bit-mapped images.
-
- After it finishes processing a command,the host "replies" the message packet
- with a return code that indicates the status of the command. This return code
- is placed in the ARexx special variable RC so that it can be examined by the
- program. A value of zero is assumed to mean that no errors occurred,while
- positive values usually indicate progressively more severe error conditions.
- The return code allows the macro program to determine whether the command
- succeeded and to take action if it failed,so it is important for each
- applictions program to document the meanings of the return codes for its
- commands.
-
- 44
-
- 5-4 USING COMMANDS IN MACRO PROGRAMS
-
- ARexx can be used to write programs for any host application that includes a
- suitable command interface. Some applications programs are designed with an
- embedded macro language,and may include many predefined macro commands. With a
- well-designed macro language interface the user will be usually unaware of
- whether a given action is implemented as a primitive operations or as a macro
- program.
-
- The starting point in designing a macro program is to examine the commands that
- would be required to perform it manually. The documentation for the host
- application program should then describe the possible return codes for each
- command;these codes can be used to determine whether the operation performed by
- the command was successful. Check also for "shortcut" commands that may be
- available only to macro programs;some applications programs may include very
- powerful functions that were implemented specifically for use in macro
- programs.
-
- 5-5 USING AREXX WITH COMMAND SHELLS
-
- Although ARexx was designed to work most effectively with programs that support
- its specific command interface,it can be used with any "command shell" program
- that uses standards I/O mechanisms to obtain its input stream. There are
- several ways to use ARexx to prepare a stream of commands for such program.
-
- One obvious technique is to create an actual command file on the "RAM:" disk
- and then pass it directly to the command shell. For example,you could open a
- new CLI window to run a standard "execute" script using the following short
- program:
-
- /* Launch a new CLI */
- address command
- conwindow = "CON:0/0/640/100/NewOne"
-
- /* create a command file on the fly */
- call open out,"ram:$$temp",write
- call writeln out,'echo "this is a test"'
- call close out
-
- /* open the new CLI window */
- 'newcli' conwindow "ram:$$temp"'
- exit
-
- Since no disk accesses are required,this method is actually fairly fast,if not
- very elegant.
-
- Another alternative is to use the command stacking facility provided by the
- PUSH and QUEUE instructions. These instructions allow an ARexx program to stack
- an arbitrary stream of commands and data for the command shell or other program
- to read. Any set of commands that could be "typed ahead" at a command prompt
- can be prepared in this fashion. After the ARexx program exits,the next program
- that uses the input stream will read the prepared commands and can process them
- in the normal fashion.
-
- 45
-
- 5-6 COMMAND INHIBITION
-
- Sometimes it is necessary to write and test macro programs that issue
- potentially destructive commands. For instance,a program to find and delete
- unneeded files would be difficult to test safely,since it might accidentally
- delete the wrong files and would require a continual source of new files for
- testing.
-
- To simply the development and testing of such programs,ARexx provides a special
- tracing mode called command inhibition that suppresses host commands. While in
- command inhibition mode,command processing proceeds normally except that the
- command is not actually issued and the variable RC is set to 0. This allows the
- program logic to be verified before any commands are actually sent to the
- external program. Chapter 7 has further information on this facility.
-
- 46
-
- CHAPTER 6 FUNCTIONS
-
- The basic concept of a function is a program or group of statements that will
- be executed whenever the function name appears in a certain context. Functions
- are an important building block of most computer languages in that they allow
- modular programming -- the ability to build a large program from a series of
- smaller,more easily developed modules. In ARexx a function may be defined as
- part of(internal to)a program,as part of a library,or as a separate external
- program.
-
- 6-1 SYNTAX AND SEARCH ORDER
-
- Function calls in an expression are defined syntactically as a symbol or string
- followed immediately by an open parenthesis. The symbol or string(taken an a
- literal)specifies the function name,and the open parenthesis begins the
- argument list. Between the opening and eventual closing parentheses are zero or
- more argument expressions,separated by commas,that supply the data being passed
- to the function. For example,
-
- CENTER('title",20)
- ADDRESS()
- 'AllocMem'(256*4,1)
-
- are all valid function calls. Each argument expression is evaluated in turn and
- the resulting strings are passed as the argument list to the function. There is
- no limit to the number of arguments that may be passed to an internal
- function,but calls to Built-In or external functions are limited to a maximum
- of 15 arguments. Note that each argument expression,while ofter just a single
- literal value,can include arithmetic or string operations or even other
- function calls. Argument expressions are evaluated from left to right.
-
- Functions can also be invoked using the CALL instruction. The syntax of this
- form is slightly different,and is described in Chapter 4. The CALL instruction
- can be used to invoke a function that may not return a value.
-
- SEARCH ORDER
-
- Function linkages in ARexx are established dynamically at the time of the
- function call. A specific search order is followed until a function matching
- the name symbol or string is found. If the specified function cannot be
- located, an error is generated and the expression evaluation is terminated. The
- full search order is:
-
- 1. Internal Functions. The program source is examined for a label that matches
- the function name. If a match is found,a new storage environment is created and
- control is transferred to the label.
-
- 2. Built-In Functions. The Build-In function library is searched for the
- specified name. All of these functions are defined by uppercase names,and the
- library has been specially organized to make the search as efficient as
- possible.
-
- 47
-
- 3. Function Libraries and Function Hosts. The available function libraries and
- function hosts are maintained in a prioritized list,which is searched starting
- at the highest priority until the requested function is found or the end of the
- list is reached. Each function library is opened and called at a special entry
- point to determine whether it contains a function matching the given name.
- Function hosts are called using a message-passing protocol similar to that used
- for commands,and may be used as gateways for remote procedure calls to other
- machines in a network.
-
- 4. External ARexx Programs. The final search step is to check for an external
- ARexx program file by sending an invocation message to the ARexx resident
- process. The search always begins in the current directory,and follows the same
- search path as the original ARexx program invocation. The name matching process
- is not case-sensitive.
-
- Note that the function name-matching procedure may be case-sensitive for some
- of the search steps but not for others. The matching procedure used in a
- function library or function host is left to the discretion of the applications
- designer. Functions defined with mixed-case names must be called using a string
- token,since symbol names are always translated to uppercase.
-
- The full search order is followed whenever the function name is defined by a
- symbol token. However,the search for internal functions is bypassed if the name
- is specified by a string token. This allows internal functions to usurp the
- names of external functions,as in the following example:
-
- CENTER: /* internal "CENTER" */
- arg string,length /* get arguments */
- length = min(length,60) /* compute length */
- return 'CENTER'(string,length)
-
- Here the Built-In fuction CENTER()has been replaced by an internal function of
- the same name,which calls the original function after modifying the length
- argument.
-
- INTERNAL FUNCTIONS
-
- The interpreter creates a new storage environment when an internal function is
- called,so that the previous(caller's)environment is preserved. The new
- environment inherits the values from its predecessor,but subsequent changes to
- the environment variables do not affect the previous environment. The specific
- values that are preserved are:
-
- The current and previous host addresses,
- The NUMERIC DIGITS,FUZZ,and FORM settings,
- The trace option,inhibit flag,and interace flag,
- The state of the interrupt flags defined by the SIGNAL instruction,and
- The current prompt string as set by the OPTIONS PROMPT instruction.
-
- The new environment does not automatically get a new symbol table,so initially
- all of the variables in the previous environment are available to the called
- function. The PROCEDURE instruction can be used to create a new symbol table
-
- 48
-
- and thereby protect the caller's symbol values.
-
- Execution of the internal function proceeds until a RETURN instruction is
- executed. At this point the new environment is dismantled and control resumes
- at the point of the function call. The expression supplied with the RETURN
- instruction is evaluated and passed back to the caller as the fuction result.
-
- BUILT-IN FUNCTIONS
-
- ARexx provides a substantial library of predefined functions as part of the
- language system. These functions are always available and have been optimized
- to work with the internal data structures. In general the Built-In functions
- execute much faster than an equivalent interpreted function,so their usage is
- strongly recommended.
-
- The Built-In Function Library is not user-extensible,but additional functions
- will be included in later releases.
-
- EXTERNAL FUNCTION LIBRARIES
-
- External function libraries provide a mechanism with which users and
- applications developers can extend the functionality of ARexx. A function
- library is a collection of one or more functions together with a "query" entry
- point that serves to match a name string with the appropriate function.
- External function libraries are supported as standard Amiga shared libraries,
- and may be either memory or disk-resident. Disk-resident libraries are loaded
- and opened as needed.
-
- The ARexx resident process maintains a list,called the Library List,of the
- currently available function libraries and function hosts. Applications
- programs can add or remove function libraries as required. The Library List is
- maintained as a priority-sorted queue,and entries can be added at an
- appropriate priority to control the function name resolution. Libraries with
- higher priorities are searched first;within a given priority level,those
- libraries added first are searched first.
-
- During the search process the ARexx interpreter opens each library and calls
- its "query" entry point. The query function must then check to see whether the
- requested function name is in the library. If not,it returns a "function not
- found" error code and the search continues with the next library in the list.
- Function libraries are always closed after being checked so that the operatiing
- system can reclaim the memory space if required. Once the requested function
- has been found,it is called with the arguments passed by the interpreter,and
- must return an error code and a result string.
-
- The ARexx language system includes an external function library in a file
- called "rexxsupport.library". It contains a number of Amiga-specific functions
- and is described in Appendix D. Chapter 10 provides information on designing
- and implementing function libraries.
-
- 49
-
- FUNCTION HOSTS
-
- Function hosts are called by sending a function invocation message packet to
- the public message port identified by the host's name. No constraints are
- imposed on the iternal design of the host except that it must eventually return
- the invocation message with an appropriate return code and result string. The
- function call may result in a new program being loaded and run,or might even be
- sent to a network handler as a remote procedure call.
-
- The available function hosts,along with the function libraries,are contained in
- the Library List maintained by the resident process. This list provides a
- general mechanism for resolving function names in a priority-controlled manner.
-
- The ARexx resident process is an example of a function host. It is added to the
- Library List at a nominal priority of -60 when the resident process is started,
- using the same name ("REXX")that is used for command invocations. When it
- receives a function invocation packet,it searches for an external file matching
- the function name,just as it would for a command invocation of the same name.
- In particular,the search begins with the current directory and process is not
- case-sensitive,but is affected by the presence of explicit directory
- specifications or file extensions in the name string. The rules governing the
- search for external programs are covered in Chapter 9.
-
- External programs are always run as a separate process in the Amiga's
- multitasking system. The calling program "sleeps" until the called function
- finishes and the message packet returns. The result string and error code are
- returned in the packet.
-
- 6-2 THE BUILT-IN FUNCTION LIBRARY
-
- This section of the chapter is devoted to descriptions of the individual Built
- In functions,which are listed alphabetically. Many of the functions have
- optional as well as required arguments. The optional arguments are shown in
- brackets,and generally have a default value that is used if the argument is
- omitted.
-
- MAXIMUM ARGUMENTS. While internal functions can be called with any number of
- arguments,the Built-In functions(and external functions as well)are limited to
- a maximum of 15 arguments.
-
- PAD AND OPTION CHARACTERS. For functions that accept a "pad" character
- argument,only the first character of the argument string is significant. If a
- null string is supplied,the default padding character(usually a blank)will be
- used. Similarly,where an option keyword is specified as an argument,only the
- first character is significant. Option keywords may be given in uppercase or
- lowercase.
-
- I/O SUPPORT FUNCTIONS. ARexx provides functions for creating and manipulating
- external DOS files. The functions available at the present time are OPEN(),
- CLOSE(),READCH(),READLN(),WRITECH(),WRITELN(),EOF(),SEEK(),and EXISTS(). Files
- are referenced by a "logical name," a case-sensitive name that is assigned to a
- file when it is first opened.
-
- 50
-
- There is no limit to the number of files that may be open simultaneously,and
- all open files are closed automatically when the program exits.
-
- BIT-MANIPULATION FUNCTIONS. The functions BITCHG(),BITCLR(),BITCOMP(),BITSET(),
- and BITTST() are provided to implement extended bit-testing on character
- strings. These functions differ from similar string-manipulation functions in
- that the elementary unit of comparison is the bit rather than the byte. Bit
- number are defined such that bit 0 is the low-order bit of the rightmost byte
- of the string.
-
- ABBREV()
-
- Usage:ABBREV(string1,string2,[length]
- Returns a boolean value that indicates whether string2 is an abbreviation of
- string1 with length greater than or equal to the specified length argument. The
- default length is 0,so the null string is an acceptable abbreviation.
- Example:
-
- say abbrev('fullname','ful' ==>1
- say abbrev('almost','alm',4) ==>0
- say abbrev('any','') ==>1
-
- ABS()
-
- Usage:ABS(number)
- Returns the absolute value of the number argument,which must be numeric.
- Examples:
-
- say abs(-5.35) ==>5.35
- say abs(10) ==>10
-
- ADDLIB()
-
- Usage ADDLIB(name,priority,[offset,version])
- Adds a function library or a function host to the Library List maintained by
- the resident process. The name argument specifies either the name of a function
- library or the public message port associated with a function host. The name is
- case-sensitive,and any libraries thus declared should reside in the system
- LIBS: directory. The priority argument specifies the search priority and must
- be an integer between 100 and -100,inclusive. The offset and version arguments
- apply only to libraries. The offset is the integer offset to the library's
- "query" entry point,and the version is an integer specifying the minimum
- acceptable release level of the library.
-
- The function returns a boolean result that indicates whether the operation was
- successful. Note that if a library is specified,it is not actually opened at
- this time;similarly,no check is performed as to whether a specified function
- host port has been opened yet.
- Example:
-
- say addlib("rexxsupport.library",0,-30,0)==>1
- call addlib "EtherNet",-20 /* a gateway */
-
- 51
-
- ADDRESS()
-
- Usage:ADDRESS()
- Returns the current host address string. The host address is the message port
- to which commands will be sent. The SHOW()function can be used to check whether
- the required external host is actually available.
- See Also:SHOW()
- Example:
-
- say address() ==>REXX
-
- ARG()
-
- Usage:ARG([number],['Exists' | 'Omitted'])
- ARG()returns the number of arguments supplied to the current environment. If
- the number parameter alone is supplied,the corresponding argument string is
- returned. If a number and one of the keywords Exists or Omitted is given,the
- boolean return indicates the status of the corresponding argument. Note that
- the existence or omission test does not indicate whether the string has a null
- value,but only whether a string was supplied.
- Examples:
-
- /* Assume arguments were: ('one,,10) */
- say arg() ==>3
- say arg(1) ==>one
- say arg(2,'0') ==>1
-
- B2C()
-
- Usage:B2C(string)
- Converts a string of binary digits(0,1)into the corresponding(packed)character
- representation. The conversion is the same as though the argument string had
- been specified as a literal binary string(e.g. '1010'B). Blanks are permitted
- in the string,but only at byte boundaries. This function is particularly useful
- for creating strings that are to be used as bit masks.
- See also:X2C()
- Examples:
-
- say b2c('00110011') ==>3
- say b2c('01100001') ==>a
-
- BITAND()
-
- Usage:BITAND(string1,string2,[pad])
- The argument strings are logically ANDed together,with the length of the result
- being the longer of the two operand strings. If a pad character is supplied,the
- shorter string is padded on the right;otherwise,the operation terminates at the
- end of the shorter string and the remainder of the longer string is appended to
- the result.
- Example:
-
- bitand('0313'x,'FFF0'x) ==>'0310'x
-
- 52
-
- BITCHG()
- Usage:BITCHG(string,bit)
- Changes the state of the specified bit in the argument string. Bit numbers are
- defined such that bit 0 is the low-order bit of the rightmost byte of the
- string.
- Example:
- bitchg('0313'x,4) ==>'0303'x
-
- BITCLR()
- Usage:BITCLR(string,bit)
- Clears(sets to zero)the specified bit in the argument string. Bit numbers are
- defined such that bit 0 is the low-order bit of the rightmost byte of the
- string.
- Example:
- bitclr('0313'x,4) ==>'0303'x
-
- BITCOMP()
- Usage:BITCOMP(string1,string2,[pad])
- Compares the argument strings bit-by-bit,starting at bit number 0. The returned
- value is the bit number of the first bit in which the strings differ,or -1 if
- the strings are identical.
- Examples:
- bitcomp('7F'x,'FF'x) ==>7
- bitcomp('FF'x,'FF'x) ==>-1
-
- BITOR()
- Usage:BITOR(string1,string2,[pad])
- The argument strings are logically ORed together,with the length of the result
- being the longer of the two operand strings. If a pad character is supplied,the
- shorter string is padded on the right;otherwise,the operation terminates at the
- end of the shorter string and the remainder of the longer string is appended to
- the result.
- Example:
- bitor('0313'x,'003F'x) ==>'033F'x
-
- BITSET()
- Usage:BITSET(string,bit)
- Sets the specified bit in the argument string is 1. Bit numbers are defined
- such that bit 0 is the low-order bit of the rightmost byte of the string.
- Example:
- bitset('0313'x,2) ==>'0317'x
-
- BITTST()
- Usage:BITTST(string,bit)
- The boolean return indicates the state of the specified bit in the argument
- string.
-
- 53
-
- Bit numbers are defined such that bit 0 is the low-order bit of the rightmost
- byte to the string.
- Example:
- bittst('0313'x,4) ==>1
-
- BITXOR()
- Usage:BITAND(string1,string2,[pad])
- The argument strings are logically exclusively-ORed together,with the length of
- the result being the longer of the two operand strings. If a pad character is
- supplied,the shorter string is padded on the right;otherwise,the operation
- terminates at the end of the shorter string and the remainder of the longer
- string is appended to the result.
- Example:
- bitxor('0313'x,'001F'x) ==>'030C'x
-
- C2B()
- Usage:C2B(string)
- Converts the character string into the equivalent string of binary digits.
- See Also:C2X()
- Example:
- say c2b('abc') ==>011000010110001001100011
-
- C2D()
- Usage:C2D(string,[n])
- Converts the string argument from its character representation to the
- corresponding decimal number,expressed as ASCII digits(0-9). If n is supplied,
- the character string is considered to be a number expressed in n bytes. The
- string is truncated or padded with nulls on the left as required,and the sign
- bit is extended for the conversion.
- Examples:
- say c2d('0020'x) ==>32
- say c2d('FFFF') ==>1
- say c2d('FF0100',x,2) ==>256
-
- C2X()
- Usage:C2X(string)
- Converts the string argument from its character representation to the
- corresponding hexadecimal number,expressed as the ACSII characters 0-9 and A-F.
- See Also:C2B()
- Example:
- say c2x('abc') ==>616263
-
- 54
-
- CENTER() or CENTRE()
- Usage:CENTER(string,length,[pad])or CENTRE(string,length,[pad])
- Centers the string argument in a string with the specified length. If the
- length is longer than that of the string,pad characters or blanks are added as
- necessary.
- Examples:
- say center('abc',6) ==>' abc '
- say center('abc',6,'+') ==>'+abc++'
- say center('123456',3) ==>'234'
-
- CLOSE()
- Usage:CLOSE(file)
- Closes the file specified by the given logical name. The returned value is a
- boolean success flag,and will be 1 unless the specified file was not open.
- Example:
- say close('input') ==>1
-
- COMPRESS()
- Usage:COMPRESS(string,[list])
- If the list argument is omitted,the function removes leading,trailing,or
- embedded blank characters from the string argument. If the optional list is
- supplied,it specifies the characters to be removed from the string.
- Examples:
- say compress (' why not ') ==>whynot
- say compress ('++12-34-+','+-') ==>1234
-
- COMPARE()
- Usage:COMPARE(string1,string2,[pad])
- Compares two strings and returns the index of the first position in which they
- differ,or 0 if the strings are identical. The shorter string is padded as
- required using the supplied character or blanks.
- Examples:
- say compare('abcde','abcce') ==>4
- say compare('abcde',abcde') ==>0
- say compare('abc++','abc+-','+') ==>5
-
- COPIES()
- Usage:COPIES(string,number)
- Creates a new string by concatenating the specified number of copies of the
- original. The number argument may be zero,in which case the null string is
- returned.
-
- 55
-
- Example:
- say copies('abc',3) ==>abcabcabc
-
- D2C()
- Usage:D2C(number)
- Creates a string whose value is the binary(packed)representation of the given
- decimal number.
- Example:
- d2c(31) ==>'1F'x
-
- DATATYPE()
- Usage:DATATYPE9string,[option])
- If the option parameter is not specified,DATATYPE()tests whether the string
- parameter is a valid number and returns either NUM or CHAR. If an option
- keyword is given,the boolean return indicates whether the string satisfied the
- requested test. The following option keywords are recognized:
-
- Table 6.1 DATATYPE()Options
-
- KEYWORD CHARACTERS ACCEPTED
- Alphanumeric Alphabetics (A-Z,a-z)
- or Numerics (0-9)
- Binary Binary Digits String
- Lowercase Lowercase Alphabetics (a-z)
- Mixed Mixed Upper/Lowercase
- Numeric Valid Numbers
- Symbol Valid REXX Symbols
- Upper Uppercase Alphabetics (A-Z)
- Whole Integer Numbers
- X Hex Digits String
- Examples:
- say datatype('123') ==>NUM
- say datatype('1a f2','x') ==>1
- say datatype('aBcde','L') ==>0
-
- DELSTR()
- Usage:DELSTR(string,n,[length])
- Deletes the substring of the string argument beginning with the nth character
- for the specified length in characters. The default length is the remaining
- length of the string.
- Example:
- say delstr('123456',2,3) ==>156
-
- 56
-
- DELWORD()
- Usage:DELWORD(string,n,[length])
- Deletes the substring of the string argument beginning with the nth word for
- the specified length in words. The default length is the remaining length of
- the string. The deleted string includes any trailing blanks following the last
- word.
- Examples:
- say delword('Tell me a story',2,2)==>'Tell story'
- say delword('one two three',3) ==>'one two '
-
- EOF()
- Usage:EOF(file)
- Checks the specified logical file name and returns the boolean value 1(True)if
- the end-of-file has been reached,and 0(False)otherwise.
- Example:
- say eof(infile) ==>1
-
- ERRORTEXT()
- Usage:ERRORTEXT(n)
- Returns the error message associated with the specified ARexx code. The null
- string is returned if the number is not a valid error code.
- Example:
- say errortext(41) ==>Invalid expression
-
- EXISTS()
- Usage:EXISTS(filename)
- Tests whether an external file of the given filename exists. The name string
- may include device and directory specifications.
- Example:
- say exists('df0:c/ed') ==>1
-
- EXPORT()
- Usage:EXPORT(address,[string],[length],[pad])
- Copies data from the (optional) string into a previously-allocated memory area,
- which must be specified as a 4-byte address. The length parameter specifies the
- maximum number of characters to be copied; the default is the length of the
- string. If the specified length is longer than the string,the remaining area is
- filled with the pad character or nulls('00'x). The returned value is the number
- of characters copied.
-
- Caution is advised in using this function. Any area of memory can be
- overwritten,possibly causing a system crash. Task switching is forbidden while
- the copy is being done,so system performance may be degraded if long strings
- are copied.
- See Also:IMPORT(),STORAGE()
-
- 57
-
- Example:
- count = export('0004 0000'x,'The answer')
-
- FREESPACE()
- Usage:FREESPACE(address,length)
- Returns a block of memory of the given length to the interpreter's internal
- pool. The address argument must be a 4-byte string obtained by a prior call to
- GETSPACE(),the internal allocator. It is not always necessary to release
- internally-allocated memory,since it will be released to the system when the
- program terminates. However,if a very large block has been allocated,returning
- it to the pool may avoid memory space problems. The return value is a boolean
- success flag.
- See Also:GETSPACE()
- Example:
- say freespace('00042000'x,32) ==>1
-
- GETCLIP()
- Usage:GETCLIP(name)
- Searches the Clip List for an entry matching the supplied name parameter,and
- returns the associated value string. The name-matching is case-sensitive,and
- the null string is returned if the name cannot be found. The usage and
- maintenance of Clip List entries is described in the Chapter 9.
- See Also:SETCLIP()
- Example:
- /* Assume 'numbers' contains 'PI=3.14159' */
- say getclip('numbers') ==>PI=3.14159
-
- GETSPACE()
- Usage:GETSPACE(length)
- Allocates a block of memory of the specified length from the interpreter's
- internal pool. The returned value is the 4-byte address of the allocated block,
- which is not cleared or otherwise initialized. Internal memory is automatically
- returned to the system when the ARexx program terminates,so this function
- should not be used to allocate memory for use by external programs. The Support
- Library(described in Appendix D)includes the function ALLOCMEM()which to
- allocate memory from the system free list.
- See Also:FREESPACE()
- Example:
- say c2x(getspace(32)) ==>'0003BF40'x
-
- HASH()
- Usage:HASH(string)
- Returns the hash attribute of a string as a decimal number,and updates the
- internal hash value of the string.
-
- 58
-
- Example:
- say hash('1') ==>49
-
- IMPORT()
- Usage:IMPORT(address,[length])
- Creates a string by copying data from the specified 4-byte address. If the
- length parameter is not supplied,the copy terminates when a null byte is found.
- See Also:EXPORT()
- Example:
- extval = import('0004 0000'x,8)
-
- INDEX()
- Usage:INDEX(string,pattern,[start])
- Searches for the first occurrence of the pattern argument in the string
- argument,beginning at the specified start position. The default start position
- is 1. The returned value is the index of the matched pattern,or 0 if the
- pattern was not found.
- Examples:
- say index("123456","23") ==>2
- say index("123456","77") ==>0
- say index("123123","23",3) ==>5
-
- INSERT()
- Usage:INSERT(new,old,[start],[length],[pad])
- Inserts the new string into the old string after the specified start position.
- The default starting position is 0. The new string is truncated or padded to
- the specified length as required,using the supplied pad character or blanks. If
- the start position is beyond the end of the old string,the old string is padded
- on the right.
- Examples:
- say insert('ab,'12345') ==>ab12345
- say insert('123','++',3,5,'-') ==>++-123--
-
- LASTPOS()
- Usage:LASTPOS(pattern,string,[start])
- Searches backwards for the first occurrence of the pattern argument in the
- string argument,beginning at the specified start position. The default starting
- position is the end of the string. The returned value is the index of the
- matched pattern,or 0 if the pattern was not found.
-
- 59
-
- Examples:
- say lastpos("123234","2") ==>4
- say lastpos("123234","5") ==>0
- say lastpos("123234","2",3) ==>2
-
- LEFT()
- Usage:LEFT(string,length,[pad])
- Returns the leftmost substring in the given string argument with the specified
- length. If the substring is shorter than the requested length,it is padded on
- the left with the supplied pad character or blanks.
- Examples:
- say left('123456',3) ==>123
- say left('123456',8,'+') ==>123456++
-
- LENGTH()
- Usage:LENGTH(string)
- Returns the length of the string.
- Example:
- say length('three') ==>5
-
- MAX()
- Usage:MAX(number,number[,number,...])
- Returns the maximum of the supplied arguments,all of which must be numeric. At
- least two parameters must be supplied.
- Example:
- say max(2.1,3,-1_ ==>3
-
- MIN()
- Usage:MIN(number,number[,number,...])
- Returns the minimum of the supplied arguments,all of which must be numeric. At
- least two parameters must be supplied.
- Example:
- say min(2.1,3,-1) ==>-1
-
- OPEN()
- Usage:OPEN(file,filename,['Append' | 'Read' | 'Write'])
- Opens an external file for the specified operation. The file argument defines
- the logical name by which the file will be referenced. The filename is the
- external name of the file,and may include device and directory specifications.
- The function returns a boolean value that indicates whether the operation was
- successful. There is no limit to the number of files that can be open
-
- 60
-
- simultaneusly,and all open files are closed automatically when the program
- exits.
- See Also:CLOSE(),READ(),WRITE()
- Examples:
- say open('MyCon','CON:160/50/320/100/MyCon/cds') ==>1
- say open('outfile','ram:temp','W') ==>1
-
- OVERLAY()
- Usage:OVERLAY(new,old,[start],[length],[pad])
- Overlays the new string onto the old string beginning at the specified start
- position,which must be positive. The default starting position is 1. The new
- string is truncated or padded to the specified length as required,using the
- supplied pad character or blanks. If the start position is beyond the end of
- the old string,the old string is padded on the right.
- Examples:
- say overlay('bb,'abcd') ==>bbcd
- say overlay('4','123',5,5,'-') ==>123--4----
-
- POS()
- Usage:POS(pattern,string,[start])
- Searches for the first occurrence of the pattern argument in the string
- argument,beginning at the position specified by the start argument. The default
- starting position is 1. The returned value is the index of the matched
- string,or 0 if the pattern wasn't found.
- Examples:
- say pos('23','123234') ==>2
- say pos('77','123234') ==>0
- say pos('23','123234',3) ==>4
-
- PRAGMA()
- Usage:PRAGMA(option,[value])
- This function allows a program to change various attributes relating to the
- system environment within which the program executes. The option argument is a
- keyword that specifies an environmental attribute;the currently implemented
- options are Directory and Priority. The value argument supplies the new
- attribute value to be installed. The value returned by the function depends on
- the attribute selected. Some attributes return the previous value
- installed,while others may simply set a boolean success flag. The currently
- defined option keywords are listed below.
-
- DIRECTORY. Specifies a new "current" directory. The current directory is used
- as the "root" for filenames that do not explicitly include a device
- specification. The return value is a boolean success flag.
-
- PRIORITY. Specifies a new task priority. The priority value must be an integer
- in the range -128 to 127,but the practical range is much more limited. ARexx
- programs should never be run at a priority higher than that of the resident
- process,which currently runs at priority 4. The returned value is the previous
- priority level.
-
- 61
-
- Examples:
- say pragma('priority',-5) ==>0
- call pragma 'Directory','df0:system'
-
- RANDOM()
- Usage:RANDOM([min],[max],[seed])
- Returns a pseudorandom integer in the interval specified by the min and max
- arguments. The default minimum value is 0 and the default maximum value is 999.
- The interval max-min must be less than or equal to 1000. If a greater range of
- random integers is required,the values from the RANDU()function can be suitable
- scaled and translated.
-
- The seed argument can be supplied to initialize the internal state of the
- random number generator.
- See Also:RANDU()
- Example:
- thisroll = random(1,6) /* might be 1 */
- nextroll = random(1,6) /* snake eyes? */
-
- RANDU()
- Usage:RANDU([seed])
- Returns a uniformly-distributed pseudorandom number between 0 and 1. The number
- of digits of precision in the result is always equal to the current Numeric
- Digits setting. With the choice of suitable scaling and translation values,
- RANDU()can be used to generate pseudorandom numbers on an arbitrary interval.
-
- The optional seed argument is used to initialize the internal state of the
- random number generator.
- See Also:RANDOM()
- Example:
- firsttry = randu() /* 0.371902021? */
- numeric digits 3
- tryagain = randu() /* 0.873? */
-
- READCH()
- Usage:READCH(file,length)
- Reads the specified number of characters from the given logical file into a
- string. The length of the returned string is the actual number of characters
- read,and may be less than the requested length if,for example,the end-of-file
- was reached.
- See Also:READLN()
- Example:
- instring = readch('input',10)
-
- 62
-
- READLN()
- Usage:READLN(file)
- Reads characters from the given logical file into a string until a "newline"
- character is found. The returned string does not include the "newline".
- See Also:READCH()
- Examples:
- instring = readln('MyFile')
-
- REMLIB()
- Usage:REMLIB(name)
- Removes an entry with the given name from the Library List maintained by the
- resident process. The boolean return is 1 if the entry was found and
- successfully removed. Note that this function does not make a distinction
- between function libraries and function hosts,but simply removes a named entry.
- See Also:ADDLIB()
- Example:
- say remlib('MyLibrary.library')==>1
-
- REVERSE()
- Usage:REVERSE(string)
- Reverses the sequence of characters in the string.
- Example:
- say reverse('?ton yhw') ==>why not?
-
- RIGHT()
- Usage:RIGHT(string,length,[pad])
- Returns the rightmost substring in the given string argument with the specified
- length. If the substring is shorter than the requested length,it is padded on
- the left with the supplied pad character or blanks.
- Examples:
- say right('123456',4) ==>3456
- say right('123456',8,'+') ==>++123456
-
- SEEK()
- Usage:SEEK(file,offset,['Begin' | 'Current' | 'End'])
- Moves to a new position in the given logical file,specified as an offset from
- an anchor position. The default anchor is Current. The returned value is the
- new position relative to the start of the file.
- Examples:
- say seek('input',10,'B') ==>10
- say seek('input',O,'E') ==>356 /* file length */
-
- 63
-
- SETCLIP()
- Usage:SETCLIP(name,[value])
- Adds a name-value pair to the Clip List maintained by the resident process. If
- an entry of the same name already exists,its value is updated to the supplied
- value string. Entries may be removed by specifying a null value. The function
- returns a boolean value that indicates whether the operation was successful.
- Examples:
- say setclip('path','df0:s') ==>1
- say setclip('path') ==>1
-
- SHOW()
- Usage:SHOW(option,[name],[pad])
- Returns the names in the resource list specified by the option argument,or
- tests to see whether an entry with the specified name is available. The
- currently implemented options keywords are Clip,Files,Libraries,and Ports,
- which are described below.
-
- Clip. Examines the names in the Clip List.
- Files. Examines the names of the currently open logical file names.
- Libraries. Examines the names in the Library List,which are either function
- libraries or function hosts.
- Ports. Examine the names in the system Ports List.
-
- If the name argument is omitted,the function returns a string with the resource
- names separated by a blank space or the pad character,if one was supplied. If
- the name argument is given,the returned boolean value indicates whether the
- name was found in the resource list. The name entries are case-sensitive.
-
- SIGN()
- Usage:SIGN(number)
- Returns 1 if the number argument is positive or zero,and -1 if number is
- negative. The argument must be numeric.
- Examples:
- say sign(12) ==>1
- say sign(-33) ==>-1
-
- SPACE()
- Usage:SPACE(string,n,[pad])
- Reformats the string argument so that there are n spaces(blank characters)
- between each pair of words. If the pad character is specified,it is used
- instead of blanks as the separator character. Specifying n as 0 will remove all
- blanks from the string.
- Examples:
- say space('Now is the time',3) ==>'Now is the time'
- say space('Now is the time',0) ==>'Nowisthetime'
- say space('1 2 3',1,'+') ==>'1+2+3'
-
- 64
-
- STORAGE()
- Usage:STORAGE([address],[string],[length],[pad])
- Calling STORAGE()with no arguments returns the available system memory. If the
- address argument is given,it must be a 4-byte string,and the function copies
- data from the(optional)string into the indicated memory area. The length
- parameter specifies the maximum number of bytes to be copied,and defaults to
- the length of the string. If the specified length is longer than the string,the
- remaining area is filled with the pad character or nulls('00'x.)
-
- The returned value is the previous contents of the memory area. This can be
- used in a subsequent call to restore the original contents.
-
- Caution is advised in using this function. Any area of memory can be
- overwritten,possibly causing a system crash. Task switching is forbidden while
- the copy is being done,so system performance may be degraded if long strings
- are copied.
- See Also:EXPORT()
- Examples:
- say storage() ==>248400
- oldval = storage('0004 000'x,'The answer')
- call storage '0004 0000'x,,32,'+'
-
- STRIP()
- Usage:STRIP(string,[{'B' | 'L' | 'T'}],[pad])
- If neither of the optional parameters is supplied,the function removes both
- leading and trailing blanks from the string argument. The second argument
- specifies whether Leading,Trailing,or Both(leading and trailing)characters are
- to be removed. The optional pad(or unpad,perhaps)argument selects the character
- to be removed.
- Examples:
- say strip(' say what? ') ==>'say what?'
- say strip(' say what? ','L') ==>'say what? '
- say strip('++123+++','B','+') ==>'123'
-
- SUBSTR()
- Usage:SUBSTR(string,start,[length],[pad])
- Returns the substring of the string argument beginning at the specified start
- position for the specified length. The starting position must be positive,and
- the default length is the remaining length of the string. If the substring is
- shorter than the requested length,it is padded on the left with the blanks or
- the specified pad character.
- Examples:
- say substr('23456',4,2) ==>45
- say substr('myname',3,6,'=') ==>name==
-
- 65
-
- SUBWORD()
- Usage:SUBWORD(string,n,[length])
- Returns the substring of the string argument beginning with the nth word for
- the specified length in words. The default length is the remaining length of
- the string. The returned string will never have leading or trailing blanks.
- Example:
- say subword('Now is the time ',2,2) ==>is the
-
- SYMBOL()
- Usage:SYMBOL(name)
- Tests whether the name argument is a valid REXX symbol. If the name is not a
- valid symbol,the function returns the string BAD. Otherwise,the returned string
- is LIT if the symbol is uninitialized and VAR if it has been assigned a value.
- Examples:
- say symbol('J') ==>VAR
- say symbol('x') ==>LIT
- say symbol('++') -->BAD
-
- TIME()
- Usage:TIME(option)
- Returns the current system time or controls the internal elapsed time counter.
- The valid option keywords are listed below.
-
- Table 6.2 TIME()Options
-
- OPTION KEYWORD DESCRIPTION
- Elapsed Elapsed time in seconds.
- Hours Current time in hours since midnight
- Minutes Current time in minutes since midnight
- Reset Reset the elapsed time clock
- Seconds Current time in seconds since midnight
-
- If no option is specified,the function returns the current system time in the
- form HH:MM:SS.
- Examples:
- /* Suppose that the time is 1:02 AM ... */
- say time('Hours') ==>1
- say time('m') ==>62
- say time('S') ==>3720
- call time 'R' /* reset timer */
- say time('E') ==>.020
-
- 66
-
- TRACE()
- Usage:TRACE(option)
- Sets the tracing mode to that specified by the option keyword,which must be one
- of the valid alphabetic or prefix options. The tracing options are described in
- Chapter 7. The TRACE()function will alter the tracing mode even during
- interactive tracing,when TRACE instructions in the source program are ignored.
- The returned value is the mode in effect before the function call;this allows
- the previous trace mode to be restored later.
- Example:
- /* Assume tracing mode is ?AL */
- say trace('Results') ==>?A
-
- TRANSLATE()
- Usage:TRANSLATE(string,[output],[input],[pad])
- This function constructs a translation table and uses it to replace selected
- characters in the argument string. If only the string argument is given,it is
- translated to uppercase. If an input table is supplied,it modifies the
- translation table so that characters in the argument string that occur in the
- input table are replaced with the corresponding character in the output table.
- Characters beyond the end of the output table are replaced with the specified
- pad character or a blank.
-
- Note that the result string is always of the same length as the original
- string. The input and output tables may be of any length.
- Examples:
- say translate("abcde","123","cbade","+") ==>321++
- say translate("low") ==>LOW
- say translate("0110","10","01") ==>1001
-
- TRIM()
- Usage:TRIM(string)
- Removes trailing blanks from the string argument.
- Example:
- say length(trim(' abc ')) ==>4
-
- UPPER()
- Usage:UPPER(string)
- Translates the strip to uppercase. The action of this function is equivalent to
- that of TRANSLATE(string),but it is slightly faster for short strings.
- Example:
- say upper('One Fine Day') ==>ONE FINE DAY
-
- 67
-
- VALUE()
- Usage:VALUE(name)
- Returns the value of the symbol represented by the name argument.
- Example:
- /* Assume that J has the value of 12 */
- say value('j') ==>12
-
- VERIFY()
- Usage:VERIFY(string,list,['Match'])
- If the Match argument is omitted,the function returns the index of the first
- character in the string argument which is not contained in the list argument,or
- 0 if all of the characters are in the list. If the Match keyword is supplied,
- the function returns the index of the first character which is in the list,or 0
- if none of the characters are.
- Examples:
- say verify('123456','0123456789') ==>0
- say verify('123a56','0123456789') ==>4
- say verify('123a45','abcdefghij','m') ==>4
-
- WORD()
- Usage:WORD(string,n)
- Returns the nth word in the string argument,or the null string if there are
- fewer than n words.
- Example:
- say word('Now is the time ',2) ==>is
-
- WORDINDEX()
- Usage:WORINDEX(string,n)
- Returns the starting position of the nth word in the argument string,or 0 if
- there are fewer than n words.
- Example:
- say wordindex('Now is the time ',3) ==>8
-
- WORDLENGTH()
- Usage:WORDLENGTH(string,n)
- Returns the length of the nth word in the string argument.
- Example:
- say wordlength('one two three',3) ==>5
-
- 68
-
- WORDS()
- Usage:WORDS(string)
- Returns the number of words in the string argument.
- Example:
- say words("You don't say!") ==>3
-
- WRITECH()
- Usage:WRITECH(file,string)
- Writes the string argument to the given logical file. The returned value is the
- actual number of characters written.
- Example:
- say writech('output','Testing') ==>7
-
- WRITELN()
- Usage:WRITELN(file,string)
- Writes the string argument to the given logical file with a "newline" appended.
- The returned value is the actual number of characters written.
- Example:
- say writeln('output','Testing') ==>8
-
- X2C()
- Usage:X2C(string)
- Converts a string of hex digits into the(packed)character representation. Blank
- characters are permitted in the argument string at byte boundaries.
- Examples:
- say x2c('12ab') ==>'12ab'x
- say x2c('12 ab') ==>'12ab'x
-
- XRANGE()
- Usage:XRANGE([start],[end])
- Generates a string consisting of all characters numerically between the
- specified start and end values. The default start character is '00'x,and the
- default end character is 'FF'x. Only the first character of the start and end
- arguments is significant.
- Examples:
- say xrange() ==>'00010203 ... FDFEFF'x
- say xrange('a','f') ==>'abcdef'
- say xrange(,'10'x) ==>'00010203040506070809010'x
-
- 69
-
- CHAPTER 7 TRACING AND INTERRUPTS
-
- ARexx provides tracing and source-level debugging facilities that are unusual
- in a high-level language. Tracing refers to the ability to display selected
- statements in a program as the program executes. When a clause is traced,its
- line number,source text,and related information are displayed on the console.
- The tracing action of the interpreter is determined by a trace option that
- selects which source clauses will be traced,and two modifier flags that control
- command inhibition and interactive tracing.
-
- The internal interrupt system enables an ARexx program to detect certain
- synchronous or asynchronous events and to take special actions when they occur.
- Events such as a syntax error or an external halt request that would normally
- cause the program to exit can instead be trapped so that corrective actions can
- be taken.
-
- 7-1 TRACING OPTIONS
-
- Trace options are sometimes called an alphabetic options,since the keywords
- that select an option can be shortened to one letter for convenience. The
- alphabetic options are:
-
- ALL. All clauses are traced.
- COMMANDS. All command clauses are traced before being sent to the external
- host. Non-zero return codes are displayed on the console.
- ERRORS. Commands that generate a non-zero return code are traced after the
- clause is executed.
- INTERMEDIATES. All clauses are traced,and intermediate results are displayed
- during expression evaluation. These include the values retrieved for variables,
- expanded compound names,and the results of function calls.
- LABELS. All label clauses are traced as they are executed. A label will be
- displayed each time a transfer of control takes place.
- NORMAL. Command clauses will return codes that exceed the current error failure
- level are traced after execution,and an error message is displayed. This is the
- default trace option.
- RESULTS. All clauses are traced before execution,and the final result of each
- expression is displayed. Values assigned to variables by ARG,PARSE,or PULL
- instructions are also displayed.
- SCAN. This is a special option that traces all clauses and checks for errors,
- but suppresses the actual execution of the statements. It is helpful as a
- preliminary screening steop for a newly-created program.
-
- The tracing mode can be set using either the TRACE instruction or the TRACE()
- Built-In function. The RESULTS trace option is recommended for general-purpose
- testing. Tracing can be selectively disabled from within a program so that
- previously-tested parts of a program can be skipped.
-
- 71
-
- 7-2 DISPLAY FORMATTING
-
- Each trace line displayed on the console is indented to show the effective
- control(nesting)level at that clause,and is identified by a special three-
- character code,as shown in Table 7.1 below. The source for each clause is
- preceded by its line number in the program. Expression results or intermediates
- are enclosed in double quotes so that leading and trailing blanks will be
- apparent.
-
- TABLE 7.1 TRACING PREFIX CODES
-
- CODE DISPLAYED VALUES
- +++ Command or syntax error
- >C> Expanded compound name
- >F> Result of a function call
- >L> Label clause
- >O> Result of a dyadic operation
- >P> Result of a prefix operation
- >U> Uninitialized variable
- >V> Value of a variable
- >>> Expression or template result
- >.> "Placeholder" token value
-
- TRACING OUTPUT
-
- The tracing output from a program is always directed to one of two logical
- streams. The interpreter first checks for a stream named STDERR,and directs the
- output there if the steam exists. Otherwise the trace output goes to the
- standard output stream STDOUT and will be interleaved with the normal console
- output of the program. The STDERR and STDOUT streams can be opened and closed
- under program control,so the programmer has complete control over the
- destination of tracing output.
-
- In some cases a program may not have a predefined output stream. For example,a
- program invoked from a host application that did not provide input and output
- streams would not have an output console. To provide a tracing facility for
- such programs,the resident process can open a special global tracing console
- for use by any active program. When this console opens,the interpreter
- automatically opens a stream named STDERR for each ARexx program in which
- STDERR is not currently defined,and the program then diverts its tracing output
- to the new stream.
-
- The global console can be opened and closed using the command utilities too and
- tcc,respectively. The console may not close immediately upon request,however.
- The resident process waits until all active programs have diverted their
- tracing streams back to the default state before actually closing the console.
- Applications programs may provide direct control over the tracing console by
- sending request packets to the resident process,which is discussed in Chapter
- 10.
-
- The trace stream(STDERR or STDOUT)is also used for trace input,so a program in
- interactive tracing mode will wait for user input from this console. The global
- tracing console is always shared among all currently active programs. Since it
- may be confusing to have several programs simultaneously writing to the same
- console,it is recommended that only one program at a time be traced using the
- global console.
-
- 72
-
- COMMAND INHIBITION
-
- ARexx provides a tracing mode called command inhibition that suppresses host
- commands. In this mode command clauses are evaluated in the normal manner,but
- the command is not actually sent to the external host,and the return code is
- set to zero. This provides a way to test programs that issue potentially
- destructive commands,such as erasing files or formatting disks. Command
- inhibition does not apply to command clauses that are entered interactively.
- These commands are always performed,but the value of the special variable RC is
- left unchanged.
-
- Command inhibition may be used in conjunction with any trace option. It is
- controlled by the "!" character,which may appear by itself or may precede any
- of the alphabetic options in a TRACE instruction. Each occurrence of the "!"
- character "toggles" the inhibition mode currently in effect. Command inhibition
- is cleared when tracing is set to OFF.
-
- 7-3 INTERACTIVE TRACING
-
- Interactive tracing is a debugging facility that allows the user to enter
- source statements while a program is executing. These statements may be used to
- examine or modify variable values,issue commands,or otherwise interact with the
- program. Any valid language statements can be entered interactively,with the
- same rules and restrictions that apply to the INTERPRET instruction. In
- particular,compound statements such as DO and SELECT must be complete within
- the entered line.
-
- Interactive tracing can be used with any of the trace options. While in
- interactive tracing mode,the interpreter pauses after each traced clause and
- prompts for input with the code "+++." At each pause,three types of user
- responses are possible.
-
- If a null line is entered,the program continues to the next pause
- point.
- If an "=" character is entered,the preceding clause is executed again.
- Any other input is treated as a debugging statement,and is scanned and
- executed.
-
- The pause points during interactive tracing are determined by the tracing
- option currently in effect,as the interpreter pauses only after a traced
- clause. However,certain instructions cannot be safely(or sensibly)re-executed,
- so the interpreter will not pause after executing one of these. The "no-pause"
- instructions are CALL,DO,ELSE,IF,THEN,and OTHERWISE. The interpreter will also
- not pause after any clause that generate and execution error.
-
- Interactive tracing mode is controlled by the "?" character,either by itself or
- in combination with an alphabetic trace option. Any number of "?" characters
- may precede an option,and each occurrence toggles the mode currently in effect.
- For example,if the current trace option was NORMAL,then "TRACE ?R" would set
- the option to RESULTS and select interactive tracing mode. A subsequent "TRACE
- ?" would turn off interactive tracing.
-
- 73
-
- ERROR PROCESSING
-
- The ARexx interpreter provides special error processing while it executes
- debugging statements. Errors that occur during interactive debugging are
- reported,but do not cause the program to terminate. This special processing
- applies only to the statements that were entered interactively. Errors occuring
- in the program source statements are treated in the usual way whether or not
- the interpreter is in interactive tracing mode.
-
- In addition to the special error processing,the interpreter also disables the
- internal interrupt flags during interactive debugging. This is necessary to
- prevent an accidental transfer of control due to an error or uninitialized
- variable. However,if a "SIGNAL label" instruction is entered,the transfer will
- take place,and any remaining interactive input will be abandoned. The SIGNAL
- instruction can still be used to alter the interrupt flags,and the new settings
- will take effect when the interpreter returns to normal processing.
-
- THE EXTERNAL TRACING FLAG
-
- The ARexx resident process maintains an external tracing flag that can be used
- to force programs into interactive tracing mode. The tracing flag can be set
- using the ts command utility. When the flag is set,any program not already in
- interactive tracing mode will enter it immediately. The internal trace option
- is set to RESULTS unless it is currently set to INTERMEDIATES or SCAN,in which
- case it remains unchanged. Programs invoked while the external tracing flag is
- set will begin executing in interactive tracing mode.
-
- The external tracing flag provides a way to regain control over programs that
- are caught in loops or are otherwise unresponsive. Once a program enters
- interactive tracing mode,the user can step through the program statements and
- diagnose the problem. There is one caveat,though:external tracing is global
- flag,so all currently-active programs are affected by it. The tracing flag
- remains set until it is cleared using the "te" command utility. Each program
- maintains an internal copy of the last state of the tracing flag,and sets its
- tracing option to OFF when it observes that the tracing flag has been cleared.
-
- 7-4 INTERRUPTS
-
- ARexx maintains an internal interrupt system that can be used to detect and
- trap certain error conditions. When an interrupt is enabled and its
- corresponding condition arises,a transfer of control to the label specific to
- that interrupt occurs. This allows a program to retain control in circumstances
- that might otherwise cause the program to terminate. The interrupt conditions
- can caused by either synchronous events like a syntax error,or asynchronous
- events like a "control-C" break request. Note that these internal interrupts
- are completely separate from the hardware interrupt system managed by the EXEC
- operating system.
-
- The interrupts supported by ARexx are described below. The name assigned to
- each is actually the label to which control will be tranferred. Thus,a SYNTAX
- interrupt will transfer control to the label "SYNTAX:." Interrupts can be
- enabled or disabled using the SIGNAL instruction. For example,the instruction
- "SIGNAL ON SYNTAX" would enable the SYNTAX interrupt.
-
- 74
-
- BREAK_C. This interrupt will trap a control-C break request generated by DOS.
- If the interrupt is not enabled,the program terminates immediately with the
- error message "Execution halted" and returns with the error code set to 2.
-
- BREAK_D. The interrupt will detect and trap a control-D break request issued by
- DOS. The break request is ignored if the interrupt is not enabled.
-
- BREAK_E. The interrupt will detect and trap a control-E break request issued by
- DOS. The break request is ignored if the interrupt is not enabled.
-
- BREAK_F. The interrupt will detect and trap a control-F break request issued by
- DOS. The break request is ignored if the interrupt is not enabled.
-
- ERROR. This interrupt is generated by any host command that returns a non-zero
- code.
-
- HALT. An external halt request will be trapped if this interrupt is enabled.
- Otherwise,the program terminates immediately with the error message "Execution
- halted" and returns with the error code set to 2.
-
- IOERR. Errors detected by the I/O system will be trapped if this interrupt is
- enabled.
-
- NOVALUE. An interrupt will occur if an uninitialized variable is used while
- this condition is enabled. The usage could be within an expression,in the UPPER
- instruction,or with the VALUE()built-in function.
-
- SYNTAX. A syntax or execution error will generate this interrupt. Not all
- errors such errors can be trapped,however. In particular,certain errors
- occurring before a program is actually executing,and those detected by the
- ARexx external interface,cannot be trapped by the SYNTAX interrupt.
-
- When an interrupt forces a transfer of control,all of the currently active
- control ranges are dismantled,and the interrupt that caused the transfer is
- disabled. This latter action is necessary to prevent a possible recursive
- interrupt loop. Only the control structures in the current environment are
- affected,so an interrupt generated within a function will not affect the
- caller's environment.
-
- SPECIAL VARIABLES. Two special variables are affected when an interrupt occurs.
- The variable SIGL is always set to the current line number before the transfer
- of control takes place,so that the program can determine which source line was
- being executed. When an ERROR or SYNTAX interrupt occurs,the variable RC is set
- to the error code that caused the condition. For ERROR interrupts this value
- will be a command return code,and can usually be interpreted as an error
- severity level. The value for SYNTAX interrupts is always an ARexx error code.
-
- Interrupts are useful primarily to allow a program to take special
- error-recovery actions. Such actions might involve informing external programs
- that an error ocurred,or simply reporting further diagnostics to help in
- isolating the problem. In the following example,the program issues a "message"
- command to an external host called "MyEdit" whenever a syntax error is
- detected:
-
- 75
-
- /* A macro program for 'MyEdit' */
- signal on syntax /* enable interrupt */
- .
- . (normal processing)
- .
- exit
- syntax: /* syntax error detected*/
- address 'MyEdit'
- 'message' 'error' rc errortext(rc)
- exit 10
-
- 76
-
- CHAPTER 8 PARSING AND TEMPLATES
-
- Parsing is a operation that extracts substrings from a string and assigns them
- to variables. It corresponds roughly to the notion of a "formatted read" used
- in other languages,but has been generalized in the several ways. Parsing is
- performed using the PARSE instruction or its variants ARG and PULL. The input
- for the operation is called the parse string and can come from several sources;
- these source options are described with the PARSE instruction in Chapter 4.
-
- Parsing is controlled by a template,a group of tokens that specifies both the
- variables to be given values and the way to determine the value strings.
- Templates were described briefly with the PARSE instruction;the present chapter
- presents a more formal description of their structure and operation.
-
- 8-1 TEMPLATE STRUCTURE
-
- The tokens that are valid in a template are symbols,strings,operators,
- parentheses,and commas. Any blanks that may be present as separators are
- removed before the template is processed. The tokens in a template ultimately
- serve to specify one of the two basic template objects:
-
- Markers determine a scan position within the parse string,and
- Targets are symbols to be assigned a value.
-
- With these objects in mind,the parsing process can be described as one of
- associating with each target a starting and ending position in the parse
- string. The substring between these positions then becomes the value for the
- target.
-
- MARKETS. There are three types of marker objects:
-
- ABSOLUTE markers specify an actual index position in the parse string,
- RELATIVE markers specify a positive or negative offset from the current
- position,and
- PATTERN markers specify a position implicitly,by matching the pattern against
- the parse string beginning at the current scan position.
-
- TARGETS. Targets,like markers,can affect the scan position if value strings are
- being extracted by tokenization. Parsing by tokenization extracts words(tokens)
- from the parse string, and is used whenever a target is followed immediately
-
- 77
-
- by another target. During tokenization the current scan position is advanced
- past any blanks to the start of the next word. The ending index is the position
- just past the end of the word,so that the value string has neither leading nor
- trailing blanks.
-
- TEMPLATE OBJECTS
-
- Each template object is specified by one or more tokens,which have the
- following interpretations.
-
- SYMBOLS. A symbol token may specify either a target or a marker object. If it
- follows an operator token(+,-,or=),it represents a marker,and the symbol value
- is used as an absolute or relative position. Symbols enclosed in parentheses
- specify pattern markers,and the symbol value is used as the pattern string.
-
- If neither of the preceding cases applies and the symbol is a variable,then it
- specifies a target. Fixed symbols always specify absolute markers and must be
- whole numbers,except for the period(.)symbol which defines a placeholder
- target.
-
- STRINGS. A string token always represents a pattern marker.
-
- PARENTHESES. A symbol enclosed in parentheses is a pattern marker,and the value
- of the symbol is used as the pattern string. While the symbol may be either
- fixed or variable,it will usually be a variable,since a fixed pattern could be
- given more simply as a string.
-
- OPERATORS. The three operators "+,"-,"and "=" are valid within a template,and
- must be followed by a fixed or variable symbol. The value of the symbol is used
- as a marker and must therefore represent a whole number. The "+" and "-"
- operators signify a relative marker,whose value is negated by the "-" operator.
- The "=" operator indicates an absolute marker,and is optional if the marker is
- defined by a fixed symbol.
-
- COMMAS. The comma(,)marks the end of a template,and is used as a separator when
- multiple templates are provided with an instruction. The interpreter obtains a
- new parse string before processing each succeeding template. For some source
- options,the new string will be identical to the previous one. The ARG,EXTERNAL,
- and PULL options will generally supply a different string,as will the VAR
- option if the variable has been modified.
-
- THE SCANNING PROCESS
-
- Scan positions are expressed as an index in the parse string,and can range from
- 1(the start of the string)to the length of the string plus 1(the end). An
- attempt to set the scan position before the start or after the end of the
- string instead sets it to the beginning or end,respectively.
-
- The substring specified by two scan indices includes the characters from the
- starting position up to,but not including,the ending position. For example,the
- indices 1 and 10 specify characters 1-9 in the parse string. One additional
- rule is applied if the second scan index is less than or equal to the first: in
- this case the remainder of the parse string is used as the substring. This
- means that a template specificaiton like
- 78
-
- parse arg 1 all 1 first second
-
- will assign the entire parse string to the variable ALL. Of course,if the
- current scan index is already at the end of the parse string,then the remainder
- is just the null string.
-
- When a pattern marker is matched against the parse string,the marker position
- is the index of the first character of the matched pattern,or the end of the
- string if no match was found. The pattern is removed from the string whenever a
- match is found. This is the only operation that modifies the parse string
- during the parsing process.
-
- Templates are scanned from left to right with the initial scan index set to 1,
- the start of the parse string. The scan position is updated each time a marker
- object is encountered,according to the type and value of the marker. Whenever a
- target object is found,the value to be assigned is determined by examining the
- next template object. If the next object is another target,the value string is
- determined by tokenizing the parse string. Otherwise,the current scan position
- is used as the start of the value string,and the position specified by the
- following marker is used as the end point.
-
- The scan continous until all of the objects in the template have been used.
- Note that every target will be assigned a value;once the parse string has been
- exhausted,the null string is assigned to any remaining targets.
-
- 8-2 TEMPLATES IN ACTION
-
- The preceding section is rather abstract,so let's look now at some examples of
- parsing with templates.
-
- PARSING BY TOKENIZATION
-
- Computer programs frequently require splitting a string into its component
- words or tokens. This is easily accomplished with a template consisting
- entirely of variables(targets).
-
- /* Assume "hammer 1 each $600.00" was entered */
- pull item qty untils cost .
-
- In this example the input line from the PULL instruction is split into words
- and assigned to the variables in the template. The variable item receives the
- value "hammer," qty is set to "1," units is set to "each," and cost gets the
- value "$600.00." The final placeholder(.) is given a null value,since there are
- only four words in the input. However,it forces the preceding variable cost to
- be given a tokenized value. If the placeholder were omitted,the remainder of
- the parse string would be assigned to cost,which would then have a leading
- blank.
-
- In the next example,the first word of a string is removed and the remainder is
- placed back in the string. The process continues until no more words are
- extracted.
-
- 79
-
- /* Assume "result" contains a string of words */
- do forever
- /* Get first word of string */
- parse var result first result
- if first == '' then leave
- /* ... process words ... */
- end
-
- PATTERN PARSING
-
- The next example uses pattern markers to extract the desired fields. The
- "pattern" in this case is very simple -- just a single character -- but in
- general can be an arbitrary string of any length. This form of parsing is
- useful whenever delimiter characters are present in the parse string.
-
- /* Assume an argument string "12,34.5,1 */
- arg hours ',' rate ',' withhold
-
- Keep in mind that the pattern is actually removed from the parse string when a
- match is found. If the parse string is scanned again from the beginning,the
- length and structure of the string may be different than at the start of the
- parsing process. However,the original source of the string is never modified.
-
- POSITIONAL MARKERS
-
- Parsing with positional markers is used whenever the fields of interest are
- known to be in certain positions in a string. In the next example,the records
- being processed contain a variable length field. The starting position and
- length of the field are given in the first part of the record,and a variable
- positional marker is used to extact the desired field.
-
- /* records look like: */
- /* start: 1-5 */
- /* length: 6-10 */
- /* name: @(start,length) */
- parse value record with 1 start +5 length +5 =start name +length
-
- The "=start" sequence in the above example is an absolute marker whose value is
- the position paced in the variable start earlier in the scan. The "+length"
- sequence supplies the effective length of the field.
-
- MULTIPLE TEMPLATES
-
- It is sometimes useful to specify more than one template with an instruction,
- which can be done by separating the templates with a comma. In this next
- example,the ARG instruction(or PARSE UPPER ARG)is used to access the argument
- strings provided when the program was called. Each template accesses the
- succeeding argument string.
-
- 80
-
- /* Assume arguments were ('one two',12,sort) */
- arg first second,amount,action,option
-
- The first template consists of the variables first and second,which are set to
- the values "one" and "two,"respectively. In the next two templates amount gets
- the value "12" and action is set to "SORT". The last template consists of the
- variable "option,"which is set to the null string,since only three arguments
- were available.
-
- When multiple templates are used with the EXTERNAL or PULL source options,each
- additional template requests an additional line of input from the user. In the
- next example two lines of input are read:
-
- /* read last,first,and middle names and ssn */
- pull last ',' first middle,ssn
-
- The first input line is expected to have three words,the first of which is
- followed by a comma,which are assigned to the variables last,first,and middle.
- The entire second input line is assigned to the variable ssn.
-
- Multiple templates can be useful even with a source option that returns the
- identical parse string. If the first template included pattern markers that
- altered the parse string,the subsequent templates could still access the
- original string. Note that subsequent parse strings obtained from the VALUE
- source do not cause the expression to be reevaluated,but only retrieve the
- prior result.
-
- 81
-
- CHAPTER 9 THE RESIDENT PROCESS
-
- This chapter describes some of the capabilities of the ARexx resident process,
- a global communications and resources manager. The material presented here is
- directed to the general user;Chapter 10 covers these topics in greater depth
- for software developers who wish to integrate ARexx with other applications
- programs.
-
- The resident process must be active before any ARexx programs can be run. It
- announces its presence to the system by opening a public message port named
- "REXX,"so applications programs that use ARexx should check for the presence of
- this port. If the port is not open,the user can either be informed that the
- macro processor is not available,or else the applications program can start up
- the resident process. The latter option can be done using the rexxmast command.
-
- The primary function of the resident process is to launch ARexx programs. When
- an applications program sends a "command" or "function" message to the "REXX"
- port,the resident process creates a new DOS process to execute the program, and
- forwards the invocation message to newly created process. It also creates a new
- instance of the ARexx global data structure,which links together all of the
- structures manipulated by the program.
-
- In addition to launching programs,the resident process managers various
- resources used by ARexx. These resources include a list of available function
- libraries called the Library List,a list of(name,value)pairs called the Clip
- List,and a list of the currently active ARexx programs. Built-In functions are
- available to manipulate the Library List and Clip List from within an ARexx
- program. Applications programs can modify a resource list either by sending a
- request packet to the resident process or by direct manipulation of the list.
-
- 9-1 COMMAND UTILITIES
-
- ARexx is supplied with a number of command utilities to provide various control
- functions. These are executable modules that can be run from the CLI,and should
- reside in the system command(C:)directory for convenience. These commands are
- relevant only when the ARexx resident process is active.
-
- The functions performed by these utilities may also be available from within an
- applications program. All of the utilities are implemented by sending message
- packets to the resident process,so an application designed to work closely with
- ARexx could easily provide these functions as part of its control menu.
-
- HI
- Usage:HI
- Sets the global halt flag,which causes all active programs to receive an
- external halt request. Each program will exit immediately unless its HALT
- interrupt has been enabled. The halt flag does not remain set,but is cleared
- automatically after all current programs have received the request.
-
- 83
-
- RX
- Usage:RX name[arguments]
- This command launches an ARexx program. If the specified name includes an
- explicit path,only that directory is searched for the program;otherwise,the
- current directory and the system REXX: device are checked for a program with
- the given name. The optional argument string is passed to the program.
-
- RXSET
- Usage:RXSET name value
- Adds a(name,value)pair to the Clip List. Name strings are assumed to be in
- mixed case. If a pair with the same name already exists,its value is replaced
- with the current string. If a name without a value string is given,the entry is
- removed from the Clip List.
-
- RXC
- Usage:RXC
- Closes the resident process. The "REXX" public port is withdrawn immediately,
- and the resident process exits as soon as the last ARexx program finishes. No
- new programs can be launched after a "close" request.
-
- TCC
- Usage:TCC
- Closes the global tracing console as soon as all active programs are no longer
- using it. All read read requests queued to the console must be satisfied before
- it can be closed.
-
- TCO
- Usage:TCO
- Open the global tracing console. The tracing output from all active programs is
- diverted automatically to the new console. The console window can be moved and
- resized by the user,and can be closed with the "TCC" command.
-
- TE
- Usage:TE
- Clears the global tracing flag,which forces the tracing mode to OFF for all
- active ARexx programs.
-
- TS
- Usage:TS
- Starts interactive tracing by setting the external trace flag,which forces all
- active ARexx programs into interactive tracing mode. Programs will start
- producing trace output and will pause after the next statement. This command is
- useful for regaining control over programs caught in infinite loops or
- otherwise misbehaving. The trace flag remains set until cleared by the TE
- command,so subsequent program invocations will begin executing in interactive
- tracing mode.
-
- 84
-
- 9-2 RESOURCE MANAGEMENT
-
- Individual ARexx programs manage their internal memory allocation and I/O file
- resources,but some resources need to be available to all programs. The
- management of these global resources is one of the major functions of the
- resident process. Global resources are maintained as doubly-linked lists,in
- keeping with the general design principles of the EXEC operating system. Linked
- lists provide a flexible and open mechanism for resource management,and help
- avoid the built-in limits common with other approaches.
-
- THE GLOBAL TRACING CONSOLE
-
- The tracing output from an ARexx program usually goes to the standard output
- stream STDOUT,and is therefore interleaved with the normal output of the
- program. Since this may be confusing at times,a global trace console can be
- opened to display only tracing output. The console can be opened using the tco
- command utility or be sending an RXTCOPN request packet to the resident
- process. ARexx programs will automatically divert their tracing output to the
- new window,which is opened as a standard AmigaDOS console. The user can move it
- and resize it as required.
-
- The tracing console also serves as the input stream for programs during
- interactive tracing. When a program pauses for tracing input,the input line
- must be entered at the trace console. Any number of programs may use the
- tracing console simultaneously,although it is generally recommended that only
- one program at a time be traced.
-
- The tracing console can be closed using the tcc command or by sending an
- RXTCCLS request packet to the resident process. The closing is delayed until
- all read requests to the console have been satisfied. Only when all of the
- active programs indicate that they are no longer using the console will it
- actually be closed.
-
- THE LIBRARY LIST
-
- The resident process maintains a Library List of the function libraries and
- function hosts currently available to ARexx programs. This list is used to
- resolve all references to external functions. Each entry has an associated
- search priority in the range 100 to -100,with the higher-valued entries being
- searched first until the requested function is found. The list is searched by
- calling each entry,using the appropriate protocol,until the return code
- indicates that the function was found.
-
- The two types of entities maintained by the list are quite different in some
- respects,but the ultimate way in which a function call is resolved is
- transparent to the calling program. A function library is a collection of
- functions organized as an Amiga shared library,while a function host is a
- separate task that manages a message port. Function libraries are called as
- part of the ARexx interpreter's task context,but calls to function hosts are
- mediated by passing a message packet. The ARexx resident process is itself a
- function host,and is installed in the Library List at a priority of -60.
-
- The resident process provides addition and deletion operations for maintaining
- the Library List;these operations are performed by sending an appropriate
- message packet. The Library List is always maintained in priority order. Within
- a given priority level any new entries are added to the end of the chain, so
- that entries added first will be searched fist. The priority levels are
-
- 85
-
- significant if any of the libraries have duplicate function name
- definitions,since the function located further down the search chain could
- never be called.
-
- FUNCTION LIBRARIES. Each function library entry in the Library List contains a
- library name,a search priority,an entry point offset,and a version number. The
- library name must refer to a standard Amiga shared library residing in the
- system LIBS: directory so that it can be loaded when needed. Function libraries
- can be created and maintained by users or applications developers;Chapter 10
- has information on their design and implementation.
-
- The "query" function is the library entry point that is actually called by the
- interpreter. It must be specified as an integer offset(e.g. "-30")from the
- library base. The return code from the query call then indicates whether the
- desired function was found;it it was,the function is called with the parameters
- passed by the interpreter and the function result is returned to the caller.
- Otherwise,the search continues with the next entry in the list. In either event
- the library is closed to await the next call.
-
- A note of caution: not every Amiga shared library can be used as a function
- library. Function libraries must have a special entry point to perform the
- dynamic linking required to access the functions from within ARexx. Each
- library should include documentation providing its version number and the
- integer offset to its "query" entry point.
-
- FUNCITON HOSTS. The name associated with a function host is the name of its
- public message port. Function calls are passed to the host as a message packet;
- it is then up to the individual host to determine whether the specified
- function name is one that it recognizes. The name resolution is completely
- internal to the host,so function hosts provide a natural gateway mechanism for
- implementing remote procedure calls to other machines in a network.
-
- THE CLIP LIST
-
- The Clip List maintains a set of(name,value)pairs that may be used for a
- variety of purposes. Each entry in the list consists of a name and a value
- string,and may be located by name. Since the Clip List is publicly accessible,
- it may be used as a general clipboard-like mechanism for intertask
- communication. In general,the names used should be chosen to be unique to an
- application to prevent collisions with other programs. Any number of entries
- may be posted to the list.
-
- One potential application for the Clip List is as a mechanism for loading
- predefined constants into an ARexx program. The language definition does not
- include a facility comparable to the "header file" preprocessor in the "C"
- language. However,consider a string in the Clip List of the form
-
- pi=3.14159; e=2.718; sqrt2=1.414 ...
-
- i.e.,a series of assignments separated by semicolons. In use,such a string
- could be retrieved by name using the Built-In function GETCLIP()and then
- INTERPRETed within the program. The assignment statements within the string
- would then create the required constant definitions. The following program
- fragment illustrates the process::
-
- 86
-
- /* assume a string called "numbers" is available*/
- numbers=getclip('numbers') /* case-sensitive */
- interpret numbers /* ... assignments*/
- ...
-
- More generally,the strings would not be restricted to contain only assignment
- statements,but could include any valid ARexx statements. The Clip List could
- thus provide a series of programs for initializations or other processing
- tasks.
-
- The resident process supports addition and deletion operations for maintaining
- the Clip List. The names in the(name,value)pairs are assumed to be in mixed
- cases,and are maintained to be unique in the list. An attempt to add a string
- with an existing name will simply update the value string. The name and value
- strings are copied when an entry is posted to the list,so the program that adds
- an entry is not required to maintain the strings.
-
- Entries posted to the Clip List remain available until explicitly removed. The
- Clip List is automatically released when the resident process exits.
-
- 87
-
- CHAPTER 10 INTERFACING TO AREXX
-
- This chapter discusses the issues involved in designing and implementing an
- interface between ARexx and an external applications program. The material
- presented here is directed to software developers,so a high degree of
- familiarity with programming the Amiga in either "C" or assembly-language is
- assumed.
-
- ARexx can interact with external programs in several ways. The command
- interface is used to communicate with an external program running as a separate
- task in the Amiga's multitasking environment. The interaction takes place by
- passing messages between public message ports,and is in many ways similar to
- the interaction of a program with Intution,the Amiga's window and menu manager.
- The command interface provides both a means of sharing data and a method of
- controlling an applications program.
-
- Function libraries provide a mechanism for calling external code as part of an
- ARexx program's tasks context. The linkages for such calls are established
- dynamically at run time rather than when the program is linked,so each function
- library must include an entry point to match function names with the address of
- the function to be called.
-
- Function hosts are external tasks that manage a public message port for
- communicating with ARexx or other programs. Both function hosts and function
- libraries are managed by the Library List,which provides a prioritized search
- mechanism for resolving function names. Function hosts may be used as a gateway
- into a metwork to provide a remote procedure call facility. ARexx imposes no
- constraints on the internal operations of a function host,except to require
- that message packets be returned with an appropriate code.
-
- The resident process acts as the hub for communications between ARexx and
- external entities. It opens and manages a public message port named "REXX," and
- provides a number of support services. Note that the resident process is itself
- a "host application" whose function it is to launch ARexx programs and maintain
- global resources. The activation structures for all ARexx programs are linked
- into a list maintained by the resident process,and in principle their compete
- internal states are accessible to external programs.
-
- The ARexx interpreter is structured as an Amiga shared library and includes
- entry points specifically designed to help implement an interface to ARexx.
- Functions are available to create and delete message packets,argument
- strings,and other resources. Software developers are rged to use these library
- routines whenever possible,as they provide "safe" access to the internal
- structures. The ARexx Systems Library functions are documented in Appendix C.
- The distribution disk contains the INCLUDE files required to required to work
- with the library and data structures.
-
- 89
-
- 10-1 BASIC STRUCTURES
-
- Most developers will need to work with only two of the data structures used by
- ARexx. The RexxArg structure is used for all of the strings manipulated by the
- interpreter. It is usually passed as an argstring,a pointer offset from the
- structure base that may be treated like an ordinary string pointer. The RexxMsg
- structure is an extension of an EXEC Message,and is the message packet used for
- all communications with external programs.
-
- ARGSTRINGS. All ARexx strings are maintained as RexxArg structures,which are
- diagrammed in Table 10.1 below. Note that his actually a variable-length
- structure allocated for each specific string length. String parameters are sent
- in the form of argstrings,a pointer to the string buffer area of the RexxArg
- structure. The string in the stucture is always given a trailing null byte,so
- that external programs can treat argstrings like a pointer to a null-terminated
- string. Additional data about the string(its length,hash code,and attributes)
- are available at negative offsets from the argstring pointer.
-
- Table 10.1 The RexxArg Structure
-
- STRUCTURE RexxArg,0
- LONG ra_Size ; allocated length
- UWORD ra_Length ; length of string
- UBYTE ra_Flags ; attribute flags
- UBYTE ra_Hash ; hash code
- STRUCT ra_Buff,8 ; buffer (argstring points here)
-
- Library functions are available to create and delete argstrings,and for
- converting integers into argstring format. The function CreateArgstring()
- allocates a structure and copies a string into it,and returns an argstring
- pointer to the structure. The function DeleteArgstring()can be used to release
- an argstring when it is no longer needed.
-
- MESSAGE PACKETS. All communications between ARexx and external programs are
- mediated with with message packets,whose structure is diagrammed in Table 10.2
- below. Functions are provided in the ARexx Systems Library to create,
- initialize,and delete these message packets. Each packet sent from ARexx to an
- external program is marked with a special pointer in its name field. This can
- be used to distinguish the message packets from those belonging to other
- programs,in case a message port is being shared.
-
- Message packets are created using the CreateRexxMsg()function,and can be
- released using the DeleteRexxMsg(). Note that the message packets passed by
- ARexx to a host application(as a command,for instance)are identical to the
- packets the host would use to invoke an ARexx program. This commonality of
- design means that only one set of functions is needed to create and delete
- message packets,and that external programs can use the same routines that the
- interpreter uses to handle the packets.
-
- RESOURCE NODES. A somewhat higher-level data structure called a "resource node"
- (a RexxRsrc structure)is used extensively within ARexx to maintain resource
- lists. These nodes are variable-length structures that include the total
- allocated length as a field within the node,and that also provide for an
- "auto-delete" function. This latter capability allows the address of a clean-up
-
- 90
-
- function to be associated with the node so that an entire(possibly
- inhomogeneous)list of resource nodes can be deallocated with a single function
- call.
-
- Table 10.2 The RexxMsg Structures
-
- STRUCTURE RexxMsg,MN_SIZE
- APTR rm_TaskBlock ; global pointer
- APTR rm_LibBase ; library pointer
- LONG rm_Action ; command code
- LONG rm_Result1 ; primary result
- LONG rm_Result2 ; secondary result
- STRUCT rm_Args,16*4 ; arguments (ARGO-ARG15)
- ; the extension area
- APTR rm_PassPort ; forwarding port
- APTR rm_CommAddr ; host address
- APTR rm_FileExt ; file extention
- LONG rm_Stdin ; input stream
- LONG rm_Stdout ; output steam
- LONG rm_avail ; reserved
- LABEL rm_SIZEOF ; 128 bytes
-
- 10-2 DESIGNING A COMMAND INTERFACE
-
- The minimal command interface between ARexx and an applications program
- requires only a public message port and a routine to process the commands
- received. For most host applications this will require little extra machinery,
- as the program will probably already have several message ports for key and
- menu events,timer messages,and so on. Processing the command strings should be
- relatively straightforward for command-oriented applications. Hosts that are
- entirely menu-driven will require somewhat more additional programming,unless
- commands are supported only as simulated menu events. The specific choice of
- which commands to support is always left up to the applications designer,as
- ARexx imposes no restrictions on the structure of the commands that can be
- issued.
-
- The basic sequence of events in the command interface begins when the host
- sends a command invocation message to the ARexx resident process. This is
- usually in response primitives supported by the host. When the resident process
- receives the message packet,it spawns a new DOS process the run the macro
- program. The command line is parsed to extract the command token(the first
- word),and the interpreter searches for a file that matches the command name.
-
- Once a macro program file has been found,it is executed by the interpreter and
- (usually)results in one or more commands being issued back to the host
- application's public port. The macro program waits while each command is
- processed by the host,and takes appropriate actions if the return code
- indicates that an error occurred. Eventually the macro program finishes and
- returns the invocation message packet back to the host.
-
- Error handling is an important consideration in the interface design. Macro
- programs must receive return codes so that processing actions can be altered
- when errors occur.
-
- 91
-
- Normally,the host application should not return a message packet until the
- command has been processed and its error status in known. Hosts that support
- two streams of commands(from the user and from the command interface)will need
- a flag to indicate the source of each command. Errors in user commands might
- normally be reported on the screen,but errors in ARexx commands must be
- reported by setting the result field in the message packet.
-
- Return codes should generally be chosen to follow the model of an error
- severity level,with small integers representing relatively harmless conditions
- and larger values indicating progressively more severe errors. This will allow
- a characteristic failure level to be established within a macro program,so that
- insignificant errors can be ignored. The choice of the specific return code
- values is left to the applications designer.
-
- RECEIVING COMMAND MESSAGES
-
- Each host application must open a public message port to support the command
- interface. When a macro program issues a command to the host,a message packet
- containing the command is sent to this public port. The structure of these
- message packets is shown in Table 10.2. The rm_Action field will be set to
- RXCOMM,and the ARGO parameter slot will contain the command as an argstring
- pointer. Parameter slots ARG1-ARG15 are not used for command messages. Two
- other fields are potentially of interest: the rm_RexxTask field contains a
- pointer to the global data structure for the program that issued the command,
- and the rm_LibBase field has the ARexx library base address. The fields in the
- extension area may also be of interest to the host program;these are described
- later on. Except for setting the result fields rm_Result1 and rm_Result2,the
- host application should not alter the message packet.
-
- RESULT FIELDS
-
- When the host program finishes processing the command,it must set the primary
- result field rm_Result1 to an error severity level or zero if no errors
- occurred. This is the field which will be assigned to the special variable RC
- in the macro program. The secondary result field rm_Result2 should be set to
- zero unless a result string(as described below)is being returned. The packet
- can then be returned to the sender using the EXEC function ReplyMsg().
-
- In some cases a macro program may request a result string by setting the
- RXFB_RESULT modifier bit in the command code. If possible,the host application
- should then return the result as an argstring pointer in the secondary result
- field rm-Result2. A result string should only be returned if explicitly
- requested and if no errors occurred during the call(rm_Result1 set to zero).
- Failure to observe these rules will result either in memory loss or in
- corruption of the system free-memory list.
-
- MULTIPLE HOST PROCESSES
-
- Many applications programs support concurrent activities on several sets of
- data. For example,most text editors allow several files to be edited at once. A
- command issued from a particular instance of the editor might invoke an ARexx
- macro program,so clearly any commands issued from that macro would have to be
- directed to the correct instance of the editor. ARexx provides for this by
-
- 92
-
- allowing the applications program to declare an initial host address when a
- program is invoked. A separate message port would be opened for each instance
- of the host application,and this port would be named as the initial host
- address for all invocations from that instance. In the example above,if the
- editor opened two ports named "MyEdit1" and "MyEdit2,"then programs invoked by
- the "MyEdit1" instance would send commands back to the "MyEdit1" port.
-
- MULTIPLE MESSAGE PORTS. Host applications are not limited to having a single
- message port for commands. If several different kinds of commands are to be
- received,it might be appropriate to set up more than one port. Macro programs
- would then use the ADDRESS instruction to direct commands to the appropriate
- port. The different ports could be used simultaneously,since ARexx programs
- execute as separate tasks.
-
- 10-3 INVOKING AREXX PROGRAMS
-
- ARexx programs are invoked by sending a message packet to the resident process.
- Programs may be invoked as either a command or as a function. The command mode
- of invocation is generally simpler,as it requires setting only a few fields in
- the message packet.
-
- MESSAGE PACKETS
-
- The structure of the message packet supported by ARexx is shown in Table 10.2.
- This structure provides fields for passing arguments and for specifying
- overrides to various internal defaults. The packets are cleared(set to 0)when
- allocated,and the client-supplied fields are never altered by ARexx. Message
- packets can be reused after being returned,and generally only one is required.
-
- COMMAND(ACTION)CODE. The rm_Action field of the message packet determines the
- mode of invocation. It can be set to either RXCOMM or RXFUNC for command or
- function mode,respectively. Several modifier flags can be used with the command
- code;these are described later in this chapter.
-
- ARGUMENT STRINGS. Command strings,function names,and argument strings must be
- supplied as argstrings. Strings can be conveniently packaged into argstrings
- using the CreateArgstring()library function,which takes a string pointer and a
- length as its arguments. Argstrings point to a null-terminated string and may
- be treated like an ordinary string pointer in most cases. In principle,a host
- application could build the argstrings directly,but since the strings must
- remain unchanged for the duration of a ARexx program,the host might need to
- maintain many such structures.
-
- The argstrng pointer returned by CreateArgstring()is installed in the
- appropriate parameter slot of the message package:ARGO for the command string
- or function name,and ARG1-ARG15 for argument strings. Argstrings can be
- recycled after a packet has returned by calling the DeleteArgstring() function.
-
- SENDING THE PACKET. Once the required fields have been filled in,the host
- application can send the packet to the "REXX" public port using the EXEC
- function PutMsg(). The address of the "REXX" port can be obtained by a call to
- the FindPort()function,but this address should not be cached internally,since
- the port could close at any time. To be absolutely safe,the calls to FindPort()
- and PutMsg()should be bracketed by calls to the EXEC routines Forbid()and
- Permit(). This will exclude the slight possibility that the message port could
- close in the few microseconds before the message packet is actually sent to the
- port address.
-
- After sending the packet the host can return to its normal processing,since the
- macro program will execute as a separate task. In most cases it will be
- advisable to "lock-out" further user commands while the ARexx program is
- running,to preserve te integrity of any shared data structures that may be
- accessed externally.
-
- COMMAND INVOCATIONS
-
- In the command mode of invocation the host supplies a command string consisting
- of a name token followed by an argument string. ARexx parses the string to
- extract the command name,which is usually the name of a program file. The
- default action is to use the remainder of the command string as the(single)
- argument string for the program. This may be overridden by requesting command
- tokenization,which is done by setting the RXFB_TOKEN modifier flag in the
- action code of the message packet. In this case the entire command string will
- be parsed,and the program may have many argument strings.(There is no limit to
- the number of arguments that may be derived from the command string,since they
- don't have to fit into the parameter slots of the message packet.)
-
- The parsing process uses "white space" (blanks,tabs,etc.)as the token
- separators,and has a several special features.
-
- QUOTING CONVENTION. Either single(')or double(")quotes may be used to surround
- items that include "white space" and would otherwise be separated during
- parsing. Single quotes may appear within a double-quote-delimited token,and
- vice versa;however,double-delimiter sequences are not accepted. The quotes are
- removed from the parsed token. An "implicit" quote at the end of the string is
- also recognized. If the command string ends before the closing delimiter has
- been found,the null byte is accepted as the final delimiter. For example,
- look.rexx "Now is the time" "can't ou see
-
- is a command with the two arguments strings "Now is the time" and "can't you
- see"(but without the quotes.)
-
- STRING FILES. If the command name(the first token of the string)is quoted,it is
- assumed to be a "string file" --an ARexx program in a string,rather than the
- name of a disk file. This is a convenient way to run very brief programs,
- although programs of any length may be stored this way. If command tokenization
- has not been specified,the remainder of the string is not scanned and no quote
- characters are removed. In this case the quoting convention isuseful only for
- indicating "string file" programs. The entire command string can be declared as
- a "string file" by setting the RXFB_STRING modifier flag of the action code.
- When this flag is set,no parsing at all is applied to the command.
-
- RESULT STRING. Command invocations do not usually request a result string,but
- can do so by setting the RXFB_RESULT modifier flag. The host application must
- be prepared to recycle the returned result string once it is no longer needed.
-
- 94
-
- FUNCTION INVOCATIONS
-
- In a function invocation the host application supplies a function name string
- and from 0 to 15 argument strings. The name string is used to locate an
- external program file and may include directory specifiers and a file
- extension. The actual argument count(not including the name string)must be
- placed in the low-order byte of the command code.
-
- This mode of invocation is normally used when a result string is expected and
- the argument strings are conveniently available. Note that a result does not
- have to be requested,however.
-
- RESULT STRINGS. Function invocations request a result string by setting the
- RXFB_RESULT modifier flag bit. If no errors occurred and a result string was
- requested,the secondary result field in the returned packet will be a pointer
- to the result string. However,if the program exited without supplying a result,
- the secondary field will be zero.
-
- STRING FILES. The function name argument may specify a "string file" rather
- than the name of a filing system object. This is indicated by setting the
- RXFB_STRING modifier flag.
-
- SEARCH ORDER
-
- The search for a program file matching a command or function name is normaly a
- two-step process. For each directory to be checked,a search is made first with
- the current file extension appended to the name string. If this search fails,
- the second search uses the unmodified name string. The first step is skipped if
- the command or function name includes an explicit file extension.
-
- The default file extension is ".rexx,"but this can be changed by supplying a
- file extension string in an extended message packet. Host applications will
- usually specify a file extension,since it provides a convenient way to
- distinguish the macro programs that are specific to that application. Refer to
- the section on Extension Fields for further details.
-
- The search path for a program depends on the way the program name was
- specified. If an explicit device or directory specification precedes the
- program name,only that directory will be searched. For example,the command-
- level invocation of "rx df0:s/test" will search only the df0:s directory for a
- file named test.rexx or test. If the program name does not include a path,the
- search path begins with the current directory and proceeds to the system REXX:
- directory. To further the above example,invoking the program as "rx test 1 2 3"
- would search for the files test.rexx,test,REXX:test.rexx,and REXX:test,in that
- order.
-
- If an ARexx program cannot be found,one alternative action may be taken. If the
- rm_PassPort field of an extended packet was supplied,the message packet is
- passed along to that port,which might be the next process in a search chain.
- Otherwise the message is returned with a "Program not found"error indication
- (error code 1.)
-
- 95
-
- EXTENSION FIELDS
-
- The RexxMsg structure includes several "extension fields" that can be used to
- override various defaults when a program is invoked. These extension fields can
- be filled in selectively,and only the non-zero values will override the
- corresponding default. ARexx never modifies the extension area.
-
- Host applications should supply values for the file extension and host address
- fields of the message packet. The file extension affects which program files
- will match a given command name,and allows macro programs specific to the host
- to be given distinctive names. The host address must refer to a public message
- port,and will usually indicate the host's own port. Any appropriate(but usually
- short)strings can be chosen for these values. Oftern,the name of the
- applications program itself can be used as its host address and file extension.
-
- PASSPORT. The rm_PassPort field allows the search for a program to be "passed
- along" to another messsage port after checking for an ARexx program. If the
- command or function name doesn't resolve to an ARexx program,the message packet
- is forwarded to the message port specified as the PassPort. This allows
- applications to maintain control over the search order for external program
- files.
-
- Note that the rm_PassPort field must be the actual address of a message port,
- rather than a name string. The PassPort therefore does not have a public port,
- but the port should be a secured resource,since the message is sent directly to
- this address without checking to see whether it is a valid message port.
-
- HOST ADDRESS. The rm_ComAddr field overrides the default initial host address,
- which is "REXX." The host address is the name of the messsage port to which
- commands will be directed,and is supplied as a pointer to a null-terminated
- string. Applications that support multiple instances of user data will usually
- create a separate message port for each instance. The name of this port would
- then be supplied as the host address for any commands issued from that
- instance.
-
- FILE EXTENSION. The rm_FileExt field is used to override the default file
- extension for ARexx programs,which is "REXX". Host applications can use the
- file extension to distinguish the names of the macro programs specific to that
- application. It is supplied as a pointer to a null-terminated string.
-
- INPUT AND OUTPUT STREAMS. The default input and output steams for an ARexx
- program are inherited from the host application's process structure,if the host
- is a process rather than just a task. One or both of these streams may be
- overridden by supplying an appropriate value in the rm-Stdin or rm_stdout
- fields. The values supplied must be valid DOS filehandles,and must not be
- closed while the program is executing. The steams are installed directly into
- the program's process structure,replacing the prior values.
-
- The output stream is also used as the default tracing stream for the program.
- If interactive tracing is to be used in a program,the output stream should
- refer to a console device,since it will be used for input as well.
-
- 96
-
- In the event than an ARexx program is invoked by an EXEC task,rather than by an
- DOS process,the extension field streams are the only way that the launched
- program can be given default I/O streams.
-
- INTERPRETING THE RESULT FIELDS
-
- The message packet that invoked an ARexx program is returned to the client when
- the program finishes. The two result fields will contain error codes or
- possibly a result string. The interpretation of the result fields depends
- partly on the mode of invocation. If the primary result field rm_Result1 is
- zero,the program executed normally and the secondary field rm_Result2 will
- contain a pointer to a result string,assuming that one was requested(and
- available.)
-
- If the primary result is non-zero,it represents either an error severity level
- or else the return code from a command invocation. The two cases can be
- distinguished by examining the secondary result. If the secondary field is also
- non-zero,an error occurred and the secondary field is an ARexx error code. If
- the secondary result is zero,then the primary result is the return code passed
- by an "EXIT rc" or "RETURN rc" instruction in the program. The application
- program can use this return code either as an error indication or to initiate
- some particular processing action.
-
- Result strings are always returned as an argstring and become the property(that
- is,responsibility)of the host. When the string is no longer needed,it can be
- released using the DelArgstring() function.
-
- Errors occurring in macro programs should usually be reported to the user.
- Explanatory messages are available for all ARexx error codes,and can be
- obtained by calling the ARexx Systems Library function ErrorMsg().
-
- 10-4 COMMUNICATING WITH THE RESIDENT PROCESS
-
- All communications with the resident process are handled by passing message
- packets,which were previously diagrammed in Table 10.2. The packet has a
- command field that describes the action to be performed and parameter fields
- that are specific to the command. Message packets are processed as they are
- received,and are then either returned to the sender or passed along to another
- process(in the case of a program invocation.) The packet includes two result
- fields that are used to return error codes or result strings. The parameter
- fields of the message packet may contain either(long)integer values or pointers
- to argument strings. String arguments are assumed to be argstring pointers
- unless otherwise specified.
-
- COMMAND(ACTION)CODES
-
- The command codes that are currently implemented in the resident process are
- described below. Commands are listed by their mnemonic codes,followed by the
- valid modifier flags. The final code value is always the logical OR of the code
- value and all of the modifier flags selected. The command code is installed in
- the rm_Action field of the message packet.
-
- USAGE: RXADDCON [RXFB_NONRET]
- This code specifies an entry to be added to the Clip List. Parameter slot ARGO
- points to the name string,slot ARG1 points to the value string,and slot ARG2
- contains the length of the value string.
-
- 97
-
- The name and value arguments do not need to be argstrings,but can be just
- pointers to storage areas. The name should be a null-terminated string,but the
- value can contain arbitrary data including nulls.
-
- USAGE: RXADDFH [RSFB_NONRET]
- This action code specifies a function host to be added to the Library List.
- Parameter slot ARGO points to the(null-terminated)host name string,and slot
- ARG1 holds the search priority for the node. The search priority should be an
- integer between 100 and -100 inclusive;the remaining priority ranges are
- reserved for future extensions. If a none already exists with the same name,the
- packet is returned with a warning level error code. Note that no test is made
- at this time as to whether the host port exists.
-
- USAGE:RXADDLIB [RXFB_NONRET]
- This code specifies an entry to be added to the Library List. Parameter slot
- ARGO points to a null-terminated name string referring either to a function
- library or a function host. Slot ARG1 is the priority for the node and should
- be an integer between 100 and -100 inclusive;the remaining priority ranges are
- reserved for future extensions. Slot ARG2 contains the entry oint offset and
- slot ARG3 is the library version number. If a node already exists with the same
- name,the packet is returned with a warning level error code. Otherwise,a new
- entry is added and the library or host becomes available to ARexx programs.
- Note that no test is made at this time as to whether the library exists and can
- be opened.
-
- USAGE:RXCOMM [RXFB_TOKEN] [RXFB_STRING] [RXFB_RESULT] [RXFB_NOIO]
- Specifies a command-mode invocation of an ARexx program. Parameter slot ARGO
- must contain an argstring ointer to the command string. The RXFB_TOKEN flag
- specifies that the command line is to be tokenized before being passed to the
- invoked program. The RXFB_STRING flag bit indicates that the command string is
- a "string file." Command invocations do not normally return result strings,but
- the RXFB_RESULT flag can be set if the caller is prepared to handle the cleanup
- associated with a returned string. The RXFB_NOIO modifier suppresses the
- inheritance of the host's input and output streams.
-
- USAGE:RXFUNC [RXFB_RESULT] [RXFB_STRING] [RXFB_NOIO] argcount
- This command code specifies a function invoction. Parameter slot ARGO contains
- a pointer to the function name string,and slots ARG1 through ARG15 point to the
- argument strings,all of which must be passed as argstrings. The lower byte of
- the command code is the argument count;this count excludes the function name
- string itself. Function calls normally set the RXFB_RESULT flag,but this is not
- mandatory. The RXFB_STRING modifier indicates that the function name string is
- actually a "string file". The RXFB_NOIO modifier suppresses the inheritance of
- the host's input and output streams.
-
- USAGE:RXREMCON [RXFB_NONRET]
- This code requests that an entry be removed from the Clip List. Parameter slot
- ARGO points to the null-terminated name to be removed. The Clip List is
- searched for a node matching the supplied name,and if a match is found the list
- node is removed and recycled. If no match is found the packet is returned with
- a warning error code.
-
- USAGE:RXREMLIB [RXFB_NONRET]
- This command removes a Library List entry. Parameter slot ARGO points to the
- null terminated string specifying the library to be removed. The Library List
- is searched for a node matching the library name,and if a match is found the
-
- 98
-
- node is removed and released. If no match is found the packet is returned with
- a warning error code. The libary node will not be removed if the library is
- currently being used by an ARexx program.
-
- USAGE:RXTCCLS [RXFB_NONRET]
- This code requests that the global tracing console be closed. The console
- window will be closed immediately unless one or more ARexx programs are waiting
- for input from the console. In this event,the window will be closed as soon as
- the active programs are no longer using it.
-
- USAGE:RXTCOPN [RXFB_NONRET]
- This command requests that the global tracing console be opened. Once the
- console is open,all active ARexx programs will divert their tracing output to
- the console. Tracing input(for interactive debugging)will also be diverted to
- the new console. Only one console can be opened;subsequent RXTCOPN requests
- will be returned with a warning error message.
-
- MODIFIER FLAGS
-
- Command codes may include modifier flags to select various processing options.
- Modifier flags are specific to certain commands,and are ignored otherwise.
-
- RXFB_NOIO. This modifier is used with the RXCOMM and RXFUNC command codes to
- suppress the automatic inheritance of the host's input and output streams.
-
- RXFB_NONRET. Specifies that the message packet is to be recycled by the
- resident process rather than being returned to the sender. This implies that
- the sender doesn't care about whether the requested action succeeded,since the
- returned packet provides the only means of acknowledgement. Messge packets are
- released using the library function DeleteRexxMsg().
-
- RXFB_RESULT. This modifer is valid with the RXCOMM and RXFUNC commands,and
- requests that the called program return a result string. If the program
- EXITs(or RETURNs)with an expression,the expression result is returned to the
- caller as an argstring. It is then the caller's responsibility to release the
- argstring when it is no longer needed;this can be done using the library
- function DeleteArgstring().
-
- RXFB_STRING. This modifer is valid with the RXCOMM and RXFUNC command codes. It
- indicates that the command or function argument(in slot ARGO)is a "string file"
- rahter than a file name.
-
- RXFB_TOKEN. This flag is used with the RXCOMM code to request that the command
- string be completely tokenized before being passed to the invoked program.
- Programs invoked as commands normally have only a single argument string. The
- tokenization process uses "white space" to separate the tokens,except within
- quoted strings. Quoted strings can use either single or double quotes,and the
- end of the command string(a null character)is considered as an implicit closing
- quote.
-
- 99
-
- RESULT FIELDS
-
- The resident process uses the standard command-level conventions for the
- primary return code installed in rm_Result1. Minor or warning errors are
- indicated by a value of 5,and more serious errors are returned as values of 10
- or 20. The secondary result field rm-Result2 will either be zero or an ARexx
- error code if applicable.
-
- Note that RXCOMM and RXFUNC messages are returned directly by the invoked macro
- program,rathe than by the residen process.
-
- 10-5 EXTERNAL FUNCTION LIBRARIES
-
- ARexx supports external function libraries as a mechanism for user-defined
- extensions to the language. Function libraries may be written and maintained by
- users or applications developers.
-
- DESIGN CONSIDERATIONS
-
- There are several different purposes for which a function library might be
- designed. In the simplest case,a library could be used to extend the string
- manipulation or mathematical capabilities of the language by defining new
- functions. Such a library could be entirely self-contained or might call other
- system libraries to perform specific operations.
-
- Another alternative would be to build a library that interacts closely with an
- external applications program. This could allow specific operations in the host
- application to be performed as function calls rather than as commands. There
- are several advantages to this approach,as it avoids the need to parse command
- strings and does not require the multiple task context changes associated with
- message-passing. The library might include entry points for specific operaions
- as well as functions to support processing required by the applications
- program.
-
- Function libraries can also serve as bridges to other system or applications
- libraries. For example,if a program needed to call the functions in a graphics
- library,a bridge library could be built to match the function names in the
- program with the appropriate entry point in the graphics library. A related
- possibility would be to use ARexx as a test driver for a program under
- development. Once the query table and parameter passing mechanisms for the
- function library have been built,new routines under development could be tested
- by just adding a table entry. Since building test programs is ofter very time-
- consuming,the flexibility and interactive debugging capabilities of ARexx make
- it an attractive alternative to compiled languages like "C."
-
- Regardless of the intended application,all function libraries share a common
- structure. The initial design follows that of the standard EXEC shared library,
- with the three required entry points Open,Close,and Expunge,plus a reserved
- slot. The library must also have a "query" entry point,which serves to match
- the name supplied by ARexx with the intended function. Typically,this will
- consist of a table of function names and a routine to search for the specified
- one.
-
- REENTRANCY. Functions libraries should be designed to be fully reentrant,since
- any number of ARexx programs may be running at any time. If this is not
- feasible due to other design constraints,the query function should include a
- lockout mechanism to prevent multiple calls to the library routines.
-
- 100
-
- CALLING CONVENTION
-
- The library's query function will be called from the interpreter's context with
- the address of a message packet in register A0 and the library base in A6. The
- structure of the message packet is the same as that in Table 10.2,but note that
- although a message packet is used to carry the arguments,it is not queued at a
- message port and does not need to be unlinked. The name of the function to be
- called is carried in the ARGO parameter slot. The query function must search
- for this function name and,if the name cannot be found,must return an error
- code of 1("Program not found")in register D0. The library will then be closed
- and the search continued in the next function library. The query function
- should not modify any fields within the message packet,as it must be passed
- along to the next library until the function is located.
-
- PARAMETER CONVERSION
-
- Once the requested function has been found,the query funcion may need to
- transform the parameters passed by ARexx into the form expected by the
- function. Whether the parameter strings need to be converted depends on how
- they are to be used. In some cases it may be sufficient just to foward a
- pointer to the message packet to the called function,while in other cases the
- query function may need to load parameters into registers or to perform
- conversion operations. The parameters in ARG1-ARG15 are always passed as
- argstrings,and may be treated like a pointer to a null-terminated string.
- Further attributes are stored at negative offsets from the argstring pointer,
- and may be helpful in working with the string.
-
- Numeric quantities are passed as strings of ASCII characters and will need to
- be converted to integer or floating-point format if arithmetic calculations are
- to be performed. The ARexx System Library includes a limited set of functions
- to do parameter conversions.
-
- The actual parameter count can be obtained from the low-order byte of the
- rm_Action field in the message packet. The count never includes the function
- name itself(in ARGO),but does include arguments specified as "defaults." Such
- arguments will have a zero value in the corresponding parameter slot.
-
- Note that the parameter block of the message packet,containing the fields
- ARG0-ARG15,is structured like the argument array expected by the main(argc,
- argv)function of a "C" program. This suggests a simple way that a function
- library could provide a bridge to a series of "C" programs. The query function
- would need only to determine the address of the called function,and then push
- the parameter block address and argument count onto the program stack.
-
- RETURNED VALUES
-
- Each library function must return an error code and a value string. The error
- code is returned in register D0,and should be 0 if no errors occurred. The
- value string must be returned as an argstring pointer in register A1,unless D0
- indicates that an error occurred during the call. The mechanisms for creating
- the proper return values can be made part of the query function,so that all
- functions in the library share a common return path.
-
- 101
-
- 10-6 DIRECT MANIPULATION OF DATA STRUCTURES
-
- All of the data structures maintained by the resident process are built into
- the ARexx Systems Library base and are therefore accessible to external
- programs. The Task List in the RexxBase structure links the global data
- structures for all currently active ARexx programs. This linkage uses the node
- contained in the message port of the RexxTask structure,rather than at the head
- of the structure. The RexxTask structure is the global data structure and
- initial storage environment for the ARexx program,and all descendant storage
- environments are linked into the Environment List. The linkage of internal data
- structures is such that the complete internal state of all ARexx programs can
- be reached starting from the library base pointer.
-
- Two library functions,LockRexxBase() and UnlockRexxBase(),are provided to
- mediate access to the global structures. The structure base should be locked
- before reading any of the data items or traversing any of the lists. The
- present version of these functions provides only a global lock,but future
- extensions will allow individual resources to be locked.
-
- In general it should not be necessary to manipulate directly any of these data
- structures. Functions have been provided in the ARexx Systems Library to
- perform all of the operations required to interface external program to the
- ARexx system. It is therefore recommended that applictions developers avoid
- using any of the internal structures except as provided through the library
- functions.
-
- 102
-
- APPENDIX A ERROR MESSAGES
-
- When the ARexx interpeter detects an error in a program,it returns an error
- code to indicate the nature of the problem. Errors are normally handled by
- displaying the error code,the source line number where the error occurred,and a
- brief message explaining the error condition. Unless the SYNTAX interrupt has
- been previously enabled(using the SIGNAL instruction),the program then
- terminates and control returns to the caller. Most syntax and execution errors
- can be trapped by the SYNTAX interrupt,allowing the user to retain control and
- perform whatever special error processing is required. Certain errors are
- generated outside of the context of an ARexx program,and therefore cannot be
- trapped by this mechanism. Refer to chapter 7 for further information on error
- trapping and processing.
-
- Associated with each error code is a severity level that is reported to the
- calling program as the primary result code. The error code itself is returned
- as the secondary result. The subsequent propagation or reporting of these codes
- is of course dependent on the external(calling)program.
-
- The following pages list all of the currently-defined error codes,along with
- the associated severity level and message string.
-
- ERROR: 1 SEVERITY: 5 MESSGE: PROGRAM NOT FOUND
- The named program could not be found,or was not an ARexx program. ARexx
- programs are expected to start with a "/*" sequence. This error is detected by
- the external interface and cannot be trapped by the SYNTAX interrupt.
-
- ERROR: 2 SEVERITY: 10 MESSAGE: EXECUTION HALTED
- A control-C break or an external half request was received and the program
- terminated. This error will be trapped if the HALT interrupt has been enabled.
-
- ERROR: 3 SEVERITY: 20 MESSAGE: INSUFFICIENT MEMORY
- The interpreter was unable to allocate enough memory for an operation. Since
- memory space is required for all parsing and execution operations,this error
- cannot usually be trapped by the SYNTAX interrupt.
-
- ERROR: 4 SEVERITY: 10 MESSAGE: INVALID CHARACTER
- A non-ASCII character was found in the program. Control codes and other non-
- ASCII characters may be used in a program by defining them as hex or binary
- strings. This is a scan phase error and cannot be trapped by the SYNTAX
- interrupt.
-
- ERROR: 5 SEVERITY: 10 MESSAGE: UNMATCHED QUOTE
- A closing single or double quote was missing. Check that each string is
- properly delimited. This is a scan phase error and cannot be trapped by the
- SYNTAX interrupt.
-
- 103
-
- ERROR: 6 SEVERITY: 10 MESSAGE: UNTERMINATED COMMENT
- The closing "*/" for a comment field was not found. Remember that comments may
- be nested,so each "/*" must be matched by a "*/." This is a scan phase error
- and cannot be trapped by the SYNTAX interrupt.
-
- ERROR: 7 SEVERITY: 10 MESSAGE: CLAUSE TOO LONG
- A clause was too long for the internal buffer used as temporary storage. The
- source line in question should be broken into smaller parts. This is a scan
- phase error and cannot be trapped by the SYNTAX interrupt.
-
- ERROR: 8 SEVERITY: 10 MESSAGE: INVALID TOKEN
- An unrecognized lexical token was found,or a clause could not be properly
- classified. This is a scan phase error and cannot be trapped by the SYNTAX
- interrupt.
-
- ERROR: 9 SEVERITY: 10 MESSAGE: SYMBOL OR STRING TOO LONG
- An attempt was made to create a string longer than the maximum supported by the
- interpreter. The implementation limits for internal structure are given in
- Appendix B.
-
- ERROR: 10 SEVERITY: 10 MESSAGE: INVALID MESSAGE PACKET
- An invalid action code was found in a message packet sent to the ARexx resident
- process. The packet was returned without being processed. This error is
- detected by the external interface and cannot be trapped by the SYNTAX
- interrupt.
-
- ERROR: 11 SEVERITY: 10 MESSAGE: COMMAND STRING ERROR
- A command string could not be processed. This error is detected by the external
- interface and cannot be trapped by the SYNTAX interrupt.
-
- ERROR: 12 SEVERITY: 10 MESSAGE: ERROR RETURN FROM FUNCTION
- An external function returned a non-zero error code. Check that the correct
- parameters were supplied to the function.
-
- ERROR: 13 SEVERITY: 10 MESSAGE: HOST ENVIRONMENT NOT FOUND
- The message port corresponding to a host address string could not be found.
- Check that the required external host is active.
-
- ERROR: 14 SEVERITY: 10 MESSAGE: REQUESTED LIBRARY NOT FOUND
- An attempt was made to open a function library included in the Library List,but
- the library could not be opened. Check that the correct name and version of the
- library were specified when the library was added to the resource list.
-
- ERROR: 15 SEVERITY: 10 MESSGE: FUNCTION NOT FOUND
- A function was called that could not be found in any of the currently
- accessible libraries,and could not be located as an external program. Check
- that the appropriate function libraries have been added to the Libraries List.
-
- 104
-
- ERROR: 16 SEVERITY: 10 MESSAGE: FUNCTION DID NOT RETURN VALUE
- A function was called which failed to return a result string,but did not
- otherwise report an error. Check that the function was programmed correctly,or
- invoke it using the CALL instruction.
-
- ERROR: 17 SEVERITY: 10 MESSAGE: WRONG NUMBER OF ARGUMENTS
- A call was made to a function which expected more(or fewer)arguments. This
- error will be generated if a Built-In or external function is called with more
- arguments than can be accomodated in the message packet used for external
- communications.
-
- ERROR: 18 SEVERITY: 10 MESSAGE: INVALID ARGUMENT TO FUNCTION
- An inappropriate argument was supplied to a function,or a required argument was
- missing. Check the parameter requirements specified for the function.
-
- ERROR: 19 SEVERITY: 10 MESSAGE: INVALID PROCEDURE
- A PROCEDURE instruction was issued in an invalid context. Either no internal
- functions were active,or a PROCEDURE had already been issued in the current
- storage environment.
-
- ERROR: 20 SEVERITY: 10 MESSAGE: UNEXPECTED THEN OR WHEN
- A WHEN or THEN instruction was executed outside of a valid context. The WHEN
- instruction is valid only within a SELECT range,and THEN must be the next
- instruciton following an IF or WHEN.
-
- ERROR: 21 SEVERITY: 10 MESSAGE: UNEXPECTED ELSE OR OTHERWISE
- An ELSE or OTHERWISE was found outside of a valid context. The OTHERWISE
- instruction is valid only within a SELECT range. ELSE is valid only following
- the THEN branch of an IF range.
-
- ERROR: 22 SEVERITY: 10 MESSAGE: UNEXPECTED BREAK,LEAVE,or ITERATE
- The BREAK instruction is valid only within a DO range or inside an INTERPRETed
- string. The LEAVE and ITERATE instuctions are valid only within an iterative DO
- range.
-
- ERROR: 23 SEVERITY: 10 MESSAGE: INVALID STATEMENT IN SELECT
- A invalid statement was encountered within a SELECT range. Only WHEN,THEN,and
- OTHERWISE statements are valid within a SELECT range,except for the conditional
- statements following THEN or OTHERWISE clauses.
-
- ERROR: 24 SEVERITY: 10 MESSAGE: MISSING OR MULTIPLE THEN
- An expected THEN clause was not found,or another THEN was found after one had
- already been executed.
-
- ERROR: 25 SEVERITY: 10 MESSAGE: MISSING OTHERWISE
- None of the WHEN clauses in a SELECT succeeded,but no OTHERWISE clause was
- supplied.
-
- ERROR: 26 SEVERITY: 10 MESSAGE: MISSING OR UNEXPECTED END
- The program source ended before an END was found for a DO or SELECT instruction
- or an END was encountered outside of a DO or SELECT range.
-
- 105
-
- ERROR: 27 SEVERITY: 10 MESSAGE: SYMBOL MISMATCH
- The symbol specified on an END,ITERATE,or LEAVE instruction did not match the
- index variable for the associated DO range. Check that the active loops have
- been nested properly.
-
- ERROR: 28 SEVERITY: 10 MESSAGE: INVALID DO SYNTAX
- An invalid DO instruction was executed. An initializer expression must be given
- if a TO or BY expression is specified,and a FOR expression must yield a non-
- negative integer result.
-
- ERROR: 29 SEVERITY: 10 MESSAGE: INCOMPLETE IF OR SELECT
- An IF or SELECT range ended before all of the required statement were found.
- Check whether the conditional statement following a THEN,ELSE,or OTHERWISE
- clause was omitted.
-
- ERROR: 30 SEVERITY: 10 MESSAGE: LABEL NOT FOUND
- A label specified by a SIGNAL instruction,or implicitly referenced by an
- enabled interrupt,could not be found in the program source. Labels defined
- dynamically by an INTERPRET instruction or by interactive input are not
- included in the search.
-
- ERROR: 31 SEVERITY: 10 MESSAGE: SYMBOL EXPECTED
- A non-symbol token was found where only a symbol token is valid. The DROP,END,
- LEAVE,ITERATE,and UPPER instructions may only be followed by a symbol token,and
- will generate this error if anything else is supplied. This message will also
- be issued if a required symbol is missing.
-
- ERROR: 32 SEVERITY: 10 MESSAGE: SYMBOL OR STRING EXPECTED
- An invalid token was found in a context where only a symbol or string is valid.
-
- ERROR: 33 SEVERITY: 10 MESSAGE: INVALID KEYWORD
- A symbol token in an instruction clause was identified as a keyword,but was
- invalid in the specific context.
-
- ERROR: 34 SEVERITY: 10 MESSAGE: REQUIRED KEYWORD MISSING
- An instuction clause required a specific keyword token to be present,but it was
- not supplied. For example,this messge will be issued if a SIGNAL ON instruction
- is not followed by one of the interrupt keywords(e.g.SYNTAX.)
-
- ERROR: 35 SEVERITY: 10 MESSAGE: EXTRANEOUS CHARACTERS
- A seemingly valid statement was executed,but extra characters were found at the
- end of the clause.
-
- ERROR: 36 SEVERITY: 10 MESSAGE: KEYWORD CONFLICT
- Two mutually exclusive keywords were included in an instruction clause,or a
- keyword was included twice in the same instruction.
-
- ERROR: 37 SEVERITY: 10 MESSAGE INVALID TEMPLATE
- The template provided with an ARG,PARSE,or PULL instruction was not properly
- constructed. Refer to Chapter 8 for a description of template structure and
- processing.
-
- 106
-
- ERROR: 38 SEVERITY: 10 MESSAGE: INVALID TRACE REQUEST
- The alphabetic keyword supplied with a TRACE instruction or as the argument to
- the TRACE()Built-In function was not valid. Refer to Chapter 7 for the valid
- TRACE options.
-
- ERROR: 39 SEVERITY: 10 MESSAGE: UNINITIALIZED VARIABLE
- An attempt was made to use an uninitialized variable while the NOVALUE
- interrupt was enabled.
-
- ERROR: 40 SEVERITY: 10 MESSAGE: INVALID VARIABLE NAME
- An attempt was made to assign a value to a fixed symbol.
-
- ERROR: 41 SEVERITY: 10 MESSAGE: INVALID EXPRESSION
- An error was detected during the evaluation an expression. Check that each
- operator has the correct number of operands,and that no extraneous tokens
- appear in the expression. This error will be detected only in expressions that
- are actually evaluated. No checking is performed on expressions in clauses that
- are being skipped.
-
- ERROR: 42 SEVERITY: 10 MESSAGE: UNBALANCED PARENTHESE
- An expression was found with an unequal number of opening and closing
- parentheses.
-
- ERROR: 43 SEVERITY: 43 MESSAGE: NESTING LIMIT EXCEEDED
- The number of subexpressions in an expression was greater than the maximum
- allowed. The expression should be simplified by breaking it into two or more
- intermediate expressions.
-
- ERROR: 44 SEVERITY: 10 MESSAGE: INVALID EXPRESSION RESULT
- The result of an expression was not valid within its context. For example,this
- messge will be issued if an increment or limit expression in a DO instruction
- yields a non-numeric result.
-
- ERROR: 45 SEVERITY: 10 MESSAGE: EXPRESSION REQUIRED
- An expression was omitted in a context where one is required. For example,the
- SIGNAL instruction,if not followed by the keywords ON or OFF,must be followed
- by an expression.
-
- ERROR: 46 SEVERITY: 10 MESSAGE: BOOLEAN VALUE NOT 0 OR 1
- An expression result was expected to yield a boolean result,but evaluated to
- something other than 0 or 1.
-
- ERROR: 47 SEVERITY: 10 MESSAGE: ARITHMETIC CONVERSION ERROR
- A non-numeric operand was used in a operation requiring numeric operands. This
- message will also be generated by an invalid hex or binary string.
-
- ERROR: 48 SEVERITY: 10 MESSAGE: INVALID OPERAND
- An operand was not valid for the intended operation. This message will be
- generated if an attempt is made to divide by 0,or if a fractional exponent is
- used in an exponentiation operation.
-
- 107
-
- APPENDIX B LIMITS AND COMPATIBILITY
-
- ARexx was designed to adhere closely to the REXX language standard. This
- appendix discusses those areas where ARexx departs from the standard.
-
- B-1 LIMITS
-
- Language definitions seldom include predefined limits to the program structures
- that can be created. Only a few such restrictions were imposed in implementing
- ARexx,and most of the internal structure are limited only by the total amount
- of memory available. The current implementation limits are listed below.
-
- LENGTH OF STRINGS. Strings,symbol names,and value strings are limited to a
- maximum length of 65,535 bytes.
-
- LENGTH OF CLAUSES. Clauses are limited to a maximum of 800 characters after
- removing comments and multiple blanks.
-
- NODES IN COMPOUND NAMES. Compound symbol names may include a maximum of 50
- nodes,including the stem.
-
- ARGUMENTS TO FUNCTIONS. Built-In and external functions are limited to a
- maximum of 15 arguments. There is no limit to the number of arguments that may
- be passed to an internal function.
-
- SUBEXPRESSION NESTING. The maximum nesting level for subexpressions is 32.
-
- B-2 COMPATIBILITY
-
- ARexx departs in a few ways from the language definition. The differences can
- be classified as omissions or extensions,and are described below.
-
- OMISSIONS. The only significant specification of the language standard omitted
- from this implementation is the arbitrary-precision arithmetic facility.
- Arithmetic operations are limited to about 14 digits of precision,and the FUZZ
- option is not implemented at all. Only the SCIENTIFIC format is used for
- exponential notation. The full numeric capabilities will be provided in a later
- release.
-
- EXTENSIONS. The following extensions to the language standard have been
- included in this implementation:
-
- BREAK INSTRUCTION. A new instruction called BREAK has been implemented. It is
- used to exit from the scope of any DO or INTERPRET instruction.
-
- ECHO INSTRUCTION. The ECHO instruction has been included as a synonym for SAY.
-
- SHELL INSTRUCTION. The SHELL instructiion has been included as a synonym for
- ADDRESS.
-
- 109
-
- SIGNAL OPTIONS. Several additional SIGNAL keywords have been implemented.
- BREAK_C,BREAK_D,BREAK_E,and BREAK_F will detect and trap the control-C through
- control-F signals passed by AmigaDOS. The IOERR keyword traps errors detected
- by the I/O system.
-
- STEM SYMBOLS. A stem symbol is valid anywhere that a simple symbol could be
- employed.
-
- TEMPLATE PROCESSING. Templates have been generalized in several ways. Variable
- symbols may be used as positional tokens if preceded by an operator;the "="
- operator is used to denote an absolute position. Multiple templates can be used
- with all source forms of the PARSE instruction.
-
- 110
-
- APPENDIX C THE AREXX SYSTEMS LIBRARY
-
- The ARexx interpreter is supplied as a shared library named rexxsyslib.library
- and should reside in the system LIBS:directory. While many of the library
- routines are highly specific to the interpreter,some of the functions will be
- useful to applications that use ARexx. The library is opened when the ARexx
- resident process is first loaded and will always be available while it remains
- active.
-
- The system library routines were designed to be called from assembly-language
- programs and,unless otherwise noted,save all registers except for A0/A1 and
- D0/D1. Many routines return values in more than one register to help reduce
- code size. In addition,the routines will set the condition-code register(CCR)
- wherever appropriate. In mode cases the CCR reflects the value returned in D0.
-
- The library offsets are defined in the file rxslib.i,which should be INDLUDEd
- in the program source code. Calls may be made from "C" programs if suitable
- binding routines are provided when the program is linked. The definitions for
- the constants and data structures used in ARexx are provided as INCLUDE files
- on the program distribution disk. These should be reviewed carefully before
- attempting to use the library functions.
-
- C-1 FUNCTION GROUPS
- The library functions can be frouped into Conversion,Input/Output,Resource
- Management,and String Manipulation functions.
-
- DATA CONVERSION. These functions provide many of the common data-conversion
- requirements.
-
- INPUT/0UTPUT. Two levels of I/O support are provided. The low level functions
- use DOS filehandles directly,while the higher-level functions use linked lists
- of IoBuff structures and support logical file names.
-
- RESOURCE. These functions allocate,release,or otherwise manage the data
- structures used with ARexx.
-
- STRING FUNCTIONS. All data in ARexx are managed as strings. These functions
- provide some of the more common string-manipulation operations.
-
- 111
-
- TABLE C.1 AREXX SYSTEMS LIBRARY FUNCTIONS
-
- NAME FUNCTIONAL GROUP DESCRIPTION
- AddClipNode Resource Allocate a Clip node
- ClearMem Resource Clear a block of memory
- ClearRexxMsg Resource Release argstrings from message
- CloseF Input/Output Close a file buffer
- ClosePublicPort Resource Close a port resource node
- CmpString String Compare string structures for equality
- CreateArgstring Resource Create an argstring structure
- CreateDOSPkt Input/Output Creata a DOS Standard Packet
- CreateRexxMsg Resource Create a message packet
- CurrentEnv Resource Get current storage environment
- CVa2i Conversion ASCII to integer
- CVc2x Conversion Character to Hex or Binary digits
- CVi2a Conversion Integer to ASCII
- CVi2arg Conversion Integer to ASCII argstring
- CVi2az Conversion Integer to ASCII,leading zeroes
- CVs2i Conversion String structure to integer
- CVx2c Conversion Hex or binary digits to binary
- DeleteArgstring Resource Release an argstring structure
- DeleteDOSPkt Input/Output Release a DOS Standard Packet
- DeleteRexxMsg Resource Release a message packet
- DOSRead Input/Output Read from a DOS filehandle
- DOSWrite Input/Output Write to a DOS filehandle
- ErrorMsg Conversion Get error message from error code
- ExistF Input/Output Check whether a DOS file exists
- FillRexxMsg Resource Convert and install argstrings
- FindDevice Input/Output Locate a DOS device node
- FindRsrcNode Resource Locate a resource node
- FreePort Resource Close a message port
- FreeSpace Resource Release internal memory
- GetSpace Resource Allocate internal memory
- InitList Resource Initialize a list header
- InitPort Resource Initialize a message port
- IsRexxMsg Resource Test a message packet
- LengthArgstring Resource Get length of argstring
- ListNames Resource Copy node names to an argstring
- OpenF Input/Output Open a file buffer
- OpenPublicPort Resource Allocate and open a port resource node
- QueueF Input/Output Queue a line in a file buffer
- ReadF Input/Output Read from a file buffer
- ReadStr Input/Output Read a string from a file buffer
- RemClipNode Resource Release a Clip node
- RemRsrcList Resource Release a resource list
- RemRsrcNode Resource Release a resource node
-
- 112
-
- TABLE C.1 LIBRARY FUNCTIONS (cont)
-
- NAME FUNCTIONAL GROUP DESCRIPTION
- SeekF Input/Output Reposition a file buffer
- StackF Input/Output Stack a line in a file buffer
- StcToken String Break out a token
- StrcmpN String Compare strings
- StrcpyA String Copy a string,converting to ASCII
- StrcpyN String Copy a string
- StrCpyU String Copy a string,converting to uppercase
- StrflipN String Reverse characters in a string
- Strlen String Find length of a string
- ToUpper Conversion ASCII to uppercase
- WriteF Input/Output Write to a file buffer
-
- C-2 LIBRARY FUNCTIONS
- The following descriptions of the ARexx Systems Library functions are listed
- alphabetically. The required arguments and register assignments are shown in
- parentheses after the function name. Multiple returns are shown in parentheses
- on the left-hand side of the call.
-
- AddClipNode()-allocate and link a Clip node
- Usage:node=AddClipNode(list,name,length,value)
- D0 A0 A1 D0 D1
- A0
- (CCR)
-
- Allocates and links a Clip node into the specified list. Clip nodes are
- resource nodes containing a name and value string,and include an "auto-delete"
- function for simple maintenance. The list argument must point to a properly-
- initialized EXEC list header. The name argument points to a null-terminated
- name string,the value argument is a pointer to a storage area,and the length
- argument is its length in bytes. The returned value is a pointer to the
- allocated node,or 0 if the allocation failed.
-
- The RemClipNode()function is installed as the "auto-delete" function for each
- node. Clip nodes can be intermixed with other resource nodes in a list and then
- released with a single call to RemRsrcList().
- See Also:RemClipNode(),RemRsrcList(),RemRsrcNode()
-
- AddRsrcNode()-allocate and link a resource node
- Usage:node=AddRsrcNode(list,name,length)
- D0 A0 A1 D0
- A0
- (CCR)
-
- Allocates and links a resource node(a RexxRsrc structure)to the specified list.
- The name argument is a pointer to a null-terminated string,a copy of which is
- installed in the node structure. The length argument is the total length for
- the node;this length is saved within the node so that it may be released later.
-
- 113
-
- The returned value is a pointer to the allocated node,or 0 if the allocation
- failed.
- See Also:RemRsrcList(),RemRsrcNode()
-
- ClearMem()-clear a block of memory
- Usage:ClearMem(address,length)
- A0 D0
-
- Clears a block of memory beginning at the given address for the specified
- length in bytes. The address must be word-aligned and the length must be a
- multiple of 4 bytes;all structures allocated by ARexx meet these restrictions.
- Register A0 is preserved.
-
- ClearRexxMsg()-release argument strings
- Usage:ClearRexxMsg(msgptr,count)
- A0 D0
-
- Releases one or more argstrings from a message packet and clears the
- corresponding slots. The count argument specifies the number of argument slots
- to clear,and can be set to less than 16 to reserve some to the slots for
- private use. No action is taken if the slot already contains a zero value.
- See Also:FillRexxMsg()
-
- CloseF()-close a file buffer
- Usage:boolean=CloseF(IoBuff)
- D0 A0
-
- Release the IoBuff structure and closes the associated DOS file. CloseF()is the
- "auto-delete" function for the IoBuff structure,so an entire list of file
- buffers can be closed with a single call to RemRsrcList().
-
- ClosePublicPort()-close a port resource node
- Usage:ClosePublicPort(node)
- A0
-
- Unlinks and closes the message port and releases the resource node structure.
- The node must have been allocated by the OpenPublicPort()function.
- See Also:OpenPublicPort()
-
- CmpString()-compare string structures for equality
- Usage:test=CmpString(ss1,ss2)
- D0 A0 A1
- (CCR)
-
- The arguments ss1 and ss2 must be pointers to ARexx string structures and are
- compared for equality. String structures include the length and hash code of
- the string,so the actual strings are not compared unless the lengths and hash
- codes match. The return value sets the CCR and will be -1(True)if the strings
- match and 0(False)otherwise.
-
- 114
-
- CreateArgstring()-create an argument string structure
- Usage:argstring=CreateArgstring(string,length)
- D0 A0 D0
- A0
- (CCR)
-
- Allocates a RexxArg structure and copies the supplied string into it. The
- argstring return is a pointer to the string buffer of the structure,and can be
- treated like an ordinary string pointer. The RexxArg structure stores the
- structure size and string length at negative offsets to the string pointer. The
- string pointer can be set to NULL if only an uninitialized structure is
- required.
- See Also:DeleteArgstring()
-
- CreateDOSPkt()-allocate and initialize a DOS standard Packet.
- Usage:packet = CreateDOSPkt()
- D0
- A0
- (CCR)
-
- Allocates a DOS StandardPacket structure and initializes it by interlinking the
- EXEC message and the DOS packet substructures. No replyport is installed in
- either the message or the packet,as these fields are generally filled in just
- before the message is sent.
- See Also:DeleteDOSPkt()
-
- CreateRexxMsg()-allocate an ARexx message packet
- Usage: msgptr=CreateRexxMsg(replyport,extension,host)
- D0 A0 A1 D0
- A0
- (CCR)
-
- This function allocates an ARexx message packet from the system free memory
- list. The message packet consists of a standard EXEC message structure extended
- to include space for function arguments,returned results,and internal defaults.
- The replyport argument points to a public or private message port and must be
- supplied,as it is required to return the message packet to the sender. The
- extension and host arguments are pointers to null-terminated strings that
- provide values for the default file extension and the initial host address,
- respectively. Additional override fields in the extended packet except for the
- primary and secondary result fields rm_Result1 and rm_Result2.
- See Also: DeleteRexxMsg()
-
- CVa2i()-convert from ASCII to integer
- Usage: (digits,value) = CVa2i(buffer)
- D0 D1 A0
-
- Converts the buffer of ASCII characters to a signed long integer value. The
- scan proceeds until a non-digit character is found or until an overflow is
- detected. The function returns both the number of digits scanned and the
- converted value.
-
- 115
-
- CVc2x()-convert(unpack)from character string to hex or binary digits.
- Usage: error = CVc2x(outbuff,string,length,mode)
- D0 A0 A1 D0 D1
-
- Converts the signed integer value argument to ASCII characters using the
- supplied buffer pointer. The digits argument specifies the maximum number of
- characters that will be copied to the buffer. The returned length is the actual
- number of characters copied. The pointer return is the new buffer pointer.
- See Also: CVi2az()
-
- CVi2arg()-convert from integer to argstring
- Usage: argstring=CVi2arg(value,digits)
- D0 D0 D1
- A0
- (CCR)
-
- Converts the signed long integer value argument to ASCII characters,and
- installs them in an argstring(a RexxArg structure). The returned value is an
- argstring pointer or 0 if the allocation failed. The allocated structure can be
- released using DeleteArgstring().
-
- CVi2az()-convert from integer to ASCII with leading zeroes
- Usage: (length,pointer)=CVi2az(buffer,value,digits)
- D0 A0 A0 D0 D1
-
- Converts the signed long integer value argument to ASCII characters in the
- supplied buffer,with leading zeroes to fill out the requested number of digits.
- This function is identical to CVi2a except that leading zeroes are supplied.
- See Also:CVi2a()
-
- CVs2i()-convert from string structure to integer
- Usage: (error,value)=CVs2i(ss)
- D0 D1 A0
-
- The ss argument must be a pointer to a string structure. It is converted to a
- signed long integer value return. The error return code is 47("Arithmetic
- conversion error")if the string is not a valid number.
-
- 116
-
- CVx2c()-convert from hex or binary digits to(packed)string
- Usage:error=CVx2c(outbuff,string,length,mode)
- D0 A0 A1 D0 D1
-
- Converts the string argument of hex(0-9,A-F)or binary(0,1)digits to the packed
- binary representation. The mode argument specifies the(hex or binary)conversion
- mode,and must be set to -1 for hex strings or 0 for binary strings. Blank
- characters may be embedded in the string for readability,but only at byte
- boundaries. The error return code is 47 if the string is not a valid hex or
- binary string.
-
- CurrentEnv()-return the current storage environment
- Usage:envptr=CurrentEnv(rxtptr)
- D0 A0
-
- Returns a pointer to the current storage environment associated with an
- executing ARexx program. The rxptr argument is a pointer to the RexxTask
- structure,and may be obtained from the message packet sent to an external
- application.
-
- DeleteArgstring()-delete(release)an argstring structure
- Usage:DeleteArgstring(argstring)
- A0
-
- Releases an argstring (RexxArg) structure. The RexxArg structure contains the
- total allocated length at a negative offset from the argstring pointer.
- See Also:CreateArgstring()
-
- DeleteDOSPkt()-release a DOS Standard Packet structure.
- Usage:DeleteDOSPkt(message)
- A0
-
- Releases a DOS StandardPacket structure,typically obtained by a prior call to
- CreateDOSPkt().
- See Also:CreateDOSPkt()
-
- DeleteRexxMsg()-delete(release)an ARexx message packet.
- Usage:DeleteRexxMsg(packet)
- A0
-
- Release an ARexx message packet to the system free-memory list. The internal
- MN-LENGTH field is used as the total size of the memory block to be released,so
- this function can be used to release any message packet that contains the total
- length in this field. Any embedded argument strings must be released before
- calling DeleteRexxMsg().
- See Also:CreateRexxMsg()
-
- 117
-
- DOSREAD()-read from a DOS file
- Usage:count=DOSRead(filehandle,buffer,length)
- D0 A0 A1 D0
- (CCR)
-
- Reads one or more characters from a DOS filehandle into the supplied buffer.
- The length argument specifies the maximum number of characters that will be
- read. The returned count is the actual number of bytes transferred,or -1 if an
- error occurred.
-
- DOSWrite()-write to a DOS file
- Usage:count=DOSWrite(filehandle,buffer,length)
- D0 A0 A1 D0
- (CCR)
-
- Writes a buffer of the specified length to a DOS filehandle. The retuned count
- is the actual number of bytes written,or -1 if an error occurred.
-
- ErrorMsg()-find the message associated with an error code
- Usage:(boolean,ss)=ErrorMsg(code)
- D0 A0 D0
-
- Returns the error message(as a pointer to a string structure)associated with
- the specified ARexx error code. The boolean return will be -1 if the supplied
- code was a valid ARexx error code,and 0 otherwise.
-
- ExistF()-check whether an external file exists
- Usage:boolean=ExistF(filename)
- D0 A0
- (CCR)
-
- Tests whether an external file currently exists by attempting to obtain a read
- lock on the file. The boolean return indicates whether the operation succeeded,
- and the lock is released.
-
- FillRexxMsg()-convert and install arguments in message packet.
- Usage:boolean=FillRexxMsg(msgptr,count,mask)
- D0 A0 D0 D1
-
- This function can be used to convert and install up to 16 argument strings in a
- RexxMsg structure. The message packet must be allocated and the argument fields
- of interest set to either a pointer to a null-terminated string or an integer
- value. The count argument specifies the number of fields,beginning with ARGO,to
- be converted into argstrings and installed into the argument slot. Bits 0-15 of
- the mask argument specify whether the corresponding argument is a string
- pointer(bit clear)or an integer value(bit set).
-
- 118
-
- The count argument is normally set to the exact number of strings to be passed.
- By setting this count to less than 16,a number of the slots can be reserved for
- private uses.
-
- The returned value is -1(True)if all of the arguments were successfully
- converted. In the event of an allocation failure,all of the partial results are
- released and a value of 0 is returned.
- See Also:ClearRexxMsg()
-
- FindDevice()-check whether a DOS device exists.
- Usage:device=FindDevice(devicename,type)
- D0 A0 D0
- A0
- (CCR)
-
- Scans the DOS DeviceList for a device node of the specified type matching the
- null-terminated name string. The acceptable values for the type argument are
- the constants DLT_DEVICE,DLT_DIRECTORY,or DLT_VOLUME define in the DOS INCLUDE
- files. Device names are conveted to uppercase before checking for a match. The
- returned value is a pointer to the matched device node,or 0 if the device was
- not found.
-
- FindRsrcNode()-locate a resource node with the given name.
- Usage:node=FindRsrcNode(list,name,type)
- D0 A0 A1 D0
- A0
- (CCR)
-
- Searchs the specified list for the first node of the selected type with the
- given name. The list argument must be a pointer to a properly-initialized EXEC
- list header. The name argument is a pointer to a null-terminated string. If the
- type argument is 0,all nodes are selected;otherwise,the supplied type must
- match the LN_TYPE field of the node. The returned value is a pointer to the
- node or 0 if no matching node was found.
-
- FreePort()-release resources associated with a message port
- Usage:FreePort(port)
- A0
-
- This function deallocates the signal bit associated with a message port and
- marks the port as "closed." The task calling FreePort()must be the same one
- that initialized the port,since signal bit allocations are specific to a task.
- The memory space associated with the port is not released.
- See Also:InitPort()
-
- FreeSpace()-releases space to the internal memory allocator.
- Usage:FreeSpace(envptr,block,length)
- A0 A1 D0
-
- Returns a block of memory to the internal allocator,which must have been
- obtained from a call to GetSpace(). The envptr argument is a pointer to the
- base or current storage environment.
- See Also:CurrentEnv(),GetSpace()
-
- 119
-
- GetSpace()-allocate memory using the internal allocator.
- Usage:block=GetSpace(envptr,length)
- D0 A0 D0
- A0
- (CCR)
-
- Allocates a block of memory using the internal allocator. The memory is
- obtained from an internal pool managed by the interpreter and is returned to
- the operating system when the ARexx program terminates. The envptr argument is
- a pointer to the base or current storage environment for the program.
-
- The internal allocator must be used to allocate strings for use as values for
- symbols,and is convenient for obtaining small blocks of memory whose lifetime
- will not exceed that of the ARexx program.
- See Also:CurrentEnv(),FreeSpace()
-
- InitList()-initialize a list header
- Usage:InitList(list)
- A0
-
- Initializes an EXEC list header structure.
-
- InitPort()-initialize a previously-allocated message port.
- Usage:(signal,port)=InitPort(port,name)
- D0 A1 A0 A1
-
- Initializes a message port structure for which memory space has been previously
- allocated,typically as part of a larger structure or as static storage in a
- program. It installs the task ID(of the task calling the function)into the
- MP_SIGTASK field and allocates a signal bit. The name parameter must be a
- pointer to a null-terminated string. The signal return is the signal bit that
- was allocated for the port. In the event that a signal could not be assigned,a
- value of -1 is returned.
-
- Note that the port is not linked into the system Ports List. If the port is to
- be made public,this can be done after the function returns. The port address is
- returned in the correct register(A1)for a subsequent call to the EXEC function
- AddPort().
- See Also:FreePort()
-
- IsRexxMsg()-check whether a message came from ARexx.
- Usage:boolean=IsRexxMsg(msgptr)
- D0 A0
-
- Tests whether the message packet specified by the msgptr argument came from an
- ARexx program. ARexx marks its messages with a pointer to a static string
- "REXX" in the LN_NAME field. The returned value is either -1(True)if the
- message came from ARexx or 0(False)otherwise.
-
- 120
-
- IsSymbol()-check whether a string is a valid symbol.
- Usage:(code,length)=IsSymbol(string)
- D0 D1 A0
-
- Scans the supplied string pointer for ARexx symbol characters. The code return
- is the symbol type if a symbol was found,or 0 if the string did not start with
- a symbol character. The length return is the total length of the symbol.
-
- ListNames()-build a string of names from a list.
- Usage:argstring=ListNames(list,separator)
- D0 A0 D0[0:7]
- A0
- (CCR)
-
- Scans the specified list and copies the name strings into an argstring. The
- list argument must be a pointer to an initialized EXEC list header. The
- separator argument is the character,possibly a null,to be placed as a delimiter
- between the node names.
-
- The list is traversed inside a Forbid()exclusion and so may be used with shared
- or system lists. The returned argstring can be released using DeleteArgstring()
- after the names are no longer needed.
- See Also:DeleteArgstring()
-
- LockRexxBase()-lock a shared resource.
- Usage:LockRexxBase(resource)
- D0
-
- Secures the specified resource in the ARexx Systems Library base for read
- access. The resource argument is a manifest constant for the required resource,
- or zero to lock the entire structure.
-
- Note that write access to shared resources is normally mediated by the ARexx
- resident process,which operates at an elevated priority to gain exclusive
- access. Locking a resource should not be attempted from a process operating at
- a priority higher than the resident process.
- See Also:UnlockRexxBase()
-
- OpenF()-open a file buffer
- Usage:IoBuff=OpenF(list,filename,mode,logical)
- D0 A0 A1 D0 D1
- A0
- (CCR)
-
- Attempts to open an external file in the specified mode,which should be one of
- the constants RXIO_READ,RXIO_WRITE,or RXIO_APPEND defined in the ARexx INCLUDE
- files.
-
- 121
-
- If successful,an IoBuff structure is allocated and linked into the specified
- list. The list argument must be a pointer to a properly-initialized EXEC list
- header.
-
- The optional logical argument is the logical name for the file,and must be
- either a pointer to a null-terminated string or zero(NULL)if a name is not
- required.
- See Also:CloseF()
-
- OpenPublicPort()-open a public message port
- Usage:node=OpenPublicPort(list,name)
- D0 A0 A1
- A0
- (CCR)
-
- Allocates a message port as an "auto-delete" resource node and links it into
- the specified list. The list argument must point to a properly initialized EXEC
- list header. The message port is initialized with the given name and linked
- into the system Ports List.
- See Also:ClosePublicPort()
-
- QueueF()-queue a line to a file buffer.
- Usage:count-=QueueF(IoBuff,buffer,length)
- D0 A0 A1 D0
-
- Queues a buffer of characters in the stream associated with the IoBuff
- structure. The stream must be managed by a DOS handler that supports the
- ACTION_QUEUE packet.
-
- Queued lines are placed in "first-in,first-out" order and are immediately
- available to be read from the stream. The buffer argument is a pointer to a
- string of characters,and the length specifies the number of characters to be
- queued. The return value is the actual count of characters or -1 if an error
- occurred.
- See Also:StackF()
-
- ReadF()-read characters from a file buffer
- Usage:count=ReadF(IoBuff,buffer,length)
- D0 A0 A1 D0
- (CCR)
-
- Reads one or more characters from the file specified by the IoBuff pointer. The
- buffer argument is a pointer to a storage area,and the length argument
- specifies the maximum number of characters to be read. The return value is the
- actual number of characters read,or -1 if an error occurred.
-
- ReadStr()-read a string from a file
- Usage:(count,pointer)=ReadStr(IoBuff,buffer,length)
- D0 A1 A0 A1 D0
-
- Reads characters from the file specified by the IoBuff pointer until a
- "newline" character is found. The "newline" is not included in the returned
- string. The return value is the actual number of characters read,or -1 if an
- error occurred.
-
- 122
-
- See Also:ReadF()
-
- RemClipNode()-unlink and deallocate a list Clip node.
- Usage:RemClipNode(node)
- A0
-
- Unlinks and releases the specified Clip node. The function is the "auto-delete"
- function for Clip nodes,and will be called automatically by RemRsrcNode() or
- RemRsrcList().
- See Also:AddClipNode(),RemRsrcList(),RemRsrcNode()
-
- RemRsrcList()-unlink and deallocate a list of resource nodes
- Usage:RemRsrcList(list)
- A0
-
- Scans the supplied list and releases any nodes found. The list must consist of
- resource nodes(RexxRsrc structures),which contain information to allow
- automatic cleanup and deletion.
- See Also:RemRsrcNode()
-
- RemRsrcNode()-unlink and deallocate a resource node
- Usage:RemRsrcNode(node)
- A0
-
- Unlinks and releases the specified resource node,including the name string if
- one is present. If an "auto-delete" function has been specified in the node,it
- is called to perform any required resource deallocation before the node is
- released.
- See Also:RemRsrcList()
-
- SeekF()-seek to the specified position in a file.
- Usage:position=SeekF(IoBuff,offset,anchor)
- D0 A0 D0 D1
-
- Seeks to a new position in the file is specified by the IoBuff pointer. The
- position is given by the offset argument,a byte offset relative to the supplied
- anchor argument. The anchor may specify the beginning(-1),the current position
- (0),or the end of the file(1). The return value is the new position relative to
- the beginning of the file.
-
- StackF()-stack a line to a file buffer.
- Usage:count=StackF(IoBuff,buffer,length)
- D0 A0 A1 D0
-
- Stacks a buffer of characters in the stream associated with the IoBuff
- structure. The buffer argument is a pointer to a string of characters,and the
- length specifies the number of characters to be stacked. The return value is
- the actual count of characters to be stacked. The return value is the actual
- count of characters or -1 if an error occurred.
-
- 123
-
- Stacked lines are placed in "last-in,first-out" order and are immediately
- available to be read from the stream. The stream must be managed by a DOS
- handler that supports the ACTION_STACK packet.
- See Also:QueueF()
-
- StcToken()-break out the next token from a string
- Usage:(quote,length,scan,token)=StcToken(string)
- D0 D1 A0 A1 A0
-
- Scans a null-terminated string to select the next token delimited by "white
- space,"and returns a pointer to the start of the token. The quote return will
- be an ASCII single or double quote if the token was quoted and 0 otherwise;
- white space characters are ignored within quoted strings. The length return is
- the total length of the token,including any quote characters. The scan return
- is advanced beyond the current token to prepare for the next call.
-
- StrcpyA()-copy a string,converting to ASCII
- Usage:hash=StrcpyA(destination,source,length)
- D0 A0 A1 D0
-
- Copies the source string to the destination area,converting the characters to
- ASCII by clearing the high-order bit of each byte. The length of the string
- (which may include embedded nulls)is considered as a 2-byte usingned integer.
- So the string is limited in length to 65,535 bytes. The hash return is the
- internal hash byte for the copied string.
- See Also:StrcpyN(),StrcpyU
-
- StrcpyN()-copy a string
- Usage:hash=StrcpyN(destination,source,length)
- D0 A0 A1 D0
-
- Copies the source string to the destination area. The length of the string
- (which may include embedded nulls)is considered as a 2-byte unsigned integer.
- The hash return is the internal hash byte for the copied string.
- See Also:StrcpyA(),StrcpyU
-
- StrcpyU()-copy a string,converting to uppercase
- Usage:hash=StrcpyU(destination,source,length)
- D0 A0 A1 D0
-
- Copies the source string to the destination area,converting to uppercase
- alphabetics. The length of the string(which may include embedded nulls)is
- considered as a 2-byte unsigned integer. The has return is the internal hash
- byte for the copied string.
- See Also:StrcpyA(),StrcpyN
-
- 124
-
- StrflipN()-reverse the characters in a string
- Usage:StrflipN(string,length)
- A0 D0
-
- Reverses the sequence of characters in a string. The conversion is performed in
- place.
-
- Strlen()-find the length of a null-terminated string
- Usage:length=Strlen(string)
- D0 A0
- (CCR)
-
- Returns the number of characters in a null-terminated string. Register A0 is
- preserved,and the CCR is set for the returned length.
-
- StrcmpN()-compare the values of strings
- Usage:test=StrcmpN(string1,string2,length)
- D0 A0 A1 D0
- (CCR)
-
- The string1 and string2 arguments are compared for the specified number of
- characters. The comparison proceeds character-by-character until a difference
- is found or the maximum number of characters have been examined. The returned
- value is -1 if the first string was less,1 if the first string was greater,and
- 0 if the strings match exactly. The CCR register is set for the returned value.
-
- ToUpper()-translate an ASCII character to uppercase
- Usage:upper=ToUpper(character)
- D0 D0
-
- Converts an ASCII character to uppercase. Only register D0 is affected.
-
- UnlockRexxBase()-unlock a shared resource.
- Usage:UnlockRexxBase(resource)
- D0
-
- Releases the specified resource,or all resources if the argument is zero. Every
- call to LockRexxBase()should be followed eventually by a call to UnlockRexxBase
- ()for the same resource.
- See Also:LockRexxBaseF()
-
- WriteF()-write characters to a file buffer
- Usage:count=WriteF(IoBuff,buffer,length)
- D0 A0 A1 D0
- (CCR)
-
- Writes a buffer of characters of the specified length to the file associated
- with the IoBuff pointer. The buffer argument is a pointer to a storage area,
-
- 125
-
- and the length argument specifies the number of characters to be written. The
- returned value is the actual number of characters written or -1 if an error
- occurred.
- See Also:CloseF(),OpenF(),ReadF()
-
- 126
-
- APPENDIX D THE AREXX SUPPORT LIBRARY
-
- The ARexx language system is distributed with an external function library that
- provides a number of Amiga-specific functions. It is a standard Amiga shared
- library named rexxsupport.library and should reside in the system
- LIBS:directory. Unlike the Systems Library described in the previous
- Appendix,the support library functions are callable from with ARexx programs.
-
- The support library was designed to supplement the generic Built-In functions
- with functions specific to the Amiga. This library will be expanded in future
- releases,and users are encouraged to submit suggestions for additional
- functions.
-
- The Support Library must be added to the global Library List before it can be
- accessed by ARexx programs. This can be done using the Built-In function
- ADDLIB() or by direct communication with the resident process. The library name
- must be specified as rexxsupport.library,the query function offset is -30,and
- the version number is 0. The search priority can be set to 0 or whatever value
- is appropriate.
-
- ALLOCMEM()
- Usage:ALLOCMEM(length,[attribute])
- Allocates a block of memory of the specified length from the system free-
- memory pool and returns its address as a 4-byte string. The optional attribute
- parameter must be a standard EXEC memory allocation flag,supplied as a 4-byte
- string. The default attribute is for "PUBLIC" memory(not cleared).
-
- This function should be used whenever memory is allocated for use by external
- programs. It is the user's responsibility to release the memory space when it
- is no longer needed.
- See Also:FREEMEM()
- Example:
- say c2x(allocmem(1000)) ==>00050000
-
- CLOSEPORT()
- Usage:CLOSEPORT(name)
- Closes the message port specified by the name argument,which must have been
- allocated by a call to OPENPORT()within the current ARexx program. Any messages
- received but not yet REPLYed are automatically returned with the return code
- set to 10.
- See Also:OPENPORT()
- Example:
- call closeport myport
-
- 127
-
- FREEMEM()
- Usage:FREEMEM(address,length)
- Releases a block of memory of the given length to the system freelist. The
- address parameter is a four-byte string,typically obtained by a prior call to
- ALLOCMEM(). FREEMEM()cannot be used to release memory allocated using
- GETSPACE(),the ARexx internal memory allocator. The returned value is a boolean
- success flag.
- See Also:ALLOCMEM()
- Example:
- say freemem('00042000'x,32) ==>1
-
- GETARG()
- Usage:GETARG(packet,[n])
- Extracts a command,function name,or argument string from a message packet. The
- packet argument must be a 4-byte address obtained from a prior call to
- GETPKT(). The optional n argument specifies the slot containing the string to
- be extracted,and must be less than or equal to the actual argument count for
- the packet. Commands and functions names are always in slot 0;function packets
- may have argument strings in slots 1-15.
- Examples:
- command = getarg(packet)
- function= getarg(packet,0) /* name string */
- arg1 = getarg(packet,1) /* 1st argumeent*/
-
- GETPKT()
- Usage:GETPKT(name)
- Checks the message port specified by the name argument to see whether any
- messages are available. The named message port must have been opened by a prior
- call to OPENPORT() within the current ARexx program. The returned value is the
- 4-byte address of the first message packet,or '0000 0000'x if no packets were
- available.
-
- The function returns immediately whether or not a packet is enqueued at the
- message port. Programs should never be designed to "busy-loop" on a message
- port. If there is no useful work to be done until the next message packet
- arrives,the program should call WAITPKT()and allow other tasks to proceed.
- See Also:WAITPKT()
- Example:
- packet = getpkt('MyPort')
-
- OPENPORT()
- Usage:OPENPORT(name)
- Creates a public message port with the given name. The returned value is the
- 4-byte address of the Port Resource strcture or '0000 000'xif the port could
- not be opened or initialized. An initialization failure will occur if another
- port of the same name already exists,or if a signal bit couldn't be allocated.
-
- 128
-
- The message port is allocated as a Port Resource node and is linked into the
- program's global data structure. Ports are automatically closed when the
- program exits,and any pending messages are returned to the sender.
- See Also:CLOSEPORT()
- Example:
- myport = openport("MyPort")
-
- REPLY()
- Usage:REPLY(packet,rc)
- Returns a message packet to the sender,with the primary result field set to the
- value given by the rc argument. The secondary result is cleared. The packet
- argument must be supplied as a 4-byte address,and the rc argument must be a
- whole number.
- Example:
- call reply packet,10 /* error return*/
-
- SHOWDIR()
- Usage:SHOWDIR(directory,['All' | 'File' | 'Dir'])
- Returns the contents of the specified directory as a string of names separated
- by blanks. The second parameter is an option keyword that selects whether all
- entries,only files,or only subdirectories will be included.
- Example:
- say showdir("df1:c") ==>rx ts te hi tco tcc
-
- SHOWLIST()
- Usage:SHOWLIST[{'D' | 'L' | 'P' | 'R' | 'W' },[name])
- The first argument is an option keyword to select a system list;the options
- currently supported are Devices,Libraries,Ports,Ready,and Waiting. If only the
- first parameter is supplied,the function scans the selected list and returns
- the node names in a string separated by blanks. If the name parameter is
- supplied,the boolean return indicates whether the specified list contains a
- node of that name. The name matching is case-sensitive.
-
- The list is scanned with task switching forbidden so as to provide an accurate
- snapshot of the list at that time.
- Example:
- say showlist('P') ==>REXX MyCon
- say showlist('P','REXX') ==>1
-
- 129
-
- STATEF()
- Usage:STATEF(filename)
- Returns a string containing information about an external file. The string is
- formatted as "{DIR | FILE} length blocks protection comment."
- The length token gives the file length in bytes,and the block token specifies
- the file length in blocks.
- Example:
- say statef("libs:rexxsupport.library")
- /* would give "FILE 1880 4 RWED " */
-
- WAITPKT()
- Usage:WAITPKT(name)
- Waits for a message to be received at the specified(named)port,which must have
- been opened by a call to OPENPORT() within the current ARexx program. The
- returned boolean value indicates whether a message packet is available at the
- port. Normally the returned value will be 1(True),since the function waits
- until an event occurs at the message port.
-
- The packet must then be removed by a call to GETPKT(),and should be returned
- eventually using the REPLY()function. Any message packets received but not
- returned when an ARexx program exits are automatically REPLYed with the return
- code set to 10.
- Example:
- call waitpkt 'MyPort' /* wait awhile */
-
- 130
-
- APPENDIX E DISTRIBUTION FILES
-
- This appendix lists the directores of the standard ARexx distribution disk. The
- contents of some of the directories may change from time to time,so your disk
- may not show exactly the same files. Most notably,the :rexx directory will
- expand as more program examples are included in it.
-
- The second section of the Appendix lists the HEADER files that define the
- constants and data structures used with ARexx. All of these files are available
- in the :INCLUDE directory,but are listed here for convenience in studying the
- structures.
-
- E-1 DIRECTORIES
-
- The files are listed below as they would be using the system dir command. For
- example,"dir df1:c opt a" would list the contents of the :c directory on disk
- drive 1.
-
- THE :C DIRECTORY
-
- This directory contains the command utilities used with ARexx. These files
- should be copied to your system C: directory when you install the program.
-
- c(dir)
- hi loadlib
- rexxmast rx
- rxc rxset
- tcc tco
- te ts
-
- THE :INCLUDE DIRECTORY
-
- This directory has the INCLUDE and HEADER files used for assembly language and
- "C" programming,respectively. These files contain the structure definitions
- necessary to build an interface to ARexx.
-
- include(dir)
- errors.h rexxio.h
- rxslib.h storage.h
- errors.i rexxio.i
- rxslib.i storage.i
-
- 131
-
- THE :LIBS DIRECTORY
-
- These are the library files for the language interpreter and the Support
- Library functions. Both files should be copied to your system LIBS:directory
- when you install ARexx.
-
- libs(dir)
- rexxsupport.library rexxsyslib.library
-
- THE :REXX DIRECTORY
-
- The :rexx directory contains example programs to illustrate various features of
- the language. New files will be added from time to time,and users are welcome
- to contribute files to be distributed in this way.
-
- rexx(dir)
- bigif.rexx break.rexx
- builtin.rexx calc.rexx
- cmdtest.rexx fact.rexx
- factw.rexx haltme.rexx
- hosttest.rexx iftest.rexx
- marquis.rexx nesttest.rexx
- paver.rexx potpourii.rexx
- rslib.rexx select.rexx
- sigtest.rexx support.rexx
- test1.rexx timer.rexx
-
- THE :TOOLS DIRECTORY
-
- These files are intended for software developers,and include examples of
- interfacing to ARexx. The file rexxtest is of particular interest;it calls the
- ARexx interpreter directly,and can be run under a debugger to aid with
- developing new function libraries.
-
- tools(dir)
- hosttest hosttest.asm
- loadlib.asm rexxtest
- rexxtest.asm rxoffsets.o
-
- Miscellaneous Files
-
- .info Install-ARexx
- README Start-Aexx
-
- 132
-
- E-2 LISTINGS OF HEADER FILES
-
- This section of the chapter consists of listings of the header files contained
- in the :include directory.
-
- storage.h
-
- This is the main header file and contains definitions for all of the important
- data structures used by ARexx.
-
- /*===rexx/storage.h=================================================
- *
- * Copyright (c) 1986,1987 by William S. Hawes (All Rights Reserved)
- *
- *==================================================================
- * Header file to define ARexx data structures.
- */
-
- #ifndef REXX_STORAGE_H
- #define REXX_STORAGE_H
-
- #ifndef EXEC_TYPES_H
- #include "exec/types.h"
- #endif
- #ifndef EXEC_NODES_H
- #include "exec/nodes.h"
- #endif
- #ifndef EXEC_LISTS_H
- #include "exec/lists.h"
- #endif
- #ifndef EXEC_PORTS_H
- #include "exec/ports.h"
- #endif
- #ifndef EXEC_LIBRARIES_H
- #include "exec/libraries.h"
- #endif
-
- /* The NexxStr structue is used to maintain the internal strings in REXX.
- * It includes the buffer area for the string and associated attributes.
- * This is actually a variable-length structure;it is allocated for a
- * specific length string,and the length is never modified thereafter
- * (since it's used for recycling).
- */
-
- 133
-
- storage.h(cont.)
-
- struct NexxStr{
- LONG ns_Ivalue; /* integer value */
- UWORD ns_Length; /* length in bytes(excl null) */
- UBYTE ns_Flags; /* attribute flags */
- UBYTE ns_Hash; /* hash code */
- BYTE ns_Buff[8]; /* buffer area for strings */
- }; /* size: 16 bytes (minimum) */
-
- #define NXADDLEN 9 /* offset plus null byte */
- #define IVALUE(nsPtr) (nsPtr->ns_Ivalue)
-
- /* String attribute flag bit definitions */
- #define NSB_KEEP 0 /* permanent string? */
- #define NSB_STRING 1 /* string form valid? */
- #define NSB_NOTNUM 2 /* non-numeric? */
- #define NSB_NUMBER 3 /* a valid number? */
- #define NSB_BINARY 4 /* integer value saved? */
- #define NSB_FLOAT 5 /* floating point format? */
- #define NSB_EXT 6 /* an external string? */
- #define NSB_SOURCE 7 /* part of the program source? */
-
- /* The flag form of the string attributes */
- #define NSF_KEEP (1<< NSB_KEEP ) */
- #define NSF_STRING (1<< NSB_STRING)
- #define NSF_NOTNUM (1<< NSB_NOTNUM)
- #define NSF_NUMBER (1<< NSB_NUMBER)
- #define NSF_BINARY (1<< NSB_BINARY)
- #define NSF_FLOAT (1<< NSB_FLOAT )
- #define NSF_EXT (1<< NSB_EXT )
- #define NSF_SOURCE (1<< NSB_SOURCE)
-
- * Combinations of flags
- #define NSF_INTNUM (NSF_NUMBER | NSF_BINARY | NSF_STRING)
- #define NSF_DPNUM (NSF_NUMBER | NSF_FLOAT)
- #define NSF_ALPHA (NSF_NOTNUM | NSF_STRING)
- #define NSF_OWNED (NSF_SOURCE | NSF_EXT | NSF_KEEP
- #define KEEPSTR (NSF_STRING | NSF_SOURCE | NSF_NOTNUM)
- #define KEEPNUM (NSF_STRING | NSF_SOURCE | NSF_NUMBER | NSF_BINARY)
-
- 134
-
- storage.h (cont.)
-
- /* The RexxArg structure is identical to the NexxStr structure,but
- * is allocated from system memory rather than from internal storage.
- * This structure is used for passing arguments to external programs.
- * It is usually passed as an "argstring",a pointer to the string buffer.
- */
-
- struct RexxArg {
- LONG ra_Size; /* total allocated length */
- UWORD ra_Length; /* length of string */
- UBYTE ra_Flags; /* attribute flags */
- UBYTE ra_Hash; /* hash code */
- BYTE ra_Buff[8]; /* buffer area */
- }; /* size: 16 bytes (minimum) */
-
- /* The RexxMsg structure is used for all communications with Rexx programs.
- * It is an EXEC message with a parameter block appended.
- */
- struct RexxMsg{
- struct Message rm_Node; /* EXEC message structure */
- APTR rm_TaskBlock; /* pointer to global structure */
- APTR rm_LibBase; /* library base */
- LONG rm_Action; /* command (action) code */
- LONG rm_Result1; /* primary result (return code) */
- LONG rm_Result2; /* secondary result */
- STRPTR rm_Args[16]; /* argument block(ARGO-ARG15) */
- struct MsgPort *rm_PassPort; /* forwarding port */
- STRPTR rm_CommAddr; /* host address (port name) */
- STRPTR rm_FileExt; /* file extension */
- LONG rm_Stdin; /* input stream(filehandle) */
- LONG rm_Stdout; /* output steam(filehandle) */
- LONG rm_avail; /* future expension */
- }; /* size: 128 bytes */
- /* Field definitions
- #define ARGO(rmp) (rmp->rm_Args[0] /* start of argblock */
- #define ARG1(rmp) (rmp->rm_Args[1] /* first argument */
- #define ARG2(rmp) (rmp->rm_Args[2] /* second argument */
-
- #define MAXRMARG 15 /* maximum arguments */
-
- /* Command (action) codes for message packets */
- #define RXCOMM $01000000 /* a command-level invocation */
- #define RXFUNC $02000000 /* a function call */
- #define RXCLOSE $03000000 /* close the port */
- #define RXQUERY $04000000 /* query for information */
- #define RXADDFH $07000000 /* add a function host */
-
- 135
-
- storage.h (cont.)
-
- #define RXADDLIB $08000000 /* add a function library */
- #define RXREMLIB $09000000 /* remove a function library */
- #define RXADDCON $0A000000 /* add/update a ClipList string */
- #define RXREMCON $0B000000 /* remove a ClipList string */
- #define RXTCOPN $0C000000 /* open the trace console */
- #define RXTCCLS $0D000000 /* close the trace console */
-
- /* Command modifier flag bits */
- #define RXFB_NOIO 16 /* suppress I/O inheritance? */
- #define RXFB_RESULT 17 /* result string expected? */
- #define RXFB_STRING 18 /* program is a "string file"? */
- #define RXFB_TOKEN 19 /* tokenize the command line? */
- #define RXFB_NONRET 20 /* a "no-return" message? */
-
- /* Modifier flags */
- #define RXFF_RESULT (1<< RSFB_RESULT)
- #define RXFF_STRING (1<< RXFB_STRING)
- #define RXFF_TOKEN (1<< RXFB_TOKEN )
- #define RXFF_NONRET (1<< RXFB_NONRET)
- #define RXCODEMASK $FF000000
- #define RXARGMASK $0000000F
-
- /* The RexxRsrc structure is used to manage global resources.
- * The name string for each node is created as a RexxArg structure,
- * and the total size of the node is saved in the "rr_Size" field.
- * Functions are provided to allocate and release resource nodes.
- * If special deletion operations are required,an offset and base can
- * be provided in "rr_Func" and "rr_Base",respectively. This function
- * will be called with the base in register A6 and the node in A0.
- */
- struct RexxRsrc {
- struct Node rr_Node;
- WORD rr_Func; /* a "auto-delete" offset */
- APTR rr_Base; /* "auto-delete" base */
- LONG rr_Size; /* total size of node */
- LONG rr_Arg1; /* available ... */
- LONG rr_Arg2; /* available ... */
- }; /* size: 32 bytes */
- /* Resource node types */
- #define RRT_ANY 0 /* any node type ... */
- #define RRT_LIB 1 /* a function library */
- #define RRT_PORT 2 /* a public port */
- #define RRT_FILE 3 /* a file IoBuff */
- #define RRT_HOST 4 /* a function host */
- #define RRT_CLIP 5 /* a Clip List node */
-
- 136
-
- storage.h (cont.)
-
- /* The RexxTask structure holds the fields used by REXX to communicate with
- * external processes,including the client task. It includes the global
- * data structure(and the base environm
-