mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 15:43:01 +00:00 
			
		
		
		
	Add tostring method for abstract types.
This lets abstract types customize how they print for debugging.
This commit is contained in:
		| @@ -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) { | ||||||
|   | |||||||
| @@ -58,6 +58,7 @@ JanetAbstractType cfun_io_filetype = { | |||||||
|     io_file_get, |     io_file_get, | ||||||
|     NULL, |     NULL, | ||||||
|     NULL, |     NULL, | ||||||
|  |     NULL, | ||||||
|     NULL |     NULL | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -650,6 +650,7 @@ static JanetAbstractType janet_parse_parsertype = { | |||||||
|     parserget, |     parserget, | ||||||
|     NULL, |     NULL, | ||||||
|     NULL, |     NULL, | ||||||
|  |     NULL, | ||||||
|     NULL |     NULL | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -986,6 +986,7 @@ static JanetAbstractType peg_type = { | |||||||
|     NULL, |     NULL, | ||||||
|     NULL, |     NULL, | ||||||
|     NULL, |     NULL, | ||||||
|  |     NULL, | ||||||
|     NULL |     NULL | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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); | ||||||
|  |             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)); |                 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); | ||||||
|   | |||||||
| @@ -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) { | ||||||
|   | |||||||
| @@ -293,6 +293,7 @@ static const JanetAbstractType type_wrap = { | |||||||
|     NULL, |     NULL, | ||||||
|     NULL, |     NULL, | ||||||
|     NULL, |     NULL, | ||||||
|  |     NULL, | ||||||
|     NULL |     NULL | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose