Commit 6922f0e7 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Starting to add sets

parent b974b146
......@@ -1388,6 +1388,6 @@ CompilerVariable* undefVariable() {
}
ConcreteCompilerType *LIST, *SLICE, *MODULE, *DICT;
ConcreteCompilerType *LIST, *SLICE, *MODULE, *DICT, *SET;
} // namespace pyston
......@@ -29,7 +29,7 @@ class OpInfo;
class CompilerType;
class IREmitter;
extern ConcreteCompilerType *INT, *BOXED_INT, *FLOAT, *BOXED_FLOAT, *VOID, *UNKNOWN, *BOOL, *STR, *NONE, *LIST, *SLICE, *MODULE, *DICT, *BOOL, *BOXED_BOOL, *BOXED_TUPLE;
extern ConcreteCompilerType *INT, *BOXED_INT, *FLOAT, *BOXED_FLOAT, *VOID, *UNKNOWN, *BOOL, *STR, *NONE, *LIST, *SLICE, *MODULE, *DICT, *BOOL, *BOXED_BOOL, *BOXED_TUPLE, *SET;
extern CompilerType* UNDEF;
class CompilerType {
......
......@@ -21,6 +21,7 @@
#include "runtime/gc_runtime.h"
#include "runtime/objmodel.h"
#include "runtime/set.h"
#include "runtime/types.h"
#include "runtime/util.h"
......@@ -315,6 +316,7 @@ void setupBuiltins() {
builtins_module->setattr("file", file_cls, NULL, NULL);
builtins_module->setattr("bool", bool_cls, NULL, NULL);
builtins_module->setattr("dict", dict_cls, NULL, NULL);
builtins_module->setattr("set", set_cls, NULL, NULL);
builtins_module->setattr("tuple", tuple_cls, NULL, NULL);
builtins_module->setattr("instancemethod", instancemethod_cls, NULL, NULL);
}
......
......@@ -104,9 +104,8 @@ Box* dictSetitem(BoxedDict* self, Box* k, Box* v) {
void dict_dtor(BoxedDict* self) {
self->d.clear();
// Not sure how to express this without the typedef:
typedef BoxedDict::PyDict T;
(&self->d)->~T();
// I can't believe this works:
(&self->d)->~decltype(self->d)();
}
void setupDict() {
......
......@@ -284,18 +284,26 @@ extern "C" Box* listNew1(Box* cls) {
return new BoxedList();
}
extern "C" Box* listNew2(Box* cls, Box* rhs) {
extern "C" Box* listNew2(Box* cls, Box* container) {
assert(cls == list_cls);
RELEASE_ASSERT(rhs->cls == list_cls, "unsupported for now");
BoxedList *lrhs = static_cast<BoxedList*>(rhs);
int size = lrhs->size;
static std::string _iter("__iter__");
static std::string _hasnext("__hasnext__");
static std::string _next("next");
BoxedList *rtn = new BoxedList();
rtn->elts = new (size) BoxedList::ElementArray();
memcpy(rtn->elts->elts, lrhs->elts->elts, size * sizeof(Box*));
rtn->size = size;
rtn->capacity = size;
Box* iter = callattr(container, &_iter, true, 0, NULL, NULL, NULL, NULL);
Box* rtn = new BoxedList();
while (true) {
Box* hasnext = callattr(iter, &_hasnext, true, 0, NULL, NULL, NULL, NULL);
bool hasnext_bool = nonzero(hasnext);
if (!hasnext_bool)
break;
Box* next = callattr(iter, &_next, true, 0, NULL, NULL, NULL, NULL);
listAppendInternal(rtn, next);
}
return rtn;
}
......
// 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 "runtime/set.h"
#include "runtime/objmodel.h"
#include "codegen/compvars.h"
#include <sstream>
namespace pyston {
BoxedClass *set_cls;
const ObjectFlavor set_flavor(&boxGCHandler, NULL);
Box* setAdd2(Box* _self, Box* b) {
assert(_self->cls == set_cls);
BoxedSet* self = static_cast<BoxedSet*>(_self);
self->s.insert(b);
return None;
}
Box* setNew1(Box* cls) {
assert(cls == set_cls);
return new BoxedSet();
}
Box* setNew2(Box* cls, Box *container) {
assert(cls == set_cls);
static std::string _iter("__iter__");
static std::string _hasnext("__hasnext__");
static std::string _next("next");
Box* iter = callattr(container, &_iter, true, 0, NULL, NULL, NULL, NULL);
Box* rtn = new BoxedSet();
while (true) {
Box* hasnext = callattr(iter, &_hasnext, true, 0, NULL, NULL, NULL, NULL);
bool hasnext_bool = nonzero(hasnext);
if (!hasnext_bool)
break;
Box* next = callattr(iter, &_next, true, 0, NULL, NULL, NULL, NULL);
setAdd2(rtn, next);
}
return rtn;
}
Box* setRepr(BoxedSet* self) {
assert(self->cls == set_cls);
std::ostringstream os("");
os << "set([";
bool first = true;
for (Box* elt : self->s) {
if (!first) {
os << ", ";
}
os << repr(elt)->s;
first = false;
}
os << "])";
return boxString(os.str());
}
Box* setOrSet(BoxedSet *lhs, BoxedSet *rhs) {
assert(lhs->cls == set_cls);
assert(rhs->cls == set_cls);
BoxedSet* rtn = new BoxedSet();
for (Box* elt : lhs->s) {
rtn->s.insert(elt);
}
for (Box* elt : rhs->s) {
rtn->s.insert(elt);
}
return rtn;
}
Box* setAndSet(BoxedSet *lhs, BoxedSet *rhs) {
assert(lhs->cls == set_cls);
assert(rhs->cls == set_cls);
BoxedSet* rtn = new BoxedSet();
for (Box* elt : lhs->s) {
if (rhs->s.count(elt))
rtn->s.insert(elt);
}
return rtn;
}
Box* setSubSet(BoxedSet *lhs, BoxedSet *rhs) {
assert(lhs->cls == set_cls);
assert(rhs->cls == set_cls);
BoxedSet* rtn = new BoxedSet();
for (Box* elt : lhs->s) {
// TODO if len(rhs) << len(lhs), it might be more efficient
// to delete the elements of rhs from lhs?
if (rhs->s.count(elt) == 0)
rtn->s.insert(elt);
}
return rtn;
}
Box* setXorSet(BoxedSet *lhs, BoxedSet *rhs) {
assert(lhs->cls == set_cls);
assert(rhs->cls == set_cls);
BoxedSet* rtn = new BoxedSet();
for (Box* elt : lhs->s) {
if (rhs->s.count(elt) == 0)
rtn->s.insert(elt);
}
for (Box* elt : rhs->s) {
if (lhs->s.count(elt) == 0)
rtn->s.insert(elt);
}
return rtn;
}
void setupSet() {
set_cls->giveAttr("__name__", boxStrConstant("set"));
CLFunction *new_ = boxRTFunction((void*)setNew1, SET, 1, false);
addRTFunction(new_, (void*)setNew2, SET, 2, false);
set_cls->giveAttr("__new__", new BoxedFunction(new_));
Box* repr = new BoxedFunction(boxRTFunction((void*)setRepr, STR, 1, false));
set_cls->giveAttr("__repr__", repr);
set_cls->giveAttr("__str__", repr);
std::vector<ConcreteCompilerType*> v_ss, v_su;
v_ss.push_back(SET); v_ss.push_back(SET);
v_su.push_back(SET); v_su.push_back(UNKNOWN);
CLFunction *or_ = createRTFunction();
addRTFunction(or_, (void*)setOrSet, SET, v_ss, false);
set_cls->giveAttr("__or__", new BoxedFunction(or_));
CLFunction *sub_ = createRTFunction();
addRTFunction(sub_, (void*)setSubSet, SET, v_ss, false);
set_cls->giveAttr("__sub__", new BoxedFunction(sub_));
CLFunction *xor_ = createRTFunction();
addRTFunction(xor_, (void*)setXorSet, SET, v_ss, false);
set_cls->giveAttr("__xor__", new BoxedFunction(xor_));
CLFunction *and_ = createRTFunction();
addRTFunction(and_, (void*)setAndSet, SET, v_ss, false);
set_cls->giveAttr("__and__", new BoxedFunction(and_));
set_cls->freeze();
}
void teardownSet() {
}
}
// 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_SET_H
#define PYSTON_RUNTIME_SET_H
#include "runtime/types.h"
#include "core/types.h"
#include <unordered_set>
namespace pyston {
void setupSet();
void teardownSet();
extern BoxedClass* set_cls;
extern const ObjectFlavor set_flavor;
class BoxedSet : public Box {
public:
std::unordered_set<Box*, PyHasher, PyEq, StlCompatAllocator<Box*> > s;
BoxedSet() __attribute__((visibility("default"))) : Box(&set_flavor, set_cls) {}
};
}
#endif
......@@ -25,6 +25,7 @@
#include "runtime/gc_runtime.h"
#include "runtime/objmodel.h"
#include "runtime/set.h"
#include "runtime/types.h"
#include "gc/collector.h"
......@@ -354,6 +355,9 @@ void setupRuntime() {
module_cls = new BoxedClass(true, NULL);
// TODO it'd be nice to be able to do these in the respective setupType methods,
// but those setup methods probably want access to these objects.
// We could have a multi-stage setup process, but that seems overkill for now.
bool_cls = new BoxedClass(false, NULL);
int_cls = new BoxedClass(false, NULL);
float_cls = new BoxedClass(false, NULL);
......@@ -365,6 +369,7 @@ void setupRuntime() {
dict_cls = new BoxedClass(false, (BoxedClass::Dtor)dict_dtor);
tuple_cls = new BoxedClass(false, (BoxedClass::Dtor)tuple_dtor);
file_cls = new BoxedClass(false, (BoxedClass::Dtor)file_dtor);
set_cls = new BoxedClass(false, NULL);
STR = typeFromClass(str_cls);
BOXED_INT = typeFromClass(int_cls);
......@@ -375,6 +380,7 @@ void setupRuntime() {
SLICE = typeFromClass(slice_cls);
MODULE = typeFromClass(module_cls);
DICT = typeFromClass(dict_cls);
SET = typeFromClass(set_cls);
BOXED_TUPLE = typeFromClass(tuple_cls);
type_cls->giveAttr("__name__", boxStrConstant("type"));
......@@ -400,6 +406,7 @@ void setupRuntime() {
setupStr();
setupList();
setupDict();
setupSet();
setupTuple();
setupFile();
......@@ -467,6 +474,7 @@ void teardownRuntime() {
teardownStr();
teardownBool();
teardownDict();
teardownSet();
teardownTuple();
teardownFile();
......
......@@ -238,8 +238,7 @@ class StlCompatAllocator {
class BoxedDict : public Box {
public:
typedef std::unordered_map<Box*, Box*, PyHasher, PyEq, StlCompatAllocator<std::pair<Box*, Box*> > > PyDict;
PyDict d;
std::unordered_map<Box*, Box*, PyHasher, PyEq, StlCompatAllocator<std::pair<Box*, Box*> > > d;
BoxedDict() __attribute__((visibility("default"))) : Box(&dict_flavor, dict_cls) {}
};
......
def sorted(s):
l = list(s)
l.sort()
return repr(l)
s1 = set() | set(range(3))
print sorted(s1)
s2 = set(range(1, 5))
print sorted(s2)
print repr(sorted(s1)), str(sorted(s1))
print sorted(s1 - s2)
print sorted(s2 - s1)
print sorted(s1 ^ s2)
print sorted(s1 & s2)
print sorted(s1 | s2)
s3 = s1
s1 -= s2
print sorted(s1), sorted(s2), sorted(s3)
# expected: fail
print hasattr(set, "__ior__")
print hasattr(set, "__isub__")
print hasattr(set, "__iand__")
print hasattr(set, "__ixor__")
s1 = set() | set(range(3))
s2 = set(range(1, 5))
s3 = s1
s1 -= s2
print s1, s2, s3
......@@ -378,7 +378,8 @@ if __name__ == "__main__":
subprocess.check_call(["make", "-j4", IMAGE], stdout=open("/dev/null", 'w'), stderr=subprocess.PIPE)
print "done"
tests.sort(key=fileSize)
if not patterns:
tests.sort(key=fileSize)
for fn in tests:
if fn in TOSKIP:
......
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