Copy Link
Add to Bookmark
Report

Chapter 4 - Modula-2 Loops and Control Structures

eZine's profile picture
Published in 
Modula2
 · 30 Jan 2023

Loops are some of the most important and most used constructs in computer programming and in all parts of your life. You use loops all the time for many things. Walking is a repetition of putting one foot in front of the other until you get where you are going. Eating a sandwich involves a loop of eating, chewing, swallowing, etc. In this chapter we will first cover all of the possible loops you can define in Modula-2, then go on to the control structures, the decision makers.

Load and display the program LOOPDEMO.MOD.

LOOPDEMO.MOD 

(* Chapter 4 - Program 1 *)
MODULE LoopDemo;

FROM InOut IMPORT WriteString, WriteInt, WriteLn, Write;

CONST Where = 11;

VAR Index : INTEGER;
What : INTEGER;
Letter : CHAR;

BEGIN

WriteString("REPEAT loop = ");
Index := 0;
REPEAT
Index := Index + 1;
WriteInt(Index,5);
UNTIL Index = 5; (* This can be any BOOLEAN expression *)
WriteLn;

WriteString("WHILE loop = ");
Index := 0;
WHILE Index < 5 DO (* This can be any BOOLEAN expression *)
Index := Index + 1;
WriteInt(Index,5);
END;
WriteLn;

WriteString("First FOR loop = ");
FOR Index := 1 TO 5 DO
WriteInt(Index,5);
END;
WriteLn;

WriteString("Second FOR loop = ");
FOR Index := 5 TO 25 BY 4 DO
WriteInt(Index,5);
END;
WriteLn;

(* Note - The four loops above could use a CARDINAL type variable
in place of the INTEGER type variable Index. The next 2
examples must use an INTEGER type variable because it
must be capable of storing a negative value. *)

WriteString("Third FOR loop = ");
FOR Index := 5 TO -35 BY -7 DO
WriteInt(Index,5);
END;
WriteLn;

What := 16;
FOR Index := (What - 21) TO (What * 2) BY Where DO
WriteString("Fourth FOR loop = ");
WriteInt(Index,5);
WriteLn;
END;

(* Note - The next two loops are demonstrations of using a CHAR
type variable to index a FOR loop. *)

FOR Letter := "A" TO 'Z' DO
Write(Letter);
END;
WriteLn;

FOR Letter := 'z' TO 'a' BY -1 DO
Write(Letter);
END;
WriteLn;

(* Note - The following loop contains an EXIT which is a way to get
out of the loop in the middle. *)

Index := 1;
LOOP
WriteString("In the EXIT loop ");
WriteInt(Index,5);
IF Index = 5 THEN
WriteLn;
EXIT;
END;
WriteString(" We are still in the loop.");
WriteLn;
Index := Index + 1;
END;

END LoopDemo.

This is a rather large program compared to the ones we have seen so far, but I felt it would be better to cover all of the loops in one file than have you compile and run 4 different files.

REPEAT ... UNTIL LOOP

Ignoring the declaration part of the listing and going straight to the program itself, we first come to the REPEAT loop which does just what it says it will do. It will repeat until it is told to stop. The REPEAT in line 16 and the UNTIL go together, and everything between them will be executed until the condition following the UNTIL becomes TRUE. The condition can be any expression that will evaluate to a BOOLEAN answer, TRUE or FALSE. It can even be a composite expression with AND's, OR's, and NOT's like we studied in the last chapter. It can be composed of any of the simple types discussed so far as long as the terms are all compatible and it evaluates to a BOOLEAN value. In this case we have a very simple expression, "Index = 5". Since "Index" is initialized to 0 and is incremented each time we go through the loop, it will eventually reach a value of 5 and the loop will terminate, after which time the expressions following it will be executed.

We are not quite finished with the REPEAT loop yet, we will have more to say about it when we complete the WHILE loop.

WHILE LOOP

The WHILE loop is very much like the REPEAT loop except that the condition is tested at the beginning of the loop and when the condition becomes FALSE, the loop is terminated. Once again, the condition can be as complex as desired but in this case it is the very simple "Index < 5". When Index reaches 5, the loop is terminated and the statements following the loop are executed.

