home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 549a.lha / M2P_v1.0 / mods.lzh / SymLists.mod < prev    next >
Text File  |  1991-08-10  |  14KB  |  364 lines

  1. (*======================================================================*)
  2. (*       Programming Support Routines - Managing Lists of Symbols       *)
  3. (*======================================================================*)
  4. (*  Version:  2.00              Author:   Dennis Brueni                 *)
  5. (*  Date:     1-20-91           Changes:  original                      *)
  6. (*  Date:     1-25-91           Changes:  Duplicate Handling            *)
  7. (*  Date:     1-25-91           Changes:  .Symbol field became pointer  *)
  8. (*  Date:     1-26-91           Changes:  CaseSensitive Bug fixed       *)
  9. (*  Date:     3-07-91           Changes:  Duplicate Handling removed    *)
  10. (*                                        Traversal routines added      *)
  11. (*                                        Merge/Sort routines added     *)
  12. (*                                        No case-sensitivity           *)
  13. (*  Date:     3-09-91           Changes:  Now uses FStorage (freelists) *)
  14. (*======================================================================*)
  15. (*  SymLists contains all the routines necessary to use, maintain, and  *)
  16. (*  destroy a linked list of symbols.  It uses a MRU (Most Recently     *)
  17. (*  Used) logic (relying on the principle of locality of reference) to  *)
  18. (*  insure that the symbols most likely to be accessed next will appear *)
  19. (*  at the beginning of the list.  This means that symbols are always   *)
  20. (*  added to the front of a list, and whenever a search is performed,   *)
  21. (*  the symbol found is moved to the front of the list.                 *)
  22. (*======================================================================*)
  23. (*  The SymList structure is itself recursively defined as follows:     *)
  24. (*                                                                      *)
  25. (*     A SymList is either NIL or a pair (Symbol,Next) where Next is    *)
  26. (*     another symbol list.                                             *)
  27. (*======================================================================*)
  28. (*  Often one will want to aggregate additional information with a      *)
  29. (*  symbol, so to make this table as general as possible, the symbol    *)
  30. (*  must be sent as a pointer to record of the following form when      *)
  31. (*  performing insertions.  (note: m should be less than 512)           *)
  32. (*                                                                      *)
  33. (*       symbolrec = RECORD OF                                          *)
  34. (*                      Symbol:  POINTER TO ARRAY [0..m] OF CHAR;       *)
  35. (*                      |                                               *)
  36. (*                   END;                                               *)
  37. (*                                                                      *)
  38. (*======================================================================*)
  39.  
  40. IMPLEMENTATION MODULE SymLists;
  41.  
  42. IMPORT
  43.     SYSTEM,FStorage,Strings;
  44.  
  45.  
  46.  
  47.  
  48.  
  49. (*----------------------------------------------------------------------*)
  50. (*  Type definitions of a symbol and a Linked List.                     *)
  51. (*----------------------------------------------------------------------*)
  52.  
  53. TYPE
  54.     SymEntryPtr = POINTER TO SymbolEntry;
  55.     SymbolEntry = RECORD
  56.         Symbol: SymbolPtr;
  57.     END;
  58.  
  59.     SymList = POINTER TO SymRec;
  60.     SymRec = RECORD
  61.         Next: SymList;
  62.         Symbol: SymEntryPtr;
  63.     END;
  64.  
  65. CONST
  66.     SymRecSize = SYSTEM.TSIZE(SymRec);
  67.  
  68.  
  69. (*----------------------------------------------------------------------*)
  70. (*  CREATE      Create an initialized linked list.                      *)
  71. (*                                                                      *)
  72. (*  PARAMETERS  SL - the SymList pointer to initialize.                 *)
  73. (*----------------------------------------------------------------------*)
  74.  
  75. PROCEDURE Create(VAR SL: SymList);
  76. BEGIN
  77.     SL := NIL;
  78. END Create;
  79.  
  80. (*----------------------------------------------------------------------*)
  81. (*  DESTROY     Destruct a linked list.  All information on the list    *)
  82. (*              at time of invocation will be unlinked from the list,   *)
  83. (*              possibly lost...                                        *)
  84. (*                                                                      *)
  85. (*  PARAMETER   SL -- The SymList to clear out                          *)
  86. (*----------------------------------------------------------------------*)
  87.  
  88. PROCEDURE Destroy(VAR SL: SymList);
  89.  
  90. VAR
  91.     Temp: SymList;
  92. BEGIN
  93.     WHILE SL # NIL DO
  94.         Temp:=SL;
  95.         SL:=SL^.Next;
  96.         FStorage.DEALLOCATE(Temp,SymRecSize);
  97.     END;
  98. END Destroy;
  99.  
  100. (*----------------------------------------------------------------------*)
  101. (*  INSERT      Add a symbol to the front of the linked list.  Please   *)
  102. (*              see the documentation above for the correct format of   *)
  103. (*              of the Symbol Entry                                     *)
  104. (*                                                                      *)
  105. (*  PARAMETERS  SL     -- the linked list                               *)
  106. (*              Symbol -- the symbol                                    *)
  107. (*----------------------------------------------------------------------*)
  108.  
  109. PROCEDURE Insert(VAR SL: SymList ; Symbol: SYSTEM.ADDRESS);
  110.  
  111. VAR
  112.     Temp: SymList;
  113. BEGIN
  114.     FStorage.ALLOCATE(Temp,SymRecSize);
  115.     Temp^.Next:=SL;
  116.     Temp^.Symbol:=Symbol;
  117.     SL:=Temp;
  118. END Insert;
  119.  
  120. (*----------------------------------------------------------------------*)
  121. (*  DELETE      Remove a symbol from the linked list.  If the symbol    *)
  122. (*              was not present this has no effect.                     *)
  123. (*                                                                      *)
  124. (*  PARAMETERS  SL     -- the linked list                               *)
  125. (*              Symbol -- the symbol                                    *)
  126. (*----------------------------------------------------------------------*)
  127.  
  128.  
  129.  
  130. PROCEDURE Delete(VAR SL: SymList; Symbol: ARRAY OF CHAR);
  131.  
  132. VAR
  133.     Temp: SymList;
  134. BEGIN
  135.     IF Search(SL,Symbol) # NIL THEN
  136.         Temp:=SL;               (* Recall that search always    *)
  137.         SL:=Temp^.Next;         (* moves the symbol to the      *)
  138.         FStorage.DEALLOCATE(Temp,SymRecSize);
  139.                     (* front of the list if found*)
  140.     END;
  141. END Delete;
  142.  
  143. (*----------------------------------------------------------------------*)
  144. (*  SEARCH      Find a symbol in the linked list and return a pointer   *)
  145. (*              to the record which it is found in.  It will also move  *)
  146. (*              the symbol to the front of the list.                    *)
  147. (*                                                                      *)
  148. (*  PARAMETERS  SL     -- the linked list                               *)
  149. (*              Symbol -- the symbol                                    *)
  150. (*----------------------------------------------------------------------*)
  151.  
  152.  
  153.  
  154. PROCEDURE Search(VAR SL: SymList; Symbol: ARRAY OF CHAR): SYSTEM.ADDRESS;
  155.  
  156. VAR
  157.     Leader: SymList;
  158.     Shadow: SymList;
  159. BEGIN
  160.     IF SL # NIL THEN
  161.         Leader:=SL;
  162.         Shadow:=Leader;
  163.         WHILE Leader # NIL DO
  164.             IF Strings.Equal(Symbol,Leader^.Symbol^.Symbol^) THEN
  165.                 IF Leader # SL THEN
  166.                     Shadow^.Next:=Leader^.Next;
  167.                     Leader^.Next:=SL;
  168.                     SL:=Leader;
  169.                 END;
  170.                 RETURN Leader^.Symbol;
  171.             ELSE
  172.                 Shadow:=Leader;
  173.                 Leader:=Leader^.Next;
  174.             END;
  175.         END;
  176.     END;
  177.     RETURN NIL;
  178. END Search;
  179.  
  180. (*----------------------------------------------------------------------*)
  181. (*  EMPTY       Tells whether a SymLists is empty OR NOT                *)
  182. (*                                                                      *)
  183. (*  PARAMETERS  SL -- The symbol list to look at                        *)
  184. (*                                                                      *)
  185. (*  RETURNS     TRUE if SL is NIL                                       *)
  186. (*----------------------------------------------------------------------*)
  187.  
  188. PROCEDURE Empty(SL: SymList):BOOLEAN;
  189. BEGIN
  190.     RETURN SL = NIL;
  191. END Empty;
  192.  
  193. (*----------------------------------------------------------------------*)
  194. (*  FIRST       Returns the first symbol on a SymList.                  *)
  195. (*                                                                      *)
  196. (*  PARAMETERS  SL -- The symbol list to look at                        *)
  197. (*                                                                      *)
  198. (*  RETURNS     NIL if the SymList is empty, otherwise the first symbol *)
  199. (*----------------------------------------------------------------------*)
  200.  
  201. PROCEDURE First(SL: SymList):SYSTEM.ADDRESS;
  202. BEGIN
  203.     IF SL # NIL THEN
  204.         RETURN SL^.Symbol;
  205.     END;
  206. END First;
  207.  
  208. (*----------------------------------------------------------------------*)
  209. (*  NEXT        SymLists are recursively defined, so each SymList is    *)
  210. (*              actually a (symbol,SymList) pair.  This procedure is    *)
  211. (*              used to access the SymList part of that pair.           *)
  212. (*                                                                      *)
  213. (*  PARAMETERS  SL   -- The SymList                                     *)
  214. (*                                                                      *)
  215. (*  RETURNS     The next SymList, NIL if none.                          *)
  216. (*----------------------------------------------------------------------*)
  217.  
  218. PROCEDURE Next(SL: SymList):SymList;
  219. BEGIN
  220.     IF SL # NIL THEN
  221.         RETURN SL^.Next;
  222.     END;
  223. END Next;
  224.  
  225. (*----------------------------------------------------------------------*)
  226. (*  ConCat      Appends two SymLists together and returns as a new      *)
  227. (*              symlist.                                                *)
  228. (*                                                                      *)
  229. (*  PARAMETERS  SL1 -- the first SymList                                *)
  230. (*              SL2 -- the second SymList                               *)
  231. (*                                                                      *)
  232. (*  RETURNS     A copy of SL1 appended to SL2                           *)
  233. (*----------------------------------------------------------------------*)
  234.  
  235. PROCEDURE ConCat(SL1,SL2: SymList):SymList;
  236.  
  237. VAR
  238.     SL: SymList;
  239.     NX: POINTER TO SymList;
  240. BEGIN
  241.     Create(SL);
  242.     NX:=SYSTEM.ADR(SL);
  243.     WHILE SL1 # NIL DO
  244.         FStorage.ALLOCATE(NX^,SymRecSize);
  245.         NX^^.Next:=NIL;
  246.         NX^^.Symbol:=SL1^.Symbol;
  247.         NX:=SYSTEM.ADR(NX^^.Next);
  248.         SL1:=SL1^.Next;
  249.     END;
  250.     WHILE SL2 # NIL DO
  251.         FStorage.ALLOCATE(NX^,SymRecSize);
  252.         NX^^.Next:=NIL;
  253.         NX^^.Symbol:=SL2^.Symbol;
  254.         SL2:=SL2^.Next;
  255.         NX:=SYSTEM.ADR(NX^^.Next) END;
  256.     RETURN SL;
  257. END ConCat;
  258.  
  259. (*----------------------------------------------------------------------*)
  260. (*  MERGE       Merges two sorted SymLists into one sorted SymList.  If *)
  261. (*              the two input lists are not presorted, it will not      *)
  262. (*              return a well sorted list.                              *)
  263. (*                                                                      *)
  264. (*  PARAMETERS  SL1 -- the first sorted SymList                         *)
  265. (*              SL2 -- the second sorted SymList                        *)
  266. (*                                                                      *)
  267. (*  RETURNS     A merged SymList                                        *)
  268. (*----------------------------------------------------------------------*)
  269.  
  270. PROCEDURE Merge(SL1,SL2: SymList):SymList;
  271.  
  272. VAR
  273.     SL: SymList;
  274.     NX: POINTER TO SymList;
  275.  
  276. BEGIN
  277.     Create(SL);
  278.     NX:=SYSTEM.ADR(SL);
  279.     LOOP
  280.         IF (SL1 = NIL) OR (SL2 = NIL) THEN
  281.             NX^:=ConCat(SL1,SL2);
  282.             RETURN SL;
  283.         END;
  284.         FStorage.ALLOCATE(NX^,SymRecSize);
  285.         NX^^.Next:=NIL;
  286.         IF Strings.Compare(SL1^.Symbol^.Symbol^, SL2^.Symbol^.Symbol^) = Strings.less THEN
  287.             NX^^.Symbol:=SL1^.Symbol;
  288.             SL1:=SL1^.Next;
  289.         ELSE
  290.             NX^^.Symbol:=SL2^.Symbol;
  291.             SL2:=SL2^.Next;
  292.         END;
  293.         NX:=SYSTEM.ADR(NX^^.Next);
  294.     END;
  295. END Merge;
  296.  
  297. (*----------------------------------------------------------------------*)
  298. (*  SORT        Performs mergesort upon a symlist, placing it in        *)
  299. (*              lexicographic order.                                    *)
  300. (*                                                                      *)
  301. (*  PARAMETERS  SL -- the SymList to sort.                              *)
  302. (*----------------------------------------------------------------------*)
  303.  
  304. PROCEDURE Sort(VAR SL: SymList);
  305.  
  306. VAR
  307.     SL1,SL2: SymList;
  308.  
  309. BEGIN
  310.     IF (SL # NIL) AND (SL^.Next # NIL) THEN
  311.                     (* 2 or more nodes      *)
  312.         SL1:=SL;
  313.         SL2:=SL;
  314.         LOOP
  315.             SL2:=SL2^.Next; (* Split the list in    *)
  316.             IF SL2=NIL THEN
  317.                 EXIT;
  318.             END;            (* half by traversing   *)
  319.             SL2:=SL2^.Next; (* with two pointers,   *)
  320.             IF SL2=NIL THEN
  321.                 EXIT;
  322.             END;            (* one at full speed,   *)
  323.             SL1:=SL1^.Next; (* and one at half speed*)
  324.         END;
  325.         SL2:=SL1^.Next;         (* SL2 is second half   *)
  326.         SL1^.Next:=NIL;         (* SL1 is first half    *)
  327.         SL1:=SL;
  328.         Sort(SL1);              (* Sort both halves     *)
  329.         Sort(SL2);
  330.         SL:=Merge(SL1,SL2);     (* Merge 'em together   *)
  331.         Destroy(SL1);           (* destroy the orginals *)
  332.         Destroy(SL2);
  333.     END;
  334. END Sort;
  335.  
  336. (*----------------------------------------------------------------------*)
  337. (*  REVERSE     Reverses a symlist.                                     *)
  338. (*                                                                      *)
  339. (*  PARAMETERS  SL -- the SymList to reverse.                           *)
  340. (*----------------------------------------------------------------------*)
  341.  
  342. PROCEDURE Reverse(VAR SL: SymList);
  343.  
  344. VAR
  345.     temp: SymList;
  346.     trav: SymList;
  347. BEGIN
  348.     trav:=SL;
  349.     SL:=NIL;
  350.     WHILE trav # NIL DO
  351.         temp:=trav;
  352.         trav:=trav^.Next;
  353.         temp^.Next:=SL;
  354.         SL:=temp;
  355.     END;
  356. END Reverse;
  357.  
  358. (************************************************************************)
  359. (*  MAIN inititalization code                                           *)
  360. (************************************************************************)
  361.  
  362. BEGIN
  363. END SymLists.
  364.