APM Pascal

Preamble

APM Pascal Compiler -- Version 1

The Pascal compiler translates programs written in the high-level language Pascal to M68000 native code.

The operation of the compiler is very similar to that of the IMP compiler; for example, the options are almost identical.

ALERT information

Input/output is temporarily restricted to text files, (the TYPE of file variables must be TEXT, not FILE OF CHAR).

Apart from the predefined files INPUT and OUTPUT, up to three input and three output files may be in use simultaneously.

To read a file you have written (within the same program), the file must be opened for input (using RESET), after the output file has been closed. Files can only be closed by re-using their file variables. It is, however, permissible (even recommended), to use the same file variable both for output and input, for example:

rewrite(filevariable,"filename"); write(filevariable,......);
reset(filevariable,"filename"); read(filevariable,......);

Calling the compiler

Example commands:

 PASCAL MYPROG                  Compile MYPROG with default options
                                producing object file MYPROG.MOB

 PASCAL PARSER-LIST             Compile PARSER producing object file PARSER.MOB 
                                and listing file PARSER.LIS

 PASCAL NEW.PAS-NOCHECK-NODIAG  Compile NEW.PAS to NEW.MOB
                                without checks and diagnostic hooks

 PASCAL PROG2-NOEDIT            Compile PROG2 to PROG2.MOB
                                without calling the editor to correct faults
                                detected in the program

Parameters

There is only one obligatory parameter for the PASCAL command and that is the name of the Pascal source program to be compiled. There is no default file-name extension for the source file-name. As a matter of personal preference, programmers may or may not choose to adopt the extension .PAS for Pascal programs.

There are two output files which may be generated by the Compiler: the object file containing the compiled code and the listing file. By default, the names for these files are derived from the source file-name. The default names may be overridden by specifying alternative names, either positionally or by keyword. For example, the generation of an object file may be suppressed in either of the following forms:

PASCAL PROG2/:N or..
PASCAL PROG2-OFILE=:N

Similarly a listing could be directed to a designated file by:

PASCAL MYPROG/,PUB:TEMP {note the comma, or..
PASCAL MYPROG-LFILE=PUB:TEMP

Object file

By default, the Compiler generates an object file provided that no errors are detected during compilation.

If no name is provided explicitly, the name is derived from the source file-name (without the extension .PAS if present). The extension .MOB (for Motorola executable) is applied to the object file-name.

The compiled code file is eligible for execution by citing the name (without extension) as a command verb at APM command level. There is no linking stage after compilation; the object file is immediately executable.

For example:

} PASCAL MYPROG
MYPROG compiled: 115 statements (+ 38 comments) to 1220 bytes (+ 24)
} MYPROG

Object file control

     -OFILE=<filename>  produce object file with specified name
                        (the extension .MOB is added unless present already)

     -OFILE=:N          do not produce object file

     -FORCE             produce object file even if program faulty

Listing file

By default the Compiler does not produce a listing. If one is required, it is requested either by including the keyword -LIST in the command or by specifying a file-name as the second output parameter or as the value for the keyword -LFILE.

If no name is provided explicitly, the name is derived from the source file-name (without the extension .PAS if present). The extension .LIS is applied to the listing file-name.

The listing file consists of the text of the source file with added line numbers, and any fault or warning messages produced during compilation. Line numbering runs from 1 at the start of the file and includes blank lines and comment lines. Lines in included files are numbered independently, with an ampersand as an indicator.

Listing control

     -LIST              produce source file listing

     -LFILE=<filename>  send listing to specified file
                        (the extension .LIS is added unless already present)

     -TT                send listing to terminal

     -MAP               output information at end of each procedure, indicating
                        size of code, etc.

     -LOG               print statistics at end of compilation indicating number
                        of statements, atoms per statement, identifiers per
                        statement, time taken, etc.

