diff options
author | Stefan Behnel <stefan_ml@behnel.de> | 2017-10-24 21:01:34 +0200 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2017-10-24 21:03:40 +0200 |
commit | 150c4283b05ed67c9620606bc298ba34b0f70fbb (patch) | |
tree | 45295e3ab96a4f4b7fc7ed102a511e5235f21b2e | |
parent | 41b4a28d7c7c505d58502c9cf69bde2e33091de0 (diff) | |
download | cython-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.py | 4 | ||||
-rw-r--r-- | Cython/Compiler/Pythran.py | 80 |
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): |