mirror of
https://github.com/janet-lang/janet
synced 2024-11-29 03:19:54 +00:00
bigint pretty printing
This commit is contained in:
parent
9bc899ccf2
commit
42a0af3b1b
@ -57,92 +57,99 @@ static const JanetAbstractType bn_uint64_type = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static int str_to_int64(const char * str, bn_int64 * box,int base) {
|
static int str_to_int64(const char *str, bn_int64 *box, int base) {
|
||||||
char *endptr;
|
char *endptr;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
*box =(bn_int64)strtoll(str, &endptr, base);
|
*box = (bn_int64)strtoll(str, &endptr, base);
|
||||||
if ((errno == ERANGE && (*box == LLONG_MAX || *box == LLONG_MIN)) ||
|
if ((errno == ERANGE && (*box == LLONG_MAX || *box == LLONG_MIN)) ||
|
||||||
(errno != 0 && *box == 0) ||
|
(errno != 0 && *box == 0) ||
|
||||||
(endptr == str) ) return 0;
|
(endptr == str)) return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int str_to_uint64(const char * str, bn_uint64 * box,int base) {
|
static int str_to_uint64(const char *str, bn_uint64 *box, int base) {
|
||||||
char *endptr;
|
char *endptr;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
*box =(bn_int64)strtoull(str, &endptr, base);
|
*box = (bn_int64)strtoull(str, &endptr, base);
|
||||||
if ((errno == ERANGE && (*box == ULLONG_MAX)) ||
|
if ((errno == ERANGE && (*box == ULLONG_MAX)) ||
|
||||||
(errno != 0 && *box == 0) ||
|
(errno != 0 && *box == 0) ||
|
||||||
(endptr == str) ) return 0;
|
(endptr == str)) return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static Janet make_bn_int64(Janet x) {
|
static Janet make_bn_int64(Janet x) {
|
||||||
bn_int64 * box = (bn_int64 *)janet_abstract(&bn_int64_type,sizeof(bn_int64));
|
bn_int64 *box = (bn_int64 *)janet_abstract(&bn_int64_type, sizeof(bn_int64));
|
||||||
switch (janet_type(x)) {
|
switch (janet_type(x)) {
|
||||||
case JANET_NUMBER : {
|
case JANET_NUMBER : {
|
||||||
double dbl = janet_unwrap_number(x);
|
double dbl = janet_unwrap_number(x);
|
||||||
if (dbl == (bn_int64)dbl) {
|
if (dbl == (bn_int64)dbl) {
|
||||||
*box = (bn_int64)dbl;
|
*box = (bn_int64)dbl;
|
||||||
return janet_wrap_abstract(box);
|
return janet_wrap_abstract(box);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case JANET_STRING:
|
||||||
|
case JANET_SYMBOL:
|
||||||
|
case JANET_KEYWORD: {
|
||||||
|
if (str_to_int64((const char *)janet_unwrap_string(x), box, 16))
|
||||||
|
return janet_wrap_abstract(box);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case JANET_ABSTRACT: {
|
||||||
|
void *abst = janet_unwrap_abstract(x);
|
||||||
|
if ((janet_abstract_type(abst) == &bn_int64_type) || (janet_abstract_type(abst) == &bn_uint64_type)) {
|
||||||
|
*box = *(bn_int64 *)abst;
|
||||||
|
return janet_wrap_abstract(box);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
janet_panic("bad int64 initializer");
|
||||||
}
|
return janet_wrap_nil();
|
||||||
case JANET_STRING:
|
|
||||||
case JANET_SYMBOL:
|
|
||||||
case JANET_KEYWORD: {
|
|
||||||
if (str_to_int64((const char*)janet_unwrap_string(x),box,16))
|
|
||||||
return janet_wrap_abstract(box);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JANET_ABSTRACT: {
|
|
||||||
void * abst = janet_unwrap_abstract(x);
|
|
||||||
if ((janet_abstract_type(abst) == &bn_int64_type) || (janet_abstract_type(abst) == &bn_uint64_type)) {
|
|
||||||
*box=*(bn_int64 *)abst;
|
|
||||||
return janet_wrap_abstract(box);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
janet_panic("bad int64 initializer");
|
|
||||||
return janet_wrap_nil();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Janet make_bn_uint64(Janet x) {
|
static Janet make_bn_uint64(Janet x) {
|
||||||
bn_uint64 * box = (bn_uint64 *)janet_abstract(&bn_uint64_type,sizeof(bn_uint64));
|
bn_uint64 *box = (bn_uint64 *)janet_abstract(&bn_uint64_type, sizeof(bn_uint64));
|
||||||
switch (janet_type(x)) {
|
switch (janet_type(x)) {
|
||||||
case JANET_NUMBER : {
|
case JANET_NUMBER : {
|
||||||
double dbl = janet_unwrap_number(x);
|
double dbl = janet_unwrap_number(x);
|
||||||
if (dbl == (bn_uint64)dbl) {
|
if (dbl == (bn_uint64)dbl) {
|
||||||
*box = (bn_uint64)dbl;
|
*box = (bn_uint64)dbl;
|
||||||
return janet_wrap_abstract(box);
|
return janet_wrap_abstract(box);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case JANET_STRING:
|
||||||
|
case JANET_SYMBOL:
|
||||||
|
case JANET_KEYWORD: {
|
||||||
|
if (str_to_uint64((const char *)janet_unwrap_string(x), box, 16))
|
||||||
|
return janet_wrap_abstract(box);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case JANET_ABSTRACT: {
|
||||||
|
void *abst = janet_unwrap_abstract(x);
|
||||||
|
if (janet_abstract_type(abst) == &bn_uint64_type) {
|
||||||
|
*box = *(bn_uint64 *)abst;
|
||||||
|
return janet_wrap_abstract(box);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
janet_panic("bad uint64 initializer");
|
||||||
}
|
return janet_wrap_nil();
|
||||||
case JANET_STRING:
|
|
||||||
case JANET_SYMBOL:
|
|
||||||
case JANET_KEYWORD: {
|
|
||||||
if (str_to_uint64((const char*)janet_unwrap_string(x),box,16))
|
|
||||||
return janet_wrap_abstract(box);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case JANET_ABSTRACT: {
|
|
||||||
void * abst = janet_unwrap_abstract(x);
|
|
||||||
if (janet_abstract_type(abst) == &bn_uint64_type) {
|
|
||||||
*box=*(bn_uint64 *)abst;
|
|
||||||
return janet_wrap_abstract(box);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
janet_panic("bad uint64 initializer");
|
|
||||||
return janet_wrap_nil();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int janet_is_bigint(Janet x, JanetBigintType type) {
|
||||||
|
return janet_checktype(x, JANET_ABSTRACT) &&
|
||||||
|
(((type == JANET_BIGINT_TYPE_int64) && (janet_abstract_type(janet_unwrap_abstract(x)) == &bn_int64_type)) ||
|
||||||
|
((type == JANET_BIGINT_TYPE_uint64) && (janet_abstract_type(janet_unwrap_abstract(x)) == &bn_uint64_type)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static Janet cfun_bn_int64_new(int32_t argc, Janet *argv) {
|
static Janet cfun_bn_int64_new(int32_t argc, Janet *argv) {
|
||||||
@ -159,16 +166,16 @@ static Janet cfun_bn_uint64_new(int32_t argc, Janet *argv) {
|
|||||||
static Janet cfun_bn_pretty(int32_t argc, Janet *argv) {
|
static Janet cfun_bn_pretty(int32_t argc, Janet *argv) {
|
||||||
janet_fixarity(argc, 1);
|
janet_fixarity(argc, 1);
|
||||||
char buf[32];
|
char buf[32];
|
||||||
if (janet_checktype(argv[0],JANET_ABSTRACT)) {
|
if (janet_checktype(argv[0], JANET_ABSTRACT)) {
|
||||||
void * box = janet_unwrap_abstract(argv[0]);
|
void *box = janet_unwrap_abstract(argv[0]);
|
||||||
if (janet_abstract_type(box) == &bn_int64_type) {
|
if (janet_abstract_type(box) == &bn_int64_type) {
|
||||||
snprintf(buf, 32,"%li",*(bn_int64 *)box);
|
snprintf(buf, 32, "%li", *(bn_int64 *)box);
|
||||||
return janet_cstringv(buf);
|
return janet_cstringv(buf);
|
||||||
}
|
}
|
||||||
if (janet_abstract_type(box) == &bn_uint64_type) {
|
if (janet_abstract_type(box) == &bn_uint64_type) {
|
||||||
snprintf(buf, 32,"%lu",*(bn_uint64 *)box);
|
snprintf(buf, 32, "%lu", *(bn_uint64 *)box);
|
||||||
return janet_cstringv(buf);
|
return janet_cstringv(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
janet_panicf("expected bigint");
|
janet_panicf("expected bigint");
|
||||||
return janet_wrap_nil();
|
return janet_wrap_nil();
|
||||||
@ -182,9 +189,9 @@ static const JanetReg bn_cfuns[] = {
|
|||||||
"Create new int64.")
|
"Create new int64.")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"bigint/uint64", cfun_bn_uint64_new,
|
"bigint/uint64", cfun_bn_uint64_new,
|
||||||
JDOC("(bigint/uint64 value )\n\n"
|
JDOC("(bigint/uint64 value )\n\n"
|
||||||
"Create new uint64.")
|
"Create new uint64.")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"bigint/pretty", cfun_bn_pretty,
|
"bigint/pretty", cfun_bn_pretty,
|
||||||
|
@ -80,6 +80,22 @@ static void integer_to_string_b(JanetBuffer *buffer, int32_t x) {
|
|||||||
buffer->count += len + neg;
|
buffer->count += len + neg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef JANET_BIGINT
|
||||||
|
|
||||||
|
static void uint64_to_string_b(JanetBuffer *buffer, uint64_t x) {
|
||||||
|
janet_buffer_ensure(buffer, buffer->count + BUFSIZE, 2);
|
||||||
|
int count = snprintf((char *) buffer->data + buffer->count, BUFSIZE, "%lu", x);
|
||||||
|
buffer->count += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void int64_to_string_b(JanetBuffer *buffer, int64_t x) {
|
||||||
|
janet_buffer_ensure(buffer, buffer->count + BUFSIZE, 2);
|
||||||
|
int count = snprintf((char *) buffer->data + buffer->count, BUFSIZE, "%li", x);
|
||||||
|
buffer->count += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#define HEX(i) (((uint8_t *) janet_base64)[(i)])
|
#define HEX(i) (((uint8_t *) janet_base64)[(i)])
|
||||||
|
|
||||||
/* Returns a string description for a pointer. Truncates
|
/* Returns a string description for a pointer. Truncates
|
||||||
@ -201,6 +217,16 @@ void janet_description_b(JanetBuffer *buffer, Janet x) {
|
|||||||
janet_escape_buffer_b(buffer, janet_unwrap_buffer(x));
|
janet_escape_buffer_b(buffer, janet_unwrap_buffer(x));
|
||||||
return;
|
return;
|
||||||
case JANET_ABSTRACT: {
|
case JANET_ABSTRACT: {
|
||||||
|
#ifdef JANET_BIGINT
|
||||||
|
if (janet_is_bigint(x, JANET_BIGINT_TYPE_int64)) {
|
||||||
|
int64_to_string_b(buffer,*(int64_t *)janet_unwrap_abstract(x));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (janet_is_bigint(x, JANET_BIGINT_TYPE_uint64)) {
|
||||||
|
uint64_to_string_b(buffer,*(uint64_t*)janet_unwrap_abstract(x));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
const char *n = janet_abstract_type(janet_unwrap_abstract(x))->name;
|
const char *n = janet_abstract_type(janet_unwrap_abstract(x))->name;
|
||||||
string_description_b(buffer, n, janet_unwrap_abstract(x));
|
string_description_b(buffer, n, janet_unwrap_abstract(x));
|
||||||
return;
|
return;
|
||||||
|
@ -1321,6 +1321,19 @@ JANET_API JanetTArrayView *janet_gettarray_view(const Janet *argv, int32_t n, Ja
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef JANET_BIGINT
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
JANET_BIGINT_TYPE_int64,
|
||||||
|
JANET_BIGINT_TYPE_uint64,
|
||||||
|
} JanetBigintType;
|
||||||
|
|
||||||
|
JANET_API int janet_is_bigint(Janet x, JanetBigintType type);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***** END SECTION MAIN *****/
|
/***** END SECTION MAIN *****/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Loading…
Reference in New Issue
Block a user