\documentstyle[a4,12pt]{article}
\begin{document}
\author{APM Manual pages}
\title{APM IMP Compiler  --  Version 2}
\maketitle
\parskip .1 in
\setcounter{secnumdepth}{10}
\parindent 0in

\section{Preamble}
The IMP compiler translates programs written in the high-level language IMP to
M68000 native code.

The operation of the compiler is very similar to the APM Pascal compiler -- for
example, the available options are identical.

\section{ALERT information}

{\hspace*{0.3 in}} . This information relates to the Version 2 Compiler {\hspace{0.2 in}} ("NIMP")
\\ {\hspace*{0.5 in}} Modules compiled with this compiler are incompatible with
\\ {\hspace*{0.5 in}} (ie cannot be linked with) modules compiled by the V1 compiler.

{\hspace*{0.3 in}} . The checking of unassigned variables and nil references is not
\\ {\hspace*{0.5 in}} 100 per cent.




\section{Calling the compiler}

{\hspace*{1.7 in}} Example commands

\small\tt \begin{verbatim} IMP MYPROG                  Compile MYPROG with default options
                                  producing object file MYPROG.MOB

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

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

 IMP PROG2-NOEDIT            Compile PROG2 to PROG2.MOB
                                  without calling the editor to correct faults
                                  detected in the program
\end{verbatim}\rm  \normalsize 
\subsection{Parameters}

There is only one obligatory parameter for the IMP command and that is the name
of the IMP 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 .IMP for IMP 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:

{\hspace*{0.7 in}} IMP PROG2/:N
\\ {\hspace*{0.3 in}} or {\hspace{0.3 in}} IMP PROG2-OFILE=:N

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

{\hspace*{0.7 in}} IMP MYPROG/,PUB:TEMP {\hspace{0.6 in}} \{note the comma
\\ {\hspace*{0.3 in}} or {\hspace{0.3 in}} IMP MYPROG-LFILE=PUB:TEMP

\subsection{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 .IMP if present). The extension .MOB (for Motorola
object) 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:

{\hspace*{0.3 in}} \} IMP MYPROG
\\ {\hspace*{0.3 in}} MYPROG compiled: 115 statements (+ 38 comments) to 1220 bytes (+ 24)
\\ {\hspace*{0.3 in}} \} MYPROG

\subsubsection{Object file control}

\small\tt \begin{verbatim}  -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
\end{verbatim}\rm  \normalsize 

\subsection{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 .IMP 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.

\subsubsection{Listing control}

\small\tt \begin{verbatim}  -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.
\end{verbatim}\rm  \normalsize  \{The following may not be available in the standard release\}

\small\tt \begin{verbatim}  -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
\end{verbatim}\rm  \normalsize 

\subsection{Options}
Run-time checks:

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

\small\tt \begin{verbatim}  -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
\end{verbatim}\rm  \normalsize 
 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.

\small\tt \begin{verbatim}  -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
\end{verbatim}\rm  \normalsize Run-time diagnostic control:

\small\tt \begin{verbatim}  -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
\end{verbatim}\rm  \normalsize 
 Default: -LINE -NOTRACE


Compiler limits:

\small\tt \begin{verbatim}  -IDENTS=n          allow for n user idents (default 1000)
                     (also controls the total lengths allowed for)

  -KBYTES=n          allow for codesize nK (default 64k, max 128k)
\end{verbatim}\rm  \normalsize Compile-time control:

\small\tt \begin{verbatim}  -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 and for-loop increments and end-values
                     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).
\end{verbatim}\rm  \normalsize 
 Default: -NONONS -NOSTRICT -NOLOW -VOL -WARN -EDIT



\section{Language facilities}

The IMP language as implemented on the APM is substantially the same as the
Vax/VMS version as defined in the EUCSD Report "The IMP77 Language" (3rd
Edition). Differences and special options are described in the following
sections.

\subsection{Exclusions}

{\hspace*{0.2 in}} . {\hspace{0.2 in}} full diagnostics and \%monitor are not yet available

{\hspace*{0.2 in}} . {\hspace{0.2 in}} \%string(*)\%array\%name variables are not implemented

{\hspace*{0.2 in}} . {\hspace{0.2 in}} procedures and functions passed as parameters must be in scope to the
\\ {\hspace*{0.5 in}} procedure to which they are passed

