| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- IMPLEMENTATION MODULE BigSets;
- (*
- * REPERTOIRE
- * Release 1.6
- * By Charles Bradford and Cole Brecheen
- * (c) Copyright 1985-1992 PMI
- * Green Bay, Wisconsin
- * All rights reserved
- * (414) 468-6040
- *
- * $Header: D:/logfiles/mods/bigsets.mov 1.3 10 Mar 1991 15:25:08 coleb $
- *
- *
- * Written and contributed by Wilbur C. Andrews.
- *
- *)
- IMPORT ErrorManager;
- IMPORT M2Strings;
- IMPORT StrEdit;
- VAR
- Initialized : BOOLEAN;
- PROCEDURE Init();
- BEGIN
- IF Initialized THEN
- RETURN;
- ELSE
- Initialized := TRUE;
- END;
- ErrorManager.Init();
- M2Strings.Init();
- StrEdit.Init();
- InitSet(DigitSet);
- InitSet(ChSet);
- AppendSet(DigitSet, "{'0'..'9'}");
- AppendSet(ChSet, "{' '..'~'}");
- END Init;
- CONST
- begin = 1;
- Dot = 2;
- Quote = 3;
- statement = 4;
- incomplete = 5;
- end = 7;
- StartSym = '{';
- EndSym = '}';
- PROCEDURE SetStuff(n : CARDINAL; VAR ArrayNo, Index : CARDINAL);
- BEGIN
- IF n=0 THEN
- ArrayNo := 0;
- Index := 0;
- ELSE
- ArrayNo := n DIV BitSetSize;
- Index := n MOD BitSetSize;
- END;
- END SetStuff;
- PROCEDURE InitSet(VAR BSet : ARRAY OF BITSET);
- VAR
- n : CARDINAL;
- BEGIN
- FOR n := 0 TO HIGH(BSet) DO
- BSet[n] := {};
- END;
- END InitSet;
- PROCEDURE AssignSet(Set1 : ARRAY OF BITSET; VAR Set2 : ARRAY OF
- BITSET);
- VAR
- a : CARDINAL;
- BEGIN
- FOR a := 0 TO HIGH(Set1) DO
- Set2[a] := Set1[a];
- END;
- END AssignSet;
- PROCEDURE Check( ArrayNumber, LastBitSet: CARDINAL );
- BEGIN
- IF ArrayNumber > LastBitSet THEN
- ErrorManager.WARN( "Set element out of range");
- END;
- END Check;
- PROCEDURE InclSet(VAR BSet : ARRAY OF BITSET; n : CARDINAL);
- VAR
- ArrayNo, Index : CARDINAL;
- BEGIN
- SetStuff(n, ArrayNo, Index);
- Check( ArrayNo, HIGH(BSet) );
- INCL(BSet[ArrayNo], Index);
- END InclSet;
- PROCEDURE ExclSet(VAR BSet : ARRAY OF BITSET; n : CARDINAL);
- VAR
- ArrayNo, Index : CARDINAL;
- BEGIN
- SetStuff(n, ArrayNo, Index);
- Check( ArrayNo, HIGH(BSet) );
- EXCL(BSet[ArrayNo], Index);
- END ExclSet;
- PROCEDURE InSet(VAR BSet : ARRAY OF BITSET; n : CARDINAL) : BOOLEAN;
- VAR
- ArrayNo, Index : CARDINAL;
- bool : BOOLEAN;
- BEGIN
- SetStuff(n, ArrayNo, Index);
- Check( ArrayNo, HIGH(BSet) );
- bool := Index IN BSet[ArrayNo];
- RETURN bool;
- END InSet;
- PROCEDURE EqualSet(VAR SetOne, SetTwo : ARRAY OF BITSET) : BOOLEAN;
- VAR
- EqualBool : BOOLEAN;
- a : CARDINAL;
- BEGIN
- a := 0;
- EqualBool := TRUE;
- WHILE (a<=HIGH(SetOne)) AND EqualBool DO
- EqualBool := SetOne[a]=SetTwo[a];
- a := a+1;
- END;
- RETURN EqualBool;
- END EqualSet;
- PROCEDURE AppendSet(VAR BSet : ARRAY OF BITSET; st : ARRAY OF CHAR);
- TYPE
- SetStType = ARRAY [0..79] OF CHAR;
- StRecord =
- RECORD
- Item : SetStType;
- type : (card, octal, char);
- END;
- VAR
- ch : CHAR;
- Error, count : CARDINAL;
- CodeSt : SetStType;
- StartSt, EndSt : StRecord;
- EndBool : BOOLEAN;
- message: ARRAY [0..79] OF CHAR;
- dumstr: ARRAY [0..0] OF CHAR;
- PROCEDURE GetCh();
- BEGIN
- IF count<=(M2Strings.Length(CodeSt)-1) THEN
- ch := CodeSt[count];
- INC(count);
- ELSE
- ch := 0C;
- END;
- END GetCh;
- PROCEDURE GetSym();
- BEGIN
- GetCh();
- WHILE ch=' ' DO
- GetCh();
- END;
- END GetSym;
- PROCEDURE StToNum(st : ARRAY OF CHAR; base : CARDINAL) : CARDINAL;
- VAR
- a, c : CARDINAL;
- BEGIN
- c := 0;
- FOR a := 0 TO M2Strings.Length(st)-1 DO
- c := c*base+(ORD(st[a])-ORD('0'));
- END;
- RETURN c;
- END StToNum;
- PROCEDURE AddToSet(VAR BSet : ARRAY OF BITSET);
- VAR
- StartNum, EndNum : CARDINAL;
- PROCEDURE SetNum(st : StRecord) : CARDINAL;
- BEGIN
- CASE st.type OF
- card :
- RETURN StToNum(st.Item,10);
- | octal :
- RETURN StToNum(st.Item,8);
- | char :
- RETURN ORD(st.Item[0]);
- END;
- RETURN 0;
- END SetNum;
- BEGIN
- (* AddToSet *)
- IF M2Strings.Length(EndSt.Item)>0 THEN
- IF M2Strings.Length(StartSt.Item)=0 THEN
- InclSet(BSet, SetNum(EndSt));
- ELSE
- StartNum := SetNum(StartSt);
- EndNum := SetNum(EndSt);
- WHILE StartNum<=EndNum DO
- InclSet(BSet, StartNum);
- INC(StartNum);
- END;
- END;
- END;
- StartSt.Item := 0C;
- EndSt.Item := 0C;
- END AddToSet;
- PROCEDURE AddToNumSt(ch : CHAR; VAR st : ARRAY OF CHAR);
- BEGIN
- StrEdit.Append(st, ch);
- END AddToNumSt;
- PROCEDURE DecodeDot();
- BEGIN
- IF ch='.' THEN
- StartSt := EndSt;
- EndSt.Item := 0C;
- ELSE
- Error := Dot;
- EndBool := TRUE;
- END;
- END DecodeDot;
- PROCEDURE DecodeNum();
- BEGIN
- EndSt.type := card;
- AddToNumSt(ch, EndSt.Item);
- GetCh();
- WHILE (ch>='0') AND (ch<='9') DO
- AddToNumSt(ch, EndSt.Item);
- GetCh();
- END;
- IF CAP(ch)='C' THEN
- EndSt.type := octal;
- GetCh();
- END;
- END DecodeNum;
- PROCEDURE DecodeQuote(QuoteCh : CHAR);
- BEGIN
- EndSt.Item[0] := ch;
- EndSt.Item[1] := 0C;
- EndSt.type := char;
- GetCh();
- IF ch#QuoteCh THEN
- Error := Quote;
- EndBool := TRUE;
- END;
- END DecodeQuote;
- PROCEDURE Statement();
- BEGIN
- (* Statement *)
- StartSt.Item := 0C;
- EndSt.Item := 0C;
- WHILE (NOT EndBool) DO
- IF ch="'" THEN
- (* Character *)
- GetCh();
- DecodeQuote("'");
- GetSym();
- ELSIF ch='"' THEN
- (* Character *)
- GetCh();
- DecodeQuote('"');
- GetSym();
- ELSIF (ch>='0') AND (ch<='9') THEN
- (* CARDINAL OR OCTAL Number *)
- DecodeNum();
- IF ch=' ' THEN
- GetSym();
- END;
- ELSE
- Error := statement;
- EndBool := TRUE;
- END;
- IF ch=0C THEN
- Error := incomplete;
- (* End of string reached *)
- EndBool := TRUE;
- ELSIF ch=',' THEN
- AddToSet(BSet);
- GetSym();
- ELSIF ch='.' THEN
- GetCh();
- DecodeDot();
- GetSym();
- ELSIF ch=EndSym THEN
- EndBool := TRUE;
- ELSE
- Error := statement;
- EndBool := TRUE;
- END;
- END;
- (* WHILE NOT EndBool *)
- END Statement;
- BEGIN
- (* AppendSet *)
- StrEdit.AssignStr( st, CodeSt );
- EndBool := FALSE;
- Error := 0;
- count := 0;
- ch := ' ';
- GetSym();
- IF ch=StartSym THEN
- GetSym();
- IF ch#EndSym THEN
- Statement();
- END;
- ELSE
- Error := begin;
- EndBool := TRUE;
- END;
- IF (ch=EndSym) AND (Error=0) THEN
- AddToSet(BSet);
- ELSIF Error=0 THEN
- Error := end;
- END;
- IF Error # 0 THEN
- StrEdit.AssignStr( 'Programmer error #', message );
- dumstr[0] := CHR(Error);
- StrEdit.Append( message, dumstr );
- StrEdit.Append( message, 'in AppendSet.' );
- ErrorManager.WARN( message );
- END;
- END AppendSet;
- PROCEDURE InclCh(VAR ChSet : ARRAY OF BITSET; ch : CHAR);
- VAR
- n : CARDINAL;
- BEGIN
- n := ORD(ch);
- InclSet(ChSet, n);
- END InclCh;
- PROCEDURE ExclCh(VAR ChSet : ARRAY OF BITSET; ch : CHAR);
- VAR
- n : CARDINAL;
- BEGIN
- n := ORD(ch);
- ExclSet(ChSet, n);
- END ExclCh;
- PROCEDURE InChSet(VAR ChSet : ARRAY OF BITSET; ch : CHAR) : BOOLEAN;
- VAR
- n : CARDINAL;
- bool : BOOLEAN;
- BEGIN
- n := ORD(ch);
- bool := InSet(ChSet,n);
- RETURN bool;
- END InChSet;
- PROCEDURE InTest(SetSt : ARRAY OF CHAR; TestCh : CHAR) : BOOLEAN;
- VAR
- TestSet : ChSetArray;
- BEGIN
- InitSet(TestSet);
- AppendSet(TestSet, SetSt);
- RETURN InChSet(TestSet,TestCh);
- END InTest;
- (* The procedures below assume that SetOne, SetTwo,
- and result are all of equal size. The compiler's
- range checking option ought to catch violations of
- that assumption, but particular implementations may
- not. The routines could be rewritten to deal with
- sets of unequal size, but that would take a lot more
- code and would probably be much slower. *)
- PROCEDURE SetUnion( SetOne, SetTwo: ARRAY OF BITSET;
- VAR result: ARRAY OF BITSET );
- VAR
- cnt, last: CARDINAL;
- BEGIN
- InitSet( result );
- last := HIGH( SetOne );
- FOR cnt := 0 TO last DO
- result[cnt] := SetOne[cnt] + SetTwo[cnt];
- END;
- END SetUnion;
- PROCEDURE SetDifference( SetOne, SetTwo: ARRAY OF
- BITSET; VAR result: ARRAY OF BITSET );
- VAR
- cnt, last: CARDINAL;
- BEGIN
- InitSet( result );
- last := HIGH( SetOne );
- FOR cnt := 0 TO last DO
- result[cnt] := SetOne[cnt] - SetTwo[cnt];
- END;
- END SetDifference;
- PROCEDURE SetIntersection( SetOne, SetTwo: ARRAY OF
- BITSET; VAR result: ARRAY OF BITSET );
- VAR
- cnt, last: CARDINAL;
- BEGIN
- InitSet( result );
- last := HIGH( SetOne );
- FOR cnt := 0 TO last DO
- result[cnt] := SetOne[cnt] * SetTwo[cnt];
- END;
- END SetIntersection;
- PROCEDURE SetSymmetricDiff( SetOne, SetTwo: ARRAY OF
- BITSET; VAR result: ARRAY OF BITSET );
- VAR
- cnt, last: CARDINAL;
- BEGIN
- InitSet( result );
- last := HIGH( SetOne );
- FOR cnt := 0 TO last DO
- result[cnt] := SetOne[cnt] / SetTwo[cnt];
- END;
- END SetSymmetricDiff;
- BEGIN
- Initialized := FALSE;
- Init();
- END BigSets.
|