{The following may not be available in the standard release}

     -CODE              print hybrid assembly language interpretation of code
                        generated for each statement.  This is before address
                        fix-up and branch shortening, and so does not fully
                        reflect the final code

     -DICT              print dictionary entries for identifiers

Options

Run-time checks:

To disable any individual check, use the indicated keyword prefixed by NO, for example -NOSTRASS

     -ASS               include unassigned check on full integers

     -STRASS            include unassigned check on strings

     -SASS              include unassigned check on 16-bit values

     -BASS              include unassigned check on 8-bit values

Defaults: -ASS -STRASS -NOSASS -NOBASS

The unassigned check is implemented by standardising all newly declared dynamic variables to a fixed pattern which is an improbable integer value. The check is defaulted off for variables occupying less than 32 bits because there is a greater possibility of the special pattern occurring as a genuine value.

Note that almost all examples of the violations listed below which involve only literal operands are detected and rejected at compile-time rather than run-time.

     -ARR               include array bound checking

     -OVER              include overflow check on addition/subtraction

     -CAP               include capacity checking on assignment

     -STACK             include stack over-run check

Defaults: -ARR -CAP -STACK

     -NOCHECK           suppress all checks apart from stack over-run

     -NOCHECK-NOSTACK   suppress all checks

Run-time diagnostic control:

     -LINE              include line-number updating for diagnostics

     -TRACE             generate code which allows the program to be executed
                        one line at a time under the control of the Software
                        Front Panel

Default: -LINE -NOTRACE

Compiler limits:

     -IDENTS=n          allow for n user idents (default 1000)

     -KBYTES=n          allow for codesize nK (default 64k, max 128k)

Compile-time control:

     -NONS              enable warning-free use of non-standard features

     -STRICT            exclude use of non-standard features

     -LOW               enable use of low-level features

     -VOL               assume functions are volatile

     -WARN              request soft warnings

     -EDIT              automatically transfer control to the standard editor
                        (VECCE) on detection of an error in the program.
                        Compilation resumes when the edit is closed (just hit
                        CPY if you do not want to correct the error at this
                        stage).

Default: -NONONS -NOSTRICT -NOLOW -VOL -WARN -EDIT

Language facilities

The language implemented is as defined in the British Standard Specification BS 6192:1982

"Computer programming language Pascal"

with the exceptions noted below. The Standard is also printed as an Appendix to Wilson and Addyman's

"A Practical Introduction to Pascal" (2nd edition).

A number of extensions are implemented, as far as possible following the pattern of the Vax/VMS Pascal extensions, though not necessarily the full detail of that implementation. Varying strings may alternatively be declared in the (rather neater) UCSD p-system style.

None of the extensions invalidates correct standard Pascal programs. They are excluded if the compiler option -STRICT is asserted, and they are flagged as 'Nonstandard' unless the option -NONS is asserted.

Data types

Integer      MAXINT is 2147483647 (2^31 - 1) and integers may lie in the
             range -MAXINT-1 to MAXINT

Real         Reals are limited to single-precision (32-bits) and the
             implementation is by software

Boolean      standard

enumerated   The maximum number of elements in an enumerated type is bounded
             by the number of identifiers which may be declared.

Char         The ordinal values of the type Char lie in the range 0 to 255.
             [comment: the construction SET OF Char would be more efficient
              if the upper-bound were 127 -- vote now]

ARRAY        standard, including conformant array parameters
             and PACKED ARRAY [1..?] OF Char for fixed length strings


RECORD       standard

SET          Sets may contain up to 256 elements.
             Sets whose base-type is Integer or a subrange of Integer
             can contain only integers in the range 0 to 255.

FILE         Variables of type FILE may not be elements of structures

POINTER      standard

String       variable length string (see Extensions)

Input

For text files, the standard input procedure READ (or READLN) is applicable to the following types:

Integer      standard, leading spaces and line-breaks being ignored

