forsyth20121205-174063a80cc13 years agoHistory
226 lines · 3.8 KB · Brainfuck
RawDownload
implement Sets;include "sys.m";	sys: Sys;include "sets32.m"; init(){	sys = load Sys Sys->PATH;} set(): Set{	return Set(0);} BITS: con 32;MSB: con 1 << (BITS - 1); Set.X(s1: self Set, o: int, s2: Set): Set{	return Set(op(o, s1.s, s2.s));} Set.invert(s: self Set): Set{	return Set(~s.s);} Set.add(s: self Set, n: int): Set{	return Set(s.s | (1 << n));} Set.del(s: self Set, n: int): Set{	return Set(s.s & ~(1 << n));} Set.addlist(s: self Set, ns: list of int): Set{	for (; ns != nil; ns = tl ns)		s.s |= (1 << hd ns);	return s;} Set.holds(s: self Set, n: int): int{	return s.s & (1 << n);} Set.str(s: self Set): string{	msb := s.s >> (BITS - 1); 	# discard all top bits that are the same as msb	t := 16rf << (BITS - 4);	sig := 8;	while (t != 0) {		if ((msb & t) != (s.s & t))			break;		sig--;		t = (t >> 4) & 16r0fffffff;		# logical shift right	}	str: string;	if (sig > 0) {		top := ~MSB & s.s;		if (sig < 8)		# shifting left by 32 bits is undefined.			top &= (1 << (sig << 2)) - 1;		str = sys->sprint("%.*ux", sig, top);	}	return str + ":" + string (msb & 1);} Set.bytes(s: self Set, n: int): array of byte{	m := (s.limit() >> 3) + 1;	if(m > n)		n = m;	d := array[n] of byte;	case len d {	1 =>		d[0] = byte s.s;	2 =>		d[0] = byte s.s;		d[1] = byte (s.s >> 8);	3 =>		d[0] = byte s.s;		d[1] = byte (s.s >> 8);		d[2] = byte (s.s >> 16);	4 =>		d[0] = byte s.s;		d[1] = byte (s.s >> 8);		d[2] = byte (s.s >> 16);		d[3] = byte (s.s >> 24);	* =>		d[0] = byte s.s;		d[1] = byte (s.s >> 8);		d[2] = byte (s.s >> 16);		d[3] = byte (s.s >> 24);		msb := byte (s.s >> (BITS - 1));		# sign extension		for(i := 4; i < len d; i++)			d[i] = msb;	}	return d;}		bytes2set(d: array of byte): Set{	if(len d == 0)		return Set(0);	msb := ~(int (d[len d - 1] >> 7) - 1);	v: int;	case len d {	1 =>		v = int d[0] | (msb & int 16rffffff00);	2 =>		v = int d[0] | (int d[1] << 8) | (msb & int 16rffff0000);	3 =>		v = int d[0] | (int d[1] << 8) | (int d[2] << 16) | (msb & int 16rff000000);	* or		# XXX could raise (or return) an error for len d > 4	4 =>		v = int d[0] | (int d[1] << 8) | (int d[2] << 16) | (int d[3] << 24);	}	return Set(v);}  Set.debugstr(s: self Set): string{	return sys->sprint("%ux", s.s);} Set.eq(s1: self Set, s2: Set): int{	return s1.s == s2.s;} Set.isempty(s: self Set): int{	return s.s == 0;} Set.msb(s: self Set): int{	return (s.s & MSB) != 0;} Set.limit(s: self Set): int{	m := s.s >> (BITS - 1);	# sign extension	return topbit(s.s ^ m);} topbit(v: int): int{	if (v == 0)		return 0;	(b, n, mask) := (1, 16, int 16rffff0000);	while (n != 0) {		if (v & mask) {			b += n;			v >>= n;		# could return if v==0 here if we thought it worth it		}		n >>= 1;		mask >>= n;	}	return b;}  str2set(str: string): Set{	n := len str;	if (n < 2 || str[n - 2] != ':')		return Set(0);	c := str[n - 1];	if (c != '0' && c != '1')		return Set(0);	n -= 2;	msb := ~(c - '1');	# XXX should we give some sort of error if there	# are more bits than we can hold?	return Set((hex2int(str[0:n], msb) & ~MSB) | (msb & MSB));} hex2int(s: string, fill: int): int{	n := fill;	for (i := 0; i < len s; i++) {		c := s[i];		if (c >= '0' && c <= '9')			c -= '0';		else if (c >= 'a' && c <= 'f')			c -= 'a' - 10;		else if (c >= 'A' && c <= 'F')			c -= 'A' - 10;		else			c = 0;		n = (n << 4) | c;	}	return n;}  op(o: int, a, b: int): int{	case o &  2r1111 {	2r0000 => return 0;	2r0001 => return ~(a | b);	2r0010 => return a & ~b;	2r0011 => return ~b;	2r0100 => return ~a & b;	2r0101 => return ~a;	2r0110 => return a ^ b;	2r0111 => return ~(a & b);	2r1000 => return a & b;	2r1001 => return ~(a ^ b);	2r1010 => return a;	2r1011 => return a | ~b;	2r1100 => return b;	2r1101 => return ~a | b;	2r1110 => return a | b;	2r1111 => return ~0;	}	return 0;}