(* ==================================================================== *)
(* === Stack ========================================================== *)
(* ==================================================================== *)
(*

  :Program.       Stack.MOD
  :Contents.      stack ADT based on linear lists
  :Author.        Peter Fröhlich [phf]
  :Copyright.     Public Domain
  :Language.      Oberon (revised)
  :Translator.    Amiga Oberon V2.01
  :History.       V0.0 [phf] 02-Sep-1991 [created]
  :History.       V1.0 [phf] 03-Sep-1991 seems to work
  :History.       V1.0 [phf] 08-Sep-1991 [last edit]

  :Support.       B. Meyer, Object-oriented Software Construction
  :Imports.       -
  :Bugs.          none known

  :Address.       Ebenböckstraße 19, D-8000 München 60
  :Address.       Z-NET:P.FROEHLICH@NEXT-BOX.ZER
  :Phone.         (089) 820 31 72

*)
(* ==================================================================== *)

MODULE Stack;

(* ==================================================================== *)
(* === Imports ======================================================== *)
(* ==================================================================== *)

IMPORT
  l : Lists;

(* ==================================================================== *)
(* === Types ========================================================== *)
(* ==================================================================== *)

TYPE
  Element* = POINTER TO ElementObject;
  ElementObject* = l.Node; (* exported to allow type-extension *)
          
  Stack* = POINTER TO l.List;

(* ==================================================================== *)
(* === Procedures ===================================================== *)
(* ==================================================================== *)

(*==== Stack creation/destruction ======================================*)

(* --- Create --------------------------------------------------------- *)
PROCEDURE Create*(VAR (*OUT*) stack: Stack);
BEGIN
  NEW(stack);
  IF (stack # NIL) THEN
    l.Init(stack^);
  END;
END Create;
(* -------------------------------------------------------------------- *)

(* --- Discard -------------------------------------------------------- *)
PROCEDURE Discard*(VAR (*INOUT*) stack: Stack);
BEGIN
  DISPOSE(stack);
  stack := NIL;
END Discard;
(* -------------------------------------------------------------------- *)

(*==== Accessing a stack ===============================================*)

(* --- Push ----------------------------------------------------------- *)
PROCEDURE Push*(VAR (*INOUT*) stack: Stack; element: Element);
BEGIN
  l.AddHead(stack^,element);
END Push;
(* -------------------------------------------------------------------- *)

(* --- Pop ------------------------------------------------------------ *)
PROCEDURE Pop*(VAR (*INOUT*) stack: Stack): Element;
BEGIN
  RETURN l.RemHead(stack^);
END Pop;
(* -------------------------------------------------------------------- *)

(* --- Top ------------------------------------------------------------ *)
PROCEDURE Top*(VAR (*IN*) stack: Stack): Element;
BEGIN
  RETURN l.Head(stack^);
END Top;
(* -------------------------------------------------------------------- *)

(*==== Status of a stack ===============================================*)

(* --- Empty ---------------------------------------------------------- *)
PROCEDURE Empty*(VAR (*IN*) stack: Stack): BOOLEAN;
BEGIN
  RETURN l.Empty(stack^);
END Empty;
(* -------------------------------------------------------------------- *)

(* --- Full ----------------------------------------------------------- *)
PROCEDURE Full*(VAR (*IN*) stack: Stack): BOOLEAN;
BEGIN
  RETURN FALSE; (* this implementation can never be full *)
END Full;
(* -------------------------------------------------------------------- *)

(* --- Elements ------------------------------------------------------- *)
PROCEDURE Elements*(VAR (*IN*) stack: Stack): LONGINT;
BEGIN
  RETURN l.CountElements(stack^);
END Elements;
(* -------------------------------------------------------------------- *)

(* ==================================================================== *)
END Stack.
(* ==================================================================== *)
