Commit d0590d23 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge branch 'master' of github.com:dropbox/pyston into github

parents 30729187 31a07ee2
import sys
_rand = 12345
def randint():
global _rand
_rand = (_rand * 1103515245 + 12345) % (1<<31)
return _rand
if __name__ == "__main__":
f = sys.stdin
if len(sys.argv) >= 2:
fn = sys.argv[1]
if fn != '-':
f = open(fn)
T = 100
for _T in xrange(T):
N = 1000
nums = [randint() for i in xrange(N)]
r = 0
while nums:
m = min(nums)
i = nums.index(m)
r += min(i, len(nums)-1-i)
del nums[i]
print "Case #%d: %d" % (_T+1, r)
......@@ -450,6 +450,8 @@ $(LLVM_BUILDS:%=llvm/%/$1): llvm/%/$1: llvm/%/$2
)
endef
###
# LLVM build dependency management:
$(call add_llvm_dep,lib/TableGen,lib/Support)
$(call add_llvm_dep,utils/TableGen,lib/TableGen)
$(call add_llvm_dep,lib/IR,utils/TableGen)
......@@ -469,9 +471,15 @@ $(call add_llvm_dep,utils,lib)
$(foreach tool,$(LLVM_TOOLS),$(foreach build,$(LLVM_BUILDS),$(eval \
llvm/$(build)/tools/$(tool): llvm/$(build)/lib \
)))
$(LLVM_BUILDS:%=llvm_%): llvm_%: llvm/%/lib llvm/%/tools/llvm-config $(LLVM_TOOLS:%=llvm/\%/tools/%)
##
# LLVM build subset specifications:
$(LLVM_BUILDS:%=llvm_%): llvm_%: llvm/%/lib llvm/%/tools/llvm-config
touch $(LLVM_BUILD)/$(patsubst llvm_%,built_%,$@)
llvm_release: llvm/release/tools llvm/release/utils
llvm_quick: $(LLVM_TOOLS:%=llvm/quick/tools/%)
llvm_debug: $(LLVM_TOOLS:%=llvm/debug/tools/%)
llvm_quick_clean:
$(MAKE) -C $(LLVM_BUILD) ENABLE_OPTIMIZED=1 clean
llvm_release_%:
......
......@@ -28,6 +28,9 @@
#include "valgrind.h"
#endif
//#undef VERBOSITY
//#define VERBOSITY(x) 2
namespace pyston {
namespace gc {
......
......@@ -26,6 +26,9 @@
#include "valgrind.h"
#endif
//#undef VERBOSITY
//#define VERBOSITY(x) 2
namespace pyston {
namespace gc {
......
......@@ -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);
......@@ -299,6 +310,18 @@ Box* getattr3(Box* obj, Box* _str, Box* default_value) {
return rtn;
}
Box* hasattr(Box* obj, Box* _str) {
if (_str->cls != str_cls) {
raiseExcHelper(TypeError, "hasattr(): attribute name must be string");
}
BoxedString* str = static_cast<BoxedString*>(_str);
Box* attr = getattr_internal(obj, str->s, true, true, NULL, NULL);
Box* rtn = attr ? True : False;
return rtn;
}
Box* map2(Box* f, Box* container) {
Box* rtn = new BoxedList();
for (Box* e : container->pyElements()) {
......@@ -452,10 +475,17 @@ void setupBuiltins() {
addRTFunction(getattr_func, (void*)getattr3, NULL, 3, false);
builtins_module->giveAttr("getattr", new BoxedFunction(getattr_func));
Box* hasattr_obj = new BoxedFunction(boxRTFunction((void*)hasattr, NULL, 2, false));
builtins_module->giveAttr("hasattr", hasattr_obj);
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,33 @@ Box* dictGet2(BoxedDict* self, Box* k) {
return dictGet3(self, k, None);
}
Box* dictSetdefault3(BoxedDict* self, Box* k, Box* v) {
assert(self->cls == dict_cls);
auto it = self->d.find(k);
if (it != self->d.end())
return it->second;
self->d.insert(it, std::make_pair(k, v));
return v;
}
Box* dictSetdefault2(BoxedDict* self, Box* k) {
return dictSetdefault3(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 +183,19 @@ 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);
......@@ -171,10 +205,26 @@ void setupDict() {
addRTFunction(get, (void*)dictGet3, UNKNOWN, 3, false);
dict_cls->giveAttr("get", new BoxedFunction(get));
CLFunction* setdefault = boxRTFunction((void*)dictSetdefault2, UNKNOWN, 2, false);
addRTFunction(setdefault, (void*)dictSetdefault3, UNKNOWN, 3, false);
dict_cls->giveAttr("setdefault", new BoxedFunction(setdefault));
dict_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)dictGetitem, NULL, 2, false)));
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;
}
}
......@@ -65,7 +65,6 @@ void BoxedList::shrink() {
capacity = new_capacity;
} else if (size == 0) {
rt_free(elts);
elts = NULL;
capacity = 0;
}
}
......
......@@ -121,7 +121,8 @@ extern "C" Box* intAddFloat(BoxedInt* lhs, BoxedFloat* rhs) {
extern "C" Box* intAdd(BoxedInt* lhs, Box* rhs) {
if (!isSubclass(lhs->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__add__' requires a 'int' object but received a '%s'", getTypeName(rhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__add__' requires a 'int' object but received a '%s'",
getTypeName(rhs)->c_str());
if (isSubclass(rhs->cls, int_cls)) {
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
......@@ -413,7 +414,8 @@ extern "C" Box* intInvert(BoxedInt* v) {
extern "C" Box* intPos(BoxedInt* v) {
if (!isSubclass(v->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__pos__' requires a 'int' object but received a '%s'", getTypeName(rhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__pos__' requires a 'int' object but received a '%s'",
getTypeName(v)->c_str());
if (v->cls == int_cls)
return v;
......@@ -432,7 +434,8 @@ extern "C" Box* intNonzero(BoxedInt* v) {
extern "C" BoxedString* intRepr(BoxedInt* v) {
if (!isSubclass(v->cls, int_cls))
raiseExcHelper(TypeError, "descriptor '__repr__' requires a 'int' object but received a '%s'", getTypeName(rhs)->c_str());
raiseExcHelper(TypeError, "descriptor '__repr__' requires a 'int' object but received a '%s'",
getTypeName(v)->c_str());
char buf[80];
int len = snprintf(buf, 80, "%ld", v->n);
......@@ -444,20 +447,21 @@ extern "C" Box* intHash(BoxedInt* self) {
return self;
}
extern "C" Box* intNew1(Box* cls) {
if (!is_subclass(_cls->cls, type_cls))
extern "C" Box* intNew1(Box* _cls) {
if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "int.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
return boxInt(0);
}
extern "C" Box* intNew2(Box* _cls, Box* val) {
if (!is_subclass(_cls->cls, type_cls))
if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "int.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
BoxedClass* cls = static_cast<BoxedClass*>(_cls);
if (!isSubclass(cls, int_cls))
raiseExcHelper(TypeError, "int.__new__(%s): %s is not a subtype of int", getNameOfClass(cls)->c_str(), getNameOfClass(cls)->c_str());
raiseExcHelper(TypeError, "int.__new__(%s): %s is not a subtype of int", getNameOfClass(cls)->c_str(),
getNameOfClass(cls)->c_str());
assert(cls->instance_size >= sizeof(BoxedInt));
void* mem = rt_alloc(cls->instance_size);
......
......@@ -58,7 +58,7 @@ extern "C" BoxedString* intRepr(BoxedInt* v);
extern "C" Box* intHash(BoxedInt* self);
extern "C" Box* intNew1(Box* cls);
extern "C" Box* intNew2(Box* cls, Box* val);
extern "C" Box* intInit1(BoxedInt* self);
extern "C" Box* intInit1(Box* self);
extern "C" Box* intInit2(BoxedInt* self, Box* val);
#define NUM_INTERNED_INTS 100
......
......@@ -1015,8 +1015,6 @@ extern "C" BoxedString* str(Box* obj) {
str = getclsattr_internal(obj, "__repr__", NULL, NULL);
if (str == NULL) {
ASSERT(isUserDefined(obj->cls), "%s.__str__", getTypeName(obj)->c_str());
char buf[80];
snprintf(buf, 80, "<%s object at %p>", getTypeName(obj)->c_str(), obj);
return boxStrConstant(buf);
......
......@@ -23,17 +23,19 @@ namespace pyston {
BoxedClass* set_cls, *set_iterator_cls;
const ObjectFlavor set_flavor(&boxGCHandler, NULL);
const ObjectFlavor set_iterator_flavor(&boxGCHandler, NULL);
extern "C" void setGCHandler(GCVisitor* v, void* p);
extern "C" void setIteratorGCHandler(GCVisitor* v, void* p);
const ObjectFlavor set_flavor(&setGCHandler, NULL);
const ObjectFlavor set_iterator_flavor(&setIteratorGCHandler, NULL);
namespace set {
class BoxedSetIterator : public Box {
private:
public:
BoxedSet* s;
decltype(BoxedSet::s)::iterator it;
public:
BoxedSetIterator(BoxedSet* s) : Box(&set_iterator_flavor, set_iterator_cls), s(s), it(s->s.begin()) {}
bool hasNext() { return it != s->s.end(); }
......@@ -45,6 +47,29 @@ public:
}
};
extern "C" void setGCHandler(GCVisitor* v, void* p) {
boxGCHandler(v, p);
BoxedSet* s = (BoxedSet*)p;
// This feels like a cludge, but we need to find anything that
// the unordered_map might have allocated.
// Another way to handle this would be to rt_alloc the unordered_map
// as well, though that incurs extra memory dereferences which would
// be nice to avoid.
void** start = (void**)&s->s;
void** end = start + (sizeof(s->s) / 8);
v->visitPotentialRange(start, end);
}
extern "C" void setIteratorGCHandler(GCVisitor* v, void* p) {
boxGCHandler(v, p);
BoxedSetIterator* it = (BoxedSetIterator*)p;
v->visit(it->s);
}
Box* setiteratorHasnext(BoxedSetIterator* self) {
assert(self->cls == set_iterator_cls);
return boxBool(self->hasNext());
......@@ -169,6 +194,13 @@ Box* setLen(BoxedSet* self) {
return boxInt(self->s.size());
}
Box* setAdd(BoxedSet* self, Box* v) {
assert(self->cls == set_cls);
self->s.insert(v);
return None;
}
} // namespace set
using namespace pyston::set;
......@@ -218,6 +250,8 @@ void setupSet() {
set_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)setLen, BOXED_INT, 1, false)));
set_cls->giveAttr("add", new BoxedFunction(boxRTFunction((void*)setAdd, NONE, 2, false)));
set_cls->freeze();
}
......
......@@ -42,6 +42,8 @@ extern "C" BoxedString* strAdd(BoxedString* lhs, Box* _rhs) {
}
extern "C" Box* strMod(BoxedString* lhs, Box* rhs) {
assert(lhs->cls == str_cls);
const BoxedTuple::GCVector* elts;
BoxedTuple::GCVector _elts;
if (rhs->cls == tuple_cls) {
......@@ -189,6 +191,8 @@ extern "C" BoxedString* strMul(BoxedString* lhs, BoxedInt* rhs) {
}
extern "C" Box* strEq(BoxedString* lhs, Box* rhs) {
assert(lhs->cls == str_cls);
if (rhs->cls != str_cls)
return boxBool(false);
......@@ -197,10 +201,14 @@ extern "C" Box* strEq(BoxedString* lhs, Box* rhs) {
}
extern "C" Box* strLen(BoxedString* self) {
assert(self->cls == str_cls);
return boxInt(self->s.size());
}
extern "C" Box* strStr(BoxedString* self) {
assert(self->cls == str_cls);
return self;
}
......@@ -223,6 +231,8 @@ static bool _needs_escaping[256]
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true };
static char _hex[17] = "0123456789abcdef"; // really only needs to be 16 but clang will complain
extern "C" Box* strRepr(BoxedString* self) {
assert(self->cls == str_cls);
std::ostringstream os("");
const std::string& s = self->s;
......@@ -270,11 +280,15 @@ extern "C" Box* strRepr(BoxedString* self) {
}
extern "C" Box* strHash(BoxedString* self) {
assert(self->cls == str_cls);
std::hash<std::string> H;
return boxInt(H(self->s));
}
extern "C" Box* strNonzero(BoxedString* self) {
assert(self->cls == str_cls);
return boxBool(self->s.size() != 0);
}
......@@ -290,6 +304,8 @@ extern "C" Box* strNew2(BoxedClass* cls, Box* obj) {
}
Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step) {
assert(self->cls == str_cls);
const std::string& s = self->s;
assert(step != 0);
......@@ -313,6 +329,7 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step) {
Box* strLower(BoxedString* self) {
assert(self->cls == str_cls);
std::string lowered(self->s);
std::transform(lowered.begin(), lowered.end(), lowered.begin(), tolower);
return boxString(std::move(lowered));
......@@ -380,34 +397,55 @@ Box* strSplit2(BoxedString* self, BoxedString* sep) {
}
}
Box* strStrip(BoxedString* self) {
Box* strStrip1(BoxedString* self) {
assert(self->cls == str_cls);
return new BoxedString(llvm::StringRef(self->s).trim(" \t\n\r\f\v"));
}
const std::string& s = self->s;
int n = s.size();
int strip_beginning = 0;
while (strip_beginning < n) {
char c = s[strip_beginning];
if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v')
strip_beginning++;
else
break;
Box* strStrip2(BoxedString* self, Box* chars) {
assert(self->cls == str_cls);
if (chars->cls == str_cls) {
return new BoxedString(llvm::StringRef(self->s).trim(static_cast<BoxedString*>(chars)->s));
} else if (chars->cls == none_cls) {
return strStrip1(self);
} else {
raiseExcHelper(TypeError, "strip arg must be None, str or unicode");
}
}
if (strip_beginning == n)
return boxStrConstant("");
Box* strLStrip1(BoxedString* self) {
assert(self->cls == str_cls);
return new BoxedString(llvm::StringRef(self->s).ltrim(" \t\n\r\f\v"));
}
int strip_end = 0;
while (strip_end < n) {
char c = s[n - strip_end - 1];
if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v')
strip_end++;
else
break;
Box* strLStrip2(BoxedString* self, Box* chars) {
assert(self->cls == str_cls);
if (chars->cls == str_cls) {
return new BoxedString(llvm::StringRef(self->s).ltrim(static_cast<BoxedString*>(chars)->s));
} else if (chars->cls == none_cls) {
return strLStrip1(self);
} else {
raiseExcHelper(TypeError, "lstrip arg must be None, str or unicode");
}
}
Box* strRStrip1(BoxedString* self) {
assert(self->cls == str_cls);
return new BoxedString(llvm::StringRef(self->s).rtrim(" \t\n\r\f\v"));
}
Box* strRStrip2(BoxedString* self, Box* chars) {
assert(self->cls == str_cls);
return new BoxedString(s.substr(strip_beginning, n - strip_beginning - strip_end));
if (chars->cls == str_cls) {
return new BoxedString(llvm::StringRef(self->s).rtrim(static_cast<BoxedString*>(chars)->s));
} else if (chars->cls == none_cls) {
return strRStrip1(self);
} else {
raiseExcHelper(TypeError, "rstrip arg must be None, str or unicode");
}
}
Box* strContains(BoxedString* self, Box* elt) {
......@@ -425,6 +463,8 @@ Box* strContains(BoxedString* self, Box* elt) {
extern "C" Box* strGetitem(BoxedString* self, Box* slice) {
assert(self->cls == str_cls);
if (slice->cls == int_cls) {
BoxedInt* islice = static_cast<BoxedInt*>(slice);
int64_t n = islice->n;
......@@ -541,7 +581,19 @@ void setupStr() {
str_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)strNonzero, NULL, 1, false)));
str_cls->giveAttr("lower", new BoxedFunction(boxRTFunction((void*)strLower, STR, 1, false)));
str_cls->giveAttr("strip", new BoxedFunction(boxRTFunction((void*)strStrip, STR, 1, false)));
CLFunction* strStrip = boxRTFunction((void*)strStrip1, STR, 1, false);
addRTFunction(strStrip, (void*)strStrip2, STR, 2, false);
str_cls->giveAttr("strip", new BoxedFunction(strStrip));
CLFunction* strLStrip = boxRTFunction((void*)strLStrip1, STR, 1, false);
addRTFunction(strLStrip, (void*)strLStrip2, STR, 2, false);
str_cls->giveAttr("lstrip", new BoxedFunction(strLStrip));
CLFunction* strRStrip = boxRTFunction((void*)strRStrip1, STR, 1, false);
addRTFunction(strRStrip, (void*)strRStrip2, STR, 2, false);
str_cls->giveAttr("rstrip", new BoxedFunction(strRStrip));
str_cls->giveAttr("__contains__", new BoxedFunction(boxRTFunction((void*)strContains, BOXED_BOOL, 2, false)));
str_cls->giveAttr("__add__", new BoxedFunction(boxRTFunction((void*)strAdd, NULL, 2, false)));
......
......@@ -147,10 +147,12 @@ extern "C" void listGCHandler(GCVisitor* v, void* p) {
BoxedList* l = (BoxedList*)p;
int size = l->size;
if (size) {
int capacity = l->capacity;
assert(capacity >= size);
if (capacity)
v->visit(l->elts);
if (size)
v->visitRange((void**)&l->elts->elts[0], (void**)&l->elts->elts[size]);
}
static StatCounter sc("gc_listelts_visited");
sc.log(size);
......@@ -262,6 +264,10 @@ extern "C" BoxedString* noneRepr(Box* v) {
return new BoxedString("None");
}
extern "C" Box* noneHash(Box* v) {
return boxInt(819239); // chosen randomly
}
extern "C" BoxedString* functionRepr(BoxedFunction* v) {
// TODO there has to be a better way
if (v == repr_obj)
......@@ -470,6 +476,7 @@ void setupRuntime() {
none_cls->giveAttr("__name__", boxStrConstant("NoneType"));
none_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)noneRepr, NULL, 1, false)));
none_cls->giveAttr("__str__", none_cls->getattr("__repr__"));
none_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)noneHash, NULL, 1, false)));
none_cls->freeze();
module_cls->giveAttr("__name__", boxStrConstant("module"));
......
......@@ -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())
......@@ -27,3 +35,9 @@ print sorted(d.items())
print d.get(4)
print d.get(4, 5)
print d.get(3, 5)
print sorted(d.items())
print d.setdefault(11, 9)
print sorted(d.items())
print d.setdefault(11, 10)
print sorted(d.items())
......@@ -25,6 +25,7 @@ def fact(n):
return t
if __name__ == "__main__":
# test data is from the Google CodeJam site:
s = """
3
3
......
import sys
if __name__ == "__main__":
# test data is from the Google CodeJam site:
s = """
5
66 150 4
0 67 54 133
55 20 60 67
61 63 64 67
65 63 65 85
64 21 8
32 1 55 13
42 14 61 19
16 6 26 20
11 1 13 3
14 2 30 4
28 9 30 16
5 14 14 17
11 4 13 6
99 321 10
0 52 16 52
22 52 38 52
83 52 98 52
16 105 82 105
0 158 16 158
31 158 47 158
83 158 98 158
15 211 81 211
0 264 16 264
20 264 36 264
6 313 1
0 157 5 286
76 119 8
13 17 72 80
25 98 38 117
50 116 63 118
49 2 66 12
61 92 66 105
1 52 7 105
9 80 9 91
45 113 59 114
22 437 1
0 187 21 315
""".strip()
l = s.split('\n')
T = int(l.pop(0))
for _T in xrange(T):
W, H, B = map(int, l.pop(0).split())
buildings = []
for i in xrange(B):
buildings.append(map(int, l.pop(0).split()))
grid = [[1] * H for i in xrange(W)]
for x0, y0, x1, y1 in buildings:
for x in xrange(x0, x1+1):
for y in xrange(y0, y1+1):
grid[x][y] = 0
r = 0
for sx in xrange(W):
if grid[sx][0] == 0:
continue
cx, cy = sx, 0
dx, dy = 0, 1
visited = []
while True:
# print "at", cx, cy
visited.append((cx, cy))
if cy == H-1:
for x, y in visited:
grid[x][y] = 0
r += 1
# print "made it!"
break
dx, dy = -dy, dx
failed = False
while True:
nx, ny = cx + dx, cy + dy
if nx >= 0 and nx < W and ny >= 0 and ny < H and grid[nx][ny]:
cx, cy = nx, ny
break
else:
if (cx, cy) == (sx, 0) and (dx, dy) == (0, -1):
failed = True
break
dx, dy = dy, -dx
if failed:
for x, y in visited:
grid[x][y] = 0
# print "failed"
break
# print "moved", dx, dy
print "Case #%d: %d" % (_T+1, r)
# expected: fail
# - crashes somewhere
import sys
P = 1000000007
def powmod(b, e):
r = 1
m = b
b = 1
while e:
if e & b:
r = (r * m) % P
e &= ~b
m = (m * m) % P
b <<= 1
return r
def inv(n):
return powmod(n, P - 2)
def choose(n, c):
t = 1
for i in xrange(c + 1, n + 1):
t = (t * i) % P
for i in xrange(1, n - c + 1):
t = (t * inv(i)) % P
return t
for i in xrange(1, 1000):
assert (inv(i) * i) % P == 1
if __name__ == "__main__":
# test data is from the Google CodeJam site:
s = """
5
20 16
IHAHAG
NPOEMADQGIHEB
IEDKEQCIOKKAKI
NHGMBMAINMQNGF
CDJPIQIGAJJOIQNAQGJI
JAMAPACLCHIPNBKAPG
DBBLEB
AIGIIPOQFK
FQHEBPIEADL
AADGDIGQQNKMPGK
ONJD
NH
ABMGHGHJACBJNIEJCAF
DQMELMNHNLHPNBFFQK
PCKPOQONKELNNDFBCE
JPLLNEECCMHPFDBJHEOJHJ
IMBPEMNPQLFOPB
PCNGQOENGKHJPDNAFIQLFCMO
AKCAOKP
OCGFQAAOOBFCOGNGKDM
17 10
GDICD
ABAEGLKABNCLKGGJJCAL
IDAIKCJHF
BNCFDDEBJ
CCJDBIHLMHGBAHMN
CMDFICIKHFKFJKBEIKI
IJJDCJFJ
LLMGGGHI
C
BEMECLEGBNBCNMEKJIB
HJCEFCG
DBNEKNIHIDLBNELBHADNGJ
DDCBJ
EDKGLCLGFKGKGFCMNFJ
DLHEEGGEKNEADN
EEENAMDBMLMLEJGCNNHGFBAM
AMHGBBCGFKLMEKCMGK
6 4
QMNCVNWWJCXHDHDKNARYXLP
DWHXQHJVPQDVO
QKKS
TRRIFUGURDFVDOALTMBUFCSST
LEIGFEXXOESUBMAGIDWKQRXR
KU
7 4
CDECGBCCFEDCA
BFFEB
EECGDCDECEAADFABCAFCDEG
CFGCCCDFADAF
BECCEAFGDADDBBBE
BGGCDDAADGEFCBCEDCGBEDA
EGFDGAGCDEFE
12 9
JNHNTURARPLCPJUEHPJLR
ML
SOQPUECHV
BEKHQCTBNFVLC
MGQARMIIDAPPJBUPG
ABWODFJJSEEHCKLIBU
IKFNEKCERIGUSS
LTMBPKRQJDVAQEBJVSPHUSBM
UKJOOQUSFGUOQRUNWVCMHQO
QQKRPHMRLALSAGLIDKLHFP
LAGNBBSVFEMUODPTKGEUSCKRA
INUVNMJPLMFSCSJNTUWHWOKO
""".strip()
l = s.split('\n')
T = int(l.pop(0))
for _T in xrange(T):
M, N = map(int, l.pop(0).split())
strings = []
suffix_map = {}
prefix_counts = {}
for i in xrange(M):
s = l.pop(0).strip()
strings.append(s)
for i in xrange(len(s) + 1):
substr = s[:i]
prefix_counts[substr] = prefix_counts.get(substr, 0) + 1
for i in xrange(len(s)):
substr1 = s[:i]
substr2 = s[:i+1]
suffix_map.setdefault(substr1, set([])).add(substr2)
suffix_map.setdefault(s, set([])).add(None)
worst = 0
for n in prefix_counts.values():
worst += min(n, N)
total = powmod(N, M)
mem = {}
def ftotal(into, exist):
# print N, into, exist
if into < max(exist):
return 0
key = (into, tuple(sorted(exist)))
if key in mem:
return mem[key]
bottom = 1
for e in exist:
bottom = (bottom * choose(into, e)) % P
bad = 0
# print bottom, "recursing:"
for i in xrange(1, into):
pbad = ftotal(i, exist)
# print i, choose(into, i), pbad
bad += choose(into, i) * pbad
# print bottom, bad
rtn = bottom - bad
mem[key] = rtn
return rtn
def frac(into, exist):
into = min(into, N)
exist = [min(e, N) for e in exist]
if into < max(exist):
return 0
if into == max(exist):
return 1
top = ftotal(into, exist) * choose(N, into)
bottom = 1
for e in exist:
bottom = (bottom * choose(N, e)) % P
# print top, bottom
return (top * inv(bottom)) % P
for prefix in prefix_counts:
suffix_counts = []
for suffix in suffix_map[prefix]:
if suffix is None:
suffix_counts.append(1)
else:
suffix_counts.append(prefix_counts[suffix])
fr = frac(prefix_counts[prefix], suffix_counts)
# print prefix, prefix_counts[prefix], suffix_counts, (fr * 81) % P, 81
total = (total * fr) % P
# print prefix_counts
print "Case #%d: %d %d" % (_T+1, worst, total % P)
a = 'test'
assert hasattr(a, "__str__")
assert hasattr(a, "dupa") == False
# Regression test:
# - create some lists
# - pop from them to make them empty, but still have capacity allocated
# - do some stuff to try to force a GC collection
# -- the old bug was that the element array would get freed because size=0 even though capacity>0
# - add more stuff to the array to try to get it to realloc more space
# -- crash
l = []
for i in xrange(100):
l2 = [0]
l.append(l2)
l2.pop()
for l2 in l:
l2 += range(100)
# allocate some data to try to force a collection:
# TODO shouldn't be too hard to add support for gc.collect()
range(10000)
......@@ -17,3 +17,14 @@ print sorted(s1 & s2)
print sorted(s1 | s2)
print len(set(range(5)))
s = set(range(5))
print sorted(s)
s.add(3)
print sorted(s)
s.add("")
print len(s)
s.add(None)
print len(s)
print set([1])
......@@ -20,7 +20,11 @@ print map(bool, ["hello", "", "world"])
if "":
print "bad"
print repr(" \t\n\v\ftest \t\n\v\f".strip())
testStr = " \t\n\v\ftest \t\n\v\f"
print repr(testStr.strip()), repr(testStr.lstrip()), repr(testStr.rstrip())
for c in [None, " ", "\t\f", "test"]:
print repr(testStr.strip(c)), repr(testStr.lstrip(c)), repr(testStr.rstrip(c))
for pattern in ["hello", "o w", "nope"]:
print pattern in "hello world"
......
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)
import os
import sys
def verify_include(_, dir, files):
for bn in files:
......
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