Real         standard, leading spaces and line-breaks being ignored;
             'E' or 'e' is valid to indicate exponent

Char         standard

String       FIXED:   characters are read until the string is filled or a
              line-break is reached, the remainder being padded with spaces.
             VARYING: characters are read up to line-break.
             Leading spaces and line-breaks are not ignored.
             The line-break is not read (unless READLN is used).

enumerated   An identifier is read, ignoring leading spaces and line-breaks;
             the identifier must be one of the constant identifiers for the
             relevant type (in either upper- or lower-case).

Opening input files

The standard procedure RESET may be used to open a file, with a second parameter specifying the file name as a (varying) string, for example:

RESET(MAINFILE,'CASE4.DAT')

Provisionally, for limited compatibilty with Vax/VMS, the form without a second parameter may be used on a file variable declared in the program parameter list. In this case, the name of the variable is used as the file name (without extension). So the form:
RESET(MAINFILE) with mainfile a program parameter

would be equivalent to:

RESET(MAINFILE,'MAINFILE')

Note that this must be a direct use of the file variable, not an indirect one, say as a VAR parameter.

Output

For text files, the standard procedure WRITE (or WRITELN) is applicable to the following types. In all cases, a default field-width of 1 is applied.

Integer        standard

Real           standard; 'E' is used to indicate any exponent.

Char           standard

String         FIXED:   the characters of the string are printed.
               VARYING:             ditto

enumerated     the associated constant identifier is printed, in lower-case.

Opening output files

The standard procedure REWRITE may be used with a second parameter of type (varying) string to open an explicitly designed file, for example:

REWRITE(RESULTS,'PUB:DUMP.LIS')

As with RESET, for limited compatibilty with Vax/VMS, the form without a second parameter may be used on a file variable declared in the program parameter list. In this case, the name of the variable is used as the file name (without extension). Note that this must be a direct use of the file variable, not an indirect one, say as a VAR parameter.

Restrictions

. The forms of NEW and DISPOSE with specified variant(s) are not distinguished
from the forms without. Consequently the various errors which can arise
with these forms are not detected (and equally, do no harm)

. The procedures PACK and UNPACK are not available
[The keyword PACKED is largely ignored except for type matching]

. File variables are not permitted as members of structures, nor as the
domain variable of a pointer

. Procedures and functions passed as parameters must be in scope to the
procedure to which they are passed

. Value conformant arrays are not implemented

Extensions

