1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-25 01:37:19 +00:00

Update module and rem operator for int types.

This commit is contained in:
Calvin Rose 2021-01-09 14:45:58 -06:00
parent 5b05da65f0
commit 11067d7a56
4 changed files with 55 additions and 29 deletions

View File

@ -85,8 +85,6 @@
# Basic predicates # Basic predicates
(defn nan? "Check if x is NaN" [x] (not= x x)) (defn nan? "Check if x is NaN" [x] (not= x x))
(defn even? "Check if x is even." [x] (= 0 (mod x 2)))
(defn odd? "Check if x is odd." [x] (= 1 (mod x 2)))
(defn number? "Check if x is a number." [x] (= (type x) :number)) (defn number? "Check if x is a number." [x] (= (type x) :number))
(defn fiber? "Check if x is a fiber." [x] (= (type x) :fiber)) (defn fiber? "Check if x is a fiber." [x] (= (type x) :fiber))
(defn string? "Check if x is a string." [x] (= (type x) :string)) (defn string? "Check if x is a string." [x] (= (type x) :string))
@ -116,6 +114,9 @@
(defn nil? "Check if x is nil." [x] (= x nil)) (defn nil? "Check if x is nil." [x] (= x nil))
(defn empty? "Check if xs is empty." [xs] (= (length xs) 0)) (defn empty? "Check if xs is empty." [xs] (= (length xs) 0))
# For macros, we define an imcomplete odd? function that will be overriden.
(defn odd? [x] (= 1 (mod x 2)))
(def idempotent? (def idempotent?
``` ```
(idempotent? x) (idempotent? x)
@ -753,6 +754,8 @@
(defn pos? "Check if x is greater than 0." [x] (= (compare x 0) 1)) (defn pos? "Check if x is greater than 0." [x] (= (compare x 0) 1))
(defn neg? "Check if x is less than 0." [x] (= (compare x 0) -1)) (defn neg? "Check if x is less than 0." [x] (= (compare x 0) -1))
(defn one? "Check if x is equal to 1." [x] (= (compare x 1) 0)) (defn one? "Check if x is equal to 1." [x] (= (compare x 1) 0))
(defn even? "Check if x is even." [x] (= 0 (compare 0 (mod x 2))))
(defn odd? "Check if x is odd." [x] (= 0 (compare 1 (mod x 2))))
(undef compare-reduce) (undef compare-reduce)

View File

@ -383,31 +383,14 @@ static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
} \ } \
static Janet cfun_it_s64_mod(int32_t argc, Janet *argv) { static Janet cfun_it_s64_mod(int32_t argc, Janet *argv) {
janet_arity(argc, 2, -1);
int64_t *box = janet_abstract(&janet_s64_type, sizeof(int64_t));
*box = janet_unwrap_s64(argv[0]);
for (int32_t i = 1; i < argc; i++) {
int64_t value = janet_unwrap_s64(argv[i]);
if (value == 0) janet_panic("division by zero");
int64_t x = *box % value;
if (x < 0) {
x = (*box < 0) ? x - *box : x + *box;
}
*box = x;
}
return janet_wrap_abstract(box);
}
static Janet cfun_it_s64_modi(int32_t argc, Janet *argv) {
janet_fixarity(argc, 2); janet_fixarity(argc, 2);
int64_t *box = janet_abstract(&janet_s64_type, sizeof(int64_t)); int64_t *box = janet_abstract(&janet_s64_type, sizeof(int64_t));
int64_t op1 = janet_unwrap_s64(argv[0]); int64_t op1 = janet_unwrap_s64(argv[0]);
int64_t op2 = janet_unwrap_s64(argv[1]); int64_t op2 = janet_unwrap_s64(argv[1]);
int64_t x = op1 % op2; int64_t x = op1 % op2;
if (x < 0) { *box = (op1 > 0)
x = (op1 < 0) ? x - op1 : x + op1; ? ((op2 > 0) ? x : (0 == x ? x : x + op2))
} : ((op2 > 0) ? (0 == x ? x : x + op2) : x);
*box = x;
return janet_wrap_abstract(box); return janet_wrap_abstract(box);
} }
@ -418,7 +401,6 @@ OPMETHOD(int64_t, s64, mul, *)
DIVMETHOD_SIGNED(int64_t, s64, div, /) DIVMETHOD_SIGNED(int64_t, s64, div, /)
DIVMETHOD_SIGNED(int64_t, s64, rem, %) DIVMETHOD_SIGNED(int64_t, s64, rem, %)
DIVMETHODINVERT_SIGNED(int64_t, s64, divi, /) DIVMETHODINVERT_SIGNED(int64_t, s64, divi, /)
DIVMETHODINVERT_SIGNED(int64_t, s64, remi, %)
OPMETHOD(int64_t, s64, and, &) OPMETHOD(int64_t, s64, and, &)
OPMETHOD(int64_t, s64, or, |) OPMETHOD(int64_t, s64, or, |)
OPMETHOD(int64_t, s64, xor, ^) OPMETHOD(int64_t, s64, xor, ^)
@ -431,7 +413,6 @@ OPMETHOD(uint64_t, u64, mul, *)
DIVMETHOD(uint64_t, u64, div, /) DIVMETHOD(uint64_t, u64, div, /)
DIVMETHOD(uint64_t, u64, mod, %) DIVMETHOD(uint64_t, u64, mod, %)
DIVMETHODINVERT(uint64_t, u64, divi, /) DIVMETHODINVERT(uint64_t, u64, divi, /)
DIVMETHODINVERT(uint64_t, u64, modi, %)
OPMETHOD(uint64_t, u64, and, &) OPMETHOD(uint64_t, u64, and, &)
OPMETHOD(uint64_t, u64, or, |) OPMETHOD(uint64_t, u64, or, |)
OPMETHOD(uint64_t, u64, xor, ^) OPMETHOD(uint64_t, u64, xor, ^)
@ -454,9 +435,9 @@ static JanetMethod it_s64_methods[] = {
{"/", cfun_it_s64_div}, {"/", cfun_it_s64_div},
{"r/", cfun_it_s64_divi}, {"r/", cfun_it_s64_divi},
{"mod", cfun_it_s64_mod}, {"mod", cfun_it_s64_mod},
{"rmod", cfun_it_s64_modi}, {"rmod", cfun_it_s64_mod},
{"%", cfun_it_s64_rem}, {"%", cfun_it_s64_rem},
{"r%", cfun_it_s64_remi}, {"r%", cfun_it_s64_rem},
{"&", cfun_it_s64_and}, {"&", cfun_it_s64_and},
{"r&", cfun_it_s64_and}, {"r&", cfun_it_s64_and},
{"|", cfun_it_s64_or}, {"|", cfun_it_s64_or},
@ -480,9 +461,9 @@ static JanetMethod it_u64_methods[] = {
{"/", cfun_it_u64_div}, {"/", cfun_it_u64_div},
{"r/", cfun_it_u64_divi}, {"r/", cfun_it_u64_divi},
{"mod", cfun_it_u64_mod}, {"mod", cfun_it_u64_mod},
{"rmod", cfun_it_u64_modi}, {"rmod", cfun_it_u64_mod},
{"%", cfun_it_u64_mod}, {"%", cfun_it_u64_mod},
{"r%", cfun_it_u64_modi}, {"r%", cfun_it_u64_mod},
{"&", cfun_it_u64_and}, {"&", cfun_it_u64_and},
{"r&", cfun_it_u64_and}, {"r&", cfun_it_u64_and},
{"|", cfun_it_u64_or}, {"|", cfun_it_u64_or},

View File

@ -42,7 +42,14 @@ static void number_to_string_b(JanetBuffer *buffer, double x) {
const char *fmt = (x == floor(x) && const char *fmt = (x == floor(x) &&
x <= JANET_INTMAX_DOUBLE && x <= JANET_INTMAX_DOUBLE &&
x >= JANET_INTMIN_DOUBLE) ? "%.0f" : "%g"; x >= JANET_INTMIN_DOUBLE) ? "%.0f" : "%g";
int count = snprintf((char *) buffer->data + buffer->count, BUFSIZE, fmt, x); int count;
if (x == 0.0) {
/* Prevent printing of '-0' */
count = 1;
buffer->data[buffer->count] = '0';
} else {
count = snprintf((char *) buffer->data + buffer->count, BUFSIZE, fmt, x);
}
buffer->count += count; buffer->count += count;
} }

View File

@ -190,4 +190,39 @@
(assert (= (test-expand "../def.txt" ":all:") "../def.txt") "module/expand-path 7") (assert (= (test-expand "../def.txt" ":all:") "../def.txt") "module/expand-path 7")
(assert (= (test-expand "../././././abcd/../def.txt" ":all:") "../def.txt") "module/expand-path 8") (assert (= (test-expand "../././././abcd/../def.txt" ":all:") "../def.txt") "module/expand-path 8")
# Integer type checks
(assert (compare= 0 (- (int/u64 "1000") 1000)) "subtract from int/u64")
(assert (odd? (int/u64 "1001")) "odd? 1")
(assert (not (odd? (int/u64 "1000"))) "odd? 2")
(assert (odd? (int/s64 "1001")) "odd? 3")
(assert (not (odd? (int/s64 "1000"))) "odd? 4")
(assert (odd? (int/s64 "-1001")) "odd? 5")
(assert (not (odd? (int/s64 "-1000"))) "odd? 6")
(assert (even? (int/u64 "1000")) "even? 1")
(assert (not (even? (int/u64 "1001"))) "even? 2")
(assert (even? (int/s64 "1000")) "even? 3")
(assert (not (even? (int/s64 "1001"))) "even? 4")
(assert (even? (int/s64 "-1000")) "even? 5")
(assert (not (even? (int/s64 "-1001"))) "even? 6")
# integer type operations
(defn modcheck [x y]
(assert (= (string (mod x y)) (string (mod (int/s64 x) y)))
(string "int/s64 (mod " x " " y ") expected " (mod x y) ", got "
(mod (int/s64 x) y)))
(assert (= (string (% x y)) (string (% (int/s64 x) y)))
(string "int/s64 (% " x " " y ") expected " (% x y) ", got "
(% (int/s64 x) y))))
(modcheck 1 2)
(modcheck 1 3)
(modcheck 4 2)
(modcheck 4 1)
(modcheck 10 3)
(modcheck 10 -3)
(modcheck -10 3)
(modcheck -10 -3)
(end-suite) (end-suite)