Allow iterating through the properties of core abstract types.

This commit is contained in:
Calvin Rose 2021-01-11 23:14:07 -06:00
parent dfbdd17dce
commit 61cca10cf6
10 changed files with 161 additions and 20 deletions

View File

@ -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 *)

View File

@ -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 ||

View File

@ -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))

View File

@ -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) {

View File

@ -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;

View File

@ -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) {

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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);