Nicolas Cannasse 8 anni fa
parent
commit
321886c76a
2 ha cambiato i file con 510 aggiunte e 511 eliminazioni
  1. 394 395
      src/std/cast.c
  2. 116 116
      src/std/random.c

+ 394 - 395
src/std/cast.c

@@ -1,395 +1,394 @@
-/*
- * Copyright (C)2005-2016 Haxe Foundation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#include <hl.h>
-
-#define TK2(a,b)		((a) | ((b)<<5))
-
-HL_PRIM vdynamic *hl_make_dyn( void *data, hl_type *t ) {
-	vdynamic *v;
-	switch( t->kind ) {
-	case HUI8:
-		v = (vdynamic*)hl_gc_alloc_noptr(sizeof(vdynamic));
-		v->t = t;
-		v->v.i = *(unsigned char*)data;
-		return v;
-	case HUI16:
-		v = (vdynamic*)hl_gc_alloc_noptr(sizeof(vdynamic));
-		v->t = t;
-		v->v.i = *(unsigned short*)data;
-		return v;
-	case HI32:
-		v = (vdynamic*)hl_gc_alloc_noptr(sizeof(vdynamic));
-		v->t = t;
-		v->v.i = *(int*)data;
-		return v;
-	case HF32:
-		v = (vdynamic*)hl_gc_alloc_noptr(sizeof(vdynamic));
-		v->t = t;
-		v->v.f = *(float*)data;
-		return v;
-	case HF64:
-		v = (vdynamic*)hl_gc_alloc_noptr(sizeof(vdynamic));
-		v->t = t;
-		v->v.d = *(double*)data;
-		return v;
-	case HBOOL:
-		v = (vdynamic*)hl_gc_alloc_noptr(sizeof(vdynamic));
-		v->t = t;
-		v->v.b = *(bool*)data;
-		return v;
-	case HBYTES:
-	case HTYPE:
-	case HREF:
-	case HABSTRACT:
-	case HENUM:
-		{
-			void *p = *(void**)data;
-			if( p == NULL ) return NULL;
-			v = (vdynamic*)hl_gc_alloc(sizeof(vdynamic));
-			v->t = t;
-			v->v.ptr = p;
-			return v;
-		}
-	default:
-		return *(vdynamic**)data;
-	}
-}
-
-
-HL_PRIM int hl_dyn_casti( void *data, hl_type *t, hl_type *to ) {
-	if( t->kind == HDYN ) {
-		vdynamic *v = *((vdynamic**)data);
-		if( v == NULL ) return 0;
-		t = v->t;
-		if( !hl_is_dynamic(t) ) data = &v->v;
-	}
-	switch( t->kind ) {
-	case HUI8:
-		return *(unsigned char*)data;
-	case HUI16:
-		return *(unsigned short*)data;
-	case HI32:
-		return *(int*)data;
-	case HF32:
-		return (int)*(float*)data;
-	case HF64:
-		return (int)*(double*)data;
-	case HBOOL:
-		return *(bool*)data;
-	case HNULL:
-		{
-			vdynamic *v = *(vdynamic**)data;
-			if( v == NULL ) return 0;
-			return hl_dyn_casti(&v->v,t->tparam,to);
-		}
-	default:
-		break;
-	}
-	hl_error_msg(USTR("Can't cast %s to %s"),hl_type_str(t),hl_type_str(to));
-	return 0;
-}
-
-HL_PRIM void *hl_dyn_castp( void *data, hl_type *t, hl_type *to ) {
-	if( to->kind == HDYN && hl_is_dynamic(t) )
-		return *(vdynamic**)data;
-	if( t->kind == HDYN || t->kind == HNULL ) {
-		vdynamic *v = *(vdynamic**)data;
-		if( v == NULL ) return NULL;
-		t = v->t;
-		if( !hl_is_dynamic(t) ) data = &v->v;
-	} else if( hl_is_dynamic(t) ) {
-		vdynamic *v = *(vdynamic**)data;
-		if( v == NULL ) return NULL;
-		t = v->t;
-	}
-	if( t == to || hl_safe_cast(t,to) )
-		return *(void**)data;
-	switch( TK2(t->kind,to->kind) ) {
-	case TK2(HOBJ,HOBJ):
-		{
-			hl_type_obj *t1 = t->obj;
-			hl_type_obj *t2 = to->obj;
-			while( true ) {
-				if( t1 == t2 )
-					return *(void**)data;
-				if( t1->super == NULL )
-					break;
-				t1 = t1->super->obj;
-			}
-			if( t->obj->rt->castFun ) {
-				vdynamic *v = t->obj->rt->castFun(*(vdynamic**)data,to);
-				if( v ) return v;
-			}
-			break;
-		}
-	case TK2(HFUN,HFUN):
-		{
-			vclosure *c = *(vclosure**)data;
-			if( c == NULL ) return NULL;
-			c = hl_make_fun_wrapper(c,to);
-			if( c ) return c;
-		}
-		break;
-	case TK2(HOBJ,HVIRTUAL):
-	case TK2(HDYNOBJ,HVIRTUAL):
-	case TK2(HVIRTUAL,HVIRTUAL):
-		return hl_to_virtual(to,*(vdynamic**)data);
-	case TK2(HVIRTUAL,HOBJ):
-		{
-			vvirtual *v = *(vvirtual**)data;
-			if( v->value == NULL ) break;
-			return hl_dyn_castp( &v->value, v->value->t, to);
-		}
-	case TK2(HOBJ,HDYN):
-	case TK2(HDYNOBJ,HDYN):
-	case TK2(HFUN,HDYN):
-	case TK2(HNULL,HDYN):
-	case TK2(HARRAY,HDYN):
-		return *(void**)data;
-	}
-	if( to->kind == HDYN )
-		return hl_make_dyn(data,t);
-	if( to->kind == HNULL ) {
-		if( to->tparam->kind == t->kind )
-			return hl_make_dyn(data,t);
-		switch( to->tparam->kind ) {
-		case HUI8:
-		case HUI16:
-		case HI32:
-		case HBOOL:
-			{
-				int v = hl_dyn_casti(data,t,to->tparam);
-				return hl_make_dyn(&v,to->tparam);
-			}
-		case HF32:
-			{
-				float f = hl_dyn_castf(data,t);
-				return hl_make_dyn(&f,to->tparam);
-			}
-		case HF64:
-			{
-				double d = hl_dyn_castd(data,t);
-				return hl_make_dyn(&d,to->tparam);
-			}
-		default:
-			break;
-		}
-	}
-	if( to->kind == HREF ) {
-		switch( to->tparam->kind ) {
-		case HUI8:
-		case HUI16:
-		case HI32:
-		case HBOOL:
-			{
-				int *v = (int*)hl_gc_alloc_raw(sizeof(int));
-				*v = hl_dyn_casti(data,t,to->tparam);
-				return v;
-			}
-		case HF32:
-			{
-				float *f = (float*)hl_gc_alloc_raw(sizeof(float));
-				*f = hl_dyn_castf(data,t);
-				return f;
-			}
-		case HF64:
-			{
-				double *d = (double*)hl_gc_alloc_raw(sizeof(double));
-				*d = hl_dyn_castd(data,t);
-				return d;
-			}
-		default:
-			{
-				void **p = (void**)hl_gc_alloc_raw(sizeof(void*));
-				*p = hl_dyn_castp(data,t,to->tparam);
-				return p;
-			}
-			break;
-		}
-	}
-	hl_error_msg(USTR("Can't cast %s to %s"),hl_type_str(t),hl_type_str(to));
-	return 0;
-}
-
-HL_PRIM double hl_dyn_castd( void *data, hl_type *t ) {
-	if( t->kind == HDYN ) {
-		vdynamic *v = *((vdynamic**)data);
-		if( v == NULL ) return 0;
-		t = v->t;
-		if( !hl_is_dynamic(t) ) data = &v->v;
-	}
-	switch( t->kind ) {
-	case HF32:
-		return *(float*)data;
-	case HF64:
-		return *(double*)data;
-	case HUI8:
-		return *(unsigned char*)data;
-	case HUI16:
-		return *(unsigned short*)data;
-	case HI32:
-		return *(int*)data;
-	case HBOOL:
-		return *(bool*)data;
-	case HNULL:
-		{
-			vdynamic *v = *(vdynamic**)data;
-			if( v == NULL ) return 0;
-			return hl_dyn_castd(&v->v,t->tparam);
-		}
-	default:
-		break;
-	}
-	return 0.;
-}
-
-HL_PRIM float hl_dyn_castf( void *data, hl_type *t ) {
-	if( t->kind == HDYN ) {
-		vdynamic *v = *((vdynamic**)data);
-		if( v == NULL ) return 0;
-		t = v->t;
-		if( !hl_is_dynamic(t) ) data = &v->v;
-	}
-	switch( t->kind ) {
-	case HF32:
-		return *(float*)data;
-	case HF64:
-		return (float)*(double*)data;
-	case HUI8:
-		return *(unsigned char*)data;
-	case HUI16:
-		return *(unsigned short*)data;
-	case HI32:
-		return (float)*(int*)data;
-	case HBOOL:
-		return *(bool*)data;
-	case HNULL:
-		{
-			vdynamic *v = *(vdynamic**)data;
-			if( v == NULL ) return 0;
-			return hl_dyn_castf(&v->v,t->tparam);
-		}
-	default:
-		break;
-	}
-	return 0;
-}
-
-static int fcompare( float a, float b ) {
-	float d = a - b;
-	if( d != d )
-		return a == b ? 0 : hl_invalid_comparison; // +INF=+INF
- 	return d == 0.f ? 0 : (d > 0.f ? 1 : -1);
-}
-
-static int dcompare( double a, double b ) {
-	double d = a - b;
-	if( d != d )
-		return a == b ? 0 : hl_invalid_comparison; // +INF=+INF
- 	return d == 0. ? 0 : (d > 0. ? 1 : -1);
-}
-
-HL_PRIM int hl_dyn_compare( vdynamic *a, vdynamic *b ) {
-	if( a == b )
-		return 0;
-	if( a == NULL )
-		return -1;
-	if( b == NULL )
-		return 1;
-	switch( TK2(a->t->kind,b->t->kind) ) {
-	case TK2(HUI8,HUI8):
-		return (int)a->v.ui8 - (int)b->v.ui8;
-	case TK2(HUI16,HUI16):
-		return (int)a->v.ui16 - (int)b->v.ui16;
-	case TK2(HI32,HI32):
-		{
-			int d = a->v.i - b->v.i;
-			return d == hl_invalid_comparison ? -1 : d;
-		}
-	case TK2(HF32,HF32):
-		return fcompare(a->v.f,b->v.f);
-	case TK2(HF64,HF64):
-		return dcompare(a->v.d,b->v.d);
-	case TK2(HBOOL,HBOOL):
-		return (int)a->v.b - (int)b->v.b;
-	case TK2(HF64, HI32):
-		return dcompare(a->v.d,(double)b->v.i);
-	case TK2(HI32, HF64):
-		return dcompare((double)a->v.i,b->v.d);
-	case TK2(HOBJ,HOBJ):
-		if( a->t->obj == b->t->obj && a->t->obj->rt->compareFun )
-			return a->t->obj->rt->compareFun(a,b);
-		return a > b ? 1 : -1;
-	case TK2(HENUM,HENUM):
-	case TK2(HTYPE,HTYPE):
-	case TK2(HBYTES,HBYTES):
-		return a->v.ptr != b->v.ptr;
-	case TK2(HOBJ,HVIRTUAL):
-	case TK2(HDYNOBJ,HVIRTUAL):
-		return hl_dyn_compare(a,((vvirtual*)b)->value);
-	case TK2(HVIRTUAL,HOBJ):
-	case TK2(HVIRTUAL,HDYNOBJ):
-		return hl_dyn_compare(((vvirtual*)a)->value,b);
-	}
-	return hl_invalid_comparison;
-}
-
-HL_PRIM void hl_write_dyn( void *data, hl_type *t, vdynamic *v ) {
-	switch( t->kind ) {
-	case HUI8:
-		*(unsigned char*)data = (unsigned char)hl_dyn_casti(&v,&hlt_dyn,t);
-		break;
-	case HBOOL:
-		*(bool*)data = hl_dyn_casti(&v,&hlt_dyn,t) != 0;
-		break;
-	case HUI16:
-		*(unsigned short*)data = (unsigned short)hl_dyn_casti(&v,&hlt_dyn,t);
-		break;
-	case HI32:
-		*(int*)data = hl_dyn_casti(&v,&hlt_dyn,t);
-		break;
-	case HF32:
-		*(float*)data = hl_dyn_castf(&v,&hlt_dyn);
-		break;
-	case HF64:
-		*(double*)data = hl_dyn_castd(&v,&hlt_dyn);
-		break;
-	default:
-		*(void**)data = hl_dyn_castp(&v,&hlt_dyn,t);
-		break;
-	}
-}
-
-HL_PRIM vdynamic* hl_value_cast( vdynamic *v, hl_type *t ) {
-	if( t->kind == HDYN || v == NULL || hl_safe_cast(v->t,t) )
-		return v;
-	hl_error_msg(USTR("Can't cast %s to %s"),hl_type_str(v->t),hl_type_str(t));
-	return NULL;
-}
-
-HL_PRIM bool hl_type_safe_cast( hl_type *a, hl_type *b ) {
-	return hl_safe_cast(a,b);
-}
-
-DEFINE_PRIM(_I32, dyn_compare, _DYN _DYN);
-DEFINE_PRIM(_DYN, value_cast, _DYN _TYPE);
-DEFINE_PRIM(_BOOL, type_safe_cast, _TYPE _TYPE);
+/*
+ * Copyright (C)2005-2016 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <hl.h>
+
+#define TK2(a,b)		((a) | ((b)<<5))
+
+HL_PRIM vdynamic *hl_make_dyn( void *data, hl_type *t ) {
+	vdynamic *v;
+	switch( t->kind ) {
+	case HUI8:
+		v = (vdynamic*)hl_gc_alloc_noptr(sizeof(vdynamic));
+		v->t = t;
+		v->v.i = *(unsigned char*)data;
+		return v;
+	case HUI16:
+		v = (vdynamic*)hl_gc_alloc_noptr(sizeof(vdynamic));
+		v->t = t;
+		v->v.i = *(unsigned short*)data;
+		return v;
+	case HI32:
+		v = (vdynamic*)hl_gc_alloc_noptr(sizeof(vdynamic));
+		v->t = t;
+		v->v.i = *(int*)data;
+		return v;
+	case HF32:
+		v = (vdynamic*)hl_gc_alloc_noptr(sizeof(vdynamic));
+		v->t = t;
+		v->v.f = *(float*)data;
+		return v;
+	case HF64:
+		v = (vdynamic*)hl_gc_alloc_noptr(sizeof(vdynamic));
+		v->t = t;
+		v->v.d = *(double*)data;
+		return v;
+	case HBOOL:
+		v = (vdynamic*)hl_gc_alloc_noptr(sizeof(vdynamic));
+		v->t = t;
+		v->v.b = *(bool*)data;
+		return v;
+	case HBYTES:
+	case HTYPE:
+	case HREF:
+	case HABSTRACT:
+	case HENUM:
+		{
+			void *p = *(void**)data;
+			if( p == NULL ) return NULL;
+			v = hl_alloc_dynamic(t);
+			v->v.ptr = p;
+			return v;
+		}
+	default:
+		return *(vdynamic**)data;
+	}
+}
+
+
+HL_PRIM int hl_dyn_casti( void *data, hl_type *t, hl_type *to ) {
+	if( t->kind == HDYN ) {
+		vdynamic *v = *((vdynamic**)data);
+		if( v == NULL ) return 0;
+		t = v->t;
+		if( !hl_is_dynamic(t) ) data = &v->v;
+	}
+	switch( t->kind ) {
+	case HUI8:
+		return *(unsigned char*)data;
+	case HUI16:
+		return *(unsigned short*)data;
+	case HI32:
+		return *(int*)data;
+	case HF32:
+		return (int)*(float*)data;
+	case HF64:
+		return (int)*(double*)data;
+	case HBOOL:
+		return *(bool*)data;
+	case HNULL:
+		{
+			vdynamic *v = *(vdynamic**)data;
+			if( v == NULL ) return 0;
+			return hl_dyn_casti(&v->v,t->tparam,to);
+		}
+	default:
+		break;
+	}
+	hl_error_msg(USTR("Can't cast %s to %s"),hl_type_str(t),hl_type_str(to));
+	return 0;
+}
+
+HL_PRIM void *hl_dyn_castp( void *data, hl_type *t, hl_type *to ) {
+	if( to->kind == HDYN && hl_is_dynamic(t) )
+		return *(vdynamic**)data;
+	if( t->kind == HDYN || t->kind == HNULL ) {
+		vdynamic *v = *(vdynamic**)data;
+		if( v == NULL ) return NULL;
+		t = v->t;
+		if( !hl_is_dynamic(t) ) data = &v->v;
+	} else if( hl_is_dynamic(t) ) {
+		vdynamic *v = *(vdynamic**)data;
+		if( v == NULL ) return NULL;
+		t = v->t;
+	}
+	if( t == to || hl_safe_cast(t,to) )
+		return *(void**)data;
+	switch( TK2(t->kind,to->kind) ) {
+	case TK2(HOBJ,HOBJ):
+		{
+			hl_type_obj *t1 = t->obj;
+			hl_type_obj *t2 = to->obj;
+			while( true ) {
+				if( t1 == t2 )
+					return *(void**)data;
+				if( t1->super == NULL )
+					break;
+				t1 = t1->super->obj;
+			}
+			if( t->obj->rt->castFun ) {
+				vdynamic *v = t->obj->rt->castFun(*(vdynamic**)data,to);
+				if( v ) return v;
+			}
+			break;
+		}
+	case TK2(HFUN,HFUN):
+		{
+			vclosure *c = *(vclosure**)data;
+			if( c == NULL ) return NULL;
+			c = hl_make_fun_wrapper(c,to);
+			if( c ) return c;
+		}
+		break;
+	case TK2(HOBJ,HVIRTUAL):
+	case TK2(HDYNOBJ,HVIRTUAL):
+	case TK2(HVIRTUAL,HVIRTUAL):
+		return hl_to_virtual(to,*(vdynamic**)data);
+	case TK2(HVIRTUAL,HOBJ):
+		{
+			vvirtual *v = *(vvirtual**)data;
+			if( v->value == NULL ) break;
+			return hl_dyn_castp( &v->value, v->value->t, to);
+		}
+	case TK2(HOBJ,HDYN):
+	case TK2(HDYNOBJ,HDYN):
+	case TK2(HFUN,HDYN):
+	case TK2(HNULL,HDYN):
+	case TK2(HARRAY,HDYN):
+		return *(void**)data;
+	}
+	if( to->kind == HDYN )
+		return hl_make_dyn(data,t);
+	if( to->kind == HNULL ) {
+		if( to->tparam->kind == t->kind )
+			return hl_make_dyn(data,t);
+		switch( to->tparam->kind ) {
+		case HUI8:
+		case HUI16:
+		case HI32:
+		case HBOOL:
+			{
+				int v = hl_dyn_casti(data,t,to->tparam);
+				return hl_make_dyn(&v,to->tparam);
+			}
+		case HF32:
+			{
+				float f = hl_dyn_castf(data,t);
+				return hl_make_dyn(&f,to->tparam);
+			}
+		case HF64:
+			{
+				double d = hl_dyn_castd(data,t);
+				return hl_make_dyn(&d,to->tparam);
+			}
+		default:
+			break;
+		}
+	}
+	if( to->kind == HREF ) {
+		switch( to->tparam->kind ) {
+		case HUI8:
+		case HUI16:
+		case HI32:
+		case HBOOL:
+			{
+				int *v = (int*)hl_gc_alloc_raw(sizeof(int));
+				*v = hl_dyn_casti(data,t,to->tparam);
+				return v;
+			}
+		case HF32:
+			{
+				float *f = (float*)hl_gc_alloc_raw(sizeof(float));
+				*f = hl_dyn_castf(data,t);
+				return f;
+			}
+		case HF64:
+			{
+				double *d = (double*)hl_gc_alloc_raw(sizeof(double));
+				*d = hl_dyn_castd(data,t);
+				return d;
+			}
+		default:
+			{
+				void **p = (void**)hl_gc_alloc_raw(sizeof(void*));
+				*p = hl_dyn_castp(data,t,to->tparam);
+				return p;
+			}
+			break;
+		}
+	}
+	hl_error_msg(USTR("Can't cast %s to %s"),hl_type_str(t),hl_type_str(to));
+	return 0;
+}
+
+HL_PRIM double hl_dyn_castd( void *data, hl_type *t ) {
+	if( t->kind == HDYN ) {
+		vdynamic *v = *((vdynamic**)data);
+		if( v == NULL ) return 0;
+		t = v->t;
+		if( !hl_is_dynamic(t) ) data = &v->v;
+	}
+	switch( t->kind ) {
+	case HF32:
+		return *(float*)data;
+	case HF64:
+		return *(double*)data;
+	case HUI8:
+		return *(unsigned char*)data;
+	case HUI16:
+		return *(unsigned short*)data;
+	case HI32:
+		return *(int*)data;
+	case HBOOL:
+		return *(bool*)data;
+	case HNULL:
+		{
+			vdynamic *v = *(vdynamic**)data;
+			if( v == NULL ) return 0;
+			return hl_dyn_castd(&v->v,t->tparam);
+		}
+	default:
+		break;
+	}
+	return 0.;
+}
+
+HL_PRIM float hl_dyn_castf( void *data, hl_type *t ) {
+	if( t->kind == HDYN ) {
+		vdynamic *v = *((vdynamic**)data);
+		if( v == NULL ) return 0;
+		t = v->t;
+		if( !hl_is_dynamic(t) ) data = &v->v;
+	}
+	switch( t->kind ) {
+	case HF32:
+		return *(float*)data;
+	case HF64:
+		return (float)*(double*)data;
+	case HUI8:
+		return *(unsigned char*)data;
+	case HUI16:
+		return *(unsigned short*)data;
+	case HI32:
+		return (float)*(int*)data;
+	case HBOOL:
+		return *(bool*)data;
+	case HNULL:
+		{
+			vdynamic *v = *(vdynamic**)data;
+			if( v == NULL ) return 0;
+			return hl_dyn_castf(&v->v,t->tparam);
+		}
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int fcompare( float a, float b ) {
+	float d = a - b;
+	if( d != d )
+		return a == b ? 0 : hl_invalid_comparison; // +INF=+INF
+ 	return d == 0.f ? 0 : (d > 0.f ? 1 : -1);
+}
+
+static int dcompare( double a, double b ) {
+	double d = a - b;
+	if( d != d )
+		return a == b ? 0 : hl_invalid_comparison; // +INF=+INF
+ 	return d == 0. ? 0 : (d > 0. ? 1 : -1);
+}
+
+HL_PRIM int hl_dyn_compare( vdynamic *a, vdynamic *b ) {
+	if( a == b )
+		return 0;
+	if( a == NULL )
+		return -1;
+	if( b == NULL )
+		return 1;
+	switch( TK2(a->t->kind,b->t->kind) ) {
+	case TK2(HUI8,HUI8):
+		return (int)a->v.ui8 - (int)b->v.ui8;
+	case TK2(HUI16,HUI16):
+		return (int)a->v.ui16 - (int)b->v.ui16;
+	case TK2(HI32,HI32):
+		{
+			int d = a->v.i - b->v.i;
+			return d == hl_invalid_comparison ? -1 : d;
+		}
+	case TK2(HF32,HF32):
+		return fcompare(a->v.f,b->v.f);
+	case TK2(HF64,HF64):
+		return dcompare(a->v.d,b->v.d);
+	case TK2(HBOOL,HBOOL):
+		return (int)a->v.b - (int)b->v.b;
+	case TK2(HF64, HI32):
+		return dcompare(a->v.d,(double)b->v.i);
+	case TK2(HI32, HF64):
+		return dcompare((double)a->v.i,b->v.d);
+	case TK2(HOBJ,HOBJ):
+		if( a->t->obj == b->t->obj && a->t->obj->rt->compareFun )
+			return a->t->obj->rt->compareFun(a,b);
+		return a > b ? 1 : -1;
+	case TK2(HENUM,HENUM):
+	case TK2(HTYPE,HTYPE):
+	case TK2(HBYTES,HBYTES):
+		return a->v.ptr != b->v.ptr;
+	case TK2(HOBJ,HVIRTUAL):
+	case TK2(HDYNOBJ,HVIRTUAL):
+		return hl_dyn_compare(a,((vvirtual*)b)->value);
+	case TK2(HVIRTUAL,HOBJ):
+	case TK2(HVIRTUAL,HDYNOBJ):
+		return hl_dyn_compare(((vvirtual*)a)->value,b);
+	}
+	return hl_invalid_comparison;
+}
+
+HL_PRIM void hl_write_dyn( void *data, hl_type *t, vdynamic *v ) {
+	switch( t->kind ) {
+	case HUI8:
+		*(unsigned char*)data = (unsigned char)hl_dyn_casti(&v,&hlt_dyn,t);
+		break;
+	case HBOOL:
+		*(bool*)data = hl_dyn_casti(&v,&hlt_dyn,t) != 0;
+		break;
+	case HUI16:
+		*(unsigned short*)data = (unsigned short)hl_dyn_casti(&v,&hlt_dyn,t);
+		break;
+	case HI32:
+		*(int*)data = hl_dyn_casti(&v,&hlt_dyn,t);
+		break;
+	case HF32:
+		*(float*)data = hl_dyn_castf(&v,&hlt_dyn);
+		break;
+	case HF64:
+		*(double*)data = hl_dyn_castd(&v,&hlt_dyn);
+		break;
+	default:
+		*(void**)data = hl_dyn_castp(&v,&hlt_dyn,t);
+		break;
+	}
+}
+
+HL_PRIM vdynamic* hl_value_cast( vdynamic *v, hl_type *t ) {
+	if( t->kind == HDYN || v == NULL || hl_safe_cast(v->t,t) )
+		return v;
+	hl_error_msg(USTR("Can't cast %s to %s"),hl_type_str(v->t),hl_type_str(t));
+	return NULL;
+}
+
+HL_PRIM bool hl_type_safe_cast( hl_type *a, hl_type *b ) {
+	return hl_safe_cast(a,b);
+}
+
+DEFINE_PRIM(_I32, dyn_compare, _DYN _DYN);
+DEFINE_PRIM(_DYN, value_cast, _DYN _TYPE);
+DEFINE_PRIM(_BOOL, type_safe_cast, _TYPE _TYPE);

+ 116 - 116
src/std/random.c

@@ -1,117 +1,117 @@
-/*
- * Copyright (C)2005-2016 Haxe Foundation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#include <hl.h>
-#include <time.h>
-#include <string.h>
-#ifdef HL_WIN
-#	include <windows.h>
-#	include <process.h>
-#else
-#	include <sys/time.h>
-#	include <sys/types.h>
-#	include <unistd.h>
-#endif
-
-#ifdef HL_PS
+/*
+ * Copyright (C)2005-2016 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <hl.h>
+#include <time.h>
+#include <string.h>
+#ifdef HL_WIN
+#	include <windows.h>
+#	include <process.h>
+#else
+#	include <sys/time.h>
+#	include <sys/types.h>
+#	include <unistd.h>
+#endif
+
+#ifdef HL_PS
 #define getpid() 0
 #define getpid() 0
-#endif
-
-#define NSEEDS	25
-#define MAX		7
-
-typedef struct _rnd rnd;
-
-struct _rnd {
-	unsigned long seeds[NSEEDS];
-	unsigned long cur;
-};
-
-static unsigned long mag01[2]={ 
-	0x0, 0x8ebfd028 // magic, don't change
-};
-
-static const unsigned long init_seeds[] = {
-	0x95f24dab, 0x0b685215, 0xe76ccae7, 0xaf3ec239, 0x715fad23,
-	0x24a590ad, 0x69e4b5ef, 0xbf456141, 0x96bc1b7b, 0xa7bdf825,
-	0xc1de75b7, 0x8858a9c9, 0x2da87693, 0xb657f9dd, 0xffdc8a9f,
-	0x8121da71, 0x8b823ecb, 0x885d05f5, 0x4e20cd47, 0x5a9ad5d9,
-	0x512c0c03, 0xea857ccd, 0x4cc1d30f, 0x8891a8a1, 0xa6b7aadb
-};
-
-HL_PRIM rnd *hl_rnd_alloc() {
-	return (rnd*)hl_gc_alloc_raw(sizeof(rnd));
-}
-
-HL_PRIM void hl_rnd_set_seed( rnd *r, int s ) {
-	int i;
-	r->cur = 0;
-	memcpy(r->seeds,init_seeds,sizeof(init_seeds));
-	for(i=0;i<NSEEDS;i++)
-		r->seeds[i] ^= s;
-}
-
-HL_PRIM rnd *hl_rnd_init_system() {
-	rnd *r = hl_rnd_alloc();
-	int pid = getpid();
-	unsigned int time;
-#ifdef HL_WIN
-	time = GetTickCount();
-#else
-	struct timeval t;
-	gettimeofday(&t,NULL);
-	time = t.tv_sec * 1000000 + t.tv_usec;
-#endif	
-	hl_rnd_set_seed(r,time ^ (pid | (pid << 16)));
-	return r;
-}
-
-HL_PRIM unsigned int hl_rnd_int( rnd *r ) {
-	unsigned int y;
-	int pos = r->cur++;
-    if( pos >= NSEEDS ) {
-		int kk;
-		for(kk=0;kk<NSEEDS-MAX;kk++)
-			r->seeds[kk] = r->seeds[kk+MAX] ^ (r->seeds[kk] >> 1) ^ mag01[r->seeds[kk] % 2];		
-		for(;kk<NSEEDS;kk++)
-			r->seeds[kk] = r->seeds[kk+(MAX-NSEEDS)] ^ (r->seeds[kk] >> 1) ^ mag01[r->seeds[kk] % 2];      
-		r->cur = 1;
-		pos = 0;
-	}
-    y = r->seeds[pos];
-    y ^= (y << 7) & 0x2b5b2500;
-    y ^= (y << 15) & 0xdb8b0000;
-    y ^= (y >> 16);
-	return y;
-}
-
-HL_PRIM double hl_rnd_float( rnd *r ) {
-	double big = 4294967296.0;	
-	return ((hl_rnd_int(r) / big + hl_rnd_int(r)) / big + hl_rnd_int(r)) / big;
-}
-
-#define _RND	_ABSTRACT(hl_random)
-
-DEFINE_PRIM(_RND,rnd_alloc,_NO_ARG);
-DEFINE_PRIM(_RND,rnd_init_system, _NO_ARG);
-DEFINE_PRIM(_VOID,rnd_set_seed, _RND _I32);
-DEFINE_PRIM(_I32,rnd_int, _RND);
-DEFINE_PRIM(_F64,rnd_float, _RND);
+#endif
+
+#define NSEEDS	25
+#define MAX		7
+
+typedef struct _rnd rnd;
+
+struct _rnd {
+	unsigned long seeds[NSEEDS];
+	unsigned long cur;
+};
+
+static unsigned long mag01[2]={
+	0x0, 0x8ebfd028 // magic, don't change
+};
+
+static const unsigned long init_seeds[] = {
+	0x95f24dab, 0x0b685215, 0xe76ccae7, 0xaf3ec239, 0x715fad23,
+	0x24a590ad, 0x69e4b5ef, 0xbf456141, 0x96bc1b7b, 0xa7bdf825,
+	0xc1de75b7, 0x8858a9c9, 0x2da87693, 0xb657f9dd, 0xffdc8a9f,
+	0x8121da71, 0x8b823ecb, 0x885d05f5, 0x4e20cd47, 0x5a9ad5d9,
+	0x512c0c03, 0xea857ccd, 0x4cc1d30f, 0x8891a8a1, 0xa6b7aadb
+};
+
+HL_PRIM rnd *hl_rnd_alloc() {
+	return (rnd*)hl_gc_alloc_noptr(sizeof(rnd));
+}
+
+HL_PRIM void hl_rnd_set_seed( rnd *r, int s ) {
+	int i;
+	r->cur = 0;
+	memcpy(r->seeds,init_seeds,sizeof(init_seeds));
+	for(i=0;i<NSEEDS;i++)
+		r->seeds[i] ^= s;
+}
+
+HL_PRIM rnd *hl_rnd_init_system() {
+	rnd *r = hl_rnd_alloc();
+	int pid = getpid();
+	unsigned int time;
+#ifdef HL_WIN
+	time = GetTickCount();
+#else
+	struct timeval t;
+	gettimeofday(&t,NULL);
+	time = t.tv_sec * 1000000 + t.tv_usec;
+#endif
+	hl_rnd_set_seed(r,time ^ (pid | (pid << 16)));
+	return r;
+}
+
+HL_PRIM unsigned int hl_rnd_int( rnd *r ) {
+	unsigned int y;
+	int pos = r->cur++;
+    if( pos >= NSEEDS ) {
+		int kk;
+		for(kk=0;kk<NSEEDS-MAX;kk++)
+			r->seeds[kk] = r->seeds[kk+MAX] ^ (r->seeds[kk] >> 1) ^ mag01[r->seeds[kk] % 2];
+		for(;kk<NSEEDS;kk++)
+			r->seeds[kk] = r->seeds[kk+(MAX-NSEEDS)] ^ (r->seeds[kk] >> 1) ^ mag01[r->seeds[kk] % 2];
+		r->cur = 1;
+		pos = 0;
+	}
+    y = r->seeds[pos];
+    y ^= (y << 7) & 0x2b5b2500;
+    y ^= (y << 15) & 0xdb8b0000;
+    y ^= (y >> 16);
+	return y;
+}
+
+HL_PRIM double hl_rnd_float( rnd *r ) {
+	double big = 4294967296.0;
+	return ((hl_rnd_int(r) / big + hl_rnd_int(r)) / big + hl_rnd_int(r)) / big;
+}
+
+#define _RND	_ABSTRACT(hl_random)
+
+DEFINE_PRIM(_RND,rnd_alloc,_NO_ARG);
+DEFINE_PRIM(_RND,rnd_init_system, _NO_ARG);
+DEFINE_PRIM(_VOID,rnd_set_seed, _RND _I32);
+DEFINE_PRIM(_I32,rnd_int, _RND);
+DEFINE_PRIM(_F64,rnd_float, _RND);