home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1988 / 08_09 / stack / stackhan.mod < prev    next >
Encoding:
Modula Implementation  |  1988-01-10  |  6.9 KB  |  214 lines

  1. IMPLEMENTATION MODULE StackHandler;
  2. (*----------------------------------------------------------------------*
  3.  * Dieses Modul verwaltet Stacks mit beliebigen Datenelementen bis zu   *
  4.  * 255 Bytes pro Element.                                               *
  5.  * Copyright 1987: Dipl.-Inform. Frank F. Wachtmeister                  *
  6.  *----------------------------------------------------------------------*
  7.  * System  :  ATARI 520 ST+, SM 124, PADERCOMP DL-2, EPSON FX-105       *
  8.  * Compiler:  TDI MODULA-2/ST 0272-742796(UK)                           *
  9.  *----------------------------------------------------------------------*
  10.  * Verwendete Module, die nicht zum Grundpaket gehören:                 *
  11.  *    Debugger: erhältlich über PASCAL Intern. 4/88                     *
  12.  *----------------------------------------------------------------------*
  13.  * Folgende Fehlermeldungen sind über den Debugger implementiert:       *
  14.  * 101: Stack Overflow                                                  *
  15.  * 102: Stack not initialized                                           *
  16.  * 103: Stack Element too large. Max. 255 Bytes                         *
  17.  * 104: Stack Underflow                                                 *
  18.  * 105: Stack element inkompatible with given variable (Pop)            *
  19.  *                                                                      *
  20.  * Vergleiche Datei ERRORS.TXT                                          *
  21.  *----------------------------------------------------------------------*)
  22.  
  23. (*$Q+,T-,$S- *)
  24.  
  25. FROM SYSTEM   IMPORT ADDRESS, BYTE, WORD;
  26. FROM Storage  IMPORT ALLOCATE, DEALLOCATE;
  27. FROM Debugger IMPORT Into, Leaving, Message, InitDebugger,
  28.                      Activate, Error;
  29.  
  30. TYPE
  31.    Stack       = POINTER TO StackDescription;
  32.    SegmentList = POINTER TO StackSegment; 
  33.    
  34.    StackDescription = RECORD
  35.       top : SegmentList;   (* Zeiger auf letztes Segment des Stacks      *)
  36.       anz : CARDINAL;      (* Anzahl der Elemente des Stacks             *)
  37.    END;
  38.    
  39.    StackSegment = RECORD
  40.       info  : ARRAY[0..255] OF BYTE;
  41.       free  : [0..255];
  42.       before: SegmentList;
  43.    END;
  44.    
  45. CONST DEBUG = FALSE;
  46.  
  47. PROCEDURE Dummy (VAR name: ARRAY OF CHAR; word: WORD);
  48. VAR w: WORD;
  49.    
  50. BEGIN w:=word;
  51. END Dummy;
  52.  
  53.  
  54. PROCEDURE InitStack (VAR s: Stack);
  55. (*----------------------------------------------------------------------*
  56.  * InitStack initialisiert einen leeren Stack.                          *
  57.  *----------------------------------------------------------------------*)
  58. BEGIN
  59. IF DEBUG THEN Into ('InitStack             ') END;
  60.    NEW (s);
  61.    WITH s^ DO
  62.       top := NIL;  anz:=0;
  63.    END;
  64.    IF DEBUG THEN Leaving ('InitStack                ') END;
  65. END InitStack;
  66.  
  67.  
  68. PROCEDURE StackSize (VAR s: Stack): CARDINAL;
  69. (*----------------------------------------------------------------------*
  70.  * StackSize liefert die Anzahl der Elemente eines Stacks.              *
  71.  * Leerer oder nicht initialisierter Stack: StackSize = 0               *
  72.  *----------------------------------------------------------------------*)
  73. BEGIN
  74.    IF DEBUG THEN Into ('StackSize') END;
  75.    IF s<>NIL THEN
  76.       RETURN (s^.anz)
  77.    ELSE
  78.       RETURN (0)
  79.    END;
  80.    IF DEBUG THEN Leaving ('StackSize') END;
  81. END StackSize;
  82.  
  83.  
  84. PROCEDURE AssByte (VAR b: BYTE; c: CARDINAL);
  85. VAR
  86.    m: RECORD
  87.       CASE : BOOLEAN OF
  88.          TRUE : high,low: BYTE;
  89.       |  FALSE: card    : CARDINAL;
  90.       END;
  91.    END;
  92.  
  93. BEGIN
  94.    m.card:=c;
  95.    b     :=m.low;
  96. END AssByte;
  97.  
  98.  
  99. PROCEDURE AssCard (VAR c: CARDINAL; b: BYTE);
  100. VAR
  101.    m: RECORD
  102.       CASE : BOOLEAN OF
  103.          TRUE : high,low: BYTE;
  104.       |  FALSE: card    : CARDINAL;
  105.       END;
  106.    END;
  107.  
  108. BEGIN
  109.    m.low:=b;
  110.    c    :=m.card;
  111. END AssCard;
  112.  
  113.  
  114. PROCEDURE Push (VAR s: Stack; elem: ARRAY OF BYTE);
  115. (*----------------------------------------------------------------------*
  116.  * Push legt ein Element beliebigen Typs auf einen Stack s.             *
  117.  *----------------------------------------------------------------------*)
  118. VAR i,
  119.     ende: CARDINAL;
  120.     seg:  SegmentList;
  121.  
  122. BEGIN
  123.    IF DEBUG THEN Into ('Push                     ') END;
  124.    IF s<>NIL THEN
  125.       IF HIGH(elem)>255 THEN
  126.          Error (103)
  127.       ELSE
  128.          IF s^.top=NIL THEN
  129.             ende:=256
  130.          ELSE
  131.             ende:=s^.top^.free+SIZE(elem)+1
  132.          END;
  133.          IF ende>255 THEN (* AddSegment *)
  134.             NEW (seg);
  135.             WITH seg^ DO
  136.                free  :=0;
  137.                before:=s^.top;
  138.             END;
  139.             s^.top:=seg;
  140.          END;
  141.          WITH s^.top^ DO (* Add Element *)
  142.             FOR i:=0 TO HIGH (elem) DO
  143.                info [free+i]:=elem[i];
  144.             END;
  145.             free:=free+SIZE(elem);
  146.             AssByte (info[free], SIZE(elem)); INC (free);
  147.          END;
  148.          INC (s^.anz);
  149.       END;
  150.    ELSE
  151.       Error (102)
  152.    END;
  153.    IF DEBUG THEN Leaving ('Push                     ') END;
  154. END Push;
  155.  
  156. PROCEDURE Pop (VAR s: Stack; VAR elem: ARRAY OF BYTE);
  157. (*----------------------------------------------------------------------*
  158.  * Pop holt ein Element von einem Stack und verkleinert den Stack.      *
  159.  * Falls Grö₧e des Stackelements ungleich des übergebenen element's,    *
  160.  * wird die Fehlerroutine aufgerufen.                                   *
  161.  *----------------------------------------------------------------------*)
  162. VAR i,      
  163.     length : CARDINAL;
  164.     p      : SegmentList;
  165.    
  166. BEGIN
  167.    IF DEBUG THEN Into ('Pop                      ') END;
  168.    IF s<>NIL THEN (* Confuse the customer        *)
  169.    (* Schöne Grü₧e vom Compiler:                 *)
  170.    (* Pop läuft nur so fehlerfrei, andernfalls   *)
  171.    (* hat der Record s falsche Werte.  (!??!)    *)
  172.       Dummy ('Anzahl', s^.anz);
  173.    END;
  174.    IF s=NIL THEN Error (102)
  175.    ELSIF s^.anz=0 THEN Error (104)
  176.    ELSE
  177.       AssCard (length, s^.top^.info[s^.top^.free-1] );
  178.       IF (length <> SIZE(elem)) THEN Error (105)
  179.       ELSE
  180.          WITH s^.top^ DO
  181.             free  :=free-length-1;
  182.             FOR i:=0 TO HIGH (elem) DO
  183.                elem[i]:=info[free+i]
  184.             END;
  185.             DEC (s^.anz);
  186.             IF free=0 THEN
  187.                p     :=s^.top;
  188.                s^.top:=before;
  189.                DISPOSE (p);
  190.             END;
  191.          END;
  192.       END;
  193.    END;
  194.    IF DEBUG THEN Leaving ('Pop                      ') END;
  195. END Pop;
  196.  
  197.  
  198. PROCEDURE TopOfStack (VAR s: Stack; VAR elem: ARRAY OF BYTE);
  199. (*----------------------------------------------------------------------*
  200.  * PopOfStack holt ein Element vom Stack, ohne diesen zu verkleinern.   *
  201.  * Typenkompatibilität wird wie bei Pop geprüft.                        *
  202.  *----------------------------------------------------------------------*)
  203. BEGIN
  204.    IF DEBUG THEN Into ('TopOfStack') END;
  205.    Pop (s,elem);
  206.    Push(s,elem);
  207.    IF DEBUG THEN Leaving ('TopOfStack') END;
  208. END TopOfStack;
  209.  
  210.  
  211. BEGIN 
  212. END StackHandler.
  213.  
  214.