Browse Source

added random module

Nicolas Cannasse 9 years ago
parent
commit
30ca19539c
4 changed files with 117 additions and 6 deletions
  1. 1 0
      hldll.vcxproj
  2. 3 0
      hldll.vcxproj.filters
  3. 113 0
      src/std/random.c
  4. 0 6
      src/std/sys.c

+ 1 - 0
hldll.vcxproj

@@ -189,6 +189,7 @@
     <ClCompile Include="src\std\maps.c" />
     <ClCompile Include="src\std\math.c" />
     <ClCompile Include="src\std\obj.c" />
+    <ClCompile Include="src\std\random.c" />
     <ClCompile Include="src\std\regexp.c" />
     <ClCompile Include="src\std\socket.c" />
     <ClCompile Include="src\std\string.c" />

+ 3 - 0
hldll.vcxproj.filters

@@ -91,6 +91,9 @@
       <Filter>std</Filter>
     </ClCompile>
     <ClCompile Include="src\alloc.c" />
+    <ClCompile Include="src\std\random.c">
+      <Filter>std</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="include\pcre\config.h">

+ 113 - 0
src/std/random.c

@@ -0,0 +1,113 @@
+/*
+ * 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
+
+#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);

+ 0 - 6
src/std/sys.c

@@ -137,11 +137,6 @@ HL_PRIM double hl_sys_time() {
 #endif
 }
 
-HL_PRIM int hl_random( int max ) {
-	if( max <= 0 ) return 0;
-	return rand() % max;
-}
-
 HL_PRIM vbyte *hl_sys_get_env( vbyte *v ) {
 	return (vbyte*)getenv((pchar*)v);
 }
@@ -499,7 +494,6 @@ DEFINE_PRIM(_BYTES, sys_string, _NO_ARG);
 DEFINE_PRIM(_VOID, sys_print, _BYTES);
 DEFINE_PRIM(_VOID, sys_exit, _I32);
 DEFINE_PRIM(_F64, sys_time, _NO_ARG);
-DEFINE_PRIM(_I32, random, _I32);
 DEFINE_PRIM(_BYTES, sys_get_env, _BYTES);
 DEFINE_PRIM(_BOOL, sys_put_env, _BYTES _BYTES);
 DEFINE_PRIM(_ARR, sys_env, _NO_ARG);