Commit 747e4ea9 authored by Krzysztof Klinikowski's avatar Krzysztof Klinikowski

Added __iter__ that return self, added __eq__ for list, implemented StopIteration

parent 1c0629a7
......@@ -352,7 +352,7 @@ BoxedModule* builtins_module;
// TODO looks like CPython and pypy put this into an "exceptions" module:
BoxedClass* Exception, *AssertionError, *AttributeError, *TypeError, *NameError, *KeyError, *IndexError, *IOError,
*OSError, *ZeroDivisionError, *ValueError, *UnboundLocalError, *RuntimeError, *ImportError;
*OSError, *ZeroDivisionError, *ValueError, *UnboundLocalError, *RuntimeError, *ImportError, *StopIteration;
const ObjectFlavor exception_flavor(&boxGCHandler, NULL);
Box* exceptionNew1(BoxedClass* cls) {
......@@ -440,6 +440,7 @@ void setupBuiltins() {
UnboundLocalError = makeBuiltinException(Exception, "UnboundLocalError");
RuntimeError = makeBuiltinException(Exception, "RuntimeError");
ImportError = makeBuiltinException(Exception, "ImportError");
StopIteration = makeBuiltinException(Exception, "StopIteration");
repr_obj = new BoxedFunction(boxRTFunction((void*)repr, NULL, 1, false));
builtins_module->giveAttr("repr", repr_obj);
......
......@@ -16,6 +16,7 @@
#include <cstring>
#include "runtime/gc_runtime.h"
#include "runtime/objmodel.h"
#include "runtime/list.h"
namespace pyston {
......@@ -23,6 +24,11 @@ namespace pyston {
BoxedListIterator::BoxedListIterator(BoxedList* l) : Box(&list_iterator_flavor, list_iterator_cls), l(l), pos(0) {
}
Box* listIterIter(Box* s) {
return s;
}
Box* listIter(Box* s) {
assert(s->cls == list_cls);
BoxedList* self = static_cast<BoxedList*>(s);
......@@ -47,7 +53,10 @@ Box* listiterNext(Box* s) {
assert(s->cls == list_iterator_cls);
BoxedListIterator* self = static_cast<BoxedListIterator*>(s);
assert(self->pos >= 0 && self->pos < self->l->size);
if(!(self->pos >= 0 && self->pos < self->l->size)) {
raiseExcHelper(StopIteration, "");
}
Box* rtn = self->l->elts->elts[self->pos];
self->pos++;
return rtn;
......
......@@ -15,6 +15,7 @@
#include <cstring>
#include "runtime/gc_runtime.h"
#include "runtime/objmodel.h"
#include "runtime/tuple.h"
namespace pyston {
......@@ -22,6 +23,10 @@ namespace pyston {
BoxedTupleIterator::BoxedTupleIterator(BoxedTuple* t) : Box(&tuple_iterator_flavor, tuple_iterator_cls), t(t), pos(0) {
}
Box* tupleIterIter(Box* s) {
return s;
}
Box* tupleIter(Box* s) {
assert(s->cls == tuple_cls);
BoxedTuple* self = static_cast<BoxedTuple*>(s);
......@@ -29,10 +34,7 @@ Box* tupleIter(Box* s) {
}
Box* tupleiterHasnext(Box* s) {
assert(s->cls == tuple_iterator_cls);
BoxedTupleIterator* self = static_cast<BoxedTupleIterator*>(s);
return boxBool(self->pos < self->t->elts.size());
return boxBool(tupleiterHasnextUnboxed(s));
}
i1 tupleiterHasnextUnboxed(Box* s) {
......@@ -46,7 +48,10 @@ Box* tupleiterNext(Box* s) {
assert(s->cls == tuple_iterator_cls);
BoxedTupleIterator* self = static_cast<BoxedTupleIterator*>(s);
assert(self->pos >= 0 && self->pos < self->t->elts.size());
if (!(self->pos >= 0 && self->pos < self->t->elts.size())) {
raiseExcHelper(StopIteration, "");
}
Box* rtn = self->t->elts[self->pos];
self->pos++;
return rtn;
......
......@@ -432,6 +432,54 @@ extern "C" Box* listNew2(Box* cls, Box* container) {
return rtn;
}
Box* _listCmp(BoxedList* lhs, BoxedList* rhs, AST_TYPE::AST_TYPE op_type) {
int lsz = lhs->size;
int rsz = rhs->size;
bool is_order
= (op_type == AST_TYPE::Lt || op_type == AST_TYPE::LtE || op_type == AST_TYPE::Gt || op_type == AST_TYPE::GtE);
int n = std::min(lsz, rsz);
for (int i = 0; i < n; i++) {
Box* is_eq = compareInternal(lhs->elts->elts[i], rhs->elts->elts[i], AST_TYPE::Eq, NULL);
bool bis_eq = nonzero(is_eq);
if (bis_eq)
continue;
if (op_type == AST_TYPE::Eq) {
return boxBool(false);
} else if (op_type == AST_TYPE::NotEq) {
return boxBool(true);
} else {
Box* r = compareInternal(lhs->elts->elts[i], rhs->elts->elts[i], op_type, NULL);
return r;
}
}
if (op_type == AST_TYPE::Lt)
return boxBool(lsz < rsz);
else if (op_type == AST_TYPE::LtE)
return boxBool(lsz <= rsz);
else if (op_type == AST_TYPE::Gt)
return boxBool(lsz > rsz);
else if (op_type == AST_TYPE::GtE)
return boxBool(lsz >= rsz);
else if (op_type == AST_TYPE::Eq)
return boxBool(lsz == rsz);
else if (op_type == AST_TYPE::NotEq)
return boxBool(lsz != rsz);
RELEASE_ASSERT(0, "%d", op_type);
}
Box* listEq(BoxedList* self, Box* rhs) {
if (rhs->cls != list_cls) {
return NotImplemented;
}
return _listCmp(self, static_cast<BoxedList*>(rhs), AST_TYPE::Eq);
}
void setupList() {
list_iterator_cls = new BoxedClass(object_cls, 0, sizeof(BoxedList), false);
......@@ -448,6 +496,8 @@ void setupList() {
list_cls->giveAttr("__iter__",
new BoxedFunction(boxRTFunction((void*)listIter, typeFromClass(list_iterator_cls), 1, false)));
list_cls->giveAttr("__eq__", new BoxedFunction(boxRTFunction((void*)listEq, NULL, 2, false)));
list_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)listRepr, STR, 1, false)));
list_cls->giveAttr("__str__", list_cls->getattr("__repr__"));
list_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)listNonzero, BOXED_BOOL, 1, false)));
......@@ -498,6 +548,8 @@ void setupList() {
CLFunction* hasnext = boxRTFunction((void*)listiterHasnextUnboxed, BOOL, 1, false);
addRTFunction(hasnext, (void*)listiterHasnext, BOXED_BOOL, 1, false);
list_iterator_cls->giveAttr("__hasnext__", new BoxedFunction(hasnext));
list_iterator_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)listIterIter, typeFromClass(list_iterator_cls), 1, false)));
list_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)listiterNext, UNKNOWN, 1, false)));
list_iterator_cls->freeze();
......
......@@ -29,6 +29,7 @@ struct BoxedListIterator : public Box {
extern "C" const ObjectFlavor list_iterator_flavor;
Box* listIter(Box* self);
Box* listIterIter(Box* self);
Box* listiterHasnext(Box* self);
i1 listiterHasnextUnboxed(Box* self);
Box* listiterNext(Box* self);
......
......@@ -232,6 +232,8 @@ void setupTuple() {
CLFunction* hasnext = boxRTFunction((void*)tupleiterHasnextUnboxed, BOOL, 1, false);
addRTFunction(hasnext, (void*)tupleiterHasnext, BOXED_BOOL, 1, false);
tuple_iterator_cls->giveAttr("__hasnext__", new BoxedFunction(hasnext));
tuple_iterator_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)tupleIterIter, typeFromClass(tuple_iterator_cls), 1, false)));
tuple_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)tupleiterNext, UNKNOWN, 1, false)));
tuple_iterator_cls->freeze();
......
......@@ -29,6 +29,7 @@ struct BoxedTupleIterator : public Box {
extern "C" const ObjectFlavor tuple_iterator_flavor;
Box* tupleIter(Box* self);
Box* tupleIterIter(Box* self);
Box* tupleiterHasnext(Box* self);
i1 tupleiterHasnextUnboxed(Box* self);
Box* tupleiterNext(Box* self);
......
......@@ -301,7 +301,7 @@ Box* exceptionNew1(BoxedClass* cls);
Box* exceptionNew2(BoxedClass* cls, Box* message);
extern BoxedClass* Exception, *AssertionError, *AttributeError, *TypeError, *NameError, *KeyError, *IndexError,
*IOError, *OSError, *ZeroDivisionError, *ValueError, *UnboundLocalError, *RuntimeError, *ImportError;
*IOError, *OSError, *ZeroDivisionError, *ValueError, *UnboundLocalError, *RuntimeError, *ImportError, *StopIteration;
// cls should be obj->cls.
// Added as parameter because it should typically be available
......
......@@ -14,3 +14,45 @@ assert iter_b.next() == 2
assert iter_b.next() == 'a'
assert iter_b.next() == (3, 2)
assert type(a) == list
# __eq__ tests
assert [3, 2, 1] == [3, 2, 1]
assert [3, 2, 1] == list(a)
assert [3, 2, ['a']] == list([3, 2, ['a']])
assert [3, 2, ['a', 2]] == list([3, 2, ['a', 2]])
class A(object):
pass
a_class = A()
assert [3, 2, ['a', 2]] == list([3, 2, ['a', 2]])
#
new_a = []
for i in a:
new_a.append(i)
assert [3, 2, 1] == new_a
# __iter__s
assert [3, 2, 1] == list(a.__iter__())
new_a = []
for i in a.__iter__():
new_a.append(i)
assert [3, 2, 1] == new_a
# StopIteration exception
try:
iter_a.next()
assert False, "next() called without StopIteration"
except StopIteration:
assert True
......@@ -13,3 +13,36 @@ iter_b = b.__iter__()
assert iter_b.next() == 2
assert iter_b.next() == 'a'
assert iter_b.next() == (3, 2)
assert type(a) == tuple
#
omglist = list(a)
assert omglist == [3, 2, 1]
assert [3, 2, 1] == list(a)
new_a = []
for i in a:
new_a.append(i)
assert [3, 2, 1] == new_a
# __iter__s
assert [3, 2, 1] == list(a.__iter__())
new_a = []
for i in a.__iter__():
new_a.append(i)
assert [3, 2, 1] == new_a
# StopIteration exception
try:
iter_a.next()
assert False, "next() called without StopIteration"
except StopIteration:
assert True
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment