From ac5df53c6cb36397215240fb82903305e1749a73 Mon Sep 17 00:00:00 2001 From: Oldes Huhuman Date: Thu, 4 Jul 2024 08:49:41 +0200 Subject: [PATCH] FEAT: implemented `take/all`, which copies all content and clears the series --- src/boot/actions.reb | 5 +++-- src/core/t-block.c | 7 +++++-- src/core/t-string.c | 14 +++++++++----- src/tests/units/series-test.r3 | 25 ++++++++++++++++++++++++- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/boot/actions.reb b/src/boot/actions.reb index 6158155a82..0517ed8028 100644 --- a/src/boot/actions.reb +++ b/src/boot/actions.reb @@ -275,11 +275,12 @@ copy: action [ take: action [ {Removes and returns one or more elements.} - series [series! port! gob! none!] {At position (modified)} + series [series! port! gob! none!] {At the current position (modified)} /part {Specifies a length or end position} range [number! series! pair!] /deep {Also copies series values within the block} - /last {Take it from the tail end} + /last {Takes from the tail end} + /all {Copies the complete content of the series and then clears it} ] put: action [ diff --git a/src/core/t-block.c b/src/core/t-block.c index 3739339855..6a82b29852 100644 --- a/src/core/t-block.c +++ b/src/core/t-block.c @@ -760,8 +760,11 @@ static struct { */ case A_TAKE: - // take/part: - if (D_REF(ARG_TAKE_PART)) { + if (D_REF(ARG_TAKE_ALL)) { + len = tail > index ? tail - index : 0; + SET_TRUE(D_ARG(ARG_TAKE_PART)); + } + else if (D_REF(ARG_TAKE_PART)) { len = Partial1(value, D_ARG(ARG_TAKE_RANGE)); if (len == 0) { zero_blk: diff --git a/src/core/t-string.c b/src/core/t-string.c index 6e98c86e77..96fe65ad77 100644 --- a/src/core/t-string.c +++ b/src/core/t-string.c @@ -713,8 +713,12 @@ static struct { break; case A_TAKE: - if (D_REF(2)) { - len = Partial(value, 0, D_ARG(3), 0); + if (D_REF(ARG_TAKE_ALL)) { + len = tail > index ? tail - index : 0; + SET_TRUE(D_ARG(ARG_TAKE_PART)); + } + else if (D_REF(ARG_TAKE_PART)) { + len = Partial(value, 0, D_ARG(ARG_TAKE_RANGE), 0); if (len == 0) { zero_str: Set_Series(VAL_TYPE(value), D_RET, Make_Binary(0)); @@ -727,15 +731,15 @@ static struct { // take/last: if (tail <= index) goto is_none; - if (D_REF(5)) index = tail - len; + if (D_REF(ARG_TAKE_LAST)) index = tail - len; if (index < 0 || index >= tail) { - if (!D_REF(2)) goto is_none; + if (!D_REF(ARG_TAKE_PART)) goto is_none; goto zero_str; } ser = VAL_SERIES(value); // if no /part, just return value, else return string: - if (!D_REF(2)) { + if (!D_REF(ARG_TAKE_PART)) { if (IS_BINARY(value)) { SET_INTEGER(value, *VAL_BIN_SKIP(value, index)); } else diff --git a/src/tests/units/series-test.r3 b/src/tests/units/series-test.r3 index 7f33bc530d..3a1499796e 100644 --- a/src/tests/units/series-test.r3 +++ b/src/tests/units/series-test.r3 @@ -971,7 +971,6 @@ Rebol [ --assert [4] = take/part s 3 --assert [] = take/part s 1 - --test-- "take binary!" ;@@ https://github.com/Oldes/Rebol-issues/issues/963 --assert 32 = take #{20} @@ -983,6 +982,24 @@ Rebol [ --assert #{0304} = take/part skip s 2 -5 ;@@ https://github.com/Oldes/Rebol-issues/issues/373 --assert #{0506} = take/part s 10 + --test-- "take/all binary!" + s: #{010203040506} + --assert all [#{010203040506} == take/all s empty? s] + s: skip #{010203040506} 3 + --assert all [#{040506} == take/all s #{010203} == head s] + + --test-- "take/all block!" + s: [1 2 3 4 5 6] + --assert all [[1 2 3 4 5 6] == take/all s empty? s] + s: skip [1 2 3 4 5 6] 3 + --assert all [[4 5 6] == take/all s [1 2 3] == head s] + + --test-- "take/all string!" + s: "123456" + --assert all ["123456" == take/all s empty? s] + s: skip "123456" 3 + --assert all ["456" == take/all s "123" == head s] + ===end-group=== @@ -2724,8 +2741,14 @@ Rebol [ ===start-group=== "TO-*" --test-- "to-path" + --assert (form to-path [1 2 3]) = "1/2/3" + --assert (form to-path [1 none 3]) = "1/none/3" --assert (mold to-path [1 2 3]) = "1/2/3" --assert (mold to-path [1 none 3]) = "1/none/3" + --assert (mold/all to-path [1 2 3]) = "#(path! [1 2 3])" + --assert (mold/all to-path [1 none 3]) = "#(path! [1 none 3])" + --assert (mold/all to-path [a 2 3]) = "a/2/3" + --assert (mold/all to-path [a none 3]) = "#(path! [a none 3])" ;@@ https://github.com/Oldes/Rebol-issues/issues/477 --assert path? p: try [to-path b: [1 #(none) #(true) [] () #{}]] --assert integer? p/1