{\hspace*{0.2 in}} . {\hspace{0.2 in}} there is no built-in function TYPEOF

{\hspace*{0.2 in}} . {\hspace{0.2 in}} untyped \%name parameters are usable only to supply an address, not type
\\ {\hspace*{0.5 in}} or length information; the built-in function SIZEOF is not applicable to
\\ {\hspace*{0.5 in}} such parameters

{\hspace*{0.2 in}} . {\hspace{0.2 in}} \%name \%function as variant for \%map is not accepted

{\hspace*{0.2 in}} . {\hspace{0.2 in}} \%on \%event * is not permitted as a way of trapping all events


{\hspace*{0.2 in}} . {\hspace{0.2 in}} line-breaks after \%and and \%or are not ignored

{\hspace*{0.2 in}} . {\hspace{0.2 in}} non-decimal constants expressed in IBM style (X'...') are accepted, but
\\ {\hspace*{0.5 in}} with a Non-standard warning

{\hspace*{0.2 in}} . {\hspace{0.2 in}} the Atlas Autocode style of \%for loop (without \%for) is accepted, but
\\ {\hspace*{0.5 in}} with a Non-standard warning

{\hspace*{0.2 in}} . {\hspace{0.2 in}} loops with a control clause after as well as before (ie an \%until as well
\\ {\hspace*{0.5 in}} as a \%while or \%for) are accepted, but with a Non-standard warning

\subsection{Modified features}

{\hspace*{0.2 in}} . {\hspace{0.2 in}} the effect of \%continue is to pass control to the head of the containing
\\ {\hspace*{0.5 in}} loop, where any \%while or \%for control clause is tested; any \%until
\\ {\hspace*{0.5 in}} clause at the end of the loop is ignored.

{\hspace*{0.2 in}} . {\hspace{0.2 in}} if no initial value is specified for an own variable, this means that it
\\ {\hspace*{0.5 in}} is initially unassigned, NOT zero.
\\ {\hspace*{0.2 in}} . {\hspace{0.2 in}} the preferred way of initialising \%name variables of all kinds is in the
\\ {\hspace*{0.5 in}} form "==NIL". The earlier form "==0" is also accepted, with a warning.

{\hspace*{0.2 in}} . {\hspace{0.2 in}} event 9 is used exclusively for end-of-input; file system errors are
\\ {\hspace*{0.5 in}} signalled as event 3, and non-numeric input for READ as event 4.

{\hspace*{0.2 in}} . {\hspace{0.2 in}} the Compiler is stricter about the ordering of statements than the Vax
\\ {\hspace*{0.5 in}} IMP Compiler. The normal ordering in any block should be declarations,
\\ {\hspace*{0.5 in}} then event trap if any, then instructions. It is acceptable for static
\\ {\hspace*{0.5 in}} declarations (eg procedures and \%own variable declarations) to be
\\ {\hspace*{0.5 in}} interspersed among instructions, but the Compiler queries any dynamic
\\ {\hspace*{0.5 in}} variable declarations which appear after instructions, and hard-faults
\\ {\hspace*{0.5 in}} any which appear in a loop or after a sequence change.

{\hspace*{0.2 in}} . {\hspace{0.2 in}} In the declaration of an array name variable, as in

{\hspace*{1.0 in}} \%INTEGER \%ARRAY \%NAME A(lo1:hi1,...,loN:hiN)

{\hspace*{0.5 in}} each of the lower and upper bounds may be:

{\hspace*{0.5 in}} (a) a literal or literal expression, for example:

{\hspace*{0.7 in}} \%integer\%array\%name a(1:1000)
\\ {\hspace*{0.7 in}} \%real\%array\%name delta(10:20,1:30)

{\hspace*{0.7 in}} In this case, the corresponding bound of every actual
\\ {\hspace*{0.7 in}} parameter must have the identical literal value.

{\hspace*{0.5 in}} (b) a variable declaration, for example:

{\hspace*{0.7 in}} \%byte\%array\%name used(1:\%integer xdim,1:\%integer ydim)
\\ {\hspace*{0.7 in}} \%short\%array\%name count(\%byte lo:\%byte hi)