The biggest difference between the REPEAT and the WHILE loops is concerned with when the test is made. In the WHILE loop, the test is made at the beginning, so it is possible that the statements inside the loop will not be executed even once. In the REPEAT loop, the test is made at the end of the loop, so the statements in the loop will always be executed at least once. It is also good to keep in mind that the REPEAT stops when its condition goes TRUE, and the WHILE stops when its condition goes FALSE.

There is another loop that we can use in which we exit from the center using any test we can devise. It will be covered after we complete the FOR loop.

THE FOR LOOP

The FOR loop exists in one form or another in nearly every programming language and you will use it repeatedly because it is so useful. It uses the reserved words FOR, TO, BY, DO, and END. It uses any simple variable type except REAL, and counts loops depending on what counts you put in for beginning and ending points. The first example on line 31 says for the computer to start "Index" at 1 and count to 5, going through the loop once for each value of "Index". The count advances by 1 each time because nothing else is specified and 1 is the default. The end of the loop is specified by the reserved word END, and as many statements as desired can be within the body of the loop.

The next loop starts in line 37 and this time counts from 5 to 25 but incrementing by 4 each time because of the "BY 4" part of the line. The loop will continue until the second limit is going to be exceeded, at which time the loop will stop. The beginning and ending limits can themselves be some kind of a calculated value or a constant, the only provision being that they must be of the same type as the loop indexing variable. In fact they can be negative and the increment value can be negative. This is illustrated in the next loop that starts in line 48 where we count by -7 until we go from 5 to -35. No further explanation should be required for this loop.

The next loop, starting in line 54, uses calculated limits to determine its starting and ending points and it uses the name "Where" for its incrementing value. The value of "Where" is established in the definition part of this program as a constant. It is simply used here and will be explained in a future lesson when we get to it. "Where" is a constant with a value of 11, and the incrementing value must always be a constant.

The next two FOR loops use a CHAR type variable and simply "count" from "A" to "Z", or backwards in the case of the second one.

Several things should be pointed out about the FOR loop for you. The three values must agree in type, that is the index, the starting point, and the ending point. The index must not be changed by any logic within the loop or the results will be unpredictable. The value of the index must be assumed to be undefined after the loop terminates. You may discover that it is predictable on your compiler, but it may not be on some other compiler, and you may want to transfer your program to another system someday.

THE INFINITE LOOP

The fourth and final loop is an infinite loop, it never terminates by itself. It is up to you the programmer to see to it that some means of terminating it is available, the most usual is through use of the EXIT statement. Anyplace in the loop you can set up some conditions for exiting based on whatever you desire. Executing the EXIT procedure will cause the program control to leave the loop and begin executing the statements following the loop.

Now you have been exposed to the four loops available in Modula-2, the REPEAT, WHILE, FOR, and LOOP. Spend some time studying this program, then compile and run it to see if it does what you expect it to do. Loops are very important. You will do the vast majority of your logical control in loops and IF statements.

WHAT IS AN IF STATEMENT?

Load the program IFDEMO.MOD and display it on your monitor for an example of some IF statements.

IFDEMO.MOD 

(* Chapter 4 - Program 2 *)
MODULE IfDemo;

FROM InOut IMPORT WriteString, WriteInt, WriteLn;

VAR Index1 : INTEGER;

BEGIN

FOR Index1 := 1 TO 8 DO
IF Index1 < 4 THEN (* Simple IF statement *)
WriteString("Index1 is less than 4.");
WriteInt(Index1,4);
WriteLn;
END; (* end of first IF statement *)

IF Index1 = 5 THEN (* two way IF statement *)
WriteString("Index1 is 5");
ELSE
WriteString("Index1 is not 5");
END; (* end of second IF statement *)
WriteLn;

IF Index1 = 2 THEN (* multiple way IF statement *)
WriteString("Index1 is 2");
ELSIF Index1 = 6 THEN
WriteString("Index1 is 6");
ELSE
WriteString("I really don't care what Index1 is");
END; (* end of third IF statement *)
WriteLn;
END; (* of big FOR loop *)

END IfDemo.

Ignoring the header we notice that the program is composed of one big loop in order to have some changing variables. Within the loop are 3 IF statements, the most used conditional statement in Modula-2.

