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.