| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | #include "master.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | namespace factor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | cell string_nth(string* str, cell index) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* If high bit is set, the most significant 16 bits of the char
 | 
					
						
							|  |  |  | 	come from the aux vector. The least significant bit of the | 
					
						
							|  |  |  | 	corresponding aux vector entry is negated, so that we can | 
					
						
							|  |  |  | 	XOR the two components together and get the original code point | 
					
						
							|  |  |  | 	back. */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	cell lo_bits = str->data()[index]; | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if((lo_bits & 0x80) == 0) | 
					
						
							|  |  |  | 		return lo_bits; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		byte_array *aux = untag<byte_array>(str->aux); | 
					
						
							|  |  |  | 		cell hi_bits = aux->data<u16>()[index]; | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | 		return (hi_bits << 7) ^ lo_bits; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | void set_string_nth_fast(string *str, cell index, cell ch) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	str->data()[index] = ch; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | void set_string_nth_slow(string *str_, cell index, cell ch) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	gc_root<string> str(str_); | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	byte_array *aux; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	str->data()[index] = ((ch & 0x7f) | 0x80); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	if(str->aux == F) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		/* We don't need to pre-initialize the
 | 
					
						
							|  |  |  | 		byte array with any data, since we | 
					
						
							|  |  |  | 		only ever read from the aux vector | 
					
						
							|  |  |  | 		if the most significant bit of a | 
					
						
							|  |  |  | 		character is set. Initially all of | 
					
						
							|  |  |  | 		the bits are clear. */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		aux = allot_array_internal<byte_array>(untag_fixnum(str->length) * sizeof(u16)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		write_barrier(str.untagged()); | 
					
						
							|  |  |  | 		str->aux = tag<byte_array>(aux); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		aux = untag<byte_array>(str->aux); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | 	aux->data<u16>()[index] = ((ch >> 7) ^ 1); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* allocates memory */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | void set_string_nth(string *str, cell index, cell ch) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							|  |  |  | 	if(ch <= 0x7f) | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		set_string_nth_fast(str,index,ch); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	else | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		set_string_nth_slow(str,index,ch); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | /* Allocates memory */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | string *allot_string_internal(cell capacity) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	string *str = allot<string>(string_size(capacity)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	str->length = tag_fixnum(capacity); | 
					
						
							|  |  |  | 	str->hashcode = F; | 
					
						
							|  |  |  | 	str->aux = F; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	return str; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | /* Allocates memory */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | void fill_string(string *str_, cell start, cell capacity, cell fill) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	gc_root<string> str(str_); | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	if(fill <= 0x7f) | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		memset(&str->data()[start],fill,capacity - start); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		cell i; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for(i = start; i < capacity; i++) | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 			set_string_nth(str.untagged(),i,fill); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | /* Allocates memory */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | string *allot_string(cell capacity, cell fill) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	gc_root<string> str(allot_string_internal(capacity)); | 
					
						
							|  |  |  | 	fill_string(str.untagged(),0,capacity,fill); | 
					
						
							|  |  |  | 	return str.untagged(); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | PRIMITIVE(string) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	cell initial = to_cell(dpop()); | 
					
						
							|  |  |  | 	cell length = unbox_array_size(); | 
					
						
							|  |  |  | 	dpush(tag<string>(allot_string(length,initial))); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | static bool reallot_string_in_place_p(string *str, cell capacity) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 16:11:31 -04:00
										 |  |  | 	return in_zone(&nursery,str) | 
					
						
							|  |  |  | 		&& (str->aux == F || in_zone(&nursery,untag<byte_array>(str->aux))) | 
					
						
							|  |  |  | 		&& capacity <= string_capacity(str); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | string* reallot_string(string *str_, cell capacity) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	gc_root<string> str(str_); | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	if(reallot_string_in_place_p(str.untagged(),capacity)) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		str->length = tag_fixnum(capacity); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		if(str->aux != F) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 			byte_array *aux = untag<byte_array>(str->aux); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 			aux->capacity = tag_fixnum(capacity * 2); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		return str.untagged(); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		cell to_copy = string_capacity(str.untagged()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 		if(capacity < to_copy) | 
					
						
							|  |  |  | 			to_copy = capacity; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		gc_root<string> new_str(allot_string_internal(capacity)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		memcpy(new_str->data(),str->data(),to_copy); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		if(str->aux != F) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 			byte_array *new_aux = allot_byte_array(capacity * sizeof(u16)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 			write_barrier(new_str.untagged()); | 
					
						
							|  |  |  | 			new_str->aux = tag<byte_array>(new_aux); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 			byte_array *aux = untag<byte_array>(str->aux); | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | 			memcpy(new_aux->data<u16>(),aux->data<u16>(),to_copy * sizeof(u16)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		fill_string(new_str.untagged(),to_copy,capacity,'\0'); | 
					
						
							|  |  |  | 		return new_str.untagged(); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | PRIMITIVE(resize_string) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	string* str = untag_check<string>(dpop()); | 
					
						
							|  |  |  | 	cell capacity = unbox_array_size(); | 
					
						
							|  |  |  | 	dpush(tag<string>(reallot_string(str,capacity))); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | PRIMITIVE(string_nth) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	string *str = untag<string>(dpop()); | 
					
						
							|  |  |  | 	cell index = untag_fixnum(dpop()); | 
					
						
							|  |  |  | 	dpush(tag_fixnum(string_nth(str,index))); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | PRIMITIVE(set_string_nth_fast) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	string *str = untag<string>(dpop()); | 
					
						
							|  |  |  | 	cell index = untag_fixnum(dpop()); | 
					
						
							|  |  |  | 	cell value = untag_fixnum(dpop()); | 
					
						
							|  |  |  | 	set_string_nth_fast(str,index,value); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | PRIMITIVE(set_string_nth_slow) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	string *str = untag<string>(dpop()); | 
					
						
							|  |  |  | 	cell index = untag_fixnum(dpop()); | 
					
						
							|  |  |  | 	cell value = untag_fixnum(dpop()); | 
					
						
							|  |  |  | 	set_string_nth_slow(str,index,value); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | } |