Browse Source

TestSpecification passing

Nicolas Cannasse 9 years ago
parent
commit
f264509db4
7 changed files with 51 additions and 26 deletions
  1. 2 0
      .gitignore
  2. 3 2
      src/hl.h
  3. 1 1
      src/std/bytes.c
  4. 19 15
      src/std/cast.c
  5. 8 1
      src/std/math.c
  6. 15 5
      src/std/obj.c
  7. 3 2
      src/std/sys.c

+ 2 - 0
.gitignore

@@ -19,3 +19,5 @@ x64
 /src/_main2.c
 /src/_main3.c
 /src/_main4.c
+/src/_main5.c
+/src/_main6.c

+ 3 - 2
src/hl.h

@@ -331,7 +331,8 @@ struct hl_runtime_obj {
 	hl_runtime_obj *parent;
 	const uchar *(*toStringFun)( vdynamic *obj );
 	int (*compareFun)( vdynamic *a, vdynamic *b );
-	vdynamic *(*castFun)( vdynamic *a, hl_type *t );
+	vdynamic *(*castFun)( vdynamic *obj, hl_type *t );
+	vdynamic *(*getFieldFun)( vdynamic *obj, int hfield );
 	// relative
 	int nlookup;
 	hl_field_lookup *lookup;
@@ -363,8 +364,8 @@ extern hl_type hlt_dyn;
 extern hl_type hlt_array;
 extern hl_type hlt_bytes;
 extern hl_type hlt_dynobj;
-extern double hl_nan;
 
+double hl_nan();
 bool hl_is_dynamic( hl_type *t );
 #define hl_is_ptr(t)	((t)->kind >= HBYTES)
 bool hl_same_type( hl_type *a, hl_type *b );

+ 1 - 1
src/std/bytes.c

@@ -138,7 +138,7 @@ HL_PRIM double hl_parse_float( vbyte *bytes, int pos, int len ) {
 	uchar *end = NULL;
 	double d = utod(str,&end);
 	if( end == str )
-		return hl_nan;
+		return hl_nan();
 	return d;
 }
 

+ 19 - 15
src/std/cast.c

@@ -141,43 +141,43 @@ static int hl_wrap0i( vclosure *c ) {
 static int hl_wrap1i( vclosure *c, vdynamic *p1 ) {
 	vdynamic *args[] = { (vdynamic*)c->value, p1 };
 	void *v = c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,args) : hlc_dyn_call(c->fun,c->t,args+1);
-	return hl_dyn_casti(&v,c->t->fun->ret,&hlt_i32);
+	return hl_dyn_casti(&v,&hlt_dyn,c->t->fun->ret);
 }
 
 static int hl_wrap2i( vclosure *c, vdynamic *p1, vdynamic *p2 ) {
 	vdynamic *args[] = { (vdynamic*)c->value, p1, p2 };
 	void *v = c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,args) : hlc_dyn_call(c->fun,c->t,args+1);
-	return hl_dyn_casti(&v,c->t->fun->ret,&hlt_i32);
+	return hl_dyn_casti(&v,&hlt_dyn,c->t->fun->ret);
 }
 
 static int hl_wrap3i( vclosure *c, vdynamic *p1, vdynamic *p2, vdynamic *p3 ) {
 	vdynamic *args[] = { (vdynamic*)c->value, p1, p2, p3 };
 	void *v = c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,args) : hlc_dyn_call(c->fun,c->t,args+1);
-	return hl_dyn_casti(&v,c->t->fun->ret,&hlt_i32);
+	return hl_dyn_casti(&v,&hlt_dyn,c->t->fun->ret);
 }
 
 static int hl_wrap4i( vclosure *c, vdynamic *p1, vdynamic *p2, vdynamic *p3, vdynamic *p4 ) {
 	vdynamic *args[] = { (vdynamic*)c->value, p1, p2, p3, p4 };
 	void *v = c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,args) : hlc_dyn_call(c->fun,c->t,args+1);
