mirror of
https://github.com/janet-lang/janet
synced 2024-11-27 18:49:54 +00:00
Add array/join and tuple/join
Utilities for combining indexed types more efficiently. `array/join` also solves some interface issues with array/concat
This commit is contained in:
parent
ce36c4c0d6
commit
ab70524d85
@ -271,6 +271,7 @@ test_files = [
|
|||||||
'test/suite-struct.janet',
|
'test/suite-struct.janet',
|
||||||
'test/suite-symcache.janet',
|
'test/suite-symcache.janet',
|
||||||
'test/suite-table.janet',
|
'test/suite-table.janet',
|
||||||
|
'test/suite-tuple.janet',
|
||||||
'test/suite-unknown.janet',
|
'test/suite-unknown.janet',
|
||||||
'test/suite-value.janet',
|
'test/suite-value.janet',
|
||||||
'test/suite-vm.janet'
|
'test/suite-vm.janet'
|
||||||
|
@ -275,6 +275,31 @@ JANET_CORE_FN(cfun_array_concat,
|
|||||||
return janet_wrap_array(array);
|
return janet_wrap_array(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JANET_CORE_FN(cfun_array_join,
|
||||||
|
"(array/join arr & parts)",
|
||||||
|
"Join a variable number of arrays and tuples into the first argument, "
|
||||||
|
"which must be an array. "
|
||||||
|
"Return the modified array `arr`.") {
|
||||||
|
int32_t i;
|
||||||
|
janet_arity(argc, 1, -1);
|
||||||
|
JanetArray *array = janet_getarray(argv, 0);
|
||||||
|
for (i = 1; i < argc; i++) {
|
||||||
|
int32_t j, len = 0;
|
||||||
|
const Janet *vals = NULL;
|
||||||
|
if (!janet_indexed_view(argv[i], &vals, &len)) {
|
||||||
|
janet_panicf("expected indexed type for argument %d, got %v", i, argv[i]);
|
||||||
|
}
|
||||||
|
if (array->data == vals) {
|
||||||
|
int32_t newcount = array->count + len;
|
||||||
|
janet_array_ensure(array, newcount, 2);
|
||||||
|
janet_indexed_view(argv[i], &vals, &len);
|
||||||
|
}
|
||||||
|
for (j = 0; j < len; j++)
|
||||||
|
janet_array_push(array, vals[j]);
|
||||||
|
}
|
||||||
|
return janet_wrap_array(array);
|
||||||
|
}
|
||||||
|
|
||||||
JANET_CORE_FN(cfun_array_insert,
|
JANET_CORE_FN(cfun_array_insert,
|
||||||
"(array/insert arr at & xs)",
|
"(array/insert arr at & xs)",
|
||||||
"Insert all `xs` into array `arr` at index `at`. `at` should be an integer between "
|
"Insert all `xs` into array `arr` at index `at`. `at` should be an integer between "
|
||||||
@ -385,6 +410,7 @@ void janet_lib_array(JanetTable *env) {
|
|||||||
JANET_CORE_REG("array/remove", cfun_array_remove),
|
JANET_CORE_REG("array/remove", cfun_array_remove),
|
||||||
JANET_CORE_REG("array/trim", cfun_array_trim),
|
JANET_CORE_REG("array/trim", cfun_array_trim),
|
||||||
JANET_CORE_REG("array/clear", cfun_array_clear),
|
JANET_CORE_REG("array/clear", cfun_array_clear),
|
||||||
|
JANET_CORE_REG("array/join", cfun_array_join),
|
||||||
JANET_REG_END
|
JANET_REG_END
|
||||||
};
|
};
|
||||||
janet_core_cfuns_ext(env, NULL, array_cfuns);
|
janet_core_cfuns_ext(env, NULL, array_cfuns);
|
||||||
|
@ -116,6 +116,34 @@ JANET_CORE_FN(cfun_tuple_setmap,
|
|||||||
return argv[0];
|
return argv[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JANET_CORE_FN(cfun_tuple_join,
|
||||||
|
"(tuple/join & parts)",
|
||||||
|
"Create a tuple by joining together other tuples and arrays.") {
|
||||||
|
janet_arity(argc, 0, -1);
|
||||||
|
int32_t total_len = 0;
|
||||||
|
for (int32_t i = 0; i < argc; i++) {
|
||||||
|
int32_t len = 0;
|
||||||
|
const Janet *vals = NULL;
|
||||||
|
if (!janet_indexed_view(argv[i], &vals, &len)) {
|
||||||
|
janet_panicf("expected indexed type for argument %d, got %v", i, argv[i]);
|
||||||
|
}
|
||||||
|
if (INT32_MAX - total_len < len) {
|
||||||
|
janet_panic("tuple too large");
|
||||||
|
}
|
||||||
|
total_len += len;
|
||||||
|
}
|
||||||
|
Janet *tup = janet_tuple_begin(total_len);
|
||||||
|
Janet *tup_cursor = tup;
|
||||||
|
for (int32_t i = 0; i < argc; i++) {
|
||||||
|
int32_t len = 0;
|
||||||
|
const Janet *vals = NULL;
|
||||||
|
janet_indexed_view(argv[i], &vals, &len);
|
||||||
|
memcpy(tup_cursor, vals, len * sizeof(Janet));
|
||||||
|
tup_cursor += len;
|
||||||
|
}
|
||||||
|
return janet_wrap_tuple(janet_tuple_end(tup));
|
||||||
|
}
|
||||||
|
|
||||||
/* Load the tuple module */
|
/* Load the tuple module */
|
||||||
void janet_lib_tuple(JanetTable *env) {
|
void janet_lib_tuple(JanetTable *env) {
|
||||||
JanetRegExt tuple_cfuns[] = {
|
JanetRegExt tuple_cfuns[] = {
|
||||||
@ -124,6 +152,7 @@ void janet_lib_tuple(JanetTable *env) {
|
|||||||
JANET_CORE_REG("tuple/type", cfun_tuple_type),
|
JANET_CORE_REG("tuple/type", cfun_tuple_type),
|
||||||
JANET_CORE_REG("tuple/sourcemap", cfun_tuple_sourcemap),
|
JANET_CORE_REG("tuple/sourcemap", cfun_tuple_sourcemap),
|
||||||
JANET_CORE_REG("tuple/setmap", cfun_tuple_setmap),
|
JANET_CORE_REG("tuple/setmap", cfun_tuple_setmap),
|
||||||
|
JANET_CORE_REG("tuple/join", cfun_tuple_join),
|
||||||
JANET_REG_END
|
JANET_REG_END
|
||||||
};
|
};
|
||||||
janet_core_cfuns_ext(env, NULL, tuple_cfuns);
|
janet_core_cfuns_ext(env, NULL, tuple_cfuns);
|
||||||
|
@ -76,6 +76,16 @@
|
|||||||
(array/trim a)
|
(array/trim a)
|
||||||
(array/ensure @[1 1] 6 2)
|
(array/ensure @[1 1] 6 2)
|
||||||
|
|
||||||
|
# array/join
|
||||||
|
(assert (deep= @[1 2 3] (array/join @[] [1] [2] [3])) "array/join 1")
|
||||||
|
(assert (deep= @[] (array/join @[])) "array/join 2")
|
||||||
|
(assert (deep= @[1 :a :b :c] (array/join @[1] @[:a :b] [] [:c])) "array/join 3")
|
||||||
|
(assert (deep= @[:x :y :z "abc123" "def456"] (array/join @[:x :y :z] ["abc123" "def456"])) "array/join 4")
|
||||||
|
(assert-error "array/join error 1" (array/join))
|
||||||
|
(assert-error "array/join error 2" (array/join []))
|
||||||
|
(assert-error "array/join error 3" (array/join [] "abc123"))
|
||||||
|
(assert-error "array/join error 4" (array/join @[] "abc123"))
|
||||||
|
(assert-error "array/join error 5" (array/join @[] "abc123"))
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
|
||||||
|
30
test/suite-tuple.janet
Normal file
30
test/suite-tuple.janet
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# Copyright (c) 2023 Calvin Rose
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
# deal in the Software without restriction, including without limitation the
|
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
# IN THE SOFTWARE.
|
||||||
|
|
||||||
|
(import ./helper :prefix "" :exit true)
|
||||||
|
(start-suite)
|
||||||
|
|
||||||
|
(assert (= [1 2 3] (tuple/join [1] [2] [3])) "tuple/join 1")
|
||||||
|
(assert (= [] (tuple/join)) "tuple/join 2")
|
||||||
|
(assert (= [:a :b :c] (tuple/join @[:a :b] [] [:c])) "tuple/join 3")
|
||||||
|
(assert (= ["abc123" "def456"] (tuple/join ["abc123" "def456"])) "tuple/join 4")
|
||||||
|
|
||||||
|
(end-suite)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user