Commit 8ffe4e64 authored by Kevin Modzelewski's avatar Kevin Modzelewski

tuple.index, set.__eq__ and __ne__

Also fix str.rpartition, and add a signal handler for SIGUSR1 that
prints out a stack trace.  I wanted this because our stack unwinder
doesn't work when called from a gdb print command, so it was hard to
debug why we were in an infinite loop.

Also, fix the '-i' argument so that we get back to the repl if the
program throws an exception.
parent 9b7cb891
......@@ -42,6 +42,7 @@
#include "core/options.h"
#include "core/types.h"
#include "core/util.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
/*
......@@ -167,10 +168,10 @@ public:
}
};
static void handle_sigfpe(int signum) {
assert(signum == SIGFPE);
fprintf(stderr, "SIGFPE!\n");
abort();
static void handle_sigusr1(int signum) {
assert(signum == SIGUSR1);
fprintf(stderr, "SIGUSR1, printing stack trace\n");
_printStacktrace();
}
static void handle_sigint(int signum) {
......@@ -272,6 +273,7 @@ void initCodegen() {
setupRuntime();
// signal(SIGFPE, &handle_sigfpe);
signal(SIGUSR1, &handle_sigusr1);
signal(SIGINT, &handle_sigint);
......
......@@ -207,14 +207,18 @@ static int main(int argc, char** argv) {
llvm::sys::path::remove_filename(path);
prependToSysPath(path.str());
main_module = createModule("__main__", fn);
try {
main_module = createAndRunModule("__main__", fn);
AST_Module* ast = caching_parse_file(fn);
compileAndRunModule(ast, main_module);
} catch (ExcInfo e) {
int retcode = 1;
(void)handle_toplevel_exn(e, &retcode);
if (stats)
Stats::dump();
return retcode;
if (!force_repl) {
if (stats)
Stats::dump();
return retcode;
}
}
}
......
......@@ -36,6 +36,7 @@ extern "C" void raise0() __attribute__((__noreturn__));
extern "C" void raise3(Box*, Box*, Box*) __attribute__((__noreturn__));
void raiseExc(Box* exc_obj) __attribute__((__noreturn__));
void raiseRaw(const ExcInfo& e) __attribute__((__noreturn__));
void _printStacktrace();
extern "C" Box* deopt(AST_expr* expr, Box* value);
......
......@@ -334,6 +334,29 @@ Box* setContains(BoxedSet* self, Box* v) {
return boxBool(self->s.count(v) != 0);
}
Box* setEq(BoxedSet* self, BoxedSet* rhs) {
assert(self->cls == set_cls || self->cls == frozenset_cls);
if (rhs->cls != set_cls && rhs->cls != frozenset_cls)
return NotImplemented;
if (self->s.size() != rhs->s.size())
return False;
for (auto e : self->s) {
if (!rhs->s.count(e))
return False;
}
return True;
}
Box* setNe(BoxedSet* self, BoxedSet* rhs) {
Box* r = setEq(self, rhs);
if (r->cls == bool_cls)
return boxBool(r == False);
assert(r == NotImplemented);
return r;
}
Box* setNonzero(BoxedSet* self) {
return boxBool(self->s.size());
}
......@@ -416,6 +439,11 @@ void setupSet() {
set_cls->giveAttr("__contains__", new BoxedFunction(boxRTFunction((void*)setContains, BOXED_BOOL, 2)));
frozenset_cls->giveAttr("__contains__", set_cls->getattr("__contains__"));
set_cls->giveAttr("__eq__", new BoxedFunction(boxRTFunction((void*)setEq, UNKNOWN, 2)));
frozenset_cls->giveAttr("__eq__", set_cls->getattr("__eq__"));
set_cls->giveAttr("__ne__", new BoxedFunction(boxRTFunction((void*)setNe, UNKNOWN, 2)));
frozenset_cls->giveAttr("__ne__", set_cls->getattr("__ne__"));
set_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)setNonzero, BOXED_BOOL, 1)));
frozenset_cls->giveAttr("__nonzero__", set_cls->getattr("__nonzero__"));
......
......@@ -1745,7 +1745,7 @@ Box* strRpartition(BoxedString* self, BoxedString* sep) {
size_t found_idx = self->s.rfind(sep->s);
if (found_idx == std::string::npos)
return new BoxedTuple({ self, boxStrConstant(""), boxStrConstant("") });
return new BoxedTuple({ boxStrConstant(""), boxStrConstant(""), self });
return new BoxedTuple({ boxStrConstantSize(self->s.c_str(), found_idx),
......
......@@ -289,6 +289,19 @@ Box* tupleContains(BoxedTuple* self, Box* elt) {
return False;
}
Box* tupleIndex(BoxedTuple* self, Box* elt) {
int size = self->elts.size();
for (int i = 0; i < size; i++) {
Box* e = self->elts[i];
Box* cmp = compareInternal(e, elt, AST_TYPE::Eq, NULL);
bool b = nonzero(cmp);
if (b)
return boxInt(i);
}
raiseExcHelper(ValueError, "tuple.index(x): x not in tuple");
}
Box* tupleHash(BoxedTuple* self) {
assert(isSubclass(self->cls, tuple_cls));
......@@ -397,6 +410,7 @@ void setupTuple() {
tuple_cls->giveAttr("__getitem__", new BoxedFunction(getitem));
tuple_cls->giveAttr("__contains__", new BoxedFunction(boxRTFunction((void*)tupleContains, BOXED_BOOL, 2)));
tuple_cls->giveAttr("index", new BoxedFunction(boxRTFunction((void*)tupleIndex, BOXED_INT, 2)));
tuple_cls->giveAttr("__iter__",
new BoxedFunction(boxRTFunction((void*)tupleIter, typeFromClass(tuple_iterator_cls), 1)));
......
......@@ -102,4 +102,4 @@ print s
s = set(range(5))
for i in xrange(10):
s2 = set(range(i))
print s.issubset(s2), s.issuperset(s2)
print s.issubset(s2), s.issuperset(s2), s == s2, s != s2
......@@ -150,8 +150,10 @@ print repr("hello\tworld\t".expandtabs(12))
print "hello world".startswith(("x", "h"))
print "hello world".endswith(("x", "h"))
print "a.b.c.d".partition('.')
print "a.b.c.d".rpartition('.')
print "partition:", "a.b.c.d".partition('.')
print "rpartition:", "a.b.c.d".rpartition('.')
print "partition:", "abcd".partition('.')
print "rpartition:", "abcd".rpartition('.')
print 'ab c\n\nde fg\rkl\r\n'.splitlines()
print 'ab c\n\nde fg\rkl\r\n'.splitlines(True)
......
......@@ -208,3 +208,9 @@ print -1 * x
print 0 * x
print 1 * x
print 5 * x
print (1, 3, 5, 3).index(3)
try:
print (1, 3, 5, 3).index(2)
except ValueError as e:
print e
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