-	return hl_dyn_casti(&v,c->t->fun->ret,&hlt_i32);
+	return hl_dyn_casti(&v,&hlt_dyn,c->t->fun->ret);
 }
 
 static int hl_wrap5i( vclosure *c, vdynamic *p1, vdynamic *p2, vdynamic *p3, vdynamic *p4, vdynamic *p5 ) {
 	vdynamic *args[] = { (vdynamic*)c->value, p1, p2, p3, p4, p5 };
 	void *v = c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,args) : hlc_dyn_call(c->fun,c->t,args+1);
-	return hl_dyn_casti(&v,c->t->fun->ret,&hlt_i32);
+	return hl_dyn_casti(&v,&hlt_dyn,c->t->fun->ret);
 }
 
 static int hl_wrap6i( vclosure *c, vdynamic *p1, vdynamic *p2, vdynamic *p3, vdynamic *p4, vdynamic *p5, vdynamic *p6 ) {
 	vdynamic *args[] = { (vdynamic*)c->value, p1, p2, p3, p4, p5, p6 };
 	void *v = c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,args) : hlc_dyn_call(c->fun,c->t,args+1);
-	return hl_dyn_casti(&v,c->t->fun->ret,&hlt_i32);
+	return hl_dyn_casti(&v,&hlt_dyn,c->t->fun->ret);
 }
 
 static int hl_wrap7i( vclosure *c, vdynamic *p1, vdynamic *p2, vdynamic *p3, vdynamic *p4, vdynamic *p5, vdynamic *p6, vdynamic *p7 ) {
 	vdynamic *args[] = { (vdynamic*)c->value, p1, p2, p3, p4, p5, p6, p7 };
 	void *v = c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,args) : hlc_dyn_call(c->fun,c->t,args+1);
-	return hl_dyn_casti(&v,c->t->fun->ret,&hlt_i32);
+	return hl_dyn_casti(&v,&hlt_dyn,c->t->fun->ret);
 }
 
 vclosure *hl_make_fun_wrapper( vclosure *c, hl_type *to ) {
@@ -318,13 +318,17 @@ float hl_dyn_castf( void *data, hl_type *t ) {
 	return 0;
 }
 
-static int fcompare( float d ) {
-	if( d != d ) return hl_invalid_comparison;
+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 d ) {
-	if( d != d ) return hl_invalid_comparison;
+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);
 }
 
@@ -343,15 +347,15 @@ int hl_dyn_compare( vdynamic *a, vdynamic *b ) {
 	case TK2(HI32,HI32):
 		return a->v.i - b->v.i;
 	case TK2(HF32,HF32):
-		return fcompare(a->v.f - b->v.f);
+		return fcompare(a->v.f,b->v.f);
 	case TK2(HF64,HF64):
-		return dcompare(a->v.d - b->v.d);
+		return dcompare(a->v.d,b->v.d);
 	case TK2(HBOOL,HBOOL):
 		return a->v.b - b->v.b;
 	case TK2(HF64, HI32):
-		return dcompare(a->v.d - (double)b->v.i);
+		return dcompare(a->v.d,(double)b->v.i);
 	case TK2(HI32, HF64):
-		return dcompare((double)a->v.i - b->v.d);
+		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);

+ 8 - 1
src/std/math.c

@@ -1,7 +1,14 @@
 #include <hl.h>
 #include <math.h>
 
