BIGSETS.MOD 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. IMPLEMENTATION MODULE BigSets;
  2. (*
  3. * REPERTOIRE
  4. * Release 1.6
  5. * By Charles Bradford and Cole Brecheen
  6. * (c) Copyright 1985-1992 PMI
  7. * Green Bay, Wisconsin
  8. * All rights reserved
  9. * (414) 468-6040
  10. *
  11. * $Header: D:/logfiles/mods/bigsets.mov 1.3 10 Mar 1991 15:25:08 coleb $
  12. *
  13. *
  14. * Written and contributed by Wilbur C. Andrews.
  15. *
  16. *)
  17. IMPORT ErrorManager;
  18. IMPORT M2Strings;
  19. IMPORT StrEdit;
  20. VAR
  21. Initialized : BOOLEAN;
  22. PROCEDURE Init();
  23. BEGIN
  24. IF Initialized THEN
  25. RETURN;
  26. ELSE
  27. Initialized := TRUE;
  28. END;
  29. ErrorManager.Init();
  30. M2Strings.Init();
  31. StrEdit.Init();
  32. InitSet(DigitSet);
  33. InitSet(ChSet);
  34. AppendSet(DigitSet, "{'0'..'9'}");
  35. AppendSet(ChSet, "{' '..'~'}");
  36. END Init;
  37. CONST
  38. begin = 1;
  39. Dot = 2;
  40. Quote = 3;
  41. statement = 4;
  42. incomplete = 5;
  43. end = 7;
  44. StartSym = '{';
  45. EndSym = '}';
  46. PROCEDURE SetStuff(n : CARDINAL; VAR ArrayNo, Index : CARDINAL);
  47. BEGIN
  48. IF n=0 THEN
  49. ArrayNo := 0;
  50. Index := 0;
  51. ELSE
  52. ArrayNo := n DIV BitSetSize;
  53. Index := n MOD BitSetSize;
  54. END;
  55. END SetStuff;
  56. PROCEDURE InitSet(VAR BSet : ARRAY OF BITSET);
  57. VAR
  58. n : CARDINAL;
  59. BEGIN
  60. FOR n := 0 TO HIGH(BSet) DO
  61. BSet[n] := {};
  62. END;
  63. END InitSet;
  64. PROCEDURE AssignSet(Set1 : ARRAY OF BITSET; VAR Set2 : ARRAY OF
  65. BITSET);
  66. VAR
  67. a : CARDINAL;
  68. BEGIN
  69. FOR a := 0 TO HIGH(Set1) DO
  70. Set2[a] := Set1[a];
  71. END;
  72. END AssignSet;
  73. PROCEDURE Check( ArrayNumber, LastBitSet: CARDINAL );
  74. BEGIN
  75. IF ArrayNumber > LastBitSet THEN
  76. ErrorManager.WARN( "Set element out of range");
  77. END;
  78. END Check;
  79. PROCEDURE InclSet(VAR BSet : ARRAY OF BITSET; n : CARDINAL);
  80. VAR
  81. ArrayNo, Index : CARDINAL;
  82. BEGIN
  83. SetStuff(n, ArrayNo, Index);
  84. Check( ArrayNo, HIGH(BSet) );
  85. INCL(BSet[ArrayNo], Index);
  86. END InclSet;
  87. PROCEDURE ExclSet(VAR BSet : ARRAY OF BITSET; n : CARDINAL);
  88. VAR
  89. ArrayNo, Index : CARDINAL;
  90. BEGIN
  91. SetStuff(n, ArrayNo, Index);
  92. Check( ArrayNo, HIGH(BSet) );
  93. EXCL(BSet[ArrayNo], Index);
  94. END ExclSet;
  95. PROCEDURE InSet(VAR BSet : ARRAY OF BITSET; n : CARDINAL) : BOOLEAN;
  96. VAR
  97. ArrayNo, Index : CARDINAL;
  98. bool : BOOLEAN;
  99. BEGIN
  100. SetStuff(n, ArrayNo, Index);
  101. Check( ArrayNo, HIGH(BSet) );
  102. bool := Index IN BSet[ArrayNo];
  103. RETURN bool;
  104. END InSet;
  105. PROCEDURE EqualSet(VAR SetOne, SetTwo : ARRAY OF BITSET) : BOOLEAN;
  106. VAR
  107. EqualBool : BOOLEAN;
  108. a : CARDINAL;
  109. BEGIN
  110. a := 0;
  111. EqualBool := TRUE;
  112. WHILE (a<=HIGH(SetOne)) AND EqualBool DO
  113. EqualBool := SetOne[a]=SetTwo[a];
  114. a := a+1;
  115. END;
  116. RETURN EqualBool;
  117. END EqualSet;
  118. PROCEDURE AppendSet(VAR BSet : ARRAY OF BITSET; st : ARRAY OF CHAR);
  119. TYPE
  120. SetStType = ARRAY [0..79] OF CHAR;
  121. StRecord =
  122. RECORD
  123. Item : SetStType;
  124. type : (card, octal, char);
  125. END;
  126. VAR
  127. ch : CHAR;
  128. Error, count : CARDINAL;
  129. CodeSt : SetStType;
  130. StartSt, EndSt : StRecord;
  131. EndBool : BOOLEAN;
  132. message: ARRAY [0..79] OF CHAR;
  133. dumstr: ARRAY [0..0] OF CHAR;
  134. PROCEDURE GetCh();
  135. BEGIN
  136. IF count<=(M2Strings.Length(CodeSt)-1) THEN
  137. ch := CodeSt[count];
  138. INC(count);
  139. ELSE
  140. ch := 0C;
  141. END;
  142. END GetCh;
  143. PROCEDURE GetSym();
  144. BEGIN
  145. GetCh();
  146. WHILE ch=' ' DO
  147. GetCh();
  148. END;
  149. END GetSym;
  150. PROCEDURE StToNum(st : ARRAY OF CHAR; base : CARDINAL) : CARDINAL;
  151. VAR
  152. a, c : CARDINAL;
  153. BEGIN
  154. c := 0;
  155. FOR a := 0 TO M2Strings.Length(st)-1 DO
  156. c := c*base+(ORD(st[a])-ORD('0'));
  157. END;
  158. RETURN c;
  159. END StToNum;
  160. PROCEDURE AddToSet(VAR BSet : ARRAY OF BITSET);
  161. VAR
  162. StartNum, EndNum : CARDINAL;
  163. PROCEDURE SetNum(st : StRecord) : CARDINAL;
  164. BEGIN
  165. CASE st.type OF
  166. card :
  167. RETURN StToNum(st.Item,10);
  168. | octal :
  169. RETURN StToNum(st.Item,8);
  170. | char :
  171. RETURN ORD(st.Item[0]);
  172. END;
  173. RETURN 0;
  174. END SetNum;
  175. BEGIN
  176. (* AddToSet *)
  177. IF M2Strings.Length(EndSt.Item)>0 THEN
  178. IF M2Strings.Length(StartSt.Item)=0 THEN
  179. InclSet(BSet, SetNum(EndSt));
  180. ELSE
  181. StartNum := SetNum(StartSt);
  182. EndNum := SetNum(EndSt);
  183. WHILE StartNum<=EndNum DO
  184. InclSet(BSet, StartNum);
  185. INC(StartNum);
  186. END;
  187. END;
  188. END;
  189. StartSt.Item := 0C;
  190. EndSt.Item := 0C;
  191. END AddToSet;
  192. PROCEDURE AddToNumSt(ch : CHAR; VAR st : ARRAY OF CHAR);
  193. BEGIN
  194. StrEdit.Append(st, ch);
  195. END AddToNumSt;
  196. PROCEDURE DecodeDot();
  197. BEGIN
  198. IF ch='.' THEN
  199. StartSt := EndSt;
  200. EndSt.Item := 0C;
  201. ELSE
  202. Error := Dot;
  203. EndBool := TRUE;
  204. END;
  205. END DecodeDot;
  206. PROCEDURE DecodeNum();
  207. BEGIN
  208. EndSt.type := card;
  209. AddToNumSt(ch, EndSt.Item);
  210. GetCh();
  211. WHILE (ch>='0') AND (ch<='9') DO
  212. AddToNumSt(ch, EndSt.Item);
  213. GetCh();
  214. END;
  215. IF CAP(ch)='C' THEN
  216. EndSt.type := octal;
  217. GetCh();
  218. END;
  219. END DecodeNum;
  220. PROCEDURE DecodeQuote(QuoteCh : CHAR);
  221. BEGIN
  222. EndSt.Item[0] := ch;
  223. EndSt.Item[1] := 0C;
  224. EndSt.type := char;
  225. GetCh();
  226. IF ch#QuoteCh THEN
  227. Error := Quote;
  228. EndBool := TRUE;
  229. END;
  230. END DecodeQuote;
  231. PROCEDURE Statement();
  232. BEGIN
  233. (* Statement *)
  234. StartSt.Item := 0C;
  235. EndSt.Item := 0C;
  236. WHILE (NOT EndBool) DO
  237. IF ch="'" THEN
  238. (* Character *)
  239. GetCh();
  240. DecodeQuote("'");
  241. GetSym();
  242. ELSIF ch='"' THEN
  243. (* Character *)
  244. GetCh();
  245. DecodeQuote('"');
  246. GetSym();
  247. ELSIF (ch>='0') AND (ch<='9') THEN
  248. (* CARDINAL OR OCTAL Number *)
  249. DecodeNum();
  250. IF ch=' ' THEN
  251. GetSym();
  252. END;
  253. ELSE
  254. Error := statement;
  255. EndBool := TRUE;
  256. END;
  257. IF ch=0C THEN
  258. Error := incomplete;
  259. (* End of string reached *)
  260. EndBool := TRUE;
  261. ELSIF ch=',' THEN
  262. AddToSet(BSet);
  263. GetSym();
  264. ELSIF ch='.' THEN
  265. GetCh();
  266. DecodeDot();
  267. GetSym();
  268. ELSIF ch=EndSym THEN
  269. EndBool := TRUE;
  270. ELSE
  271. Error := statement;
  272. EndBool := TRUE;
  273. END;
  274. END;
  275. (* WHILE NOT EndBool *)
  276. END Statement;
  277. BEGIN
  278. (* AppendSet *)
  279. StrEdit.AssignStr( st, CodeSt );
  280. EndBool := FALSE;
  281. Error := 0;
  282. count := 0;
  283. ch := ' ';
  284. GetSym();
  285. IF ch=StartSym THEN
  286. GetSym();
  287. IF ch#EndSym THEN
  288. Statement();
  289. END;
  290. ELSE
  291. Error := begin;
  292. EndBool := TRUE;
  293. END;
  294. IF (ch=EndSym) AND (Error=0) THEN
  295. AddToSet(BSet);
  296. ELSIF Error=0 THEN
  297. Error := end;
  298. END;
  299. IF Error # 0 THEN
  300. StrEdit.AssignStr( 'Programmer error #', message );
  301. dumstr[0] := CHR(Error);
  302. StrEdit.Append( message, dumstr );
  303. StrEdit.Append( message, 'in AppendSet.' );
  304. ErrorManager.WARN( message );
  305. END;
  306. END AppendSet;
  307. PROCEDURE InclCh(VAR ChSet : ARRAY OF BITSET; ch : CHAR);
  308. VAR
  309. n : CARDINAL;
  310. BEGIN
  311. n := ORD(ch);
  312. InclSet(ChSet, n);
  313. END InclCh;
  314. PROCEDURE ExclCh(VAR ChSet : ARRAY OF BITSET; ch : CHAR);
  315. VAR
  316. n : CARDINAL;
  317. BEGIN
  318. n := ORD(ch);
  319. ExclSet(ChSet, n);
  320. END ExclCh;
  321. PROCEDURE InChSet(VAR ChSet : ARRAY OF BITSET; ch : CHAR) : BOOLEAN;
  322. VAR
  323. n : CARDINAL;
  324. bool : BOOLEAN;
  325. BEGIN
  326. n := ORD(ch);
  327. bool := InSet(ChSet,n);
  328. RETURN bool;
  329. END InChSet;
  330. PROCEDURE InTest(SetSt : ARRAY OF CHAR; TestCh : CHAR) : BOOLEAN;
  331. VAR
  332. TestSet : ChSetArray;
  333. BEGIN
  334. InitSet(TestSet);
  335. AppendSet(TestSet, SetSt);
  336. RETURN InChSet(TestSet,TestCh);
  337. END InTest;
  338. (* The procedures below assume that SetOne, SetTwo,
  339. and result are all of equal size. The compiler's
  340. range checking option ought to catch violations of
  341. that assumption, but particular implementations may
  342. not. The routines could be rewritten to deal with
  343. sets of unequal size, but that would take a lot more
  344. code and would probably be much slower. *)
  345. PROCEDURE SetUnion( SetOne, SetTwo: ARRAY OF BITSET;
  346. VAR result: ARRAY OF BITSET );
  347. VAR
  348. cnt, last: CARDINAL;
  349. BEGIN
  350. InitSet( result );
  351. last := HIGH( SetOne );
  352. FOR cnt := 0 TO last DO
  353. result[cnt] := SetOne[cnt] + SetTwo[cnt];
  354. END;
  355. END SetUnion;
  356. PROCEDURE SetDifference( SetOne, SetTwo: ARRAY OF
  357. BITSET; VAR result: ARRAY OF BITSET );
  358. VAR
  359. cnt, last: CARDINAL;
  360. BEGIN
  361. InitSet( result );
  362. last := HIGH( SetOne );
  363. FOR cnt := 0 TO last DO
  364. result[cnt] := SetOne[cnt] - SetTwo[cnt];
  365. END;
  366. END SetDifference;
  367. PROCEDURE SetIntersection( SetOne, SetTwo: ARRAY OF
  368. BITSET; VAR result: ARRAY OF BITSET );
  369. VAR
  370. cnt, last: CARDINAL;
  371. BEGIN
  372. InitSet( result );
  373. last := HIGH( SetOne );
  374. FOR cnt := 0 TO last DO
  375. result[cnt] := SetOne[cnt] * SetTwo[cnt];
  376. END;
  377. END SetIntersection;
  378. PROCEDURE SetSymmetricDiff( SetOne, SetTwo: ARRAY OF
  379. BITSET; VAR result: ARRAY OF BITSET );
  380. VAR
  381. cnt, last: CARDINAL;
  382. BEGIN
  383. InitSet( result );
  384. last := HIGH( SetOne );
  385. FOR cnt := 0 TO last DO
  386. result[cnt] := SetOne[cnt] / SetTwo[cnt];
  387. END;
  388. END SetSymmetricDiff;
  389. BEGIN
  390. Initialized := FALSE;
  391. Init();
  392. END BigSets.