|
Iron Spring PL/I compiler
Programming Guide
Alpha Version 0.5d
|
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 a powerful programming language suitable for a wide range of
problems. PL/I has been used to write operating systems and compilers,
simulations, real-time programs, mathematical software, spreadsheets,
GUI programs, and for general computing.
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.
This is a list of major current restrictions of the compiler.
The compiler currently generates assembler output. Generation of
.obj files is a priority goal for the near future.
The compiler doesn't yet support building Presentation Manager
applications. Only text-mode applications are allowed.
This is a priority goal.
PL/I procedures can call functions coded in other languages as
long as they use the "system" calling convention. Programs coded
in other languages can not yet call PL/I procedures. The "optlink"
and other calling conventions are not supported.
Compiled PL/I code has not yet been tested as part of a DLL.
major features not implemented
- Preprocessor
- In the current version of the compiler the only preprocessor statements fully
implemented are %INCLUDE and the listing control statements %PAGE, %SKIP[(n)], %PRINT,
and %NOPRINT.
%PROCESS (*PROCESS) is implemented incompatibly from the IBM compilers.
All other preprocessor
statements will generate a diagnostic.
- Special characters
- The compiler currently uses the Unicode characters U+00AA for 'NOT' (¬),
and U+007C for 'OR' (|). Other characters may be coded on the command-line
to also represent these operators. (NOT is Alt-1-7-0 on the numeric keypad).
- Tasking
- TASK and EVENT data, the WAIT statement, and the tasking builtins PRIORITY,
COMPLETION, and STATUS.
- GENERIC attribute
- The GENERIC attribute.
- DEFAULT
- The DEFAULT statement.
- Input/output
- The I/O statements DELETE and UNLOCK are not implemented due to differences in Input/Output
of the PC vs. the mainframe. This is a permanent restriction.
The COPY option of the GET statement, the ONKEY and SAMEKEY builtin functions.
Data-directed I/O is not currently supported.
- FETCH and RELEASE
- The FETCH and Release statements are not currently implemented.
- Array Handling builtins
- The following array handling builtin functions
are not implemented in the current version of the compiler: ALL, ANY, POLY, PROD,
and SUM.
- Mathematical builtins
- The following mathematical builtin functions
are not implemented in the current version of the compiler:
ACOS | COS | LOG | SINH | EXP |
ASIN | COSD | LOG2 | SQRT |
ATAN | COSH | LOG10 | TAN |
ATAND | ERF | SIN | TAND |
ATANH | ERFC | SIND | TANH |
- Arithmetic builtins
- The following arithmetic builtin functions
are not implemented in the current version of the compiler:
ADD | CONJG | DIVIDE | SUBTRACT | MULTIPLY |
ROUND | TRUNC |
- PLICKPT, PLICANC, PLIREST, PLITEST
- These builtins are not implemented. This is a
permanent restriction.
- PLISRTx
- The sort builtin functions PLISRTA, PLISRTB, PLISRTC, and PLISRTD
are not currently implemented. It is anticipated that versions of these functions
that interface to one or more sort products will be added in the future.
- Aggregate Results
- Builtin functions will not return agregate results in the current
version. This is similar to Subset G support for builtins.
- AREA
- The AREA attribute, AREA data. and the EMPTY builtin function are not currently supported.
- GRAPHIC data
- GRAPHIC data support will not be included in this compiler. This is a permanent restriction.
A future version will include
WIDECHAR data for 16-bit Unicode character support. The features not supported include:
- LIKE
- The LIKE attribute is implemented with one restriction. If a structure is declared
as DECLARE a LIKE b; and some elements of "b" have the INITIAL
attribute, the initialization is not performed for "a". This will be fixed in a future version.
- DEFAULT
- The DEFAULT statement is not implemented in the current version.
- *PROCESS
- The *PROCESS statement is used by this compiler to provide debug support.
Parameters not recognized are ignored.
Other features
The compiler error message 995 ("Unimplemented feature xxx") and the
run-time condition "UNIMPLEMENTED" are used to flag unimplemented
features. Except for "premanent restrictions" noted above,
these should be removed in future releases. Some less-used
conversions may be only partially implemented.
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 |
Except as noted under Compiler Differences and
Restrictions this compiler is compatible with
The IBM "PL/I for MVS and VM Compiler 1.1". Complete HTML documentation will
be available as part of a future release. In the meantime, documentation
for the IBM compiler is available
online.
The reference implementation for this compiler is IBM PL/I for MVS and VM 1.1.
Most of the differences are in the area of Input/Output.
See the section Input and Output for a description of
the input/output facilities.
See Restrictions for information on major language
features that are not currently implemented.
- Special characters
- Alternate characters can be substituted for the NOT (ª) and
OR (|) operators. See Running the compiler for the procedure for
specifying additional characters. String data can be delimited by either the single (')
or double (") quote characters. The same character must be used to begin and and the
string. The character not used as a delimiter may be part of the string.
If portability is a concern, use only the single-quote to delimit strings.
- DECIMAL FLOAT
- DECIMAL FLOAT data is simulated using BINARY FLOAT. This is similar
to S/370 PL/I implementations that simulate both DECIMAL FLOAT and BINARY FLOAT using
the hardware Hexadecimal floating point formats.
- FIXED BINARY
- FIXED BINARY data with precision 7 or less is stored in a single byte.
- ONCODE
- The ONCODE builtin function returns only the base value of the error code.
For example, IBM PL/I can return codes 600 to 639 for CONVERSION. This compiler will
return 600 in all cases. This is a permanent restriction.
- Additional builtins
- The following additional builtin functions are supported:
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
|
- ATTENTION
- The ATTENTION condition is always enabled. It is raised by pressing ^C while running
a VIO application or otherwise sending XCPT_SIGNAL_INTR to the PL/I process. If no ON-Unit is established
for ATTENTION, the implicit action is the same as for ERROR: Print an error message and raise the
FINISH condition. On normal return from an established ON-Unit, execution continues unaffected.
Note that signal interrupts are sent only to thread 1 (the major task). Due to OS/2 restrictions,
a backtrace printed as a result of 'ON ATTENTION SNAP ...' may be incomplete.
- EXTERNAL Attribute and Program Linkage
-
The EXTERNAL attribute has been enhanced to allow the provision of a non-PL/I name visible to procedures
outside the PL/I program. The syntax is EXTERNAL( 'environment_name' )
, where the character string 'environment_name' can contain any characters
acceptable to the OS/2 linker. The declaring PL/I code recognizes only the declared name.
External "environment_name"s beginning with the string "_pli" are reserved for use by the
run-time library. If the 'environment name' is not specified, the default external name is
an uppercase translation of the first label on the external procedure, or of the declared entry
name. For example,
x: y: PROCEDURE; will use "X" as the external name for the linker.
DECLARE abc ENTRY; will use "ABC".
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 "PLIC" command is used to invoke the compiler.
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.
Compiler output currently consists of the source and attribute listing,
and an assembler file of the compiled program.
Source and attribute listing:
Compiling a program xxx.pli will create a combined source listing/data attributes file named xxx.lst.
Future compiler versions will add additional listing options and allow more flexibility in what is produced.
Here are a few lines from a listing: The letters are a key to the descriptions below, and are not part of the listing.
A B C
340
341 %include DSA;
342
D E F
341 (INF104)Processing include file DSA.
G
1 /********************************************************************/
2 /* */
'B' is the line number. The source file and each %include file
are numbered starting from line one. A future compiler version will also provide a file
number for each include file to be used on error messages.
'C', the next 100 characters of the listing, show the input line. If the line is longer than
100 characters additional unnumbered lines will display the excess.
The line following line 342 above shows the format of error, warning, and information messages.
'D' is the source line number. 'E' is the message number and severity (xxxyyy)
'xxx' is 'INF' for information-only messages as shown,
'WRN' for warnings, and 'ERR' for errors. 'yyy' is a unique message identifier for this error.
'F' is the message text.
Currently messages generated by the parser appear intermixed in the source listing, while code
generator messages appear at the end of the source. In a future version all messages will appear at the end.
The listing is paginated with imbedded formfeed characters 'G', currently every fifty-six lines.
Following the source listing the attribute list (symbol table) is printed as shown below.
A future release will optionally combine a cross-reference listing. Variables are listed in
alphabetic order.
H I J K
ADDR 124 Builtin
BSW 309 Entry Unaligned < Code+'13C0'x >
BYTE 332* Builtin
C 77 Char(1) Unaligned < DSA-'51'x(1) >
C4 109 Char(4) Unaligned Based < +'00'x(4) >
C4 327 Char(4) Unaligned Parameter < Loc @DSA+'08'x(4) >
CONDS 97 (9) Char(6) Var Unaligned Static Init() < Static+'12'x(8) >
DSA_BELOW_EBP 27 Unaligned Structure In(PLI_DSA) < +'00'x(32) >
DSA_CHC 33 Ptr Aligned In(PLI_DSA.DSA_BELOW_EBP) < +'08'x(4) >
PLI_DSA 340 Unaligned Based Structure Level(1) < +'00'x(40) >
'H' is the name of the data element. If the name is longer than twenty characters it will appear
on a line by itself, with the remaining data shown on the next line. 'I' is the line
number of the declaration of this item. Undeclared data, like 'BYTE' above show the line number where this
element is first used, followed by '*'.
'J' lists the data attributes, which should be self-explanatory. This field may occupy more than one line.
'K shows the address of the item in '<' '>'. The addresses are displayed as follows:
- Code labels
- Code+'oooo'x. 'oooo' is the hexadecimal offset from the label '_pli_code'. See 'BSW' above.
- STATIC data
- Static+'oooo'x(ll). 'oooo' is the offset from the label '_pli_data. 'll' is
the (decimal) length of the data element. If this was an UNALIGNED BIT element, the length would
be shown as (x.y) where 'x' is the number of whole bytes, and 'y' is the number of additional bits.
For an array, 'll' is the length of one member. See 'CONDS' above.
- AUTOMATIC data
- DSA-oooo'x(ll). 'oooo' is the offset from the start of the DSA containing the data.
Register EBP always points to the current DSA. Lexically containing DSAs (static scope) are chained from
offset -8 in the contained DSA. See the file 'DSA.INC' distributed with the library. 'C' above
is an example of AUTOMATIC data.
- BASED data
- +'oooo'x(ll). 'oooo' shows the offset from the beginning of the BASED variable or
structure. See the first occurrence of 'C4' above.
- Data addressed via locator
- Loc @DSA±'0000'(ll). This is the address format for parameters,
adjustable data, and CONTROLLED data. 'oooo' is the offset of the locator/descriptor which points to
and describes the data. See the second 'C4' above.
If there were any errors or warnings, a message showing the number of them appears at the end of the listing.
Assembler output:
Compiling a program xxx.pli will create an assembler file xxx.asm in a format suitable for the
IBM ALP assembler. Other assemblers will most likely not be able to assemble this file.
A future version of the compiler will produce .obj, .exe, and .dll files. A few lines
of assembler output are shown:
; Stmt 31, Line 128 (Assignment)
.code
mov byte ptr -77[ebp],29h ; 00000023(4)
The source statement and line number that generated each piece of code, along with
the statement type is shown as indicated. The line number ties this code to the source
listing. Each line of code and some lines of data contain a comment at the end
indicating the hex offset and length of this assembler statement. Offsets for EXTERNAL
data always start at zero.
The generated program consists of a single code segment '_pli_code', a single static data segment
'_pli_data', an unnamed stack segment, and zero or more external data segments.
No BSS segment is currently generated:
PL/I programs typically do not contain large amounts of uninitialized static data that would go
into a BSS segment, although it is possible one will be added later.
External segments are generated for each variable or structure declared EXTERNAL, as well as for
each EXTERNAL FILE. If the variable has the INITIAL attribute the data is always generated, otherwise the
declared amount of storage is reserved. Here is the generated code for an uninitialized
external segment named MSGBLK:
MSGBLK segment dword common 'MSGBLK'
_MSGBLK EQU $
org _MSGBLK+34h
MSGBLK ends
Here is the code for the initialized external segment SYSIN:
SYSIN segment dword common 'SYSIN'
_SYSIN EQU $
dd 0 ; FFFFFFFF(4)
dd 0 ; 00000003(4)
dd _SYSIN+12
dw 5 ; 0000000B(2)
db 'SYSIN'
SYSIN ends
The linker combines all identically-named external segments. The resulting length
will be the length of the largest such segment. The data values will be taken from the first
initialized segment encountered.
All declarations of EXTERNAL data should be identical in length, and, if one or more of
the declarations contains the INITIAL attribute, the initial values should be the same.
It is permissible to have only one declaration of EXTERNAL data have the INITIAL attribute, and
all procedures declaring it will reference that data.
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:
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.
In the following discussion, delimiter signifies either a linefeed character (ASCII '0A'x),
or a carriage-return/linefeed combination (ASCII '0D0A'x).
Iron Spring PL/I can read and write:
- Standard OS/2 text files, with lines of text terminated by delimiters.
- Files of fixed-length records with or without delimiters.
- Files of variable-length records where the length of each record
is indicated by a two-byte binary prefix, with or without delimiters.
- Files containing arbitrary streams of binary data with no record boundaries.
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-+
The ENVIRONMENT attribute allows specification of implementation-dependent options for a file.
Iron Spring PL/I allows coding of all ENVIRONMENT attributes allowed by IBM PL/I for MVS and VM.
Only attributes actually used are described here.
- Record format keywords: D, DB, F, FB, FS, FBS, V, VB, VS, VBS, U. One of these keywords is
coded to indicate the type of records to be processed. Only the D, F, V, and U are significant, the others
are provided for compatibility. F indicates that the file is expected to consist of records having all
the same length. V or D indicate that the records in the file can have different lengths.
U indicates that the file will be read or written as a stream of bytes with no record boundaries.
The options CRLF, LF, and VARLS provide additional information about format F, V,
and D files.
Record format U allows reading and writing files without regard to formatting or record boundaries.
When reading INTO a character string, the amount of data available up to the maximum
length of the string is returned. ENDFILE is raised only on the next read after the last byte has been returned.
See the sample program 'readu.pli' for an example of using ENV(U) to read a file with no
predetermined maximum record length. Writing FROM a character string writes n bytes of data from the
string, where n is the current or constant length of the string.
- BLKSIZE(n) specifies the size of the buffer used to transfer data to or from the file or device.
If this keyword is not specified, a default value is used.
- RECSIZE(n) specifies the uniform record length for F files, or the maximum record length for
V or D files. If this keyword is not specified, the default is LINESIZE. The RECSIZE value
describes only the data portion of the record, exclusive of delimiters, length prefixes, etc.
- CRLF or LF specifies the presence of record delimiters. If neither is specified, no delimiters
will be written on output or expected on input. LF indicates that a single newline character (ASCII '0A'x)
delimits records in the file (Unix convention). CRLF indicates that a carriage-return/linefeed combination
(ASCII '0D0A'x) is used as a delimiter (DOS convention). The delimiters will be written as specified on output, but
either is always acceptable for input.
- VARLS specifies that records in the file will be written with a FIXED BINARY(15) prefix containing the
length of the record.
- APPEND specifies that an INPUT or UPDATE file will have data appended to the end if it
already exists. When the file is opened, the current file position will be set to the end of the file.
- Storage attributes ALIGNED, UNALIGNED, AUTOMATIC, BASED, DEFINED, STATIC, INTERNAL, and EXTERNAL may be
used with declarations of file variables. INTERNAL and EXTERNAL are also applicable to file constants.
The default for a file constant is EXTERNAL.
- BUFFERED or UNBUFFERED are used to control the amount of storage that will be used for buffers
for this file. BUFFERED requests that a storage area a multiple of record size is to be used to handle
transfers to or from the file or device, minimizing interaction with the Operating System. UNBUFFERED requests
that each record is read or written immediately, and no additional storage is used.
- KEYED indicates that keys may be used to select a particular record to be read or written, bypassing
normal sqeuential processing. A key for this implementation is a CHARACTER(12) data item which uniquely identifies
a record in the file. This is not intended to be user-modifiable data, except that key of (12)'00'x indicates the beginning
of the file, and (12)'FF'x indicates the end. The KEY, KEYFROM, and KEYTO keywords may be used
on I/O statements to receive or supply the identifier of the record.
- PRINT is an additional attribute for STREAM OUTPUT files indicating that this file is ultimately
destined to be printed. The compiler keeps track of the current "page" and "line" in the file, and raises the
ENDPAGE condition when starting a new page. PRINT also enables print-related processing of the PAGE
option on the PUT statement and the PAGE format item.
- VARIABLE indicates that this declaration is a file variable rather than a file constant.
File variables can be assigned the value of a file constant at run time, for example, to pass a file
as a parameter to a procedure, but cannot be used for I/O unless a value has been assigned.
Unless overridden by ENVIRONMENT or OPEN, the
standard files SYSIN and SYSPRINT default to stdin and stdout with the following attributes
respectively.
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.
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.
- OPEN statement.
-
+----------------------- , -------------------------------------+
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-+
TITLE
The TITLE(string) option provides the OS/2 "filespec" of the file to be read or written.
"String" is any valid character string expression.
If the TITLE is omitted, the file name used by OS/2 will be the declared PL/I filename
in uppercase, except for SYSIN and SYSPRINT which default to stdin and stdout.
The TITLE may be a full filespec [TITLE('C:/test.dat')], an OS/2 device name
[TITLE('LPT1:')], or a relative filespec.
Unlike IBM OS/2 PL/I, file attributes may not be specified in the title string.
- CLOSE statement.
-
+----- , ---------+
v |
>>-CLOSE--.--FILE(file_ref)-+-- ; --><
STREAM Input/Output
- GET statement.
-
>>-GET-FILE(file_ref)-+-----------------+-+----------------------+- ; --><
| | | |
+-SKIP----------+-+ +-|data_specification|-+
| |
+-(expr)-+
- PUT statement.
-
>>-PUT-FILE(file_ref)-+---------------------+-+----------------------+- ; --><
| | | |
+-PAGE-+------------+-+ +-|data_specification|-+
| | | |
| +-LINE(expr)-+ |
| |
+-SKIP-+--------+-----+
| | | |
| +-(expr)-+ |
| |
+-LINE(expr)----------+
Data Specification
|--+------+---( |data-list| )---------------------+----|
| | |
+-LIST-+ |
| |
+-DATA---+-----------------+-------------------+
| | | |
| +-( |data-list| )-+ |
| |
| +-----------------------------------+ |
| v | |
+-EDIT---.-( |data-list| )-( |format-list| }-+-+
SKIP[(expr)]
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.
PAGE
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.
LINE(expr)
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 statement.
>>-READ-FILE(file_ref)-+-----------------------------------+----------- ; --><
| |
+-INTO(ref)-+-------------+---------+
| | | |
| +-KEY(expr)---+ |
| | | |
| +-KEYTO(ref)--+ |
| |
+-SET(pointer-ref)-+-------------+--+
| | | |
| +-KEY(expr)---+ |
| | | |
| +-KEYTO(ref)--+ |
| |
+-IGNORE(expr)----------------------+
WRITE statement.
>>-WRITE-FILE(file_ref)--FROM(ref)--+-------------------------+----------- ; --><
| |
+-KEYFROM(expr)-----------+
| |
+-KEYTO(ref)--------------+
LOCATE statement.
>>-LOCATE--based-variable--FILE(file-ref)--+--------------------------------------+---- ; --><
| | | |
+-SET(pointer-ref)-+ +-KEYFROM(expr)--+
REWRITE statement.
>>-REWRITE-FILE(file_ref)--+-----------+--+-----------+----------- ; --><
| | | |
+-FROM(ref)-+ +-KEY(expr)-+
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 );
- filename
- a character string variable or constant containing
the name of the file to be deleted.
- rc
- a FIXED BIN(31) data element which will contain the
OS/2 error code from DosDelete.
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.
tempnam generates a unique name for a temporary file.
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 );
- sDir
- a VARYING CHARACTER string identifying the directory in which the
file is to be located. If this is the null string the file will be located
in the current working directory.
- sPfx, sSfx
- VARYING CHARACTER strings containing the prefix (sPfx) and
the suffix (sSfx) to be attached to the generated name. Either or both may
be the null string. The generated name will be:
'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.
- temp_filename
- In the example this represents a VARYING CHARACTER
string which will contain the generated unique name.
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.
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.
elseif _dbg@dbg$os == 12 && ?@main { | Following this |
go/until/noflip @main | |
} | |
elseif ?@@_PLI_MAIN { | Insert these three lines |
go/until/noflip @@_PLI_MAIN | |
} | |
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.
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:
*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.
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.
version 0.5d, 30 Jan, 2008
http://www.iron-spring.com