From 0459130b8389b28a250b43f453d213bf13997023 Mon Sep 17 00:00:00 2001 From: Wolf Vollprecht Date: Mon, 29 Jun 2015 09:22:48 +0200 Subject: [PATCH] Added correct indexing for negative steps and check for 0-index --- mathics/builtin/lists.py | 47 ++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/mathics/builtin/lists.py b/mathics/builtin/lists.py index c872853db8..8984b8d18b 100644 --- a/mathics/builtin/lists.py +++ b/mathics/builtin/lists.py @@ -276,10 +276,18 @@ def replace_item(all, item, new): return False if len(index.leaves) > 2: step = index.leaves[2].get_int_value() + + if start == 0 or stop == 0: + # index 0 is undefined + evaluation.message('Part', 'span', 0) + return False + if start is None or step is None: evaluation.message('Part', 'span', index) return False - start, stop = python_seq(start, stop) + + start, stop = python_seq(start, stop, step) + for inner in inner_list: if inner.is_atom(): evaluation.message('Part', 'partd') @@ -533,14 +541,31 @@ def test(self, ls): return False -def python_seq(start, stop): - if start > 0: - start -= 1 - if stop is not None and stop < 0: - stop += 1 - if stop == 0: +def python_seq(start, stop, step=+1): + if not step: step = +1 + if step == +1: + if start > 0: + start -= 1 + if stop is not None and stop < 0: + stop += 1 + if stop == 0: + stop = None + return start, stop + else: + if stop and stop > 0: + stop -= 2 + elif stop and stop < 0: + stop -= 1 + if start and start > 0: + start -= 1 + if not start: + start = None + if stop == -1: stop = None - return start, stop + elif stop == None: + # No stop equals len(list)! + stop = -1 + return start, stop def convert_seq(seq): @@ -972,7 +997,7 @@ def apply(self, list, seqs, evaluation): evaluation.message('Take', 'seqs', seq) return start, stop, step = seq_tuple - py_start, py_stop = python_seq(start, stop) + py_start, py_stop = python_seq(start, stop, step) for inner in inner_list: if (inner.is_atom() or # noqa abs(start) > len(inner.leaves) or @@ -1023,7 +1048,7 @@ def apply(self, list, seqs, evaluation): evaluation.message('Drop', 'seqs', seq) return start, stop, step = seq_tuple - py_start, py_stop = python_seq(start, stop) + py_start, py_stop = python_seq(start, stop, step) for inner in inner_list: if (inner.is_atom() or # noqa abs(start) > len(inner.leaves) or @@ -2011,4 +2036,4 @@ def get_call(): *self.complement(all.leaves, others_leaves, evaluation, same_test)) result.sort() - return result + return result \ No newline at end of file