![]() |
Iron Spring PL/I compilerProgramming Guide
|
| This is alpha software. The compiler is capable of compiling itself, but no guarantee of completeness or correctness should be inferred. Many PL/I features, or parts of features, that were not necessary for the compiler have been omitted from the initial version. A partial list is provided under restrictions below. |
PL/I is widely used on mainframes and midrange systems today, but since the demise of Digital Research, Inc. has not been easily available on personal computers.
This as an alpha version of Iron Spring PL/I. Version 0.5d is missing many features and parts of features of full PL/I. The section Restrictions lists many of the missing features.
Trademarks
eComStation is a trademark of Serenity Systems International.
EMX is a trademark of Eberhard Mattes.
Gnu is a trademark of the Free Software Foundation.
IBM is a trademark of IBM, Inc.
Intel is a trademark of Intel Corporation.
Iron Spring is a trademark of Iron Spring Software.
Linux is a registered trademark of Linus Torvalds.
WATCOM is a trademark of Sybase, Inc. and its subsidiaries.
| Compiler Limits | |
|---|---|
| Maximum number of dimensions | 15 |
| Maximum number of levels in a structure | 15 |
| Maximum level number in a structure | 255 |
| Maximum number of picture characters in a picture (after expanding all repetition factors) | 511 |
| Maximum length of a CHAR or BIT string (after expanding all repetition factors) | ~32000 |
| Maximum nesting depth of %include files | 4 |
| Maximum precision of FIXED DECIMAL data | 18 |
| Default precision of FIXED DECIMAL data | 5 |
| Maximum precision of FIXED BINARY data | 31 |
| Default precision of FIXED BINARY data | 15 |
| Maximum precision of FLOAT DECIMAL data | 20 |
| Default precision of FLOAT DECIMAL data | 6 |
| Maximum precision of FLOAT BINARY data | 64 |
| Default precision of FLOAT BINARY data | 52 |
| Minimum/maximum scale factor | -128 / 128 |
| Maximum length of an internal or external label | 31 |
See Restrictions for information on major language features that are not currently implemented.
| ALLOCATE | ALLOCATE(n) allocates n bytes of storage and returns a pointer to the first byte. |
| BYTE | BYTE returns a character string of length one. Byte(n) is equivalent to the
following: SUBSTR( COLLATE(), MOD(n,256)+1, 1 ) |
| COLLATE | COLLATE Returns a character string of length 256 containing all 256 possible character values. |
| COMPARE | COMPARE(x,y,z) compares "z" bytes from locations pointed to by "x" and "y". |
| COPY | COPY(x,y) returns a string consisting of "y" concatenated copies of string "x". |
| PLIFILL | PLIFILL moves requested number of copies of a single byte to a specified location with no conversion, padding, or truncation. |
| PLIFREE | PLIFREE frees storage allocated by ALLOCATE |
| PLIMOVE | PLIMOVE(x,y,z) moves "z" bytes to the location pointed to by "x" from the location pointed to by "y". |
| RANK | RANK returns a FIXED BINARY(15) result. The argument for RANK is a
character string of length one. RANK(c) is equivalent to the following: INDEX( COLLATE(), c ) - 1 |
EXTERNAL data (not EXTERNAL ENTRY) is not shared between executable and DLL code, nor among procedures in different DLLs. For example, data declared DECLARE a EXTERNAL POINTER; will identify different "a"s in procedures linked into in the executable, in DLL "1", and DLL "2". Within the executable or any one of the DLLs all occurrences of that declaration will identify the same "a".
The OPTIONS keyword on an ENTRY or PROCEDURE statement or an ENTRY declaration provides information regarding the linkage convention to be used.
OPTIONS( LINKAGE(SYSTEM) ) indicates that the entry uses
a C-type linkage convention, where arguments are passed by value without descriptors.
This can be used to call OS/2 functions which use this convention, but is also a valid
convention among PL/I procedures, with some restrictions.
For source compatibility with IBM PL/I for OS/2, specify
'OPTIONS( BYVALUE LINKAGE(SYSTEM)'.
BYVALUE is assumed by this compiler and the keyword is ignored, but IBM PL/I defaults
to BYADDR unless otherwise specified.
OPTIONS( LINKAGE(OPTLINK) ) will be implemented in a future version to specify the "Optlink" calling convention that uses registers for some arguments.
OPTIONS( ASM ) indicates that the called entry point is a non-PL/I entry, and saves an instruction on the call.
If OPTIONS is not specified, a standard PL/I calling convention is used where arguments are passed by reference and descriptors are passed for arguments other than computational element-variables.
An example of an entry declaration using these features and the equivalent C-language definition is:
DECLARE Create_MUTEX ENTRY( PTR, PTR, FIXED BIN(31), FIXED BIN(31) )
RETURNS( FIXED BIN(31) )
OPTIONS( ASM BYVALUE LINKAGE(SYSTEM) )
EXTERNAL( 'DosCreateMutexSem' );
ULONG DosCreateMutexSem (PCSZ pszName, PHMTX phmtx, ULONG ulAttr, BOOL32 fState);
The syntax of the PLIC command is:
PLIC [<options>] <input files> [-o <output file>]
<options> = <output option> [<include options>] [<listing options>]
[<source margins>] [<character substitutions>] [<version info>]
[<error option>] [<misc options>]
(options may be entered in any order).
<output option> = -S | -C | -L
-S = generate assembler (symbolic) output.
This is the only output option currently supported.
-C = generate compiled (object) output.
-L = generated linked (EXE or DLL) output.
<include options> = -i<directory>
where <directory> is the absolute or relative path
to a directory to be searched for %INCLUDE files.
This option may be used more than once on the command line,
and directories will be searched in the order listed.
<listing options> = -l[siaxg]
one or more of [siaxg] may be entered, in any order.
-ls = list source
-li = list insource
-la = list attributes
-lx = list cross-reference
-lg = list aggregates
None of these options are currently implemented, the source
and attribute listings are always generated.
<source margins> = -m(start[,end])
This option defines the first and last positions of each
input line that contain input for the compiler. If this
option is omitted the source is assumed to be the entire line.
This is included for compatibility with mainframe compilers
which would use, for example, -m(2,72).
There is no restriction on the length of an input line.
<character substitutions> = -cn(<list>) and/or
-co(<list>)
This option defines up to four characters each to be used as
substitutions for the NOT(¬) [-cn()] and/or OR(|) [-co()]
operator IN ADDITION TO the defaults. The caret (^) is
a metacharacter for the OS/2 command processor; if the
caret is to be used, code two consecutive carets,
for example -cn(^^).
<version info> = -V
The compiler prints version and copyright information.
<error option> = This option sets the errorlevel returned by the compiler for warning
and error messages. Normally compiler returns 4 if only warnings were
issued, and 8 for any errors.
-ew tells the compiler to return 0 if only warning messages were issued.
-es tells the compiler to return 0 if any errors or warnings were issued.
This option is useful when the compiler is run from a script or makefile.
<misc options> = -d<option> where <option> is a character string, with or without enclosing quotes.
Currently the only miscellaneous option is -dLIB to tell the compiler it
is compiling a standard run-time library procedure.
<input files> and <output files> are absolute or relative path names. Ony one input and one
one output file are currently allowed. If the output file is omitted the name
is generated. For example, PLIC -S abc.pli will create a file named abc.asm.
The input file must be plain-text, with lines delimited by either a linefeed
[PL/I ENV(LF)] or carriage-return/linefeed [PL/I ENV(CRLF)]. There is no maximum
length for the input line, however each token is limited to approximately
32000 characters.
| Internal Data Representations | |
|---|---|
| FIXED BIN, precision 7 or less | BYTE |
| FIXED BIN, precision 15 or less | WORD |
| FIXED BIN, precision 31 or less | DWORD |
| FIXED DEC, any precision Intel x87 BCD format | TBYTE |
| FLOAT BIN, precision 23 or less Intel x87 short floating-point | REAL4 |
| FLOAT BIN, precision 52 or less Intel x87 long floating-point | REAL8 |
| FLOAT BIN, precision>52 Intel x87 extended floating-point | REAL10 |
| FLOAT DEC, precision 5 or less | REAL4 |
| FLOAT DEC, precision 14 or less | REAL8 |
| FLOAT DEC, precision>14 | REAL10 |
| CHARACTER(n) | n bytes |
| BIT(n) ALIGNED | (n+7)/8 bytes |
| BIT(n) UNALIGNED | n bits |
| PTR, OFFSET | NEAR PTR |
Run-time messages: All run-time messages are written to stderr:
For OS/2 system exceptions, "hhhhhhhh" and "tttttttt" are the hexadecimal value and the description of the exception respectively.
Work file:
The compiler creates a temporary work file named PLI-xxxxxxxx-yyyyyyyy-zzzzzzzz.tmp
in the current working directory. Normally this file is deleted at the end
of compliation. Errors in the alpha version of the compiler causing
certain traps may prevent deletion of this file. If it not automatically removed
it may be deleted manually.
Iron Spring PL/I can read and write:
File Declarations
The general form of a file declaration is shown below. As usual, keywords can be specified in any order. Many
keywords may be specified either in the declaration or in the OPEN statement for the file. If they are
specified in both, they must not conflict. For example, a file declared INPUT cannot be opened as OUTPUT.
>>-DECLARE-name-+------+-+--------+-+--------+-+----------------------------------+-+---------------+-><
| | | | | | | | | |
+-FILE-+ +-RECORD-+ +-INPUT -+ +-ENVIRONMENT(environment options)-+ +-other attributes-+
| | | |
+-STREAM-+ +-OUTPUT-+
| |
+-UPDATE-+
RECORD and STREAM Files
INPUT, OUTPUT, and UPDATE
| SYSIN | ENV(V CRLF RECSIZE(120)) LINESIZE(120) |
| SYSPRINT | ENV(V CRLF RECSIZE(120)) LINESIZE(120) PAGESIZE(60) |
| If stdin and stdout are the current VIO window, these files default to ENV( BLKSIZE(0) ). | |
STREAM files default to ENV(V CRLF) unless other attributes are specified. All other ENV(V) files default to ENV(V VARLS). Specifying PAGESIZE(0) on the OPEN statement will suppress page breaks for PRINT files.
Data Specification
SKIP[(expr)]
PAGE
LINE(expr)
tempnam generates a unique name for a temporary file.
The following steps are not required, but will simplify debugging.
To get the debugger to stop at the beginning of the PL/I program,
make the following modifications to "setup.dbg", normally found
in the <WATCOM>\binw directory.
The IBM "ASDT" debugger is also usable.
Sometimes it may be desirable to compile-in a breakpoint
to be activated when a specific location is reached or
condition occurs. The following statement inserted in your
source will activate a breakpoint when it is reached when running
under control of a debugger:
SNAP traceback
The PL/I statement "ON CONDITION(xxx) SNAP..." will generate a traceback
to stderr
when the specified condition is raised. Beginning with the procedure
generating the traceback (_pli_Trace) and working backwards, the trace
lists the address of the active entry point of the procedure, the address
of the statement in the calling procedure that called that entry, and
the name of the entry point if available.
PLIDUMP output
The PL/I statement "CALL PLIDUMP( "<options>", "<title>" );
will generate debugging output to stderr when executed.
"title" is a character string used as the title of the dump. "options"
provide one or more dump options, 'S' = terminate, 'C'=continue, 'T'=print traceback,
'B' = dump automatic storage. Options may be combined and may appear in
any order, for example "TCB" means print trace, continue after snap, and dump
all automatic storage. Storage is dumped in three sections: Temporaries (argument lists
and storage used during expression evaluation), Data (non-temporary user data in
the stack frame), and DSA (system data in stack frame). The layout of the DSA is
given in lib\include\dsa.inc. This is subject to change in future releases.
Input/Output Statements
OPEN and CLOSE apply to both STREAM and RECORD files. The GET and PUT
statements operate on STREAM files. The READ, WRITE, REWRITE, and LOCATE
statements operate on RECORD files. The assumption is made that the reader is familiar with, or has access
to a reference for, the I/O statements of IBM PL/I for MVS and VM. Only the syntax accepted by Iron Spring
PL/I is shown here, no explanation is provided.
+----------------------- , -------------------------------------+
v |
>>-OPEN--.---FILE(file_ref)-+------------------+----+---------------+----+---- ; ----><
| | | |
+-|stream-options|-+ +-TITLE(string)-+
| |
+-|record-options|-+
|stream-options|
+-INPUT ---------------------------+
| |
|----STREAM---+----------------------------------+-+-------------+-----|
| | | |
+OUTPUT ---+-----------------------+ +-LINESIZE(m)-+
| |
+-PRINT-+-------------+-+
| |
+-PAGESIZE(n)-+
|record-options|
+-INPUT -+
| |
|---RECORD----+--------+-+------------+-+-------+------|
| | | | | |
+-OUTPUT-+ +-BUFFERED---+ +-KEYED-+
| | | |
+-UPDATE-+ +-UNBUFFERED-+
STREAM Input/Output
>>-GET-FILE(file_ref)-+-----------------+-+----------------------+- ; --><
| | | |
+-SKIP----------+-+ +-|data_specification|-+
| |
+-(expr)-+
>>-PUT-FILE(file_ref)-+---------------------+-+----------------------+- ; --><
| | | |
+-PAGE-+------------+-+ +-|data_specification|-+
| | | |
| +-LINE(expr)-+ |
| |
+-SKIP-+--------+-----+
| | | |
| +-(expr)-+ |
| |
+-LINE(expr)----------+
|--+------+---( |data-list| )---------------------+----|
| | |
+-LIST-+ |
| |
+-DATA---+-----------------+-------------------+
| | | |
| +-( |data-list| )-+ |
| |
| +-----------------------------------+ |
| v | |
+-EDIT---.-( |data-list| )-( |format-list| }-+-+
The SKIP option causes a new line to be started
in the data stream prior to transmitting any data from the current or subsequent GET or PUT statement.
The (expr) is converted to an integer n. On output, n newlines (linefeed or
carriage-return/linefeed) are inserted. On input the remainder of the current line and the n-1 following
lines are skipped.
If (expr) is omitted or not greater than zero, 1 is used for the value of n.
For PRINT files, the ENDPAGE condition may be raised if PAGESIZE is exceeded.
The PAGE option is valid only for PRINT files. It causes a page eject (ASCII '0C'x)
to be inserted in the output stream prior to transmitting any data from the current or subsequent
PUT statement. If both PAGE and LINE are present, the PAGE option is
applied first.
The LINE option is valid only for PRINT files. It causes a new line to be started
in the output stream prior to transmitting any data from the current or subsequent PUT statement.
The (expr) is converted to an integer n. If n or more lines have been written on the
current page, or if n exceeds PAGESIZE, a new page is started. newlines are inserted in
the output strean to position the next data written at line n.
If (expr) is less than or equal to zero, 1 is used for the value of n.
RECORD Input/Output
>>-READ-FILE(file_ref)-+-----------------------------------+----------- ; --><
| |
+-INTO(ref)-+-------------+---------+
| | | |
| +-KEY(expr)---+ |
| | | |
| +-KEYTO(ref)--+ |
| |
+-SET(pointer-ref)-+-------------+--+
| | | |
| +-KEY(expr)---+ |
| | | |
| +-KEYTO(ref)--+ |
| |
+-IGNORE(expr)----------------------+
>>-WRITE-FILE(file_ref)--FROM(ref)--+-------------------------+----------- ; --><
| |
+-KEYFROM(expr)-----------+
| |
+-KEYTO(ref)--------------+
>>-LOCATE--based-variable--FILE(file-ref)--+--------------------------------------+---- ; --><
| | | |
+-SET(pointer-ref)-+ +-KEYFROM(expr)--+
>>-REWRITE-FILE(file_ref)--+-----------+--+-----------+----------- ; --><
| | | |
+-FROM(ref)-+ +-KEY(expr)-+
User-callable PL/I Library Procedures
Most of the procedures in the PL/I runtime library (prf.lib) are for use by the compiler
and are not user-callable. The following, however, may be useful:
osdelete deletes a file by name.
DECLARE osdelete ENTRY( CHAR(*) VAR )
RETURNS( FIXED BIN(31) )
EXT( '_pli_OSDelete' );
DECLARE rc FIXED BIN(31);
RC = osdelete( filename );
0 indicates no error.
2 indicates that the file was not found.
for other errors see the OS/2 Operating System Control Program
Guide and Reference.
DECLARE tempnam ENTRY( CHAR(*) VAR, CHAR(*) VAR, CHAR(*) VAR )
RETURNS( CHAR(260) VARYING)
EXT( '_pli_Tempnam' );
DECLARE temp_filename CHAR(260) VARYING;
temp_filename = tempnam( sDir, sPfx, sSfx );
'sPfxpppppppp-tttttttt-uuuuuuuusSfx'
where 'pppppppp' is the hex value of the current process id (pid),
'tttttttt' is the hex value of the current thread id (tid), and 'uuuuuuuu'
is a unique number within this process. If another file with this name
already exists, the unique number is incremented until the generated name
does not confilct with an existing file.
Debugging PL/I programs
The WATCOM® debugger may be used to debug PL/I programs.
Source-level debugging is not yet available, but since the
compiler can generate assembly-language output, debugging
at the assembly level is straightforward.
After this, you will also need to link your program with a module definition file
to export the symbol "_PLI_Main" so that it is visible to the debugger.
The "samples" directory contains an example .def file and linker command
to do this.
elseif _dbg@dbg$os == 12 && ?@main { Following this go/until/noflip @main } elseif ?@@_PLI_MAIN { Insert these three lines go/until/noflip @@_PLI_MAIN } *PROCESS DBG(INT3);
If the resulting executable is not run under a debugger, the
interrupt will be ignored. Nevertheless, INT3 traps should not be
left in a production program.
version 0.5d, 30 Jan, 2008
http://www.iron-spring.com