$a invert=0; cap=0; capsh=0; und=0; undsh=0
$a line=80; page=0; top=0; bottom=0
$b8 $l
           A P M   I M P   P R O G R A M M E R ' S   G U I D E
$b6
This manual describes the implementation of the IMP programming language
for the APM and includes a description of the main library modules
which are available to the programmer.
$n $l1u
Definition of Language
$p The IMP language as implemented on the APM is the agreed version
for forward development on the VAX/VMS and M68000 systems.
It is substantially as defined in the EUCSD Report "The IMP77 Language"
(3rd Edition), with the following exceptions.
$a tab=6,10; indent=2
$b2 $l1
Discarded features:
$l0
$i- .$t+ non-decimal constants expressed in IBM style (X'...')
$i- .$t+ %name %function as alternative to %map
$i- .$t+ loops with a control clause after as well as before
    (ie an %until as well as a %while or %for)
$b2 $l1
Modified features:
$b $i- .$t+ the declaration of %arrayname parameters requires the
specification of bounds either as literals or as declared
local variables, as illustrated in the following examples:
$l0i
        %integerarrayname a(1:1000)
        %realarrayname delta(10:20,1:30)
        %bytearrayname used(1:%integer xdim,1:%integer ydim)
        %shortarrayname count(%byte lo:%byte hi)
$b0 in order to match the formal parameter, an actual array must have
been declared with at least as many dimensions and with identical
literals where the formal has literals.
$b2 $l1
Added features
$i- .$t+ there are a number of additions which make it possible to exercise
greater control over the way in which variables are allocated
and parameters are passed; these are not of general utility
and are not described here.
$b2 $l1
Variant implementation
$l0
$i- .$t+ the effect of %continue is to pass control to the head of
the containing loop, where any %while or %for control clause is
tested; any %until clause at the end of the loop is ignored.
$n $l1u
Implementation restrictions
$p The range of integers handled is the 32-bit signed twos-complement range.
Apart from type-checking, the declaration %longinteger is treated
as equivalent to %integer.
$b0 Both signed and unsigned (%short and %half) 16-bit integers are
supported, the former slightly more efficiently.
$b0 Both signed and unsigned (%mite and %byte) 8-bit integers are
supported, the former slightly more efficiently.
$p In the present implementation, floating-point numbers are limited to 32-bits
and the operations on them are implemented by software.
Apart from type-checking, the declaration %longreal has the same effect
as %real
$p The maximum number of nested textual levels permitted is eight.
In this respect, no distinction is made between procedures and %begin/%end
blocks.
$p The maximum number of nested conditionals or loops is fifteen.
$p A strict rule of ordering between the declarations and instructions
in a block is not imposed, but the following restrictions apply:
$l0
No declarations are permitted within conditionals or loops;
Only static declarations (%const, %own, %external and procedures)
are permitted to follow instructions which include a forward
jump or procedure call;
The specifications for %external procedures and data objects must appear
in the outermost level or main %begin/%end block.
$b
Features of IMP77 which are not valid in IMP80
(EMAS IMP) and conversely, or which are peculiar to this implementation,
are reported as 'non-standard' (warning only).
However, this warning is not produced for the following widely used
IMP77 facilities, even though they are not available in IMP80:
$l0
        %shortintegers, %predicates, %else %if, operator mod-sign,
        initialisation of dynamic variables to literal values
        (but initialisation to non-literal values is flagged).
