add random module (FROM Jacky888)

This commit is contained in:
blueloveTH 2022-11-13 19:36:36 +08:00
parent 80c8c837c4
commit 2f1effb3e4
4 changed files with 93 additions and 23 deletions

View File

@ -147,3 +147,71 @@ class dict:
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
)";

View File

@ -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("@num"))) return parser->previous.value;
if(match(TK("@str"))) goto __LITERAL_EXIT; if(match(TK("@str"))) return parser->previous.value;
if(match(TK("True"))) goto __LITERAL_EXIT; if(match(TK("True"))) return vm->PyBool(true);
if(match(TK("False"))) goto __LITERAL_EXIT; if(match(TK("False"))) return vm->PyBool(false);
if(match(TK("None"))) goto __LITERAL_EXIT; 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 nullptr;
return parser->previous.value;
} }
void compileTopLevelStatement() { void compileTopLevelStatement() {

View File

@ -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;
}
} }

View File

@ -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;