mirror of
https://github.com/janet-lang/janet
synced 2024-11-19 15:14:48 +00:00
add int/to-number: converts s64 and u64 to numbers
(int/to-number value) converts an s64 or u64 to a number. It restricts the value to the int32 range, so that `int32?` will always suceeded when called on the result.
This commit is contained in:
parent
6f645c4cb7
commit
88db9751d7
@ -207,6 +207,38 @@ JANET_CORE_FN(cfun_it_u64_new,
|
||||
return janet_wrap_u64(janet_unwrap_u64(argv[0]));
|
||||
}
|
||||
|
||||
JANET_CORE_FN(cfun_to_number,
|
||||
"(int/to-number value)",
|
||||
"Convert an int/u64 or int/s64 to a number. Fails if the number is out of range for an int32.") {
|
||||
janet_fixarity(argc, 1);
|
||||
if (janet_type(argv[0]) == JANET_ABSTRACT) {
|
||||
void* abst = janet_unwrap_abstract(argv[0]);
|
||||
|
||||
if (janet_abstract_type(abst) == &janet_s64_type) {
|
||||
int64_t value = *((int64_t*)abst);
|
||||
if (value > INT32_MAX) {
|
||||
janet_panicf("cannot convert %q to a number, exceededs int32 max", argv[0]);
|
||||
}
|
||||
if (value < INT32_MIN) {
|
||||
janet_panicf("cannot convert %q to a number, exceededs int32 min", argv[0]);
|
||||
}
|
||||
|
||||
return janet_wrap_integer(value);
|
||||
}
|
||||
|
||||
if (janet_abstract_type(abst) == &janet_u64_type) {
|
||||
uint64_t value = *((uint64_t*)abst);
|
||||
if (value > INT32_MAX) {
|
||||
janet_panicf("cannot convert %q to a number, exceededs int32 max", argv[0]);
|
||||
}
|
||||
|
||||
return janet_wrap_integer(value);
|
||||
}
|
||||
}
|
||||
|
||||
janet_panicf("expected int/u64 or int/s64, got %q", argv[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Code to support polymorphic comparison.
|
||||
* int/u64 and int/s64 support a "compare" method that allows
|
||||
@ -514,6 +546,7 @@ void janet_lib_inttypes(JanetTable *env) {
|
||||
JanetRegExt it_cfuns[] = {
|
||||
JANET_CORE_REG("int/s64", cfun_it_s64_new),
|
||||
JANET_CORE_REG("int/u64", cfun_it_u64_new),
|
||||
JANET_CORE_REG("int/to-number", cfun_to_number),
|
||||
JANET_REG_END
|
||||
};
|
||||
janet_core_cfuns_ext(env, NULL, it_cfuns);
|
||||
|
@ -39,6 +39,20 @@
|
||||
(def c (u64 "32rvv_vv_vv_vv"))
|
||||
(def d (u64 "123456789"))))
|
||||
|
||||
# Conversion back to an int32
|
||||
(assert (= (int/to-number (u64 0xFaFa)) 0xFaFa))
|
||||
(assert (= (int/to-number (i64 0xFaFa)) 0xFaFa))
|
||||
|
||||
(assert-error
|
||||
"int64 out of bounds for int32"
|
||||
(do
|
||||
(int/to-number (u64 "0x7fff_ffff_ffff_ffff"))
|
||||
(int/to-number (i64 "-0x7fff_ffff_ffff_ffff"))))
|
||||
|
||||
(assert-error
|
||||
"int/to-number fails on non-abstract types"
|
||||
(int/to-number 1))
|
||||
|
||||
(assert-no-error
|
||||
"create some int64 bigints"
|
||||
(do
|
||||
|
Loading…
Reference in New Issue
Block a user