A Pascal program that provides command-shell access to a queue is a straightforward application of the procedures of Chapter 5, as long as some of the realities of Pascal as a working language are respected. In particular, care must be taken with the distinction between value and variable parameters in procedures.
Input and output from a terminal must deal with end-of-line codes, and the dual use of the screen (or print paper) can affect program details. Standard programming techniques suffice, applied with a token-entry procedure that can acquire values for the insert and bound commands.
The command repertoire for a queue machine is:
I insert
D delete the front value
F display the front value
B set a bound for the number of items on the queue
C clear (empty) the queue
E exit (quit)
For the sake of robustness, miskeying of input is ignored if possible. For the sake of simplicity, errors of deletion from an empty queue and insertion into a full one only invoke mild reproof. Simplicity also dictates the replacement of function Front with procedure Display that writes an "empty queue" message when necessary.
PROGRAM QueueMachine(Input,Output);
TYPE ValueType = 0..99;
QueueType = ARRAY [1..99] OF INTEGER;
VAR ValueIn : ValueType;
Queue : QueueType;
Bound : ValueType;
Front : ValueType;
Rear : ValueType;
Op : CHAR;
{ }
PROCEDURE Preface;
BEGIN
Write('This program operates a queue with the');
Writeln('single-letter commands:');
Writeln('I - insert a value into the queue');
Writeln('D - delete the front value from the queue');
Writeln('F - display the front value of the queue');
Writeln('B - set the queue bound between 1 and 99');
Writeln('C - clear (empty) the queue');
Writeln('E - exit (quit)'); Writeln;
Writeln('Commands should be separated by spaces. B and I');
Write('are to be followed by an integer in the range 0');
Writeln(' to 99.'); Writeln;
END {Preface};
{ }
PROCEDURE WhatNow(VAR Op : CHAR; VAR ValueIn : ValueType);
BEGIN
ValueIn := 0;
Read(Op);
WHILE NOT (Op IN ['I','D','F','B','C','E']) DO
Read (Op);
IF (Op = 'I') THEN Readln(ValueIn);
IF (Op = 'B') THEN Readln(ValueIn)
END {WhatNow};
{ }
PROCEDURE InsertRear(ValueIn : ValueType);
{ }
PROCEDURE ShiftQ(Queue : QueueType);
VAR k : INTEGER;
BEGIN
IF (Front > 0)
THEN BEGIN
FOR k := 1 TO (Rear - Front) DO
Queue[k] := Queue[Front+k];
Rear := Rear - Front;
Front := 0
END
END {ShiftQ};
{ }
BEGIN
IF (Rear >= Bound)
THEN ShiftQ(Queue)
END;
IF (Rear >= Bound)
THEN Writeln('The Queue is full. Try another command.')
ELSE BEGIN
Rear := Rear + 1;
Queue[Rear] := ValueIn
END
END {InsertRear};
{ }
FUNCTION Empty(Queue : QueueType) : BOOLEAN;
BEGIN
IF (Rear = 0)
THEN Empty := TRUE
ELSE Empty := FALSE
END {Empty};
{ }
PROCEDURE DeleteFront(Queue : QueueType);
BEGIN
IF Empty(Queue)
THEN Writeln('The queue is empty. Try another command.')
ELSE BEGIN
Front := Front + 1;
IF (Front = Rear)
THEN BEGIN
Front := 0;
Rear := 0
END
END
END {DeleteFront};
{ }
PROCEDURE Display(Front : ValueType);
VAR k : ValueType;
BEGIN
Writeln;
IF Empty(Queue)
THEN Writeln('The queue is empty.')
ELSE Writeln('The front value is',Queue[Front+1] : 3);
Writeln
END {Display};
{**
**}
BEGIN {QueueMachine}
Preface;
Front : = 0;
Rear : = 0;
Bound : = 10;
WhatNow(Op,ValueIn);
WHILE (Op <> 'E') DO BEGIN
CASE Op OF
'I' : InsertRear(ValueIn);
'D' : DeleteFront(Queue);
'F' : Display(Front);
'B' : Bound := ValueIn;
'C' : BEGIN
Front := 0;
Rear := 0
END
END {CASE};
WhatNow(Op,ValueIn)
END {WHILE}
END {StackMachine}.