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
    // Komórki listy
    String10 = String[10];
    PStackCell = ^TStackCell;
    TStackCell = record
        Value    : String10;   // The data.
        NextCell : PStackCell; // The next cell.
    end;

    // Klasa reprezentująca listę łączoną
    TStack = class(TObject)
        private
            Top : PStackCell; // Wskaźnik na pierwszy element

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

implementation

// Zwolnij obiekt
destructor TStack.Destroy;
begin
    EmptyStack;
    inherited Destroy;
end;

// Umieść element na stosie
procedure TStack.Push(new_value : String10);
var
    new_cell : PStackCell;
begin
    // Twórz nową komórkę
    New(new_cell);
    new_cell^.Value := new_value;

    // Wstaw komórkę reprezentującą element na pierwszą pozycję
    new_cell^.NextCell := Top;
    Top := new_cell;
end;

// Usuń pierwszą komórkę z listy
function TStack.Pop : String10;
var
    target : PStackCell;
begin
    if (Top = nil) then
        raise EInvalidOperation.Create(
            'Cannot pop items from an empty stack.');

    // Zachowaj wskaźnik do usuwanej komórki
    target := Top;
    Pop := target^.Value;

    // Usuń komórkę
    Top := target^.NextCell;

    // Zwolnij usuniętą komórkę
    Dispose(target);
end;

// Sprawdź, czy stos jest pusty
function TStack.StackEmpty : Boolean;
begin
    StackEmpty := (Top = nil);
end;

// Utwórz łańcuch reprezentujący zawartość stosu jako całości
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;

// Usuń wszystkie elementy ze stosu
procedure TStack.EmptyStack;
var
    target : PStackCell;
begin
    while (Top <> nil) do
    begin
        target := Top;
        Top := Top^.NextCell;
        Dispose(target);
    end;
end;

end.
