From 582e43d309b30602e579917b0bd148945bb5911a Mon Sep 17 00:00:00 2001 From: Oldes Date: Wed, 13 Jun 2018 21:13:07 +0200 Subject: [PATCH 1/2] FEAT/FIX: Picking the right PICK In Rebol2, picking value with index 0 was always returning null. In R3-alpha it was changed that zero index was working like index -1... more at this blog http://www.rebol.net/cgi-bin/r3blog.r?view=0173 I decided to revert this change and let it working as before (and so be compatible with Red too) So now it works for example like: >> pick tail "123" -1 == #"3" >> pick tail "123" 0 == none and it is also consistent with AT positioning: >> at tail "123" -1 == "3" Related issues: https://github.com/rebol/rebol-issues/issues/608 https://github.com/rebol/rebol-issues/issues/609 https://github.com/rebol/rebol-issues/issues/748 https://github.com/rebol/rebol-issues/issues/857 https://github.com/rebol/rebol-issues/issues/2117 and also: https://github.com/rebol/rebol-issues/issues/613 --- src/core/t-block.c | 7 ++++++- src/core/t-string.c | 10 +++++++--- src/core/t-vector.c | 7 +++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/core/t-block.c b/src/core/t-block.c index 32f90ada93..59daf0ff27 100644 --- a/src/core/t-block.c +++ b/src/core/t-block.c @@ -540,7 +540,10 @@ static struct { */ if (IS_INTEGER(pvs->select)) { - n = Int32(pvs->select) + VAL_INDEX(pvs->value) - 1; + REBINT i = Int32(pvs->select); + if (i == 0) return PE_NONE; // like in case: path/0 + if (i < 0) i++; + n = i + VAL_INDEX(pvs->value) - 1; } else if (IS_WORD(pvs->select)) { n = Find_Word(VAL_SERIES(pvs->value), VAL_INDEX(pvs->value), VAL_WORD_CANON(pvs->select)); @@ -573,6 +576,8 @@ static struct { REBINT n = 0; n = Get_Num_Arg(selector); + if (n == 0) return 0; + if (n < 0) n++; n += VAL_INDEX(block) - 1; if (n < 0 || (REBCNT)n >= VAL_TAIL(block)) return 0; return VAL_BLK_SKIP(block, n); diff --git a/src/core/t-string.c b/src/core/t-string.c index 8358c86f80..d033b10843 100644 --- a/src/core/t-string.c +++ b/src/core/t-string.c @@ -354,7 +354,10 @@ static REBSER *make_binary(REBVAL *arg, REBOOL make) REBSER *ser = VAL_SERIES(data); if (IS_INTEGER(pvs->select)) { - n = Int32(pvs->select) + VAL_INDEX(data) - 1; + i = Int32(pvs->select); + if (i == 0) return PE_NONE; // like in case: path/0 + if (i < 0) i++; + n = i + VAL_INDEX(data) - 1; } else return PE_BAD_SELECT; @@ -542,8 +545,9 @@ static REBSER *make_binary(REBVAL *arg, REBOOL make) case A_PICK: case A_POKE: len = Get_Num_Arg(arg); // Position - //if (len > 0) index--; - if (REB_I32_SUB_OF(len, 1, &len) + if (len < 0) REB_I32_ADD_OF(index, 1, &index); + if (len == 0 + || REB_I32_SUB_OF(len, 1, &len) || REB_I32_ADD_OF(index, len, &index) || index < 0 || index >= tail) { if (action == A_PICK) goto is_none; diff --git a/src/core/t-vector.c b/src/core/t-vector.c index e3c632e9ea..35faf88ce4 100644 --- a/src/core/t-vector.c +++ b/src/core/t-vector.c @@ -468,10 +468,13 @@ void Set_Vector_Row(REBSER *ser, REBVAL *blk) REBINT bits; REBYTE *vp; REBI64 i; - REBDEC f; + REBDEC f = 0.0; - if (IS_INTEGER(pvs->select) || IS_DECIMAL(pvs->select)) + if (IS_INTEGER(pvs->select) || IS_DECIMAL(pvs->select)) { n = Int32(pvs->select); + if (n == 0) return PE_NONE; + if (n < 0) n++; + } else return PE_BAD_SELECT; n += VAL_INDEX(pvs->value); From 6202a850c610bd2596cbb22d1fda21ab9dddbb23 Mon Sep 17 00:00:00 2001 From: Oldes Date: Thu, 14 Jun 2018 11:34:30 +0200 Subject: [PATCH 2/2] FIX: DECIMAL! picking acting as SELECT, though it PICKed in Rebol2 fixes: https://github.com/rebol/rebol-issues/issues/2312 --- src/core/t-block.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/core/t-block.c b/src/core/t-block.c index 59daf0ff27..db62a054d0 100644 --- a/src/core/t-block.c +++ b/src/core/t-block.c @@ -534,12 +534,11 @@ static struct { REBINT n = 0; /* Issues!!! - a/1.3 a/not-found: 10 error or append? a/not-followed: 10 error or append? */ - if (IS_INTEGER(pvs->select)) { + if (IS_INTEGER(pvs->select) || IS_DECIMAL(pvs->select)) { REBINT i = Int32(pvs->select); if (i == 0) return PE_NONE; // like in case: path/0 if (i < 0) i++;