diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b47c9cf..16f9261b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. ## ??? - Unreleased +- Use the new `.length` function pointer on abstract types for lengths. Adding + a `length` method will still work as well. +- Support byte views on abstract types with the `bytes` function pointer. - Add the `u` format specifier to printf family functions. - Allow printing 64 integer types in `printf` and `string/format` family functions. - Allow importing modules from custom directories more easily with the `@` prefix diff --git a/Makefile b/Makefile index 02bd3c22..a72413b6 100644 --- a/Makefile +++ b/Makefile @@ -169,9 +169,9 @@ build/c/janet.c: build/janet_boot src/boot/boot.janet ######################## ifeq ($(UNAME), Darwin) -SONAME=libjanet.1.25.dylib +SONAME=libjanet.1.26.dylib else -SONAME=libjanet.so.1.25 +SONAME=libjanet.so.1.26 endif build/c/shell.c: src/mainclient/shell.c diff --git a/meson.build b/meson.build index 2b504f73..f6ffee70 100644 --- a/meson.build +++ b/meson.build @@ -20,7 +20,7 @@ project('janet', 'c', default_options : ['c_std=c99', 'build.c_std=c99', 'b_lundef=false', 'default_library=both'], - version : '1.25.2') + version : '1.26.0') # Global settings janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet') diff --git a/src/conf/janetconf.h b/src/conf/janetconf.h index 1a3a269c..8f850684 100644 --- a/src/conf/janetconf.h +++ b/src/conf/janetconf.h @@ -4,10 +4,10 @@ #define JANETCONF_H #define JANET_VERSION_MAJOR 1 -#define JANET_VERSION_MINOR 25 +#define JANET_VERSION_MINOR 26 #define JANET_VERSION_PATCH 2 #define JANET_VERSION_EXTRA "-dev" -#define JANET_VERSION "1.25.2-dev" +#define JANET_VERSION "1.26.0-dev" /* #define JANET_BUILD "local" */ diff --git a/src/core/inttypes.c b/src/core/inttypes.c index eb7f6bba..c27811f4 100644 --- a/src/core/inttypes.c +++ b/src/core/inttypes.c @@ -532,7 +532,6 @@ OPMETHOD(uint64_t, u64, rshift, >>) #undef DIVMETHOD_SIGNED #undef COMPMETHOD - static JanetMethod it_s64_methods[] = { {"+", cfun_it_s64_add}, {"r+", cfun_it_s64_add}, @@ -555,7 +554,6 @@ static JanetMethod it_s64_methods[] = { {"<<", cfun_it_s64_lshift}, {">>", cfun_it_s64_rshift}, {"compare", cfun_it_s64_compare}, - {NULL, NULL} }; @@ -581,7 +579,6 @@ static JanetMethod it_u64_methods[] = { {"<<", cfun_it_u64_lshift}, {">>", cfun_it_u64_rshift}, {"compare", cfun_it_u64_compare}, - {NULL, NULL} }; diff --git a/src/core/os.c b/src/core/os.c index 360e285f..a6a4594a 100644 --- a/src/core/os.c +++ b/src/core/os.c @@ -1810,11 +1810,9 @@ static Janet os_stat_or_lstat(int do_lstat, int32_t argc, Janet *argv) { janet_arity(argc, 1, 2); const char *path = janet_getcstring(argv, 0); JanetTable *tab = NULL; - int getall = 1; - const uint8_t *key; + const uint8_t *key = NULL; if (argc == 2) { if (janet_checktype(argv[1], JANET_KEYWORD)) { - getall = 0; key = janet_getkeyword(argv, 1); } else { tab = janet_gettable(argv, 1); @@ -1840,7 +1838,7 @@ static Janet os_stat_or_lstat(int do_lstat, int32_t argc, Janet *argv) { return janet_wrap_nil(); } - if (getall) { + if (NULL == key) { /* Put results in table */ for (const struct OsStatGetter *sg = os_stat_getters; sg->name != NULL; sg++) { janet_table_put(tab, janet_ckeywordv(sg->name), sg->fn(&st)); diff --git a/src/core/peg.c b/src/core/peg.c index 1633d546..3759b973 100644 --- a/src/core/peg.c +++ b/src/core/peg.c @@ -306,7 +306,7 @@ tail: case RULE_THRU: case RULE_TO: { const uint32_t *rule_a = s->bytecode + rule[1]; - const uint8_t *next_text; + const uint8_t *next_text = NULL; CapState cs = cap_save(s); down1(s); while (text <= s->text_end) { diff --git a/src/core/specials.c b/src/core/specials.c index c608f8ab..d2c44106 100644 --- a/src/core/specials.c +++ b/src/core/specials.c @@ -813,7 +813,7 @@ static JanetSlot janetc_fn(JanetFopts opts, int32_t argn, const Janet *argv) { JanetSlot ret; Janet head; JanetScope fnscope; - int32_t paramcount, argi, parami, arity, min_arity, max_arity, defindex, i; + int32_t paramcount, argi, parami, arity, min_arity = 0, max_arity, defindex, i; JanetFopts subopts = janetc_fopts_default(c); const Janet *params; const char *errmsg = NULL; diff --git a/src/core/util.c b/src/core/util.c index d92c4c4e..937dbfbc 100644 --- a/src/core/util.c +++ b/src/core/util.c @@ -701,15 +701,25 @@ int janet_indexed_view(Janet seq, const Janet **data, int32_t *len) { /* Read both strings and buffer as unsigned character array + int32_t len. * Returns 1 if the view can be constructed and 0 if the type is invalid. */ int janet_bytes_view(Janet str, const uint8_t **data, int32_t *len) { - if (janet_checktype(str, JANET_STRING) || janet_checktype(str, JANET_SYMBOL) || - janet_checktype(str, JANET_KEYWORD)) { + JanetType t = janet_type(str); + if (t == JANET_STRING || t == JANET_SYMBOL || t == JANET_KEYWORD) { *data = janet_unwrap_string(str); *len = janet_string_length(janet_unwrap_string(str)); return 1; - } else if (janet_checktype(str, JANET_BUFFER)) { + } else if (t == JANET_BUFFER) { *data = janet_unwrap_buffer(str)->data; *len = janet_unwrap_buffer(str)->count; return 1; + } else if (t == JANET_ABSTRACT) { + void *abst = janet_unwrap_abstract(str); + const JanetAbstractType *atype = janet_abstract_type(abst); + if (NULL == atype->bytes) { + return 0; + } + JanetByteView view = atype->bytes(abst, janet_abstract_size(abst)); + *data = view.bytes; + *len = view.len; + return 1; } return 0; } diff --git a/src/core/value.c b/src/core/value.c index f5ed6fe5..c114a6ea 100644 --- a/src/core/value.c +++ b/src/core/value.c @@ -651,6 +651,15 @@ int32_t janet_length(Janet x) { case JANET_TABLE: return janet_unwrap_table(x)->count; case JANET_ABSTRACT: { + void *abst = janet_unwrap_abstract(x); + const JanetAbstractType *type = janet_abstract_type(abst); + if (type->length != NULL) { + size_t len = type->length(abst, janet_abstract_size(abst)); + if (len > INT32_MAX) { + janet_panicf("invalid integer length %u", len); + } + return (int32_t)(len); + } Janet argv[1] = { x }; Janet len = janet_mcall("length", 1, argv); if (!janet_checkint(len)) @@ -679,6 +688,16 @@ Janet janet_lengthv(Janet x) { case JANET_TABLE: return janet_wrap_integer(janet_unwrap_table(x)->count); case JANET_ABSTRACT: { + void *abst = janet_unwrap_abstract(x); + const JanetAbstractType *type = janet_abstract_type(abst); + if (type->length != NULL) { + size_t len = type->length(abst, janet_abstract_size(abst)); + if ((uint64_t) len <= (uint64_t) JANET_INTMAX_INT64) { + return janet_wrap_number((double) len); + } else { + janet_panicf("integer length %u too large", len); + } + } Janet argv[1] = { x }; return janet_mcall("length", 1, argv); } diff --git a/src/include/janet.h b/src/include/janet.h index b83d2f2c..53264781 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1093,6 +1093,8 @@ struct JanetAbstractType { int32_t (*hash)(void *p, size_t len); Janet(*next)(void *p, Janet key); Janet(*call)(void *p, int32_t argc, Janet *argv); + size_t (*length)(void *p, size_t len); + JanetByteView(*bytes)(void *p, size_t len); }; /* Some macros to let us add extra types to JanetAbstract types without @@ -1110,7 +1112,9 @@ struct JanetAbstractType { #define JANET_ATEND_COMPARE NULL,JANET_ATEND_HASH #define JANET_ATEND_HASH NULL,JANET_ATEND_NEXT #define JANET_ATEND_NEXT NULL,JANET_ATEND_CALL -#define JANET_ATEND_CALL +#define JANET_ATEND_CALL NULL,JANET_ATEND_LENGTH +#define JANET_ATEND_LENGTH NULL,JANET_ATEND_BYTES +#define JANET_ATEND_BYTES struct JanetReg { const char *name;