mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-19 19:10:17 +00:00
add collections
This commit is contained in:
parent
1e4c571685
commit
d4ae2727a1
@ -113,7 +113,7 @@ def str::strip(self, chars=None):
|
||||
|
||||
##### list #####
|
||||
|
||||
list.__new__ = lambda obj: [i for i in obj]
|
||||
list.__new__ = lambda iterable: [x for x in iterable]
|
||||
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]) + ']'
|
||||
|
87
python/collections.py
Normal file
87
python/collections.py
Normal file
@ -0,0 +1,87 @@
|
||||
class _LinkedListNode:
|
||||
def __init__(self, prev, next, value) -> None:
|
||||
self.prev = prev
|
||||
self.next = next
|
||||
self.value = value
|
||||
|
||||
class deque:
|
||||
def __init__(self, iterable=None) -> None:
|
||||
self.head = _LinkedListNode(None, None, None)
|
||||
self.tail = _LinkedListNode(None, None, None)
|
||||
self.head.next = self.tail
|
||||
self.tail.prev = self.head
|
||||
self.size = 0
|
||||
if iterable is not None:
|
||||
for value in iterable:
|
||||
self.append(value)
|
||||
|
||||
def append(self, value):
|
||||
node = _LinkedListNode(self.tail.prev, self.tail, value)
|
||||
self.tail.prev.next = node
|
||||
self.tail.prev = node
|
||||
self.size += 1
|
||||
|
||||
def appendleft(self, value):
|
||||
node = _LinkedListNode(self.head, self.head.next, value)
|
||||
self.head.next.prev = node
|
||||
self.head.next = node
|
||||
self.size += 1
|
||||
|
||||
def pop(self):
|
||||
assert self.size > 0
|
||||
node = self.tail.prev
|
||||
node.prev.next = self.tail
|
||||
self.tail.prev = node.prev
|
||||
self.size -= 1
|
||||
return node.value
|
||||
|
||||
def popleft(self):
|
||||
assert self.size > 0
|
||||
node = self.head.next
|
||||
node.next.prev = self.head
|
||||
self.head.next = node.next
|
||||
self.size -= 1
|
||||
return node.value
|
||||
|
||||
def copy(self):
|
||||
new_list = deque()
|
||||
for value in self:
|
||||
new_list.append(value)
|
||||
return new_list
|
||||
|
||||
def __len__(self):
|
||||
return self.size
|
||||
|
||||
def __iter__(self):
|
||||
node = self.head.next
|
||||
while node is not self.tail:
|
||||
yield node.value
|
||||
node = node.next
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"deque({list(self)})"
|
||||
|
||||
def __eq__(self, __o: object) -> bool:
|
||||
if not isinstance(__o, deque):
|
||||
return False
|
||||
if len(self) != len(__o):
|
||||
return False
|
||||
t1, t2 = self.head.next, __o.head.next
|
||||
while t1 is not self.tail:
|
||||
if t1.value != t2.value:
|
||||
return False
|
||||
t1, t2 = t1.next, t2.next
|
||||
return True
|
||||
|
||||
def __ne__(self, __o: object) -> bool:
|
||||
return not self == __o
|
||||
|
||||
|
||||
def Counter(iterable):
|
||||
a = {}
|
||||
for x in iterable:
|
||||
if x in a:
|
||||
a[x] += 1
|
||||
else:
|
||||
a[x] = 1
|
||||
return a
|
@ -1067,7 +1067,9 @@ __LISTCOMP:
|
||||
_compile_f_args(func, true);
|
||||
consume(TK(")"));
|
||||
}
|
||||
if(match(TK("->"))) consume(TK("@id")); // eat type hints
|
||||
if(match(TK("->"))){
|
||||
if(!match(TK("None"))) consume(TK("@id"));
|
||||
}
|
||||
func.code = make_sp<CodeObject>(parser->src, func.name.str());
|
||||
this->codes.push(func.code);
|
||||
compile_block_body();
|
||||
|
@ -133,6 +133,10 @@ void init_builtins(VM* _vm) {
|
||||
return VAR("0x" + ss.str());
|
||||
});
|
||||
|
||||
_vm->bind_builtin_func<1>("iter", [](VM* vm, Args& args) {
|
||||
return vm->asIter(args[0]);
|
||||
});
|
||||
|
||||
_vm->bind_builtin_func<1>("dir", [](VM* vm, Args& args) {
|
||||
std::set<StrName> names;
|
||||
if(args[0]->is_attr_valid()){
|
||||
@ -713,12 +717,6 @@ void add_module_random(VM* vm){
|
||||
vm->_exec(code, mod);
|
||||
}
|
||||
|
||||
void add_module_functools(VM* vm){
|
||||
PyVar mod = vm->new_module("functools");
|
||||
CodeObject_ code = vm->compile(kPythonLibs["functools"], "functools.py", EXEC_MODE);
|
||||
vm->_exec(code, mod);
|
||||
}
|
||||
|
||||
void VM::post_init(){
|
||||
init_builtins(this);
|
||||
add_module_sys(this);
|
||||
@ -730,8 +728,9 @@ void VM::post_init(){
|
||||
add_module_random(this);
|
||||
add_module_io(this);
|
||||
add_module_os(this);
|
||||
add_module_functools(this);
|
||||
add_module_c(this);
|
||||
_lazy_modules["functools"] = kPythonLibs["functools"];
|
||||
_lazy_modules["collections"] = kPythonLibs["collections"];
|
||||
|
||||
CodeObject_ code = compile(kPythonLibs["builtins"], "<builtins>", EXEC_MODE);
|
||||
this->_exec(code, this->builtins);
|
||||
|
16
tests/70_collections.py
Normal file
16
tests/70_collections.py
Normal file
@ -0,0 +1,16 @@
|
||||
from collections import Counter, deque
|
||||
|
||||
q = deque()
|
||||
q.append(1)
|
||||
q.append(2)
|
||||
q.appendleft(3)
|
||||
q.append(4)
|
||||
|
||||
assert len(q) == 4
|
||||
|
||||
assert q == deque([3, 1, 2, 4])
|
||||
assert q.popleft() == 3
|
||||
assert q.pop() == 4
|
||||
|
||||
assert len(q) == 2
|
||||
assert q == deque([1, 2])
|
Loading…
x
Reference in New Issue
Block a user