mirror of
https://github.com/janet-lang/janet
synced 2025-01-12 16:40:27 +00:00
All tests pass.
This commit is contained in:
parent
411c5da6d3
commit
01837f2bb6
@ -197,6 +197,80 @@ static Janet cfun_it_u64_new(int32_t argc, Janet *argv) {
|
|||||||
return janet_wrap_u64(janet_unwrap_u64(argv[0]));
|
return janet_wrap_u64(janet_unwrap_u64(argv[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Janet cfun_it_s64_compare(int32_t argc, Janet *argv) {
|
||||||
|
janet_fixarity(argc, 2);
|
||||||
|
if (janet_is_int(argv[0]) != JANET_INT_S64)
|
||||||
|
janet_panic("compare method requires int/s64 as first argument");
|
||||||
|
int64_t x = janet_unwrap_s64(argv[0]);
|
||||||
|
switch (janet_type(argv[1])) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case JANET_NUMBER : {
|
||||||
|
double y = round(janet_unwrap_number(argv[1]));
|
||||||
|
double dx = round((double) x); //double trouble?
|
||||||
|
return janet_wrap_number(dx < y ? -1 : (dx > y ? 1 : 0));
|
||||||
|
}
|
||||||
|
case JANET_ABSTRACT: {
|
||||||
|
void *abst = janet_unwrap_abstract(argv[1]);
|
||||||
|
if (janet_abstract_type(abst) == &janet_s64_type) {
|
||||||
|
int64_t y = *(int64_t *)abst;
|
||||||
|
return janet_wrap_number((x < y) ? -1 : (x > y ? 1 : 0));
|
||||||
|
} else if (janet_abstract_type(abst) == &janet_u64_type) {
|
||||||
|
// comparing signed to unsigned -- be careful!
|
||||||
|
uint64_t y = *(uint64_t *)abst;
|
||||||
|
if (x < 0) {
|
||||||
|
return janet_wrap_number(-1);
|
||||||
|
} else if (y > INT64_MAX) {
|
||||||
|
return janet_wrap_number(-1);
|
||||||
|
} else {
|
||||||
|
int64_t y2 = (int64_t) y;
|
||||||
|
return janet_wrap_number((x < y2) ? -1 : (x > y2 ? 1 : 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return janet_wrap_nil();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Janet cfun_it_u64_compare(int32_t argc, Janet *argv) {
|
||||||
|
janet_fixarity(argc, 2);
|
||||||
|
if (janet_is_int(argv[0]) != JANET_INT_U64) // is this needed?
|
||||||
|
janet_panic("compare method requires int/u64 as first argument");
|
||||||
|
uint64_t x = janet_unwrap_u64(argv[0]);
|
||||||
|
switch (janet_type(argv[1])) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case JANET_NUMBER : {
|
||||||
|
double y = round(janet_unwrap_number(argv[1]));
|
||||||
|
if (y < 0) // unsigned int x has to be greater
|
||||||
|
return janet_wrap_number(1);
|
||||||
|
double dx = round((double) x); //double trouble?
|
||||||
|
return janet_wrap_number(dx < y ? -1 : (dx > y ? 1 : 0));
|
||||||
|
}
|
||||||
|
case JANET_ABSTRACT: {
|
||||||
|
void *abst = janet_unwrap_abstract(argv[1]);
|
||||||
|
if (janet_abstract_type(abst) == &janet_u64_type) {
|
||||||
|
uint64_t y = *(uint64_t *)abst;
|
||||||
|
return janet_wrap_number((x < y) ? -1 : (x > y ? 1 : 0));
|
||||||
|
} else if (janet_abstract_type(abst) == &janet_s64_type) {
|
||||||
|
// comparing unsigned to signed -- be careful!
|
||||||
|
int64_t y = *(int64_t *)abst;
|
||||||
|
if (y < 0) {
|
||||||
|
return janet_wrap_number(1);
|
||||||
|
} else if (x > INT64_MAX) {
|
||||||
|
return janet_wrap_number(1);
|
||||||
|
} else {
|
||||||
|
int64_t x2 = (int64_t) x;
|
||||||
|
return janet_wrap_number((x2 < y) ? -1 : (x2 > y ? 1 : 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return janet_wrap_nil();
|
||||||
|
}
|
||||||
|
|
||||||
#define OPMETHOD(T, type, name, oper) \
|
#define OPMETHOD(T, type, name, oper) \
|
||||||
static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
||||||
janet_arity(argc, 2, -1); \
|
janet_arity(argc, 2, -1); \
|
||||||
@ -266,13 +340,14 @@ static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
|||||||
return janet_wrap_abstract(box); \
|
return janet_wrap_abstract(box); \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
|
/*
|
||||||
#define COMPMETHOD(T, type, name, oper) \
|
#define COMPMETHOD(T, type, name, oper) \
|
||||||
static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
||||||
janet_fixarity(argc, 2); \
|
janet_fixarity(argc, 2); \
|
||||||
T v1 = janet_unwrap_##type(argv[0]); \
|
T v1 = janet_unwrap_##type(argv[0]); \
|
||||||
T v2 = janet_unwrap_##type(argv[1]); \
|
T v2 = janet_unwrap_##type(argv[1]); \
|
||||||
return janet_wrap_boolean(v1 oper v2); \
|
return janet_wrap_boolean(v1 oper v2); \
|
||||||
}
|
} */
|
||||||
|
|
||||||
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);
|
janet_arity(argc, 2, -1);
|
||||||
@ -316,12 +391,14 @@ OPMETHOD(int64_t, s64, or, |)
|
|||||||
OPMETHOD(int64_t, s64, xor, ^)
|
OPMETHOD(int64_t, s64, xor, ^)
|
||||||
OPMETHOD(int64_t, s64, lshift, <<)
|
OPMETHOD(int64_t, s64, lshift, <<)
|
||||||
OPMETHOD(int64_t, s64, rshift, >>)
|
OPMETHOD(int64_t, s64, rshift, >>)
|
||||||
|
/*
|
||||||
COMPMETHOD(int64_t, s64, lt, <)
|
COMPMETHOD(int64_t, s64, lt, <)
|
||||||
COMPMETHOD(int64_t, s64, gt, >)
|
COMPMETHOD(int64_t, s64, gt, >)
|
||||||
COMPMETHOD(int64_t, s64, le, <=)
|
COMPMETHOD(int64_t, s64, le, <=)
|
||||||
COMPMETHOD(int64_t, s64, ge, >=)
|
COMPMETHOD(int64_t, s64, ge, >=)
|
||||||
COMPMETHOD(int64_t, s64, eq, ==)
|
COMPMETHOD(int64_t, s64, eq, ==)
|
||||||
COMPMETHOD(int64_t, s64, ne, !=)
|
COMPMETHOD(int64_t, s64, ne, !=)
|
||||||
|
*/
|
||||||
|
|
||||||
OPMETHOD(uint64_t, u64, add, +)
|
OPMETHOD(uint64_t, u64, add, +)
|
||||||
OPMETHOD(uint64_t, u64, sub, -)
|
OPMETHOD(uint64_t, u64, sub, -)
|
||||||
@ -336,18 +413,20 @@ OPMETHOD(uint64_t, u64, or, |)
|
|||||||
OPMETHOD(uint64_t, u64, xor, ^)
|
OPMETHOD(uint64_t, u64, xor, ^)
|
||||||
OPMETHOD(uint64_t, u64, lshift, <<)
|
OPMETHOD(uint64_t, u64, lshift, <<)
|
||||||
OPMETHOD(uint64_t, u64, rshift, >>)
|
OPMETHOD(uint64_t, u64, rshift, >>)
|
||||||
|
/*
|
||||||
COMPMETHOD(uint64_t, u64, lt, <)
|
COMPMETHOD(uint64_t, u64, lt, <)
|
||||||
COMPMETHOD(uint64_t, u64, gt, >)
|
COMPMETHOD(uint64_t, u64, gt, >)
|
||||||
COMPMETHOD(uint64_t, u64, le, <=)
|
COMPMETHOD(uint64_t, u64, le, <=)
|
||||||
COMPMETHOD(uint64_t, u64, ge, >=)
|
COMPMETHOD(uint64_t, u64, ge, >=)
|
||||||
COMPMETHOD(uint64_t, u64, eq, ==)
|
COMPMETHOD(uint64_t, u64, eq, ==)
|
||||||
COMPMETHOD(uint64_t, u64, ne, !=)
|
COMPMETHOD(uint64_t, u64, ne, !=) */
|
||||||
|
|
||||||
#undef OPMETHOD
|
#undef OPMETHOD
|
||||||
#undef DIVMETHOD
|
#undef DIVMETHOD
|
||||||
#undef DIVMETHOD_SIGNED
|
#undef DIVMETHOD_SIGNED
|
||||||
#undef COMPMETHOD
|
#undef COMPMETHOD
|
||||||
|
|
||||||
|
|
||||||
static JanetMethod it_s64_methods[] = {
|
static JanetMethod it_s64_methods[] = {
|
||||||
{"+", cfun_it_s64_add},
|
{"+", cfun_it_s64_add},
|
||||||
{"r+", cfun_it_s64_add},
|
{"r+", cfun_it_s64_add},
|
||||||
@ -361,12 +440,12 @@ static JanetMethod it_s64_methods[] = {
|
|||||||
{"rmod", cfun_it_s64_modi},
|
{"rmod", cfun_it_s64_modi},
|
||||||
{"%", cfun_it_s64_rem},
|
{"%", cfun_it_s64_rem},
|
||||||
{"r%", cfun_it_s64_remi},
|
{"r%", cfun_it_s64_remi},
|
||||||
{"<", cfun_it_s64_lt},
|
/* {"<", cfun_it_s64_lt},
|
||||||
{">", cfun_it_s64_gt},
|
{">", cfun_it_s64_gt},
|
||||||
{"<=", cfun_it_s64_le},
|
{"<=", cfun_it_s64_le},
|
||||||
{">=", cfun_it_s64_ge},
|
{">=", cfun_it_s64_ge},
|
||||||
{"=", cfun_it_s64_eq},
|
{"=", cfun_it_s64_eq},
|
||||||
{"!=", cfun_it_s64_ne},
|
{"!=", cfun_it_s64_ne},*/
|
||||||
{"&", 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},
|
||||||
@ -375,6 +454,7 @@ static JanetMethod it_s64_methods[] = {
|
|||||||
{"r^", cfun_it_s64_xor},
|
{"r^", cfun_it_s64_xor},
|
||||||
{"<<", cfun_it_s64_lshift},
|
{"<<", cfun_it_s64_lshift},
|
||||||
{">>", cfun_it_s64_rshift},
|
{">>", cfun_it_s64_rshift},
|
||||||
|
{"compare", cfun_it_s64_compare},
|
||||||
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
@ -392,12 +472,12 @@ static JanetMethod it_u64_methods[] = {
|
|||||||
{"rmod", cfun_it_u64_modi},
|
{"rmod", cfun_it_u64_modi},
|
||||||
{"%", cfun_it_u64_mod},
|
{"%", cfun_it_u64_mod},
|
||||||
{"r%", cfun_it_u64_modi},
|
{"r%", cfun_it_u64_modi},
|
||||||
{"<", cfun_it_u64_lt},
|
/* {"<", cfun_it_u64_lt},
|
||||||
{">", cfun_it_u64_gt},
|
{">", cfun_it_u64_gt},
|
||||||
{"<=", cfun_it_u64_le},
|
{"<=", cfun_it_u64_le},
|
||||||
{">=", cfun_it_u64_ge},
|
{">=", cfun_it_u64_ge},
|
||||||
{"=", cfun_it_u64_eq},
|
{"=", cfun_it_u64_eq},
|
||||||
{"!=", cfun_it_u64_ne},
|
{"!=", cfun_it_u64_ne}, */
|
||||||
{"&", 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},
|
||||||
@ -406,6 +486,7 @@ static JanetMethod it_u64_methods[] = {
|
|||||||
{"r^", cfun_it_u64_xor},
|
{"r^", cfun_it_u64_xor},
|
||||||
{"<<", cfun_it_u64_lshift},
|
{"<<", cfun_it_u64_lshift},
|
||||||
{">>", cfun_it_u64_rshift},
|
{">>", cfun_it_u64_rshift},
|
||||||
|
{"compare", cfun_it_u64_compare},
|
||||||
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
@ -336,7 +336,7 @@
|
|||||||
|
|
||||||
## Polymorphic comparison -- Issue #272
|
## Polymorphic comparison -- Issue #272
|
||||||
|
|
||||||
# confirm delegation to primitive comparators:
|
# confirm polymorphic comparison delegation to primitive comparators:
|
||||||
(assert (= 0 (compare-primitive 3 3)) "compare-primitive integers (1)")
|
(assert (= 0 (compare-primitive 3 3)) "compare-primitive integers (1)")
|
||||||
(assert (= -1 (compare-primitive 3 5)) "compare-primitive integers (2)")
|
(assert (= -1 (compare-primitive 3 5)) "compare-primitive integers (2)")
|
||||||
(assert (= 1 (compare-primitive "foo" "bar")) "compare-primitive strings")
|
(assert (= 1 (compare-primitive "foo" "bar")) "compare-primitive strings")
|
||||||
@ -367,7 +367,7 @@
|
|||||||
(fn [x] (+ x x))
|
(fn [x] (+ x x))
|
||||||
print) "compare type ordering")
|
print) "compare type ordering")
|
||||||
|
|
||||||
# test polymorphic
|
# test polymorphic compare with 'objects' (table/setproto)
|
||||||
(def mynum
|
(def mynum
|
||||||
@{:type :mynum :v 0 :compare
|
@{:type :mynum :v 0 :compare
|
||||||
(fn [self other]
|
(fn [self other]
|
||||||
@ -386,6 +386,34 @@
|
|||||||
(assert (compare= 3 n3 (table/setproto @{:v 3} mynum)) "compare= poly")
|
(assert (compare= 3 n3 (table/setproto @{:v 3} mynum)) "compare= poly")
|
||||||
(assert (deep= (sorted @[4 5 n3 2] compare<) @[2 n3 4 5]) "polymorphic sort"))
|
(assert (deep= (sorted @[4 5 n3 2] compare<) @[2 n3 4 5]) "polymorphic sort"))
|
||||||
|
|
||||||
|
# test polymorphic compare with int/u64 and int/s64
|
||||||
|
(def MAX_INT_64_STRING "9223372036854775807")
|
||||||
|
(def MAX_UINT_64_STRING "18446744073709551615")
|
||||||
|
(def MAX_INT_IN_DBL_STRING "9007199254740992")
|
||||||
|
(assert (= 0 (compare (int/u64 3) 3)) "compare number to int/u64")
|
||||||
|
(assert (= -1 (compare (int/u64 3) 4)) "compare number to int/u64 less")
|
||||||
|
(assert (= 0 (compare 3 (int/u64 3))) "compare number to int/u64")
|
||||||
|
(assert (= 1 (compare 4 (int/u64 3))) "compare number to int/u64 greater")
|
||||||
|
(assert (= 0 (compare (int/u64 3) (int/u64 3))) "compare int/u64 to int/u64")
|
||||||
|
(assert (= 1 (compare (int/u64 4) (int/u64 3))) "compare int/u64 to int/u64 greater")
|
||||||
|
(assert (= 0 (compare (int/s64 3) 3)) "compare number to int/s64")
|
||||||
|
(assert (= -1 (compare (int/s64 3) 4)) "compare number to int/s64 less")
|
||||||
|
(assert (= 0 (compare 3 (int/s64 3))) "compare number to int/s64")
|
||||||
|
(assert (= 1 (compare 4 (int/s64 3))) "compare number to int/s64 greater")
|
||||||
|
(assert (= 0 (compare (int/s64 3) (int/s64 3))) "compare int/s64 to int/s64")
|
||||||
|
(assert (= 1 (compare (int/s64 4) (int/s64 3))) "compare int/s64 to int/s64 greater")
|
||||||
|
(assert (= 0 (compare (int/u64 3) (int/s64 3))) "compare int/u64 to int/s64 (1)")
|
||||||
|
(assert (= -1 (compare (int/u64 3) (int/s64 4))) "compare int/u64 to int/s64 (2)")
|
||||||
|
(assert (= 1 (compare (int/u64 1) (int/s64 -1))) "compare int/u64 to int/s64 (3)")
|
||||||
|
(assert (= 1 (compare (int/s64 4) (int/u64 3))) "compare int/s64 to int/u64")
|
||||||
|
(assert (= -1 (compare (int/s64 -1) (int/u64 0))) "compare int/s64 to int/u64 negative")
|
||||||
|
(assert (= -1 (compare (int/s64 MAX_INT_64_STRING) (int/u64 MAX_UINT_64_STRING))) "compare big ints")
|
||||||
|
(assert (= 0 (compare (int/s64 MAX_INT_IN_DBL_STRING) (scan-number MAX_INT_IN_DBL_STRING))) "compare max int in double (1)")
|
||||||
|
(assert (= 0 (compare (int/u64 MAX_INT_IN_DBL_STRING) (scan-number MAX_INT_IN_DBL_STRING))) "compare max int in double (2)")
|
||||||
|
(assert (= 1 (compare (+ 2 (int/u64 MAX_INT_IN_DBL_STRING)) (scan-number MAX_INT_IN_DBL_STRING))) "compare max int in double (3)")
|
||||||
|
# Beware: This is a horrible effect of comparing doubles to integers
|
||||||
|
# int/64(MAX+1) should compare greater than the double, (but doesn't due to precision)
|
||||||
|
(assert (= 0 (compare (+ 1 (int/u64 MAX_INT_IN_DBL_STRING)) (scan-number MAX_INT_IN_DBL_STRING))) "compare max int in double (3)")
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user