HiSoft Pascal Primer cover: a square, a triangle and a circle drawn and filled by a HiSoft Pascal program on the Tatung Einstein
← Back to Courses
module
10

Choices, Loops And Procedures

Introduction

IF, WHILE, REPEAT, FOR, procedures, functions and VAR parameters all work as they did in the Turbo course's S12 to S16. Three things do not: CASE is written differently, a line that starts with a number needs care in XBAS, and recursion - the thing Turbo made you ask for - works without being asked.

CASE

Turbo's case had an else for "anything else", and then an end. HiSoft's ELSE takes the place of the END:

CASE P OF
(**) 1:WRITE('LEFT');
(**) 2:WRITE('MIDDLE')
ELSE WRITE('RIGHT')

There is no END after the ELSE statement. Put one there, the Turbo way, and it is taken to close whatever BEGIN comes before the CASE - the compiler only complains a line or two later.

Without an ELSE, a CASE ends with END as usual, and a value that matches none of the labels does nothing at all.

A Line That Starts With A Number

Why the (**) in front of each label? Because of XBAS. When you type

60 1:WRITE('LEFT');

XBAS reads the line number as far as the digits go - spaces make no difference - and stores line 601, :WRITE('LEFT');. It happens to any line whose Pascal starts with a digit: CASE labels, and GOTO labels.

The cure is to put anything else first. (**) is an empty comment: HiSoft Pascal ignores it, and it keeps the number where it belongs. Or put the label at the end of the line before, after the statement it follows.

GOTO And FORWARD

Both are there. A GOTO label is declared with LABEL and marks a statement - so in XBAS it too wants (**) in front. A FORWARD procedure gives its parameters once, in the FORWARD declaration; the heading of the procedure itself, later, repeats only its name.

Recursion

The Turbo course's S16 had to warn you: without {$A-}, a routine that called itself shared its parameters between all its calls, and gave wrong answers without a word. HiSoft Pascal needs nothing. Every call has its own parameters, and a routine can call itself thousands of times deep. If it goes too deep, the program stops with Out of RAM at PC=... rather than going wrong.

One limit: a procedure or function cannot be passed as a parameter to another.

The Code

The Towers of Hanoi: move a pile of discs from the left peg to the right, one at a time, never a larger on a smaller. To move N discs, move N-1 out of the way, move the biggest, and move the N-1 back on top - a procedure that calls itself twice.

10 PROGRAM HANOI;
20 VAR MOVES:INTEGER;
30 PROCEDURE NAME(P:INTEGER);
40 BEGIN
50 CASE P OF
60 (**) 1:WRITE('LEFT');
70 (**) 2:WRITE('MIDDLE')
80 ELSE WRITE('RIGHT')
90 END;
100 PROCEDURE MOVE(N,FROM,DEST,SPARE:INTEGER);
110 BEGIN
120 IF N>0 THEN
130 BEGIN
140 MOVE(N-1,FROM,SPARE,DEST);
150 MOVES:=MOVES+1;
160 WRITE(MOVES:2,' ');
170 NAME(FROM); WRITE(' TO '); NAME(DEST);
180 WRITELN;
190 MOVE(N-1,SPARE,DEST,FROM)
200 END
210 END;
220 BEGIN
230 MOVES:=0;
240 MOVE(3,1,3,2)
250 END.

Line 90's END belongs to line 40's BEGIN: the CASE needs none.

Starting from

HANOI.ASC saved from XBAS; HPEIN HANOI.

What you should see

 1 LEFT TO RIGHT
 2 LEFT TO MIDDLE
 3 RIGHT TO MIDDLE
 4 LEFT TO RIGHT
 5 MIDDLE TO LEFT
 6 MIDDLE TO RIGHT
 7 LEFT TO RIGHT

Change One Thing

  • Change line 80 to 80 ELSE WRITE('RIGHT') END, the Turbo way. Where does the compiler complain, and why there?
  • Change line 240 to move four discs. How many moves does it take?
  • Put line 80 back, and replace it and line 70 with 70 (**) 2:WRITE('MIDDLE');, 80 (**) 3:WRITE('RIGHT') and a new 85 END. Does anything change in what it prints?

Exercises

10.1 Type line 60 without its (**), LIST the program, and explain what you see.

10.2 Write a recursive function that adds up the numbers from 1 to N, and print it for N = 100.

Worked solutions are in Appendix II.

When It Goes Wrong

SymptomCause
A line has a strange number like 601Its Pascal started with a digit. Put (**) in front.
*ERROR* a line or two after a CASEIt has both ELSE and END. The ELSE ends it.
Out of RAM at PC=...A routine called itself too deeply - usually one that never stops.

Summary

CASE ends with END or with ELSE and a statement - not both. In XBAS, a line whose Pascal starts with a number must have (**) or something else in front. GOTO and FORWARD are there. Recursion needs no option and works thousands of calls deep.

Next

S11, Types, Sets, Arrays And Records - the same building blocks, with stricter rules about which arrays go into which.

Get the Newsletter

New guides, disk images and community finds, roughly once a quarter. No spam, we promise, this isn't Tatung's marketing department.
Your subscription could not be saved. Please try again.
Your subscription has been successful.

Newsletter

Subscribe to our newsletter and stay updated.