|
|
1.1 root 1: /*
2: * File: oset.c
3: * Contents: compl, diff, inter, unions
4: */
5:
6: #include "../h/rt.h"
7:
8: /*
9: * ~x - complement cset x.
10: */
11:
12: /* >compl */
13: OpDcl(compl,1,"~")
14: {
15: register int i, j;
16: union block *bp;
17: int *cs, csbuf[CsetSize];
18: extern struct b_cset *alccset();
19:
20: blkreq((word)sizeof(struct b_cset));
21:
22: /*
23: * Arg1 must be a cset.
24: */
25: if (cvcset(&Arg1, &cs, csbuf) == NULL)
26: runerr(104, &Arg1);
27:
28: /*
29: * Allocate a new cset and then copy each cset word from Arg1
30: * itno the new cset words, complementing each.
31: */
32: bp = (union block *) alccset(0);
33: for (i = 0; i < CsetSize; i++) {
34: bp->cset.bits[i] = ~cs[i];
35: }
36: j = 0;
37: for (i = 0; i < CsetSize * CIntSize; i++) {
38: if (Testb(i, bp->cset.bits))
39: j++;
40: }
41: bp->cset.size = j;
42:
43: Arg0.dword = D_Cset;
44: BlkLoc(Arg0) = bp;
45: Return;
46: }
47: /* <compl */
48:
49:
50: /*
51: * x -- y - difference of csets x and y or of sets x and y.
52: */
53:
54: OpDcl(diff,2,"--")
55: {
56: register word i, j;
57: register union block *bp;
58: int *cs1, *cs2, csbuf1[CsetSize], csbuf2[CsetSize];
59: extern struct b_cset *alccset();
60: struct descrip *dp;
61: struct b_set *srcp, *dstp, *tstp;
62: struct b_selem *sep;
63: extern struct b_set *alcset();
64: extern struct b_selem *alcselem();
65:
66: if (Qual(Arg1) || Qual(Arg2))
67: goto skipsets;
68: if (Arg1.dword == D_Set && Arg2.dword != D_Set)
69: runerr(119,&Arg2);
70: if (Arg2.dword == D_Set && Arg1.dword != D_Set)
71: runerr(119,&Arg1);
72: if (Arg1.dword == D_Set && Arg2.dword == D_Set) {
73: /*
74: * Both x and y are sets - do set difference
75: * get enough space for a new set the size of x.
76: */
77: blkreq(sizeof(struct b_set) + BlkLoc(Arg1)->set.size *
78: sizeof(struct b_selem));
79: /*
80: * For each element in set x if it isn't in set y
81: * copy it directly into the result set.
82: */
83: srcp = (struct b_set *) BlkLoc(Arg1);
84: tstp = (struct b_set *) BlkLoc(Arg2);
85: Arg0.dword = D_Set;
86: dstp = alcset();
87: BlkLoc(Arg0) = (union block *) dstp;
88: for (i = 0; i < SSlots; i++) {
89: sep = (struct b_selem *) BlkLoc(srcp->sbucks[i]);
90: dp = &dstp->sbucks[i];
91: while (sep != NULL) {
92: if ( !locate((struct b_selem *)BlkLoc(tstp->sbucks[i]), sep) ) {
93: dp->dword = D_Selem;
94: BlkLoc(*dp) = (union block *) alcselem(&sep->setmem, sep->hashnum);
95: dp = &BlkLoc(*dp)->selem.clink;
96: dstp->size++;
97: }
98: sep = (struct b_selem *) BlkLoc(sep->clink);
99: }
100: }
101: }
102: else {
103: skipsets:
104: blkreq((word)sizeof(struct b_cset));
105:
106: /*
107: * x and y must be csets.
108: */
109: if (cvcset(&Arg1, &cs1, csbuf1) == NULL)
110: runerr(104, &Arg1);
111: if (cvcset(&Arg2, &cs2, csbuf2) == NULL)
112: runerr(104, &Arg2);
113:
114: /*
115: * Allocate a new cset and in each word of it, compute the value
116: * of the bitwise difference of the corresponding words in the
117: * x and y csets.
118: */
119: bp = (union block *) alccset(0);
120: for (i = 0; i < CsetSize; i++) {
121: bp->cset.bits[i] = cs1[i] & ~cs2[i];
122: }
123: j = 0;
124: for (i = 0; i < CsetSize*CIntSize; i++) {
125: if (Testb(i,bp->cset.bits))
126: j++;
127: }
128: bp->cset.size = j;
129:
130: Arg0.dword = D_Cset;
131: BlkLoc(Arg0) = bp;
132: }
133: Return;
134: }
135:
136:
137: /*
138: * x ** y - intersection of csets x and y or of sets x and y.
139: */
140:
141: OpDcl(inter,2,"**")
142: {
143: register word i, j;
144: union block *bp;
145: int *cs1, csbuf1[CsetSize], *cs2, csbuf2[CsetSize];
146: extern struct b_cset *alccset();
147: struct descrip *dp;
148: struct b_set *srcp, *tstp, *dstp;
149: struct b_selem *sep;
150: extern struct b_set *alcset();
151: extern struct b_selem *alcselem();
152:
153: if (Qual(Arg1) || Qual(Arg2))
154: goto skipsets;
155: if (Arg1.dword == D_Set && Arg2.dword != D_Set)
156: runerr(119,&Arg2);
157: if (Arg2.dword == D_Set && Arg1.dword != D_Set)
158: runerr(119,&Arg1);
159: if (Arg1.dword == D_Set && Arg2.dword == D_Set) {
160: /*
161: * Both x and y are sets - do set intersection
162: * get enough space for a new set the size of the smaller
163: * of the two sets.
164: */
165: blkreq(sizeof(struct b_set) + Min(BlkLoc(Arg1)->set.size,
166: BlkLoc(Arg2)->set.size) * sizeof(struct b_selem));
167: /*
168: * Using the smaller of the two sets as the source
169: * copy directly into the result each of its elements
170: * that are also members of the other set.
171: */
172: if (BlkLoc(Arg1)->set.size <= BlkLoc(Arg2)->set.size) {
173: srcp = (struct b_set *) BlkLoc(Arg1);
174: tstp = (struct b_set *) BlkLoc(Arg2);
175: }
176: else {
177: srcp = (struct b_set *) BlkLoc(Arg2);
178: tstp = (struct b_set *) BlkLoc(Arg1);
179: }
180: Arg0.dword = D_Set;
181: dstp = alcset();
182: BlkLoc(Arg0) = (union block *) dstp;
183: for (i = 0; i < SSlots; i++) {
184: sep = (struct b_selem *) BlkLoc(srcp->sbucks[i]);
185: dp = &dstp->sbucks[i];
186: while (sep != NULL) {
187: if (locate((struct b_selem *)BlkLoc(tstp->sbucks[i]), sep)) {
188: dp->dword = D_Selem;
189: BlkLoc(*dp) = (union block *) alcselem(&sep->setmem, sep->hashnum);
190: dp = &BlkLoc(*dp)->selem.clink;
191: dstp->size++;
192: }
193: sep = (struct b_selem *) BlkLoc(sep->clink);
194: }
195: }
196: }
197: else {
198: skipsets:
199: blkreq((word)sizeof(struct b_cset));
200:
201: /*
202: * x and y must be csets.
203: */
204: if (cvcset(&Arg1, &cs1, csbuf1) == NULL)
205: runerr(104, &Arg1);
206: if (cvcset(&Arg2, &cs2, csbuf2) == NULL)
207: runerr(104, &Arg2);
208:
209: /*
210: * Allocate a new cset and in each word of it, compute the value
211: * of the bitwise intersection of the corresponding words in the
212: * x and y csets.
213: */
214: bp = (union block *) alccset(0);
215: for (i = 0; i < CsetSize; i++) {
216: bp->cset.bits[i] = cs1[i] & cs2[i];
217: }
218: j = 0;
219: for (i = 0; i < CsetSize*CIntSize; i++) {
220: if (Testb(i,bp->cset.bits))
221: j++;
222: }
223: bp->cset.size = j;
224:
225: Arg0.dword = D_Cset;
226: BlkLoc(Arg0) = bp;
227: }
228: Return;
229: }
230:
231:
232: /*
233: * x ++ y - union of csets x and y or of sets x and y.
234: */
235:
236: OpDcl(unions,2,"++")
237: {
238: register word i, j;
239: union block *bp;
240: int *cs1, *cs2, csbuf1[CsetSize], csbuf2[CsetSize];
241: extern struct b_cset *alccset();
242: int res;
243: struct b_set *srcp, *tstp, *dstp;
244: struct b_selem *ep;
245: struct descrip *dp, *hook;
246: extern struct b_set *alcset();
247: extern struct b_selem *alcselem();
248: extern struct descrip *memb();
249:
250: if (Qual(Arg1) || Qual(Arg2))
251: goto skipsets;
252: if (Arg1.dword == D_Set && Arg2.dword != D_Set)
253: runerr(119,&Arg2);
254: if (Arg2.dword == D_Set && Arg1.dword != D_Set)
255: runerr(119,&Arg1);
256: if (Arg1.dword == D_Set && Arg2.dword == D_Set) {
257: /*
258: * Both x and y are sets - do set union
259: * get enough space for a set as big as x + y.
260: */
261: blkreq(sizeof(struct b_set) + (BlkLoc(Arg1)->set.size +
262: BlkLoc(Arg2)->set.size) * sizeof(struct b_selem));
263: /*
264: * Select the larger of the two sets as the source
265: * copy each element to a new set for the result
266: * then insert each member of the second set into the
267: * result set if it is not already there.
268: */
269: if (BlkLoc(Arg1)->set.size >= BlkLoc(Arg2)->set.size) {
270: srcp = (struct b_set *) BlkLoc(Arg1);
271: tstp = (struct b_set *) BlkLoc(Arg2);
272: }
273: else {
274: srcp = (struct b_set *) BlkLoc(Arg2);
275: tstp = (struct b_set *) BlkLoc(Arg1);
276: }
277: Arg0.dword = D_Set;
278: dstp = alcset();
279: BlkLoc(Arg0) = (union block *) dstp;
280: for (i = 0; i < SSlots; i++) {
281: ep = (struct b_selem *) BlkLoc(srcp->sbucks[i]);
282: dp = &dstp->sbucks[i];
283: while (ep != NULL) {
284: dp->dword = D_Selem;
285: BlkLoc(*dp) = (union block *) alcselem(&ep->setmem, ep->hashnum);
286: dp = &BlkLoc(*dp)->selem.clink;
287: dstp->size++;
288: ep = (struct b_selem *) BlkLoc(ep->clink);
289: }
290: }
291: for (i = 0; i < SSlots; i++) {
292: ep = (struct b_selem *) BlkLoc(tstp->sbucks[i]);
293: while (ep != NULL) {
294: hook = memb(dstp, &ep->setmem, ep->hashnum, &res);
295: if (res == 0)
296: addmem(dstp, alcselem(&ep->setmem, ep->hashnum), hook);
297: ep = (struct b_selem *) BlkLoc(ep->clink);
298: }
299: }
300: }
301: else {
302: skipsets:
303:
304: blkreq((word)sizeof(struct b_cset));
305:
306: /*
307: * x and y must be csets.
308: */
309: if (cvcset(&Arg1, &cs1, csbuf1) == NULL)
310: runerr(104, &Arg1);
311: if (cvcset(&Arg2, &cs2, csbuf2) == NULL)
312: runerr(104, &Arg2);
313:
314: /*
315: * Allocate a new cset and in each word of it, compute the value
316: * of the bitwise union of the corresponding words in the
317: * x and y csets.
318: */
319: bp = (union block *) alccset(0);
320: for (i = 0; i < CsetSize; i++) {
321: bp->cset.bits[i] = cs1[i] | cs2[i];
322: }
323: j = 0;
324: for (i = 0; i < CsetSize*CIntSize; i++) {
325: if (Testb(i,bp->cset.bits))
326: j++;
327: }
328: bp->cset.size = j;
329:
330: Arg0.dword = D_Cset;
331: BlkLoc(Arg0) = bp;
332: }
333: Return;
334: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.