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

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