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 <stdlib.h>
#include <limits.h>
#include <inttypes.h>
#ifndef JANET_AMALG
#include <janet.h>
@ -45,6 +46,18 @@ static void int64_unmarshal(void *p, JanetMarshalContext *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 = {
"core/s64",
NULL,
@ -52,7 +65,8 @@ static const JanetAbstractType it_s64_type = {
it_s64_get,
NULL,
int64_marshal,
int64_unmarshal
int64_unmarshal,
it_s64_tostring
};
static const JanetAbstractType it_u64_type = {
@ -62,7 +76,8 @@ static const JanetAbstractType it_u64_type = {
it_u64_get,
NULL,
int64_marshal,
int64_unmarshal
int64_unmarshal,
it_u64_tostring
};
int64_t janet_unwrap_s64(Janet x) {

View File

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

View File

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

View File

@ -986,6 +986,7 @@ static JanetAbstractType peg_type = {
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));
return;
case JANET_ABSTRACT: {
const char *n = janet_abstract_type(janet_unwrap_abstract(x))->name;
string_description_b(buffer, n, janet_unwrap_abstract(x));
void *p = 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;
}
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.
* Similar to printf, but specialized for operating with janet. */
const uint8_t *janet_formatc(const char *format, ...) {
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) {
void janet_formatb(JanetBuffer *bufp, const char *format, va_list args) {
for (const char *c = format; *c; c++) {
switch (*c) {
default:
janet_buffer_push_u8(bufp, c);
janet_buffer_push_u8(bufp, *c);
break;
case '%': {
if (i + 1 >= len)
if (c[1] == '\0')
break;
switch (format[++i]) {
switch (*++c) {
default:
janet_buffer_push_u8(bufp, format[i]);
janet_buffer_push_u8(bufp, *c);
break;
case 'f':
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);
ret = janet_string(buffer.data, buffer.count);

View File

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

View File

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

View File

@ -833,6 +833,7 @@ struct JanetAbstractType {
void (*put)(void *data, Janet key, Janet value);
void (*marshal)(void *p, JanetMarshalContext *ctx);
void (*unmarshal)(void *p, JanetMarshalContext *ctx);
void (*tostring)(void *p, JanetBuffer *buffer);
};
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_stringv(str, len) janet_wrap_string(janet_string((str), (len)))
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 */
JANET_API const uint8_t *janet_symbol(const uint8_t *str, int32_t len);