From fb0daad20211a8f5acc9f870c70cf130e011ec19 Mon Sep 17 00:00:00 2001 From: Oldes Date: Wed, 6 Oct 2021 19:02:20 +0200 Subject: [PATCH] FEAT: new `ATz` action returning the seriest at 0-based position (index) CHANGE: `at` action on image with pair position was 0-based, now is 1-based related to: https://github.com/Oldes/Rebol-issues/issues/613 --- src/boot/actions.reb | 6 ++++ src/core/f-series.c | 14 ++------- src/core/t-gob.c | 1 + src/core/t-image.c | 13 ++++---- src/tests/units/gob-test.r3 | 2 ++ src/tests/units/image-test.r3 | 55 +++++++++++++++++++++++++++------- src/tests/units/series-test.r3 | 16 ++++++++++ 7 files changed, 77 insertions(+), 30 deletions(-) diff --git a/src/boot/actions.reb b/src/boot/actions.reb index 29b92125c3..d13d458f0b 100644 --- a/src/boot/actions.reb +++ b/src/boot/actions.reb @@ -170,6 +170,12 @@ at: action [ index [number! logic! pair!] ] +atz: action [ + {Returns the series at the specified 0-based index.} + series [series! gob! port!] + index [number! logic! pair!] +] + index?: action [ {Returns the current position (index) of the series.} series [series! gob! port! none!] diff --git a/src/core/f-series.c b/src/core/f-series.c index 70d16e174c..36353fd345 100644 --- a/src/core/f-series.c +++ b/src/core/f-series.c @@ -80,12 +80,13 @@ case A_SKIP: case A_AT: + case A_ATZ: len = Get_Num_Arg(arg); { REBI64 i = (REBI64)index + (REBI64)len; if (action == A_SKIP) { if (IS_LOGIC(arg)) i--; - } else { // A_AT + } else if (action == A_AT) { if (len > 0) i--; } if (i > (REBI64)tail) i = (REBI64)tail; @@ -93,16 +94,7 @@ VAL_INDEX(value) = (REBCNT)i; } break; -/* - case A_ATZ: - len = Get_Num_Arg(arg); - { - REBI64 idx = Add_Max(0, index, len, MAX_I32); - if (idx < 0) idx = 0; - VAL_INDEX(value) = (REBCNT)idx; - } - break; -*/ + case A_INDEXQ: SET_INTEGER(DS_RETURN, ((REBI64)index) + 1); return R_RET; diff --git a/src/core/t-gob.c b/src/core/t-gob.c index 8fd8d0e4d6..b5ad8fca8c 100644 --- a/src/core/t-gob.c +++ b/src/core/t-gob.c @@ -910,6 +910,7 @@ const REBCNT Gob_Flag_Words[] = { case A_AT: index--; case A_SKIP: + case A_ATZ: index += VAL_INT32(arg); goto set_index; diff --git a/src/core/t-image.c b/src/core/t-image.c index 76ad1fe3fa..faebe80516 100644 --- a/src/core/t-image.c +++ b/src/core/t-image.c @@ -1070,21 +1070,18 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i) Pick_Path(value, arg, D_ARG(3)); return R_ARG3; - case A_SKIP: - case A_AT: - // This logic is somewhat complicated by the fact that INTEGER args use - // base-1 indexing, but PAIR args use base-0. + case A_AT: // base-1 + case A_ATZ: // base-0 + case A_SKIP: // base-0 if (IS_PAIR(arg)) { - if (action == A_AT) action = A_SKIP; - diff = (VAL_PAIR_Y_INT(arg) * VAL_IMAGE_WIDE(value) + VAL_PAIR_X_INT(arg)) + - ((action == A_SKIP) ? 0 : 1); + diff = ((VAL_PAIR_Y_INT(arg) - ((action == A_AT) ? 1 : 0)) * VAL_IMAGE_WIDE(value) + VAL_PAIR_X_INT(arg)); } else diff = Get_Num_Arg(arg); index += diff; if (action == A_SKIP) { if (IS_LOGIC(arg)) index--; - } else { + } else if (action == A_AT) { if (diff > 0) index--; // For at, pick, poke. } diff --git a/src/tests/units/gob-test.r3 b/src/tests/units/gob-test.r3 index 8b3c03e87a..7bc4fdaca1 100644 --- a/src/tests/units/gob-test.r3 +++ b/src/tests/units/gob-test.r3 @@ -17,11 +17,13 @@ Rebol [ --assert 1 = index? back g --assert 2 = index? next g --assert 3 = index? tail g + --assert 2 = index? at g 2 --test-- "indexz? gob!" --assert 0 = indexz? g --assert 0 = indexz? back g --assert 1 = indexz? next g --assert 2 = indexz? tail g + --assert 1 = indexz? atz g 1 ===end-group=== ===start-group=== "gob issues" diff --git a/src/tests/units/image-test.r3 b/src/tests/units/image-test.r3 index 8921f9a0ea..dcc80cad20 100644 --- a/src/tests/units/image-test.r3 +++ b/src/tests/units/image-test.r3 @@ -69,22 +69,55 @@ Rebol [ ===end-group=== -===start-group=== "INDEX? / INDEXZ?" +===start-group=== "INDEX? / INDEXZ? / AT / ATZ" img: make image! 2x2 --test-- "index? image!" - --assert 1 = index? img - --assert 2 = index? next img - --assert 5 = index? tail img + --assert 1 = index? img + --assert 2 = index? next img + --assert 5 = index? tail img + --assert 4 = index? skip tail img -1 + --test-- "index? at image!" + --assert 1 = index? at img -1 + --assert 1 = index? at img 0 + --assert 1 = index? at img 1 + --assert 2 = index? at img 2 + --assert 5 = index? at img 6 + --assert 1 = index? skip at img 2 -1 + --test-- "index?/xy image!" --assert 1x1 = index?/xy img --assert 2x1 = index?/xy next img --assert 1x3 = index?/xy tail img + --assert 2x2 = index?/xy skip tail img -1 + --test-- "index?/xy at image!" + --assert 1x1 = index?/xy at img 1x1 + --assert 1x2 = index?/xy at img 1x2 + --assert 2x2 = index?/xy at img 2x2 + --assert 1x3 = index?/xy at img 20x2 + --assert 1x2 = index?/xy skip at img 2x2 -1x0 --test-- "indexz? image!" - --assert 0 = indexz? img - --assert 1 = indexz? next img - --assert 4 = indexz? tail img + --assert 0 = indexz? img + --assert 1 = indexz? next img + --assert 4 = indexz? tail img + --assert 3 = indexz? skip tail img -1 + --test-- "indexz? atz image!" + --assert 0 = indexz? atz img -1 + --assert 0 = indexz? atz img 0 + --assert 2 = indexz? atz img 2 + --assert 4 = indexz? atz img 6 + --assert 3 = indexz? skip atz img 6 -1 + --assert 1 = indexz? skip atz img 2 -1 + --test-- "indexz?/xy image!" --assert 0x0 = indexz?/xy img --assert 1x0 = indexz?/xy next img --assert 0x2 = indexz?/xy tail img + --assert 1x1 = indexz?/xy skip tail img -1x0 + --test-- "indexz?/xy atz image!" + --assert 0x0 = indexz?/xy atz img 0x0 + --assert 0x1 = indexz?/xy atz img 0x1 + --assert 1x1 = indexz?/xy atz img 1x1 + --assert 0x2 = indexz?/xy atz img 2x2 + --assert 0x2 = indexz?/xy atz img 20x2 + --assert 0x1 = indexz?/xy skip atz img 1x1 -1x0 ===end-group=== ===start-group=== "FOREACH" @@ -250,26 +283,26 @@ Rebol [ 000000000000FFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFF} - change at img 1x1 make image! [2x2 220.22.22] + change at img 2x2 make image! [2x2 220.22.22] --assert img/rgb = #{ 000000000000FFFFFFFFFFFF 000000DC1616DC1616FFFFFF FFFFFFDC1616DC1616FFFFFF FFFFFFFFFFFFFFFFFFFFFFFF} - change at img 2x2 make image! [3x3 33.33.33] + change at img 3x3 make image! [3x3 33.33.33] --assert img/rgb = #{ 000000000000FFFFFFFFFFFF 000000DC1616DC1616FFFFFF FFFFFFDC1616212121212121 FFFFFFFFFFFF212121212121} - change at img 0x3 make image! [4x4 66.166.66] + change at img 1x4 make image! [4x4 66.166.66] --assert img/rgb = #{ 000000000000FFFFFFFFFFFF 000000DC1616DC1616FFFFFF FFFFFFDC1616212121212121 42A64242A64242A64242A642} - change at img 3x0 make image! [2x1 #{AAAAAABBBBBB}] + change at img 4x1 make image! [2x1 #{AAAAAABBBBBB}] --assert img/rgb = #{ 000000000000FFFFFFAAAAAA 000000DC1616DC1616FFFFFF diff --git a/src/tests/units/series-test.r3 b/src/tests/units/series-test.r3 index 138636fe2a..b8a57e371c 100644 --- a/src/tests/units/series-test.r3 +++ b/src/tests/units/series-test.r3 @@ -627,6 +627,10 @@ Rebol [ 0 = indexz? s 1 = indexz? next s 3 = indexz? tail s + 0 = indexz? atz s -1 + 0 = indexz? atz s 0 + 2 = indexz? atz s 2 + 3 = indexz? atz s 6 ] --test-- "indexz? on binary" s: to binary! "abc" @@ -634,6 +638,10 @@ Rebol [ 0 = indexz? s 1 = indexz? next s 3 = indexz? tail s + 0 = indexz? atz s -1 + 0 = indexz? atz s 0 + 2 = indexz? atz s 2 + 3 = indexz? atz s 6 ] --test-- "indexz? on block" s: [1 2 3] @@ -641,6 +649,10 @@ Rebol [ 0 = indexz? s 1 = indexz? next s 3 = indexz? tail s + 0 = indexz? atz s -1 + 0 = indexz? atz s 0 + 2 = indexz? atz s 2 + 3 = indexz? atz s 6 ] --test-- "indexz? on vector" s: #[u16! 3] @@ -648,6 +660,10 @@ Rebol [ 0 = indexz? s 1 = indexz? next s 3 = indexz? tail s + 0 = indexz? atz s -1 + 0 = indexz? atz s 0 + 2 = indexz? atz s 2 + 3 = indexz? atz s 6 ] ===end-group===