1 08/04/86 pascal_separate_comp.gi.info
  2 
  3 This info file describes how to share procedures and variables between
  4 Pascal programs, how to call from Pascal procedures written in other
  5 languages, how to reference from Pascal Multics external variables,
  6 and how to, from programs written in other languages, call procedures
  7 or reference variables exported by Pascal programs.
  8 
  9 
 10 Summary of compiler directives: (Extensions described below are SOL
 11 extensions) Since the standard does not allow to reference external
 12 variables or procedures (i.e.  variables or procedures defined in one
 13 other program, separately compiled), necessary extensions have been
 14 implemented.  They are the compiler directives $IMPORT and $EXPORT.
 15 
 16 $import
 17   identifies the procedures, functions and variables that are defined
 18 outside
 19   the program.
 20 $export
 21   identifies which of this program's procedures, functions and
 22 variables are to
 23   be made accessible to other programs.
 24 
 25 These directives must appear immediately after the program header,
 26 with $import first if it exists.
 27 
 28   ONLY PROCEDURES, FUNCTIONS OR VARIABLES DECLARED AT THE MAIN LEVEL
 29 (GLOBALS) CAN BE EXPORTED OR IMPORTED.
 30 
 31 
 32 The $import directive:
 33    The $import directive appears immediately after the program header
 34 and identifies the procedures, functions and variables that are
 35 defined outside the program.  Its syntax is:
 36 
 37    $import <imported_list> { ";" <imported_list>} "$"
 38 
 39  <imported_list>  = <external_description_string> ":" <pascal_id_list>
 40  <pascal_id_list> = <pascal_id> {"," <pascal_id>}
 41  <external_description_string> =
 42     "'" <target_name> "(" <generator_name> ["descriptors"] ")" "'"
 43     | "'external_static'"
 44  <target_name> = <multics_segment_name> ["$" <entry_name>]
 45  <generator_name> = "pl1" | "pascal" | "fortran" | "cobol" etc..
 46 
 47    The <pascal_id> is the identifier of the procedure or function or
 48 variable as it is declared in the Pascal program.
 49    The <external_description_string> gives information to the compiler
 50 about where is allocated the variable or in which segment is the
 51 procedure.  The compiler uses this information to generate a Multics
 52 link in the object segment.  Usually, this link consists on a segment
 53 name and an entry name in this segment.  The segment name is found by
 54 the compiler in the <external_description_string>.  If this string
 55 contains an <entry_name> this entry name is used by the compiler to
 56 generate the link.  Otherwise, the compiler takes the internal (lower
 57 case) name of the procedure, function or variable.  The list of the
 58 generated links may be obtained using the Multics "print_link_info"
 59 command which analyzes the object segment.  These links are used by
 60 the Multics dynamic linker to locate, at execution time, the concerned
 61 variable, function or procedure.
 62 
 63 
 64 Examples of $import:
 65 
 66    program example;
 67    $import
 68       ' pl1_program (pl1)' : proc1, funct1 ;
 69       'fortran_program (fortran)' : proc3 ;
 70       'external_static' : v1, v2, v3 ; (* Multics external variables
 71                          allocated in external static standard area *)
 72       'hcs_ (pl1 descriptors)' : make_seg ;
 73       'pascal_program (pascal)' : proc5, v4, v5 ;
 74       'segment_x$procedure_y (pl1)' : proc_xy ;
 75       'static_data (cds)' : v6, v7 ; (* allocated in a data segment
 76                                          created by the cds command *)
 77       'ioa_$ioa_ (pl1 descriptors)' : ioa_1, ioa_2 $
 78 
 79    The generated links will be:
 80 
 81        Pascal object name                      Multics target
 82 
 83       proc1                                    pl1_program$proc1
 84       funct1                                   pl1_program$funct1
 85       proc3                                    fortran_program$proc3
 86       v1                                       *system$v1
 87       v2                                       *system$v2
 88       v3                                       *system$v3
 89       make_seg                                 hcs_$make_seg
 90       proc5                                    pascal_program$proc5
 91       v4                                       pascal_program$v4*
 92       v5                                       pascal_program$v5*
 93       proc_xy                                  segment_x$procedure_y
 94       v6                                       static_data$v6
 95       v7                                       static_data$v7
 96       ioa_1                                    ioa_$ioa_
 97       ioa_2                                    ioa_$ioa_
 98 
 99    Imported variables must be declared in the var section in the
