Browse Source

add random module (FROM Jacky888)

blueloveTH 3 years ago
parent
commit
2f1effb3e4
4 changed files with 93 additions and 23 deletions
  1. 68 0
      src/builtins.h
  2. 6 7
      src/compiler.h
  3. 18 16
      src/pocketpy.h
  4. 1 0
      src/vm.h

+ 68 - 0
src/builtins.h

@@ -146,4 +146,72 @@ class dict:
             a.append(k.__json__()+': '+v.__json__())
             a.append(k.__json__()+': '+v.__json__())
         return '{'+ ', '.join(a) + '}'
         return '{'+ ', '.join(a) + '}'
 
 
+)";
+
+const char* __RANDOM_CODE = R"(
+import time as _time
+
+__all__ = ['Random', 'seed', 'random', 'randint', 'uniform']
+
+def _int32(x):
+	return int(0xffffffff & x)
+
+class Random:
+	def __init__(self, seed=None):
+		if seed is None:
+			seed = int(_time.time() * 1000000)
+		seed = _int32(seed)
+		self.mt = [0] * 624
+		self.mt[0] = seed
+		self.mti = 0
+		for i in range(1, 624):
+			self.mt[i] = _int32(1812433253 * (self.mt[i - 1] ^ self.mt[i - 1] >> 30) + i)
+	
+	def extract_number(self):
+		if self.mti == 0:
+			self.twist()
+		y = self.mt[self.mti]
+		y = y ^ y >> 11
+		y = y ^ y << 7 & 2636928640
+		y = y ^ y << 15 & 4022730752
+		y = y ^ y >> 18
+		self.mti = (self.mti + 1) % 624
+		return _int32(y)
+	
+	def twist(self):
+		for i in range(0, 624):
+			y = _int32((self.mt[i] & 0x80000000) + (self.mt[(i + 1) % 624] & 0x7fffffff))
+			self.mt[i] = (y >> 1) ^ self.mt[(i + 397) % 624]
+			
+			if y % 2 != 0:
+				self.mt[i] = self.mt[i] ^ 0x9908b0df
+				
+	def seed(self, x):
+		assert type(x) is int
+		self.mt = [0] * 624
+		self.mt[0] = _int32(x)
+		self.mti = 0
+		for i in range(1, 624):
+			self.mt[i] = _int32(1812433253 * (self.mt[i - 1] ^ self.mt[i - 1] >> 30) + i)
+			
+	def random(self):
+		return self.extract_number() / 2 ** 32
+		
+	def randint(self, a, b):
+		assert type(a) is int and type(b) is int
+		assert a <= b
+		return int(self.random() * (b - a + 1)) + a
+		
+	def uniform(self, a, b):
+        assert type(a) is int or type(a) is float
+        assert type(b) is int or type(b) is float
+		if a > b:
+			a, b = b, a
+		return self.random() * (b - a) + a
+		
+_inst = Random()
+seed = _inst.seed
+random = _inst.random
+randint = _inst.randint
+uniform = _inst.uniform
 )";
 )";

+ 6 - 7
src/compiler.h

@@ -862,14 +862,13 @@ __LISTCOMP:
             PyVar val = parser->previous.value;
             PyVar val = parser->previous.value;
             return vm->numNegated(val);
             return vm->numNegated(val);
         }
         }
-        if(match(TK("@num"))) goto __LITERAL_EXIT;
-        if(match(TK("@str"))) goto __LITERAL_EXIT;
-        if(match(TK("True"))) goto __LITERAL_EXIT;
-        if(match(TK("False"))) goto __LITERAL_EXIT;
-        if(match(TK("None"))) goto __LITERAL_EXIT;
+        if(match(TK("@num"))) return parser->previous.value;
+        if(match(TK("@str"))) return parser->previous.value;
+        if(match(TK("True"))) return vm->PyBool(true);
+        if(match(TK("False"))) return vm->PyBool(false);
+        if(match(TK("None"))) return vm->None;
         syntaxError(_Str("expect a literal, not ") + TK_STR(parser->current.type));
         syntaxError(_Str("expect a literal, not ") + TK_STR(parser->current.type));
-__LITERAL_EXIT:
-        return parser->previous.value;
+        return nullptr;
     }
     }
 
 
     void compileTopLevelStatement() {
     void compileTopLevelStatement() {

+ 18 - 16
src/pocketpy.h

@@ -586,22 +586,6 @@ extern "C" {
         }
         }
     };
     };
 
 
-    __EXPORT
-    VM* pkpy_new_vm(PrintFn _stdout, PrintFn _stderr){
-        VM* vm = new VM();
-        __initializeBuiltinFunctions(vm);
-        vm->_stdout = _stdout;
-        vm->_stderr = _stderr;
-
-        _Code code = compile(vm, __BUILTINS_CODE, "<builtins>");
-        if(code == nullptr) exit(1);
-        vm->_exec(code, vm->builtins);
-
-        __addModuleSys(vm);
-        __addModuleTime(vm);
-        return vm;
-    }
-
     __EXPORT
     __EXPORT
     void pkpy_delete(PkExportedResource* p){
     void pkpy_delete(PkExportedResource* p){
         delete p;
         delete p;
@@ -643,4 +627,22 @@ extern "C" {
         PyVar _m = vm->newModule(name);
         PyVar _m = vm->newModule(name);
         return vm->exec(code, _m) != nullptr;
         return vm->exec(code, _m) != nullptr;
     }
     }
+
+    __EXPORT
+    VM* pkpy_new_vm(PrintFn _stdout, PrintFn _stderr){
+        VM* vm = new VM();
+        __initializeBuiltinFunctions(vm);
+        vm->_stdout = _stdout;
+        vm->_stderr = _stderr;
+
+        _Code code = compile(vm, __BUILTINS_CODE, "<builtins>");
+        if(code == nullptr) exit(1);
+        vm->_exec(code, vm->builtins);
+
+        __addModuleSys(vm);
+        __addModuleTime(vm);
+
+        pkpy_add_module(vm, "random", __RANDOM_CODE);
+        return vm;
+    }
 }
 }

+ 1 - 0
src/vm.h

@@ -145,6 +145,7 @@ private:
                         PyVar fn = frame->popValue(this);
                         PyVar fn = frame->popValue(this);
                         if(fn == None) break;
                         if(fn == None) break;
                         const _Func& f = PyFunction_AS_C(fn);
                         const _Func& f = PyFunction_AS_C(fn);
+                        setAttr(fn, __module__, frame->_module);
                         setAttr(cls, f->name, fn);
                         setAttr(cls, f->name, fn);
                     }
                     }
                     frame->f_globals()[clsName] = cls;
                     frame->f_globals()[clsName] = cls;