summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2017-10-24 21:01:34 +0200
committerStefan Behnel <stefan_ml@behnel.de>2017-10-24 21:03:40 +0200
commit150c4283b05ed67c9620606bc298ba34b0f70fbb (patch)
tree45295e3ab96a4f4b7fc7ed102a511e5235f21b2e
parent41b4a28d7c7c505d58502c9cf69bde2e33091de0 (diff)
downloadcython-150c4283b05ed67c9620606bc298ba34b0f70fbb.tar.gz
Repair indexing syntax in generated Pythran code: must use "(...)" for multiple indices, but "[...]" for a single index.
Also refactor indexing code to avoid duplication. Closes #1946.
-rw-r--r--Cython/Compiler/ExprNodes.py4
-rw-r--r--Cython/Compiler/Pythran.py80
2 files changed, 47 insertions, 37 deletions
diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py
index cb3d3ab78..e71292d0f 100644
--- a/Cython/Compiler/ExprNodes.py
+++ b/Cython/Compiler/ExprNodes.py
@@ -4193,7 +4193,7 @@ class BufferIndexNode(_IndexingBaseNode):
# case.
code.putln("__Pyx_call_destructor(%s);" % obj)
code.putln("new (&%s) decltype(%s){%s};" % (obj, obj, self.base.pythran_result()))
- code.putln("%s(%s) %s= %s;" % (
+ code.putln("%s%s %s= %s;" % (
obj,
pythran_indexing_code(self.indices),
op,
@@ -4224,7 +4224,7 @@ class BufferIndexNode(_IndexingBaseNode):
if is_pythran_expr(self.base.type):
res = self.result()
code.putln("__Pyx_call_destructor(%s);" % res)
- code.putln("new (&%s) decltype(%s){%s[%s]};" % (
+ code.putln("new (&%s) decltype(%s){%s%s};" % (
res,
res,
self.base.pythran_result(),
diff --git a/Cython/Compiler/Pythran.py b/Cython/Compiler/Pythran.py
index ae3e646ce..0a5743012 100644
--- a/Cython/Compiler/Pythran.py
+++ b/Cython/Compiler/Pythran.py
@@ -58,45 +58,55 @@ def pythran_unaryop_type(op, type_):
op, pythran_type(type_))
+@cython.ccall
+def _index_access(index_code, indices):
+ indexing = ",".join([index_code(idx) for idx in indices])
+ return ('[%s]' if len(indices) == 1 else '(%s)') % indexing
+
+
+def _index_type_code(idx):
+ if idx.is_slice:
+ if idx.step.is_none:
+ func = "contiguous_slice"
+ n = 2
+ else:
+ func = "slice"
+ n = 3
+ return "pythonic::types::%s(%s)" % (
+ func, ",".join(["0"]*n))
+ elif idx.type.is_int:
+ return "std::declval<%s>()" % idx.type.sign_and_name()
+ elif idx.type.is_pythran_expr:
+ return "std::declval<%s>()" % idx.type.pythran_type
+ raise ValueError("unsupported indexing type %s!" % idx.type)
+
+
+def _index_code(idx):
+ if idx.is_slice:
+ values = idx.start, idx.stop, idx.step
+ if idx.step.is_none:
+ func = "contiguous_slice"
+ values = values[:2]
+ else:
+ func = "slice"
+ return "pythonic::types::%s(%s)" % (
+ func, ",".join((v.pythran_result() for v in values)))
+ elif idx.type.is_int:
+ return to_pythran(idx)
+ elif idx.type.is_pythran_expr:
+ return idx.pythran_result()
+ raise ValueError("unsupported indexing type %s" % idx.type)
+
+
def pythran_indexing_type(type_, indices):
- def index_code(idx):
- if idx.is_slice:
- if idx.step.is_none:
- func = "contiguous_slice"
- n = 2
- else:
- func = "slice"
- n = 3
- return "pythonic::types::%s(%s)" % (
- func, ",".join(["0"]*n))
- elif idx.type.is_int:
- return "std::declval<%s>()" % idx.type.sign_and_name()
- elif idx.type.is_pythran_expr:
- return "std::declval<%s>()" % idx.type.pythran_type
- raise ValueError("unsupported indexing type %s!" % idx.type)
-
- indexing = ",".join(index_code(idx) for idx in indices)
- return type_remove_ref("decltype(std::declval<%s>()[%s])" % (pythran_type(type_), indexing))
+ return type_remove_ref("decltype(std::declval<%s>()%s)" % (
+ pythran_type(type_),
+ _index_access(_index_type_code, indices),
+ ))
def pythran_indexing_code(indices):
- def index_code(idx):
- if idx.is_slice:
- values = idx.start, idx.stop, idx.step
- if idx.step.is_none:
- func = "contiguous_slice"
- values = values[:2]
- else:
- func = "slice"
- return "pythonic::types::%s(%s)" % (
- func, ",".join((v.pythran_result() for v in values)))
- elif idx.type.is_int:
- return to_pythran(idx)
- elif idx.type.is_pythran_expr:
- return idx.pythran_result()
- raise ValueError("unsupported indexing type %s" % idx.type)
-
- return ",".join(index_code(idx) for idx in indices)
+ return _index_access(_index_code, indices)
def pythran_func_type(func, args):