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

CTuple indexing support.

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