| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | #include "master.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* FFI calls this */ | 
					
						
							|  |  |  | void box_boolean(bool value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	dpush(value ? T : F); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* FFI calls this */ | 
					
						
							|  |  |  | bool to_boolean(CELL value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return value != F; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-03 19:39:56 -04:00
										 |  |  | CELL clone_object(CELL object) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	CELL size = object_size(object); | 
					
						
							|  |  |  | 	if(size == 0) | 
					
						
							|  |  |  | 		return object; | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 		REGISTER_ROOT(object); | 
					
						
							|  |  |  | 		void *new_obj = allot_object(type_of(object),size); | 
					
						
							|  |  |  | 		UNREGISTER_ROOT(object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		CELL tag = TAG(object); | 
					
						
							|  |  |  | 		memcpy(new_obj,(void*)UNTAG(object),size); | 
					
						
							|  |  |  | 		return RETAG(new_obj,tag); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | DEFINE_PRIMITIVE(clone) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-07-03 19:39:56 -04:00
										 |  |  | 	drepl(clone_object(dpeek())); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | F_WORD *allot_word(CELL vocab, CELL name) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	REGISTER_ROOT(vocab); | 
					
						
							|  |  |  | 	REGISTER_ROOT(name); | 
					
						
							|  |  |  | 	F_WORD *word = allot_object(WORD_TYPE,sizeof(F_WORD)); | 
					
						
							|  |  |  | 	UNREGISTER_ROOT(name); | 
					
						
							|  |  |  | 	UNREGISTER_ROOT(vocab); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-04 08:08:03 -04:00
										 |  |  | 	word->hashcode = tag_fixnum((rand() << 16) ^ rand()); | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	word->vocabulary = vocab; | 
					
						
							|  |  |  | 	word->name = name; | 
					
						
							|  |  |  | 	word->def = userenv[UNDEFINED_ENV]; | 
					
						
							|  |  |  | 	word->props = F; | 
					
						
							|  |  |  | 	word->counter = tag_fixnum(0); | 
					
						
							|  |  |  | 	word->compiledp = F; | 
					
						
							| 
									
										
										
										
											2008-07-11 18:25:46 -04:00
										 |  |  | 	word->subprimitive = F; | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	word->profiling = NULL; | 
					
						
							| 
									
										
										
										
											2008-04-13 10:20:19 -04:00
										 |  |  | 	word->code = NULL; | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	REGISTER_UNTAGGED(word); | 
					
						
							|  |  |  | 	default_word_code(word,true); | 
					
						
							|  |  |  | 	UNREGISTER_UNTAGGED(word); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	REGISTER_UNTAGGED(word); | 
					
						
							|  |  |  | 	update_word_xt(word); | 
					
						
							|  |  |  | 	UNREGISTER_UNTAGGED(word); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	return word; | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | /* <word> ( name vocabulary -- word ) */ | 
					
						
							|  |  |  | DEFINE_PRIMITIVE(word) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	CELL vocab = dpop(); | 
					
						
							|  |  |  | 	CELL name = dpop(); | 
					
						
							|  |  |  | 	dpush(tag_object(allot_word(vocab,name))); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-14 18:56:47 -05:00
										 |  |  | /* word-xt ( word -- start end ) */ | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | DEFINE_PRIMITIVE(word_xt) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-02-14 18:56:47 -05:00
										 |  |  | 	F_WORD *word = untag_word(dpop()); | 
					
						
							|  |  |  | 	F_COMPILED *code = word->code; | 
					
						
							|  |  |  | 	dpush(allot_cell((CELL)code + sizeof(F_COMPILED))); | 
					
						
							|  |  |  | 	dpush(allot_cell((CELL)code + sizeof(F_COMPILED) + code->code_length)); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | DEFINE_PRIMITIVE(wrapper) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	F_WRAPPER *wrapper = allot_object(WRAPPER_TYPE,sizeof(F_WRAPPER)); | 
					
						
							|  |  |  | 	wrapper->object = dpeek(); | 
					
						
							|  |  |  | 	drepl(tag_object(wrapper)); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | /* Arrays */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* the array is full of undefined data, and must be correctly filled before the
 | 
					
						
							|  |  |  | next GC. size is in cells */ | 
					
						
							|  |  |  | F_ARRAY *allot_array_internal(CELL type, CELL capacity) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	F_ARRAY *array = allot_object(type,array_size(capacity)); | 
					
						
							|  |  |  | 	array->capacity = tag_fixnum(capacity); | 
					
						
							|  |  |  | 	return array; | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | /* make a new array with an initial element */ | 
					
						
							|  |  |  | F_ARRAY *allot_array(CELL type, CELL capacity, CELL fill) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	int i; | 
					
						
							|  |  |  | 	REGISTER_ROOT(fill); | 
					
						
							|  |  |  | 	F_ARRAY* array = allot_array_internal(type, capacity); | 
					
						
							|  |  |  | 	UNREGISTER_ROOT(fill); | 
					
						
							|  |  |  | 	if(fill == 0) | 
					
						
							|  |  |  | 		memset((void*)AREF(array,0),'\0',capacity * CELLS); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2008-04-13 10:20:19 -04:00
										 |  |  | 		/* No need for write barrier here. Either the object is in
 | 
					
						
							|  |  |  | 		the nursery, or it was allocated directly in tenured space | 
					
						
							|  |  |  | 		and the write barrier is already hit for us in that case. */ | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 		for(i = 0; i < capacity; i++) | 
					
						
							| 
									
										
										
										
											2008-04-13 10:20:19 -04:00
										 |  |  | 			put(AREF(array,i),fill); | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return array; | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | /* push a new array on the stack */ | 
					
						
							|  |  |  | DEFINE_PRIMITIVE(array) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	CELL initial = dpop(); | 
					
						
							|  |  |  | 	CELL size = unbox_array_size(); | 
					
						
							|  |  |  | 	dpush(tag_object(allot_array(ARRAY_TYPE,size,initial))); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  | CELL allot_array_1(CELL obj) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	REGISTER_ROOT(obj); | 
					
						
							|  |  |  | 	F_ARRAY *a = allot_array_internal(ARRAY_TYPE,1); | 
					
						
							|  |  |  | 	UNREGISTER_ROOT(obj); | 
					
						
							|  |  |  | 	set_array_nth(a,0,obj); | 
					
						
							|  |  |  | 	return tag_object(a); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | CELL allot_array_2(CELL v1, CELL v2) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	REGISTER_ROOT(v1); | 
					
						
							|  |  |  | 	REGISTER_ROOT(v2); | 
					
						
							|  |  |  | 	F_ARRAY *a = allot_array_internal(ARRAY_TYPE,2); | 
					
						
							|  |  |  | 	UNREGISTER_ROOT(v2); | 
					
						
							|  |  |  | 	UNREGISTER_ROOT(v1); | 
					
						
							|  |  |  | 	set_array_nth(a,0,v1); | 
					
						
							|  |  |  | 	set_array_nth(a,1,v2); | 
					
						
							|  |  |  | 	return tag_object(a); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CELL allot_array_4(CELL v1, CELL v2, CELL v3, CELL v4) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	REGISTER_ROOT(v1); | 
					
						
							|  |  |  | 	REGISTER_ROOT(v2); | 
					
						
							|  |  |  | 	REGISTER_ROOT(v3); | 
					
						
							|  |  |  | 	REGISTER_ROOT(v4); | 
					
						
							|  |  |  | 	F_ARRAY *a = allot_array_internal(ARRAY_TYPE,4); | 
					
						
							|  |  |  | 	UNREGISTER_ROOT(v4); | 
					
						
							|  |  |  | 	UNREGISTER_ROOT(v3); | 
					
						
							|  |  |  | 	UNREGISTER_ROOT(v2); | 
					
						
							|  |  |  | 	UNREGISTER_ROOT(v1); | 
					
						
							|  |  |  | 	set_array_nth(a,0,v1); | 
					
						
							|  |  |  | 	set_array_nth(a,1,v2); | 
					
						
							|  |  |  | 	set_array_nth(a,2,v3); | 
					
						
							|  |  |  | 	set_array_nth(a,3,v4); | 
					
						
							|  |  |  | 	return tag_object(a); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | F_ARRAY *reallot_array(F_ARRAY* array, CELL capacity, CELL fill) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	F_ARRAY* new_array; | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	CELL to_copy = array_capacity(array); | 
					
						
							|  |  |  | 	if(capacity < to_copy) | 
					
						
							|  |  |  | 		to_copy = capacity; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	REGISTER_UNTAGGED(array); | 
					
						
							|  |  |  | 	REGISTER_ROOT(fill); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	new_array = allot_array_internal(untag_header(array->header),capacity); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	UNREGISTER_ROOT(fill); | 
					
						
							|  |  |  | 	UNREGISTER_UNTAGGED(array); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memcpy(new_array + 1,array + 1,to_copy * CELLS); | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	for(i = to_copy; i < capacity; i++) | 
					
						
							| 
									
										
										
										
											2008-04-13 10:20:19 -04:00
										 |  |  | 		put(AREF(new_array,i),fill); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return new_array; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DEFINE_PRIMITIVE(resize_array) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	F_ARRAY* array = untag_array(dpop()); | 
					
						
							|  |  |  | 	CELL capacity = unbox_array_size(); | 
					
						
							|  |  |  | 	dpush(tag_object(reallot_array(array,capacity,F))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-30 02:31:05 -04:00
										 |  |  | F_ARRAY *growable_array_add(F_ARRAY *result, CELL elt, CELL *result_count) | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | { | 
					
						
							|  |  |  | 	REGISTER_ROOT(elt); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(*result_count == array_capacity(result)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		result = reallot_array(result, | 
					
						
							|  |  |  | 			*result_count * 2,F); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	UNREGISTER_ROOT(elt); | 
					
						
							|  |  |  | 	set_array_nth(result,*result_count,elt); | 
					
						
							| 
									
										
										
										
											2008-05-30 02:31:05 -04:00
										 |  |  | 	(*result_count)++; | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-30 02:31:05 -04:00
										 |  |  | F_ARRAY *growable_array_append(F_ARRAY *result, F_ARRAY *elts, CELL *result_count) | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | { | 
					
						
							|  |  |  | 	REGISTER_UNTAGGED(elts); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CELL elts_size = array_capacity(elts); | 
					
						
							|  |  |  | 	CELL new_size = *result_count + elts_size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(new_size >= array_capacity(result)) | 
					
						
							|  |  |  | 		result = reallot_array(result,new_size * 2,F); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	UNREGISTER_UNTAGGED(elts); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-13 10:20:19 -04:00
										 |  |  | 	write_barrier((CELL)result); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-30 02:31:05 -04:00
										 |  |  | 	memcpy((void *)AREF(result,*result_count),(void *)AREF(elts,0),elts_size * CELLS); | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	*result_count += elts_size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Byte arrays */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* must fill out array before next GC */ | 
					
						
							|  |  |  | F_BYTE_ARRAY *allot_byte_array_internal(CELL size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	F_BYTE_ARRAY *array = allot_object(BYTE_ARRAY_TYPE, | 
					
						
							|  |  |  | 		byte_array_size(size)); | 
					
						
							|  |  |  | 	array->capacity = tag_fixnum(size); | 
					
						
							|  |  |  | 	return array; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* size is in bytes this time */ | 
					
						
							|  |  |  | F_BYTE_ARRAY *allot_byte_array(CELL size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	F_BYTE_ARRAY *array = allot_byte_array_internal(size); | 
					
						
							|  |  |  | 	memset(array + 1,0,size); | 
					
						
							|  |  |  | 	return array; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* push a new byte array on the stack */ | 
					
						
							|  |  |  | DEFINE_PRIMITIVE(byte_array) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	CELL size = unbox_array_size(); | 
					
						
							|  |  |  | 	dpush(tag_object(allot_byte_array(size))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-28 19:15:21 -05:00
										 |  |  | F_BYTE_ARRAY *reallot_byte_array(F_BYTE_ARRAY *array, CELL capacity) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	CELL to_copy = array_capacity(array); | 
					
						
							|  |  |  | 	if(capacity < to_copy) | 
					
						
							|  |  |  | 		to_copy = capacity; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	REGISTER_UNTAGGED(array); | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	F_BYTE_ARRAY *new_array = allot_byte_array(capacity); | 
					
						
							|  |  |  | 	UNREGISTER_UNTAGGED(array); | 
					
						
							| 
									
										
										
										
											2008-01-28 19:15:21 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	memcpy(new_array + 1,array + 1,to_copy); | 
					
						
							| 
									
										
										
										
											2008-01-28 19:15:21 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 	return new_array; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-01-28 19:15:21 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | DEFINE_PRIMITIVE(resize_byte_array) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	F_BYTE_ARRAY* array = untag_byte_array(dpop()); | 
					
						
							|  |  |  | 	CELL capacity = unbox_array_size(); | 
					
						
							|  |  |  | 	dpush(tag_object(reallot_byte_array(array,capacity))); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-05-30 02:31:05 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | F_BYTE_ARRAY *growable_byte_array_append(F_BYTE_ARRAY *result, void *elts, CELL len, CELL *result_count) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	CELL new_size = *result_count + len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(new_size >= byte_array_capacity(result)) | 
					
						
							|  |  |  | 		result = reallot_byte_array(result,new_size * 2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memcpy((void *)BREF(result,*result_count),elts,len); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*result_count = new_size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-01-28 19:15:21 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 04:57:48 -04:00
										 |  |  | /* Tuple layouts */ | 
					
						
							|  |  |  | DEFINE_PRIMITIVE(tuple_layout) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	F_TUPLE_LAYOUT *layout = allot_object(TUPLE_LAYOUT_TYPE,sizeof(F_TUPLE_LAYOUT)); | 
					
						
							|  |  |  | 	layout->echelon = dpop(); | 
					
						
							|  |  |  | 	layout->superclasses = dpop(); | 
					
						
							|  |  |  | 	layout->size = dpop(); | 
					
						
							|  |  |  | 	layout->class = dpop(); | 
					
						
							|  |  |  | 	layout->hashcode = untag_word(layout->class)->hashcode; | 
					
						
							|  |  |  | 	dpush(tag_object(layout)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | /* Tuples */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* push a new tuple on the stack */ | 
					
						
							| 
									
										
										
										
											2008-03-26 04:57:48 -04:00
										 |  |  | F_TUPLE *allot_tuple(F_TUPLE_LAYOUT *layout) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	REGISTER_UNTAGGED(layout); | 
					
						
							|  |  |  | 	F_TUPLE *tuple = allot_object(TUPLE_TYPE,tuple_size(layout)); | 
					
						
							|  |  |  | 	UNREGISTER_UNTAGGED(layout); | 
					
						
							|  |  |  | 	tuple->layout = tag_object(layout); | 
					
						
							|  |  |  | 	return tuple; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | DEFINE_PRIMITIVE(tuple) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-03-26 04:57:48 -04:00
										 |  |  | 	F_TUPLE_LAYOUT *layout = untag_object(dpop()); | 
					
						
							|  |  |  | 	F_FIXNUM size = to_fixnum(layout->size); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	F_TUPLE *tuple = allot_tuple(layout); | 
					
						
							|  |  |  | 	F_FIXNUM i; | 
					
						
							|  |  |  | 	for(i = size - 1; i >= 0; i--) | 
					
						
							|  |  |  | 		put(AREF(tuple,i),F); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dpush(tag_tuple(tuple)); | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* push a new tuple on the stack, filling its slots from the stack */ | 
					
						
							|  |  |  | DEFINE_PRIMITIVE(tuple_boa) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-03-26 04:57:48 -04:00
										 |  |  | 	F_TUPLE_LAYOUT *layout = untag_object(dpop()); | 
					
						
							|  |  |  | 	F_FIXNUM size = to_fixnum(layout->size); | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 04:57:48 -04:00
										 |  |  | 	REGISTER_UNTAGGED(layout); | 
					
						
							|  |  |  | 	F_TUPLE *tuple = allot_tuple(layout); | 
					
						
							|  |  |  | 	UNREGISTER_UNTAGGED(layout); | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 04:57:48 -04:00
										 |  |  | 	F_FIXNUM i; | 
					
						
							| 
									
										
										
										
											2008-09-03 04:46:56 -04:00
										 |  |  | 	for(i = size - 1; i >= 0; i--) | 
					
						
							| 
									
										
										
										
											2008-03-26 04:57:48 -04:00
										 |  |  | 		put(AREF(tuple,i),dpop()); | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-26 04:57:48 -04:00
										 |  |  | 	dpush(tag_tuple(tuple)); | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Strings */ | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | CELL string_nth(F_STRING* string, CELL index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	CELL ch = bget(SREF(string,index)); | 
					
						
							|  |  |  | 	if(string->aux == F) | 
					
						
							|  |  |  | 		return ch; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		F_BYTE_ARRAY *aux = untag_object(string->aux); | 
					
						
							|  |  |  | 		return (cget(BREF(aux,index * sizeof(u16))) << 8) | ch; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | /* allocates memory */ | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | void set_string_nth(F_STRING* string, CELL index, CELL value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	bput(SREF(string,index),value & 0xff); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | 	F_BYTE_ARRAY *aux; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | 	if(string->aux == F) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if(value <= 0xff) | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | 			REGISTER_UNTAGGED(string); | 
					
						
							|  |  |  | 			aux = allot_byte_array( | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | 				untag_fixnum_fast(string->length) | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | 				* sizeof(u16)); | 
					
						
							|  |  |  | 			UNREGISTER_UNTAGGED(string); | 
					
						
							| 
									
										
										
										
											2008-04-13 10:20:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			write_barrier((CELL)string); | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | 			string->aux = tag_object(aux); | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		aux = untag_object(string->aux); | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	cput(BREF(aux,index * sizeof(u16)),value >> 8); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-01-29 16:04:26 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | /* untagged */ | 
					
						
							|  |  |  | F_STRING* allot_string_internal(CELL capacity) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | 	F_STRING *string = allot_object(STRING_TYPE,string_size(capacity)); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	string->length = tag_fixnum(capacity); | 
					
						
							|  |  |  | 	string->hashcode = F; | 
					
						
							| 
									
										
										
										
											2008-01-31 21:11:46 -05:00
										 |  |  | 	string->aux = F; | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	return string; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | /* allocates memory */ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | void fill_string(F_STRING *string, CELL start, CELL capacity, CELL fill) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(fill == 0) | 
					
						
							| 
									
										
										
										
											2008-02-01 19:36:13 -05:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		memset((void *)SREF(string,start),'\0',capacity - start); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(string->aux != F) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			F_BYTE_ARRAY *aux = untag_object(string->aux); | 
					
						
							|  |  |  | 			memset((void *)BREF(aux,start * sizeof(u16)),'\0', | 
					
						
							|  |  |  | 				(capacity - start) * sizeof(u16)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		CELL i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for(i = start; i < capacity; i++) | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			REGISTER_UNTAGGED(string); | 
					
						
							| 
									
										
										
										
											2008-01-31 21:11:46 -05:00
										 |  |  | 			set_string_nth(string,i,fill); | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | 			UNREGISTER_UNTAGGED(string); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* untagged */ | 
					
						
							|  |  |  | F_STRING *allot_string(CELL capacity, CELL fill) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	F_STRING* string = allot_string_internal(capacity); | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | 	REGISTER_UNTAGGED(string); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	fill_string(string,0,capacity,fill); | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | 	UNREGISTER_UNTAGGED(string); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	return string; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DEFINE_PRIMITIVE(string) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	CELL initial = to_cell(dpop()); | 
					
						
							|  |  |  | 	CELL length = unbox_array_size(); | 
					
						
							|  |  |  | 	dpush(tag_object(allot_string(length,initial))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | F_STRING* reallot_string(F_STRING* string, CELL capacity, CELL fill) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							|  |  |  | 	CELL to_copy = string_capacity(string); | 
					
						
							|  |  |  | 	if(capacity < to_copy) | 
					
						
							|  |  |  | 		to_copy = capacity; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-16 18:42:56 -05:00
										 |  |  | 	REGISTER_UNTAGGED(string); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	F_STRING *new_string = allot_string_internal(capacity); | 
					
						
							| 
									
										
										
										
											2007-12-16 18:42:56 -05:00
										 |  |  | 	UNREGISTER_UNTAGGED(string); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | 	memcpy(new_string + 1,string + 1,to_copy); | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-01 19:36:13 -05:00
										 |  |  | 	if(string->aux != F) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		REGISTER_UNTAGGED(string); | 
					
						
							|  |  |  | 		REGISTER_UNTAGGED(new_string); | 
					
						
							|  |  |  | 		F_BYTE_ARRAY *new_aux = allot_byte_array(capacity * sizeof(u16)); | 
					
						
							|  |  |  | 		UNREGISTER_UNTAGGED(new_string); | 
					
						
							|  |  |  | 		UNREGISTER_UNTAGGED(string); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-28 22:55:40 -04:00
										 |  |  | 		write_barrier((CELL)new_string); | 
					
						
							| 
									
										
										
										
											2008-04-13 10:20:19 -04:00
										 |  |  | 		new_string->aux = tag_object(new_aux); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-01 19:36:13 -05:00
										 |  |  | 		F_BYTE_ARRAY *aux = untag_object(string->aux); | 
					
						
							|  |  |  | 		memcpy(new_aux + 1,aux + 1,to_copy * sizeof(u16)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | 	REGISTER_UNTAGGED(string); | 
					
						
							| 
									
										
										
										
											2008-09-28 22:55:40 -04:00
										 |  |  | 	REGISTER_UNTAGGED(new_string); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	fill_string(new_string,to_copy,capacity,fill); | 
					
						
							| 
									
										
										
										
											2008-09-28 22:55:40 -04:00
										 |  |  | 	UNREGISTER_UNTAGGED(new_string); | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | 	UNREGISTER_UNTAGGED(string); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return new_string; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DEFINE_PRIMITIVE(resize_string) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	F_STRING* string = untag_string(dpop()); | 
					
						
							|  |  |  | 	CELL capacity = unbox_array_size(); | 
					
						
							|  |  |  | 	dpush(tag_object(reallot_string(string,capacity,0))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Some ugly macros to prevent a 2x code duplication */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define MEMORY_TO_STRING(type,utype) \
 | 
					
						
							|  |  |  | 	F_STRING *memory_to_##type##_string(const type *string, CELL length) \ | 
					
						
							|  |  |  | 	{ \ | 
					
						
							|  |  |  | 		REGISTER_C_STRING(string); \ | 
					
						
							|  |  |  | 		F_STRING* s = allot_string_internal(length); \ | 
					
						
							|  |  |  | 		UNREGISTER_C_STRING(string); \ | 
					
						
							|  |  |  | 		CELL i; \ | 
					
						
							|  |  |  | 		for(i = 0; i < length; i++) \ | 
					
						
							|  |  |  | 		{ \ | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | 			REGISTER_UNTAGGED(s); \ | 
					
						
							| 
									
										
										
										
											2008-01-31 21:11:46 -05:00
										 |  |  | 			set_string_nth(s,i,(utype)*string); \ | 
					
						
							| 
									
										
										
										
											2008-02-01 17:26:11 -05:00
										 |  |  | 			UNREGISTER_UNTAGGED(s); \ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 			string++; \ | 
					
						
							|  |  |  | 		} \ | 
					
						
							|  |  |  | 		return s; \ | 
					
						
							|  |  |  | 	} \ | 
					
						
							|  |  |  | 	F_STRING *from_##type##_string(const type *str) \ | 
					
						
							|  |  |  | 	{ \ | 
					
						
							|  |  |  | 		CELL length = 0; \ | 
					
						
							|  |  |  | 		const type *scan = str; \ | 
					
						
							|  |  |  | 		while(*scan++) length++; \ | 
					
						
							|  |  |  | 		return memory_to_##type##_string(str,length); \ | 
					
						
							|  |  |  | 	} \ | 
					
						
							|  |  |  | 	void box_##type##_string(const type *str) \ | 
					
						
							|  |  |  | 	{ \ | 
					
						
							|  |  |  | 		dpush(str ? tag_object(from_##type##_string(str)) : F); \ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MEMORY_TO_STRING(char,u8) | 
					
						
							|  |  |  | MEMORY_TO_STRING(u16,u16) | 
					
						
							| 
									
										
										
										
											2008-02-01 19:36:13 -05:00
										 |  |  | MEMORY_TO_STRING(u32,u32) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool check_string(F_STRING *s, CELL max) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	CELL capacity = string_capacity(s); | 
					
						
							|  |  |  | 	CELL i; | 
					
						
							|  |  |  | 	for(i = 0; i < capacity; i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | 		CELL ch = string_nth(s,i); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 		if(ch == '\0' || ch >= (1 << (max * 8))) | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | F_BYTE_ARRAY *allot_c_string(CELL capacity, CELL size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return allot_byte_array((capacity + 1) * size); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define STRING_TO_MEMORY(type) \
 | 
					
						
							|  |  |  | 	void type##_string_to_memory(F_STRING *s, type *string) \ | 
					
						
							|  |  |  | 	{ \ | 
					
						
							|  |  |  | 		CELL i; \ | 
					
						
							|  |  |  | 		CELL capacity = string_capacity(s); \ | 
					
						
							|  |  |  | 		for(i = 0; i < capacity; i++) \ | 
					
						
							|  |  |  | 			string[i] = string_nth(s,i); \ | 
					
						
							|  |  |  | 	} \ | 
					
						
							|  |  |  | 	DEFINE_PRIMITIVE(type##_string_to_memory) \ | 
					
						
							|  |  |  | 	{ \ | 
					
						
							|  |  |  | 		type *address = unbox_alien(); \ | 
					
						
							|  |  |  | 		F_STRING *str = untag_string(dpop()); \ | 
					
						
							|  |  |  | 		type##_string_to_memory(str,address); \ | 
					
						
							|  |  |  | 	} \ | 
					
						
							|  |  |  | 	F_BYTE_ARRAY *string_to_##type##_alien(F_STRING *s, bool check) \ | 
					
						
							|  |  |  | 	{ \ | 
					
						
							|  |  |  | 		CELL capacity = string_capacity(s); \ | 
					
						
							|  |  |  | 		F_BYTE_ARRAY *_c_str; \ | 
					
						
							|  |  |  | 		if(check && !check_string(s,sizeof(type))) \ | 
					
						
							|  |  |  | 			general_error(ERROR_C_STRING,tag_object(s),F,NULL); \ | 
					
						
							| 
									
										
										
										
											2007-12-16 18:42:56 -05:00
										 |  |  | 		REGISTER_UNTAGGED(s); \ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 		_c_str = allot_c_string(capacity,sizeof(type)); \ | 
					
						
							| 
									
										
										
										
											2007-12-16 18:42:56 -05:00
										 |  |  | 		UNREGISTER_UNTAGGED(s); \ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 		type *c_str = (type*)(_c_str + 1); \ | 
					
						
							|  |  |  | 		type##_string_to_memory(s,c_str); \ | 
					
						
							|  |  |  | 		c_str[capacity] = 0; \ | 
					
						
							|  |  |  | 		return _c_str; \ | 
					
						
							|  |  |  | 	} \ | 
					
						
							|  |  |  | 	type *to_##type##_string(F_STRING *s, bool check) \ | 
					
						
							|  |  |  | 	{ \ | 
					
						
							| 
									
										
										
										
											2008-02-04 14:07:34 -05:00
										 |  |  | 		return (type*)(string_to_##type##_alien(s,check) + 1); \ | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	} \ | 
					
						
							|  |  |  | 	type *unbox_##type##_string(void) \ | 
					
						
							|  |  |  | 	{ \ | 
					
						
							|  |  |  | 		return to_##type##_string(untag_string(dpop()),true); \ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | STRING_TO_MEMORY(char); | 
					
						
							|  |  |  | STRING_TO_MEMORY(u16); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | DEFINE_PRIMITIVE(string_nth) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | 	F_STRING *string = untag_object(dpop()); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	CELL index = untag_fixnum_fast(dpop()); | 
					
						
							|  |  |  | 	dpush(tag_fixnum(string_nth(string,index))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | DEFINE_PRIMITIVE(set_string_nth) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-02-01 00:03:10 -05:00
										 |  |  | 	F_STRING *string = untag_object(dpop()); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	CELL index = untag_fixnum_fast(dpop()); | 
					
						
							|  |  |  | 	CELL value = untag_fixnum_fast(dpop()); | 
					
						
							|  |  |  | 	set_string_nth(string,index,value); | 
					
						
							|  |  |  | } |