enhanced the compiler to handle array enclosed in #().
added partial code to handle dictionary enclosed in #{}
			
			
This commit is contained in:
		
							
								
								
									
										170
									
								
								hcl/lib/obj.c
									
									
									
									
									
								
							
							
						
						
									
										170
									
								
								hcl/lib/obj.c
									
									
									
									
									
								
							| @ -558,3 +558,173 @@ hcl_oop_t hcl_reversecons (hcl_t* hcl, hcl_oop_t cons) | ||||
|  | ||||
| 	return ptr; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ------------------------------------------------------------------------ * | ||||
|  * OBJECT HASHING | ||||
|  * ------------------------------------------------------------------------ */ | ||||
| int hcl_hashobj (hcl_t* hcl, hcl_oop_t obj, hcl_oow_t* xhv) | ||||
| { | ||||
| 	hcl_oow_t hv; | ||||
|  | ||||
| 	switch (HCL_OOP_GET_TAG(obj)) | ||||
| 	{ | ||||
| 		case HCL_OOP_TAG_SMOOI: | ||||
| 			hv = HCL_OOP_TO_SMOOI(obj); | ||||
| 			break; | ||||
|  | ||||
| /* | ||||
| 		case HCL_OOP_TAG_SMPTR: | ||||
| 			hv = (hcl_oow_t)HCL_OOP_TO_SMPTR(obj); | ||||
| 			break; | ||||
| */ | ||||
|  | ||||
| 		case HCL_OOP_TAG_CHAR: | ||||
| 			hv = HCL_OOP_TO_CHAR(obj); | ||||
| 			break; | ||||
|  | ||||
| /* | ||||
| 		case HCL_OOP_TAG_ERROR: | ||||
| 			hv = HCL_OOP_TO_ERROR(obj); | ||||
| 			break; | ||||
| */ | ||||
|  | ||||
| 		default: | ||||
| 		{ | ||||
| 			int type; | ||||
|  | ||||
| 			HCL_ASSERT (hcl, HCL_OOP_IS_POINTER(obj)); | ||||
| 			type = HCL_OBJ_GET_FLAGS_TYPE(obj); | ||||
| 			switch (type) | ||||
| 			{ | ||||
| 				case HCL_OBJ_TYPE_BYTE: | ||||
| 					hv = hcl_hashbytes(((hcl_oop_byte_t)obj)->slot, HCL_OBJ_GET_SIZE(obj)); | ||||
| 					break; | ||||
|  | ||||
| 				case HCL_OBJ_TYPE_CHAR: | ||||
| 					hv = hcl_hashoochars (((hcl_oop_char_t)obj)->slot, HCL_OBJ_GET_SIZE(obj)); | ||||
| 					break; | ||||
|  | ||||
| 				case HCL_OBJ_TYPE_HALFWORD: | ||||
| 					hv = hcl_hashhalfwords(((hcl_oop_halfword_t)obj)->slot, HCL_OBJ_GET_SIZE(obj)); | ||||
| 					break; | ||||
|  | ||||
| 				case HCL_OBJ_TYPE_WORD: | ||||
| 					hv = hcl_hashwords(((hcl_oop_word_t)obj)->slot, HCL_OBJ_GET_SIZE(obj)); | ||||
| 					break; | ||||
|  | ||||
| 				default: | ||||
| 					/* HCL_OBJ_TYPE_OOP, ... */  | ||||
| 					hcl_seterrbfmt(hcl, HCL_ENOIMPL, "no builtin hash implemented for %O", obj); /* TODO: better error code? */ | ||||
| 					return -1; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* i assume that hcl_hashxxx() functions limits the return value to fall  | ||||
| 	 * between 0 and HCL_SMOOI_MAX inclusive */ | ||||
| 	HCL_ASSERT (hcl, hv >= 0 && hv <= HCL_SMOOI_MAX); | ||||
| 	*xhv = hv; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* ------------------------------------------------------------------------ * | ||||
|  * OBJECT EQUALITY | ||||
|  * ------------------------------------------------------------------------ */ | ||||
| int hcl_equalobjs (hcl_t* hcl, hcl_oop_t rcv, hcl_oop_t arg) | ||||
| { | ||||
| 	int rtag; | ||||
|  | ||||
| 	if (rcv == arg) return 1; /* identical. so equal */ | ||||
|  | ||||
| 	rtag = HCL_OOP_GET_TAG(rcv); | ||||
| 	if (rtag != HCL_OOP_GET_TAG(arg)) return 0; | ||||
|  | ||||
| 	switch (rtag) | ||||
| 	{ | ||||
| 		case HCL_OOP_TAG_SMOOI: | ||||
| 			return HCL_OOP_TO_SMOOI(rcv) == HCL_OOP_TO_SMOOI(arg)? 1: 0; | ||||
|  | ||||
| #if 0 | ||||
| 		case HCL_OOP_TAG_SMPTR: | ||||
| 			return HCL_OOP_TO_SMPTR(rcv) == HCL_OOP_TO_SMPTR(arg)? 1: 0; | ||||
| #endif | ||||
|  | ||||
| 		case HCL_OOP_TAG_CHAR: | ||||
| 			return HCL_OOP_TO_CHAR(rcv) == HCL_OOP_TO_CHAR(arg)? 1: 0; | ||||
|  | ||||
| #if 0 | ||||
| 		case HCL_OOP_TAG_ERROR: | ||||
| 			return HCL_OOP_TO_ERROR(rcv) == HCL_OOP_TO_ERROR(arg)? 1: 0; | ||||
| #endif | ||||
|  | ||||
| 		default: | ||||
| 		{ | ||||
| 			HCL_ASSERT (hcl, HCL_OOP_IS_POINTER(rcv)); | ||||
|  | ||||
| 			if (HCL_OBJ_GET_CLASS(rcv) != HCL_OBJ_GET_CLASS(arg)) return 0; /* different class, not equal */ | ||||
| 			HCL_ASSERT (hcl, HCL_OBJ_GET_FLAGS_TYPE(rcv) == HCL_OBJ_GET_FLAGS_TYPE(arg)); | ||||
|  | ||||
| 			if (HCL_OBJ_GET_CLASS(rcv) == hcl->_class && rcv != arg)  | ||||
| 			{ | ||||
| 				/* a class object are supposed to be unique */ | ||||
| 				return 0; | ||||
| 			} | ||||
| 			if (HCL_OBJ_GET_SIZE(rcv) != HCL_OBJ_GET_SIZE(arg)) return 0; /* different size, not equal */ | ||||
|  | ||||
| 			switch (HCL_OBJ_GET_FLAGS_TYPE(rcv)) | ||||
| 			{ | ||||
| 				case HCL_OBJ_TYPE_BYTE: | ||||
| 				case HCL_OBJ_TYPE_CHAR: | ||||
| 				case HCL_OBJ_TYPE_HALFWORD: | ||||
| 				case HCL_OBJ_TYPE_WORD: | ||||
| 					return (HCL_MEMCMP(HCL_OBJ_GET_BYTE_SLOT(rcv), HCL_OBJ_GET_BYTE_SLOT(arg), HCL_BYTESOF(hcl,rcv)) == 0)? 1: 0; | ||||
|  | ||||
| 				default: | ||||
| 				{ | ||||
| 					hcl_oow_t i, size; | ||||
|  | ||||
| 					if (rcv == hcl->_nil) return arg == hcl->_nil? 1: 0; | ||||
| 					if (rcv == hcl->_true) return arg == hcl->_true? 1: 0; | ||||
| 					if (rcv == hcl->_false) return arg == hcl->_false? 1: 0; | ||||
|  | ||||
| 					/* HCL_OBJ_TYPE_OOP, ... */ | ||||
| 					HCL_ASSERT (hcl, HCL_OBJ_GET_FLAGS_TYPE(rcv) == HCL_OBJ_TYPE_OOP); | ||||
|  | ||||
| 				#if 0 | ||||
| 					hcl_seterrbfmt (hcl, HCL_ENOIMPL, "no builtin comparison implemented for %O and %O", rcv, arg); /* TODO: better error code */ | ||||
| 					return -1; | ||||
| 				#else | ||||
|  | ||||
| 					if (HCL_IS_PROCESS(hcl,rcv)) | ||||
| 					{ | ||||
| 						/* the stack in a process object doesn't need to be  | ||||
| 						 * scanned in full. the slots above the stack pointer  | ||||
| 						 * are garbages. */ | ||||
| 						size = HCL_PROCESS_NAMED_INSTVARS + | ||||
| 							  HCL_OOP_TO_SMOOI(((hcl_oop_process_t)rcv)->sp) + 1; | ||||
| 						HCL_ASSERT (hcl, size <= HCL_OBJ_GET_SIZE(rcv)); | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						size = HCL_OBJ_GET_SIZE(rcv); | ||||
| 					} | ||||
| 					for (i = 0; i < size; i++) | ||||
| 					{ | ||||
| 						int n; | ||||
| 						/* TODO: remove recursion */ | ||||
| 						/* NOTE: even if the object implements the equality method,  | ||||
| 						 * this primitive method doesn't honor it. */ | ||||
| 						n = hcl_equalobjs(hcl, ((hcl_oop_oop_t)rcv)->slot[i], ((hcl_oop_oop_t)arg)->slot[i]); | ||||
| 						if (n <= 0) return n; | ||||
| 					} | ||||
|  | ||||
| 					/* the default implementation doesn't take the trailer space into account */ | ||||
| 					return 1; | ||||
| 				#endif | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user