A Pascal program that provides command-shell access to a stack is a straightforward application of the procedures of Chapter 4, 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 within a token-entry procedure that can acquire values for the insert and bound commands.
The command repertoire of section 4.1.1 can be extended somewhat, but a complete set seems to be:
I insert
D delete the top value
T display the top value
B set a bound for the number of items on the stack
C clear (empty) the stack
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 stack and insertion into a full one only invoke mild reproof. Simplicity also dictates the replacement of function TopValue with procedure Display that writes an "empty stack" message when necessary:
PROGRAM StackMachine(Input,Output);
TYPE ValueType = 0. .99;
StackType = ARRAY [1. .99] OF INTEGER;
Var Stack : StackType ;
Value : ValueType ;
Bound : ValueType ;
Top : ValueType ;
Op : CHAR;
{ }
PROCEDURE Preface;
BEGIN
Write('This program operates a stack with the');
Writeln(' single-letter commands:');
Writeln('I - insert a value into the stack');
Writeln('D - delete the top value from the stack');
Writeln('T - display the top value of the stack');
Writeln('B - set the stack bound between 1 and 99');
Writeln('C - clear (empty) the stack');
Writeln('E - exit (quit)'); Writeln;
Writeln('Commands should be separated by spaces.');
Writeln('B and I are to be followed by an integer');
Writeln(' in the range 0 to 99.') Writeln;
END {Preface};
{ }
PROCEDURE WhatNow(VAR Op : CHAR; VAR Value : ValueType);
BEGIN
Value := 0;
Read(Op);
WHILE NOT (Op IN ['I','D','T','B','C','E']) DO Read(Op);
IF (Op = 'I') THEN Readln(Value);
IF (Op = 'B') THEN Readln(Value)
END {WhatNow};
{ }
PROCEDURE Push(Value : ValueType);
BEGIN
IF (Top >= Bound)
THEN Writeln('Stack full. Try another command.')
ELSE BEGIN
Top := Top + 1;
Stack[Top] := Value
END {ELSE}
END {Push};
{ }
FUNCTION Empty(Stack : StackType) : BOOLEAN;
BEGIN
IF (Top = 0)
THEN Empty := TRUE
ELSE Empty := FALSE
END {Empty};
{ }
PROCEDURE DeleteTop(Stack : StackType);
BEGIN
IF Empty(Stack)
THEN Writeln('Stack empty. Try another command.')
ELSE Top := Top - 1
END {DeleteTop};
{ }
PROCEDURE Display(Top : ValueType);
VAR k : ValueType;
BEGIN
Writeln;
IF Empty(Stack)
THEN Writeln('The stack is Empty.')
ELSE Writeln('The top value is' ,Stack[Top] : 3);
Writeln
END {Display};
{**
**}
BEGIN {StackMachine}
Preface;
Top := 0 ;
Bound := 10;
WhatNow(Op,Value);
WHILE (Op < > 'E') DO BEGIN
CASE Op OF
'I' : Push(Value);
'D' : DeleteTop(Stack);
'T' : Display(Top);
'B' : Bound := Value;
'C' : Top : = 0
END { CASE };
WhatNow( Op,Value);
END {WHILE}
END {StackMachine}.