May 15, 1984 ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º A Comparison of PC Pascal and Pascal/VS º º º º by º º º º J. David Pickens º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ EDITOR'S NOTE: This is a two-part article. This excerpt is from the manuscript "A Comparison of PC Pascal and Pascal/VS" by J. David Pickens, of the Santa Teresa Laboratory. The second part will appear in the next issue of PCFL/PCUG. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Introduction ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ In recent years, Pascal has been used as a general purpose programming language and as a system program implementation language. However, "standard" Pascal, as designed by Niclaus Wirth, lacks many of the features which are required for general purpose and system programming. As a result, most implementations of the language have added extensions to give more capabilities to the Pascal programmer. The function of these extensions tend to be similar from one implementation to the next; unfortunately, the syntax and underlying philosophy vary considerably among the various implementations. Extensions and features of two Pascal implementations will be examined. One is the IBM Personal Computer Pascal (PC Pascal for short) and the other is Pascal/VS. (EDITOR'S NOTE: Pascal/VS is the implementation of Pascal on the IBM 370.) ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Constants ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Non-decimal Radicies ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Pascal/VS permits integer, floating-point, and character constants to be specified in hexadecimal: `00FF'X (*Integer*) `F1'XC (*Character*) `40100000'XR (*Real*) In addition, integer constants may also be specified in binary: `00001011'B PC Pascal supports integer constants in hexadecimal, octal, or binary radix. Floating-point may only be specified in decimal. 16#FF02 (*Hexadecimal*) #FF02 (*Hexadecimal*) 8#776 (*Octal*) 2#1010 (*Binary*) The value of allowing floating point numbers to be specified in hexadecimal is not obvious. A Pascal/VS program which uses this facility would not be portable. Floating-point data is represented differently on the System/370 than on the IBM Personal Computer. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Constant Expressions ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ A constant expression (or static expression) is an expression which can be evaluated at compile time. Both Pascal Compilers permit constant expressions where constants are required. Built-in functions such as ABS, ORD, CHR, etc. may appear in a constant expression. const PI = 3.14159; TWO_PI = 2 * PI; ORDA = ORD(`A'); ORDA1 = ORDA + 1; type MINUTES = 0..24*60; SECONDS = 0..sqr(60)*24; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Structured Constants ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ A structured constant is a constant which is of a structured data type. Both compilers support structured constant and with almost identical syntax. const LETTERS = [`A'..`Z',`a'..`z']; type COMPLEX = record RE,IM: REAL end; const Q = COMPLEX(3.0,4.0); type VEC = array[-2..2] of INTEGER; const VECT = TVEC(5,4,3,2,1); ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Data Types ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Integers ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Integer variables in Pascal/VS can occupy 1,2,3, or 4 bytes. Pascal/VS supports unsigned integers which may occupy 1,2, or 3 bytes. The default integer size is 4 bytes (1 full word). To declare an integer with a smaller size, a subrange type definition is prefixed with the word packed. type HALFWORD = packed -32768..32767; (*2 bytes, signed*) UNSIGNED = packed 0..65535; (*2 bytes, unsigned*) BYTE = packed 0..255; (*1 byte, unsigned*) Pascal/VS does not support unsigned, full word integers. PC Pascal supports 1 and 2 byte integers; both signed and unsigned. To declare an unsigned integer, the predefined type WORD is used. Subrange types are automatically mapped to single bytes if the range permits it. var SIGNED_BYTE : -127..127; (*1 byte variable, signed*) UWORD : WORD; (*2 bytes variable, unsigned*) type BYTE = WRD(0)..255 (*1 bytes, unsigned*) Most Pascal compilers which allow byte packing of integer subranges do it implicitly, as is done in PC Pascal. On the other hand, Pascal/VS will map an integer subrange to a 4 byte word unless it is qualified with the word "packed". Unfortunately, most Pascals would diagnose a "packed" subrange as an error. (Standard Pascal allows only structured types to be "packed"). In other words, Pascal/VS has extended the language to support a feature which could have been supported within the language. PC Pascal does not support integers which are greater than two bytes in length (the word length of the IBM-PC). As a consequence, many Pascal programs which depend on integers outside the range of -32767 to 32768 would need major redesigning in order to run under PC Pascal. (One possibility is to add a predefined type called "DOUBLE" or "LONG_INTEGER," which would allow 4 byte integers to be declared.) ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Floating Point ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Pascal/VS supports two precisions of floating point data: double precision (8 bytes) and single precision (4 bytes). The standard predefined type REAL is used to declare a double precision variable; a predefined type called "SHORTREAL" was added to declare a single-precision variable. var R: REAL; (*double precision floating point*) S: SHORTREAL; (*single precisions*) PC Pascal supports only one floating point type which consists of 4 bytes: a 24 bit mantissa and an 8-bit binary exponent, giving about 7 digits of precision. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Conformant/ Dynamic Arrays ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ A well known problem in standard Pascal is in the compatibility rules governing array variables. Arrays of different lengths are never compatible and, as a result, one is unable to write a general procedure for manipulating vectors and matrices. PC Pascal has defined a type mechanism called "SUPER ARRAYS" which permits you to define a class of arrays with different lengths. For example: type VECTOR = super array [1..*] of REAL; MATRIX = super array [1..*,1..*] of REAL; VECT10 = VECTOR(10); MATDEC = MATRIX(100,100); var ROW: VECT10; COL: VECTOR(10); MAT: MATRIX(40,40); procedure INVERT(var M: MATRIX); EXTERN; begin ... INVERT(MAT); (*allows any MATRIX type*) ... end; In a variable declaration, the super type must be qualified with operands which designate the array length (as in the declaration of COL and MAT above.) If a formal reference parameter is being declared, only the super type name need appear (as in the declaration of INVERT above). Any variable declared with the corresponding super type may be passed as the formal parameter, regardless of the length. As a by-product of the super type mechanism, PC Pascal has added dynamic arrays - arrays for which a length is not determined until execution time. Dynamic arrays are defined by declaring a pointer to a super array. The length of the pointer's object is determined when the object is allocated (via NEW). type VECTOR = super array [1..*] of INTEGER; var ROWP : @VECTOR; L : INTEGER; procedure INVERT(var M: MATRIX); EXTERN; begin ... NEW(ROWP,L); (*Allocates a VECTOR array of length L*) ... end; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Strings ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Both compilers support character-string variables which may vary in length at execution time. Pascal/VS has added a predefined type called "STRING". When used in a variable declaration, the word STRING must be qualified with a positive integer constant which specifies the maximum length of the string variable. var S: STRING(100); (*S declared as string with max of 100*) PC Pascal has added two predefined types to define strings: "STRING" and "LSTRING". STRING defines a super array which is equivalent to: packed array[1..*] of CHAR LSTRING defines a string with a length which may vary at execution time. Thus, the type LSTRING in PC Pascal is similar to the type STRING in Pascal/VS. Both STRING and LSTRING are qualified with a length when used in a variable declaration. Both compilers have relaxed the strict type compatibility rules in handling string data. A string variable may be assigned to another and their lengths need not be the same. PC Pascal does not allow a formal reference parameter of type STRING or LSTRING to be assigned to, or compared with, another string variable. Pascal/VS has no such restriction. Pascal/VS allows varying-length string variables to be up to 32767 characters in length; in PC Pascal, the limit is 255 characters. (EDITOR'S NOTE: At this point the reader is directed to the following footnote: ...The first release of Pascal/VS had a 255 character limit on string, but many customers complained that the limit was too small for many of their applications. As a result, the second release moved the limit up to 32767...) ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Sets ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Both compilers have similar restrictions on the use of set variables. "Set of CHAR" is supported by each compiler. Sets with negative members are not allowed. The ordinal value of the largest member of a set is 255. The two compilers map set variables differently. In Pascal/VS a variable declared as set of `A'..`Z' will occupy 32 bytes (256 bits). Such a variable in PC Pascal would occupy the least number of words needed to contain the largest member "Z" (in ASCII), which would be 12 bytes (96 bits). In short, Pascal/VS allocates as many bytes as necessary to hold all members of the fundamental base type, that is, the type from which the base subrange was derived (In the example above, the fundamental base type is CHAR.) Pascal/VS maps packed sets more compactly. For example, a variable declared as packed setof 0..7 will occupy 1 byte (8 bits). Pascal/VS supports sets that are one byte in length (as shown in the last example.) In contrast, PC Pascal requires all sets to occupy an even number of bytes, thus the smallest set size is 2 bytes. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Variable Attributes ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Both compilers support static-internal and static-external variables. Pascal/VS has added three new reserved words to the language: static, def, and ref. These words are used in the similar context as var to declare variables. "Static" specifies that the following variable declarations are static-internal. "Def" specifies that the variables are to become names of COMMON sections. "Ref" specifies that the variables are external references. static (*internal*) varid1 : typedef1; varid2 : typedef2; ... def (*Named common*) varid1 : typedef1; varid2 : typedef2; ... ref (*External static*) varid1 : typedef1; varid2 : typedef2; ... In PC Pascal, variable declarations may be qualified with an attribute description enclosed in square brackets. This descriptor designates the storage class of the variable. var[PUBLIC] (*publicly assessable variable*) varid1 : typedef; var[EXTERN] (*external reference*) varid1 : typedef; var[STATIC] (*static internal*) varid1 : typedef; Pascal/VS provides a way to share non-static variables across compilational units in order to provide reentrancy. Variables declared with the var construct in the outermost level of the module will be mapped directly on top of the variables which are declared local to the main program. In effect, the variables which were allocated for the main program are accessible from all modules. In the following example, the variables A and R will be shared across the two modules at execution time (assuming the two are link-edited together). (*main program*) (auxiliary module*) program ABC; segment XYZ; var A: Integer; var A: Integer; R: Real; R: Real; begin ... end. This approach has the problem of being very insecure. If the variables declared in the outer level of a module do not match in type, number, and order to those in the main program, the results will be unpredictable. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ File Name: ÛÛ pas1.txt ÛÛ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