Selaa lähdekoodia

TestSpecification running

Nicolas Cannasse 9 vuotta sitten
vanhempi
commit
72114cd3c3
9 muutettua tiedostoa jossa 265 lisäystä ja 27 poistoa
  1. 2 0
      .gitignore
  2. 1 1
      src/alloc.c
  3. 11 0
      src/std/buffer.c
  4. 118 18
      src/std/cast.c
  5. 22 2
      src/std/fun.c
  6. 12 0
      src/std/math.c
  7. 69 6
      src/std/obj.c
  8. 24 0
      src/std/sys.c
  9. 6 0
      src/std/types.c

+ 2 - 0
.gitignore

@@ -17,3 +17,5 @@ x64
 /src/_main.c
 *.o
 /src/_main2.c
+/src/_main3.c
+/src/_main4.c

+ 1 - 1
src/alloc.c

@@ -120,7 +120,7 @@ void *hl_gc_alloc_finalizer( int size ) {
 }
 
 vdynamic *hl_alloc_dynamic( hl_type *t ) {
-	vdynamic *d = (vdynamic*)hl_gc_alloc(sizeof(vdynamic));
+	vdynamic *d = (vdynamic*) ((t->kind == HENUM || t->kind == HABSTRACT) ? hl_gc_alloc(sizeof(vdynamic)) : hl_gc_alloc_noptr(sizeof(vdynamic)));
 	d->t = t;
 	d->v.ptr = NULL;
 	return d;

+ 11 - 0
src/std/buffer.c

@@ -131,6 +131,17 @@ static void hl_buffer_addr( hl_buffer *b, void *data, hl_type *t, vlist *stack )
 	case HBYTES:
 		hl_buffer_str(b,*(uchar**)data);
 		break;
+	case HENUM:
+	case HTYPE:
+	case HREF:
+	case HABSTRACT:
+		{
+			vdynamic tmp;
+			tmp.t = t;
+			tmp.v.ptr = *(void**)data;
+			hl_buffer_rec(b, tmp.v.ptr ? &tmp : NULL, stack);
+		}
+		break;
 	case HBOOL:
 		if( *(unsigned char*)data )
 			hl_buffer_str_sub(b,USTR("true"),4);

+ 118 - 18
src/std/cast.c

@@ -40,10 +40,14 @@ vdynamic *hl_make_dyn( void *data, hl_type *t ) {
 	case HREF:
 	case HABSTRACT:
 	case HENUM:
-		v = (vdynamic*)hl_gc_alloc(sizeof(vdynamic));
-		v->t = t;
-		v->v.ptr = *(void**)data;
-		return v;
+		{
+			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;
 	}
@@ -57,18 +61,18 @@ int hl_dyn_casti( void *data, hl_type *t, hl_type *to ) {
 		t = v->t;
 		if( !hl_is_dynamic(t) ) data = &v->v;
 	}
-	switch( TK2(t->kind,to->kind) ) {
-	case TK2(HI8,HI8):
+	switch( t->kind ) {
+	case HI8:
 		return *(char*)data;
-	case TK2(HI16,HI16):
+	case HI16:
 		return *(short*)data;
-	case TK2(HI32,HI32):
+	case HI32:
 		return *(int*)data;
-	case TK2(HF32,HI32):
+	case HF32:
 		return (int)*(float*)data;
-	case TK2(HF64,HI32):
+	case HF64:
 		return (int)*(double*)data;
-	case TK2(HBOOL,HBOOL):
+	case HBOOL:
 		return *(bool*)data;
 	default:
 		switch( t->kind ) {
@@ -86,28 +90,124 @@ int hl_dyn_casti( void *data, hl_type *t, hl_type *to ) {
 }
 
 
-#define HL_MAX_ARGS 0
+#define HL_MAX_ARGS 7
 
 void *hlc_dyn_call( void *fun, hl_type *t, vdynamic **args );
 
-void *hl_wrap0( vclosure *c ) {
+static void *hl_wrap0( vclosure *c ) {
 	return c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,(vdynamic**)&c->value) : hlc_dyn_call(c->fun,c->t,NULL);
 }
 
+static void *hl_wrap1( vclosure *c, vdynamic *p1 ) {
+	vdynamic *args[] = { (vdynamic*)c->value, p1 };
+	return c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,args) : hlc_dyn_call(c->fun,c->t,args + 1);
+}
+
+static void *hl_wrap2( vclosure *c, vdynamic *p1, vdynamic *p2 ) {
+	vdynamic *args[] = { (vdynamic*)c->value, p1, p2 };
+	return c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,args) : hlc_dyn_call(c->fun,c->t,args + 1);
+}
+
+static void *hl_wrap3( vclosure *c, vdynamic *p1, vdynamic *p2, vdynamic *p3 ) {
+	vdynamic *args[] = { (vdynamic*)c->value, p1, p2, p3 };
+	return c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,args) : hlc_dyn_call(c->fun,c->t,args + 1);
+}
+
+static void *hl_wrap4( vclosure *c, vdynamic *p1, vdynamic *p2, vdynamic *p3, vdynamic *p4 ) {
+	vdynamic *args[] = { (vdynamic*)c->value, p1, p2, p3, p4 };
+	return c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,args) : hlc_dyn_call(c->fun,c->t,args + 1);
+}
+
+static void *hl_wrap5( vclosure *c, vdynamic *p1, vdynamic *p2, vdynamic *p3, vdynamic *p4, vdynamic *p5 ) {
+	vdynamic *args[] = { (vdynamic*)c->value, p1, p2, p3, p4, p5 };
+	return c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,args) : hlc_dyn_call(c->fun,c->t,args + 1);
+}
+
+static void *hl_wrap6( 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 };
+	return c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,args) : hlc_dyn_call(c->fun,c->t,args + 1);
+}
+
+static void *hl_wrap7( 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 };
+	return c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,args) : hlc_dyn_call(c->fun,c->t,args + 1);
+}
+
+static int hl_wrap0i( vclosure *c ) {
+	void *v = c->hasValue ? hlc_dyn_call(c->fun,c->t->fun->parent,(vdynamic**)&c->value) : hlc_dyn_call(c->fun,c->t,NULL);
+	return hl_dyn_casti(&v,c->t->fun->ret,&hlt_i32);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
 vclosure *hl_make_fun_wrapper( vclosure *c, hl_type *to ) {
-	static void *fptr[HL_MAX_ARGS+1] = { hl_wrap0 };
+	static void *fptr_p[HL_MAX_ARGS+1] = { hl_wrap0, hl_wrap1, hl_wrap2, hl_wrap3, hl_wrap4, hl_wrap5, hl_wrap6, hl_wrap7 };
+	static void *fptr_i[HL_MAX_ARGS+1] = { hl_wrap0i, hl_wrap1i, hl_wrap2i, hl_wrap3i, hl_wrap4i, hl_wrap5i, hl_wrap6i, hl_wrap7i };
 	hl_type_fun *ct = c->t->fun;
 	int i;
 	if( ct->nargs != to->fun->nargs )
 		return NULL;
-	if( !hl_is_ptr(to->fun->ret) )
-		return NULL;
 	for(i=0;i<to->fun->nargs;i++)
 		if( !hl_is_ptr(to->fun->args[i]) )
 			return NULL;
 	if( to->fun->nargs > HL_MAX_ARGS )
 		return NULL;
-	return hl_alloc_closure_wrapper(to,fptr[to->fun->nargs],c);
+	if( hl_is_ptr(to->fun->ret) )
+		return hl_alloc_closure_wrapper(to,fptr_p[to->fun->nargs],c);
+	switch( to->fun->ret->kind ) {
+	case HI8:
+	case HI16:
+	case HI32:
+	case HBOOL:
+		return hl_alloc_closure_wrapper(to,fptr_i[to->fun->nargs],c);
+	case HF64:
+		hl_fatal("TODO");
+	case HF32:
+		hl_fatal("TODO");
+	default:
+		break;
+	}
+	return NULL;
 }
 
 void *hl_dyn_castp( void *data, hl_type *t, hl_type *to ) {
@@ -292,7 +392,7 @@ void hl_write_dyn( void *data, hl_type *t, vdynamic *v ) {
 }
 
 HL_PRIM vdynamic* hl_value_cast( vdynamic *v, hl_type *t ) {
-	if( t->kind == HDYN )
+	if( t->kind == HDYN || v == NULL || hl_safe_cast(v->t,t) )
 		return v;
 	hl_fatal("TODO");
 	return NULL;

+ 22 - 2
src/std/fun.c

@@ -79,8 +79,28 @@ HL_PRIM vdynamic* hl_call_method( vdynamic *c, varray *args ) {
 			v = hl_alloc_dynamic(t);
 			v->v.d = 0;
 			vargs[i] = v;
-		} else if( !hl_safe_cast(v->t,t) )
-			hl_write_dyn(vargs + i, t, v);
+		} else if( hl_is_ptr(t) )
+			vargs[i] = (vdynamic*)hl_dyn_castp(vargs + i,&hlt_dyn,t);
+		else {
+			vdynamic *v = hl_alloc_dynamic(t);
+			switch( t->kind ) {
+			case HBOOL:
+			case HI8:
+			case HI16:
+			case HI32:
+				v->v.i = hl_dyn_casti(vargs +i, &hlt_dyn,t);
+				break;
+			case HF32:
+				v->v.f = hl_dyn_castf(vargs +i, &hlt_dyn);
+				break;
+			case HF64:
+				v->v.d = hl_dyn_castd(vargs +i, &hlt_dyn);
+				break;
+			default:
+				hl_fatal("assert");
+			}
+			vargs[i] = v;
+		}
 	}
 	ret = hlc_dyn_call(cl->fun,cl->t,vargs);
 	tret = cl->t->fun->ret;

+ 12 - 0
src/std/math.c

@@ -88,3 +88,15 @@ HL_PRIM double hl_math_pow( double a, double b ) {
 	return pow(a,b);
 }
 
+HL_PRIM double hl_math_log( double a ) {
+	return log(a);
+}
+
+HL_PRIM double hl_math_exp( double a ) {
+	return exp(a);
+}
+
+HL_PRIM double hl_math_sqrt( double a ) {
+	return sqrt(a);
+}
+

+ 69 - 6
src/std/obj.c

@@ -385,7 +385,8 @@ double hl_dyn_getd( vdynamic *d, int hfield ) {
 }
 
 void hl_dyn_setf( vdynamic *d, int hfield, float value ) {
-	if( d == NULL ) hl_error("Invalid field access");
+	if( d == NULL )
+		hl_error("Invalid field access");
 	switch( d->t->kind ) {
 	case HDYNOBJ:
 		{
@@ -417,7 +418,8 @@ void hl_dyn_setf( vdynamic *d, int hfield, float value ) {
 }
 
 void hl_dyn_setd( vdynamic *d, int hfield, double value ) {
-	if( d == NULL ) hl_error("Invalid field access");
+	if( d == NULL )
+		hl_error("Invalid field access");
 	switch( d->t->kind ) {
 	case HDYNOBJ:
 		{
@@ -510,7 +512,8 @@ void *hl_dyn_getp( vdynamic *d, int hfield, hl_type *t ) {
 }
 
 void hl_dyn_seti( vdynamic *d, int hfield, hl_type *t, int value ) {
-	if( d == NULL ) hl_error("Invalid field access");
+	if( d == NULL )
+		hl_error("Invalid field access");
 	switch( d->t->kind ) {
 	case HDYNOBJ:
 		{
@@ -553,7 +556,8 @@ void hl_dyn_seti( vdynamic *d, int hfield, hl_type *t, int value ) {
 }
 
 void hl_dyn_setp( vdynamic *d, int hfield, hl_type *t, void *value ) {
-	if( d == NULL ) hl_error("Invalid field access");
+	if( d == NULL )
+		hl_error("Invalid field access");
 	switch( d->t->kind ) {
 	case HDYNOBJ:
 		{
@@ -589,7 +593,16 @@ void hl_dyn_setp( vdynamic *d, int hfield, hl_type *t, void *value ) {
 }
 
 HL_PRIM vdynamic *hl_obj_get_field( vdynamic *obj, int hfield ) {
-	return (vdynamic*)hl_dyn_getp(obj,hfield,&hlt_dyn);
+	if( obj == NULL )
+		return NULL;
+	switch( obj->t->kind ) {
+	case HOBJ:
+	case HVIRTUAL:
+	case HDYNOBJ:
+		return (vdynamic*)hl_dyn_getp(obj,hfield,&hlt_dyn);
+	default:
+		return NULL;
+	}
 }
 
 HL_PRIM void hl_obj_set_field( vdynamic *obj, int hfield, vdynamic *v ) {
@@ -645,7 +658,32 @@ HL_PRIM bool hl_obj_has_field( vdynamic *obj, int hfield ) {
 }
 
 HL_PRIM bool hl_obj_delete_field( vdynamic *obj, int hfield ) {
-	hl_fatal("TODO");
+	switch( obj->t->kind ) {
+	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));
+			d->nfields--;
+			// rebuild virtuals
+			{
+				vvirtual *v = d->virtuals;
+				while( v ) {
+					hl_field_lookup *vf = hl_lookup_find((hl_field_lookup*)v->t->vobj_proto,v->t->virt->nfields,hfield);
+					if( vf )
+						v->indexes[vf->field_index] = 0;
+					v = v->next;
+				}
+			}
+			return true;
+		}
+		break;
+	case HVIRTUAL:
+		return hl_obj_delete_field(((vvirtual*)obj)->value,hfield);
+	default:
+		break;
+	}
 	return false;
 }
 
@@ -680,3 +718,28 @@ HL_PRIM varray *hl_obj_fields( vdynamic *obj ) {
 	}
 	return a;
 }
+
+HL_PRIM vdynamic *hl_obj_copy( vdynamic *obj ) {
+	if( obj == NULL )
+		return NULL;
+	switch( obj->t->kind ) {
+	case HDYNOBJ:
+		{
+			vdynobj *o = (vdynobj*)obj;
+			vdynobj *c = hl_alloc_dynobj();
+			int protoSize = sizeof(vdynobj_proto) + sizeof(hl_field_lookup) * (o->nfields + 1 - 1);
+			c->dataSize = o->dataSize;
+			c->nfields = o->nfields;
+			c->virtuals = NULL;
+			c->dproto = (vdynobj_proto*)hl_gc_alloc(protoSize);
+			memcpy(c->dproto,o->dproto,protoSize);
+			c->fields_data = (char*)hl_gc_alloc(o->dataSize);
+			memcpy(c->fields_data,o->fields_data,o->dataSize);
+			return (vdynamic*)c;
+		}
+		break;
+	default:
+		break;
+	}
+	return NULL;
+}

+ 24 - 0
src/std/sys.c

@@ -8,6 +8,30 @@ HL_PRIM void hl_sys_exit( int code ) {
 	exit(code);
 }
 
+HL_PRIM double hl_sys_time() {
+#ifdef HL_WIN
+#define EPOCH_DIFF	(134774*24*60*60.0)
+	SYSTEMTIME t;
+	FILETIME ft;
+    ULARGE_INTEGER ui;
+	GetSystemTime(&t);
+	if( !SystemTimeToFileTime(&t,&ft) )
+		return 0.;
+    ui.LowPart = ft.dwLowDateTime;
+    ui.HighPart = ft.dwHighDateTime;
+	return ((double)ui.QuadPart) / 10000000.0 - EPOCH_DIFF;
+#else
+	struct timeval tv;
+	if( gettimeofday(&tv,NULL) != 0 )
+		neko_error();
+	return tv.tv_sec + ((double)tv.tv_usec) / 1000000.0;
+#endif
+}
+
+HL_PRIM int hl_random() {
+	return rand();
+}
+
 #ifndef HL_JIT
 
 #include <hlc.h>

+ 6 - 0
src/std/types.c

@@ -313,6 +313,12 @@ HL_PRIM varray *hl_type_instance_fields( hl_type *t ) {
 	return a;
 }
 
+HL_PRIM hl_type *hl_type_super( hl_type *t ) {
+	if( t->kind == HOBJ && t->obj->super )
+		return t->obj->super;
+	return &hlt_void;
+}
+
 HL_PRIM vdynamic *hl_type_get_global( hl_type *t ) {
 	switch( t->kind ) {
 	case HOBJ: