package sdsi;
import sdsi.sexp.*;

/**
 * The (* set ...) special form tag. Used to say that any member of the
 * set is acceptable.
 */
class TESet
	extends TESpecial {

	TagExpression[] members;

	String mySpecialToken() { return "set"; }

	TESet(TagExpression[] members) {
		this.members = members;
		Sexp sexpary[] = new Sexp[members.length+2];
		sexpary[0] = new SexpString("*");
		sexpary[1] = new SexpString(mySpecialToken());
		for (int i=0; i<members.length; i++) {
			sexpary[i+2] = members[i].getSexp();
		}
		srep = new SexpList(sexpary);
	}

	public TESet(SexpList l)
		throws SexpParseException{
		super(l);
		int argc = countArgs();
		members = new TagExpression[argc];
		for (int i=0; i<argc; i++) {
			members[i] = TEParse.parse(l.elementAt(i+2));
		}
	}

	public TagExpression intersect(TagExpression otherTE) {
		TagExpression newTags[] = new TagExpression[members.length];
		int mi; 	// index into members
		int nti=0; 	// index into newTags
		for (mi=0; mi<members.length; mi++) {
			newTags[nti] = members[mi].intersect(otherTE);
			if (!(newTags[nti] instanceof TENull)) {
				nti++;
			}
		}
		if (nti==0) {
			// no intersections
			return TENull.getNull();
		} else if (nti==1) {
			// no need for a TESet anymore
			return newTags[0];
		} else {
			// shrink down the array and make a new TESet out of it.
			TagExpression newTags2[] = new TagExpression[nti];
			System.arraycopy(newTags, 0, newTags2, 0, nti);
			TESet newSet = new TESet(newTags2);

			// TODO: if otherTE was a TESet, we might end up with a
			// construct like (set a b (set c d)), which we should reduce
			// to (set a b c d) for clarity.

			return newSet;
		}
	}
}