The first IF statement is given in line 11. It simply says "if the value of Index1 is less than 4, then" do everything from the reserved word THEN to the reserved word END which is associated with it. If the value of Index1 is not less than 4, then all of these statements are ignored and the next statement to be executed will be the one following the reserved word END. In a nutshell, that is all there is to the simple IF statement. Once again, the condition can be any expression that will evaluate to a BOOLEAN result, and it can be composed of any of the simple types of data elements.

THE "ELSE" CLAUSE

The second IF statement, beginning in line 17 has an added feature, the ELSE clause. If the BOOLEAN expression does not evaluate to TRUE, then instead of the expressions following the THEN being executed, the group following the ELSE will be. Thus, if it is TRUE, everything from the THEN to the ELSE is executed, but if it is FALSE, everything from the ELSE to the END is executed. The END statement is therefore the terminator for the effect of the IF statement.

WHAT CAN GO IN THE IF STATEMENTS?

You may be wondering what is allowed to go into the group of executable statements between the THEN and the ELSE or some other place. The answer is, anything you want to put there. You can put other IF statements, loops, input or output statements, calculations, just about anything. If you indent the statements properly, you will even be able to read and understand what you put in there and why you put it there. Of course, if you put a loop in there, for example, you can put other constructs within the loop including other IF statements, etc. Thus you can go as far as you desire in building up a program.

THE ELSIF CLAUSE

The third and last kind of IF statement is given in the third example starting on line 24. In this case, if the expression within the IF statement is found to be FALSE, the statements following the THEN are skipped and the next construct is found, the ELSIF. If program control comes here, it has a further expression to evaluate, which if TRUE, will cause the statements immediately following its THEN to be executed. If this expression is found to be FALSE, the statements following the ELSE will be executed. The net result is that, one and only one of the 3 groups of instructions will be executed each time through the loop. It is permissible to add as many ELSIF cases as desired to this construct, leading to a "many way" branch. In addition, the ELSE is entirely optional regardless of whether or not the ELSIF's are used.

After studying this program, compile and run it and compare the results with what you expected.

LOOP's IN IF's IN LOOP's

Load and display the next example program LOOPIF.MOD for an example of some of the latest topics being combined.

LOOPIF.MOD 

(* Chapter 4 - Program 3 *)
MODULE LoopIf;

FROM InOut IMPORT WriteString, WriteInt, WriteLn;

VAR Index, Count, Dog : INTEGER;

BEGIN
FOR Index := 1 TO 10 DO
WriteString("Major loop");
WriteInt(Index,3);
IF Index < 7 THEN
FOR Count := 15 TO (15 + Index) DO
WriteString(' XXX');
END;
WriteLn;
ELSE
WriteString(' How many dogs?');
FOR Dog := 1 TO 10 - Index DO
WriteString(" too many");
END;
WriteLn;
END; (* ELSE part of IF statement *)

END (* Major FOR loop *)
END LoopIf.

This program makes nonsense data but is valuable because it is small enough to understand quickly to see how LOOP's and IF's can be nested together. The entire program is a FOR loop containing an IF statement. Each part of the IF statement has a loop nested within it. There is no reason why this process could not be continued if there were a need to. Study this program then compile and run it.

FINALLY, A MEANINGFUL PROGRAM

Load and display the program named TEMPCONV.MOD for your first look at a program that really does do something useful.

TEMPCONV.MOD 

(* Chapter 4 - Program 4 *)

(* This program is a good example of proper formatting, it is *)
(* easy to read and very easy to understand. It should be a *)
(* snap to update a program that is well written like this. You *)
(* should begin to develop good formatting practice early in *)
(* your programming career. *)

MODULE TempConv;

FROM InOut IMPORT WriteString, WriteInt, WriteLn;

VAR Count : INTEGER; (* a variable used for counting *)
Centigrade : INTEGER; (* the temperature in centigrade *)
Farenheit : INTEGER; (* the temperature in farenheit *)

BEGIN

WriteString("Farenheit to Centigrade temperature table");
WriteLn;
WriteLn;

FOR Count := -2 TO 12 DO
Centigrade := 10 * Count;
Farenheit := 32 + Centigrade *9 DIV 5;
WriteString(" C =");
WriteInt(Centigrade,5);
WriteString(" F =");
WriteInt(Farenheit,5);
IF Centigrade = 0 THEN
WriteString(" Freezing point of water");
END;
IF Centigrade = 100 THEN
WriteString(" Boiling point of water");
END;
WriteLn;
END; (* of main loop *)