{The numbers are those cited in the compiler's Nonstandard reports}

1. The predefined types include varying length strings.

2. The LABEL, CONST, TYPE and VAR sections may appear in any order
and may be repeated.

3. An initial (literal) value may be specified for variables.

4. The attributes STATIC, VOLATILE, READONLY, WRITEONLY, and
@(address) may be applied to variables.

5. A literal (constant) expression is permitted wherever a constant
may appear. {This leads to a syntactic ambiguity in the case of
the declaration of enumerated types versus subranges: hence, in
this context, a subrange is not allowed to start with a left
parenthesis}

6. A record type identifier may be used as a constructor;
an ordinal type identifier may be used to cause type transfer from
Integer (hence Boolean(0) = false, for example).

7. Functions may return results of structured type (except FILE)

8. The statement EXIT may be used to exit from a loop structure

9. The statement RETURN may be used to exit from a procedure or function

10. A case statement in which not all values of the selector expression
appear as labels may have a default statement at the end in the form:
OTHERWISE <statement> or alternatively ELSE <statement>

11. Non-decimal numerals may be represented in the form <radix>_<digits>
(for example 2_101010 or 16_7FFF).

. the sub character ('_') is permitted within identifiers

. The prevailing Options may be varied during compilation by
means of the %OPTION directive.

. Other source files may be included in the file being compiled
by means of the %INCLUDE directive.

. The special function ADDR(var) is implemented

%OPTION

Compiler options may be switched off and on by means of the directive

                       %OPTION '....'
         for example   %OPTION '-NOWARN-NOLIST'

The quoted string must consist of a sequence of Option keywords each preceded by a dash (hyphen).

Note that the %OPTION directive does not require a terminating semi-colon.

Caution: indiscriminate variation of checking options within a
program can create considerable confusion for debugging.

The effect of options is localised to the current procedure or block.

%INCLUDE

Other files may be included in the source by means of the directive

                       %INCLUDE '....'
         for example   %INCLUDE 'GRAPHICS.PAS-NOCHECK'

The quoted string specifies the name of the file together with any Options to be applied to it. These Options, and any which are specified within the included file itself, are localised to this file.

Note that the %INCLUDE directive does not require a terminating semi-colon.

See the example program under Libraries.

Varying length strings

Varying length strings may be declared using the special type identifier STRING followed in square brackets by the maximum length of the string. Alternatively, the Vax/VMS form may be used: VARYING [maxlength] OF Char. The two forms are equivalent. The maximum length must be a literal and the upper limit is 255.

Equivalent examples of the two forms are:

VAR s1,s2: STRING

[120];
VAR s1,s2: VARYING

[120] OF Char;

The following are assignment compatible with varying strings:

varying strings
quoted strings
single characters

Note that fixed length strings (that is, PACKED ARRAYs of Char) are not assignment compatible with varying strings, nor conversely.

Array indexing may be used to access individual elements of strings, which are of type Char. The operator '+' may be used for concatenation.

Attributes

One or more of a group of special attributes may be specified in the declaration of identifiers. The attributes which may be specified are:

   STATIC             storage for the variable is to be pre-allocated
                      rather than being allocated dynamically.

   VOLATILE           main use is as an attribute for the result type of a
                      function indicating that the function is not a pure
                      function of its arguments.  This prevents optimisation
                      of repeated calls.

   READONLY          [not currently used]
   WRITEONLY   /

   @<machine-address> the variable is to identify the explicitly
                      given storage location (Low-level facility).

The names are given, separated by commas, in square brackets between the colon and the type specification in the declaration of variables. For example:

VAR i,j,k: [STATIC] Integer;

FUNCTION random: [VOLATILE] Real;

VAR devstatus: [@16_4466AA] Byteinteger;

Variable initialisation

Any variable may have an initial value specified at the point of declaration. This is particularly useful for STATIC variables.

The initialisation is indicated by including an assignment at the end of the declaration, for example:

        VAR first: [STATIC] Boolean := true;
              p,r: Integer := 999;

If there is more than one variable in the variable-part, the initial value applies only to the last.

Record initialisation

A record type identifier may be used as a constructor for that record type, from components values specified in parentheses following the record type identifier. At present only literal component values are permitted. This form is particularly useful for specifying initial values for records, but it is not restricted to that context.

The component values may be presented either positionally or using the record component names, preceded by a dot, as keywords.

Examples of use of record constructors

TYPE f1 = RECORD
            lo,hi:Integer;
            code:String[7];
            now:Boolean;
            weight:0..999
          END;

VAR  r1 : [STATIC] f1 := f1(-100,100,'factor',false,1);
  By complete enumeration

     r2 : [STATIC] f1 := f1(0,,'dummy');
  By enumeration, any omitted values unassigned

     r3 : [STATIC] f1 := f1(.code='undef',.weight=999);
     r4 : [STATIC] f1 := f1(.hi=99999,.code='max');
  By selection using field names, any omitted values unassigned
   field names must appear in order of occurrence in declaration

EXIT and RETURN

These statements allow for the dynamic termination of loops and procedures respectively other than at the textual end. Syntactically, they are imperative statements.

When the RETURN statement is used in a function, it must be followed by an expression for the result of the function, and if this form is used anywhere within a function, the standard method of specifying a function result, viz asignment to the function name, may not be used.

Library Procedures

The full complement of standard functions is available, viz:

ABS, ARCTAN, CHR, COS, EOF, EOLN, EXP, ODD, ORD,
PRED, ROUND, SIN, SQR, SQRT, SUCC, and TRUNC.

The procedures PACK and UNPACK are not available; otherwise all the standard procedures are available, viz:

DISPOSE, GET, NEW, PAGE, PUT, READ, READLN, RESET, REWRITE,
WRITE, and WRITELN.

Pre-declared procedures

There are a number of additional functions and procedures which are pre-declared:

    REM(i,j)      : the remainder when I is divided by J
    FLOAT(i)      : I explicitly floated
    CPUTIME       : cpu time in milliseconds since process start
    LENGTH(s)     : length of string S
    CLIPARAM      : parameters typed in with command, as string
    PROMPT(s)     : establish S as prompt string
    HALT          : terminate program

Libraries

There are a number of libraries available on the system which provide groups of related procedures for use in writing programs. In order to make use of these, it is necessary to include the necessary declarations in the source program. Also, when running the program, it may be necessary to INSTALL the related object file (see the general system information on Libraries).

Short files containing the relevant declarations for the main system libraries are available for general use in the directory INC. These files may be 'included' in Pascal programs by means of the %INCLUDE statement, for example,
INCLUDE 'INC:UTIL.PAS'.

Library interface files currently available are:

INC:UTIL.PAS -- sundry utility procedures

[others under preparation]

Example of use of UTIL
{Simple file copy program}

        program copy(output,infile,outfile);
        %include 'inc:util.pas'
        var infile,outfile:text;
            inname,outname:string[255];
            ch:char;
        begin
          DefineParam('Input file:',inname,PamNodefault);
          DefineParam('Output file:',outname,PamNewGroup+PamNoDefault);
          ProcessParameters(cliparam);
          writeln('Copying ',inname,' to ',outname);
          reset(infile,inname);       open input file
          rewrite(outfile,outname);   open output file
          while not eof(infile) do begin
            while not eoln(infile) do begin
              read(infile,ch); write(outfile,ch);
            end;
            readln(infile); writeln(outfile);
          end;
        end.

External linkage

The pre-prepared libraries make use of the general external linkage mechanism implemented for APM Pascal. The linkage process, which occurs when a program is run, involves matching up REFERENCES in one program with DEFINITIONS in another.

External References

A procedure or function header may be followed by the directive EXTERN or EXTERNAL, instead of a procedure body. For example:

PROCEDURE diagnose(i,j:Integer; VAR flag:Boolean); EXTERN;

This indicates an external reference, the actual procedure existing in another module. Such dummy procedure headings must appear in the main program block, or before it, not within a contained block.

External Definitions
The actual procedures corresponding to external references may themselves be written in Pascal, or another language. To define such procedures in APM Pascal, it is necessary to place them at the start of the source program file, that is, before the PROGRAM header, and attach the directive GLOBAL to the header. For example, the form of a procedure which would correspond to the example above would be:

PROCEDURE diagnose(i,j:Integer; VAR flag:Boolean); GLOBAL;
....
....
END

In fact, in a source file containing external procedure definitions, the main PROGRAM block is optional.

Cross-calling

In general, data formats and the mechanisms for passing parameters and function results are completely compatible between Pascal and IMP. This applies to full integers, reals, varying strings, records, and arrays.

Pascal VAR parameters are compatible with IMP %name parameters.

Pascal Boolean functions are compatible with IMP predicates.

The Pascal Char is storage compatible with the IMP %byte.

Integer subrange correspondence is as follows:

           Pascal                          IMP

       -32768..32767                     %short
            0..65535                     %half
         -128..127                       %mite
            0..255                       %byte

Compiler Error Reports

Error reports are kept short to economise on screen space. For reports which relate to a particular component of a statement, the culprit is identified by a marker at the start of the component.

 REPORT                     MEANING

Faulty form         statement part indicated is syntactically faulty
; missing           syntax fault probably caused by omission of semi-colon
Unknown atom        lexical atom indicated is mis-spelt or unknown
Non-starter         atom at the start of the statement is not a
                      possible statement introducer
Unknown name        identifier indicated has not been declared
Duplicate           identifier indicated has already been declared
Not variable        operand in assignment context is not a variable
Not reference       operand for VAR parameter is not a reference
Wrong type          expression is of wrong type for context
Wrong class         category of identifier is wrong for context
Not literal         expression in literal context is not literal
Inside out          upper bound is less than lower
Out of range        operand value is out of range
Too few args        too few arguments are given for procedure call
Too many args       too many arguments are given for procedure call
RESULT missing      there is no assignment to the function name
Not accessible   W  instruction apparently cannot be executed
Dubious usage    W  expression, though valid, is implausible
Out of order     W? statement appears in incorrect order in block
Low level        W  low-level language feature
Nonstandard <n>  W* non-standard language feature (once only per case)
<ident> void     W  identifier is used before a value is assigned to it
<.....> missing     label or forward identifier does not appear in block
Faulty operand      incorrect operand type for machine instruction
Wrong size          operand is of incorrect size for machine instruction

       W: warning report only
      W*: hard error if -STRICT, otherwise warning
      W?: warning in benign cases; hard error otherwise

Too complex!            compiler limitation exceeded
Out of reach!           %const or literal string, record or array is not
                        within the range of the machine addressing capability
<ident> Out of reach!   call to procedure specified is not within the
                        range of the machine addressing capability
Internal error <n>!     compiler fault


Disastrous errors

These reports relate to compiler limits being exceeded.  They all cause
compilation to be abandoned.

** Program too big             total size of the compiled code and constants
                               exceeds the maximum allowed for
** Code space exhausted        size of the code for currently open blocks
                               exceeds the maximum allowed for
** Identifiers too big         total length of all identifiers currently
                               in scope exceeds the maximum permitted
** Too many identifiers        number of identifiers currently in scope
                               exceeds the maximum permitted
** Too many levels             depth of textual nesting of blocks exceeds
                               the maximum permitted
** Too many owns               space required for static variable
                               initialisation exceeds the maximum permitted
** Too many literals           internal storage space for literals is exhausted
** Input ended                 there is no END. statement
** Too many nested includes    there are more than three levels of nesting

Compiler limits

The following limits apply:

. The maximum depth of textual nesting is 8, including the outer level.

. The size of the storage area for program, constants and owns is limited
to 68k bytes.

. In programs which exceed 32k bytes in size, the compiler uses a number
of techniques to avoid within-program references breaching the M68000
PC-relative address limit of +-32k. There is a possibility that some
cases are not caught, leading to an 'out-of-reach' report.
If a name is given in the report, it is that of a procedure which is
too distant from one of the calls on it.
If no name is given, the problem is access to a constant.

Run-time diagnostics

Errors detected at run-time are reported through the system's exception signalling mechanism (also used for IMP 'events'). If an exception is not trapped, the occurrence of the exception is reported in the form of an error code and text message. In general, the line number at which the failure occurred is provided, but full monitoring of program variables is not at present provided.

For most errors, detection at run-time depends on whether particular checking options were selected at compile-time. The availability of a relevant line number depends on having compiled with the option -LINE. The default compile-time options include line numbering and most checks, but not unassigned checks on variables occupying less than 32 bits nor overflow checks for integer addition or subtraction.

Run-time errors

         ERROR                            CODE          REQUISITE
                                                         OPTION
Variable value undefined (unassigned)      8 1            -ASS, -BASS, etc
  [sometimes detected as "Void" at compile-time]

Function result undefined                  8 1            -ASS, -BASS, etc
  [sometimes detected as "No result" at compile-time]

Array index out of range                   6 2 <culprit>  -ARR

Integer arithmetic overflow                1 1            -OVER
Real arithmetic overflow                   1 2            -OVER
Division by zero (integer or real)         1 4            none
Second argument for MOD <= 0               1 4            none
Trig function error                       10              none

TRUNC result outside integer range         ?              none
ROUND result outside integer range         ?              none
CHR result outside CHAR range              6 1            -CAP
SUCC result outside range                  6 1 or 1 1     -CAP or -OVER
PRED result outside range                  6 1 or 1 1     -CAP or -OVER

Assignment value out-of-range              6 1            -CAP
Value parameter out-of-range               6 1            -CAP

Member of set out-of-range                 not detected

Case selector value not catered for        falls through
    [warning issued at compile-time]

Record variant abuse                       not detected

Pointer variable NIL                       8 1            -ASS
Pointer variable undefined                 8 1            -ASS
Pointer variable used after disposal       not detected

File variable undefined for PUT, GET,      8 1            none
    WRITE(LN), PAGE, READ(LN), EOLN, EOF
File variable undefined for RESET          8 1            none

EOF true for GET, READ(LN), or EOLN        9              none

Non-numeric character for numeric READ     4 1 <culprit>

Value out-of-range for READ or WRITE       6 1            -CAP

Buffer variable undefined for PUT          not detected

File altered while reference to the        not detected
  associated buffer variable exists

File not in Generation mode for PUT,       3 2            none
    WRITE(LN), PAGE

File not in Inspection mode for GET,       3 2            none
    READ(LN), or EOLN

Field width for WRITE(LN) less than 1      not detected

Efficiency

. In the absence of floating-point hardware, all floating-point
operations are performed by software.

. Integer multiply and divide are also performed by software, although
a number of special cases are optimised.

. Sets are more efficient when the cardinality of the canonical base type
is small (as typically with enumerated types). The specification of
sets in terms of subranges does NOT improve the efficiency of either
computation or representation.

. Full checking is expensive in both time and space. Developed programs
should be compiled with checks and diagnostics disabled.
Fullest optimisation is obtained by specifying:

-NOCHECK-NODIAG-NOSTACK-NOVOL

. Procedure and function calls are implemented with a minimum of overhead
so that they may be freely used without significant penalty in all but
the most time-critical contexts. The space-saving from making full use
of procedures and functions can be substantial.

Porting programs from VMS

The following notes may be helpful to those porting programs from Vax/VMS to the APM. They relate to the Vax-11 Pascal compiler V2.0.

The APM implementation includes a number of the Vax-11 extensions, but by no means all. It may be useful before porting a program to compile it on Vax with the /STANDARD qualifier to establish the extent of its reliance on non-standard features of the language.

Both compilers accept case statements in which not all values of the selector are catered for, either explicitly or by means of the catch-all OTHERWISE clause (a common extension). In both implementations the effect at run-time is a null action. The APM compiler, however, produces a compile-time warning.

In the variable initialisation extension, for example:

VAR i,j,k: [STATIC] integer := 999;

the Vax implementation treats the initial value as applying to all variables in the declaration group, while the APM compiler treats it as applying to the last only.

In the OTHERWISE extension, Vax defines what follows the OTHERWISE to be a statement sequence, APM a single statement (which may, of course, be a BEGIN/END block).

The Vax NEW procedure returns zeroed storage; the APM NEW procedure does not.

In general, the Vax implementation is a fairly permissive one. The following are known cases which are allowed on Vax but not on the APM:

use of non-local variable to control for-loop

omission of some values of tag type in record variant part

testing for EOLN when EOF is true

[Vax V1.0 coonsidered EOLN to be true when EOF was true; V2.0 considers
EOLN to be false when EOF is true "to conform to the ISO standard,
which prohibits a program from testing for EOLN at end-of-file"]

view:pascal printed on 17/02/89 at 12.40

APM Manual pages