diff --git a/src/core/capi.c b/src/core/capi.c index e661b942..b4f9bae7 100644 --- a/src/core/capi.c +++ b/src/core/capi.c @@ -147,6 +147,23 @@ int janet_getmethod(const uint8_t *method, const JanetMethod *methods, Janet *ou return 0; } +Janet janet_nextmethod(const JanetMethod *methods, Janet key) { + if (!janet_checktype(key, JANET_NIL)) { + while (methods->name) { + if (janet_keyeq(key, methods->name)) { + methods++; + break; + } + methods++; + } + } + if (methods->name) { + return janet_ckeywordv(methods->name); + } else { + return janet_wrap_nil(); + } +} + DEFINE_GETTER(number, NUMBER, double) DEFINE_GETTER(array, ARRAY, JanetArray *) DEFINE_GETTER(tuple, TUPLE, const Janet *) diff --git a/src/core/ev.c b/src/core/ev.c index 0691d219..2547bd4c 100644 --- a/src/core/ev.c +++ b/src/core/ev.c @@ -378,7 +378,6 @@ static int janet_stream_getter(void *p, Janet key, Janet *out) { if (!janet_checktype(key, JANET_KEYWORD)) return 0; const JanetMethod *stream_methods = stream->methods; return janet_getmethod(janet_unwrap_keyword(key), stream_methods, out); - return 0; } static void janet_stream_marshal(void *p, JanetMarshalContext *ctx) { @@ -421,6 +420,10 @@ static void *janet_stream_unmarshal(JanetMarshalContext *ctx) { return p; } +static Janet janet_stream_next(void *p, Janet key) { + JanetStream *stream = (JanetStream *)p; + return janet_nextmethod(stream->methods, key); +} const JanetAbstractType janet_stream_type = { "core/stream", @@ -430,7 +433,11 @@ const JanetAbstractType janet_stream_type = { NULL, janet_stream_marshal, janet_stream_unmarshal, - JANET_ATEND_UNMARSHAL + NULL, + NULL, + NULL, + janet_stream_next, + JANET_ATEND_NEXT }; /* Register a fiber to resume with value */ @@ -587,16 +594,24 @@ static void janet_chan_deinit(JanetChannel *chan) { * Janet Channel abstract type */ -/*static int janet_chanat_get(void *p, Janet key, Janet *out);*/ static int janet_chanat_mark(void *p, size_t s); static int janet_chanat_gc(void *p, size_t s); +static Janet janet_chanat_next(void *p, Janet key); +static int janet_chanat_get(void *p, Janet key, Janet *out); static const JanetAbstractType ChannelAT = { "core/channel", janet_chanat_gc, janet_chanat_mark, - NULL, /* janet_chanat_get */ - JANET_ATEND_GET + janet_chanat_get, + NULL, /* put */ + NULL, /* marshal */ + NULL, /* unmarshal */ + NULL, /* tostring */ + NULL, /* compare */ + NULL, /* hash */ + janet_chanat_next, + JANET_ATEND_NEXT }; static int janet_chanat_gc(void *p, size_t s) { @@ -816,6 +831,28 @@ static Janet cfun_channel_new(int32_t argc, Janet *argv) { return janet_wrap_abstract(channel); } +static const JanetMethod ev_chanat_methods[] = { + {"select", cfun_channel_choice}, + {"rselect", cfun_channel_rchoice}, + {"count", cfun_channel_count}, + {"take", cfun_channel_pop}, + {"give", cfun_channel_push}, + {"capacity", cfun_channel_capacity}, + {"full", cfun_channel_full}, + {NULL, NULL} +}; + +static int janet_chanat_get(void *p, Janet key, Janet *out) { + (void) p; + if (!janet_checktype(key, JANET_KEYWORD)) return 0; + return janet_getmethod(janet_unwrap_keyword(key), ev_chanat_methods, out); +} + +static Janet janet_chanat_next(void *p, Janet key) { + (void) p; + return janet_nextmethod(ev_chanat_methods, key); +} + /* Main event loop */ void janet_loop1_impl(int has_timeout, JanetTimestamp timeout); @@ -1256,9 +1293,9 @@ void janet_loop1_impl(int has_timeout, JanetTimestamp timeout) { if (mask & POLLIN) status2 = state->machine(state, JANET_ASYNC_EVENT_READ); if (mask & POLLERR) - status2 = state->machine(state, JANET_ASYNC_EVENT_ERR); + status3 = state->machine(state, JANET_ASYNC_EVENT_ERR); if (mask & POLLHUP) - status2 = state->machine(state, JANET_ASYNC_EVENT_HUP); + status4 = state->machine(state, JANET_ASYNC_EVENT_HUP); if (status1 == JANET_ASYNC_STATUS_DONE || status2 == JANET_ASYNC_STATUS_DONE || status3 == JANET_ASYNC_STATUS_DONE || diff --git a/src/core/inttypes.c b/src/core/inttypes.c index 4e84a046..59cd4899 100644 --- a/src/core/inttypes.c +++ b/src/core/inttypes.c @@ -1,5 +1,5 @@ /* -* Copyright (c) 2020 Calvin Rose & contributors +* Copyright (c) 2021 Calvin Rose & contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -39,6 +39,8 @@ static int it_s64_get(void *p, Janet key, Janet *out); static int it_u64_get(void *p, Janet key, Janet *out); +static Janet janet_int64_next(void *p, Janet key); +static Janet janet_uint64_next(void *p, Janet key); static int32_t janet_int64_hash(void *p1, size_t size) { (void) size; @@ -92,7 +94,8 @@ const JanetAbstractType janet_s64_type = { it_s64_tostring, janet_int64_compare, janet_int64_hash, - JANET_ATEND_HASH + janet_int64_next, + JANET_ATEND_NEXT }; const JanetAbstractType janet_u64_type = { @@ -106,7 +109,8 @@ const JanetAbstractType janet_u64_type = { it_u64_tostring, janet_uint64_compare, janet_int64_hash, - JANET_ATEND_HASH + janet_uint64_next, + JANET_ATEND_NEXT }; int64_t janet_unwrap_s64(Janet x) { @@ -477,6 +481,16 @@ static JanetMethod it_u64_methods[] = { {NULL, NULL} }; +static Janet janet_int64_next(void *p, Janet key) { + (void) p; + return janet_nextmethod(it_s64_methods, key); +} + +static Janet janet_uint64_next(void *p, Janet key) { + (void) p; + return janet_nextmethod(it_u64_methods, key); +} + static int it_s64_get(void *p, Janet key, Janet *out) { (void) p; if (!janet_checktype(key, JANET_KEYWORD)) diff --git a/src/core/io.c b/src/core/io.c index 8bdb3202..d7cea320 100644 --- a/src/core/io.c +++ b/src/core/io.c @@ -1,5 +1,5 @@ /* -* Copyright (c) 2020 Calvin Rose +* Copyright (c) 2021 Calvin Rose * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -39,6 +39,7 @@ static int cfun_io_gc(void *p, size_t len); static int io_file_get(void *p, Janet key, Janet *out); static void io_file_marshal(void *p, JanetMarshalContext *ctx); static void *io_file_unmarshal(JanetMarshalContext *ctx); +static Janet io_file_next(void *p, Janet key); const JanetAbstractType janet_file_type = { "core/file", @@ -48,7 +49,11 @@ const JanetAbstractType janet_file_type = { NULL, io_file_marshal, io_file_unmarshal, - JANET_ATEND_UNMARSHAL + NULL, /* tostring */ + NULL, /* compare */ + NULL, /* hash */ + io_file_next, + JANET_ATEND_NEXT }; /* Check arguments to fopen */ @@ -346,6 +351,11 @@ static int io_file_get(void *p, Janet key, Janet *out) { return janet_getmethod(janet_unwrap_keyword(key), io_file_methods, out); } +static Janet io_file_next(void *p, Janet key) { + (void) p; + return janet_nextmethod(io_file_methods, key); +} + static void io_file_marshal(void *p, JanetMarshalContext *ctx) { JanetFile *iof = (JanetFile *)p; if (ctx->flags & JANET_MARSHAL_UNSAFE) { diff --git a/src/core/math.c b/src/core/math.c index 808267cc..a7a57646 100644 --- a/src/core/math.c +++ b/src/core/math.c @@ -1,5 +1,5 @@ /* -* Copyright (c) 2020 Calvin Rose +* Copyright (c) 2021 Calvin Rose * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -31,6 +31,7 @@ static JANET_THREAD_LOCAL JanetRNG janet_vm_rng = {0, 0, 0, 0, 0}; static int janet_rng_get(void *p, Janet key, Janet *out); +static Janet janet_rng_next(void *p, Janet key); static void janet_rng_marshal(void *p, JanetMarshalContext *ctx) { JanetRNG *rng = (JanetRNG *)p; @@ -60,7 +61,11 @@ const JanetAbstractType janet_rng_type = { NULL, janet_rng_marshal, janet_rng_unmarshal, - JANET_ATEND_UNMARSHAL + NULL, /* tostring */ + NULL, /* compare */ + NULL, /* hash */ + janet_rng_next, + JANET_ATEND_NEXT }; JanetRNG *janet_default_rng(void) { @@ -203,6 +208,11 @@ static int janet_rng_get(void *p, Janet key, Janet *out) { return janet_getmethod(janet_unwrap_keyword(key), rng_methods, out); } +static Janet janet_rng_next(void *p, Janet key) { + (void) p; + return janet_nextmethod(rng_methods, key); +} + /* Get a random number */ static Janet janet_rand(int32_t argc, Janet *argv) { (void) argv; diff --git a/src/core/os.c b/src/core/os.c index ad345e66..e914472e 100644 --- a/src/core/os.c +++ b/src/core/os.c @@ -571,6 +571,10 @@ error: static const JanetMethod proc_methods[] = { {"wait", os_proc_wait}, {"kill", os_proc_kill}, + /* dud methods for janet_proc_next */ + {"in", NULL}, + {"out", NULL}, + {"err", NULL}, {NULL, NULL} }; @@ -596,12 +600,24 @@ static int janet_proc_get(void *p, Janet key, Janet *out) { return janet_getmethod(janet_unwrap_keyword(key), proc_methods, out); } +static Janet janet_proc_next(void *p, Janet key) { + (void) p; + return janet_nextmethod(proc_methods, key); +} + static const JanetAbstractType ProcAT = { "core/process", janet_proc_gc, janet_proc_mark, janet_proc_get, - JANET_ATEND_GET + NULL, /* put */ + NULL, /* marshal */ + NULL, /* unmarshal */ + NULL, /* tostring */ + NULL, /* compare */ + NULL, /* hash */ + janet_proc_next, + JANET_ATEND_NEXT }; static JanetHandle janet_getjstream(Janet *argv, int32_t n, void **orig) { diff --git a/src/core/parse.c b/src/core/parse.c index e59ca132..a384796a 100644 --- a/src/core/parse.c +++ b/src/core/parse.c @@ -1,5 +1,5 @@ /* -* Copyright (c) 2020 Calvin Rose +* Copyright (c) 2021 Calvin Rose * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -840,13 +840,21 @@ static int parsergc(void *p, size_t size) { } static int parserget(void *p, Janet key, Janet *out); +static Janet parsernext(void *p, Janet key); const JanetAbstractType janet_parser_type = { "core/parser", parsergc, parsermark, parserget, - JANET_ATEND_GET + NULL, /* put */ + NULL, /* marshal */ + NULL, /* unmarshal */ + NULL, /* tostring */ + NULL, /* compare */ + NULL, /* hash */ + parsernext, + JANET_ATEND_NEXT }; /* C Function parser */ @@ -1183,6 +1191,11 @@ static int parserget(void *p, Janet key, Janet *out) { return janet_getmethod(janet_unwrap_keyword(key), parser_methods, out); } +static Janet parsernext(void *p, Janet key) { + (void) p; + return janet_nextmethod(parser_methods, key); +} + static const JanetReg parse_cfuns[] = { { "parser/new", cfun_parse_parser, diff --git a/src/core/peg.c b/src/core/peg.c index 9e8c9e1c..c3628839 100644 --- a/src/core/peg.c +++ b/src/core/peg.c @@ -1446,16 +1446,21 @@ bad: } static int cfun_peg_getter(JanetAbstract a, Janet key, Janet *out); +static Janet peg_next(void *p, Janet key); const JanetAbstractType janet_peg_type = { "core/peg", NULL, peg_mark, cfun_peg_getter, - NULL, + NULL, /* put */ peg_marshal, peg_unmarshal, - JANET_ATEND_UNMARSHAL + NULL, /* tostring */ + NULL, /* compare */ + NULL, /* hash */ + peg_next, + JANET_ATEND_NEXT }; /* Convert Builder to JanetPeg (Janet Abstract Value) */ @@ -1641,6 +1646,11 @@ static int cfun_peg_getter(JanetAbstract a, Janet key, Janet *out) { return janet_getmethod(janet_unwrap_keyword(key), peg_methods, out); } +static Janet peg_next(void *p, Janet key) { + (void) p; + return janet_nextmethod(peg_methods, key); +} + static const JanetReg peg_cfuns[] = { { "peg/compile", cfun_peg_compile, diff --git a/src/core/thread.c b/src/core/thread.c index 20fc4d57..9e019013 100644 --- a/src/core/thread.c +++ b/src/core/thread.c @@ -418,13 +418,21 @@ int janet_thread_receive(Janet *msg_out, double timeout) { } static int janet_thread_getter(void *p, Janet key, Janet *out); +static Janet janet_thread_next(void *p, Janet key); const JanetAbstractType janet_thread_type = { "core/thread", thread_gc, thread_mark, janet_thread_getter, - JANET_ATEND_GET + NULL, /* put */ + NULL, /* marshal */ + NULL, /* unmarshal */ + NULL, /* tostring */ + NULL, /* compare */ + NULL, /* hash */ + janet_thread_next, + JANET_ATEND_NEXT }; static JanetThread *janet_make_thread(JanetMailbox *mailbox, JanetTable *encode) { @@ -708,6 +716,11 @@ static int janet_thread_getter(void *p, Janet key, Janet *out) { return janet_getmethod(janet_unwrap_keyword(key), janet_thread_methods, out); } +static Janet janet_thread_next(void *p, Janet key) { + (void) p; + return janet_nextmethod(janet_thread_methods, key); +} + static const JanetReg threadlib_cfuns[] = { { "thread/current", cfun_thread_current, diff --git a/src/include/janet.h b/src/include/janet.h index 740fc7f3..38586820 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1702,6 +1702,7 @@ JANET_API void janet_arity(int32_t arity, int32_t min, int32_t max); JANET_API void janet_fixarity(int32_t arity, int32_t fix); JANET_API int janet_getmethod(JanetKeyword method, const JanetMethod *methods, Janet *out); +JANET_API Janet janet_nextmethod(const JanetMethod *methods, Janet key); JANET_API double janet_getnumber(const Janet *argv, int32_t n); JANET_API JanetArray *janet_getarray(const Janet *argv, int32_t n);