Commit eb72b555 authored by Chris Ramstad's avatar Chris Ramstad

Merge remote-tracking branch 'upstream/master' into runtime

Conflicts:
	src/runtime/tuple.cpp
	test/tests/tuples.py
parents 3b1fed05 c7a7ed80
......@@ -49,6 +49,7 @@ TOOLS_DIR := ../tools
TESTS_DIR := ../test/tests
GPP := $(GCC_DIR)/bin/g++
GCC := $(GCC_DIR)/bin/gcc
ifeq ($(V),1)
VERBOSE := 1
......@@ -122,11 +123,12 @@ LLVM_PROFILE_LIB_DEPS := $(wildcard $(LLVM_BUILD)/Release+Profile/lib/*)
CLANG_EXE := $(LLVM_BIN)/clang
CLANGPP_EXE := $(LLVM_BIN)/clang++
COMMON_CFLAGS := -g -Werror -Wreturn-type -Woverloaded-virtual -Wall -Wno-sign-compare -Wno-unused -I. -I../include -fno-omit-frame-pointer
COMMON_CFLAGS := -g -Werror -Wreturn-type -Wall -Wno-sign-compare -Wno-unused -I. -I../include -fno-omit-frame-pointer
COMMON_CFLAGS += -Wextra -Wno-sign-compare
COMMON_CFLAGS += -Wno-unused-parameter # should use the "unused" attribute
COMMON_CXXFLAGS := $(COMMON_CFLAGS)
COMMON_CXXFLAGS += -std=c++11
COMMON_CXXFLAGS += -Woverloaded-virtual
COMMON_CXXFLAGS += -fexceptions -fno-rtti
COMMON_CXXFLAGS += -Wno-invalid-offsetof # allow the use of "offsetof", and we'll just have to make sure to only use it legally.
COMMON_CXXFLAGS += -DENABLE_INTEL_JIT_EVENTS=$(ENABLE_INTEL_JIT_EVENTS)
......@@ -203,8 +205,11 @@ endif
CLANGFLAGS := $(CXXFLAGS_DBG) $(CLANG_EXTRA_FLAGS)
CLANGFLAGS_RELEASE := $(CXXFLAGS_RELEASE) $(CLANG_EXTRA_FLAGS)
EXT_CFLAGS := $(COMMON_CFLAGS) -fPIC -Wimplicit -O2 -I../include $(CLANG_EXTRA_FLAGS)
EXT_CFLAGS := $(COMMON_CFLAGS) -fPIC -Wimplicit -O2 -I../include
EXT_CFLAGS += -Wno-missing-field-initializers
ifneq ($(USE_CLANG),0)
EXT_CFLAGS += $(CLANG_EXTRA_FLAGS)
endif
# Extra flags to enable soon:
CLANGFLAGS += -Wno-sign-conversion -Wnon-virtual-dtor -Winit-self -Wimplicit-int -Wmissing-include-dirs -Wstrict-overflow=5 -Wundef -Wpointer-arith -Wtype-limits -Wwrite-strings -Wempty-body -Waggregate-return -Wstrict-prototypes -Wold-style-definition -Wmissing-field-initializers -Wredundant-decls -Wnested-externs -Winline -Wint-to-pointer-cast -Wpointer-to-int-cast -Wlong-long -Wvla
......@@ -218,11 +223,13 @@ CLANGFLAGS += -Wno-sign-conversion -Wnon-virtual-dtor -Winit-self -Wimplicit-int
# CLANGFLAGS += -Weverything -Wno-c++98-compat-pedantic -Wno-shadow -Wno-padded -Wno-zero-length-array
CXX := $(GPP)
CC := $(GCC)
CXX_PROFILE := $(GPP)
CLANG_CXX := $(CLANGPP_EXE)
ifneq ($(USE_CLANG),0)
CXX := $(CLANG_CXX)
CC := $(CLANG_EXE)
CXXFLAGS_DBG := $(CLANGFLAGS)
CXXFLAGS_RELEASE := $(CLANGFLAGS_RELEASE)
......@@ -873,4 +880,4 @@ ext: ../test/test_extension/test.so
../lib_python/2.7_Modules/%.o: ../lib_python/2.7_Modules/%.c $(BUILD_SYSTEM_DEPS)
$(ECHO) Compiling extension file $@
$(VERB) $(CLANG_EXE) $(EXT_CFLAGS) -c $< -o $@ -g -ferror-limit=$(ERROR_LIMIT) -MMD -MP -MF $<.d
$(VERB) $(CC) $(EXT_CFLAGS) -c $< -o $@ -g -MMD -MP -MF $<.d
......@@ -77,6 +77,10 @@ Box* dictKeys(BoxedDict* self) {
return rtn;
}
Box* dictLen(BoxedDict* self) {
return boxInt(self->d.size());
}
Box* dictGetitem(BoxedDict* self, Box* k) {
Box*& pos = self->d[k];
......@@ -181,8 +185,7 @@ void setupDict() {
dict_iterator_cls = new BoxedClass(object_cls, &dictIteratorGCHandler, 0, sizeof(BoxedDict), false);
dict_cls->giveAttr("__name__", boxStrConstant("dict"));
// dict_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)dictLen, NULL, 1)));
// dict_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)dictGetitem, NULL, 2)));
dict_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)dictLen, BOXED_INT, 1)));
dict_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)dictNew, UNKNOWN, 1, 0, false, true)));
// dict_cls->giveAttr("__init__", new BoxedFunction(boxRTFunction((void*)dictInit, NULL, 1)));
dict_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)dictRepr, STR, 1)));
......
......@@ -376,6 +376,145 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step) {
return boxString(std::string(chars.begin(), chars.end()));
}
Box* strIsAlpha(BoxedString* self) {
assert(self->cls == str_cls);
const std::string& str(self->s);
if (str.empty())
return False;
for (const auto& c : str) {
if (!std::isalpha(c))
return False;
}
return True;
}
Box* strIsDigit(BoxedString* self) {
assert(self->cls == str_cls);
const std::string& str(self->s);
if (str.empty())
return False;
for (const auto& c : str) {
if (!std::isdigit(c))
return False;
}
return True;
}
Box* strIsAlnum(BoxedString* self) {
assert(self->cls == str_cls);
const std::string& str(self->s);
if (str.empty())
return False;
for (const auto& c : str) {
if (!std::isalnum(c))
return False;
}
return True;
}
Box* strIsLower(BoxedString* self) {
assert(self->cls == str_cls);
const std::string& str(self->s);
bool lowered = false;
if (str.empty())
return False;
for (const auto& c : str) {
if (std::isspace(c) || std::isdigit(c)) {
continue;
} else if (!std::islower(c)) {
return False;
} else {
lowered = true;
}
}
return boxBool(lowered);
}
Box* strIsUpper(BoxedString* self) {
assert(self->cls == str_cls);
const std::string& str(self->s);
bool uppered = false;
if (str.empty())
return False;
for (const auto& c : str) {
if (std::isspace(c) || std::isdigit(c)) {
continue;
} else if (!std::isupper(c)) {
return False;
} else {
uppered = true;
}
}
return boxBool(uppered);
}
Box* strIsSpace(BoxedString* self) {
assert(self->cls == str_cls);
const std::string& str(self->s);
if (str.empty())
return False;
for (const auto& c : str) {
if (!std::isspace(c))
return False;
}
return True;
}
Box* strIsTitle(BoxedString* self) {
assert(self->cls == str_cls);
const std::string& str(self->s);
if (str.empty())
return False;
if (str.size() == 1)
return boxBool(std::isupper(str[0]));
bool cased = false, start_of_word = true;
for (const auto& c : str) {
if (std::isupper(c)) {
if (!start_of_word) {
return False;
}
start_of_word = false;
cased = true;
} else if (std::islower(c)) {
if (start_of_word) {
return False;
}
start_of_word = false;
cased = true;
} else {
start_of_word = true;
}
}
return boxBool(cased);
}
Box* strJoin(BoxedString* self, Box* rhs) {
assert(self->cls == str_cls);
......@@ -660,6 +799,14 @@ void setupStr() {
str_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)strHash, BOXED_INT, 1)));
str_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)strNonzero, BOXED_BOOL, 1)));
str_cls->giveAttr("isalnum", new BoxedFunction(boxRTFunction((void*)strIsAlnum, STR, 1)));
str_cls->giveAttr("isalpha", new BoxedFunction(boxRTFunction((void*)strIsAlpha, STR, 1)));
str_cls->giveAttr("isdigit", new BoxedFunction(boxRTFunction((void*)strIsDigit, STR, 1)));
str_cls->giveAttr("islower", new BoxedFunction(boxRTFunction((void*)strIsLower, STR, 1)));
str_cls->giveAttr("isspace", new BoxedFunction(boxRTFunction((void*)strIsSpace, STR, 1)));
str_cls->giveAttr("istitle", new BoxedFunction(boxRTFunction((void*)strIsTitle, STR, 1)));
str_cls->giveAttr("isupper", new BoxedFunction(boxRTFunction((void*)strIsUpper, STR, 1)));
str_cls->giveAttr("lower", new BoxedFunction(boxRTFunction((void*)strLower, STR, 1)));
str_cls->giveAttr("swapcase", new BoxedFunction(boxRTFunction((void*)strSwapcase, STR, 1)));
str_cls->giveAttr("upper", new BoxedFunction(boxRTFunction((void*)strUpper, STR, 1)));
......
......@@ -33,26 +33,71 @@ extern "C" Box* createTuple(int64_t nelts, Box** elts) {
return new BoxedTuple(std::move(velts));
}
Box* tupleGetitem(BoxedTuple* self, Box* slice) {
assert(self->cls == tuple_cls);
Box* _tupleSlice(BoxedTuple* self, i64 start, i64 stop, i64 step) {
i64 size = self->elts.size();
assert(step != 0);
if (step > 0) {
assert(0 <= start);
assert(stop <= size);
} else {
assert(start < size);
assert(-1 <= stop);
}
if (slice->cls == int_cls) {
i64 n = static_cast<BoxedInt*>(slice)->n;
// This is adapted from CPython's PySlice_GetIndicesEx.
i64 slicelength;
if (step < 0)
slicelength = (stop - start + 1) / (step)+1;
else
slicelength = (stop - start - 1) / (step)+1;
if (n < 0)
n = size - n;
if (n < 0 || n >= size) {
fprintf(stderr, "IndexError: tuple index out of range\n");
raiseExcHelper(IndexError, "");
}
if (slicelength < 0)
slicelength = 0;
Box* rtn = self->elts[n];
return rtn;
} else {
RELEASE_ASSERT(0, "");
// FIXME: No need to initialize with 0.
BoxedTuple::GCVector velts(slicelength, 0);
i64 curr, i;
for (curr = start, i = 0; i < slicelength; curr += step, i++)
velts[i] = self->elts[curr];
return new BoxedTuple(std::move(velts));
}
Box* tupleGetitemInt(BoxedTuple* self, BoxedInt* slice) {
i64 n = slice->n;
i64 size = self->elts.size();
if (n < 0)
n = size - n;
if (n < 0 || n >= size) {
fprintf(stderr, "IndexError: tuple index out of range\n");
raiseExcHelper(IndexError, "");
}
Box* rtn = self->elts[n];
return rtn;
}
Box* tupleGetitemSlice(BoxedTuple* self, BoxedSlice* slice) {
assert(self->cls == tuple_cls);
assert(slice->cls == slice_cls);
i64 start, stop, step;
parseSlice(slice, self->elts.size(), &start, &stop, &step);
return _tupleSlice(self, start, stop, step);
}
Box* tupleGetitem(BoxedTuple* self, Box* slice) {
assert(self->cls == tuple_cls);
if (slice->cls == int_cls)
return tupleGetitemInt(self, static_cast<BoxedInt*>(slice));
else if (slice->cls == slice_cls)
return tupleGetitemSlice(self, static_cast<BoxedSlice*>(slice));
else
raiseExcHelper(TypeError, "tuple indices must be integers, not %s", getTypeName(slice)->c_str());
}
Box* tupleAdd(BoxedTuple* self, Box* rhs) {
......@@ -257,8 +302,14 @@ void setupTuple() {
tuple_cls->giveAttr("__name__", boxStrConstant("tuple"));
tuple_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)tupleGetitem, UNKNOWN, 2)));
tuple_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)tupleNew, UNKNOWN, 1, 0, true, true)));
CLFunction* getitem = createRTFunction(2, 0, 0, 0);
addRTFunction(getitem, (void*)tupleGetitemInt, UNKNOWN,
std::vector<ConcreteCompilerType*>{ BOXED_TUPLE, BOXED_INT });
addRTFunction(getitem, (void*)tupleGetitemSlice, SLICE, std::vector<ConcreteCompilerType*>{ BOXED_TUPLE, SLICE });
addRTFunction(getitem, (void*)tupleGetitem, UNKNOWN, std::vector<ConcreteCompilerType*>{ BOXED_TUPLE, UNKNOWN });
tuple_cls->giveAttr("__getitem__", new BoxedFunction(getitem));
tuple_cls->giveAttr("__contains__", new BoxedFunction(boxRTFunction((void*)tupleContains, BOXED_BOOL, 2)));
tuple_cls->giveAttr("__iter__",
......
......@@ -32,12 +32,6 @@ try:
except TypeError:
print 'TypeError raised'
for i in xrange(256):
c = chr(i)
s = "a%sb" % c
if s.title()[2] == 'b':
print repr(c)
try:
var = 'hello'
var.lower(42)
......@@ -58,3 +52,94 @@ try:
print 'TypeError not raised'
except TypeError:
print 'TypeError raised'
# Testing isalnum, isalpha, isdigit, islower, isspace, istitle and isupper methods
def test_is(s):
print 'string:', repr(s), 'isalnum:', s.isalnum(), 'isalpha:', s.isalpha(), 'isdigit:', s.isdigit(), 'islower:', s.islower(), 'isspace:', s.isspace(), 'istitle:', s.istitle(), 'isupper:', s.isupper()
test_is('')
test_is('a')
test_is('A')
test_is('123abc456')
test_is('a1b3c')
test_is('aBc000 ')
test_is('abc\n')
test_is('aBc123')
test_is('abc')
test_is('0')
test_is('0123456789')
test_is('0123456789a')
test_is(' ')
test_is('\t')
test_is('\r')
test_is('\n')
test_is(' \t\r\n')
test_is(' \t\r\na')
test_is('A Titlecased Line')
test_is('A\nTitlecased Line')
test_is('A Titlecased, Line')
test_is('Not a capitalized String')
test_is('Not\ta Titlecase String')
test_is('Not--a Titlecase String')
test_is('NOT')
for i in xrange(256):
c = chr(i)
s = "a%sb" % c
if s.title()[2] == 'b':
print repr(c)
test(c)
test_is(c)
try:
var = 'abc'
var.isalnum(42)
print 'TypeError not raised'
except TypeError:
print 'TypeError raised'
try:
var = 'abc'
var.isalpha(42)
print 'TypeError not raised'
except TypeError:
print 'TypeError raised'
try:
var = 'abc'
var.isdigit(42)
print 'TypeError not raised'
except TypeError:
print 'TypeError raised'
try:
var = 'abc'
var.islower(42)
print 'TypeError not raised'
except TypeError:
print 'TypeError raised'
try:
var = 'abc'
var.isspace(42)
print 'TypeError not raised'
except TypeError:
print 'TypeError raised'
try:
var = 'abc'
var.istitle(42)
print 'TypeError not raised'
except TypeError:
print 'TypeError raised'
try:
var = 'abc'
var.isupper(42)
print 'TypeError not raised'
except TypeError:
print 'TypeError raised'
......@@ -83,7 +83,7 @@ print tuple((1,3,7,42))
print tuple(['i', 42, 'j', 318])
print tuple('hello world')
print tuple({'a': 1})
#print tuple({1,2,3,4})
print sorted(tuple({1,2,3,4}))
print tuple(sequence=(1,3,7,42))
print tuple(sequence=['i', 42, 'j', 318])
......@@ -118,3 +118,38 @@ try:
tuple(oops='invalid keyword')
except TypeError, e:
print e
# __getitem__
t = (1, "2")
print t[0]
print t[1]
t = (1, 2, 'a', 'b', 'c')
print t[::-1]
print t[:-1]
print t[0:2]
print t[-5:]
print t[-5:3]
print t[-5:10]
print t[:-5]
print t[:3]
print t[:10]
print t[1:3:-1]
print t[3:1:-1]
print t[1:3:1]
print t[1:3:2]
print t[1:5:3]
print t[5:1:-1]
print t[5:1:-2]
print t[5:1:-5]
print t[5:1]
try:
t[None]
except TypeError as e:
print e
try:
t[(1, 2)]
except TypeError 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