+ switch (op) {
+
+ /* --- The union operation isn't hard --- */
+
+ case clNode_union:
+ if (rnode == clNode_immed) {
+ if (type & clType_user) {
+ sym_find(&l->v.t, (char *)&r->v.u,
+ sizeof(r->v.u), sizeof(sym_base), 0);
+ } else
+ sym_find(&l->v.t, r->v.s, -1, sizeof(sym_base), 0);
+ } else {
+ sym_iter i;
+ sym_base *b;
+
+ for (sym_createIter(&i, &r->v.t); (b = sym_next(&i)) != 0; )
+ sym_find(&l->v.t, b->name, b->len, sizeof(sym_base), 0);
+ }
+ break;
+
+ /* --- Set difference is similar in spirit --- */
+
+ case clNode_diff:
+ if (rnode == clNode_immed) {
+ sym_base *f;
+
+ if (type & clType_user)
+ f = sym_find(&l->v.t, (char *)&r->v.u, sizeof(r->v.u), 0, 0);
+ else
+ f = sym_find(&l->v.t, r->v.s, -1, 0, 0);
+ if (f)
+ sym_remove(&l->v.t, f);
+ } else {
+ sym_iter i;
+ sym_base *b, *f;
+
+ for (sym_createIter(&i, &r->v.t); (b = sym_next(&i)) != 0; ) {
+ if ((f = sym_find(&l->v.t, b->name, b->len, 0, 0)) != 0)
+ sym_remove(&l->v.t, f);
+ }
+ }
+ break;
+
+ /* --- Intersection is wild and wacky --- */
+
+ case clNode_isect:
+ if (rnode == clNode_immed) {
+ sym_base *f;
+
+ if (type & clType_user)
+ f = sym_find(&l->v.t, (char *)&r->v.u, sizeof(r->v.u), 0, 0);
+ else
+ f = sym_find(&l->v.t, r->v.s, -1, 0, 0);
+ if (f) {
+ class_dec(l);
+ return (r);
+ } else {
+ class_dec(l);
+ class_dec(r);
+ return (class_none);
+ }
+ } else {
+ sym_iter i;
+ sym_base *b;
+
+ for (sym_createIter(&i, &l->v.t); (b = sym_next(&i)) != 0; ) {
+ if (!sym_find(&r->v.t, b->name, b->len, 0, 0))
+ sym_remove(&l->v.t, b);
+ }
+ }
+ break;
+ }
+
+ /* --- Now trim the @l@ table to size --- *