Add tostring method for abstract types.

This lets abstract types customize how they
print for debugging.
This commit is contained in:
Calvin Rose 2019-03-19 13:36:26 -04:00
parent 22e24fb47b
commit 94a2084723
8 changed files with 59 additions and 32 deletions

View File

@ -23,6 +23,7 @@
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <limits.h> #include <limits.h>
#include <inttypes.h>
#ifndef JANET_AMALG #ifndef JANET_AMALG
#include <janet.h> #include <janet.h>
@ -45,6 +46,18 @@ static void int64_unmarshal(void *p, JanetMarshalContext *ctx) {
*((int64_t *)p) = janet_unmarshal_int64(ctx); *((int64_t *)p) = janet_unmarshal_int64(ctx);
} }
static void it_s64_tostring(void *p, JanetBuffer *buffer) {
char str[32];
sprintf(str, "<core/s64 %" PRId64 ">", *((int64_t *)p));
janet_buffer_push_cstring(buffer, str);
}
static void it_u64_tostring(void *p, JanetBuffer *buffer) {
char str[32];
sprintf(str, "<core/u64 %" PRIu64 ">", *((uint64_t *)p));
janet_buffer_push_cstring(buffer, str);
}
static const JanetAbstractType it_s64_type = { static const JanetAbstractType it_s64_type = {
"core/s64", "core/s64",
NULL, NULL,
@ -52,7 +65,8 @@ static const JanetAbstractType it_s64_type = {
it_s64_get, it_s64_get,
NULL, NULL,
int64_marshal, int64_marshal,
int64_unmarshal int64_unmarshal,
it_s64_tostring
}; };
static const JanetAbstractType it_u64_type = { static const JanetAbstractType it_u64_type = {
@ -62,7 +76,8 @@ static const JanetAbstractType it_u64_type = {
it_u64_get, it_u64_get,
NULL, NULL,
int64_marshal, int64_marshal,
int64_unmarshal int64_unmarshal,
it_u64_tostring
}; };
int64_t janet_unwrap_s64(Janet x) { int64_t janet_unwrap_s64(Janet x) {

View File

@ -58,6 +58,7 @@ JanetAbstractType cfun_io_filetype = {
io_file_get, io_file_get,
NULL, NULL,
NULL, NULL,
NULL,
NULL NULL
}; };

View File

@ -650,6 +650,7 @@ static JanetAbstractType janet_parse_parsertype = {
parserget, parserget,
NULL, NULL,
NULL, NULL,
NULL,
NULL NULL
}; };

View File

@ -986,6 +986,7 @@ static JanetAbstractType peg_type = {
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
NULL NULL
}; };

View File

@ -201,8 +201,14 @@ 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: {
const char *n = janet_abstract_type(janet_unwrap_abstract(x))->name; void *p = janet_unwrap_abstract(x);
string_description_b(buffer, n, janet_unwrap_abstract(x)); const JanetAbstractType *at = janet_abstract_type(p);
if (at->tostring) {
at->tostring(p, buffer);
} else {
const char *n = at->name;
string_description_b(buffer, n, janet_unwrap_abstract(x));
}
return; return;
} }
case JANET_CFUNCTION: { case JANET_CFUNCTION: {
@ -456,38 +462,18 @@ static void pushtypes(JanetBuffer *buffer, int types) {
} }
} }
/* Helper function for formatting strings. Useful for generating error messages and the like. void janet_formatb(JanetBuffer *bufp, const char *format, va_list args) {
* Similar to printf, but specialized for operating with janet. */ for (const char *c = format; *c; c++) {
const uint8_t *janet_formatc(const char *format, ...) { switch (*c) {
va_list args;
int32_t len = 0;
int32_t i;
const uint8_t *ret;
JanetBuffer buffer;
JanetBuffer *bufp = &buffer;
/* Calculate length */
while (format[len]) len++;
/* Initialize buffer */
janet_buffer_init(bufp, len);
/* Start args */
va_start(args, format);
/* Iterate length */
for (i = 0; i < len; i++) {
uint8_t c = format[i];
switch (c) {
default: default:
janet_buffer_push_u8(bufp, c); janet_buffer_push_u8(bufp, *c);
break; break;
case '%': { case '%': {
if (i + 1 >= len) if (c[1] == '\0')
break; break;
switch (format[++i]) { switch (*++c) {
default: default:
janet_buffer_push_u8(bufp, format[i]); janet_buffer_push_u8(bufp, *c);
break; break;
case 'f': case 'f':
number_to_string_b(bufp, va_arg(args, double)); number_to_string_b(bufp, va_arg(args, double));
@ -535,7 +521,25 @@ const uint8_t *janet_formatc(const char *format, ...) {
} }
} }
} }
}
/* Helper function for formatting strings. Useful for generating error messages and the like.
* Similar to printf, but specialized for operating with janet. */
const uint8_t *janet_formatc(const char *format, ...) {
va_list args;
const uint8_t *ret;
JanetBuffer buffer;
int32_t len = 0;
/* Calculate length, init buffer and args */
while (format[len]) len++;
janet_buffer_init(&buffer, len);
va_start(args, format);
/* Run format */
janet_formatb(&buffer, format, args);
/* Iterate length */
va_end(args); va_end(args);
ret = janet_string(buffer.data, buffer.count); ret = janet_string(buffer.data, buffer.count);

View File

@ -117,6 +117,7 @@ static const JanetAbstractType ta_buffer_type = {
NULL, NULL,
ta_buffer_marshal, ta_buffer_marshal,
ta_buffer_unmarshal, ta_buffer_unmarshal,
NULL
}; };
static int ta_mark(void *p, size_t s) { static int ta_mark(void *p, size_t s) {
@ -273,7 +274,8 @@ static const JanetAbstractType ta_view_type = {
ta_getter, ta_getter,
ta_setter, ta_setter,
ta_view_marshal, ta_view_marshal,
ta_view_unmarshal ta_view_unmarshal,
NULL
}; };
JanetTArrayBuffer *janet_tarray_buffer(size_t size) { JanetTArrayBuffer *janet_tarray_buffer(size_t size) {

View File

@ -293,6 +293,7 @@ static const JanetAbstractType type_wrap = {
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
NULL NULL
}; };

View File

@ -833,6 +833,7 @@ struct JanetAbstractType {
void (*put)(void *data, Janet key, Janet value); void (*put)(void *data, Janet key, Janet value);
void (*marshal)(void *p, JanetMarshalContext *ctx); void (*marshal)(void *p, JanetMarshalContext *ctx);
void (*unmarshal)(void *p, JanetMarshalContext *ctx); void (*unmarshal)(void *p, JanetMarshalContext *ctx);
void (*tostring)(void *p, JanetBuffer *buffer);
}; };
struct JanetReg { struct JanetReg {
@ -1101,6 +1102,7 @@ JANET_API void janet_description_b(JanetBuffer *buffer, Janet x);
#define janet_cstringv(cstr) janet_wrap_string(janet_cstring(cstr)) #define janet_cstringv(cstr) janet_wrap_string(janet_cstring(cstr))
#define janet_stringv(str, len) janet_wrap_string(janet_string((str), (len))) #define janet_stringv(str, len) janet_wrap_string(janet_string((str), (len)))
JANET_API const uint8_t *janet_formatc(const char *format, ...); JANET_API const uint8_t *janet_formatc(const char *format, ...);
JANET_API void janet_formatb(JanetBuffer *bufp, const char *format, va_list args);
/* Symbol functions */ /* Symbol functions */
JANET_API const uint8_t *janet_symbol(const uint8_t *str, int32_t len); JANET_API const uint8_t *janet_symbol(const uint8_t *str, int32_t len);