home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1991 / 05 / tricks / stack.mod < prev    next >
Encoding:
Modula Implementation  |  1991-01-08  |  5.7 KB  |  215 lines

  1. (* ------------------------------------------------------ *)
  2. (*                      STACK.MOD                         *)
  3. (* ------------------------------------------------------ *)
  4. IMPLEMENTATION MODULE Stack;
  5.  
  6. (*$T-*) (* Kein NIL check, da interner Pointer Guard! *)
  7.  
  8. FROM SYSTEM IMPORT ADDRESS, ADR;
  9.  
  10. IMPORT Storage, Terminal, System;
  11.  
  12. TYPE
  13.   pStackObject = POINTER TO tStackObject;
  14.   tStackObject = RECORD
  15.                    Object : ADDRESS;
  16.                    Size   : CARDINAL;
  17.                    Prev   : pStackObject;
  18.                  END;
  19.   tStackInfo   = RECORD
  20.                    Guard : ADDRESS;
  21.                    Num   : CARDINAL;
  22.                    Top   : pStackObject
  23.                  END;
  24.   tStack       = POINTER TO tStackInfo;
  25.  
  26.  
  27.   PROCEDURE ErrorHalt(str : ARRAY OF CHAR);
  28.   BEGIN
  29.     Terminal.WriteString(str);
  30.     HALT;
  31.   END ErrorHalt;
  32.  
  33.   PROCEDURE Create(VAR stack : tStack);
  34.   BEGIN
  35.     IF NOT Storage.Available (SIZE(tStack)) THEN
  36.       ErrorHalt('Stack.Create: Out of memory');
  37.       HALT;
  38.     END;
  39.     Storage.ALLOCATE(stack, SIZE(tStackInfo));
  40.     stack^.Guard := stack;
  41.     stack^.Num   := 0;
  42.     stack^.Top   := NIL;
  43.   END Create;
  44.  
  45.   PROCEDURE Delete(VAR stack : tStack);
  46.   BEGIN
  47.     IF stack # stack^.Guard THEN
  48.       ErrorHalt
  49.       ('Stack.Delete: Variable "stack" not created');
  50.       HALT();
  51.     END;
  52.     IF stack^.Top # NIL THEN
  53.       ErrorHalt('Stack.Delete: Stack not empty');
  54.       HALT();
  55.     END;
  56.     stack^.Guard := NIL;
  57.     Storage.DEALLOCATE(stack, SIZE(tStackInfo));
  58.   END Delete;
  59.  
  60.   PROCEDURE Push(stack : tStack;
  61.                  size : CARDINAL; addr : ADDRESS);
  62.   VAR
  63.     newObject : pStackObject;
  64.   BEGIN
  65.     IF stack # stack^.Guard THEN
  66.       HALT();
  67.     END;
  68.     IF NOT Storage.Available (SIZE(tStackObject)) THEN
  69.       ErrorHalt('Stack.Push: Out of memory');
  70.       HALT();
  71.     END;
  72.     Storage.ALLOCATE(newObject, SIZE(tStackObject));
  73.     newObject^.Prev := stack^.Top;
  74.     stack^.Top := newObject;
  75.     IF NOT Storage.Available (size) THEN
  76.       ErrorHalt('Stack.Push: Out of memory');
  77.       HALT();
  78.     END;
  79.     Storage.ALLOCATE(stack^.Top^.Object, size);
  80.     System.Move(addr, stack^.Top^.Object, size);
  81.     stack^.Top^.Size    := size;
  82.     INC(stack^.Num);
  83.   END Push;
  84.  
  85.   PROCEDURE Pop(    stack : tStack;
  86.                 VAR size : CARDINAL; addr : ADDRESS);
  87.   VAR
  88.     oldObject : pStackObject;
  89.   BEGIN
  90.     IF stack # stack^.Guard THEN
  91.       ErrorHalt
  92.       ('Stack.Pop: Variable "stack" not created');
  93.       HALT();
  94.     END;
  95.     IF stack^.Num < 1 THEN
  96.       ErrorHalt('Stack.Pop: Stack is empty');
  97.       HALT();
  98.     END;
  99.     size  := stack^.Top^.Size;
  100.     System.Move(stack^.Top^.Object, addr, size);
  101.     oldObject := stack^.Top^.Prev;
  102.     Storage.DEALLOCATE(stack^.Top^.Object, size);
  103.     Storage.DEALLOCATE(stack^.Top, SIZE(tStackObject));
  104.     stack^.Top := oldObject;
  105.     DEC(stack^.Num);
  106.   END Pop;
  107.  
  108.   PROCEDURE Peep(    stack : tStack;
  109.                  VAR size : CARDINAL; addr : ADDRESS);
  110.   BEGIN
  111.     IF stack # stack^.Guard THEN
  112.       ErrorHalt
  113.       ('Stack.Peep: Variable "stack" not created');
  114.       HALT();
  115.     END;
  116.     IF stack^.Num < 1 THEN
  117.       ErrorHalt('Stack.Peep: Stack is empty');
  118.       HALT();
  119.     END;
  120.     size  := stack^.Top^.Size;
  121.     System.Move(stack^.Top^.Object, addr, size);
  122.   END Peep;
  123.  
  124.   PROCEDURE IsEmpty(stack : tStack) : BOOLEAN;
  125.   BEGIN
  126.     IF stack^.Guard # stack THEN
  127.       ErrorHalt
  128.       ('Stack.IsEmpty: Variable "stack" not created');
  129.       HALT();
  130.     END;
  131.     RETURN stack^.Num = 0;
  132.   END IsEmpty;
  133.  
  134.   PROCEDURE NumEntries(stack : tStack) : CARDINAL;
  135.   BEGIN
  136.     IF stack^.Guard # stack THEN
  137.       ErrorHalt
  138.       ('Stack.NumEntries: Variable "stack" not created');
  139.       HALT();
  140.     END;
  141.     RETURN stack^.Num;
  142.   END NumEntries;
  143.  
  144.   PROCEDURE Reset(stack : tStack);
  145.   VAR
  146.     oldObject : pStackObject;
  147.     size : CARDINAL;
  148.   BEGIN
  149.     IF stack^.Guard # stack THEN
  150.       ErrorHalt
  151.       ('Stack.Reset: Variable "stack" not created');
  152.       HALT();
  153.     END;
  154.     WHILE stack^.Num > 0 DO
  155.       size  := stack^.Top^.Size;
  156.       oldObject := stack^.Top^.Prev;
  157.       Storage.DEALLOCATE(stack^.Top^.Object, size);
  158.       Storage.DEALLOCATE(stack^.Top, SIZE(tStackObject));
  159.       stack^.Top := oldObject;
  160.       DEC(stack^.Num);
  161.     END;
  162.   END Reset;
  163.  
  164.   PROCEDURE Drop(stack : tStack; num : CARDINAL);
  165.   VAR
  166.     moveObject, targetObject : pStackObject;
  167.     ind : CARDINAL;
  168.   BEGIN
  169.     IF stack^.Guard # stack THEN
  170.       ErrorHalt
  171.       ('Stack.Drop: Variable "stack" not created');
  172.       HALT();
  173.     END;
  174.     IF num < 1 THEN RETURN END;
  175.     ind := 1;
  176.     moveObject := stack^.Top;
  177.     stack^.Top := moveObject^.Prev;
  178.     targetObject := stack^.Top;
  179.     WHILE (ind < num) AND (targetObject^.Prev # NIL) DO
  180.       INC(ind);
  181.       targetObject := targetObject^.Prev;
  182.     END;
  183.     moveObject^.Prev := targetObject^.Prev;
  184.     targetObject^.Prev := moveObject;
  185.   END Drop;
  186.  
  187.   PROCEDURE Join(stackTop, stackBot : tStack);
  188.   VAR
  189.     lastObject : pStackObject;
  190.   BEGIN
  191.     IF stackTop^.Guard # stackTop THEN
  192.       ErrorHalt
  193.       ('Stack.Join: Variable "stackTop" not created');
  194.       HALT();
  195.     END;
  196.     IF stackBot^.Guard # stackBot THEN
  197.       ErrorHalt
  198.       ('Stack.Join: Varibale "stackBot" not created');
  199.       HALT();
  200.     END;
  201.     lastObject := stackTop^.Top;
  202.     WHILE lastObject^.Prev # NIL DO
  203.       lastObject := lastObject^.Prev;
  204.     END;
  205.     lastObject^.Prev := stackBot^.Top;
  206.     INC(stackTop^.Num, stackBot^.Num);
  207.     stackBot^.Num := 0;
  208.     stackBot^.Top := NIL;
  209.   END Join;
  210.  
  211. BEGIN
  212. END Stack.
  213. (* ------------------------------------------------------ *)
  214. (*                 Ende von STACK.MOD                     *)
  215.