$b $l1
!<Calling the Compiler
The Compiler is invoked by the command IMP. There is only one obligatory
parameter and that is the name of the IMP source program to be compiled.
There is no default extension for the source file-name.
$b
Error reports are directed to the terminal.
Line-numbering continues through any included files.
$b
Unless otherwise directed the Compiler generates a code file
with the same name as the source file and extension MEX (for Motorola
executable file).
The code file is eligible for execution by citing the name as a
command verb. No linkage operation is required.
$b
For example, the system command IMP MYFIRST calls for the source
file "MYFIRST" (no extension) to be compiled as an IMP program,
creating the file "MYFIRST.MOB". On successful completion of the
compilation, the command "MYFIRST ...." becomes available as
a system command, and causes the object program to be loaded and
entered.
$l2
!>
!<Options
There are a number of options affecting the way in which the
Compiler processes the source program. Modifications to the
default choices may be selected by including
appropriate keywords in the parameter string. These
are introduced by a dash (minus).
$b
The main options are given below. Those not yet implemented are marked
with an asterisk, and those only partially implemented with a query.
In the case of the yes/no options, the option is suppressed by selecting
the keyword prefixed with "NO".
$l0

 Source listing control:
      -LIST=<filename>    produce listing to specified file
                          (extension LIS)
      -LIST               produce listing to file with same name
                          as source and extension LIS
      -LIST               produce listing to network printer
      -NOLIST             do not produce listing
      -LOG                output statistics indicating number of statements,
                          atoms per statement, identifiers per statement,
                          time taken, etc.
   Default: -NOLIST-NOLOG

 Object program control:
      -OBJ                produce object file with same name as source
                          and extension MOB
      -OBJ=<filename>     produce object file with specified name
                          (default extension MOB)
      -NOOBJ              do not produce object file
   Default: -OBJ (but only if no errors reported)

 Run-time checks:
  ?   -ASS       include unassigned check on full integers
  ?   -STRASS    include unassigned check on strings
  ?   -SASS      include unassigned check on shorts
  ?   -BASS      include unassigned check on bytes

  ?   -ARR       include array bound checking
  *   -LOOP      include %for loop check
  *   -OVER      include overflow check
  *   -CAP       include capacity checking
  Default: -ASS-STRASS-NOSASS-NOBASS-ARR-LOOP-OVER-CAP
           -NOCHECK has the effect of suppressing all checks


 Run-time diagnostics:
      -DIAG         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: -NODIAG-NOTRACE

$l2
!>
!<Omissions
Omissions in current release -- to be added:
$l0
 .  full diagnostics and %monitor
 .  %begin/%end blocks
 .  procedures as parameters
$b $l1
Variant features [provisional]
$l0
 .  %continue by-passes any test on the %repeat at the end of a loop
 .  Array name parameters must have bounds specified in the declaration
    [eg %byteintegerarrayname a(0:31) or %integerarrayname b(1:%integer n)]
    ** In the present compiler only the first form (with literal bounds,
    ** one-dimension) is accepted.  However, actual parameters with the
    ** specified LOWER bound will work irrespective of the actual upper bound.
$b $l1
Omitted features which may be added:
$l0
 .  %label declarations
$b $l1
Omitted features which are unlikely to be added:
$l0
$l3
!>
!>
!<External linkage (May 83)
The external linkage mechanism provides for the use of program modules
or libraries containing externally accessible procedures or variables.
$b
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.
$b
The system command HELP LIB gives information about generally available
libraries.
$b $l1
!<Restrictions on externals
The following restrictions apply to the current implementation:-
$a tab=5; indent=1
$b
$i- 1. $t+ Names are truncated to 11 characters for purposes of matching
as externals.
$i- 2. $t+ The type checking is nominal.
$i- 3. $t+ External %name variables are not supported.
$i- 4. $t+ External specs must all be at the top program level, that is, they
may not appear within procedures or inner blocks.
$i- 5. $t+ 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.
$i- 6. $t+ Externals may not be combined with a main program (%begin ...
%endofprogram).
$b
$i- CAUTION: The final form of external linkage will certainly differ from this
interim form, necessitating re-compilation.
$a indent=0
$l3
!>
!>
!<Permanent procedures
The permanent procedures listed below are available without specification.
These are generally as provided on Vax, with exceptions and additions
noted.  Terminal output is direct, so that there is no need for any
TTPUT or FLUSH OUTPUT procedures.
$b $l1
!<Standard PERM
$l0

%integermap      INTEGER(%integer a)
%realmap         REAL(%integer a)
%string(*)%map   STRING(%integer a)
%record(*)%map   RECORD(%integer a)
%bytemap         BYTEINTEGER(%integer a)
%shortmap        SHORTINTEGER(%integer a)
%bytemap         LENGTH(%string(*)%name s)
%bytemap         CHARNO(%string(*)%name s, %integer n)
%integerfn       ADDR(%name n)
!PAGE
%string(1)%fn    TOSTRING(%integer k)
%string(255)%fn  SUBSTRING(%string(255) s, %integer from,to)

%integerfn       REM(%integer a,b)

%integerfn       INTPT(%real x)
%integerfn       INT(%real x)
%realfn          FRACPT(%real x)
%realfn          SQRT(%real x)

