WIP: Added more functionalities in deque

This commit is contained in:
S. Mahmudul Hasan 2023-10-10 13:43:02 -04:00
parent 836f0506fa
commit 76e7746d25
2 changed files with 99 additions and 38 deletions

View File

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

View File

@ -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()
{