100 standard manner.  But, since they were mentionned in the $IMPORT
101 section, they are not allocated in the object segment and will be
102 referenced through a link.
103    Imported procedures and functions are declared at the standard
104 place in the program with a standard heading including the declaration
105 of the parameters in the standard manner, but their body (declarations
106 plus statement part) is replaced by the reserved word "external".
107 
108 
109 
110 The $export directive: The $export directive appears immediately after
111 the $import directive (if it exists) and identifies which of this
112 program's procedures, functions and variables are to be made
113 accessible to other programs.  It can be used to obtain more space for
114 large global variables or arrays.  (Internal global variables can
115 occupy only 16383 words.)
116 
117 
118 Its syntax is:
119 
120    $export <pascal_id_list> "$"
121 
122    <pascal_id_list> = <identifier> {"," <identifier> }
123 
124    The given <identifier> is the identifier of the variable, procedure or
125 function in the Pascal program.
126 
127 
128 Examples of $export:
129 
130   $export
131      proc6, v8, v9 $
132 
133    Exported variables, procedure or functions are declared in the
134 standard manner.  But the compiler makes them accessible by external
135 programs through definitions which are generated in the object
136 segment.  List of generated definitions may be obtained using the
137 Multics "print_link_info" command which analyzes the object segment.
138 
139 
140    However, there is one difference between exported and non exported
141 variables.  Non exported variables are allocated in the static section
142 of the object segment, which is limited by Pascal implementation to
143 16K machine words.
144   Exported variables are by default dynamically allocated as external
145 variables in the process_dir (like PL1 external statics).  So, you can
146 use $EXPORT directive to export too big variables which could not be
147 allocated in the static section of the object segment.
148    If the program is compiled using the "-private_storage" control
149 argument, which is not the default, the exported variables will be
150 allocated in a data segment named "program_name.defs".  In this case
151 total size of exported variables cannot exceed one segment.
152 
153 
154 
155 Separate Pascal compilations:
156    This part concerns only Pascal programs sharing procedures,
157 functions or variables.
158 
159    Separate Pascal compilations can be used for the developpment of
160 big applications, libraries, etc..
161    Since these programs share procedures, variables, they must contain
162 the declarations of these objects, and these declarations must be
163 identical in the different programs.
164    It is highly recommended to use include files ($INCLUDE extension)
165 to include in the different sources the useful constant declarations,
166 type declarations, variable declarations and procedure or function
167 headings.
168 
169 
170    The pascal_cref command can be used to improve, after compilation,
171 the validity of the separate compilations by checking the conformity
172 of types of objects shared by different Pascal object segments.  (This
173 command scans the symbol tables of the object segments.)
174 
175    Example of separate Pascal compilations:
176 
177     PROGRAM caller (output) ;
178        $IMPORT
179           'called (pascal)' : open, n_lines, close ;
180           'called$out_nl (pascal)' : write_line $
181        TYPE
182           output_type = (discard, terminal) ;
183        VAR
184           n_lines : integer ;
185        PROCEDURE open
186           (file_type : output_type) ; EXTERNAL ;
187        PROCEDURE write_line
188           (str : PACKED ARRAY [a..b : integer] OF char) ; EXTERNAL ;
189 
190 
191        PROCEDURE close ; EXTERNAL ;
192        BEGIN
193           open (terminal) ;
194              ....
195           write_line ('This is a line.') ;
196              ....
197           write_line ('This is one other line.') ;
198              ....
199           close ;
200           writeln ('Number of lines written : ', n_lines) ;
201        END.
202 
203 
204     PROGRAM called ;
205        $EXPORT
206           open, out_nl, close, n_lines $
207        TYPE
208           output_type = (discard, terminal) ;
209        VAR
210           output_file : text ;
211           n_lines : integer ;
212 
213 
214        PROCEDURE open
215              (file_type : output_type) ;
216           BEGIN
217              CASE file_type OF
218                 discard :
219                    fconnect (output_file, 'discard_') ;
220                 terminal :
221                    fconnect (output_file, 'syn_ user_output') ;
222              END ;
223              n_lines := 0 ;
224              rewrite (output_file)
225           END ;
226 
227 
228        PROCEDURE out_nl
229              (str : PACKED ARRAY [a..b : integer] OF char) ;
230           BEGIN
231              writeln (output_file, str) ;
232              n_lines := n_lines + 1
233           END ;
234        PROCEDURE close ;
235           BEGIN
236              fclose (output_file)
237           END ;
238        BEGIN
239        END.
240 
241 
242    Note that "called" is a kind of library.  His main procedure is
243 empty and never used.
244    Such are most of the Pascal applications using separate
245 compilations.  There is only one significant main procedure, which is
246 first called when the program is executed.
247 
248 
249 Call from Pascal to other languages:
250    This part describes the rules which must be observed when a Pascal
251 program calls a procedure written in one other language.
252 
253 
254    Multics Pascal allows a Pascal program to "import" external
255 procedures written in other languages and compiled by other
256 translators.
257    Since these procedures are somewhere else, they dont have any body
258 in your source program.  This body is replaced by the reserved word
259 "external":
260 
261 
262 Examples:
263 
264  PROCEDURE arg_count (VAR arg_count, error_code : integer) ; EXTERNAL;
265 
266    The "$import" directive, which takes place immediately after the
267 program header, contains informations usefull to the compiler for the
268 generation of a link to the external procedure: the name of the
269 segment containing this procedure, and the name of this procedure in
270 this segment.  It contains also the name of the language in which this
271 procedure was compiled.  This name can be followed by the word
272 "descriptors" meaning that this procedure is expecting for parameter
273 descriptors.
274 
275 
276 Examples:
277 
278  $IMPORT 'cu_ (pl1)' : arg_count $
279 
280  This program imports the PL/I procedure arg_count from the segment
281 cu_.
282 
283 $IMPORT
284    'cu_ (pl1)' : arg_count, arg_ptr $
285    ...
286 PROCEDURE arg_count (VAR arg_count, error_code : integer) ; EXTERNAL ;
287 PROCEDURE arg_ptr (arg_no : integer ; VAR arg_addr : arg_ptr ;
288    VAR arg_len, err_code : integer) ; EXTERNAL ;
289 
290  This program imports from the segment cu_ the procedures arg_count
291 and arg_ptr.
292 
293    In the two previous examples, the name of the entry point is the
294 same than the internal Pascal name of the procedure.  But this
295 internal name can be different:
296 
297 
298 Examples:
299 
300 $IMPORT
301   'cu_$arg_count(pl1)' : argument_count ;
302   'cu_$arg_ptr (pl1)' : argument_pointer $
303   ...
304   TYPE
305   argument = PACKED ARRAY [1..256] OF CHAR ;
306   arg_ptr = ^argument ;
307   ...
308 PROCEDURE argument_count (VAR arg_count, error_code : integer) ;
309 EXTERNAL ;
310 PROCEDURE argument_pointer (arg_no : integer ; VAR arg_addr : arg_ptr ;
311   VAR arg_len, err_code : integer) ; EXTERNAL ;
312 
313 
314 Note that the following "import" specifications are equivalent:
315 
316    $IMPORT 'cu_$arg_count (pl1)' : arg_count $
317 
318    $IMPORT 'cu_ (pl1)' : arg_count $
319 
320 
321    When you want to use a procedure which was written in one other
322 language, you know this language if you wrote yourself this procedure,
323 or you can determine what is the language used looking at the
324 declaration of the procedure (You probably found this declaration in a
325 manual, or an info segment..).  It does not matter if the procedure
326 was not really written in this language, the only one thing you have
327 to know is in which language the declaration is given.  (For instance,
328 the entry point cu_$arg_count is described using a PL/I declaration.
329 In reality it is an ALM program.  It does not matter.  Since this
330 program is described in the documentation with a PL/I declaration he
331 conforms to the PL/I call standards and for your Pascal program it
332 will be a PL/I program.)
333 
334 
335    Now, you have to determine if this entry point needs descriptors.
336 This point is very important.
337    A descriptor is a data structure which is passed to the called
338 procedure and describes the type and dimensions of a parameter.  This
339 descriptor is used by the generated code of the called procedure if
340 the parameter may have different sizes or dimensions.  It is the only
341 whay for this procedure to find out what are the actual size or
342 dimensions of the passed parameter.
343 
344 
345    Descriptors are used by PL/I and FORTRAN.
346    A PL/I procedure needs descriptors when type description of at
347 least one of his parameters contains stars ("*") or when it is
348 declared "options (variable)".
349    A FORTRAN procedure needs descriptors when type description of at
350 least one of his parameters contains stars ("*").
351 
352 
353   If the external procedure needs descriptors, you must add the word
354 "descriptors" after the name of the language, between the parentheses.
355 
356    Examples:
357 
358    $IMPORT 'hcs_ (pl1 descriptors)' : make_seg $
359     ...
360    TYPE
361       data = ...
362       dir_name = PACKED ARRAY [1..168] OF char ;
363       entry_name, ref_name = PACKED ARRAY [1..32] OF char ;
364       data_ptr = ^data ;
365     ...
366 
367 
368    PROCEDURE make_seg (dir : dir_name ; entry : entry_name ;
369       ref : ref_name ; mode : integer ; VAR seg_ptr : data_ptr ;
370       VAR err_code : integer) ;
371    ...
372    BEGIN
373           ....
374       make_seg ('>udd>PROJECT>Me>this_dir', 'this_segment', '  ',
375          read_write, seg_ptr, error_code) ;
376       IF error_code <> 0 THEN
377          BEGIN
378             ...
379 
380 
381   Pascal only accepts declaration of procedures which have a definite
382 -and fixed- number of parameters, which types can't change.
383    But for PL/I or FORTRAN procedures which may receive different
384 numbers of parameters, or parameters which type may change, Pascal
385 allows to declare more than one Pascal procedure, each Pascal
386 procedure corresponding to a different use of this procedure.
387 
388    Examples:
389 
390    $IMPORT 'ioa_$ioa_ (pl1 descriptors)' : ioa_1, ioa_2 $
391     ....
392    TYPE
393      char_18: PACKED ARRAY [1..18] OF char
394      ...
395     ...
396 
397 
398 PROCEDURE ioa_1 (control_string : char_18) ; EXTERNAL ;
399 PROCEDURE ioa_2 (control_string : char_18; number : integer); EXTERNAL;
400     ....
401    BEGIN
402     ....
403       IF result = 0 THEN
404          ioa_1 ('The result is null')
405       ELSE
406          ioa_2 ('The result is : ^d', number) ;
407 
408    The procedures ioa_1 and ioa_2 have the same target : the Multics
409 subroutine ioa_ which is declared "options (variable)".  They
410 correspond to different uses of this procedure.  (ioa_ uses the
411 descriptors to know the number of parameters and their types.)
412 
413 
414    Now you have to determine if the parameter has to be passed by
415 address (i.e.  declared with the reserved word "VAR") or by value
416 (i.e.  without the reserved word "VAR").
417    If the parameter is an input-output parameter or an output
418 parameter, it MUST be passed by address.  If it is an input parameter,
419 it is more secure to pass it by value.  But since this way of passing
420 parameters is less efficient (a copy of the value is made in the stack
421 frame of the calling procedure), and is sometimes impossible if the
422 value is too big, you can pass it by address.  Let's hope that the
423 called procedure works as it is supposed to and doesn't modify it!
424    Normally, even if you did not write this procedure, you must be
425 able to know which parameters are input, output or input-output
426 parameters (A good documentation must say these things).
427   If you have some doubt, pass the parameter by address.
428 
429 
430    Now you have to give your parameters the right type which
431 corresponds to the type of the parameter the procedure is waiting for.
432 
433    If the procedure does not need descriptors, declare parameter types
434 which conform to the data types equivalences given at the end of this
435 segment.
436 
437 
438    If the procedure needs descriptors, during the compilation, the
439 compiler looks at the types of the parameters and generates (if
440 possible, otherwise there is one error) the descriptor for the
441 concerned language corresponding to the Pascal type of this parameter.
442 
443 
444 If the Pascal type is:           The generated PL/I descriptor will be:
445 
446 boolean                               fixed bin (35) [aligned]
447                                    (value transmitted is the internal
448                                       code 1=true, 0=false)
449 integer                               fixed bin (35) [aligned]
450 real                                  float bin (63) [aligned]
451 any typed pointer                     ptr aligned
452 any enumerated type                   fixed bin (35) [aligned]
453                                      (value transmitted is the internal
454                                          code)
455 SET OF boolean                        bit (2) [unal]
456 SET OF char                           bit (128) [unal]
457 SET OF a..b                           bit (b+1) [unal]
458   string (n)                            char (n) varying [unaligned]
459 
460 
461   RECORD   (see NOTE (*) below)
462     length : 0..n ;
463     string : PACKED ARRAY [1..n] of char
464   END;                                  char (n) varying [unaligned]
465   RECORD
466     a : [any type of this
467           list excepted sets]
468     ...
469     (No variant part)
470   END                                   1 aligned,
471                                            2 [the corresponding type] ,
472                                            ...
473 
474 
475   ARRAY [...] OF [any type of this
476                     list excepted sets]
477                                         (...) [the corresponding type]
478           Subscripts:
479                                        Pascal type element.
480           Subscripts:
481              boolean                              0:1
482              char                                 0:127
483              enumerated of n elements             0:n-1
484              numeric a..b                         a:b
485 
486 
487   (*) NOTE : This way of passing char(n) varying parameters was useful
488 in Pascal 8.02, when dynamic-strings did not exist.
489   If you want continue to use it, BE CAREFUL: The Multics PL/1
490 implementation supposes that, for these parameters, the address passed
491 is not the address of the beginning of the variable (length integer
492 word) but the address of the string itself.  So, for these parameters,
493 pass ALWAYS BY ADDRESS the "string" field of the corresponding Pascal
494 record.  (This is done automatically for "string (n)" Pascal
495 parameters transmitted to PL1)
496 
497 
498 Reference from Pascal to non Pascal variables:
499    Non Pascal variables can be external variables or variables
500 allocated in a data segment.
501    Pascal declarations must conform to the data type equivalences
502 given at the end of this info file.
503 
504    External variables can have been created by Multics (like
505 pl1_severity_ or pascal_severity_ after a compilation) or may be
506 FORTRAN commons or variables declared "external static" in a PL/I
507 program.  The given <external_description_string> must be
508 'external_static':
509 
510 
511 Examples:
512 
513   $IMPORT 'external_static' :  pascal_severity, common_a $
514       ....
515   VAR
516     pascal_severity_ :  integer ;
517     common_a :  ARRAY [1..10000] OF real ;
518 
519    Variables allocated in a data segment must be referenced using the
520 name of the segment followed by the name of the variable.  Data
521 segments can be generated using the Multics "create_data_segment"
522 command.
523 
524 
525 Examples:
526 
527   $IMPORT 'common_data (cds)' :  nbr_of_calls, last_caller$
528    ....
529    VAR
530       nbr_of_calls :  integer ;
531       last_caller :  RECORD
532             user :  PACKED ARRAY [1..22] OF char;
533             project :  PACKED ARRAY [1..9] OF char
534          END;
535 
536 
537 Call from PL/I to a Pascal main procedure:
538    Pascal main procedures accept arguments which can be read from
539 inside the program using ARGC and ARGV extensions.  (Multics PL/I
540 subroutines cu_$arg_count, cu_$arg_ptr, etc...  can also be used).
541 These arguments must be non varying character strings.  The Pascal
542 main procedure must be declared "options (variables)" (PL/I) or
543 "descriptors" (FORTRAN) because it needs descriptors.
544   The last argument can optionnally be an integer (or fixed bin (35)).
545 If this argument exists, it will be affected by the STOP Pascal
546 predefined procedure (extension) and can be used to contain a return
547 code if necessary (It is set to zero by default if it is transmitted
548 and not affected by a STOP in the Pascal program).
549 
550 
551 Examples:
552 
553    In a PL/I program:
554           dcl pascal_program entry options(variable) ;
555           dcl code fixed bin (35) ;
556           dcl name char (32) ;
557           dcl string char (168) ;
558 
559           call pascal_program ("-arg1", "-arg2", name, string) ;
560 
561     Or:
562 
563           call pascal_program ("-arg1", "-arg2", code) ;
564           if code ^= 0 then
565             .....
566 
567 
568 For the Pascal program :
569 
570        PROGRAM pascal_program ;
571           ...
572        VAR
573           error_code :  integer ;
574           ....
575        BEGIN
576           ...
577               (* process args, etc...  *)
578           ...
579           IF error THEN stop (error_code)
580           ELSE stop (0)
581        END.
582 
583 
584 Call from PL/I to a Pascal exported procedure or function:
585    In your PL/I program, give your procedure a name of the form:
586 
587           <pascal_program_name>$<lower_case_procedure_name>
588 
589    If the name of the exported procedure was added to the Pascal
590 program, you can only use the procedure name.
591    The number of parameters must be equal to the number of parameters
592 the procedure is waiting for.
593    The types of the parameters must conform to the data type
594 equivalences given at the end of this segment.
595 
596    If the Pascal procedure is waiting for one conformant array, the
597 PL/I description of the corresponding array must contain star array
598 bounds for the variable dimensions.  (Descriptors will be passed to
599 the Pascal procedure).
600 
601 
602 Examples:
603 
604       For the Pascal declarations:
605 
606   PROGRAM pascal_program ;
607           ....
608    $EXPORT foo, get_ptr $
609           ....
610    TYPE
611       char_32 = PACKED ARRAY [1..32] OF char ;
612       data = RECORD
613                ....
614              END ;
615       data_ptr = ^data ;
616           ....
617 
618 
619    PROCEDURE foo (VAR index : integer ;
620       VAR matrix ARRAY [a..b : integer; c..d : integer] OF real ;
621       string : char_32) ;
622           ....
623       BEGIN
624           .....
625       END (* foo *) ;
626           ....
627    FUNCTION get_ptr (VAR seg_name : char_32) : data_ptr ;
628           ....
629       BEGIN
630           ....
631       END (*get_ptr *) ;
632 
633 
634 You will declare, for instance, in your PL/I program:
635 
636    dcl pascal_program$foo entry (fixed bin (35),
637       (*,*) float bin (63), char (32)) ;
638    dcl pascal_program$get_ptr entry (char (32)) returns (ptr) ;
639 
640    Note that if the Pascal program was compiled with the control
641 argument "-add_exportable_names", the names of the exported procedures
642 have been added by the compiler to the object segment, and that you
643 can, in the PL/I program, call the procedures "foo" and "get_ptr",
644 without giving the segment name.
645 
646 
647 Reference from PL/I to a Pascal exported variable:
648 The following example illustrates how to access a Pascal exported variable.
649 
650      dcl pascalprogram$a ptr external;
651      dcl a fixed bin (35) based (pascalprogram$a);
652 
653   for:
654 
655      program pascalprogram ;
656      ...
657      $export a $
658      var
659         a :  integer ;
660 
661 This convoluted method is used because a Pascal exported variable is
662 not necessarily the same as a PL/I external variable with the same
663 name.  If the Pascal program above has been compiled with the
664 -private_storage (-ps) option, the variable "a" will be allocated in a
665 segment named "pascalprogram.defs" as pascalprogram.defs$a instead of
666 in the user free area as the *system variable a.
667 
668 
669 Data types equivalences:
670 
671    Simple data:
672 
673                                         PASCAL
674  (PL/I alignment between brackets
675   is the default)
676 
677 FORTRAN integer
678 PL/I fixed bin (35) [aligned]
679 PL/I fixed bin (35) unaligned           integer
680 PL/I fixed bin (n) [aligned]  0<n<36    numeric (-2**n .. +2**n - 1)
681 PL/I fixed bin [aligned]                numeric (-2**17 .. +2**17 -1)
682 
683 FORTRAN logical true                    integer = -1
684 FORTRAN logical false                   integer = 0
685 
686 FORTRAN integer = 0
687 PL/I fixed bin (35) = 0                 boolean false
688 FORTRAN integer = 1
689 PL/I fixed bin (35) = 1                 boolean true
690 
691 FORTRAN double precision
692 PL/I float bin (63) [aligned]
693 PL/I float bin (63) unaligned           real
694 
695 PL/I char aligned
696 PL/I char [unaligned]                   packed array [1..1] of char
697 FORTRAN character*n
698 PL/I char (n) [unaligned]
699 PL/I char (n) aligned                   packed array [1..n] of char
700 
701 PL/I ptr [aligned]                      any typed pointer
702 PL/I null  value                        nil value
703 
704 PL/I bit (n) [unaligned]
705 PL/I bit (n) aligned            SET OF [a .. x] (enumerated base type)
706                                 with ord (a) = 0 and ord (x) = n-1
707                                 SET OF [0..n-1]  (numeric base type)
708 
709 PL/I char (n) varying aligned
710 PL/I char (n) varying [unaligned]       string (n)
711                               or : (still possible. See NOTE above..)
712                                         RECORD
713                                           length : 0..n ;
714                                   string : PACKED ARRAY [1..n] OF CHAR
715                                         END ;
716 PL/I (n) char [unaligned]               PACKED ARRAY [1..n] OF char
717 
718 PL/I char [unal]
719 PL/I char aligned                       PACKED ARRAY [1..1] OF char
720 
721    Agregates
722 
723 PL/I aligned structure which members are
724 type of any aligned type of this list
725 (excepted bit strings)
726                                 Unpacked unvariant record which fields
727                                 have the corresponding Pascal type.
728 
729 PL/I array of aligned elements which type
730 if any type of this list (excepted
731 bit strings)
732                                 Unpacked array of corresponding
733                                 Pascal type element.
734 
735 Fortran ONE DIMENSION array of
736 integer, or double precision    Unpacked array of corresponding
737                                 Pascal type element.
738 
739       Subscripts:
740       0:1                                     boolean
741       0:127                                   char
742       0:(n-1)                                 enumerated of n elements
743       a:b                                     numeric (a..b)