unit LStackC;
//*******************************************************
// Linked list-based stack class.
//*******************************************************
// Copyright (C) 1998 John Wiley & Sons, Inc.
// All rights reserved. See additional copyright
// information in Readme.txt.
//*******************************************************

interface

uses
    Dialogs, SysUtils, Classes;

type
    // The linked list cells.
    String10 = String[10];
    PStackCell = ^TStackCell;
    TStackCell = record
        Value    : String10;   // The data.
        NextCell : PStackCell; // The next cell.
    end;

    // The linked list class.
    TStack = class(TObject)
        private
            Top : PStackCell; // Top of list pointer.

        public
            destructor Destroy; override;
            procedure Push(new_value : String10);
            function Pop : String10;
            function StackEmpty : Boolean;
            function TextValue : String;
            procedure EmptyStack;
    end;

implementation

// Free any allocated memory.
destructor TStack.Destroy;
begin
    EmptyStack;
    inherited Destroy;
end;

// Add an item to the stack.
procedure TStack.Push(new_value : String10);
var
    new_cell : PStackCell;
begin
    // Create the new cell.
    New(new_cell);
    new_cell^.Value := new_value;

    // Insert the cell at the top of the stack.
    new_cell^.NextCell := Top;
    Top := new_cell;
end;

// Remove the first item from the stack.
function TStack.Pop : String10;
var
    target : PStackCell;
begin
    if (Top = nil) then
        raise EInvalidOperation.Create(
            'Cannot pop items from an empty stack.');

    // Save the return value;
    target := Top;
    Pop := target^.Value;

    // Remove the first cell from the stack.
    Top := target^.NextCell;

    // Free the target cell's memory.
    Dispose(target);
end;

// Return the number of items in the list.
function TStack.StackEmpty : Boolean;
begin
    StackEmpty := (Top = nil);
end;

// Return a string representing all of the stack's entries.
function TStack.TextValue : String;
const
    CR = #13#10;
var
    cell_ptr : PStackCell;
begin
    Result := '';
    cell_ptr := Top;
    while (cell_ptr <> nil) do
    begin
        Result := Result + cell_ptr^.Value + CR;
        cell_ptr := cell_ptr^.NextCell;
    end;
end;

// Remove all items from the stack.
procedure TStack.EmptyStack;
var
    target : PStackCell;
begin
    while (Top <> nil) do
    begin
        target := Top;
        Top := Top^.NextCell;
        Dispose(target);
    end;
end;

end.