{\hspace*{0.7 in}} In this case, the corresponding bound of the actual parameter is
\\ {\hspace*{0.7 in}} assigned to the stated variable at the time of procedure entry. This
\\ {\hspace*{0.7 in}} case, which is similar to the Pascal conformant array concept, is
\\ {\hspace*{0.7 in}} confined to \%array \%names as procedure parameters. It cannot be used
\\ {\hspace*{0.7 in}} for \%array \%names declared as ordinary variables.

{\hspace*{0.5 in}} (c) an asterisk, for example:

{\hspace*{0.7 in}} \%integer\%array\%name cases(1:*)

{\hspace*{0.7 in}} The use of an asterisk should be confined to the UPPER bound of the
\\ {\hspace*{0.7 in}} FIRST (outer) dimension only, and when it appears, all other bounds
\\ {\hspace*{0.7 in}} should be literal. It implies an unspecified number of elements in
\\ {\hspace*{0.7 in}} the array (and the absence of bound-checking even with checks on).

{\hspace*{0.5 in}} For the time being, the Vax/VMS form ... \%array(n)\%name ... is also
\\ {\hspace*{0.5 in}} accepted, but note that the '(n)' part is obligatory even when n is one.

\subsection{New warning messages}

Warnings are issued in a number of cases where it may be useful to have an
indication of possible hazards at compile-time rather than run-time.

{\hspace*{0.2 in}} . {\hspace{0.2 in}} All unused switch index values are reported
\\ {\hspace*{0.5 in}} [add a switch label with index (*) to eliminate]

{\hspace*{0.2 in}} . {\hspace{0.2 in}} A report is made if the destination variable(s) in a string resolution
\\ {\hspace*{0.5 in}} are not manifestly capacious enough to receive whatever might be assigned
\\ {\hspace*{0.5 in}} to them.
\\ {\hspace*{0.5 in}} [increase the length (to 255 if necessary) to eliminate]

\subsection{Data types}

\small\tt \begin{verbatim}%integer      range: -2147483648 (-2^31) to 2147483647 (2^31 - 1)
              storage: 32 bits
%long%integer  not accepted

%short        range: -32768 to 32767         storage: 16 bits
%half         range: 0 to 65535              storage: 16 bits
%byte         range: 0 to 255                storage: 8 bits
%mite         range: -128 to 127             storage: 8 bits

%real         reals are limited to single-precision (32-bits) and the
              implementation is by software
%long%real    treated as %real, apart from type-checking

%record, %array, %string -- standard
\end{verbatim}\rm  \normalsize 

\subsection{\%OPTION}

Compiler options are generally established at the outset in the command used to
call the compiler. However, most of them may also be switched off and on within
the program text by means of the directive

\small\tt \begin{verbatim}                       %OPTION "...."

         for example   %OPTION "-NOWARN-NOLIST"
\end{verbatim}\rm  \normalsize 
The quoted string must consist of a sequence of Option keywords each preceded by
a dash (hyphen).

{\hspace*{0.3 in}} Caution: indiscriminate variation of checking options within a
\\ {\hspace*{0.9 in}} program can create considerable confusion for debugging.

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


\subsection{\%INCLUDE}

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

\small\tt \begin{verbatim}                       %INCLUDE "...."

         for example   %INCLUDE "GRAPHICS.IMP-NOCHECK"
\end{verbatim}\rm  \normalsize 
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.

Include files may be nested to a maximum of three.


