Commit 0cda22c4 authored by Stefan Behnel's avatar Stefan Behnel

allow slice assignments for arrays

parent 15d20eaf
......@@ -1779,19 +1779,29 @@ class SliceIndexNode(ExprNode):
self.start.analyse_types(env)
if self.stop:
self.stop.analyse_types(env)
if self.base.type.is_array or self.base.type.is_ptr:
# we need a ptr type here instead of an array type, as
# array types can result in invalid type casts in the C
# code
self.type = PyrexTypes.CPtrType(self.base.type.base_type)
else:
self.base = self.base.coerce_to_pyobject(env)
self.type = py_object_type
c_int = PyrexTypes.c_py_ssize_t_type
if self.start:
self.start = self.start.coerce_to(c_int, env)
if self.stop:
self.stop = self.stop.coerce_to(c_int, env)
self.type = py_object_type
self.gil_check(env)
self.is_temp = 1
gil_message = "Slicing Python object"
def generate_result_code(self, code):
if not self.type.is_pyobject:
error(self.pos,
"Slicing is not currently supported for '%s'." % self.type)
return
code.putln(
"%s = PySequence_GetSlice(%s, %s, %s); %s" % (
self.result(),
......@@ -1802,16 +1812,38 @@ class SliceIndexNode(ExprNode):
def generate_assignment_code(self, rhs, code):
self.generate_subexpr_evaluation_code(code)
if self.type.is_pyobject:
code.put_error_if_neg(self.pos,
"PySequence_SetSlice(%s, %s, %s, %s)" % (
self.base.py_result(),
self.start_code(),
self.stop_code(),
rhs.result()))
else:
if rhs.type.is_array:
# FIXME: we should check both array sizes here
array_length = rhs.type.size
else:
array_length = self.base.type.size
start_offset = ''
if self.start:
start_offset = self.start_code()
if start_offset == '0':
start_offset = ''
else:
start_offset += '+'
for i in range(array_length):
code.putln("%s[%s%s] = %s[%d];" % (
self.base.result(), start_offset, i,
rhs.result(), i))
self.generate_subexpr_disposal_code(code)
rhs.generate_disposal_code(code)
def generate_deletion_code(self, code):
if not self.type.is_pyobject:
error(self.pos,
"Deleting slices is only supported for Python types, not '%s'." % self.type)
return
self.generate_subexpr_evaluation_code(code)
code.put_error_if_neg(self.pos,
"PySequence_DelSlice(%s, %s, %s)" % (
......@@ -1829,6 +1861,8 @@ class SliceIndexNode(ExprNode):
def stop_code(self):
if self.stop:
return self.stop.result()
elif self.base.type.is_array:
return self.base.type.size
else:
return "PY_SSIZE_T_MAX"
......
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