Commit 54cda5d7 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #71 from undingen/dict_iter

Implement dict iterators
parents 6174a694 f4ae6973
......@@ -244,6 +244,17 @@ Box* notimplementedRepr(Box* self) {
}
Box* sorted(Box* obj) {
BoxedList* rtn = new BoxedList();
for (Box* e : obj->pyElements()) {
listAppendInternal(rtn, e);
}
std::sort<Box**, PyLt>(rtn->elts->elts, rtn->elts->elts + rtn->size, PyLt());
return rtn;
}
Box* sortedList(Box* obj) {
RELEASE_ASSERT(obj->cls == list_cls, "");
BoxedList* lobj = static_cast<BoxedList*>(obj);
......@@ -455,7 +466,10 @@ void setupBuiltins() {
Box* isinstance_obj = new BoxedFunction(boxRTFunction((void*)isinstance_func, NULL, 2, false));
builtins_module->giveAttr("isinstance", isinstance_obj);
builtins_module->giveAttr("sorted", new BoxedFunction(boxRTFunction((void*)sorted, NULL, 1, false)));
CLFunction* sorted_func = createRTFunction();
addRTFunction(sorted_func, (void*)sortedList, LIST, { LIST }, false);
addRTFunction(sorted_func, (void*)sorted, LIST, { UNKNOWN }, false);
builtins_module->giveAttr("sorted", new BoxedFunction(sorted_func));
builtins_module->giveAttr("True", True);
builtins_module->giveAttr("False", False);
......
......@@ -12,10 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "runtime/dict.h"
#include "codegen/compvars.h"
#include "core/common.h"
#include "core/stats.h"
#include "core/types.h"
#include "gc/collector.h"
#include "runtime/gc_runtime.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
......@@ -145,7 +148,19 @@ Box* dictGet2(BoxedDict* self, Box* k) {
return dictGet3(self, k, None);
}
BoxedClass* dict_iterator_cls = NULL;
extern "C" void dictIteratorGCHandler(GCVisitor* v, void* p) {
boxGCHandler(v, p);
BoxedDictIterator* it = (BoxedDictIterator*)p;
v->visit(it->d);
}
extern "C" const ObjectFlavor dict_iterator_flavor(&dictIteratorGCHandler, NULL);
void setupDict() {
dict_iterator_cls = new BoxedClass(object_cls, 0, sizeof(BoxedDict), false);
dict_cls->giveAttr("__name__", boxStrConstant("dict"));
// dict_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)dictLen, NULL, 1, false)));
// dict_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)dictGetitem, NULL, 2, false)));
......@@ -154,14 +169,17 @@ void setupDict() {
dict_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)dictRepr, NULL, 1, false)));
dict_cls->giveAttr("__str__", dict_cls->getattr("__repr__"));
dict_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)dictIterKeys, typeFromClass(dict_iterator_cls), 1, false)));
dict_cls->giveAttr("items", new BoxedFunction(boxRTFunction((void*)dictItems, NULL, 1, false)));
dict_cls->giveAttr("iteritems", dict_cls->getattr("items"));
dict_cls->giveAttr("iteritems", new BoxedFunction(boxRTFunction((void*)dictIterItems, typeFromClass(dict_iterator_cls), 1, false)));
dict_cls->giveAttr("values", new BoxedFunction(boxRTFunction((void*)dictValues, NULL, 1, false)));
dict_cls->giveAttr("itervalues", dict_cls->getattr("values"));
dict_cls->giveAttr("itervalues", new BoxedFunction(boxRTFunction((void*)dictIterValues, typeFromClass(dict_iterator_cls), 1, false)));
dict_cls->giveAttr("keys", new BoxedFunction(boxRTFunction((void*)dictKeys, NULL, 1, false)));
dict_cls->giveAttr("iterkeys", dict_cls->getattr("keys"));
dict_cls->giveAttr("iterkeys", dict_cls->getattr("__iter__"));
CLFunction* pop = boxRTFunction((void*)dictPop2, UNKNOWN, 2, false);
addRTFunction(pop, (void*)dictPop3, UNKNOWN, 3, false);
......@@ -175,6 +193,18 @@ void setupDict() {
dict_cls->giveAttr("__setitem__", new BoxedFunction(boxRTFunction((void*)dictSetitem, NULL, 3, false)));
dict_cls->freeze();
gc::registerStaticRootObj(dict_iterator_cls);
dict_iterator_cls->giveAttr("__name__", boxStrConstant("dictiterator"));
CLFunction* hasnext = boxRTFunction((void*)dictIterHasnextUnboxed, BOOL, 1, false);
addRTFunction(hasnext, (void*)dictIterHasnext, BOXED_BOOL, 1, false);
dict_iterator_cls->giveAttr("__hasnext__", new BoxedFunction(hasnext));
dict_iterator_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)dictIterIter, typeFromClass(dict_iterator_cls), 1, false)));
dict_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)dictIterNext, UNKNOWN, 1, false)));
dict_iterator_cls->freeze();
}
void teardownDict() {
......
// 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_DICT_H
#define PYSTON_RUNTIME_DICT_H
#include "core/types.h"
#include "runtime/types.h"
namespace pyston {
extern BoxedClass* dict_iterator_cls;
struct BoxedDictIterator : public Box {
enum IteratorType { KeyIterator, ValueIterator, ItemIterator };
BoxedDict* d;
BoxedDict::DictMap::iterator it;
const BoxedDict::DictMap::iterator itEnd;
const IteratorType type;
BoxedDictIterator(BoxedDict* d, IteratorType type);
};
extern "C" const ObjectFlavor dict_iterator_flavor;
Box* dictIterKeys(Box* self);
Box* dictIterValues(Box* self);
Box* dictIterItems(Box* self);
Box* dictIterIter(Box* self);
Box* dictIterHasnext(Box* self);
i1 dictIterHasnextUnboxed(Box* self);
Box* dictIterNext(Box* self);
}
#endif
// 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/dict.h"
#include "runtime/gc_runtime.h"
namespace pyston {
BoxedDictIterator::BoxedDictIterator(BoxedDict* d, IteratorType type)
: Box(&dict_iterator_flavor, dict_iterator_cls), d(d), it(d->d.begin()), itEnd(d->d.end()), type(type) {
}
Box* dictIterKeys(Box* s) {
assert(s->cls == dict_cls);
BoxedDict* self = static_cast<BoxedDict*>(s);
return new BoxedDictIterator(self, BoxedDictIterator::KeyIterator);
}
Box* dictIterValues(Box* s) {
assert(s->cls == dict_cls);
BoxedDict* self = static_cast<BoxedDict*>(s);
return new BoxedDictIterator(self, BoxedDictIterator::ValueIterator);
}
Box* dictIterItems(Box* s) {
assert(s->cls == dict_cls);
BoxedDict* self = static_cast<BoxedDict*>(s);
return new BoxedDictIterator(self, BoxedDictIterator::ItemIterator);
}
Box* dictIterIter(Box* s) {
return s;
}
i1 dictIterHasnextUnboxed(Box* s) {
assert(s->cls == dict_iterator_cls);
BoxedDictIterator* self = static_cast<BoxedDictIterator*>(s);
return self->it != self->itEnd;
}
Box* dictIterHasnext(Box* s) {
return boxBool(dictIterHasnextUnboxed(s));
}
Box* dictIterNext(Box* s) {
assert(s->cls == dict_iterator_cls);
BoxedDictIterator* self = static_cast<BoxedDictIterator*>(s);
Box* rtn = nullptr;
if (self->type == BoxedDictIterator::KeyIterator) {
rtn = self->it->first;
} else if (self->type == BoxedDictIterator::ValueIterator) {
rtn = self->it->second;
} else if (self->type == BoxedDictIterator::ItemIterator) {
BoxedTuple::GCVector elts{ self->it->first, self->it->second };
rtn = new BoxedTuple(std::move(elts));
}
++self->it;
return rtn;
}
}
......@@ -253,7 +253,9 @@ struct PyLt {
class BoxedDict : public Box {
public:
std::unordered_map<Box*, Box*, PyHasher, PyEq, StlCompatAllocator<std::pair<Box*, Box*> > > d;
typedef std::unordered_map<Box*, Box*, PyHasher, PyEq, StlCompatAllocator<std::pair<Box*, Box*> > > DictMap;
DictMap d;
BoxedDict() __attribute__((visibility("default"))) : Box(&dict_flavor, dict_cls) {}
};
......@@ -310,6 +312,5 @@ inline void initUserAttrs(Box* obj, BoxedClass* cls) {
attrs = new ((void*)attrs) HCAttrs();
}
}
}
#endif
......@@ -9,6 +9,14 @@ for i in xrange(10):
print sorted(d.items())
print sorted(d.values())
print sorted(d.keys())
print sorted(d.iteritems())
print sorted(d.itervalues())
print sorted(d.iterkeys())
l = []
for i in d:
l.append(i)
print sorted(l)
print d.pop(5, 5)
print sorted(d.items())
......
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