Commit 1c0629a7 authored by Krzysztof Klinikowski's avatar Krzysztof Klinikowski

Implementation of __iter__ for tuple, added tests

parent 8e09e7fc
// Copyright (c) 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <cstring>
#include "runtime/gc_runtime.h"
#include "runtime/tuple.h"
namespace pyston {
BoxedTupleIterator::BoxedTupleIterator(BoxedTuple* t) : Box(&tuple_iterator_flavor, tuple_iterator_cls), t(t), pos(0) {
}
Box* tupleIter(Box* s) {
assert(s->cls == tuple_cls);
BoxedTuple* self = static_cast<BoxedTuple*>(s);
return new BoxedTupleIterator(self);
}
Box* tupleiterHasnext(Box* s) {
assert(s->cls == tuple_iterator_cls);
BoxedTupleIterator* self = static_cast<BoxedTupleIterator*>(s);
return boxBool(self->pos < self->t->elts.size());
}
i1 tupleiterHasnextUnboxed(Box* s) {
assert(s->cls == tuple_iterator_cls);
BoxedTupleIterator* self = static_cast<BoxedTupleIterator*>(s);
return self->pos < self->t->elts.size();
}
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());
Box* rtn = self->t->elts[self->pos];
self->pos++;
return rtn;
}
}
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "runtime/tuple.h"
#include <sstream> #include <sstream>
#include "codegen/compvars.h" #include "codegen/compvars.h"
...@@ -19,6 +21,7 @@ ...@@ -19,6 +21,7 @@
#include "core/common.h" #include "core/common.h"
#include "core/stats.h" #include "core/stats.h"
#include "core/types.h" #include "core/types.h"
#include "gc/collector.h"
#include "runtime/gc_runtime.h" #include "runtime/gc_runtime.h"
#include "runtime/objmodel.h" #include "runtime/objmodel.h"
#include "runtime/types.h" #include "runtime/types.h"
...@@ -187,12 +190,28 @@ Box* tupleHash(BoxedTuple* self) { ...@@ -187,12 +190,28 @@ Box* tupleHash(BoxedTuple* self) {
return boxInt(rtn); return boxInt(rtn);
} }
BoxedClass* tuple_iterator_cls = NULL;
extern "C" void tupleIteratorGCHandler(GCVisitor* v, void* p) {
boxGCHandler(v, p);
BoxedTupleIterator* it = (BoxedTupleIterator*)p;
v->visit(it->t);
}
extern "C" const ObjectFlavor tuple_iterator_flavor(&tupleIteratorGCHandler, NULL);
void setupTuple() { void setupTuple() {
tuple_iterator_cls = new BoxedClass(object_cls, 0, sizeof(BoxedTuple), false);
tuple_cls->giveAttr("__name__", boxStrConstant("tuple")); tuple_cls->giveAttr("__name__", boxStrConstant("tuple"));
tuple_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)tupleGetitem, NULL, 2, false))); tuple_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)tupleGetitem, NULL, 2, false)));
tuple_cls->giveAttr("__contains__", new BoxedFunction(boxRTFunction((void*)tupleContains, NULL, 2, false))); tuple_cls->giveAttr("__contains__", new BoxedFunction(boxRTFunction((void*)tupleContains, NULL, 2, false)));
tuple_cls->giveAttr("__iter__",
new BoxedFunction(boxRTFunction((void*)tupleIter, typeFromClass(tuple_iterator_cls), 1, false)));
tuple_cls->giveAttr("__lt__", new BoxedFunction(boxRTFunction((void*)tupleLt, NULL, 2, false))); tuple_cls->giveAttr("__lt__", new BoxedFunction(boxRTFunction((void*)tupleLt, NULL, 2, false)));
tuple_cls->giveAttr("__le__", new BoxedFunction(boxRTFunction((void*)tupleLe, NULL, 2, false))); tuple_cls->giveAttr("__le__", new BoxedFunction(boxRTFunction((void*)tupleLe, NULL, 2, false)));
tuple_cls->giveAttr("__gt__", new BoxedFunction(boxRTFunction((void*)tupleGt, NULL, 2, false))); tuple_cls->giveAttr("__gt__", new BoxedFunction(boxRTFunction((void*)tupleGt, NULL, 2, false)));
...@@ -206,8 +225,20 @@ void setupTuple() { ...@@ -206,8 +225,20 @@ void setupTuple() {
tuple_cls->giveAttr("__str__", tuple_cls->getattr("__repr__")); tuple_cls->giveAttr("__str__", tuple_cls->getattr("__repr__"));
tuple_cls->freeze(); tuple_cls->freeze();
gc::registerStaticRootObj(tuple_iterator_cls);
tuple_iterator_cls->giveAttr("__name__", boxStrConstant("tupleiterator"));
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("next", new BoxedFunction(boxRTFunction((void*)tupleiterNext, UNKNOWN, 1, false)));
tuple_iterator_cls->freeze();
} }
void teardownTuple() { void teardownTuple() {
// TODO do clearattrs?
// decref(tuple_iterator_cls);
} }
} }
// Copyright (c) 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PYSTON_RUNTIME_TUPLE_H
#define PYSTON_RUNTIME_TUPLE_H
#include "core/types.h"
#include "runtime/types.h"
namespace pyston {
extern BoxedClass* tuple_iterator_cls;
struct BoxedTupleIterator : public Box {
BoxedTuple* t;
int pos;
BoxedTupleIterator(BoxedTuple* t);
};
extern "C" const ObjectFlavor tuple_iterator_flavor;
Box* tupleIter(Box* self);
Box* tupleiterHasnext(Box* self);
i1 tupleiterHasnextUnboxed(Box* self);
Box* tupleiterNext(Box* self);
}
#endif
a = (3, 2, 1)
b = (2, 'a', (3, 2))
# TODO: uncomment when hassattr will be implemented
#assert hasattr(a, '__iter__')
iter_a = a.__iter__()
assert iter_a.next() == 3
assert iter_a.next() == 2
assert iter_a.next() == 1
iter_b = b.__iter__()
assert iter_b.next() == 2
assert iter_b.next() == 'a'
assert iter_b.next() == (3, 2)
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