END TempConv.

This is a program that generates a list of temperatures in centigrade, converts the list to farenheit, and displays the list along with a note in the table at the freezing point and boiling point of water. You should have no difficulty understanding this program, so the fine points will be left up to you.

A few comments on good formatting is in order at this point. Notice the temperature conversion program and how well it is formatted. It is simple to follow the flow of control, and the program itself needs no comments because of the judicious choice of variable names. The block header at the top of the page is a good example of how you should get used to defining your programs. A simple block header of that variety goes a long way toward making a program maintainable and useful later. Take notice also of the way the variables are each defined in a comment. A program as simple as this probably doesn't need this much attention, but it would be good for you to get into practice early. It would be good for you to think of each of your programs as a work of art and strive to make them look good.

After spending some time studying this program, compile and run it to see what it does. Load and study the next program named DUMBCONV.MOD to see if you can figure out what it does.

DUMBCONV.MOD 

(* Chapter 4 - Program 5 *)
MODULE DumbConv;
FROM InOut IMPORT WriteString, WriteInt, WriteLn;
VAR a, b, c : INTEGER;
BEGIN
WriteString("Farenheit to Centigrade temperature table");
WriteLn;
WriteLn;
FOR a := -2 TO 12 DO
b := 10 * a;
c := 32 + b *9 DIV 5;
WriteString(" C =");
WriteInt(b,5);
WriteString(" F =");
WriteInt(c,5);
IF b = 0 THEN
WriteString(" Freezing point of water");
END;
IF b = 100 THEN
WriteString(" Boiling point of water");
END;
WriteLn;
END; (* of main loop *)

END DumbConv.

If you are really sharp, you will see that it is the same program as the last one but without all of the extra effort to put it into a neat, easy to follow format. Compile and run this program and you will see that they both do the same thing. They are identical as far as the computer is concerned. But there is a world of difference in the way they can be understood by a human being.

THE CASE STATEMENT

Load and display the program named CASEDEMO.MOD for an example of the last decision making construct in Modula-2, the CASE statement.

CASEDEMO.MOD 

(* Chapter 4 - Program 6 *)
MODULE CaseDemo;

FROM InOut IMPORT WriteString, WriteInt, WriteLn;

VAR Dummy : INTEGER;

BEGIN

FOR Dummy := 1 TO 25 DO
WriteInt(Dummy,4);
WriteString(" ");
CASE Dummy OF
1..5 : WriteString("the number is small"); |
6..9 : WriteString("it is a little bigger"); |
10,11 : WriteString("it is 10 or 11"); |
14..17 : WriteString("it is midrange"); |
18,20,22,24 : WriteString("it is big and even"); |
19,21,23 : WriteString("it is big and odd");
ELSE
WriteString("The number didn't make the list");
END; (* of CASE *)
WriteLn;
END; (* of FOR loop *)

END CaseDemo.

A CASE statement is a "many-way" branch based on some simple variable. In this program we have a loop which sets the variable "Dummy" to the values from 1 to 25 successively. Each time it comes to the CASE statement, one of the branches is taken. The first branch is taken if the value is from 1 to 5, the second branch is taken if the value is from 6 to 9, the third is taken if it is either a 10 or 11, etc. Finally, if the value is not found in any of the branches, the ELSE path is taken as would be the case of a 12, a 13, or a few others. The important point is that one and only one of the many paths are taken each time the CASE construct is entered. The CASE variable can be any of the simple types except for the REAL type. For each path, as many statements can be executed as desired before the "|" is put in to end that path. The CASE statement is a powerful statement when you need it but you will not use it nearly as often as you will use the IF statement and the various loops.

PROGRAMMING EXERCISES

  1. Write a program that will put your name on the monitor10 times using a loop.
  2. Write a program that lists the numbers from 1 to 12 on the monitor and prints a special message beside the number that represents the month of your birthday.
  3. Write a program that calculates and lists the numbers from 1 to 8 along with the factorial of each. This will require use of a loop within a loop. A factorial is the number obtained by multiplying each number less than and up to the number in question. For example, factorial 4 = 1 * 2 * 3 * 4. Use a CARDINAL type variable for the result, then change it to an INTEGER to see the difference in output due to the range of the two different variable types. This is a good illustration of the fact that careful choice of variable type is sometimes very important.

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT