mirror of
https://github.com/pocketpy/pocketpy
synced 2025-11-09 21:20:17 +00:00
WIP: Added more functionalities in deque
This commit is contained in:
parent
836f0506fa
commit
76e7746d25
@ -108,19 +108,6 @@ namespace pkpy
|
||||
return false;
|
||||
}
|
||||
|
||||
int count(VM *vm, PyObject *obj)
|
||||
{
|
||||
int cnt = 0;
|
||||
DequeNode *p = this->head->next;
|
||||
while (p != this->tail)
|
||||
{
|
||||
if (vm->py_equals(p->obj, obj))
|
||||
cnt++;
|
||||
p = p->next;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int size() const
|
||||
{
|
||||
return this->len;
|
||||
@ -136,17 +123,22 @@ namespace pkpy
|
||||
|
||||
void reverse()
|
||||
{
|
||||
DequeNode *p = this->head->next;
|
||||
while (p != this->tail)
|
||||
{
|
||||
if (this->empty())
|
||||
return;
|
||||
// Go through each node, including the dummy nodes
|
||||
// and swap the prev and next pointers
|
||||
DequeNode *p = this->head;
|
||||
while (p!=nullptr){
|
||||
DequeNode *tmp = p->next;
|
||||
p->next = p->prev;
|
||||
p->prev = tmp;
|
||||
p = tmp;
|
||||
}
|
||||
DequeNode *tmp = this->head->next;
|
||||
this->head->next = this->tail->prev;
|
||||
this->tail->prev = tmp;
|
||||
|
||||
// swap the head and tail pointers
|
||||
DequeNode *tmp = this->head;
|
||||
this->head = this->tail;
|
||||
this->tail = tmp;
|
||||
}
|
||||
|
||||
};
|
||||
@ -165,6 +157,7 @@ namespace pkpy
|
||||
PyObject *pop();
|
||||
std::stringstream getRepr(VM *vm);
|
||||
void reverse();
|
||||
int findIndex(PyObject *obj, int startPos, int endPos); // vm is needed for the py_equals
|
||||
|
||||
int count(VM *vm, PyObject *obj); // vm is needed for the py_equals
|
||||
void clear();
|
||||
|
||||
@ -6,6 +6,19 @@ namespace pkpy
|
||||
{
|
||||
vm->bind_default_constructor<PyDeque>(type);
|
||||
|
||||
vm->bind(type, "__init__(self) -> None",
|
||||
[](VM *vm, ArgsView args)
|
||||
{
|
||||
PyDeque &self = _CAST(PyDeque &, args[0]);
|
||||
PyObject *maxlen = args[1];
|
||||
if (maxlen != vm->None)
|
||||
{
|
||||
// printf("TODO: implement deque.__init__(maxlen) -> None: %d\n", CAST(int, maxlen));
|
||||
}
|
||||
|
||||
return vm->None;
|
||||
});
|
||||
|
||||
vm->bind(type, "__len__(self) -> int",
|
||||
[](VM *vm, ArgsView args)
|
||||
{
|
||||
@ -42,12 +55,15 @@ namespace pkpy
|
||||
vm->bind(type, "copy(self) -> deque",
|
||||
[](VM *vm, ArgsView args)
|
||||
{
|
||||
// followed implementation of dict.copy()
|
||||
// PyDeque &self = _CAST(PyDeque &, args[0]);
|
||||
// return VAR(self);
|
||||
//todo: implement
|
||||
printf("TODO: implement deque.copy()");
|
||||
return vm->None;
|
||||
PyDeque &self = _CAST(PyDeque &, args[0]);
|
||||
PyDeque *newDeque = new PyDeque();
|
||||
DequeNode *p = self.dequeItems->head->next;
|
||||
while (p != self.dequeItems->tail)
|
||||
{
|
||||
newDeque->append(p->obj);
|
||||
p = p->next;
|
||||
}
|
||||
return vm->heap.gcnew<PyDeque>(PyDeque::_type(vm), *newDeque);
|
||||
});
|
||||
|
||||
vm->bind(type, "count(self, obj) -> int",
|
||||
@ -89,12 +105,20 @@ namespace pkpy
|
||||
return vm->None;
|
||||
});
|
||||
|
||||
vm->bind(type, "index(self, obj, start=0, stop=None) -> int",
|
||||
vm->bind(type, "index(self, obj, start=-1, stop=-1) -> int",
|
||||
[](VM *vm, ArgsView args)
|
||||
{
|
||||
// TODO: implement and validate
|
||||
printf("TODO: implement deque.index()");
|
||||
return vm->None;
|
||||
// Return the position of x in the deque (at or after index start and before index stop). Returns the first match or raises ValueError if not found.
|
||||
PyDeque &self = _CAST(PyDeque &, args[0]);
|
||||
PyObject *obj = args[1];
|
||||
int start = CAST(int, args[2]);
|
||||
int stop = CAST(int, args[3]);
|
||||
int idx = self.findIndex(obj, start, stop);
|
||||
|
||||
if (idx == -1)
|
||||
vm->ValueError(_CAST(Str &, vm->py_repr(obj)) + " is not in list");
|
||||
|
||||
return VAR(idx);
|
||||
});
|
||||
|
||||
vm->bind(type, "insert(self, index, obj) -> None",
|
||||
@ -160,7 +184,12 @@ namespace pkpy
|
||||
|
||||
void PyDeque::_gc_mark() const
|
||||
{
|
||||
// TODO: implement
|
||||
DequeNode *p = this->dequeItems->head->next;
|
||||
while (p != this->dequeItems->tail)
|
||||
{
|
||||
PK_OBJ_MARK(p->obj); // PK_OBJ_MARK is a macro that calls _gc_mark on the PK_OBJ
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
std::stringstream PyDeque::getRepr(VM *vm)
|
||||
{
|
||||
@ -178,6 +207,37 @@ namespace pkpy
|
||||
return ss;
|
||||
}
|
||||
|
||||
int PyDeque::findIndex(PyObject *obj, int startPos = -1, int endPos = -1)
|
||||
{
|
||||
|
||||
if (startPos == -1)
|
||||
startPos = 0;
|
||||
if (endPos == -1)
|
||||
endPos = this->dequeItems->size();
|
||||
|
||||
if (!(startPos <= endPos))
|
||||
{
|
||||
throw std::runtime_error("startPos<=endPos");
|
||||
}
|
||||
int cnt = 0;
|
||||
DequeNode *p = this->dequeItems->head->next;
|
||||
while (p != this->dequeItems->tail)
|
||||
{
|
||||
if (p->obj == obj)
|
||||
{
|
||||
if (startPos == -1 || cnt >= startPos)
|
||||
{
|
||||
if (endPos == -1 || cnt < endPos)
|
||||
{
|
||||
return cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
cnt++;
|
||||
p = p->next;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
void PyDeque::reverse()
|
||||
{
|
||||
this->dequeItems->reverse();
|
||||
@ -216,7 +276,15 @@ namespace pkpy
|
||||
|
||||
int PyDeque::count(VM *vm, PyObject *obj)
|
||||
{
|
||||
return this->dequeItems->count(vm, obj);
|
||||
int cnt = 0;
|
||||
DequeNode *p = this->dequeItems->head->next;
|
||||
while (p != this->dequeItems->tail)
|
||||
{
|
||||
if (vm->py_equals(p->obj, obj))
|
||||
cnt++;
|
||||
p = p->next;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
void PyDeque::clear()
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user