%string(8)%fn    DATE
%string(5)%fn    TIME
%integerfn       CPUTIME  
                 !in milliseconds (actually elapsed time at present)

%record(*)       NIL
%recordformat    EVENTFM(%integer event,sub,extra,pc,
                 %string(255) message,%integerarray r(0:15))
                 !PC and R are APM-specific extensions
%record(eventfm) EVENT
!PAGE
%constinteger    NL
%integerfn       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         SELECTINPUT(%integer n)
%routine         SELECTOUTPUT(%integer n)
%routine         RESET INPUT
%routine         RESET OUTPUT
%routine         CLOSE INPUT
%routine         CLOSE OUTPUT
!PAGE
%integerfn       INSTREAM
%integerfn       OUTSTREAM
%routine         OPEN INPUT(%integer n, %string(31) S)
                 !*selects N at present*
%routine         OPEN OUTPUT(%integer n, %string(31) S)
                 !*selects N at present*
%routine         PROMPT(%string(31) S)
%integerfn       TESTSYMBOL
                 !*APM specific*
                 !value is -1 if no symbol available from terminal
                 !otherwise value is the symbol, which is skipped

%constinteger    NOECHO,NOTERMECHO,SINGLE,NOPAGE
%routine         SET TERMINAL MODE(%integer m)
                 !*APM specific*
                 !set terminal mode as specified by M (sum of flags)
$l3
!>
!>
!<Compiler limits
The following limits apply in the current release:
$l0

1. The maximum length of a source line including continuation lines
   is 512 characters (lines following comma-terminated lines do not
   count as continuation lines).
2. The depth of textual nesting of procedures is limited to between
   three and six levels, depending on what the procedures get up to.
3. The number of parameters to a procedure may not exceed five
   numeric values and four non-numeric value or name parameters.
4. The total size of the static data area (for owns/externals) is
   limited to 16k bytes.
5. The size of the code area (for program and constants) is limited
   to 64k bytes.  In addition, there is no escape from the machine
   limited reach of +-32k bytes for accesses to constants.
   The compiler does automatically cater for procedure calls which
   would otherwise run into this limitation, but this does not apply
   to calls made from the main program block.
$l2
!>
!<Known Defects
$l1
Compiler bugs:
$b
Statements like "%if COND %then %result = EXP1 %else %result = EXP2"
are liable to be mis-compiled. Fix: change "%else" to ";".
$b
The use of certain compound expressions as argument
to one of the store-mapping functions causes mis-compilation and
the error report "Faulty operand" or "Internal error".
$b0
Fix: assign the expression to a simple variable and use that.
$b $l1
Run-time deficiencies:
$b
The general level of checking for run-time errors is fairly low
in this release, since the main priority is to permit already developed
programs to be moved across to the APM.
$b0
The unassigned variable check is not foolproof and may allow certain
unassigned variable references to slip through.
$b0
The array bound check is applied only to arrays with dynamic (or very large)
bounds.
$b0
There is no run-time check on the validity of %for loops.
$b0
There is no run-time capacity checking.
$b2
Please report any difficulties by Mail (not Notify) to HMD,
giving the name of the source file (which should be permitted)
and a brief indication of the nature of the trouble (eg 'Address
error at compile-time' or 'Spurious Event 8 at run-time').
$b
Note that object code conventions are provisional and the
source of all programs should be retained in case they require
to be re-compiled.
$e
$l1
Parameters for programs
$p As a step towards a systematic treatment of command parameters,
I have provided a procedure PARMSET which takes three arguments:
$l0

   %string(255) PARM    the parameter string as typed by user, with the
                        convention that a value of "-" implies that
                        parameters should be read from the current
                        input stream;

   %string(255) GUIDE   defines the types and mnemonics of the
                        parameters;

   %integer BASE        the address of the first parameter variable
                        within the program.
$b
The parameter variables within the program must all be initialised
owns and must appear in strict sequence as defined by GUIDE. They
should be either strings with a length one less than a multiple
of four (to avoid alignment problems on different
machines) or full integers (although GUIDE may
define binary flags packed in an integer).
$b2
Syntax?????
$b
The file PARM.IMP contains a version of the procedure
for inclusion within a source file (see it for an example
calling sequence).
$b
The file PARM.OBJ contains a compiled version suitable for linking
as an external routine with a Vax program.
$b4 $l1
                                                 Hamish Dewar
