pocketpy/src/builtins.h
blueloveTH 2012e47507 up
2023-02-01 15:30:57 +08:00

450 lines
11 KiB
C++

#pragma once
const char* __BUILTINS_CODE = R"(
def print(*args, sep=' ', end='\n'):
s = sep.join([str(i) for i in args])
__sys_stdout_write(s + end)
def round(x, ndigits=0):
assert ndigits >= 0
if ndigits == 0:
return x >= 0 ? int(x + 0.5) : int(x - 0.5)
if x >= 0:
return int(x * 10**ndigits + 0.5) / 10**ndigits
else:
return int(x * 10**ndigits - 0.5) / 10**ndigits
def isinstance(obj, cls):
assert type(cls) is type
obj_t = type(obj)
while obj_t is not None:
if obj_t is cls:
return True
obj_t = obj_t.__base__
return False
def abs(x):
return x < 0 ? -x : x
def max(a, b):
return a > b ? a : b
def min(a, b):
return a < b ? a : b
def sum(iterable):
res = 0
for i in iterable:
res += i
return res
def map(f, iterable):
return [f(i) for i in iterable]
def zip(a, b):
return [(a[i], b[i]) for i in range(min(len(a), len(b)))]
def reversed(iterable):
a = list(iterable)
return [a[i] for i in range(len(a)-1, -1, -1)]
def sorted(iterable, key=None, reverse=False):
if key is None:
key = lambda x: x
a = [key(i) for i in iterable]
b = list(iterable)
for i in range(len(a)):
for j in range(i+1, len(a)):
if (a[i] > a[j]) ^ reverse:
a[i], a[j] = a[j], a[i]
b[i], b[j] = b[j], b[i]
return b
##### str #####
str.__mul__ = lambda self, n: ''.join([self for _ in range(n)])
def __str4split(self, sep):
if sep == "":
return list(self)
res = []
i = 0
while i < len(self):
if self[i:i+len(sep)] == sep:
res.append(self[:i])
self = self[i+len(sep):]
i = 0
else:
i += 1
res.append(self)
return res
str.split = __str4split
del __str4split
def __str4index(self, sub):
for i in range(len(self)):
if self[i:i+len(sub)] == sub:
return i
return -1
str.index = __str4index
del __str4index
def __str4strip(self, chars=None):
chars = chars or ' \t\n\r'
i = 0
while i < len(self) and self[i] in chars:
i += 1
j = len(self) - 1
while j >= 0 and self[j] in chars:
j -= 1
return self[i:j+1]
str.strip = __str4strip
del __str4strip
##### list #####
list.__repr__ = lambda self: '[' + ', '.join([repr(i) for i in self]) + ']'
tuple.__repr__ = lambda self: '(' + ', '.join([repr(i) for i in self]) + ')'
list.__json__ = lambda self: '[' + ', '.join([i.__json__() for i in self]) + ']'
tuple.__json__ = lambda self: '[' + ', '.join([i.__json__() for i in self]) + ']'
def __list4extend(self, other):
for i in other:
self.append(i)
list.extend = __list4extend
del __list4extend
def __list4remove(self, value):
for i in range(len(self)):
if self[i] == value:
del self[i]
return True
return False
list.remove = __list4remove
del __list4remove
def __list4index(self, value):
for i in range(len(self)):
if self[i] == value:
return i
return -1
list.index = __list4index
del __list4index
def __list4pop(self, i=-1):
res = self[i]
del self[i]
return res
list.pop = __list4pop
del __list4pop
def __list4__mul__(self, n):
a = []
for i in range(n):
a.extend(self)
return a
list.__mul__ = __list4__mul__
del __list4__mul__
def __iterable4__eq__(self, other):
if len(self) != len(other):
return False
for i in range(len(self)):
if self[i] != other[i]:
return False
return True
list.__eq__ = __iterable4__eq__
tuple.__eq__ = __iterable4__eq__
list.__ne__ = lambda self, other: not self.__eq__(other)
tuple.__ne__ = lambda self, other: not self.__eq__(other)
del __iterable4__eq__
def __iterable4count(self, x):
res = 0
for i in self:
if i == x:
res += 1
return res
list.count = __iterable4count
tuple.count = __iterable4count
del __iterable4count
def __iterable4__contains__(self, item):
for i in self:
if i == item:
return True
return False
list.__contains__ = __iterable4__contains__
tuple.__contains__ = __iterable4__contains__
del __iterable4__contains__
list.__new__ = lambda obj: [i for i in obj]
# https://github.com/python/cpython/blob/main/Objects/dictobject.c
class dict:
def __init__(self, capacity=16):
self._capacity = capacity
self._a = [None] * self._capacity
self._len = 0
def __len__(self):
return self._len
def __probe(self, key):
i = hash(key) % self._capacity
while self._a[i] is not None:
if self._a[i][0] == key:
return True, i
i = (i + 1) % self._capacity
return False, i
def __getitem__(self, key):
ok, i = self.__probe(key)
if not ok:
raise KeyError(key)
return self._a[i][1]
def __contains__(self, key):
ok, i = self.__probe(key)
return ok
def __setitem__(self, key, value):
ok, i = self.__probe(key)
if ok:
self._a[i][1] = value
else:
self._a[i] = [key, value]
self._len += 1
if self._len > self._capacity * 0.8:
self._capacity *= 2
self.__rehash()
def __delitem__(self, key):
ok, i = self.__probe(key)
if not ok:
raise KeyError(key)
self._a[i] = None
self._len -= 1
def __rehash(self):
old_a = self._a
self._a = [None] * self._capacity
self._len = 0
for kv in old_a:
if kv is not None:
self[kv[0]] = kv[1]
def keys(self):
return [kv[0] for kv in self._a if kv is not None]
def values(self):
return [kv[1] for kv in self._a if kv is not None]
def items(self):
return [kv for kv in self._a if kv is not None]
def clear(self):
self._a = [None] * self._capacity
self._len = 0
def update(self, other):
for k, v in other.items():
self[k] = v
def copy(self):
d = dict()
for kv in self._a:
if kv is not None:
d[kv[0]] = kv[1]
return d
def __repr__(self):
a = [repr(k)+': '+repr(v) for k,v in self.items()]
return '{'+ ', '.join(a) + '}'
def __json__(self):
a = []
for k,v in self.items():
if type(k) is not str:
raise TypeError('json keys must be strings, got ' + repr(k) )
a.append(k.__json__()+': '+v.__json__())
return '{'+ ', '.join(a) + '}'
class set:
def __init__(self, iterable=None):
iterable = iterable or []
self._a = dict()
for item in iterable:
self.add(item)
def add(self, elem):
self._a[elem] = None
def discard(self, elem):
if elem in self._a:
del self._a[elem]
def remove(self, elem):
del self._a[elem]
def clear(self):
self._a.clear()
def update(self,other):
for elem in other:
self.add(elem)
return self
def __len__(self):
return len(self._a)
def copy(self):
return set(self._a.keys())
def __and__(self, other):
ret = set()
for elem in self:
if elem in other:
ret.add(elem)
return ret
def __or__(self, other):
ret = self.copy()
for elem in other:
ret.add(elem)
return ret
def __sub__(self, other):
ret = set()
for elem in self:
if elem not in other:
ret.add(elem)
return ret
def __xor__(self, other):
ret = set()
for elem in self:
if elem not in other:
ret.add(elem)
for elem in other:
if elem not in self:
ret.add(elem)
return ret
def union(self, other):
return self | other
def intersection(self, other):
return self & other
def difference(self, other):
return self - other
def symmetric_difference(self, other):
return self ^ other
def __eq__(self, other):
return self.__xor__(other).__len__() == 0
def __ne__(self, other):
return self.__xor__(other).__len__() != 0
def isdisjoint(self, other):
return self.__and__(other).__len__() == 0
def issubset(self, other):
return self.__sub__(other).__len__() == 0
def issuperset(self, other):
return other.__sub__(self).__len__() == 0
def __contains__(self, elem):
return elem in self._a
def __repr__(self):
if len(self) == 0:
return 'set()'
return '{'+ ', '.join(self._a.keys()) + '}'
def __iter__(self):
return self._a.keys().__iter__()
)";
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
def shuffle(self, L):
for i in range(len(L)):
j = self.randint(i, len(L) - 1)
L[i], L[j] = L[j], L[i]
def choice(self, L):
return L[self.randint(0, len(L) - 1)]
_inst = Random()
seed = _inst.seed
random = _inst.random
randint = _inst.randint
uniform = _inst.uniform
shuffle = _inst.shuffle
choice = _inst.choice
)";