E D I N B U R G H R E G I O N AL C O M P U T I N G C E N T R E
October 1981
IMP80 on EMAS 2900: Differences from IMP9
Contents
Page
1. Compiler name 2
2. Lower case input 2
3. Continuation 2
4. Comments 2
5. == and ## 2
6. Available types 3
7. Keyword and operator alternatives 3
8. own initialisation 3
9. Switch labels 4
10. Cycles 4
11. start/finish blocks 5
12. Constants 6
13. Strings 7
14. Records 8
15. external entities 10
16. Procedures as parameters 10
Introduction
This document is intended for users of the programming language IMP on EMAS
2900 who wish to know how the new version of IMP, IMP80, differs from the
current version, IMP9.
It should be noted that IMP80 on EMAS 2900 differs in certain respects from
other implementations of IMP80, and that this document should not be trusted
as far as other implementations are concerned.
Some of the features of IMP80 described below exist in IMP9. They are
included here either to help explain some other feature or for completeness.
IMP80 Differences 1
For convenience constants used in own array initialisations can be
followed by a repeat count, in brackets. This repeat count can be
given as '(*)' where * represents the number of remaining array
elements to be initialised.
Example:
own integer array VALUES (1:50) = %C
17, 4, 6(3), 9, 22(17),
100(*) {all the rest}
This also applies, of course, to constant and external array
initialisation.
9. Switch labels
Consider the following:
switch LETTER('a':'z')
:
:
LETTER('a'):
LETTER('e'):
LETTER('i'):
LETTER('o'):
LETTER('u'):
! Deal with the vowels here
:
LETTER(*):
! All the rest (i.e. the consonants)
:
:
Instead of using a constant to specify a specific element of a switch
vector, * can be used. It represents all the elements of the switch
vector not defined elsewhere. Note that it does not have to come
after the specifically defined switch labels.
10. Cycles
The permissible forms of cycle are these:
a) cycle (endless cycle)
:
repeat
b) while condition cycle
:
repeat
c) cycle
:
repeat until condition
d) for var = init, inc , final cycle
:
repeat
4 IMP80 Differences
The unconditional instructions continue and exit can be used inside a
cycle of any type. continue causes a branch to the next repeat; exit
causes a branch to the statement following the next repeat.
Notes on the cycle types:
b) while cycles are executed zero or more times. When the cycle
body consists of a single statement, the form
statement while condition
can be used.
Example:
SKIP SYMBOL while NEXT SYMBOL=' '
c) until cycles are executed one or more times. The simple form is
statement until condition
d) for cycles: the cycle variable must be of type integer; it should
not be changed explicitly within the cycle body; the cycle body
is executed (final-init)//inc + 1 times or zero times, whichever
is the greater; if the cycle is not executed the cycle variable
is not set; (final-init) must be exactly divisible by inc; the
simple form is
statement for var = init, inc, final
Example:
A(I)=0 for I=20,-1,1
[Going down in steps of -1 to 1 happens to be more efficient
on EMAS 2900 than the more usual 1,1,20 form.]
11. start/finish blocks
The general form is
if cond 1 then start
:
:
:
finish else if cond 2 then start
:
:
:
finish else if cond n then start
:
:
:
finish else start
:
:
:
finish
IMP80 Differences 5
Notes
* Every start matches with the next occurring finish. If they
enclose only one statement then they can be replaced by that
statement.
Example:
if cond 3 then start
statement
finish else if .......
can be expressed as
if cond 3 then statement else if .......
* then start can be replaced by start.
* if can be replaced by unless, the effect being to negate the
condition following.
* Any of the statements starting "finish else" in the general form
can be omitted, including the last one.
* If the condition controlling a start/finish block can be
determined at compile-time then the IMP80 compiler may do so, and
might not generate code for statements that cannot logically be
executed. This is known as "conditional compilation".
12. Constants
a) An integer constant of any integer base from 2 to 36 may be
specified. The form is
base_constant
where base is a decimal constant and constant is an integer
expressed with respect to the base. The letters A, B, ..., Y, Z
can be used to represent the digits 10, 11, ...., 34, 35.
An alternative form is provided for binary, octal and hexadecimal
constants:
B'1010' ten in binary
K'12' ten in octal
X'A' ten in hexadecimal
b) Named constants
Variables of all types can be given the attribute constant. This
can be considered a special form of own variable, which cannot be
changed from its initial value. However it is probably better to
consider such variables as "named constants", since 1) this
accords with their intended use, i.e. for replacing arithmetic or
string constants within code by meaningful names; and 2) they do
not have addresses, unlike other variables (but like constants).
Wherever a constant is permitted in an IMP80 program, a "constant
expression" can be used instead. A constant expression is one
which can be evaluated at compile-time, i.e. its operands are
constants or named constants.
6 IMP80 Differences
Example:
string (73) DELIVERY
can be replaced by
constant integer MAXNAME=20, MAXADDRESS=52
string (MAXNAME+1{for the newline}+MAXADDRESS) DELIVERY
Example:
constant integer NO=0, YES=1,
INPUT=1 , CALCULATION=2,
OUTPUT=3
switch PHASE(INPUT:OUTPUT)
:
:
->PHASE(OUTPUT) if DONE=YES
:
:
PHASE(OUTPUT): ! Now print the results
:
13. Strings
a) The keyword string may always be followed by a length
specification.
Thus string(10)array name ....
and string(255)name ......
are permitted.
In EMAS 2900 IMP80, no use is made of the maximum length
specification for string name and string array name variables.
[In other IMP80 implementations, however, a string name variable
must have a maximum length specification and can only refer to
("be pointed at") a string variable of the same maximum length.
The forms
string(*)array name .....
string(*)name ...........
are also provided, however, to enable declarations of reference
variables which can point at any string variable.]
b) The string function FROMSTRING is renamed SUBSTRING.
c) A string resolution of the form
S -> (A).B
succeeds in IMP9 only if string S starts with string expression
A. In IMP80, however, the resolution is interpreted as being
equivalent to S -> JUNK.(A) .B where JUNK is a "hidden" string
(255) variable; that is, the resolution will succeed if A appears
anywhere within S.
IMP80 Differences 7
When converting an IMP9 program to IMP80, the following
translations are recommended:
if S -> (B).C then ... in IMP9
becomes if S -> A.(B).C and A="" then ... in IMP80
[A is a new string (255) variable]
and if S -> (B).S then ... in IMP9
becomes if S -> A.(B).C and A="" then S = C and ... in IMP80
[A and C are new string (255) variables]
14. Records
a) The syntax of declarations in IMP80 differ from that in IMP9.
They are of the form
record (format) ident, ...
record (format) array ident, ...
record (format) name ident, ...
record (format) array name ident, ...
"format" is either the name of a record format previously
described or is the actual record format itself.
Example:
record format RF(integer I, J, K)
record (RF) R
and
record (integer I, J, K) R
are both valid and have the same effect, except that the first
version declares a record format with identifier RF, which can be
used elsewhere, clash with other identifiers, etc.
To summarise: the keyword record in IMP80 must either be followed
by the keyword format or by a bracketed format or format
reference.
This can cause difficulties when translating IMP9 programs: a
routine spec such as
routinespec NAME1(record name NAME2, ...)
must now be converted to
routinespec NAME1(record (FORM2) name NAME2, ...)
The record format FORM2 is presumably declared somewhere in the
program, since a record of this format is required in order to
call the routine; but it might not be in scope at the routine
spec statement, and may have to be moved so that it is.]
record spec statements are not allowed in IMP80.
8 IMP80 Differences
b) The syntax of record format statements has been extended to
permit alternative formats, i.e. to enable all or part of a
record to be interpreted in different ways.
Example:
record format RF(integer A or byteinteger B, C, D c
or long real E)
record (RF) R
The record R can be considered to consist of an integer or three
byte integers or a long real. Each alternative starts at the
same address. Thus it follows that in
record format RF2 (byteintegerarray A(0:10) or c
string(10) S)
record (RF2) R2
R2_A(i) holds the ith character of string R2_S.
Note that all the sub-fields in a record format must have
distinct identifiers.
In the first example above, the three alternatives were of
different sizes. This is permitted: the alternatives have
padding bytes appended to them to bring them up to the size of
the largest. Thus when calculating the size of a record, use the
size of the largest alternative.
When only part of a record is to have alternative formats, the
alternatives must be bracketed within the record format
statement.
Example:
record format RF3(integer TYPE, real RATIO,
(byte integer array A(1:20) c
or string (10) S c
or record (RF2) DATA),
string(*) name SN)
More than one set of alternatives can be given within a single
record format; in addition, they can be nested. Note that
redundant brackets round alternatives are not allowed.
c) Records can contain records. The format of such a record must
have already been defined, or be explicit.
Records can contain single dimensional arrays of fixed bounds, of
any type.
d) Records can contain record names. The format of such a record
name can be the same as that of the record containing it; thus
record format RF4(integer X, record (RF4) name NEXT)
is permitted.
IMP80 Differences 9