July 15, 1984 ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» º A Comparison of PC Pascal and Pascal/VS º º º º by º º º º J. David Pickens º ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ EDITOR'S NOTE: The first part of this article appeared in the previous issue of PCFL/PCUG. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Compile-time Initialization ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ To initialize static variables at compile-time, both implementations have added a "value section" to the language. The syntax and semantics of the value section is identical in both compilers. The value section consists of the word "value" followed by a sequence of assignment statements. The left side of each assignment statement must be a variable whose address is known at compile-time. The right-side of the assignment must be a constant expression, including structured constants. type Complex = record RE, IM: Real end; var[STATIC] Q: Complex; A: array[1..3] of Integer; value Q := Complex(3.0,4.0); A[1] := 1; A[2] := 512-1; A[3] := 0; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Loop control ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Both PC Pascal and Pascal/VS have extended the language with statements which alter control flow. Pascal/VS has introduced the "leave," "continue," and "return" statements. Leave is a goto to the first statement following an enclosing loop statement. Continue is a goto to an implied empty statement ending the body of an enclosing loop statement. Thus, both leave and continue may appear only in a loop statement. The "return" statement is a goto to an implied empty statement following the last statement in the current procedure or function, or the body of a main program-module. PC Pascal supports the return statement as in Pascal/VS. PC Pascal also has similar loop control statements but with different names. The cycle statement performs the same function as the continue statement in Pascal/VS; likewise, the break statement performs the same function as the leave statement in Pascal/VS. In Pascal/VS, the leave and continue statements apply only to the most nested enclosing loop statement. PC Pascal permits the cycle or break statement to be followed by a loop label which identifies the applicable loop statement. For example: begin LOOP1: while A<>B do begin for I := 1 to 100 do begin ... break LOOP1; ... end; ... end; (*control resumes here after break is executed*) end; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Separate Compilation ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Both implementations permit programs to exist in multiple compilational units. In PC Pascal, such units are called modules; in Pascal/VS they are called segments. (*A PC Pascal module*) (*A Pascal/VS segment*) module ABC; segment ABC; var X,Y: REAL; static X,Y: REAL; procedure XYZ; procedure XYZ; begin begin end; end; ... ... .(*end of ABC*) .(*end of ABC*) PC Pascal also supports a feature called a unit. A unit is a set of related data types, variables, constants, procedures, and functions, plus an initialization procedure. It has two parts, the interface and the implementation. The interface contains a list of identifiers to export and their declarations (including procedure and function headers). The implementation contains any local declarations, procedure and function bodies, and the initialization code. interface; unit GRAPHICS (MOVE, UP, DOWN, COORDINATES); type COORDINATES = 0..512; procedure MOVE(X,Y: COORDINATES); procedure UP; procedure DOWN; begin end; implementation of GRAPHICS; procedure MOVE; begin (*code for MOVE*) end; procedure UP; begin (*code for UP*) end; procedure DOWN; begin (*code for DOWN*) end; begin (*initialization code goes here*) end; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Procedure/Function Attributes ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Both PC Pascal and Pascal/VS allow a procedure or function in one module to be made accessible from another. In PC Pascal, a procedure may be declared with the "PUBLIC" attribute, which indicates that the procedure may be called from other modules. procedure XYZ(A,B: INTEGER) [PUBLIC]; begin ... end; To declare a procedure which is defined in another module, the EXTERNAL directive is used: procedure XYZ(A,B: INTEGER); EXTERNAL; In Pascal/VS, the EXTERNAL directive has a slightly different interpretation. A procedure declared with the EXTERNAL directive indicates one of the following: 1. The code of the procedure resides in another module; 2. The code of the procedure follows in the current module and is to be marked as an external entry point (local definition). In the following example, procedure XYZ resides in segment SEG1 and is callable from SEG2: segment SEG1 procedure XYZ(A,B: INTEGER); EXTERNAL; ... procedure XYZ; begin (*body of XYZ*) ... end; (*end of SEG1*) segment SEG2 procedure XYZ(A,B: INTEGER); EXTERNAL; ... . (*end of SEG2*) ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Arithmetic ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ PC Pascal and Pascal/VS permit bit-wise logical operations on integers. This includes "and"ing, "or"ing, exclusive "or"ing, and complementing. For example, 10 and 3 yields 2 not 0 yields -1 8 or 15 yields 15 In addition, Pascal/VS provides shifting operators 256 >> 1 yields 128 1 << 3 yields 8 (EDITOR'S NOTE: Shades of C.) ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Input/Output ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Interactive I/O ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ The lack of interactive I/O has been a well known problem in standard Pascal. According to the standard, immediately after a file is opened for input (using RESET), the file pointer must reference the first byte of the file. This implies that the first record of the file is read implicitly when the file is opened. In addition, after each READ operation, the file pointer must reference the following byte of the file; thus, Pascal I/O is always one record ahead. These requirements make interactive I/O impractical in standard Pascal. Pascal/VS and PC Pascal have each solved the problem of interactive I/O differently. Pascal/VS has adopted an optional attribute string to the RESET procedure. One of the attributes that may be specified in this string is "INTERACTIVE," which specifies that no reading ahead is to be performed. PC Pascal has solved the problem without extending the language or violating the standard. An internal mechanism is used called "lazy evaluation." Lazy evaluation occurs only when reading from a text file. The file's buffer variable has a special status value which can be "full" or "empty." When a file's buffer variable is accessed, if its status is "empty," the next file component is physically input; after an access the status is always "full". When a GET operation is performed, if the file status is "empty," the next file component is physically input; after a call to GET, the status is always "empty." Lazy evaluation effectively defers physical input until actually needed by a buffer variable access. In the following example, the physical input of the first record of the file will not occur until statement (2) is executed. var F: Text: C: Char; begin (1) Reset(F); (2) C := F@ end; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ I/O Error Detection ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ In Pascal/VS, there is no easy way to retrieve the status of an I/O operation to see if it was completed successfully. For example, when a file is opened for input, it is difficult to find out if the file actually exists. (When such errors occur, Pascal/VS produces a run-time diagnostic). PC Pascal permits a program to directly access the fields of a file variable's file control block (FCB). One of the fields of the FCB is a TRAP field which, when set to TRUE, suppresses run-time error diagnostics when an error occurs. By examining the error-code field of the FCB, the status of the last I/O operation can be determined. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Relative Record I/O ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Both implementations support relative record-access by means of the SEEK procedure. var F: file of record ... end; begin RESET(F); ... SEEK(F,N); (*Position file to record N*) GET(F); (*Get the Nth record*) end; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Error Interception ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Pascal/VS provides a mechanism for intercepting run-time errors (such as subscript errors, overflow, etc.). When a run-time error is detected, a public Pascal procedure called ONERROR is invoked. The following parameters are passed to the procedure: 1. Number corresponding to the error that occurred; 2. The name of the procedure in which the error occurred; 3. The statement number; 4. A set of flags, passed by reference, to indicate what action the system is to take. By writing a public procedure called ONERROR, a user can intercept errors as they occur. In practice, however, this mechanism is difficult to use for the casual programmer and not powerful enough for the more advanced programmer. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Other Extensions ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Both implementations support an "otherwise" clause on the "case" statement. In addition, ranges may be specified for case-statement values. Both allow functions to return structured types (sets, arrays, records). Pascal/VS provides an assert statement to cause a run-time error to occur if a condition is not true. Both allow alphanumeric identifiers to be statement labels. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Compiler Directives ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ PC Pascal supports a set of "meta-language" commands. These commands provide control over generating error-checking codes, listing format controls, a construct for conditional compilations, and a mechanism for inserting source files into a compilation. The meta-language commands always appear within Pascal comments, so source files which contain them do not lose their portability. In Pascal/VS, compiler directives are specified with a percent sign ("%") followed by the directive name. The directives are NOT allowed in comments, thus Pascal/VS programs which contain compiler directives are not portable. The Pascal/VS directives have functions similar to the PC Pascal meta-language, except, that there is no conditional compilation facility. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ Language Restrictions ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ In Pascal/VS, only the first 16 characters of an identifier are significant. Names which are to appear in an external-symbol dictionary (i.e. public procedures) are significant only in the first 8 characters. (Unfortunately, the compiler does not diagnose conflicts if two external symbols are not unique in the first 8 characters!) In contrast, PC Pascal treats the first 31 characters of an identifier as significant, even for public names. In both implementations, "set" variables may not be declared with more than 256 members. The ordinal value of a set member must lie within the range 0 to 255. Pascal/VS will not compile a procedure which generates more than 8192 bytes of code. PC Pascal has no such limit. In PC Pascal, the size of the representation of structured constants may not exceed 255 bytes. Pascal/VS has no such restriction. Unlike PC Pascal, Pascal/VS does not allow procedures to be nested to a depth greater than 7. ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ File Name: ÛÛ pas1.txt ÛÛ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