Commit 4598f534 authored by Robert Bradshaw's avatar Robert Bradshaw

CTuple indexing support.

parent ed37fcd8
......@@ -2916,6 +2916,12 @@ class IndexNode(ExprNode):
return item_type
elif base_type.is_ptr or base_type.is_array:
return base_type.base_type
elif base_type.is_ctuple and isinstance(self.index, IntNode):
index = self.index.constant_result
if index < 0:
index += base_type.size
if 0 <= index < base_type.size:
return base_type.components[index]
if base_type.is_cpp_class:
class FakeOperand:
......@@ -3251,6 +3257,23 @@ class IndexNode(ExprNode):
error(self.pos, "Wrong number of template arguments: expected %s, got %s" % (
(len(base_type.templates), len(self.type_indices))))
self.type = base_type.specialize(dict(zip(base_type.templates, self.type_indices)))
elif base_type.is_ctuple:
if isinstance(self.index, IntNode):
index = self.index.constant_result
if -base_type.size <= index < base_type.size:
if index < 0:
index += base_type.size
self.type = base_type.components[index]
else:
error(self.pos,
"Index %s out of bounds for '%s'" %
(index, base_type))
self.type = PyrexTypes.error_type
else:
error(self.pos,
"Can't use non-constant indices for '%s'" %
base_type)
self.type = PyrexTypes.error_type
else:
error(self.pos,
"Attempting to index non-array type '%s'" %
......@@ -3436,6 +3459,11 @@ class IndexNode(ExprNode):
return "%s<%s>" % (
self.base.result(),
",".join([param.declaration_code("") for param in self.type_indices]))
elif self.base.type.is_ctuple:
index = self.index.constant_result
if index < 0:
index += self.base.type.size
return "%s.f%s" % (self.base.result(), index)
else:
if (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
error(self.pos, "Invalid use of pointer slice")
......
......@@ -224,6 +224,7 @@ class PyrexType(BaseType):
is_returncode = 0
is_error = 0
is_buffer = 0
is_ctuple = 0
is_memoryviewslice = 0
has_attributes = 0
default_value = ""
......@@ -3313,9 +3314,12 @@ class CEnumType(CType):
class CTupleType(CType):
# components [PyrexType]
is_ctuple = True
def __init__(self, cname, components):
self.cname = cname
self.components = components
self.size = len(components)
self.to_py_function = "%s_to_py_%s" % (Naming.convert_func_prefix, self.cname)
self.from_py_function = "%s_from_py_%s" % (Naming.convert_func_prefix, self.cname)
self.exception_check = True
......
def convert(*o):
def simple_convert(*o):
"""
>>> convert(1, 2)
>>> simple_convert(1, 2)
(1, 2.0)
>>> convert(1)
>>> simple_convert(1)
Traceback (most recent call last):
...
TypeError: Expected a tuple of size 2, got tuple
>>> convert(1, 2, 3)
>>> simple_convert(1, 2, 3)
Traceback (most recent call last):
...
TypeError: Expected a tuple of size 2, got tuple
......@@ -15,6 +15,17 @@ def convert(*o):
cdef (int, double) xy = o
return xy
def rotate_via_indexing((int, int, double) xyz):
"""
>>> rotate_via_indexing((1, 2, 3))
(2, 3, 1.0)
"""
a = xyz[0]
xyz[0] = xyz[1]
xyz[1] = <int>xyz[2]
xyz[-1] = a
return xyz
cpdef (int, double) ctuple_return_type(x, y):
"""
>>> ctuple_return_type(1, 2)
......
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