Home
Up
Intro
Contents
Chapter
1
2
3
4
5
6
7
8
9
10
Design
Assert
Timing
EBNF
Report
Pas
Last Changed: July 12th, 1997
This is a conversion from Oberon text to HTML, and from German to English. The converter software is still under development,
and some features or information may be missing in this converted version.
HTML hypertext facilities are not yet active in this document.
To exploit the interactive facilities, use Oberon System 3 and the source of this text,
available for download using binary ftp as Oberon System 3 archive.
The converter from German to English is still under development as well.
A previous version is also available for Oberon V4.
To access this and other additional material use
ftp.
For the convenience of our students, most of this information and the related material is available
in German as well.
Introduction to Oberon
The Oberon Programming Language
06 Control Structures
Like in most programming languages, the actual program is described as a
sequence of instructions in Oberon. We already met these instruction sequences
in the body section of a module, as well as in procedure declarations. The
examples we have seen up to now were strictly sequential: the statements
were executed in exactly the order in which they are given.
Only few problems can be solved in a strictly sequential way. Among others,
for a problem to allow a strictly sequential solution, there must be an algorithm
which leads to the required solution in a fixed (a priori given) number of
steps. Even elementary problems, like for example writing a decimal expression
for a rational number, do not fall into this class. We need a possibility
of controlling an algorithm in a way which might dependent on intermediate
results. Thus besides the linear sequential structure in which a program
is written down, we will have another structure, or a group of structures,
called control structures.
In Oberon there are two elementary control structures: the IF statement and
the LOOP statement. The IF statement only executes a statement sequence if
a controlling logical expression is true. The LOOP statement repeatedly executes
a series of instructions.
The formal syntax of the elementary control structure in Oberon is:
Elementary IF Statement:
IF expression
THEN
statement
sequence
END
LOOP Statement:
LOOP
statement
sequence
END
The interpretation of the IF statement is immediate. Expression
can be any expression which evaluates to one of the logical values, TRUE
or FALSE. The meaning corresponds to what the English-language formulation
suggest. The statement sequence in the IF statement is executed if the expression
evalutates as TRUE. If the expression yields FALSE, the statement sequence
is not executed.
Example
IF ( i MOD 3)
= 0 THEN
Texts.WriteString(W,"i
is divisible by 3.")
END;
The interpretation of the LOOP statement is more delicate. The statement
sequence in the LOOP statement is executed repeatedly. This is a rather exceptional
situation. The operating system is one of these rare exceptions. In principle
it reduces to a LOOP statement of the following form:
LOOP
... (* identify next command *)
... (* execute command *)
END
In most cases however a statement sequence should not repeat indefinitely
for all times, but only until some controlled condition is satisfied: there
must be a way to terminate a LOOP statement. This leads to a set of specializations
which we will discuss later in this section.
All control structures can be used exactly the same way as individual statements
can. In formal definitions of the language they are but special cases of
the general class of statements. If it is necessary to point out their more
complex internal structure out, they are called structured statements. Languages
with structured statements are called structured programming languages.
Both elementary control structures come with various versions. These versions
could be expressed logically as statement sequences using the elementary
control structures. Because they are used very frequently, they are defined
as language constituents. We look at the IF statement first, and return to
the LOOP statement later.
The IF statement may have an alternative. Example:
IF ( i MOD 3)
= 0 THEN
Texts.WriteString(W,"i
is divisible by 3.")
ELSE
Texts.WriteString(W,"i
is not divisible by 3.")
END;
IF statements can form a "cascade". Cascades can be used with or without
alternative. Example:
IF length >=
1000 THEN
Texts.WriteReal(W,length/1000,6);
Texts.WriteString(W,"km.")
ELSEIF length >= 1 THEN
Texts.WriteReaFixl(W,length,6,2);
Texts.WriteString(W,"m.")
ELSE
Texts.WriteRealFix(W,length*100,6,2);
Texts.WriteString(W,"cm.")
END;
The complete syntax is
IF Statement:
IF expression
THEN
statement
sequence
{ELSIF
expression THEN
statement
sequence}
[ELSE statement
sequence]
END
For the special case that a list of cases needs to be handled which
one could write as list of integral or CHAR values, there is a special CASE
statement. The "cases" in this CASE statement must be constant expressions,
i.e. their values must be determined at compiling time. While for in an IF
statement the expressions are evaluated in the given order, for a CASE statement
the evaluation and the analysis of the decision takes place only once at
entrance of the CASE statement.
CASE Statement:
CASE
expression OF
case
{ |
case
}
[ELSE statement
sequence]
END
where
Case:
Case list : statement sequence
Case List:
Case label
{, Case label}
Case Label:
Case expression
[.. Case expression]
Example:
CASE ch OF
"A".."Z": Texts.WriteString(W,"letter
(upper case)")
| "a".."z": Texts.WriteString(W,""letter
(lower case)")
| "0".."9": Texts.WriteString(W,"digit")
| ".",
",", ":", "?", "!": Texts.WriteString(W,"mark")
ELSE Texts.WriteString(W,"something
else")
END
The LOOP statement is only left by an EXIT
statement in the statement sequence. The statement EXIT leaves the containing
LOOP statement. Processing is continued with the next statement following
the LOOP statement.
Example:
LOOP
... (* any statement sequence,
for example a calculation with I *)
IF I>IMAX OR I<IMIN THEN EXIT;
... (* any statement sequence,
for example a calculation with I *)
END
In principle the inner core of Oberon is just one LOOP statement. A simplified
picture is:
LOOP
... identify
(* next command *)
IF... (* command
= System.Quit *) THEN EXIT END;
... (* otherwise:
execute command *)
END
The LOOP construct is inherently dangerous: the programmer has to guarantee
that the LOOP construct will leave correctly. The LOOP is left by EXIT. But
execution is not continued after the EXIT statement, but after the end of
the appropriate LOOP statement: Non-local knowledge of the program structure
is necessary in order to be able to interpret the control flow. Even harmless
looking LOOP construct can be insidious. Example:
LOOP
IF X=1 THEN EXIT
ELSIF X MOD
2 = 0 THEN X:=X DIV 2 ELSE X: = TO X*3+1 END;
END;
Try to find out whether this program fragment will leave for an arbitrary
integral value of X. Do not be disappointed, if you did not find the solution
by next morning.
For the LOOP statement there are these variants:
REPEAT Statement:
REPEAT
statement
sequence
UNTIL expression
;
The statement sequence in the REPEAT statement is executed and repeated until
the expression yields TRUE.
WHILE Statement:
WHILE
expression
DO
statement
sequence
END
The REPEAT statement sequence is at least executed once. After
execution of the statement sequence the expression is checked, and the repear
statement sequence is repeated unless the expression yields TRUE. For a WHILE
statement the expression is evaluated first. Only if the expression has the
value TRUE the statement sequence is executed and repeated, until the expression
is FALSE. If the expression yields FALSE at start, the statement sequence
is not executed at all.
Exercises:
Let i,k be integer variables and k=0. What is the meaning of
k:=0;
WHILE i > 0 DO i := i DIV 2; k
:= k + 1 END
Give a LOOP statement, which is equivalent to this WHILE statement.
What is the meaning of this REPEAT statement?
k:=0; REPEAT
i := i DIV 2; k := k + 1 UNTIL i<=0
(Hint: Discuss the cases i>0, i=0, i<0 one
by one).
An additional loop construction, used commonly in other languages,
is
FOR Statement:
FOR name
:=expression TO expression
[BY constant expression] DO
statement
sequence
END
The statement
FOR v := beg
TO end BY step DO statements END
is equivalent to
temp := end; v := beg;
IF step > 0 THEN
WHILE v <= temp DO statements;
v := v + step END
ELSE
WHILE v >= temp DO statements;
v := v + step END
END
The FOR statement is used when a statement sequence is to be executed for
a successive set of values of some variable. Name
must be a variable of integer type. Its value is set on that of the first
expression and with each turn it is changed by the the increment const
expression, as long as the second expression is not exceeded.
The constant expression must have the same type as the variable. It may not
have the value 0. If no increment is given, then the increment 1 is taken.
Exercises:
Which output is produced by the following FOR
statements:
a) FOR I:= 1
TO 10 DO Texts.WriteInt(W,I,20) END
b) FOR I:= 8 TO 8 DO Texts.WriteInt(W,I,20)
END
c) FOR I:= 10 TO 0 DO Texts.WriteInt(W,I,20)
END
d) FOR I:= 5 TO 0 BY -1 DO Texts.WriteInt(W,I,20)
END
e) FOR I:= 5 TO 0 BY -2 DO Texts.WriteInt(W,I,20)
END
f) FOR I:= 5 TO 10 BY -5 DO Texts.WriteInt(W,I,20)
END
The FOR statement makes some iteration constructs simpler. It should
however be used only in trivial situations. In critical situations its meaning
is not always obvious. E.g. what is the meaning of the following ( formally
admissible) statement:
...
FOR I:= I-11 TO I+1 DO ... END
Exercises:
1.) Calculate and tabulate n! for n=0... 10.
2.) Calculate and tabulate n! as far as n! can be represented as number of
the type INTEGER resp. LONGINT.
3.) Tabulate n for k=1,2... the value of min {: n! >
= 2k} as far as possible.
4.) A linear congruence generator is a pseudo-random number generator which
generates numbers following the rule
x - > (ax + b) MOD
m.
a) Write a program that generates
pseudo-random numbers for constants of a, b, m and write n of the generated
numbers. Try different constants. How do you select an initial value?
b) If necessary, check and modify
your program in such a way that it works correctly for all a, x, b, m: MAX(LONGINT)>=a,
x>0, MAX(LONGINT) > =b>=0.
Generate 1000 pseudo-random numbers each with the following generators:
(Lewis, Goodman, Miller ) a=75=16807,
b=0, m=231-1
(Payne, Rebung, Bogyo) a=630360016,
b=0, m=231-1
(UNIX rand) a=1103515245,
b=12345, m=231
[Literature: B.D. Ripley,
Computer Generation of Random Variables: A Tutorial. International Statistical
Review 51 (1983) 301-319;
see also Reiser&Wirth, Ch.2]
5.) Take the time to generate 10, 100, 1000, 10000, 100000 random numbers.
Use the program fragment Test2 in ItO/ItOTime06.Mod. Which measurements
are below time measurement resolution? How reliable are the measured values?
The pre-defined procedure HALT allows
to break all current control structures and of leaving a process. HALT is
called as HALT(status), where status is a
value which is returned to the global environment. In a sense, HALT is an
ultimate exit. Oberon modules are resident,s even after a HALT abort. The
module remains loaded, and on all exported variables can be accessed even
after the abort. The handling of HALT is implementation dependent. Usually
the control is transferred to the Oberon module, and Oberon would open a
window with a diagnostic message.
Control statements play different roles in different stages of program development.
Besides control statements directing the intended program flow, there may
be implementation dependent additional control statements to support error
handling. The most important of these is the ASSERT
statement. It called as ASSERT(condition,status).
The meaning is equivalent to
IF condition
THEN HALT(status) END;
In contrast to the IF construct, the implementation is controlled
by the compiler. Usually there is a compiler option which permits to swich
off or on any code generation for ASSERTs. With the appropriate option set
on, ASSERT statements are generated and the appropriate checks are executed.
Without this option set to off, no ASSERT code is generated. Since the ASSERT
statements are administered by the compiler it offer a possibility for code
analysis and diagnostics. The use of ASSERTs and further checks is discussed
in a special chapter.
Different compilers offer specific possibilities for diagnostics and program
checkin. These options are documented in the respective compiler documents.
Exercises:
Which control and test options are offered by your compiler? For system 3
you find more information in
Compiler.Tool
Introduction to the Oberon programming language. ItO/Ch06.Text
gs (c) G. Sawitzki, StatLab Heidelberg
<http://statlab.uni-heidelberg.de/projects/oberon/intro/>
Home
Up
Intro
Contents
Chapter
1
2
3
4
5
6
7
8
9
10
Design
Assert
Timing
EBNF
Report
Pas