diff --git a/src/boot/boot.janet b/src/boot/boot.janet index 012c3fb4..b198949f 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -1435,7 +1435,7 @@ (defn every? ``Evaluates to the last element of `ind` if all preceding elements are truthy, - otherwise evaluates to the first falsey argument.`` + otherwise evaluates to the first falsey element.`` [ind] (var res true) (loop [x :in ind :while res] @@ -1455,28 +1455,29 @@ `Reverses the order of the elements in a given array or buffer and returns it mutated.` [t] - (def len-1 (- (length t) 1)) - (def half (/ len-1 2)) - (forv i 0 half - (def j (- len-1 i)) - (def l (in t i)) - (def r (in t j)) - (put t i r) - (put t j l)) + (var i 0) + (var j (length t)) + (while (< i (-- j)) + (def ti (in t i)) + (put t i (in t j)) + (put t j ti) + (++ i)) t) (defn reverse `Reverses the order of the elements in a given array or tuple and returns - a new array. If a string or buffer is provided, returns an array of its - byte values, reversed.` + a new array. If a string or buffer is provided, returns a buffer instead.` [t] - (var n (length t)) - (def ret (if (bytes? t) - (buffer/new-filled n) - (array/new-filled n))) - (each v t - (put ret (-- n) v)) - ret) + (if (lengthable? t) + (do + (var n (length t)) + (def ret (if (bytes? t) + (buffer/new-filled n) + (array/new-filled n))) + (each v t + (put ret (-- n) v)) + ret) + (reverse! (seq [v :in t] v)))) (defn invert ``Given an associative data structure `ds`, returns a new table where the @@ -1586,32 +1587,41 @@ (defn keys "Get the keys of an associative data structure." [x] - (def arr @[]) - (var i 0) - (eachk k x - (put arr i k) - (++ i)) - arr) + (if (lengthable? x) + (do + (def arr (array/new-filled (length x))) + (var i 0) + (eachk k x + (put arr i k) + (++ i)) + arr) + (seq [k :keys x] k))) (defn values "Get the values of an associative data structure." [x] - (def arr @[]) - (var i 0) - (each v x - (put arr i v) - (++ i)) - arr) + (if (lengthable? x) + (do + (def arr (array/new-filled (length x))) + (var i 0) + (each v x + (put arr i v) + (++ i)) + arr) + (seq [v :in x] v))) (defn pairs "Get the key-value pairs of an associative data structure." [x] - (def arr @[]) - (var i 0) - (eachp p x - (put arr i p) - (++ i)) - arr) + (if (lengthable? x) + (do + (def arr (array/new-filled (length x))) + (var i 0) + (eachp p x + (put arr i p) + (++ i)) + arr) + (seq [p :pairs x] p))) (defn frequencies "Get the number of occurrences of each value in an indexed data structure." diff --git a/src/core/corelib.c b/src/core/corelib.c index c89787b9..5e46f33e 100644 --- a/src/core/corelib.c +++ b/src/core/corelib.c @@ -680,6 +680,13 @@ JANET_CORE_FN(janet_core_is_dictionary, return janet_wrap_boolean(janet_checktypes(argv[0], JANET_TFLAG_DICTIONARY)); } +JANET_CORE_FN(janet_core_is_lengthable, + "(lengthable? x)", + "Check if x is a bytes, indexed, or dictionary.") { + janet_fixarity(argc, 1); + return janet_wrap_boolean(janet_checktypes(argv[0], JANET_TFLAG_LENGTHABLE)); +} + JANET_CORE_FN(janet_core_signal, "(signal what x)", "Raise a signal with payload x. ") { @@ -1079,6 +1086,7 @@ static void janet_load_libs(JanetTable *env) { JANET_CORE_REG("bytes?", janet_core_is_bytes), JANET_CORE_REG("indexed?", janet_core_is_indexed), JANET_CORE_REG("dictionary?", janet_core_is_dictionary), + JANET_CORE_REG("lengthable?", janet_core_is_lengthable), JANET_CORE_REG("slice", janet_core_slice), JANET_CORE_REG("range", janet_core_range), JANET_CORE_REG("signal", janet_core_signal),