\subsection{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 the sub character ('\_'), as keywords.

\subsubsection{Examples of use of record constructors}

\small\tt \begin{verbatim}%record%format f1(%integer lo,hi, %string(7) code,
                 %byte%name where, %short weight)

%own%record(f1) r1=0
  {Meaning: numeric values = 0, strings = "", names == NIL}

%own%record(f1) r2=f1(-100,100,"FACTOR",nil,1)
%own%record(f1) r3=f1(0,,"DUMMY")
  {By enumeration, any omitted values unassigned}

%own%record(f1) r4=f1(_code="UNDEF",_weight=99)
%own%record(f1) r5=f1(_hi=99999,_code="MAX")
  {By selection using field names, any omitted values unassigned}
  { field names must appear in order of occurrence in declaration}
\end{verbatim}\rm  \normalsize 


\subsection{Declaration attributes}

The keyword \%volatile may be prefixed to a function declaration to indicate that
the result of the function is not a pure function of its arguments. This stops
the compiler optimising repeated calls.


The prefix '@'$<$machine-address$>$ may be placed in front of a variable or
procedure declaration to indicate that the corresponding entity is to be
addressed at the location indicated. The $<$machine-address$>$ may be either an
absolute value or a register-relative value. For example:

\small\tt \begin{verbatim}    @16_041234 %byte DEVICE STATUS
    @16_1BC8   %routine ABANDON   (formally equivalent to an %external %spec)
    @4(A5)     %integer USERNO
\end{verbatim}\rm  \normalsize 
Caution: this is a Low-level facility


\subsection{Name-relative addressing}

When a number of elements of a given type are stored consecutively, for example,
in an array or mapped file, it is sometimes convenient to use a \%name variable
as a base point for addressing different elements. The name-relative addressing
facility allows this to be done. This takes the form of a \%name variable
followed by an index value enclosed in square brackets. Such an expression
denotes a reference to the variable located that number of elements away from
the element identified by the current assignment to the name variable.

Caution: this is a Low-level facility

There is no check on the validity of the references. Use of the facility is,
however, preferable to the use of store-mapping functions in a similar role,
because it preserves the type identity of the objects denoted.

\subsubsection{Example}

With the following definitions and assignment:

\small\tt \begin{verbatim}          %recordformat       PAIR(%real x,y)
          %record(pair)%array A(1:100)
          %record(pair)%name  P
          P == A(7)
\end{verbatim}\rm  \normalsize 
the following would hold:

\small\tt \begin{verbatim}          P[2]  would denote A(9)
          P[-6] would denote A(1)
          P == P[1] would advance P to denote A(8)
\end{verbatim}\rm  \normalsize 



\section{Standard libraries}

\subsection{Pre-declared procedures}

The procedures listed below are available without specification.

\small\tt \begin{verbatim}%integer%map     INTEGER(%integer a)
%real%map        REAL(%integer a)
%string(*)%map   STRING(%integer a)
%record(*)%map   RECORD(%integer a)
%byte%map        BYTEINTEGER(%integer a)
%short%map       SHORTINTEGER(%integer a)
%byte%map        LENGTH(%string(*)%name s)
%byte%map        CHARNO(%string(*)%name s, %integer n)
%integer%fn      ADDR(%name n)
%string(1)%fn    TOSTRING(%integer k)
%string(255)%fn  SUBSTRING(%string(255) s, %integer from,to)

%integer%fn      REM(%integer a,b)

%integer%fn      INTPT(%real x)
%integer%fn      INT(%real x)
%real%fn         FRACPT(%real x)
%real%fn         SQRT(%real x)

%integer%fn      CPUTIME  
                 !in milliseconds (since process creation)

%name            NIL
%record%format   EVENTFM(%byte event,sub, %short line, %integer extra,
                 %string(255) message,%integerarray r(0:15))
                 !LINE and R are APM-specific extensions
%record(eventfm) EVENT
%const%integer   NL
%const%string    SNL
%integer%fn      NEXTSYMBOL
%routine         READSYMBOL(%name n)
%routine         PRINTSYMBOL(%integer k)
%routine         SKIPSYMBOL
%routine         PRINTSTRING(%string(255) s)
%routine         READ(%name n)
%routine         WRITE(%integer m, n)
%routine         PRINT(%real x, %integer n,m)
%routine         PRINTFL(%real x, %integer n)
%routine         NEWLINE
%routine         NEWLINES(%integer i)
%routine         SPACE
%routine         SPACES(%integer i)
%routine         SELECT INPUT(%integer n)
%routine         SELECT OUTPUT(%integer n)
%routine         CLOSE INPUT
%routine         CLOSE OUTPUT
%routine         SET INPUT(%integer pos)
                 !establish new active position for current input stream
                 ! set input(0) resets to the beginning of a file
                 !!!  temporary restriction: only POS=0 accepted ***
%routine         SET OUTPUT(%integer pos)
                 !establish new active position for current output stream
                 ! set output(0) resets to the beginning of a file
                 !!!  temporary restriction: only POS=0 accepted ***
%routine         RESET INPUT    {equivalent to SET INPUT(0)
%routine         RESET OUTPUT   {equivalent to SET OUTPUT(0)
%integer%fn      INSTREAM
%integer%fn      OUTSTREAM
%routine         OPEN INPUT(%integer n, %string(255) S)
                 !*selects N at present*
%routine         OPEN OUTPUT(%integer n, %string(255) S)
                 !*selects N at present*
%string(255)     CLIPARAM
                 ! returns the parameter string supplied with the command
                 ! invoking the program
%routine         PROMPT(%string(255) S)
\end{verbatim}\rm  \normalsize 
\subsection{General-purpose 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 IMP programs by means of the \%INCLUDE statement, for example,
\%INCLUDE 'INC:UTIL.IMP'.

Library interface files currently available are:

{\hspace*{0.3 in}} INC:UTIL.IMP -- sundry utility procedures
\\ {\hspace*{0.3 in}} INC:FS.IMP {\hspace{0.3 in}} -- file system procedures

{\hspace*{0.3 in}} [others under preparation]

\subsubsection{Example of use of UTIL}

\small\tt \begin{verbatim}    {Simple file copy program}
    %begin
    %include "INC:UTIL.IMP"
    %string(255) inname,outname
    %on %event 9 %start;  !end-of-file
      %stop
    %finish
      define param("Input file:",inname,PamNodefault+PamInfile)
      define param("Output file:",outname,PamNewGroup+PamNoDefault+PamOutfile)
      process parameters(cliparam)
      print line("Copying ".inname." to ".outname)
      select input(1);  select output(1)
      %cycle
        read symbol(ch);  print symbol(ch)
      %repeat
    %endofprogram
\end{verbatim}\rm  \normalsize 

\subsection{External linkage}

The pre-prepared libraries make use of the general external linkage mechanism
implemented for IMP. This allows external REFERENCES in one program to be
matched up with external DEFINITIONS in another program or module. The linkage
takes place automatically when the program is run.

In IMP, an external reference starts with the keyword \%external and includes the
keyword \%spec after the type. For example:

{\hspace*{0.3 in}} \%external \%routine \%spec INITIALISE(\%integer case)
\\ {\hspace*{0.3 in}} \%external \%integer \%spec CURRENT DEVICE

In APM IMP, external references must appear at the outermost textual level, that
is, before the first \%begin or in the main program block. An external spec for
a procedure may be satisfied by a procedure occurring later in the same module,
but the same is not true for variables.

External definitions start with the keyword \%external. For example:

{\hspace*{0.3 in}} \%external \%routine INITIALISE(\%integer case)
\\ {\hspace*{0.5 in}} ......
\\ {\hspace*{0.3 in}} \%end

{\hspace*{0.3 in}} \%external \%integer CURRENT DEVICE=2

These must appear in the source file before the main block (if any).


A program module containing external procedures or variables, and terminated by
\%endoffile, is compiled in the ordinary way, eg IMP MYLIB. Before the externals
it contains can be accessed, the compiled module must be installed by the
INSTALL command. The INSTALL command takes as parameter the name of a program
file (extension MOB assumed) -- or list of names separated by commas. For
example INSTALL MYLIB. The effect of installing a program file is to add all
the external names it contains to the external symbol table; the code of the
module is not loaded at this stage. Thereafter (until logoff) these names are
available for external linking, which is done automatically when a program
referencing any of the names is loaded. It is only necessary to re-install a
program file if a change is made to the external names it contains.

An external name is the identifier declared as external (standardised to
space-free lower-case form) unless this is over-ridden by an alias, in which
case the alias name is used instead (exactly as presented). Note that an alias
over-rides the declared identifier, rather than providing an alternative to it.


\subsection{Cross-calling}

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

IMP \%name parameters are compatible with Pascal VAR parameters.

IMP predicates are compatible with Pascal Boolean functions .

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

Integer subrange correspondence is as follows:

\small\tt \begin{verbatim}             IMP                     Pascal

           %short                -32768..32767
           %half                      0..65535
           %mite                   -128..127
           %byte                      0..255
\end{verbatim}\rm  \normalsize 

\section{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.

\small\tt \begin{verbatim} REPORT                     MEANING

Faulty form      statement part indicated is syntactically faulty
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
Mismatch         parameters in body of procedure do not match spec
Not variable     operand in assignment context is not a variable
Not reference    operand in pointer context 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
Endless loop     literal %for loop cannot terminate
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
Not in loop      %exit %or %continue is not within a loop construct
Not in routine   %return is not within a routine
Not in fn/map    %result is not within a function or map
Not in pred      %true/%false is not within a predicate
%CYCLE missing   %repeat encountered with no matching %cycle
%REPEAT missing  %end reached with unmatched %cycle
%START missing   %finish or %else encountered with no matching %start
%FINISH missing  %end reached with unmatched %start
Extra %ELSE      %else encountered matching earlier unconditional %else
%BEGIN missing   %end encountered with no matching %begin or
                 procedure header
%END missing     %end %of %program or %file reached with unmatched
                 %begin or procedure header
%RESULT missing  there is apparently a path to the end of a function
                 or map which does not specify a result
Not accessible   instruction apparently cannot be executed (warning only)
Out of order     statement appears in incorrect order in block
                 (warning if benign)
Nonstandard      non-standard language feature (warning only)
<ident> void     identifier is used before a value is assigned to it
                 (warning only)
<ident> missing  forward label or specced identifier does not appear
                 in block
<ident>(?) missing  switch label to which there is an explicit jump
                 has not been specified
<n> extra values for <ident>
                 too many values for %const or %own array
Faulty operand   incorrect operand type for machine instruction
Wrong size       operand is of incorrect size for machine instruction

Too complex!     compiler limitation exceeded (eg no free register)

Internal error <n>!   compiler fault

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

In the case of programs which exceed 32k bytes in size, the compiler
uses a number of techniques to avoid creating within-program references
which breach the M68000 PC-relative addressing limitation of +-32k.
There is a possibility in some cases that these do not succeed, 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 its calls.
If no name is given, the problem is access to a constant.
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 (see Option -KBYTES)
Code space exhausted     Size of the code for currently open blocks
                         exceeds the maximum allowed for
Identifiers too big      Total length of all current identifiers exceeds
                         the maximum allowed for (see Option -IDENTS)
Too many identifiers     Number of current identifiers exceeds the maximum
                         allowed for (see Option -IDENTS)
Too many levels          Depth of textual nesting of blocks exceeds
                         the maximum permitted (8)
Too many literals        Internal storage space for literals is exhausted
Input ended              There is no %endofprogram or %endoffile statement
Too many nested includes There are more than three levels of nesting


\section{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.

\subsection{Run-time errors}
\small\tt \begin{verbatim}         ERROR                            CODE          REQUISITE
                                                         OPTION
Variable value undefined (unassigned)      8 1            -ASS, -BASS, etc
  [sometimes detected as "Void" 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
Trig function error                       10              none

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

Switch label not catered for             taken as at %end
    [warning issued at compile-time]

Name variable NIL                          8 1            -ASS
Name variable undefined                    8 1            -ASS

File system error                          3 x            none

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

End-of-input                               9              none
\end{verbatim}\rm  \normalsize 

\section{Efficiency}

{\hspace*{0.3 in}} . In the absence of floating-point hardware, all floating-point
\\ {\hspace*{0.5 in}} operations are performed by software.

{\hspace*{0.3 in}} . Integer multiply and divide are also performed by software, although
\\ {\hspace*{0.5 in}} a number of special cases are optimised.

{\hspace*{0.3 in}} . Full checking is expensive in both time and space. Developed programs
\\ {\hspace*{0.5 in}} should be compiled with checks and diagnostics disabled.
\\ {\hspace*{0.5 in}} Fullest optimisation is obtained by specifying:

{\hspace*{1.0 in}} -NOCHECK-NODIAG-NOSTACK-NOVOL

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


\section{Low-level facilities}

As a system implementation language IMP provides a number of facilities which
permit access to parts of the system other languages do not reach. The
store-mapping functions (INTEGER, BYTEINTEGER, etc) allow for direct addressing
using machine addresses; the name-relative indexing facility (as in CUR[1] or
POS[-2]) extends the capability of \%name variables; the fixed-address
declaration facility (as in @16\_200C \%byte TIMER, KBIN, KBOUT) allows efficient
source-level access to specific areas of store.

The use of these facilities involves some loss of the protection normally
conferred by a high-level language and a potential (particularly on a processor
without hardware protection) for uncontrolled malfunction. They should,
therefore, be used with restraint and care.

\subsection{Assembler in IMP}

Sequences of assembly language instructions may be incorporated in an IMP
program at any point. At present no enabling directive is required. Apart from
the usual hazards of machine level programming, there is the danger of
corrupting the environment pre-supposed by the high-level facilities. For this
reason, it is sensible to keep the use of these instructions to a minimum and to
take particular care in programming these sections.

Assembly language instructions are distinguished from IMP statements by being
prefaced by an asterisk (eg *MOVE D0,D1). They appear within IMP blocks and
procedures and are executed according to the normal flow of control, subject to
any control transfers invoked by the instructions themselves. IMP conventions
for statement termination, labelling and commenting apply, but otherwise the
form of instruction follows closely that defined under the heading of Assembler
Syntax for each individual instruction in the Motorola M68000 manual.

Machine-level operands are specified using the mnemonics D0-D7 and A0-A7 (or
SP), and the standard syntax for $<$ea$>$ modes. Immediate and Address register
variants of op-codes are selected automatically. By comparison with full
Assembler, most of the directives do not apply; assembly-time expression
evaluation is restricted; size specification in cases where the size is implicit
in the op-code is not in general allowed; the indexed PC-relative mode is not
supported, nor is the 'current location counter'.

The error report 'Faulty operand' indicates use of an invalid operand for the
context, but the compiler does not fully check the validity of $<$ea$>$ modes for
the particular instruction.

NB the default 'size' applied is Long (32-bits) rather than Word (16-bits) which
is the manufacturer's default. Programmers may choose to make a practice of
including the size suffix explicitly for all relevant instructions.

The special mnemonics USP (User Stack Pointer), SR (Status Register) and CCR
(Condition Code Register) are NOT supported but the relevant effects can be
achieved by use of the additional op-codes:

\small\tt \begin{verbatim}  MTCCR <ea>          for      MOVE <ea>,CCR
  MTSR <ea>           for      MOVE <ea>,SR
  MFSR <ea>           for      MOVE SR,<ea>
  MTUSP An            for      MOVE An,USP
  MFUSP An            for      MOVE USP,An
  ATCCR #<data>       for      AND #<data>,CCR
  ATSR #<data>        for      AND #<data>,SR
  ETCCR #<data>       for      EOR #<data>,CCR
  ETSR #<data>        for      EOR #<data>,SR
  OTCCR #<data>       for      OR #<data>,CCR
  OTSR #<data>        for      OR #<data>,SR
\end{verbatim}\rm  \normalsize 
IMP identifiers may also be used as operands for assembly language instructions.
The detailed implications of this over the whole range of data types are fairly
complex and subject to change. The following cases are reasonably
straightforward and stable. Scalar variables or elements of scalar records may
be used as $<$ea$>$ operands provided that they are:

{\hspace*{0.3 in}} declared as own or
\\ {\hspace*{0.3 in}} declared at the outermost level or
\\ {\hspace*{0.3 in}} declared at the current level or
\\ {\hspace*{0.3 in}} declared by means of a fixed-address declaration

Variables declared at intermediate levels should not be accessed since they are
not necessarily directly addressable. In the case of a \%name variable the
effective operand is the pointer value (32-bit address) rather than the
referenced object.

Labels and procedure names may be referenced in the Branch group of
instructions, including BSR. The only alternative form of operand for these
instructions is immediate (eg *BLT \#-4), the value specified being the
machine-level displacement. Short and long branches are handled automatically
(though the Compiler's CODE listing does not show this). To access a forward
label in an assembly language instruction, it is neccesary for the label to have
been declared by means of the IMP declaration \%LABEL $<$lab$>$.

The registers D0-D3 and A0-A3 may be freely used within assembly sections, but
no assumptions can be made about their contents after execution of most IMP
statements. Other registers may be used only on the basis that their values are
restored before reverting to IMP. In particular this applies to SP. In
addition, NOTE WELL that the accessing of local variables depends on SP; if SP
is changed, access to such variables in machine instructions becomes a nonsense
(though no error report can be made). Similarly, any modification of A4-A6
rules out access to non-local variables.

Note that any declaration of IMP identifiers which co-incide with the register
mnemonics takes precedence.


\vspace{.75in} view:impv2 printed on 06/04/89 at 09.10

\newpage
\tableofcontents
\end{document}
