Executable Statements
KEY
In IMP80 a condition can form part of any executable statement.
Conditions are therefore described before the various types of
executable statement.
Conditions
KEY
The commonest form of simple condition in IMP80 is made up of two
expressions separated by a comparator. The expressions are evaluated
and compared. The condition is true if the relation specified by the
comparator holds. The expressions must yield values of the same type.
Complete records cannot be compared.
Examples:
J = 0
A = "END"
X+23.7 <= F(J+2,Y) - 2*Z/P
REF == K
The comparators are:
= is equal to
# (or \= or <>) is not equal to
< is less than
<= is less than or equal to
> is greater than
>= is greater than or equal to
== refers to the same variable as
## (or \==) does not refer to the same variable as
In the case of the last two comparators, == and ##, the items being
compared are references to variables, which must be of identical type.
The condition is true if the addresses of the variables referred to are
equal (==) or not equal (##). (Note that the address of a reference
variable is the address of the variable to which it refers: see Section
6.1.2)
{EMAS IMP80: the == and ## comparators cannot be used to compare
references to arrays.}
The other forms of simple condition are as follows:
a) <expression> <comparator> <expression> <comparator> <expression>
This is known as a double-sided condition.
Example:
A+B <= C+D < E+F
This condition is true if A+B <= C+D and C+D < E+F .
The third expression is only evaluated if the condition between the
first two expressions is true.
The comparators == and ## (or \==) may not be used in double-sided
conditions.
b) String resolution
Example:
A -> B.(C).D
The resolution is attempted. If it succeeds the condition is true AND
the resolution is performed. If it fails the condition is false, but
no event is signalled.
c) Compound condition (see below) enclosed in brackets
Example:
(A>0 %or B<=0)
d) Any of the above forms preceded by the keyword %not
The effect of preceding a simple condition with %not is to reverse the
truth value of the condition.
Examples:
%not A <= 0 (equivalent to A > 0)
%not 23 <= I+J <= 99
Compound conditions can be produced by combining simple conditions using
the keywords %and and %or:
<simple condition> %and <simple condition> %and ....
<simple condition> %or <simple condition> %or ......
Examples:
A+B <= C+D %and C+D < E+F
I = 20 %or A -> B.("..").C %or X > Y >= Z+3.47
It is not valid to combine %and and %or, as in
X < Y %and B = C %or D = 24
However a compound condition enclosed in brackets is treated as a form
of simple condition (see above). Thus
(X < Y %and B = C) %or D = 24
is valid. Note that the form
%not (X < Y %and B = C)
is also permitted.
By combining %and and %or and brackets, conditions of arbitrary
complexity can be produced:
Example:
(A <= B %or C == D) %and S -> ("Jim").T %and %c
(X <= Y <= Z %or (P_K = 23 %and Q < 0))
The testing of conditions proceeds from left to right, simple condition
by simple condition, terminating any clause as soon as an inevitable
outcome for the clause has been established. Thus, in the example
above, if A <= B were true then C == D would not be evaluated; if A <= B
were false and C == D were false then the remainder of the condition
would not be evaluated.
Example:
A = 0 %or B/A = C
If the variable A has the value 0 the whole condition will be true
without B/A = C being tested.
B/A = C %or A = 0
In this case an event will be signalled ("overflow") if variable A has
the value 0.
Instructions
KEY
An <instruction> is an imperative statement which may be made
conditional. The following IMP80 statement types are instructions:
statement described in
assignment Section 2
routine call Section 3.2
%monitor Section 4.2.4
%signal %event Section 3.1
%return Section 3.2
%result= Section 3.2
jump Section 4.2.1
%stop Section 4.2.3
%exit Section 4.4.3
%continue Section 4.4.3
In addition, a <compound instruction> can be formed by use of the
keyword %and:
<instruction> %and <instruction> %and ......
Example:
X = 23 %and %continue
The last of the series of instructions in a compound instruction can be
any of those listed above; the other component instructions can only be
assignments, routine calls or %monitor statements.
Conditional instructions
KEY
Instructions without conditions are called unconditional. An
unconditional instruction can be made conditional as follows:
%if <condition> %then <unconditional instruction>
or
%unless <condition> %then <unconditional instruction>
In the first form, the instruction is executed if the condition is
true; in the second, the instruction is not executed if the condition
is true. If the instruction is not executed, nothing is done.
Examples:
%if 0 < I <= 9 %and K > 0 %then B(I) = K
%unless J = I %then A(I,J) = 0
%if and %unless statements can be elaborated to allow specification of
an alternative instruction, to be executed if the first one is not:
%if <condition> %then <unconditional instr> %else <instr>
%unless <condition> %then <unconditional instr> %else <instr>
Example:
%if X < 47.2 %then Y = Z+3 %else Y = 0.0
Note that the first instruction in these elaborated %if and %unless
statements must be unconditional but the second instruction can be
conditional.
Example:
%if STATE < 0 %then ERROR = IN %else %c
%if STATE = 0 %then ERROR = CALCULATION %else ERROR = OUT
The simple forms of %if and %unless statements (i.e. those without the
%else) can be made simpler still:
<unconditional instruction> %if <condition>
<unconditional instruction> %unless <condition>
Examples:
B(I) = K %if 0 <= I <= 9 %and K>0
A(I,J) = 0 %unless J = I
Labels and jumps
KEY
Any statement, excluding declarations, may be given one or more
labels. A label is an identifier but it is not declared; however, it
does have to be distinct from other local identifiers.
{EMAS IMP80: labels do not have to be distinct from other
identifiers.}
Each label is located immediately to the left of the statement to
which it refers, followed by a colon.
Examples:
NEXT: P = P+1 %if P < 0
ERR1: ERR2: FAULTS = FAULTS+1
Control is passed to a labelled statement when a jump instruction of
the form
-> <label>
is executed.
Examples:
->NEXT
%if DIVISOR = 0 %then ->ERR1
As indicated, jump instructions can be made conditional (as can all
instructions).
Switches
KEY
A set of labels, known as a switch, may be declared in a manner
similar to a one-dimensional array, but using the keyword %switch.
The switch must have bounds which can be determined at compile-time
(i.e. constants, or expressions comprising constants and variables of
type %constant).
Examples:
%switch TYPE(4:9)
%switch S1, S2(1:10), S3('A':'Z')
Once declared, switch labels may be located in the same way as simple
labels, the particular label of the switch being specified by an
integer constant.
Example:
%switch SW(4:9)
%constant %integer FAULTY = 6
:
:
SW(4): CHECK VALUE(1)
:
SW(FAULTY): ERROR FLAG = 1
:
:
LAST: SW(9): ! All finished.
:
Control is passed to a statement labelled by a switch label when a
jump instruction of the form
-> <switch> ( <integer expression> )
is executed.
Not all of the labels in the switch need be located; in the example
above SW(5), SW(7) and SW(8) are not, and do not need to be elsewhere
in the program. An event is signalled if an attempt is made to jump
to an undefined switch label.
Instead of an integer constant, an asterisk (*) may be used when
locating a switch label. This has the effect of defining any labels
in the switch not defined elsewhere in the program block.
Example:
%switch LET('a':'z')
:
:
LET('a'):LET('e'):LET('i'):LET('o'):LET('u'):
! Deal with vowels here.
:
:
LET(*): ! All the rest, i.e. consonants
:
Notes
* A label can appear on a line without being followed by a statement.
This is sometimes done to improve readability. Strictly, the label
is labelling a null statement.
Example:
LAST STAGE:
%if Y < 23.7 %and ....
* The use of both types of label is limited to the block in which
they are defined, excluding any blocks described therein. That is,
labels cannot be global to a block and therefore it is not possible
to jump into or out of a block.
* The identifiers used for labels must be distinct from other local
identifiers.
{EMAS IMP80: labels do not have to be distinct.}
* The effect of jumping into a %for loop (see Section 4.4) is
undefined.
%stop
KEY
This instruction causes the execution of the program to be terminated.
{IMP77: %stop is event 0 and can therefore be trapped.}
%monitor
KEY
This instruction passes control to a run-time diagnostic package which
then generates a trace of the state of the program. In
implementations of IMP80 without a run-time diagnostic package
%monitor is a null instruction. In some implementations the amount of
trace information can be controlled by the programmer.
Following the trace the program resumes at the point where it left
off.
%start/%finish
KEY
%start/%finish statements are used to make the execution of a group of
statements conditional. The most general type of conditional group is a
sequence of statements of the form:
%if <condition 1> %then %start
statements to be executed if <condition 1> is true
%finish %else %if <condition 2> %then %start
statements to be executed if <condition 1> is false
and <condition 2> is true
%finish %else %if <condition 3> %then %start
:
:
%finish %else %start
statements to be executed if all the previous
conditions are false
%finish
Notes
* "%if ... %start" and "%finish %else ... %start" are complete
statements in their own right and as such must be terminated by a
newline or semicolon.
* Each %start and the next %finish effectively bracket the statements
between them, which are all controlled by the same set of conditions.
* Any or all of the statements containing the keyword %else may be
omitted. When they are all omitted, the form becomes:
%if <condition 1> %then %start
statements to be executed if
<condition 1> is true
%finish
* Other simple forms:
a) %if <condition 1> %then %start
statements to be executed if
<condition 1> is true
%finish %else %start
statements to be executed if
<condition 1> is false
%finish
b) %if <condition 1> %then %start
statements to be executed if
<condition 1> is true
%finish %else %if <condition 2> %then %start
statements to be executed if
<condition 1> is false and
<condition 2> is true
%finish
* %start/%finish groups may be nested to any depth.
* %then %start may be elided into %start.
* If a %start and the next %finish enclose only one instruction then the
complete %start...%finish sequence can be replaced by that
instruction.
Example:
:
%else %if K = 0 %then %start
X = 4*SQRT(Y**2 + Z**2 - 4)
%finish %else %start
:
can be given as
:
%else %if K = 0 %then X=4*SQRT(Y**2 + Z**2 - 4) %else %start
:
* The keyword %if may always be replaced by %unless, with the effect of
negating the subsequent condition. Thus the following two statements
are equivalent:
%if X = 0 %then Y = 1 %else Z = -1
%unless X = 0 %then Z = -1 %else Y = 1
* Where a small group of unconditional instructions is to be made
conditional, a compound instruction (Section 4.2) can be used instead
of a %start/%finish construction.
Example:
%if K<0 %then X = 4 %and %return
is equivalent to
%if K<0 %start
X = 4; %return
%finish
%cycle/%repeat
KEY
%cycle and %repeat statements are used to bracket statements which are
to be repeated. In the simplest case, a group of statements may be
repeated indefinitely by enclosing them between the statements %cycle
and %repeat.
Example:
%cycle
READ DATA; ! Get next set of data
PROCESS DATA; ! Carry out calculation
OUTPUT DATA; ! Print results
%repeat
The statements between a %cycle statement and the corresponding %repeat
statement are known as the cycle body. %cycle/%repeat groups can be
nested to any depth, i.e. a cycle body can contain further
%cycle/%repeat groups.
Conditional repetition
KEY
The number of times the cycle body is executed can be controlled by
modifying the %cycle statement or the %repeat statement.
a) %while <condition> %cycle
:
:
%repeat
The specified condition is tested before each execution of the
cycle body. If the condition is true the cycle body is executed;
otherwise control is passed to the statement following the matching
%repeat.
The cycle body will be executed zero or more times.
b) %for <control variable> = <init> , <inc> , <final> %cycle
:
:
%repeat
where <control variable> is a variable of type %integer, and
<init>, <inc> and <final> are all integer expressions.
This is a special form of %while...%cycle, in which an integer
variable takes a series of regularly spaced values in a specified
range. Each value corresponds to an execution of the cycle body.
Example:
%for I = 1,1,10 %cycle
A(I) = I+1
B(I) = 0
%repeat
The cycle body is executed 10 times, the control variable (I)
taking the values 1, 2, 3, ..., 9, 10 in succession.
In detail, the execution of a %for loop entails the following
stages. A test is first made that <inc> is non-zero and that
(<final> - <init>) is exactly divisible by <inc>. An event is
signalled if it is not. This test may be carried out at
compile-time, if the three expressions permit; a compile-time fault
may then be given.
If the test is successful, the total number of times that the cycle
body could be executed is calculated; this is
((<final> - <init>) // <inc>) + 1.
{EMAS IMP80: if this number is less than or equal to zero, the
control variable is set to be unassigned and control is passed to
the statement following the matching %repeat. Otherwise the
control variable is assigned the value of <init> and the cycle body
is executed. When the matching %repeat is reached the value of the
control variable is tested, and if it is equal to <final>, control
is passed to the statement following the %repeat. Otherwise the
control variable has <inc> added to its value and the cycle body is
executed again.}
{IMP77: an event is signalled if the total number of times that the
cycle body could be executed is less than 0. Otherwise the control
variable is assigned the value <init> - <inc>. Before each
execution of the cycle body the value of the control variable is
compared with <final>. If they are equal control is passed to the
statement following the matching %repeat; otherwise <inc> is added
to the control variable and the cycle body is executed. It follows
that if the cycle execution is terminated by means of this test,
the control variable will thereafter be equal to <final> in all
cases.}
It follows that the cycle body will be executed zero or more times.
Notes
* <inc> can be negative.
* The control variable must be of type %integer - a byte integer
or long integer etc. is not allowed.
* The effect of jumping into a %for loop is undefined.
* The effect of changing the value of the control variable within
the cycle body is undefined.
* The three expressions <init>, <inc> and <final> are evaluated
once only, before the cycle body is executed. It is
permissible, within the cycle body, to change the value of any
variable appearing in one of these expressions, but it has no
effect on the execution of the %for loop.
c) %cycle
:
:
%repeat %until <condition>
After each execution of the cycle body the condition is tested. If
false the cycle body is executed again.
%until loops always execute the cycle body at least once (cf.
%while loops).
{IMP77:
d) Any of the statements described above containing the keyword
%cycle can be matched with any of the statements containing the
keyword %repeat.
Example:
%while I<=100 %cycle
:
:
%repeat %until J=4
The cycle-termination test implied by each statement is made when
the statement is executed.}
Simple forms of loop
KEY
If the cycle body comprises only one instruction (which can be a
compound instruction), the loop may be written in the form:
<instruction> <loop clause>
i.e.
<instruction> %while <condition>
<instruction> %for <control> = <init>, <inc>, <final>
<instruction> %until <condition>
Examples:
SKIPSYMBOL %and SP = SP+1 %while NEXTSYMBOL = ' '
A(J) = 0 %for J = 1,1,20
READSYMBOL(S) %until S = NL
%exit and %continue
KEY
Two instructions are provided to control the execution of a cycle from
within the cycle body.
a) %exit
This instruction causes execution of the cycle to be terminated.
Control is passed to the statement following the matching %repeat.
b) %continue
This instruction causes control to be passed to the matching
%repeat. The effect is thus to terminate this execution of the
cycle body, but not of the complete cycle.
Notes
* %exit and %continue can only be used within %cycle/%repeat loops.
* %exit and %continue are instructions, and can thus be made
conditional.
Examples:
%continue %if P_J = 0
X = 5 %and %exit %if CPU TIME > 50
* Within nested loops, %continue and %exit operate with respect to
the innermost loop in which they are contained; i.e. control is
passed to the next %repeat or to the statement following it,
respectively.