From 61712bae9c96450987d2c02f12251b50cac0285d Mon Sep 17 00:00:00 2001 From: primo-ppcg Date: Tue, 1 Aug 2023 23:00:54 +0700 Subject: [PATCH 1/3] speed up range creation --- src/boot/boot.janet | 24 ------------------------ src/core/corelib.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/boot/boot.janet b/src/boot/boot.janet index 93be8b88..46432619 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -1007,30 +1007,6 @@ (map-template :keep res pred ind inds) res) -(defn range - `Create an array of values [start, end) with a given step. - With one argument, returns a range [0, end). With two arguments, returns - a range [start, end). With three, returns a range with optional step size.` - [& args] - (case (length args) - 1 (do - (def [n] args) - (def arr (array/new n)) - (forv i 0 n (put arr i i)) - arr) - 2 (do - (def [n m] args) - (def arr (array/new (- m n))) - (forv i n m (put arr (- i n) i)) - arr) - 3 (do - (def [n m s] args) - (cond - (zero? s) @[] - (neg? s) (seq [i :down [n m (- s)]] i) - (seq [i :range [n m s]] i))) - (error "expected 1 to 3 arguments to range"))) - (defn find-index ``Find the index of indexed type for which `pred` is true. Returns `dflt` if not found.`` [pred ind &opt dflt] diff --git a/src/core/corelib.c b/src/core/corelib.c index 56b1d41e..bfcfa181 100644 --- a/src/core/corelib.c +++ b/src/core/corelib.c @@ -426,6 +426,39 @@ JANET_CORE_FN(janet_core_slice, } } +JANET_CORE_FN(janet_core_range, + "(range & args)", + "Create an array of values [start, end) with a given step. " + "With one argument, returns a range [0, end). With two arguments, returns " + "a range [start, end). With three, returns a range with optional step size.") { + janet_arity(argc, 1, 3); + int32_t start = 0, stop = 0, step = 1, count = 0; + switch (argc) { + case 1: + stop = janet_getinteger(argv, 0); + count = stop; + break; + case 2: + start = janet_getinteger(argv, 0); + stop = janet_getinteger(argv, 1); + count = stop - start; + break; + case 3: + start = janet_getinteger(argv, 0); + stop = janet_getinteger(argv, 1); + step = janet_getinteger(argv, 2); + count = (step > 0) ? (stop - start - 1) / step + 1 : + ((step < 0) ? (stop - start + 1) / step + 1 : 0); + break; + } + JanetArray *array = janet_array(count); + for (int32_t i = 0; i < count; i++) { + array->data[i] = janet_wrap_number(start + i * step); + } + array->count = count; + return janet_wrap_array(array); +} + JANET_CORE_FN(janet_core_table, "(table & kvs)", "Creates a new table from a variadic number of keys and values. " @@ -1024,6 +1057,7 @@ static void janet_load_libs(JanetTable *env) { JANET_CORE_REG("int?", janet_core_check_int), JANET_CORE_REG("nat?", janet_core_check_nat), JANET_CORE_REG("slice", janet_core_slice), + JANET_CORE_REG("range", janet_core_range), JANET_CORE_REG("signal", janet_core_signal), JANET_CORE_REG("memcmp", janet_core_memcmp), JANET_CORE_REG("getproto", janet_core_getproto), From d8b45ecd6104a82ba1b54b0ed3f17f5d14d6156a Mon Sep 17 00:00:00 2001 From: primo-ppcg Date: Thu, 3 Aug 2023 20:39:32 +0700 Subject: [PATCH 2/3] better test coverage --- test/suite-boot.janet | 7 ------- test/suite-corelib.janet | 12 ++++++++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/test/suite-boot.janet b/test/suite-boot.janet index dca18bb9..c907731a 100644 --- a/test/suite-boot.janet +++ b/test/suite-boot.janet @@ -362,14 +362,7 @@ (assert (= false (and false false)) "and 1") (assert (= false (or false false)) "or 1") -# Range -# a982f351d -(assert (deep= (range 10) @[0 1 2 3 4 5 6 7 8 9]) "range 1 argument") -(assert (deep= (range 5 10) @[5 6 7 8 9]) "range 2 arguments") -(assert (deep= (range 5 10 2) @[5 7 9]) "range 3 arguments") # 11cd1279d -(assert (= (length (range 10)) 10) "(range 10)") -(assert (= (length (range 1 10)) 9) "(range 1 10)") (assert (deep= @{:a 1 :b 2 :c 3} (zipcoll '[:a :b :c] '[1 2 3])) "zipcoll") # bc8be266f diff --git a/test/suite-corelib.janet b/test/suite-corelib.janet index 213a33f4..ea03b548 100644 --- a/test/suite-corelib.janet +++ b/test/suite-corelib.janet @@ -159,5 +159,17 @@ (assert-error "invalid offset-a: 1" (memcmp "a" "b" 1 1 0)) (assert-error "invalid offset-b: 1" (memcmp "a" "b" 1 0 1)) +# Range +# a982f351d +(assert (deep= (range 10) @[0 1 2 3 4 5 6 7 8 9]) "(range 10)") +(assert (deep= (range 5 10) @[5 6 7 8 9]) "(range 5 10)") +(assert (deep= (range 0 16 4) @[0 4 8 12]) "(range 0 16 4)") +(assert (deep= (range 0 17 4) @[0 4 8 12 16]) "(range 0 17 4)") +(assert (deep= (range 16 0 -4) @[16 12 8 4]) "(range 16 0 -4)") +(assert (deep= (range 17 0 -4) @[17 13 9 5 1]) "(range 17 0 -4)") + +(assert (= (length (range 10)) 10) "(range 10)") +(assert (= (length (range 1 10)) 9) "(range 1 10)") + (end-suite) From 8a70fb95b54982a181b68fde8a4457b5c9e64e55 Mon Sep 17 00:00:00 2001 From: primo-ppcg Date: Thu, 3 Aug 2023 21:48:59 +0700 Subject: [PATCH 3/3] slight refactoring --- src/core/corelib.c | 31 ++++++++++++++----------------- test/suite-corelib.janet | 1 + 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/core/corelib.c b/src/core/corelib.c index bfcfa181..0241f7d1 100644 --- a/src/core/corelib.c +++ b/src/core/corelib.c @@ -433,24 +433,21 @@ JANET_CORE_FN(janet_core_range, "a range [start, end). With three, returns a range with optional step size.") { janet_arity(argc, 1, 3); int32_t start = 0, stop = 0, step = 1, count = 0; - switch (argc) { - case 1: - stop = janet_getinteger(argv, 0); - count = stop; - break; - case 2: - start = janet_getinteger(argv, 0); - stop = janet_getinteger(argv, 1); - count = stop - start; - break; - case 3: - start = janet_getinteger(argv, 0); - stop = janet_getinteger(argv, 1); - step = janet_getinteger(argv, 2); - count = (step > 0) ? (stop - start - 1) / step + 1 : - ((step < 0) ? (stop - start + 1) / step + 1 : 0); - break; + if (argc == 3) { + start = janet_getinteger(argv, 0); + stop = janet_getinteger(argv, 1); + step = janet_getinteger(argv, 2); + count = (step > 0) ? (stop - start - 1) / step + 1 : + ((step < 0) ? (stop - start + 1) / step + 1 : 0); + } else if (argc == 2) { + start = janet_getinteger(argv, 0); + stop = janet_getinteger(argv, 1); + count = stop - start; + } else { + stop = janet_getinteger(argv, 0); + count = stop; } + count = (count > 0) ? count : 0; JanetArray *array = janet_array(count); for (int32_t i = 0; i < count; i++) { array->data[i] = janet_wrap_number(start + i * step); diff --git a/test/suite-corelib.janet b/test/suite-corelib.janet index ea03b548..5107c555 100644 --- a/test/suite-corelib.janet +++ b/test/suite-corelib.janet @@ -169,6 +169,7 @@ (assert (deep= (range 17 0 -4) @[17 13 9 5 1]) "(range 17 0 -4)") (assert (= (length (range 10)) 10) "(range 10)") +(assert (= (length (range -10)) 0) "(range -10)") (assert (= (length (range 1 10)) 9) "(range 1 10)") (end-suite)