mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 07:33: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 <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) { | ||||
|   | ||||
| @@ -58,6 +58,7 @@ JanetAbstractType cfun_io_filetype = { | ||||
|     io_file_get, | ||||
|     NULL, | ||||
|     NULL, | ||||
|     NULL, | ||||
|     NULL | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -650,6 +650,7 @@ static JanetAbstractType janet_parse_parsertype = { | ||||
|     parserget, | ||||
|     NULL, | ||||
|     NULL, | ||||
|     NULL, | ||||
|     NULL | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -986,6 +986,7 @@ static JanetAbstractType peg_type = { | ||||
|     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)); | ||||
|             return; | ||||
|         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)); | ||||
|             } | ||||
|             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); | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -293,6 +293,7 @@ static const JanetAbstractType type_wrap = { | ||||
|     NULL, | ||||
|     NULL, | ||||
|     NULL, | ||||
|     NULL, | ||||
|     NULL | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose