HP Pascal/iX Programmer’s Manual HP 3000 MPE/iX Computer Systems Edition 6 Manufacturing Part Number: 31502-90023 E0692 U.S.A.
Notice The information contained in this document is subject to change without notice. Hewlett-Packard makes no warranty of any kind with regard to this material, including, but not limited to, the implied warranties of merchantability or fitness for a particular purpose. Hewlett-Packard shall not be liable for errors contained herein or for direct, indirect, special, incidental or consequential damages in connection with the furnishing or use of this material.
Printing History New editions are complete revisions of the manual. Update packages, which are issued between editions, contain additional and replacement pages to be merged into the manual by the customer. The dates on the title page change only when a new edition or a new update is published. No information is incorporated into a reprinting unless it appears as a prior update; the edition does not change when an update is incorporated.
Throughout this manual, the term HP Pascal refers to both HP Pascal/iX and HP Pascal/HP-UX. The following is a short description of each chapter and appendix. Chapter 1 Describes HP Pascal/iX and HP Pascal/HP-UX and explains their relationship to HP Standard Pascal and its subsets. Chapter 2 Describes HP Pascal program structure in terms of syntax and compilation units, and explains how your program can interface with its external environment. Chapter 3 Explains how program input/output works.
* MPE/iX Commands Reference Manual, Volumes 1 and 2 and 32650-90364) * MPE/iX Intrinsics Reference Manual * MPE/iX Symbolic Debugger User's Guide * MPE/iX System Debug Reference Manual * Programming on HP-UX * Switch Programming Guide * Trap Handling Programmer's Guide * TurboIMAGE/XL Reference Manual * Using VPLUS/V: Introduction to Forms Designs (32650-90003 (32650-90028) (31508-90003) (32650-90013) (B2355-90010) (32650-90014) (32650-90026) (30391-90001) (32209-90004) If you have sugg
When several elements are stacked within brackets, you can select one or none of the elements. In the following example, you can select OPTION or Parameter or neither. The elements cannot be repeated. COMMAND FileName [OPTION ] [Parameter ] Conventions (continued) [...] In a syntax statement, horizontal ellipses enclosed in brackets indicate that you can repeatedly select the element(s) that appear within the immediately preceding pair of brackets or braces.
Examples: * BEGIN, REPEAT, FORWARD Standard identifiers are in all lowercase letters. Examples: * readln, maxint, text General information concerning an area of programming (topic) appears as a heading with initial capitalization. All headings that are not reserved words or standard identifiers appear with initial capitalization.
p- 6
Chapter 1 Introduction HP Pascal/iX and HP Pascal/HP-UX are supersets of HP Standard Pascal, the Pascal language that runs on all HP computers. HP Pascal/iX runs on the MPE/iX operating system and HP Pascal/HP-UX runs on the HP-UX operating system. Both operating systems run on HP PA-RISC computers, and both achieve ISO and ANSI validation. HP Pascal takes advantage of the architecture of these computers and has system programming extensions to HP Standard Pascal.
preprocessor has macros that generate calls to SQL. 1- 2 HP System Dictionary/XL Dictionary of MPE/iX data elements. HP System Dictionary/XL General Reference Manual VPLUS Forms generator. Your HP Pascal program accesses VPLUS routines with intrinsic calls. Using VPLUS/V: Introduction to Form Designs HP Pascal can interface with several system debuggers.
Chapter 2 Program Structure This chapter summarizes program structure--in terms of syntax and in terms of compilation units. For complete syntactic definitions of programs and their components, refer to the HP Pascal/iX Reference Manual or the HP Pascal/HP-UX Reference Manual, depending on your implementation. Syntactic Structure Syntactically, every HP Pascal program is composed of two major parts: the program heading and the program block.
Program Block The program block consists of an optional declaration part and a statement (executable) part. The declaration part defines whatever labels, constants, data types, variables (including program parameters), procedures, functions, or modules you want. It can also redefine standard constants, data types, variables, and routines in the declaration part; however, if you do redefine them, you cannot use their original definitions. You cannot redefine reserved words.
Compilation Unit Structure A compilation unit is a unit of source code that can be compiled independently of other code (for example, a program is a compilation unit; a block is not). You can design your program in two ways: * As a single compilation unit. entire program at once. In this case you must compile the * As two or more compilation units. In this case you can compile one unit at a time, or you can compile in groups. This is also known as separate compilation.
of entire modules a second time. A module's export declaration specifies the constants, data types, variables, functions, and procedures that it exports to the modules or programs that import it. A module defines its exportable routines in its implement part. A module's implement part defines constants, data types, variables, and routines. The routines are accessible only to the module itself, unless they are exported in the export declaration.
Figure 2-3 . shows what a module can access. Figure 2-3. What a Module Can Access A module must be compiled before a program or another module imports it (therefore, two modules cannot import each other). For the compiler to compile a module with a program, the program must define the module in its declaration part. After defining this module, the program can import it.
and SEARCH, refer to the HP Pascal/iX Reference Manual or the HP Pascal/HP-UX Reference Manual, depending on your implementation. A program can define a module with the same name as a module in the library that SEARCH specifies. In that case, the program imports the module that it defines, rather than the library module with the same name. If a library contains two modules with the same name, the second one overrides the first.
. : MODULE Mod3; {The program defines this Mod3} . : END; {Mod3} $SEARCH 'Mod1.o'$ IMPORT Mod2, {Mod2 comes from the library Mod1.o} Mod3; {Mod3 is the one that the program defined} BEGIN . : END. Global, Subprogram, and External Compilation Units A global compilation unit defines global constants, data types, and variables within a Pascal program. It also contains the body of the main program. Syntactically, it is a program that begins with the GLOBAL compiler option.
There are four methods used for separate compilation. They are performed by using modules and by using the compiler options SUBPROGRAM, GLOBAL, and EXTERNAL. Using modules is the preferred method for separate compilation from a structured programming point of view. However, using modules does have certain limitations, as does using SUBPROGRAM, GLOBAL, and EXTERNAL. You must decide which method works in the way you prefer for your specific situation.
SUBPROGRAM Advantages. Using SUBPROGRAM results in smaller object files and less link time. You also get faster access to the first 8K bytes of globals. The SUBPROGRAM option can also be specified with a list of routines to compile as few as one procedure, if RLFILE is used. SUBPROGRAM Limitations. The variables must be in the exact same order and must be declared with the same types.
GLOBAL/EXTERNAL Limitations. The following are some limitations of using GLOBAL/EXTERNAL: * All global variables must be declared in the GLOBAL compilation unit. * Using GLOBAL/EXTERNAL results in slower link time. * Code that references global variables is not as efficient as code that does not use GLOBAL/EXTERNAL. Using SUBPROGRAM with GLOBAL The SUBPROGRAM with GLOBAL compiler options result in Pascal programs that are a mixture of subprogram and global compilation units.
Chapter 3 Input/Output Input/output depends on files: your program reads input from files and writes output to files. The terms that describe the three varieties of input/output--sequential, textfile, and direct --also describe the associated files. This chapter: * Gives general information about files. * Explains the predefined file-opening procedures and how they determine whether files are sequential or direct, for input or for output.
Table 3-1.
Figure 3-2. File Relationships Physical Files A physical file is a program-independent entity that the operating system controls. It can be a file on a disk or other medium, or an interactive file created at a terminal (refer to your operating system manual for information on creating and controlling physical files). Your program can manipulate a physical file if the physical file is associated with one of the program's logical files.
Textfiles A textfile is a logical file that is subdivided into lines, each of which ends with an end-of-line marker. The components of a textfile are of type char, but a textfile declaration specifies the type text, not FILE OF char. The standard files input and output are textfiles. If you declare them in the program header, they are the default file parameters for all of the sequential input and output procedures, respectively. Example PROGRAM prog (input,output); VAR tfile : text; c : char; BEGIN . . .
File Buffer Variables and Selectors Every logical file has a file buffer variable, or buffer, which is a variable of the same type as the file components. Some file operations assign the value of the current component to the buffer; other operations leave the buffer undefined. When the buffer is defined, you can access its value with its file buffer selector. The file buffer selector for the file f is f^ or f@. Accessing an undefined buffer causes an error.
physical file file2.} END. If logical_file is not a program parameter, and physical_file is not specified, logical_file remains associated with its previously associated physical file. If logical_file was not previously associated with a physical file, the system associates logical_file with a temporary, nameless physical file.
Table 3-2 summarizes the characteristics of the four predefined file-opening procedures. Table 3-2.
Parameters logical_file file_number open_options The name of the logical file. The file number of the open physical file. The physical file must have been opened with a direct call to an operating system routine or a non-Pascal routine. You cannot call the associate procedure with the file number of a closed file or a file that was opened with the Pascal procedure append, associate, open, reset, or rewrite. One of the following options.
| Where it Puts Current Position Index | Before first component. | | | | --------------------------------------------------------------------------------------------| | | | Value of eof for File * | False unless opened for write, in which | | | case eof returns true despite possible old | | | data after the current component. | | | | --------------------------------------------------------------------------------------------| | | | Erases Old file Contents | No.
Example 1 This example applies to HP Pascal on the MPE/iX operating system only. For a description of the MPE/iX intrinsic FOPEN, refer to the MPE/iX Intrinsics Reference Manual. PROGRAM test; TYPE pac100 = PACKED ARRAY [1..
(VAR fpathname : pac100; foption : integer; mode : integer) : integer; EXTERNAL; BEGIN tmpnam(name); {get unique name for temporary file} mode := octal('666'); {read-write access for file} option := octal('402'); {specify read-write access} fnum := file_open(name,option,mode); {open the file} associate(f,fnum,'READ,WRITE,DIRECT');{associate with file for read-write direct access} writedir(f,3,5); readdir(f,3,j); rewrite(e,'UDC'); {create text file 'UDC'} writeln('This is a test'); {write to file} close(e,'S
Table 3-4.
VAR f1,f2,f3 : seqfile; c1,c2 : char; BEGIN reset(f1); c1 := f1^; {Opens f1 for sequential input. First component of f1 becomes its current component.} {Assigns f1's first component to f1's buffer. Assigns f1's buffer (first component) to c1.} get(f1); {Advances f1's current position index. Second component of f1 becomes its current component.} read(f1,c2); {Implicit reference to f1's buffer -deferred get from get(f1) assigns f1's current (second) component to f1's buffer.
VAR f : intfile; x,y,z : integer; BEGIN reset(f); {Opens f for sequential input. First component becomes current component.} read(f,x); {Implicit reference to f's buffer -- deferred get from reset(f), above -- assigns current (first) component to buffer. Then read(f,x) assigns current (first) component to x. Second component becomes current component.} read(f,y); {Implicit reference to buffer -deferred get from read(f,x) assigns current (second) component to buffer.
VAR f : seqfile; i : integer; a : ARRAY [1..100] OF real; BEGIN reset(f); {Open f} i := 1; WHILE not eof(f) AND (i<=100) DO BEGIN read(f,a[i]); i := i+1; END; END; END. {Read array values from f} If f is a terminal, the appropriate action for eof is a device read. The next read or readln of f accesses the component in the buffer, without performing another device read. Example 4 PROGRAM prog (input); {for this example, assume input is from terminal} TYPE readbuf = PACKED ARRAY [1..
Table 3-6.
rewrite(out); readln(in,x,y,z); write(out,x); overprint(out); writeln(out,y); page(out); writeln(out,z); prompt(out,'?'); readln(in,w); writeln(out,w); END.
readln(infile); {and advance to the next line.} writeln(linepos(outfile)); {Also, print the number of characters written to outfile,} writeln(outfile); {and start a new line of outfile.} END {IF} {If the current line of infile has not ended,} ELSE BEGIN read(in,c); {read the next character of infile,} write(out,c); {and write it to outfile.} END; END; {WHILE} END.
The procedures readdir, writedir, seek, read, and write have this relationship: This Is equivalent to this readdir(f,i,x); seek(f,i); read(f,x); writedir(f,i,x); seek(f,i); write(f,x); Example 1 PROGRAM prog; TYPE dirfile = FILE OF integer; VAR f : dirfile; i1,i2,i3,i4 : integer; BEGIN open(f); {Opens f for direct input/output} {READ TWO SPECIFIC COMPONENTS USING readdir AND read} readdir(f,50,i1); {Puts the current position index at component 50. Assigns component 50 to i1.
before referencing the buffer implicitly (with a sequential I/O procedure) or explicitly. Table 3-9 summarizes the characteristics of the predefined direct file functions. Table 3-9.
the following syntax and parameters. Syntax close (logical_file [, close_option ]) Parameters logical_file close_option The name of the logical file to be closed. A string or PAC expression whose value is one of the following: SAVE or LOCK The file is saved permanently. TEMP or NORMAL The file is saved temporarily. What happens to the temporary file when the current session or job ends is system-dependent. For the MPE/iX operating system, see Appendix A ; for HP-UX, see Appendix B .
BEGIN reset(f2); goto 9999; END; {Opens f2} {Closes f2 and f3} PROCEDURE q; VAR f3 : ftype; BEGIN open(f3); {Opens f3} p; {p never returns here} END; BEGIN rewrite(f1); q; 9999 : reset(f1); close(f1); END.
Chapter 4 Predefined Pascal Constants, Data Types, and Modules This chapter: * Gives the value of each predefined constant. * Gives the range of each predefined data type. * Explains in detail the predefined data types bit16, bit32, bit52, longint, and shortint, which are unique to HP Pascal. * Explains each predefined module.
| | 0, | | | | 4.940656458412466*10-324..1.797693134862315*10308 | | | | | | ---------------------------------------------------------------------------------------------| | | | | Real * | -3.402823*1038..-1.401298*10-45, | 32 | | | 0, | | | | 1.401298*10-45..3.402823*1038 | | | | | | ---------------------------------------------------------------------------------------------| | | | | Shortint | -32768..
b16 := v1; b16 := b16 + 5; b16 := b16 - 5; {legal} {legal; now b16 = (65540 MOD 65535) = 4} {legal; now b16 = 65535} v3 v3 v3 v3 {causes run-time error} := := := := 65535; v3 + 4; 4; v3 - 5; v1 := -20; b16 := v1; v2 := -30; b16 := v2; END. {prog} {causes run-time error} {causes run-time error} {causes compile-time error} Bit32 The predefined data type bit32 is a subrange, 0..232-1, that is stored in 32 bits.
b := bit32(i) + 1; { zero is stored } b := bit32(hex('ffffffff')); $pop$ try i := b; recover ; try i := b + i; { run-time error } { b and i are converted to longint and are } { too big to fit back into i } recover ; i := hex('ffffffff'); { both b and i now have all bits on } { the following never prints since i is sign extended to longint and b is zero extended to longint } if i = b then writeln('equal'); end. Bit52 The predefined data type bit52 is a subrange, 0..252-1, that is stored in 64 bits.
const v_rec = rec[f1: hex('ffffffff')]; { bit52 constant field } $pop$ begin b := hex('ffffffff'); { compile-time error } i := -1; try b := i; recover ; { run-time error } (Example is continued on next page.
Example PROGRAM prog; TYPE T1 = integer; T2 = -10..40000; T3 = 40000..
b := longint(1000000) * 1000000; $pop$ writeln(b); end. Output: 8589934591 1000000000000 Predefined Modules On both the MPE/iX and HP-UX operating systems, HP Pascal has these predefined modules: * stdinput * stdoutput On the HP-UX operating system only, HP Pascal has these additional predefined modules: * stderr * arg * pas_hp1000 In its import declaration section, your program can import any or all of the predefined modules supported by the operating system on which it runs.
(which has no program header) to use stderr. Importing the stderr module into an independent module is the same as declaring stderr in the program header of a program. The content of the predefined module stderr is: VAR stderr : text; The predefined module stderr is only available on the HP-UX operating system. The main use of stdinput, stdoutput, and stderr is to allow a module to perform a read or write operation to either standard input files, standard output files, or, on HP-UX, standard error files.
Declaration: FUNCTION argc : integer; argv Returns a pointer to an array of pointers to the actual arguments. Declaration: FUNCTION argv : argarrayptr; argn A specific argument, in the form of a Pascal string. Declaration: FUNCTION argn (argnum : integer) : String1024; The predefined module arg is only available on the HP-UX operating system. pas_hp1000 The pas_hp1000 module contains routines that help you migrate Pascal/1000 programs to HP Pascal/HP-UX on the HP 9000 Series 700 or 800 machine.
pas_getnewparms Only for programs running under the RTE shell on the HP 9000 Series 700 or 800. Reinitializes the argument data structures when the program has been rescheduled after being suspended. Declaration: PROCEDURE pas_getnewparms; pas_filenamr Returns the name of the physical file associated with the specified logical file. Declaration: FUNCTION pas_filenamr (ANYVAR f : text) : pas_nametype; pas_timestring Returns the time of day as a 26-character PACKED ARRAY OF CHAR.
Chapter 5 Allocation and Alignment This chapter: * Defines allocation, alignment, * Shows how unpacked and packed variables are allocated and aligned. * Tells how entire arrays and records are allocated and aligned (whether they are unpacked, packed, or crunched). * Shows how array elements and record fields are allocated and aligned when they are unpacked, packed, and crunched. * Explains how enumeration and subrange types are related and shows how they are allocated and aligned.
a variable contains the variable's name. If the name does not fit the space, it is printed outside, with an arrow pointing to the space. Example The variables a and b occupy one bit each, c occupies six bits, d and e occupy two bytes each, f occupies three bytes, and g occupies eight bytes. Allocation, Alignment, and Packing Algorithm Allocation is the assignment of memory to variables.
A packing algorithm determines a variable's allocation and alignment, and the allocation and alignment of its elements or fields, if it has them. The HP Pascal packing algorithm uses the following factors to allocate and align a particular variable: * Variable type. * Whether the variable (if it is an array, record, or set) is unpacked, packed, or crunched. When the compiler options TABLES or MAPINFO are ON, the program listing contains packing information.
| | | | | Function | 8 bytes | 4-byte | | | | | ------------------------------------------------------------------------------| | | | | Globalanyptr | 8 bytes | 4-byte | | | | | ------------------------------------------------------------------------------| | | | | Integer | 4 bytes | 4-byte | | | | | ------------------------------------------------------------------------------| | | | | Localanyptr | 4 bytes | 4-byte | | | | | ------------------------------------------------------------------------------|
Table 5-2.
| | | | ------------------------------------------------------------------------------| | | | | Pointer | 4 bytes | 4-byte | | | | | ------------------------------------------------------------------------------| | | | | Procedure | 8 bytes | 4-byte | | | | | ------------------------------------------------------------------------------| | | | | Real | 4 bytes | 4-byte | | | | | ------------------------------------------------------------------------------Table 5-2.
Column-major order: The HP Pascal packing algorithm uses this formula to allocate an array: number_of_elements * space_for_one_element The space_for_one_element depends upon the array element type and whether the array is unpacked, packed, or crunched. The same factors determine element alignment.
A record of the type Rec is 8-byte-aligned because its most restricted field, l, must be 8-byte-aligned. The variant part of a record of type Rec is 4-byte-aligned, because the most restricted first field of the two variants, i, must be 4-byte-aligned. A variable of type Rec is allocated 16 bytes. variants are aligned like this: The TRUE and FALSE TRUE Variant FALSE Variant Sometimes you can reduce the space that a record takes by declaring its fields in different order.
The variable upr1 takes six bytes: Because pf must be 2-byte-aligned, it cannot start in the second byte. The extra byte after cf is allocated because the most restricted element, pf, is 2-byte-aligned. The variable upr2 takes four bytes: Sometimes you cannot reduce the space that a record takes by declaring its fields in different order. Example VAR pr1 : PACKED RECORD srf : 0..32; b : Boolean; pf : 0..32767; cf : char; END; pr2 : PACKED RECORD srf : 0..32; b : Boolean; cf : char; pf : 0..
Packed Arrays Table 5-3 shows how the HP Pascal packing algorithm allocates and aligns the elements of a packed array. The element types are in alphabetical order. Table 5-3.
----------------------------------------------------------------------------------------------| | | | | Localanyptr | 4 bytes | 4-byte | | | | | ----------------------------------------------------------------------------------------------| | | | | Longint | 8 bytes | 4-byte | | | | | ----------------------------------------------------------------------------------------------| | | | | Longreal | 8 bytes | 8-byte | | | | | ------------------------------------------------------------------------------------
The array uba takes three bytes: The array pba takes three bits: If an array is not within a crunched structure, the compiler aligns the entire array on the same boundary as its first element, or on a byte boundary. Declaring an array PACKED has no effect on its elements if the elements are unpacked structures. Packed Records Table 5-4 shows how the HP Pascal packing algorithm allocates and aligns the fields of a packed record. The field types are in alphabetical order. Table 5-4.
| | | | | Bit16 | 2 bytes | Bit | | | | | ----------------------------------------------------------------------------------------------| | | | | Bit32 | 4 bytes | 4-byte | | | | | ----------------------------------------------------------------------------------------------| | | | | Bit52 | 8 bytes | 4-byte | | | | | ----------------------------------------------------------------------------------------------| | | | | Boolean | 1 bit | Bit | | | | | --------------------------------------------------------
Table 5-4. Allocation and Alignment of Packed Record Fields (HP Pascal Packing Algorithm) (cont.) ----------------------------------------------------------------------------------------------| | | | | Field Type | Allocation | Field Alignment | | | | | ----------------------------------------------------------------------------------------------| | | | | Record, packed | Fields are allocated by type, and record is padded | Largest alignment | | | to the alignment boundary.
elements of crunched arrays or fields of crunched records. If a type is not in Table 5-5 , a crunched array or record cannot have elements or fields of that type. Table 5-5.
3. The value zero is always included in the subrange when calculating the minimum number of bits; for example, this record takes seven bits: CRUNCHED RECORD f : 100..101; END; If any element can be negative, an extra bit is allocated for the sign; for example, this record takes three bits: [REV BEG] CRUNCHED RECORD f : -4..3; END; [REV END] Example A record that is defined: TYPE u_rec = RECORD {4-byte aligned} a,b : Boolean; c : char; d : minint..
A record that is defined: p_rec2 a,b c : d : e : END; = PACKED RECORD {4-byte-aligned} : Boolean; char; integer; Boolean; is allocated and aligned this way: A record that is defined: TYPE c_rec1 a,b c d e END; = : : : : CRUNCHED RECORD Boolean; char; minint..
Table 5-6.
Table 5-7. Allocation and Alignment of Unpacked Enumeration or Unsigned Subrange Variables (HP Pascal Packing Algorithm) --------------------------------------------------------------------------------------| | | | |Values in Enumeration or Subrange | | | | | Allocation | Alignment | | | | | --------------------------------------------------------------------------------------| | | | | 0..
Table 5-8.
Packed Record Elements of Enumeration or Subrange Types If the variable belongs to a packed record, the HP Pascal packing algorithm allocates it as many bits as it requires, and bit-aligns it. Example TYPE day = (sun,mon,tues,wed,thurs,fri,sat); VAR r : PACKED RECORD f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11 : day; END; Each field of the record r requires three bits. occupies 33 bits.
Table 5-9.
Table 5-10.
set_33 = SET OF (e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11, e12,e13,e14,e15,e16,e17,e18,e19,e20,e21,e22, e23,e24,e25,e26,e27,e28,e29,e30,e31,e32,e33); p_set_33 = PACKED SET OF (e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11, e12,e13,e14,e15,e16,e17,e18,e19,e20,e21,e22, e23,e24,e25,e26,e27,e28,e29,e30,e31,e32,e33); The set days has seven elements and requires seven bits. Its set chunk size is four bytes (32 bits), so days is allocated one set chunk.
To minimize storage space, avoid base types that are small subranges that overlap set chunk boundaries. Example 3 VAR s1 : SET OF 31..32; s2 : PACKED SET OF 15..16; The set s1 takes two 32-bit set chunks, using 64 bits to represent a set that requires only two bits. The arithmetic is: (floor(32/32) floor(31/32)) + 1 = (1-0) + 1 = 2. The PACKED set s2 takes two 8-bit set chunks, using 16 bits to represent a set that requires only two bits. The arithmetic is: (floor(16/8) floor(15/8)) + 1 = (2-1)+1 = 2.
The formula for the number of bytes allocated to a string is: Example VAR s1 : string[10]; s2 : string[7]; The string s1 takes 16 bytes: (((4 + 10 + 1) + 3) DIV 4) * 4 = (18 DIV 4) * 4 = 4 * 4 = 16 The allocation is: The string s2 takes 12 bytes: (((4 + 7 + 1) + 3) DIV 4) * 4 = (15 DIV 4) * 4 = 3 * 4 = 12 The allocation is: 5-: 26
Chapter 6 Dynamic Variables A dynamic variable is allocated during program execution. In contrast, a global, module, or local variable is allocated when the block containing its declaration is activated. Table 6-1 shows the differences between dynamic and static variables. Table 6-1.
appears. A variable of type globalanyptr is not bound to a specific pointer type. You can assign it any pointer-type value, or compare it to any pointer-type value with the operator = or <>, but you cannot dereference it. Because a globalanyptr variable can be assigned any pointer-type value, the compiler allocates it 64 bits. If your program does not use extended address pointers, you can save space by substituting localanyptr for globalanyptr.
LOCALANYPTR Variables The pointer type localanyptr is similar to the type globalanyptr (or anyptr ) in that it is assignment compatible with every pointer type and the value nil. A localanyptr variable differs from a globalanyptr variable in that the compiler allocates it 32 bits instead of 64 bits. If your program does not use extended address pointers, you can save space by using localanyptr instead of globalanyptr.
New Procedure The predefined procedure new takes a pointer variable as a parameter, allocates a variable of the type that the pointer references, and "points" the pointer at the new variable (that is, new assigns the address of the new variable to the pointer). The program can then access the new variable by dereferencing the pointer.
mstat := single; {New does not make this assignment} divorced := FALSE; widowed := FALSE; engaged := FALSE; END; new(person2,married); WITH person2^ DO BEGIN lname := 'Smith'; fname := 'Jane'; kids := 3; mstat := married; {New does not make this assignment} how_many_times := 1; how_long_this_time := 9; END; new(person3); END. The new record variable person1^ has space for the fixed fields lname, fname, kids, and mstat, and for the single variant fields divorced, widowed, and engaged.
new(v,a,f); END. {illegal -- with variant a, variant f is impossible} Example 4 This program is semantically equivalent to the program in the immediately preceding example (Example 3), and the declaration order of the tag fields is the same.
recptr = ^rec; VAR small, small2, large, default : recptr; PROCEDURE p (r : rec); EXTERNAL; BEGIN new(small,a); {allocates only enough space for smaller variant, a} new(small2,a); {allocates only enough space for smaller variant, a} new(large,b); {allocates enough space for larger variant, b} new(default); {allocates enough space for larger variant by default} WITH small^ DO BEGIN t := a; a1 := 350; a2 := 609; END; WITH large^ DO BEGIN t := b; b1 := 350; b2 := 609; END; (Example is continued on next page.
Dispose Procedure The predefined procedure dispose takes a pointer variable as a parameter and deallocates the dynamic variable that it references. When the variable is deallocated, it is inaccessible, and the pointer is undefined. Files in the deallocated space are closed. The procedure new can only reallocate the space that dispose has deallocated if the program contains the compiler option HEAP_DISPOSE.
new(v4); p(v4^); new(v4); r(v4); {s (within r) disposes r's actual parameter v4, which is illegal} new(v4); new(v5); WITH v4^,v5^ DO BEGIN f1 := 1; f2 := 2; f3 := 3; q; {illegal -- q disposes v4 while the WITH statement whose record variable list it is in is active} dispose(v5); {illegal -- v5 is in the record variable list of an active WITH statement} END; END.
Mark and Release Procedures The predefined procedure mark takes a pointer variable p as a parameter, marks the state of the heap, and sets the value of p to specify that state. The pointer variable p is called a mark (once a pointer variable becomes a mark, you cannot dereference it). You can allocate heap space beyond the mark, and then deallocate that space with the predefined procedure release.
ptr2 = ^real; ptr3 = ^char; ptr4 = ^ptr3; VAR m1 m2 m3 m4 m6 : : : : : ptr1; ptr2; ptr3; ptr4; ptr1; r : RECORD i : integer; m5 : ptr1; END; BEGIN mark(m1); mark(m2); mark(m3); new(m4); mark(m4^); {m4^ is of type ptr3} mark(r.m5); new(m6); release(m6); END. {illegal -- current value of m6 was assigned by new} If you set several marks, and release one of them, those set after it are also released.
specified size and alignment. If it succeeds, it "points" its VAR pointer parameter at the first element of the region and assigns its VAR Boolean parameter the value true. If it fails, it assigns its VAR Boolean parameter the value false.
intpointer = ^integer; VAR b : Boolean; i : integer; ptr1, ptr2 : intpointer; PROCEDURE p_getheap (VAR regptr regsize alignment VAR ok : : : : intpointer; integer; integer; Boolean); EXTERNAL; PROCEDURE p_rtnheap (VAR regptr regsize alignment VAR ok : : : : intpointer; integer; integer; Boolean); EXTERNAL; BEGIN p_getheap(ptr1,40,4,b); ptr2 := ptr1; {allocate a 40-byte region} {save ptr1 for later call to p_rtnheap} FOR i := 1 TO 10 DO BEGIN ptr2^ := i; ptr2 := addtopointer(ptr2,4); END; p_rtnheap(p
p_getheap(ptr1,4,4,b); {allocate a 4-byte region} (Example continued on next page.) release(ptr2); ptr1^ := 0; p1^ := p2^ + p3^; END. {The 4-byte region was not deallocated, and the values in it are still accessible} {illegal -- p1, p2, and p3 were deallocated} Getheap and Rtnheap Procedures The procedures getheap and rtnheap are intrinsics in the Pascal run-time library.
Chapter 7 Parameters This chapter explains: * The differences between value and reference parameters. * ANYVAR and READONLY reference parameters (which are HP Pascal system programming extensions). * Conformant array parameters. * Routines (procedures and functions) as parameters. * Congruent parameter lists. * Hidden parameters (which affect debugging and interfacing with external non-Pascal routines).
depending on your implementation. HP Pascal with system programming extensions has two additional kinds of reference parameters: ANYVAR and READONLY. An actual READONLY parameter can be a constant, an expression, or a function result.
ANYVAR Parameters An ANYVAR parameter parameter is passed routine changes the value of the actual is similar to a VAR parameter in that its actual by reference and must be a variable access. If the value of a formal ANYVAR parameter, it changes the parameter. An ANYVAR parameter differs from a VAR parameter in that its actual parameter can be of any type. HP Pascal treats the actual parameter as if it were of the data type of the formal ANYVAR parameter. This is implicit type coercion.
j : shortint; i : integer; PROCEDURE show_anyvar_alignment (ANYVAR anyvar_parm : shortint); EXTERNAL; BEGIN show_anyvar_alignment(c); {illegal -- must be 2-byte-aligned} show_anyvar_alignment(j); {legal} show_anyvar_alignment(i); {legal -- references high-order 2 bytes} END. When HP Pascal passes an actual parameter to a formal ANYVAR parameter, it also passes a hidden parameter. The hidden parameter can be used to determine the size of the actual parameter. See "Hidden Parameters" for more information.
(varp), and a READONLY parameter (readonlyp). Conformant Array Parameters A conformant array parameter is a formal array parameter defined by a conformant array schema (the syntax appears in the HP Pascal/iX Reference Manual or the HP Pascal/HP-UX Reference Manual ). Its actual parameter must be an array variable that conforms to the schema. An array variable conforms to a conformant array schema if all of the following are true: * The variable and the schema are both PACKED, or neither is PACKED.
different but structurally equivalent ways. Example 2 VAR var1 : ARRAY [3..5,1..10] OF integer; var2 : ARRAY [3..5] OF ARRAY [1..10] OF integer; PROCEDURE p (yes1 : ARRAY [lb1..ub1 : itype] ARRAY [lb2..ub2 : itype] yes2 : ARRAY [lb3..lb3 : itype; lb4..ub4 : itype] no1 : ARRAY [lb5..ub5 : itype] no2 : ARRAY [lb6..ub6 : itype; lb7..ub7 : itype; lb8..
Table 7-2. Routine Parameters versus Parameters of Routine Type ---------------------------------------------------------------------------------------------| | | | | | Routine Parameter | Parameter of Routine Type | | | | | ---------------------------------------------------------------------------------------------| | | | | Availability | ANSI Pascal | System programming extensions.
END; FUNCTION actual_funcparm1 (z : integer) : char; {user-defined function} BEGIN . . END; PROCEDURE actual_procparm2; {another user-defined procedure} BEGIN . . END; FUNCTION actual_funcparm2 : integer; {another user-defined function} BEGIN . . END; BEGIN {prog} p(actual_procparm1, {actual parameter for procparm1} actual_funcparm1); {actual parameter for funcparm1} s := f(actual_procparm2, {actual parameter for procparm2} actual_funcparm2); {actual parameter for funcparm2} END.
$STANDARD_LEVEL 'HP_MODCAL'$ PROGRAM prog; TYPE proctype1 functype1 proctype2 functype2 = = = = PROCEDURE (a,b : integer); FUNCTION (c : integer) : char; PROCEDURE; FUNCTION : integer; VAR s : char; PROCEDURE p (procparm1 : proctype1; funcparm1 : functype1); VAR ch : char; BEGIN call(procparm1,1,2); ch := fcall(funcparm1,3); END; FUNCTION f (procparm2 : proctype2; funcparm2 : functype2); VAR i : integer; BEGIN call(procparm2); i := fcall(funcparm2); END; PROCEDURE actual_procparm1 (x,y : integer); BEGIN
Variables of Routine Types Variables of routine types (procedure and function types) can be actual parameters for formal parameters of routine types (function and procedure types, respectively). See "Parameters of Routine Types" . The values that you can assign to a function variable are: * The value nil. * The value returned by the predefined function addr when you call it with the name of an appropriate function (appropriate is defined below).
PROCEDURE p1 (a,b : integer); EXTERNAL; PROCEDURE p2 (a,b : integer); EXTERNAL; FUNCTION f1 (a,b : integer) : integer; EXTERNAL; FUNCTION f2 (a,b : integer) : integer; EXTERNAL; BEGIN read(b); IF b THEN BEGIN procvar := addr(p1); funcvar := addr(f1); END ELSE BEGIN procvar := addr(p2); funcvar := addr(f2); END; call(procvar,10,20); i := fcall(funcvar,10,20); END. Example 2 This program declares procedures and procedure variables at different levels and assigns each procedure visible to each variable.
Example 3 This program uses functions whose return types are function and procedure types to assign values to routine variables. The comments tell you which assignments are illegal and why.
IF j IN [-10..-1] THEN procvar2 := addr(gamma) ELSE IF j IN [0..10] THEN procvar2 := addr(delta); {Call procvar1 and procvar2, unless they are nil} IF procvar1 = nil THEN writeln('i is out of range') ELSE call(procvar1,i,j); IF procvar2 = nil THEN writeln('j is out of range') ELSE call(procvar2,i,j); END. Call Procedure The predefined procedure call executes a call to the procedure specified by a procedure variable.
v1 : ^integer; FUNCTION f (a,b : integer) : integer; BEGIN f := (a+b)*(a-b); END; BEGIN new(v1); funcvar := addr(f); v1^ := fcall(funcvar,27,94); v1^ := f(27,94); END. The calls to the functions fcall equivalent. The first parameter to fcall value nil or be undefined. and f are semantically (the function variable) cannot have the Congruent Parameter Lists Two parameter lists are congruent if they have the same number of parameters, and if parameters in the same positions are equivalent.
. END; FUNCTION func (PROCEDURE pvar (x : integer)) : real; BEGIN . . END; PROCEDURE PROCEDURE PROCEDURE PROCEDURE PROCEDURE p1 p2 p3 p4 p5 BEGIN proc(p1); proc(p2); proc(p3); proc(p4); proc(p5); (a : (a : (VAR (a,b (a : r r r r r END.
proc(f1); proc(f2); {illegal} r := func(f2); r := func(f1); END. {illegal} The procedure proc has a function parameter, funcvar. The parameter list of funcvar is congruent with the parameter list of the function f1, but not with that of f2. Therefore, f1 can be an actual parameter for funcvar, but f2 cannot. The function func has a function parameter, fvar. The parameter list of fvar is congruent with the parameter list of the function f2, but not with that of f1.
passed. Example 4 PROGRAM prog (output); PROCEDURE outer2 (PROCEDURE procvar (v : integer)); BEGIN {outer2} procvar(7); END; {outer2} PROCEDURE outer1 (p : integer); VAR x : integer; PROCEDURE inner (i : integer); BEGIN {inner} writeln(x,i,x+i,p); END; {inner} BEGIN {outer1} x := 5; outer2(inner); END; {outer1} BEGIN {prog} outer1(2); END.
| | | | | | Extensible parameter | One hidden parameter. | First parameter. | Number of actual | | list | | | parameters passed | | | | | (excluding hidden | | | | | parameters). | | | | | | -----------------------------------------------------------------------------------------------| | | | | | Multi-dimensional | One hidden parameter | Each one follows | Element size, in | | conformant array | for each nested | bounds values of | units meaningful to | | parameters | conformant array.
Including hidden parameters ( highlighted), the parameter list that appears as p(1,x,y,4,z) in the preceding program is: ------------------| | | Value 1 | | | ------------------| | | Address of x | | | ------------------| | | Size of x | | | ------------------| | | Address of y | | | ------------------| | | Size of y | | | ------------------| | | Value 4 | | | ------------------| | | Address of z | | | ------------------| | | Size of z | | | ------------------You can access these hidden parameters with the
p1(v); p2(v); END. {prog} The preceding program prints: Size of actual parameter = 80 Bit size of actual parameter = 640 Size of formal parameter = 44 Bit size of formal parameter = 352 The procedure p1 does not specify the option UNCHECKABLE_ANYVAR, so it can access the hidden parameter associated with the actual parameter v. The functions sizeof(parm) and bitsizeof(parm) return the size of the actual parameter v.
In the third call, p receives two values from the actual parameter list; the value of the hidden parameter is two. In the fourth call, p receives one value from DEFAULT_PARMS and one from the actual parameter list; the value of the hidden parameter is two. For more information on OPTION EXTENSIBLE and OPTION DEFAULT_PARMS, see Chapter 8 .
The call p(a) passes two hidden parameters to p, one for each nested conformant array dimension.
VAR i : integer; BEGIN {p} param1(v); param2(v); i := param3(v); END; {p} PROCEDURE actual1 (a : integer); PROCEDURE actual2 (b : integer); FUNCTION actual3 (c : integer) : integer; BEGIN {actual3} p(actual1,actual2,actual3,100); END; {actual3} BEGIN {actual2} . . END; {actual2} BEGIN {actual1} . . END; {actual1} BEGIN . . . END.
EXTERNAL SPL VARIABLE The EXTERNAL SPL VARIABLE directive causes the compiler to pass a hidden parameter that specifies the presence of parameters. The hidden parameter is a 32 bit integer with the mask right justified as required by SPL/V. Example program prog1; var count : integer; procedure ext_spl(p1, p2, p3 : integer); external spl variable; begin ext_spl(1,,count); ext_spl(1); end.
Chapter 8 Procedure Options Procedure options, which immediately follow a routine head, can specify: * That the routine has an extensible parameter list--that is, one or more optional parameters (EXTENSIBLE option). * Default values for formal parameters, allowing their actual parameters to be left out of actual parameter lists (DEFAULT_PARMS option). * That formal ANYVAR parameters do not have the usual hidden parameters that specify their sizes (UNCHECKABLE_ANYVAR option).
NOTE You can pass only level 1 procedures to EXTENSIBLE. You cannot pass large (greater than 8 bytes) value parameters to an extension parameter. Example PROGRAM prog; $STANDARD_LEVEL 'EXT_MODCAL'$ VAR b : boolean; FUNCTION f (i,j : integer) : boolean OPTION EXTENSIBLE 2; {both parameters are required} BEGIN . . END; PROCEDURE p (x,y : integer) OPTION EXTENSIBLE 0; BEGIN . . END; PROCEDURE q (a : b : c : d : OPTION BEGIN . .
can specify or omit actual parameters for them. If the second actual parameter is specified, the first must also be specified. The first two parameters of the procedure q are nonextension parameters; the last two are extension parameters. A call to q must specify actual parameters for the first two parameters, but it can specify or omit actual parameters for the last two parameters. If the fourth actual parameter is specified, the third must also be specified.
. . END; END; {p} The procedure p must be recompiled, but the program oldprog need not be. Its call to p is still legal, as is the call to p from the program newprog: PROGRAM newprog; PROCEDURE p (n1,n2,e1,e2 : integer) OPTION EXTENSIBLE 2; EXTERNAL; BEGIN p(1,2,3,4); END. A call to a routine with an extensible parameter list contains a hidden parameter. See Chapter 7 for details.
If it is left out of the middle, its default value is assigned to the formal parameter. If it is left off the end, no value is assigned to the formal parameter. Example PROGRAM prog; PROCEDURE p (a,b,c : integer) OPTION EXTENSIBLE 0 {all parameters are extensible} DEFAULT_PARMS (a:=1,b:=2,c:=3); {all have default values} BEGIN . . . END; BEGIN p(9,,5); p(6,7); p(8); p(,4,5); END.
Haveoptvarparm Function A routine can use the predefined function haveoptvarparm to determine whether the value that it received for a formal reference parameter was passed as an actual parameter or defaulted.
Table 8-2. Values Returned by Haveoptvarparm(x) -----------------------------------------------------------------------------------------------| Type of Parameter | Actual | Position of x in formal parameter list p(..,n,..) | | | Parameter | where n is the last actual parameter specified in | | | for x is | the actual parameter list p(..
Table 8-3. Values Returned by Haveextension(x) -----------------------------------------------------------------------------------------------| | | | | | Actual | Position of x informal parameter list p(..,n,..) | | | Parameter | where n is the last actual parameter specified in the | | Type of Parameter | for x is | actual parameter list p(..
UNRESOLVED The UNRESOLVED procedure option prevents the compiler/linker/loader from resolving a routine until the program calls it. The routine must be at level one. To resolve a routine is to associate it with its system name. Calling an OPTION UNRESOLVED routine implicitly resolves it at run-time, before it is called. The routine must be resolvable. Alternatively, an OPTION UNRESOLVED routine can be explicitly resolved by calling the predefined function addr with the routine name as its parameter.
BEGIN max(10,20,i); max(i,j,k); END. is equivalent to the program: PROGRAM prog; VAR i,j,k : integer; BEGIN {max(10,20,i)} IF 10 > 20 THEN i := 10 ELSE i := 20; {max(i,j,k)} IF i > j THEN k := i ELSE k := j; END. The INLINE procedure option requires STANDARD_LEVEL 'EXT_MODCAL'. The equivalent INLINE compiler option does not. Refer to the HP Pascal/iX Reference Manual or the HP Pascal/HP-UX Reference Manual, depending on your implementation, for more information on the INLINE compiler option.
Chapter 9 External Routines An external routine is a routine that is not in the compilation unit that calls it. Its source language can be the same as that of the calling compilation unit or it can be different. This chapter explains: * The EXTERNAL directive, which allows an HP Pascal compilation unit to access an external routine. * How an HP Pascal program accesses external routines written in C, COBOL II, FORTRAN 77, FORTRAN 66/V, and SPL.
SPL The source code of the external routine is SPL, without option variable parameters. The compilation unit that makes the call must also contain the compiler option HP3000_16 (see compiler options in the HP Pascal/iX Reference Manual or the HP Pascal/HP-UX Reference Manual ). See Table 9-4 for corresponding HP Pascal and SPL types. SPL VARIABLE The source code of the external routine is SPL, with optional variable parameters.
END. {pascal_pascal} This is the external Pascal procedure: $EXTERNAL$ PROGRAM PASCALSUB; VAR global : integer; PROCEDURE psubproc ( adder : integer; VAR total : integer); VAR localconstant : integer; BEGIN {psubproc} IF (global MOD 2) = 0 THEN localconstant := adder * 2 ELSE localconstant := adder; total := total + localconstant; END; {psubproc} BEGIN END. You can use the EXTERNAL directive with procedure declarations in the implement part of a module.
Table 9-1.
| | | -------------------------------------------------------------------------------------------| | | | Pointer: EXTNADDR | Long ptr to corresponding type7 | | | | -------------------------------------------------------------------------------------------| | | | Procedure | void function | | | | -------------------------------------------------------------------------------------------| | | | Procedure parameter or variable | Pass a pointer that references a C | | | function6 | | | | ----------------------
real Re ; unsigned char Ch ; } UnionType ; corresponds to the untagged HP Pascal record variant UnionType = RECORD CASE integer OF 1 : (In : integer) ; 2 : (Re : real) ; 3 : (Ch : char) ; END ; while the tagged HP Pascal record variant Tagged_UnionType = RECORD CASE Tag : integer OF 1 : (In : integer) ; 2 : (Re : real) ; END ; corresponds to the C struct type typedef struct { Tag : int ; union { int : In ; float : Re ; } } Tagged_UnionType ; 5.
BEGIN ... END ; BEGIN { main program } { Actual call to C function Signal } Dummy := Signal(3 , waddress(Signal_Handler) ) ; END . Declaring a long pointer in C is analogous to declaring an ordinary pointer in Pascal, except that the "*" is replaced by "^". For example, 7. int Func (Rec) struct Stat ^Rec ; declares Rec to be a VAR $EXTNADDR$ of type Stat. 8.
Pascal program: PROGRAM Pascal_C2 (output); VAR str : string[40]; FUNCTION c_read (VAR s : string) : Boolean; EXTERNAL C; BEGIN setstrlen(str,0); IF c_read(str) THEN writeln('str = ', str) ELSE writeln('couldn''t read str'); END. C routine: #include int c_read(s) /* no Boolean type in C */ char *s; { return (fgets(stdin,s) >= 0); } Calling COBOL II from HP Pascal The table and example in this and the COBOL II routine that If the COBOL II routine is in write a switch stub to access Stubs" ).
- PAC of n characters - PIC X(n ) (8 bits). --------------------------------------------------------------------------- Pointer - Not available. --------------------------------------------------------------------------- Procedure - Not available. --------------------------------------------------------------------------- Procedure parameter or variable - Not available. --------------------------------------------------------------------------- Real - Not available.
Calling FORTRAN 77 from HP Pascal The table and example in this section assume that the HP Pascal program and the FORTRAN 77 routine that it calls are both compiled in Native Mode. If the FORTRAN 77 routine is in a Compatibility Mode SL instead, you must write a switch stub to access it from your HP Pascal program (see "Switch Stubs" ). Table 9-3 matches corresponding HP Pascal and FORTRAN 77 or FORTRAN 66/V types. (It contains only the types that are acceptable for formal intrinsic parameters.
| Pointer | Not available | | | | ------------------------------------------------------------------------------| | | | Procedure | Subroutine3 | | | | ------------------------------------------------------------------------------| | | | Procedure parameter or variable | Not available | | | | ------------------------------------------------------------------------------| | | | Real | REAL or REAL*4 | | | | ------------------------------------------------------------------------------| | | | Record | Build e
CHARACTER*(*) Str2 ... RETURN END An HP Pascal program that calls the FORTRAN 77 routine: TYPE Str40 = string[40] ; Pac80 = PACKED ARRAY [1..80] OF char ; FUNCTION F77_Func (VAR Str1 : Pac80 ; VAR Str2 : Str40) : Str40 ; EXTERNAL FTN77 ; VAR Vbl1, Vbl2 : Str40 ; Pac1 : Pac80 ; BEGIN { main program } ... Vbl2 := strrtrim(F77_Func(Vbl1,Pac1)) ; ... END ; 3. This is not correctly implemented in FORTRAN 77. Example The Pascal program Pascal_Fort FORTPRC.
RETURN END Calling FORTRAN 66/V from HP Pascal FORTRAN 66/V is a Compatibility Mode language only. The FORTRAN 66/V routine that your HP Pascal program calls must reside in a Compatibility Mode SL, and you must write a switch stub to access it from your HP Pascal program (see "Switch Stubs" ). The directive EXTERNAL FORTRAN passes parameters the same way in HP Pascal as it does in FORTRAN 66/V. For corresponding HP Pascal and FORTRAN 66/V types, see Table 9-3 "Calling FORTRAN 77 from HP Pascal" .
Table 9-4. Corresponding HP Pascal and SPL Types --------------------------------------------------------------------------------------------| | | | HP Pascal Type | Corresponding SPL Type | | | | --------------------------------------------------------------------------------------------| | | | Array: Not PACKED | Array of corresponding type. | | | | --------------------------------------------------------------------------------------------| | | | Array: PACKED | Array of corresponding type.
| | | | Pointer EXTNADDR | Not available. | | | | --------------------------------------------------------------------------------------------| | | | Procedure | Procedure. | | | | --------------------------------------------------------------------------------------------| | | | Procedure parameter or variable | Not available. | | | | --------------------------------------------------------------------------------------------| | | | Real (HP3000_16) | Real.
sum : small_int; PROCEDURE splprc (VAR cstr : char_str; inta : small_int; intb : small_int; VAR total : small_int); EXTERNAL SPL; BEGIN a_str := 'Add these 2 numbers:'; int1 := 25; int2 := 15; writeln(a_str,int1,int2); splprc(a_str,int1,int2,sum); writeln(a_str,sum); END. SPL routine: $CONTROL SUBPROGRAM BEGIN PROCEDURE splprc(cstr,int1,int2,sum); VALUE int1,int2; INTEGER int1,int2,sum; BYTE ARRAY cstr; BEGIN sum := int1 + int2; MOVE cstr := "Sum of two numbers: "; END; END.
BEGIN PROCEDURE splprv(cstr,int1,int2,sum); OPTION VARIABLE; VALUE int1,int2; INTEGER int1,int2,sum; BYTE ARRAY cstr; BEGIN sum := int1 + int2; MOVE cstr := "Sum of two numbers: "; END; END. Switch Stubs A switch stub is a program that allows your HP Pascal program, which is compiled in Native Mode (the default on PA-RISC machines) to call a routine compiled in Compatibility Mode (the default on earlier HP 3000 machines). The routine must reside in a Compatibility Mode SL.
You must write a switch stub for each Compatibility Mode routine that your program calls. The Switch Assist Tool (SWAT), an interactive utility, can help you write your switch stubs (see step 2 of the example in "Calling SPL from HP Pascal" ). For more information, refer to the Switch Programming Guide. How Non-Pascal Programs Call Pascal Routines A program written in C, COBOL II, FORTRAN 66/V, FORTRAN 77, or SPL can call an external routine written in HP Pascal.
COBOL II program: IDENTIFICATION DIVISION. PROGRAM-ID. COBOL-TO-PASCAL. AUTHOR. BP. DATA DIVISION. WORKING-STORAGE SECTION. 77 ASTRING PIC X(16) VALUE "A COBOL STRING!". 77 ANUM PIC 9(04) USAGE COMP. 77 ANUM2 PIC 9(04) USAGE COMP. 77 RESULT PIC -ZZZZ. PROCEDURE DIVISION. FIRST-PARA. MOVE 9999 TO ANUM. DISPLAY ASTRING. CALL "PASPROG" USING ASTRING, \ANUM\, ANUM2. MOVE ANUM2 TO RESULT. DISPLAY ASTRING, RESULT. STOP RUN. Pascal procedure: $SUBPROGRAM$ PROGRAM pas_proc; TYPE charstr = PACKED ARRAY [1..
VAR sum : small_int); BEGIN carr := 'Sum of two numbers: '; sum := sint1 + sint2; END; BEGIN END. Example 4 The following FORTRAN77 program calls the external Pascal procedure pas: $ALIAS PAS(%REF,%VAL,%VAL,%REF) INTEGER INT1, INT2, ISUM CHARACTER CSTR*20 CSTR = "Add these 2 numbers" INT1 = 25 INT2 = 15 PRINT *, CSTR, INT1, INT2 CALL PAS(CSTR, INT1, INT2, ISUM) PRINT *, CSTR, ISUM STOP END Pascal procedure: $SUBPROGRAM$ PROGRAM example; TYPE arr = PACKED ARRAY [1..20] OF char; small_int = -32768..
PRINT(chr,10,0); len := ASCII(sint,-10,cint); len := ASCII(sint2,-10,cint2); PRINT(cint,-2,0); PRINT(cint2,-2,0); pas(chr,sint,sint2,sum); PRINT(chr,10,0); len := ASCII(sum,-10,csum); PRINT(csum,-2,0); END. Pascal procedure: $HP3000_16$ $SUBPROGRAM$ PROGRAM example; TYPE arr = PACKED ARRAY [1..20] OF char; small_int = -32768..32767; PROCEDURE pas(VAR carr : arr; sint : small_int; sint2 : small_int; VAR sum : small_int); BEGIN carr := 'Sum of two numbers: '; sum := sint1 + sint2; END; BEGIN END.
$literal_alias on$ program dick(input,output $if 'hpux'$ ,stderr $endif$ ); $if 'hpux'$ type argtype = packed array[1..32000] of char; argarray= array[0..32000] of ^argtype; argarrayptr = ^argarray; var argc $alias '__argc_value'$ : integer; argv $alias '__argv_value'$ : argarrayptr; env $alias '_environ'$ : argarrayptr; procedure p_init_args $alias 'P_INIT_ARGS'$(c:integer; v,e:argarrayptr); external; $endif$ procedure u_init_traps $alias 'U_INIT_TRAPS'$; external; (Example continued on next page.
Chapter 10 Intrinsics An intrinsic is an external routine that can be called by a program written in any language that the operating system supports. An intrinsic can be written in any supported language, but its formal parameters must be of types that have counterparts in the other supported languages. An intrinsic definition resides in an intrinsic file (though its code resides in a library). You can use existing intrinsics as they are, modify them, or define new intrinsics.
compiler option.) To list an intrinsic file, use the LISTINTR compiler option (refer to the HP Pascal/iX Reference Manual the HP Pascal/HP-UX Reference Manual, depending on your implementation, for more information on the LISTINTR compiler option). NOTE The compiler options LITERAL_ALIAS and UPPERCASE apply to all external routine names, including intrinsic names. When either of these options is set, the compiler performs a case-sensitive search of the intrinsic file for the intrinsic names.
Formal parameters are optional. If you do not declare them, you can pass the intrinsic actual parameters of types that would otherwise be incompatible. Usually, programmers want this flexibility; therefore, they rarely declare formal parameters. If you do not declare a formal parameter, its actual parameters are type-checked against their corresponding intrinsic parameters. Type checking depends upon whether the intrinsic parameter is a reference, value, or function or procedure parameter.
----------------------------------------------------------------------------------------------| | | | Integer | Integer subrange m..n with either | | | m < 0 or m >= 0 and n >65535 | | | | ----------------------------------------------------------------------------------------------| | | | | Integer subrange | m < 0, or m >= 0, | Integer, or integer subrange m..n with | | m..
intrinsic parameter type, and which are not. The intrinsic parameter type is the type of the parameter as the intrinsic file declares it. actual parameter type is the type of the actual parameter. Table 10-2.
| | Bit32 | | | | Bit52 | | | | Integer | | | | Integer Subrange | | | | Longint | | | | Record | | | | Set | | | | Shortint | | | | | | ----------------------------------------------------------------------------------------------- Function and Procedure Parameter Compatibility. A function or procedure parameter is a parameter that is a routine. The compiler only checks that the actual parameter for a function or procedure parameter is a routine.
A function type must be specified when using the intrinsic directive with functions. A formal function type is compatible with an intrinsic function type as long as the size of the formal type matches the size of the intrinsic type. NOTE In general, the formal type and the intrinsic type should match the function return type. If the types do not match, they are the same as a free union type coercion. This can cause problems for signed versus unsigned types.
The program can declare intr in any of these ways: PROCEDURE intr (a, b, c, d, e : integer); INTRINSIC; PROCEDURE intr (a, b : integer); INTRINSIC; {All parameters} {Required parameters only} PROCEDURE intr (a, b, c : integer); INTRINSIC; {First extensible parameter} PROCEDURE intr (a, b, c, d : integer); INTRINSIC; {Extensible parameters} The program cannot declare intr in any of these ways: PROCEDURE intr (a : integer); INTRINSIC; {Without second nonextensible parameter} PROCEDURE intr (a, b, c,
parameter type is the type of the intrinsic parameter, as the intrinsic file declares it. The formal parameter type is the type of the formal parameter in your program. Table 10-3.
----------------------------------------------------------------------------------------------| | | | Shortint | Integer | | | | ----------------------------------------------------------------------------------------------| | | | Shortint | Integer subrange m..n | | | (except where m >=0 and n <=255) | | | | ----------------------------------------------------------------------------------------------- Table 10-4 shows which intrinsic and formal reference parameter types are compatible.
| Array | Array | | | Record | | | | --------------------------------------------------------------------------| | | | Boolean | Boolean | | | | --------------------------------------------------------------------------| | | | Char | Char | | | | --------------------------------------------------------------------------| | | | Integer | Bit16 | | | Bit32 | | | Bit52 | | | Integer | | | Integer subrange | | | Longint | | | Shortint | | | | ---------------------------------------------------------------------
program, omitting the result type. To use an intrinsic function as both a function and a procedure, declare it both ways, giving the routine different names in your program. Use the ALIAS compiler option to associate the intrinsic's system name with the names you have given it. If you declare an intrinsic function as a procedure only, you cannot call it as a function.
function returns: Anyptr Bit16 Bit32 Bit52 Longint Conformant array Enumeration File Function type Globalanyptr Localanyptr PAC, with the directive EXTERNAL FTN77 * Pointer Procedure type String Subrange m..n where m>=0 and n<=255 * An intrinsic parameter of type PAC is not an acceptable intrinsic parameter when used in an external procedure declaration with the directive EXTERNAL FTN77.
3. Declare your intrinsics as you would declare external routines (explained in Chapter 9 ), except: * Use only the acceptable intrinsic parameter types listed in "Defining Intrinsics" . * Use only these forms of the EXTERNAL directive: EXTERNAL EXTERNAL C EXTERNAL COBOL EXTERNAL FTN77 4. Leave the outer block of the compilation unit empty. Example 1 This program builds an intrinsic file.
3. Declare any new intrinsic routines (see the third instruction for building an intrinsic file). If a new routine has the same name as one that is already in the file, the new one replaces the old one; otherwise, the new one is added to the file. 4. Leave the outer block of the compilation unit empty. Example 2 This program changes the intrinsic file that the preceding example built, replacing the procedure proc1 and adding the function func1.
10: 16
Chapter 11 Error Recovery and Debugging There are three types of Pascal errors. They are: * An error, which violates the definition of the HP Pascal language. * A compile-time error, which occurs when you compile your program (as in the case of a syntax error). * A run-time error, which occurs when you run your program (as in the case of a value out of range). Errors are not to be confused with notes and warnings, both of which occur at compile time.
The procedure escape has one parameter, error_code, which is an integer expression. Escape sets error_code, whose value you can then access with the predefined function escapecode. Example PROGRAM p; VAR x : integer; ecode : integer; . . PROCEDURE PUTJCW; INTRINSIC; PROCEDURE proc (n : integer); BEGIN {proc} {Test for erroneous parameter} IF NOT (n IN [0..100]) THEN escape(-755); . . putjcw(jcwname,jcwvalue,error); IF error > 0 THEN escape(error); . .
1. The subsystem in which the error occurred (the program, a library, or the operating system) calls the predefined procedure escape with error_code as its parameter. The parameter error_code is an integer expression whose value represents the error. 2. The procedure escape 3. The program's run-time environment reverts to that of the program unit (main program, procedure, or function) that contains the TRY-RECOVER construct. 4.
BEGIN IF NOT iok THEN i := 0 ELSE newj; END; BEGIN {prog} iok := FALSE; TRY prompt('Enter an integer for i:'); read(i); {An error here transfers control to newij} iok := TRUE; {Not executed if read(i) causes an error} TRY read(j); RECOVER newj; RECOVER newij; END. {prog} {An error here transfers control to newj} {An error here transfers control to newij} {An error here aborts the program} The following example illustrates how nested TRY-RECOVER statements divide the responsibility of error recovery.
The diagram below shows when, in time, the TRY-RECOVER statements labeled A, B1, B2, and C in the preceding program are active. When more than one TRY-RECOVER statement is active, the innermost one takes precedence. The RECOVER's statement can use the predefined function escapecode to determine the error that occurred and act accordingly.
TRY-RECOVER and Optimization If the OPTIMIZE compiler option is used with the TRY-RECOVER construct, the following information explains what will or will not work at different levels. * If an ESCAPE is done in the TRY block, or in any procedure called from within the TRY block, all values on the left side of an assignment statement, appearing before an ESCAPE or a procedure call, are stored. * If a trap occurs instead of an ESCAPE, the above statement is not true.
If the compiler can determine that b is a constant expression whose value is true, then it does not generate code for the call to assert. i An integer expression. If the value of b is false and p is specified, procedure p is called with i as the actual value parameter. If b is false and p is not specified, the system issues a run-time error message that includes the value of i. A call to the predefined function statement_number is a useful integer expression for i.
The default for the ASSERT_HALT compiler option is OFF (see the HP Pascal/iX Reference Manual or HP Pascal/HP-UX Reference Manual for more information). Example PROCEDURE my_assert (value : integer); BEGIN writeln('my_assert #', value); END; PROCEDURE x (p : ptrtype; n : integer); BEGIN assert(p <> nil, 80101, my_assert); assert(n >= 0, 80102); END; Traps Your HP Pascal program can use these MPE/iX traps: * MPE/iX intrinsic XLIBTRAP, which traps library errors.
HPENBLTRAP (mask, oldmask ); Parameters flag 32-bit integer, passed by value. If flag is zero, all traps are disabled; otherwise, all traps are enabled. mask 32-bit integer, passed by value, whose bits specify which trap conditions are enabled. The assignment of each position in the bit mask is described in "XARITRAP Intrinsic." oldmask 32-bit integer, passed by reference, in which the old value of mask is returned.
XLIBTRAP stores the address of the Library Trap Handler (plabel ) so that the library routines can find the routine to call if an error occurs. The old value of PLabel is returned in the parameter OldPLabel. The only ways to leave a trap handler is by a normal return or by an escape. Your library trap handler cannot execute a nonlocal goto (a goto whose destination is outside the procedure). NOTE This routine is available on the MPE/iX and HP-UX operating systems.
to execute. If AbortFlag is not zero, the Pascal run-time library prints an error message and aborts the program. To trap all run-time library errors and have them invoke your Library Trap Handler, call XLIBTRAP this way: XLIBTRAP (baddress (My_Library_Trap_Handler ), OldPLabel ); To disable your Library Trap Handler, pass zero to XLIBTRAP as the first parameter.
31 30 29 28 27 26 25 24 23 22 21 20-19 18 17 16 15 14 13 12 11 10 9 8 7-1 0 Compatibility Mode floating-point divide by zero Integer divide by zero Compatibility Mode floating-point underflow Compatibility Mode floating-point overflow Integer Overflow Compatibility Mode double precision overflow Compatibility Mode double precision underflow Compatibility Mode double precision divide by zero Decimal Overflow (COBOL) Invalid ASCII digit (COBOL) Invalid decimal digit (COBOL) Reserved Decimal divide by zero IE
numbers have the format of reals on the MPE V system. The compiler options HP3000_32 and HP3000_16 specify native and compatibility Mode real numbers, respectively. For more information on HP3000_32 and HP3000_16, see the HP Pascal/iX Reference Manual or the HP Pascal/HP-UX Reference Manual, depending on your implementation.
you perform will cause this trap to be raised. To disable your Arithmetic Trap Handler, pass zero to XARITRAP as the second parameter. For the following traps, the system trap handler passes your Arithmetic Trap Handler more fields than the four defined above in the TrapInfo record, and you must adjust TrapInfo accordingly.
1. Status (word #5) contains the value in the status register of the IEEE floating-point coprocessor. Any change in this field is reflected in the value of the status register when the program resumes execution. 2. Operation (word #6) contains one of the following codes, which tells the type of floating-point operation that caused the trap. Value 3.
You can examine and replace the contents of the area referenced by result_ptr, and the Trap Subsystem will ensure that the change is reflected in the appropriate place. Compatibility Mode Floating-Point Traps. The TrapInfo record has one extra field, Result_ptr. Result_ptr (word #5) contains the address of the result of the operation, which can be a single- or double-word floating-point number, depending on the type of trap.
END; END; {divide by zero} {IEEE_trap_handler} {user main program} VAR l1, l2, l3 : longreal; oldmask, oldplabel : integer; BEGIN {main program} ARITRAP (1); {see "ARITRAP and HPENBLTRAP Intrinsics" for details} XARITRAP (IEEE_mask, BAddress (IEEE_trap_handler), oldmask, oldplabel); l1 := 233.0; l2 := 0.0; l3 := l1/l2; {oops! divide by zero!} writeln (l3); {the trap handler should have fixed the result of the previous operation to maxlongreal (1.79769e+308)} END.
keyboard, control transfers to the procedure control_y_handler, which writes the current loop counter value, then re-enables the subsystem break, and returns to the point in the loop where the interrupt occurred.
Pascal/iX Reference Manual or the HP Pascal/HP-UX Reference Manual, depending on your implementation. For information on HP TOOLSET/XL, refer to the HP TOOLSET/XL Reference Manual. For more information on HP Symbolic Debugger, refer to the MPE/iX Symbolic Debugger User's Guide. System Debuggers The compiler listing of your program is an indispensable debugging aid. The following compiler options provide the listing with additional information, as noted.
11- 20
Appendix A MPE/iX Dependencies This appendix explains how the HP Pascal compiler and HP Pascal programs work on the MPE/iX operating system. It explains: * How MPE/iX affects system dependent HP Pascal features. * MPE/iX extensions to HP Pascal. * How to compile, link, and run your HP Pascal program on MPE/iX.
Example For more information on MPE/iX file names, refer to the MPE/iX Commands Reference Manual. Associating Logical and Physical Files Your program does not affect its external environment unless its logical files are associated with physical files at run-time. If they are, file operations work concurrently on logical and physical files (see Chapter 3 ). In HP Pascal on the MPE/iX operating system, a logical file is associated with a physical file under any one of the following conditions: 1.
If a logical file name is not a program parameter, but is the first parameter of a file-opening procedure that has no second parameter, the operating system associates the logical file with a temporary, nameless physical file (assuming that the logical file is not already associated with a physical file). You cannot save the temporary file. When the program ends or the logical file is associated with another physical file, the temporary file is inaccessible. 2.
Example PROGRAM prog (outfile); VAR i : integer; outfile : text; BEGIN rewrite(outfile); FOR i := 1 TO 20000 DO writeln(outfile,i); END. If PRG is the program file for prog and you execute the MPE/iX command sequence :FILE OUTFILE = FILE2 :RUN PRG then output goes to FILE2 instead of OUTFILE. If you execute the MPE/iX command sequence FILE OUTFILE; DISC=21000; REC=-20,,F,ASCII RUN PROG then a nondefault attribute file is created.
Example MODULE mymod; IMPORT stdinput, stdoutput; EXPORT FUNCTION myproc : integer; IMPLEMENT FUNCTION myproc : integer; VAR i : integer; BEGIN prompt('enter number:'); readln(i); myproc := i; END; END. {need not specify output file} {need not specify input file} Additional Features The HP Pascal features in the left-hand column depend on the MPE/iX operating system in the ways explained in the right hand column.
file-opening procedures append, associate, open, read, reset, rewrite, and write. They and their meanings are: Option Meaning CCTL The file has carriage control. (Ignored for associate.) DIRECT The file is open for read and write access (associate only). NOCCTL The file does not have carriage control. (Ignored for associate.) READ The file is open for read access only (associate and open only). WRITE The file is open for write access only (associate and open only).
MPE/iX Extensions MPE/iX extensions are available only to programs that are run on the MPE/iX operating system or contain the compiler option OS 'MPE/XL'. They are: * Predefined function ccode * Predefined function fnum * Predefined function get_alignment * Predefined function statement_number * Predefined procedure setconvert * Predefined procedure strconvert * Pascal/V packing algorithm ccode Function The predefined function ccode returns an integer in the range 0..
physical file currently associated with a given logical file. You can use this file number in calls to MPE/iX file system intrinsics. Syntax fnum (filename ) Parameter filename The name of the logical file. This parameter is required, even if the logical file is the standard file input or output. The logical file must be associated with a physical file. Example PROGRAM aaa (output,f); VAR f : text; file_number : integer; file_name : PACKED ARRAY [1..
ptr : ^integer_; BEGIN i := get_alignment(rec); IF get_alignment(ptr^) <> 2 THEN ... END. Statement_number Function The predefined function statement_number returns the statement number of the statement that calls it, as shown on the compiled listing. It is a useful debugging aid, especially when used with the predefined procedure assert.
set32_1 : hp3000_32_set1; set32_2 : hp3000_32_set2; set32_3 : hp3000_32_set3; BEGIN setconvert(set16_1,set32_1); setconvert(set32_1,set16_1); {convert from Pascal/V to HP Pascal} {convert from HP Pascal to Pascal/V} setconvert(set16_1,set32_2); setconvert(set16_1,set32_3); setconvert(set16_1,set16_2); END.
algorithm. algorithm. * Buffer size is determined by the Pascal/V packing Variables of types that specify the HP3000_32 compiler option are allocated and aligned according to the HP Pascal packing algorithm. Unpacked Variables. An unpacked variable is either not part of an array or record, or it is part of an unpacked array or record. In either case, it is allocated and aligned the same way.
----------------------------------------------------------------------------------------------| | | | | Longint | 8 bytes | 2-byte | | | | | ----------------------------------------------------------------------------------------------| | | | | Longreal | 8 bytes | 2-byte | | | | | ----------------------------------------------------------------------------------------------| | | | Pointer | HP3000_16 does not affect pointers. See Table 5-1 .
----------------------------------------------------------------------------------------------| | | | | Bit16 | 2 bytes | 2-byte | | | | | ----------------------------------------------------------------------------------------------| | | | | Bit32 | 4 bytes | 2-byte | | | | | ----------------------------------------------------------------------------------------------| | | | | Bit52 | 8 bytes | 2-byte | | | | | ----------------------------------------------------------------------------------------------|
section, "Pascal/V Packing Algorithm" . Table A-4.
| | | ----------------------------------------------------------------------------------------------| | | | Subrange of enumeration | See "Packed Subranges of Enumerations" | | | | ----------------------------------------------------------------------------------------------| | | | Subrange of integer | See "Packed Subranges of Integers" | | | | ----------------------------------------------------------------------------------------------- Arrays.
is allocated and aligned like this: Files. The HP Pascal compiler allocates space for an HP3000_16 file this way: * The file control block is allocated according to the HP Pascal packing algorithm. * The file buffer variable size is allocated according to the Pascal/V packing algorithm. * The file is 8-byte-aligned. Records. This section applies to unpacked and packed records unless otherwise noted. The Pascal/V packing algorithm does not always align variant parts of fields on the same boundary.
FALSE Variant The variants f1 and f2 do not start on the same boundary; therefore, f1 cannot be overlaid with f2. Sometimes you can reduce the space that a record takes by declaring its fields in different order. Example VAR upr1 : RECORD b : boolean; p : 0..32767; c : char; END; upr2 : RECORD b : boolean; c : char; p : 0..32767; END; The only difference between the variables upr1 and upr2 above is the order of their fields.
Sets. The Pascal/V packing algorithm allocates sets in byte pairs. The number of byte pairs allocated to a set depends on its type. For the types Boolean, char, enumeration, and integer, the formula for the number of byte pairs is: number_of_byte_pairs = ceil(bits_required_for_set /16) (where ceil(x ) means the integer closest to x that is greater than or equal to x ). Table A-5 gives the values for bits_required_for_set and number_of_byte_pairs for Boolean, char, and integer types. Table A-5.
The set months has 12 elements and requires 12 bits. It is allocated one byte pair (ceil(12/16) = 1). Each element is represented by one bit. The set set_33 has 33 elements and requires 33 bits. It is allocated three byte pairs (ceil(33/16) = 3). Each element is represented by one bit.
To minimize storage space, avoid base types that are small subranges that overlap byte pair boundaries. Example VAR s : SET OF 31..32; The set s takes two byte pairs, using 32 bits to represent a set that requires only two bits. The arithmetic is: floor(32/16) - floor31/16) + 1 = (2-1)+1 = 2. Strings. The Pascal/V packing algorithm aligns strings on 2-byte boundaries. Because the current length (0..32767) is allocated two bytes, four bytes is the smallest possible string allocation.
Example VAR s1 : string[10]; s2 : string[7]; The string s1 takes 14 bytes: 2+10+{2-ORD[ODD(10)]} = 12+[2-ORD(FALSE)] = 12+(2-0) = 14 The allocation is: The string s2 takes 10 bytes: 2+7+{2-ORD[ODD(7)]} = 9+[2-ORD(TRUE)] = 9+(2-1) = 10 The allocation is: A-: 21
Packed Enumerations. This subsection explains how the Pascal/V packing algorithm allocates and aligns packed enumeration variables. A packed enumeration variable is either the element of a packed array or the field of a packed record. The algorithm treats the two cases differently. Table A-6 shows the relationship between the number of bits that an enumeration element of a packed array requires, the number of bits that the Pascal/V packing algorithm allocates it, and its alignment.
Table A-7.
Example TYPE day = (sun,mon,tues,wed,thurs,fri,sat); enum_32 = (e1,e2,e3,e4,e5,e6,e7,e8, e9,e10,e11,e12,e13,e14,e15,e16, e17,e18,e19,e20,e21,e22,e23,e24, e25,e26,e27,e28,e29,e30,e31,e32); VAR a : PACKED ARRAY [1..11] OF day; r : PACKED RECORD f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11 : day; END; aa : PACKED ARRAY [1..4] OF enum_32; rr : PACKED RECORD f1,f2,f3,f4 : enum_32; END; Each element of the array a requires three bits, and no element can cross a 2-byte boundary.
Packed Subranges of Enumerations. This subsection explains how the Pascal/V packing algorithm allocates and aligns packed variables whose types are subranges of enumerations. These packed variables are either the elements of packed arrays or the fields of packed records. The algorithm treats the two cases differently. The number of bits that an enumeration of a subrange type requires is determined by ord(upper_bound_of_enumerated_subrange ).
Each element of array b requires and is allocated five bits (see Table A-6 ). The elements are bit-aligned, and the entire array occupies 21 bits. It is allocated four bytes. To the enumeration-of-subrange field of a packed record, the Pascal/V packing algorithm allocates the required number of bits. Any allocation from one bit to two bytes is possible. The field is bit-aligned, but never crosses a 2-byte boundary.
Table A-9 shows the relationship between the number of bits that an element of a PACKED array of subrange type requires, the number of bits that the Pascal/V mapping algorithm allocates it, and its alignment. Table A-9.
For the integer subrange type of a packed record, any bit allocation from one bit to 15 bits is possible, as are allocations of two and four bytes. Bit allocations are bit-aligned, but never cross 2-byte boundaries. Twoand 4-byte allocations are 2-byte aligned. See "Records" for more information. Example VAR r : PACKED a : b : c : d : e : f : END; RECORD 0..1; 0..255; 0..16; 0..4; 10..40000; 0..
HP Pascal/iX Reference Manual. Figure A-1 shows how a source program (in a textfile ) becomes a running program on MPE/iX. Figure A-1. How Source Code Becomes a Running Program on MPE/iX This section explains: * The MPE/iX command files that perform the steps shown in Figure A-1 . * How to run the HP Pascal compiler with the MPE/iX command :RUN PASCALXL.PUB.SYS. * How to pass run-time parameters to your program.
right-hand column of Table A-1 performs the step or steps in the left-hand column (for example, the command :PASXL performs the compilation step, the command :PASXLLK performs the compilation and linking steps, and the command :PASXLGO performs the compilation, linking, and running steps). Table A-10.
PASXLGO [textfile ][,[listfile ][,libfile ]][; INFO="options "] Parameters textfile The name of the textfile compiled. that contains the source code to be If you are running HP Pascal from your terminal, textfile usually a file, but the default is $STDIN. $STDIN is the current input device, usually your terminal. is When textfile is the terminal, you can enter source code interactively in response to the prompt ">.
Listing file $STDLIST Library file PASLIB To override the defaults: 1. Use the MPE/iX command :FILE to equate the nondefault file with its formal file designator (the :FILE parameter formaldesignator ). Use one :FILE command for each nondefault file. 2. Tell the MPE/iX command :RUN which files are not to be defaulted by passing the appropriate value to its PARM parameter.
| | | | | | 7 | * | * | * | | | | | | --------------------------------------------------------------------------------* PARM=0 is equivalent to the command :PASXL (without parameters). Example :RUN PASCALXL.PUB.SYS :FILE PASTEXT=Program1 :FILE PASOBJ=Object1 :FILE PASLIST=List1 :FILE PASLIB=Library1 :RUN PASCALXL.PUB.SYS;PARM=7;INFO="TABLES ON" :FILE PASTEXT=Program2 :FILE PASLIST=List2 :RUN PASCALXL.PUB.SYS;PARM=3 :FILE PASLIST=List3 :FILE PASOBJ=Object3 :RUN PASCALXL.PUB.
parm : integer; info : PACKED ARRAY [1..255] OF char; BEGIN END. then the command: :RUN ex1; PARM=3; INFO="abc" assigns the value 3 to parm and the value abc to info before executing the program example_1.
Appendix B HP-UX Dependencies This appendix explains how the HP Pascal compiler works on the HP-UX operating system. It explains: * How HP-UX affects system dependent HP Pascal features. * HP-UX extensions to HP Pascal. * How to compile, prepare, and run your HP Pascal program on HP-UX. System Dependent Features System dependent features are available to all HP Pascal programs (regardless of the system on which the compiler is running), but the system affects their definitions and behavior.
Standard Modules Three standard modules are available on HP-UX: stdinput, stdoutput, and stderr. If a module imports the stdinput module, it can use the predefined file input in I/O statements such as read and readln. If a module imports the stdoutput module, it can use the predefined file output in I/O statements such as write and writeln. If a module imports the stderr module, it can use the predefined file stderr in I/O statements such as write and writeln.
setenv PASXDATA n or the command: PASXDATA=n export PASXDATA Maxpos The call maxpos(f) f. returns maxint, regardless of Open options The third parameter of the predefined file-opening procedures append, associate, open, read, reset, rewrite, and write. It is optional for all but associate, for which it must have one of the values listed in "Associate Procedure" . Ord At the STANDARD_LEVEL 'EXT_MODCAL' ord short pointers as arguments.
PROGRAM ErrorNo_Example; VAR ErrorNumber $ALIAS 'errno'$ : INTEGER; FUNCTION Pas_Errno : integer; BEGIN Pas_Errno := ErrorNumber; END; BEGIN END. When another compilation unit is linked with the preceding program, it can access the function Pas_Errno, which returns the value of the global variable errno. Fnum Function The predefined function fnum returns the HP-UX file number of the physical file currently associated with a given logical file. You[REV BEG] can use this file number in system calls.
Parameters variable Any variable. The function get_alignment returns its alignment requirement. type Any type identifier (the name of any type). The function get_alignment returns its alignment requirement. Example PROGRAM prog; TYPE Rec = $ALIGNMENT 8$ RECORD f1 : integer; f2 : shortint; f3 : real; END; integer_ = $ALIGNMENT 2$ integer; VAR ptr : ^integer_; BEGIN i := get_alignment(rec); IF get_alignment(ptr^) <> 2 THEN . . . END.
Pascal compiler, which compiles your program and stores the resultant code in an object file. The name of the object file ends in .o (if the source file name is prog.p, the object file name is prog.o). If prog.p is the only file parameter of a particular pc command, and it compiles and links successfully, then the object file is not saved. If the compiler does not find errors in the program, the pc command calls the linker, ld, which links the object file with required library files into a program file.
This section explains: * The HP-UX pc * How to pass run-time parameters to your program. * How HP-UX handles interrupts. * How HP-UX handles run-time errors. command. pc Command The HP-UX command pc coordinates the HP Pascal compiler (/usr/lib/pascomp) and the HP-UX linker loader (/bin/ld). Additionally, the compiler looks for a system-wide file called /usr/lib/pasopts. If the file exists and is not empty, the compiler opens and reads the file. The file should contain only directives and comments.
structure account/group, where group is a directory containing the file f. If a Pascal source program contains the statement $INCLUDE 'F.Group.Account'$ then the compiler appends the appropriate path information to f and searches for the resulting name (for example, root/account/group/f, where root is the parent of the account-level directories). -c Suppress linking and only produce object (.o) files from source files.
1.0 Perform scheduling tuned to a model representative of PA-RISC 1.0 implementations. 1.1 Perform scheduling tuned to a model representative of PA-RISC 1.1 implementations. The default scheduling is based on the model number returned by uname(2). This option affects only performance of the object code by scheduling the code based on the specific latencies of the target implementation. The resulting code executes correctly on other PA-RISC implementation, subject to the +DA option.
2. Directories specified with the -I option. 3. The current working directory. 4. The standard directory /usr/include. -L Write a program listing to stdout. -lx Cause the linker to search the libx.sl or libx.a libraries in an attempt to resolve currently unresolved external references. Because a library is searched when its name is encountered, placement of a -l is significant.
The arguments in the second group implicitly request level 2 optimizations, but an argument from the first group overrides the implicit level 2 regardless of their relative positions on the command line. -o outfile Name the output file from the linker outfile instead of a.out. -P lines Allow lines lines per page of compiler listing, including header or trailer (same as the LINES compiler option). -p Prepare object files for profiling with the prof utility.
-Wc,arg1 [,arg2,... argn] Cause arg1 through arg n to be handed off to subprocess c. The arg parameters are of the form: -argoption [,argvalue ] where argoption is the name of an option recognized by subprocess c and argvalue is a parameter for argoption (if it has one). The parameter c can have these values: Value c 0 d l Meaning Compiler body (standard suffix is pascomp ). Same as c. Driver program. Linker (standard suffix is ld ).
and it compiles and links successfully, then its object file, prog.o, is not saved. Example The command: pc main.p ext1.p ext2.p compiles the object files main.o, ext1.o, and ext2.o, into the final program file a.out. It is equivalent to the command sequence: pc pc pc pc NOTE -c main.p -c ext1.p -c ext2.p main.o ext1.o ext2.
The export section for the module arg is: MODULE arg; EXPORT TYPE arg_string1024 = string[1024]; arg_type = PACKED ARRAY[1..32000] OF char; argarray = ARRAY[0..32000] OF ^argtype; argarrayptr = ^argarray; FUNCTION argv : argarrayptr; FUNCTION argc : integer; FUNCTION argn (n : integer) : arg_string1024; IMPLEMENT . . . . END.
reset (file1); it is equivalent to the statement: reset (file1, 'arg1'); If there is no run-time argument for a program header file, then the upshifted formal name of the file is implicitly associated with it. For example, if the program above is run with the command: a.out arg1 then there is no run-time argument for file2, so it is associated with the file named FILE2. Of course, if you provide an explicit association, it overrides this implicit association.
Old_Action := signal (SIGQUIT, Baddress (InterruptHandler)); IF Old_Action = SIG_IGN THEN Old_Action := signal (SIGQUIT, SIG_IGN) ELSE IF Old_Action = BADSIG THEN {An invalid SignalNum or ProcAddress was passed}; END. When either of the signals SIGINT or SIGQUIT is raised (by entering CONTROL C on the keyboard, for example), the procedure InterruptHandler is called.
GLOSSARY actual parameter An argument that is passed to a procedure, function, or subprogram. Contrast with formal parameter. address An exact location in memory. this address. A program can store or retrieve data from algorithm A procedure used to solve a task. It describes the sequence of steps or operations, done in a finite number of steps. allocate To set up a memory location to hold variable values. alpha character A character in the range of A through Z and a through z.
boolean expression An expression that evaluates to a value of true or false. buffer The part of a computer or device memory where data is held temporarily until it can be processed or transmitted elsewhere. A buffer usually refers to a memory area that is reserved for I/O operations. byte A combination of eight consecutive bits treated as a unit. represents one letter or number within the computer. A byte C A high-level computer programming language that can do low-level manipulations.
disk A circular plate used to store computer data; the disk can be fixed, removable, hard, or flexible. dynamic variable A variable which is not declared and cannot be referred to by name. dynamic variable is created during execution of a program. A error recovery The process of writing code that prevents a program from aborting due to run-time errors. Error recovery code does not catch compile-time errors, warnings, or notes. executable object A program or procedure that is ready to be executed.
minint The minimum value that an integer can contain. NLS An acronym for Native Language Support. operand The variables, constants, or literals that are used in an operation. operator Defines the action to be performed on one or more operands. optimization The process which the compiler uses to modify your program so that it uses machine resources more efficiently. parameter The argument used for sending and receiving information to and from functions and procedures.
top-down design The process of breaking a problem into pieces that can be easily solved. variable A memory location that holds data values, and which is referenced by a variable name. Information in this location can be changed. warning The compiler produces warnings to indicate a possible source of run-time errors. word [REV BEG] Four consecutive bytes.[REV END] Some numeric items are defined in terms of words, and many items must start at a word boundary in memory.
G- 6