-double hl_nan;
+#ifndef NAN
+    static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
+    #define NAN (*(const float *) __nan)
+#endif
+
+double hl_nan() {
+	return NAN;
+}
 
 HL_PRIM double hl_math_abs( double a ) {
 	return fabs(a);

+ 15 - 5
src/std/obj.c

@@ -119,6 +119,7 @@ hl_runtime_obj *hl_get_obj_rt( hl_type *ot ) {
 	t->toStringFun = NULL;
 	t->compareFun = NULL;
 	t->castFun = NULL;
+	t->getFieldFun = NULL;
 	t->parent = p;
 
 	// fields indexes
@@ -159,7 +160,7 @@ hl_runtime_obj *hl_get_obj_proto( hl_type *ot ) {
 	hl_module_context *m = o->m;
 	hl_alloc *alloc = &m->alloc;
 	hl_runtime_obj *p = NULL, *t = hl_get_obj_rt(ot);
-	hl_field_lookup *strField, *cmpField, *castField;
+	hl_field_lookup *strField, *cmpField, *castField, *getField;
 	int i;
 	if( ot->vobj_proto ) return t;
 	if( o->super ) p = hl_get_obj_proto(o->super);
@@ -167,9 +168,11 @@ hl_runtime_obj *hl_get_obj_proto( hl_type *ot ) {
 	strField = hl_lookup_find(t->lookup,t->nlookup,hl_hash_gen(USTR("__string"),false));
 	cmpField = hl_lookup_find(t->lookup,t->nlookup,hl_hash_gen(USTR("__compare"),false));
 	castField = hl_lookup_find(t->lookup,t->nlookup,hl_hash_gen(USTR("__cast"),false));
+	getField = hl_lookup_find(t->lookup,t->nlookup,hl_hash_gen(USTR("__get_field"),false));
 	t->toStringFun = strField ? m->functions_ptrs[o->proto[-(strField->field_index+1)].findex] : (p ? p->toStringFun : NULL);	
 	t->compareFun = cmpField ? m->functions_ptrs[o->proto[-(cmpField->field_index+1)].findex] : (p ? p->compareFun : NULL);	
 	t->castFun = castField ? m->functions_ptrs[o->proto[-(castField->field_index+1)].findex] : (p ? p->castFun : NULL);	
+	t->getFieldFun = getField ? m->functions_ptrs[o->proto[-(getField->field_index+1)].findex] : (p ? p->getFieldFun : NULL);
 
 	if( t->nproto ) {
 		void **fptr = (void**)hl_malloc(alloc, sizeof(void*) * t->nproto);
@@ -495,7 +498,14 @@ void *hl_dyn_getp( vdynamic *d, int hfield, hl_type *t ) {
 				if( f != NULL ) break;
 				rt = rt->parent;
 			} while( rt );
-			if( f == NULL ) return NULL;
+			if( f == NULL ) {
+				rt = d->t->obj->rt;
+				if( rt->getFieldFun ) {
+					vdynamic *v = rt->getFieldFun(d,hfield);
+					if( v != NULL ) return hl_dyn_castp(&v,&hlt_dyn,t);
+				}
+				return NULL;
+			}
 			if( f->field_index < 0 ) {
 				vclosure *c = hl_alloc_closure_ptr(f->t,rt->methods[-f->field_index-1],d);
 				return hl_dyn_castp(&c,c->t,t);
@@ -662,9 +672,9 @@ HL_PRIM bool hl_obj_delete_field( vdynamic *obj, int hfield ) {
 	case HDYNOBJ:
 		{
 			vdynobj *d = (vdynobj*)obj;
-			int i = hl_lookup_find_index(&d->dproto->fields,d->nfields,hfield);
-			if( i < 0 ) return false;
-			memcpy(&d->dproto->fields + i, &d->dproto->fields + (i + 1), sizeof(hl_field_lookup) * (d->nfields - i));
+			hl_field_lookup *f = hl_lookup_find(&d->dproto->fields,d->nfields,hfield);
+			if( f == NULL ) return false;
+			memcpy(f, f + 1, ((char*)(&d->dproto->fields + d->nfields)) - (char*)(f + 1));
 			d->nfields--;
 			// rebuild virtuals
 			{

+ 3 - 2
src/std/sys.c

@@ -28,8 +28,9 @@ HL_PRIM double hl_sys_time() {
 #endif
 }
 
-HL_PRIM int hl_random() {
-	return rand();
+HL_PRIM int hl_random( int max ) {
+	if( max <= 0 ) return 0;
+	return rand() % max;
 }
 
 #ifndef HL_JIT