diff --git a/src/core/array.c b/src/core/array.c index c697fa97..0c9810c7 100644 --- a/src/core/array.c +++ b/src/core/array.c @@ -122,14 +122,19 @@ Janet janet_array_peek(JanetArray *array) { /* C Functions */ -static Janet cfun_array_new(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_array_new, + "(array/new capacity)", + "Creates a new empty array with a pre-allocated capacity. The same as " + "(array) but can be more efficient if the maximum size of an array is known.") { janet_fixarity(argc, 1); int32_t cap = janet_getinteger(argv, 0); JanetArray *array = janet_array(cap); return janet_wrap_array(array); } -static Janet cfun_array_new_filled(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_array_new_filled, + "(array/new-filled count &opt value)", + "Creates a new array of `count` elements, all set to `value`, which defaults to nil. Returns the new array.") { janet_arity(argc, 1, 2); int32_t count = janet_getinteger(argv, 0); Janet x = (argc == 2) ? argv[1] : janet_wrap_nil(); @@ -141,7 +146,10 @@ static Janet cfun_array_new_filled(int32_t argc, Janet *argv) { return janet_wrap_array(array); } -static Janet cfun_array_fill(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_array_fill, + "(array/fill arr &opt value)", + "Replace all elements of an array with `value` (defaulting to nil) without changing the length of the array. " + "Returns the modified array.") { janet_arity(argc, 1, 2); JanetArray *array = janet_getarray(argv, 0); Janet x = (argc == 2) ? argv[1] : janet_wrap_nil(); @@ -151,19 +159,26 @@ static Janet cfun_array_fill(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_array_pop(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_array_pop, + "(array/pop arr)", + "Remove the last element of the array and return it. If the array is empty, will return nil. Modifies " + "the input array.") { janet_fixarity(argc, 1); JanetArray *array = janet_getarray(argv, 0); return janet_array_pop(array); } -static Janet cfun_array_peek(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_array_peek, + "(array/peek arr)", + "Returns the last element of the array. Does not modify the array.") { janet_fixarity(argc, 1); JanetArray *array = janet_getarray(argv, 0); return janet_array_peek(array); } -static Janet cfun_array_push(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_array_push, + "(array/push arr x)", + "Insert an element in the end of an array. Modifies the input array and returns it.") { janet_arity(argc, 1, -1); JanetArray *array = janet_getarray(argv, 0); if (INT32_MAX - argc + 1 <= array->count) { @@ -176,7 +191,12 @@ static Janet cfun_array_push(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_array_ensure(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_array_ensure, + "(array/ensure arr capacity growth)", + "Ensures that the memory backing the array is large enough for `capacity` " + "items at the given rate of growth. Capacity and growth must be integers. " + "If the backing capacity is already enough, then this function does nothing. " + "Otherwise, the backing memory will be reallocated so that there is enough space.") { janet_fixarity(argc, 3); JanetArray *array = janet_getarray(argv, 0); int32_t newcount = janet_getinteger(argv, 1); @@ -186,7 +206,13 @@ static Janet cfun_array_ensure(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_array_slice(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_array_slice, + "(array/slice arrtup &opt start end)", + "Takes a slice of array or tuple from `start` to `end`. The range is half open, " + "[start, end). Indexes can also be negative, indicating indexing from the " + "end of the array. By default, `start` is 0 and `end` is the length of the array. " + "Note that index -1 is synonymous with index `(length arrtup)` to allow a full " + "negative slice range. Returns a new array.") { JanetView view = janet_getindexed(argv, 0); JanetRange range = janet_getslice(argc, argv); JanetArray *array = janet_array(range.end - range.start); @@ -196,7 +222,12 @@ static Janet cfun_array_slice(int32_t argc, Janet *argv) { return janet_wrap_array(array); } -static Janet cfun_array_concat(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_array_concat, + "(array/concat arr & parts)", + "Concatenates a variable number of arrays (and tuples) into the first argument, " + "which must be an array. If any of the parts are arrays or tuples, their elements will " + "be inserted into the array. Otherwise, each part in `parts` will be appended to `arr` in order. " + "Return the modified array `arr`.") { int32_t i; janet_arity(argc, 1, -1); JanetArray *array = janet_getarray(argv, 0); @@ -219,7 +250,12 @@ static Janet cfun_array_concat(int32_t argc, Janet *argv) { return janet_wrap_array(array); } -static Janet cfun_array_insert(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_array_insert, + "(array/insert arr at & xs)", + "Insert all `xs` into array `arr` at index `at`. `at` should be an integer between " + "0 and the length of the array. A negative value for `at` will index backwards from " + "the end of the array, such that inserting at -1 appends to the array. " + "Returns the array.") { size_t chunksize, restsize; janet_arity(argc, 2, -1); JanetArray *array = janet_getarray(argv, 0); @@ -245,7 +281,12 @@ static Janet cfun_array_insert(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_array_remove(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_array_remove, + "(array/remove arr at &opt n)", + "Remove up to `n` elements starting at index `at` in array `arr`. `at` can index from " + "the end of the array with a negative index, and `n` must be a non-negative integer. " + "By default, `n` is 1. " + "Returns the array.") { janet_arity(argc, 2, 3); JanetArray *array = janet_getarray(argv, 0); int32_t at = janet_getinteger(argv, 1); @@ -270,7 +311,9 @@ static Janet cfun_array_remove(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_array_trim(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_array_trim, + "(array/trim arr)", + "Set the backing capacity of an array to its current length. Returns the modified array.") { janet_fixarity(argc, 1); JanetArray *array = janet_getarray(argv, 0); if (array->count) { @@ -290,103 +333,33 @@ static Janet cfun_array_trim(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_array_clear(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_array_clear, + "(array/clear arr)", + "Empties an array, setting it's count to 0 but does not free the backing capacity. " + "Returns the modified array.") { janet_fixarity(argc, 1); JanetArray *array = janet_getarray(argv, 0); array->count = 0; return argv[0]; } -static const JanetReg array_cfuns[] = { - { - "array/new", cfun_array_new, - JDOC("(array/new capacity)\n\n" - "Creates a new empty array with a pre-allocated capacity. The same as " - "(array) but can be more efficient if the maximum size of an array is known.") - }, - { - "array/new-filled", cfun_array_new_filled, - JDOC("(array/new-filled count &opt value)\n\n" - "Creates a new array of `count` elements, all set to `value`, which defaults to nil. Returns the new array.") - }, - { - "array/fill", cfun_array_fill, - JDOC("(array/fill arr &opt value)\n\n" - "Replace all elements of an array with `value` (defaulting to nil) without changing the length of the array. " - "Returns the modified array.") - }, - { - "array/pop", cfun_array_pop, - JDOC("(array/pop arr)\n\n" - "Remove the last element of the array and return it. If the array is empty, will return nil. Modifies " - "the input array.") - }, - { - "array/peek", cfun_array_peek, - JDOC("(array/peek arr)\n\n" - "Returns the last element of the array. Does not modify the array.") - }, - { - "array/push", cfun_array_push, - JDOC("(array/push arr x)\n\n" - "Insert an element in the end of an array. Modifies the input array and returns it.") - }, - { - "array/ensure", cfun_array_ensure, - JDOC("(array/ensure arr capacity growth)\n\n" - "Ensures that the memory backing the array is large enough for `capacity` " - "items at the given rate of growth. Capacity and growth must be integers. " - "If the backing capacity is already enough, then this function does nothing. " - "Otherwise, the backing memory will be reallocated so that there is enough space.") - }, - { - "array/slice", cfun_array_slice, - JDOC("(array/slice arrtup &opt start end)\n\n" - "Takes a slice of array or tuple from `start` to `end`. The range is half open, " - "[start, end). Indexes can also be negative, indicating indexing from the " - "end of the array. By default, `start` is 0 and `end` is the length of the array. " - "Note that index -1 is synonymous with index `(length arrtup)` to allow a full " - "negative slice range. Returns a new array.") - }, - { - "array/concat", cfun_array_concat, - JDOC("(array/concat arr & parts)\n\n" - "Concatenates a variable number of arrays (and tuples) into the first argument, " - "which must be an array. If any of the parts are arrays or tuples, their elements will " - "be inserted into the array. Otherwise, each part in `parts` will be appended to `arr` in order. " - "Return the modified array `arr`.") - }, - { - "array/insert", cfun_array_insert, - JDOC("(array/insert arr at & xs)\n\n" - "Insert all `xs` into array `arr` at index `at`. `at` should be an integer between " - "0 and the length of the array. A negative value for `at` will index backwards from " - "the end of the array, such that inserting at -1 appends to the array. " - "Returns the array.") - }, - { - "array/remove", cfun_array_remove, - JDOC("(array/remove arr at &opt n)\n\n" - "Remove up to `n` elements starting at index `at` in array `arr`. `at` can index from " - "the end of the array with a negative index, and `n` must be a non-negative integer. " - "By default, `n` is 1. " - "Returns the array.") - }, - { - "array/trim", cfun_array_trim, - JDOC("(array/trim arr)\n\n" - "Set the backing capacity of an array to its current length. Returns the modified array.") - }, - { - "array/clear", cfun_array_clear, - JDOC("(array/clear arr)\n\n" - "Empties an array, setting it's count to 0 but does not free the backing capacity. " - "Returns the modified array.") - }, - {NULL, NULL, NULL} -}; - /* Load the array module */ void janet_lib_array(JanetTable *env) { - janet_core_cfuns(env, NULL, array_cfuns); + JanetRegExt array_cfuns[] = { + JANET_CORE_REG("array/new", cfun_array_new), + JANET_CORE_REG("array/new-filled", cfun_array_new_filled), + JANET_CORE_REG("array/fill", cfun_array_fill), + JANET_CORE_REG("array/pop", cfun_array_pop), + JANET_CORE_REG("array/peek", cfun_array_peek), + JANET_CORE_REG("array/push", cfun_array_push), + JANET_CORE_REG("array/ensure", cfun_array_ensure), + JANET_CORE_REG("array/slice", cfun_array_slice), + JANET_CORE_REG("array/concat", cfun_array_concat), + JANET_CORE_REG("array/insert", cfun_array_insert), + JANET_CORE_REG("array/remove", cfun_array_remove), + JANET_CORE_REG("array/trim", cfun_array_trim), + JANET_CORE_REG("array/clear", cfun_array_clear), + JANET_REG_END + }; + janet_core_cfuns_ext(env, NULL, array_cfuns); } diff --git a/src/core/buffer.c b/src/core/buffer.c index 4747c4eb..802051f1 100644 --- a/src/core/buffer.c +++ b/src/core/buffer.c @@ -162,14 +162,20 @@ void janet_buffer_push_u64(JanetBuffer *buffer, uint64_t x) { /* C functions */ -static Janet cfun_buffer_new(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_new, + "(buffer/new capacity)", + "Creates a new, empty buffer with enough backing memory for capacity bytes. " + "Returns a new buffer of length 0.") { janet_fixarity(argc, 1); int32_t cap = janet_getinteger(argv, 0); JanetBuffer *buffer = janet_buffer(cap); return janet_wrap_buffer(buffer); } -static Janet cfun_buffer_new_filled(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_new_filled, + "(buffer/new-filled count &opt byte)", + "Creates a new buffer of length count filled with byte. By default, byte is 0. " + "Returns the new buffer.") { janet_arity(argc, 1, 2); int32_t count = janet_getinteger(argv, 0); int32_t byte = 0; @@ -183,7 +189,10 @@ static Janet cfun_buffer_new_filled(int32_t argc, Janet *argv) { return janet_wrap_buffer(buffer); } -static Janet cfun_buffer_fill(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_fill, + "(buffer/fill buffer &opt byte)", + "Fill up a buffer with bytes, defaulting to 0s. Does not change the buffer's length. " + "Returns the modified buffer.") { janet_arity(argc, 1, 2); JanetBuffer *buffer = janet_getbuffer(argv, 0); int32_t byte = 0; @@ -196,7 +205,10 @@ static Janet cfun_buffer_fill(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_buffer_trim(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_trim, + "(buffer/trim buffer)", + "Set the backing capacity of the buffer to the current length of the buffer. Returns the " + "modified buffer.") { janet_fixarity(argc, 1); JanetBuffer *buffer = janet_getbuffer(argv, 0); if (buffer->count < buffer->capacity) { @@ -211,7 +223,10 @@ static Janet cfun_buffer_trim(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_buffer_u8(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_u8, + "(buffer/push-byte buffer & xs)", + "Append bytes to a buffer. Will expand the buffer as necessary. " + "Returns the modified buffer. Will throw an error if the buffer overflows.") { int32_t i; janet_arity(argc, 1, -1); JanetBuffer *buffer = janet_getbuffer(argv, 0); @@ -221,7 +236,11 @@ static Janet cfun_buffer_u8(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_buffer_word(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_word, + "(buffer/push-word buffer & xs)", + "Append machine words to a buffer. The 4 bytes of the integer are appended " + "in twos complement, little endian order, unsigned for all x. Returns the modified buffer. Will " + "throw an error if the buffer overflows.") { int32_t i; janet_arity(argc, 1, -1); JanetBuffer *buffer = janet_getbuffer(argv, 0); @@ -235,7 +254,12 @@ static Janet cfun_buffer_word(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_buffer_chars(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_chars, + "(buffer/push-string buffer & xs)", + "Push byte sequences onto the end of a buffer. " + "Will accept any of strings, keywords, symbols, and buffers. " + "Returns the modified buffer. " + "Will throw an error if the buffer overflows.") { int32_t i; janet_arity(argc, 1, -1); JanetBuffer *buffer = janet_getbuffer(argv, 0); @@ -250,7 +274,13 @@ static Janet cfun_buffer_chars(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_buffer_push(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_push, + "(buffer/push buffer & xs)", + "Push both individual bytes and byte sequences to a buffer. For each x in xs, " + "push the byte if x is an integer, otherwise push the bytesequence to the buffer. " + "Thus, this function behaves like both `buffer/push-string` and `buffer/push-byte`. " + "Returns the modified buffer. " + "Will throw an error if the buffer overflows.") { int32_t i; janet_arity(argc, 1, -1); JanetBuffer *buffer = janet_getbuffer(argv, 0); @@ -270,14 +300,19 @@ static Janet cfun_buffer_push(int32_t argc, Janet *argv) { } -static Janet cfun_buffer_clear(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_clear, + "(buffer/clear buffer)", + "Sets the size of a buffer to 0 and empties it. The buffer retains " + "its memory so it can be efficiently refilled. Returns the modified buffer.") { janet_fixarity(argc, 1); JanetBuffer *buffer = janet_getbuffer(argv, 0); buffer->count = 0; return argv[0]; } -static Janet cfun_buffer_popn(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_popn, + "(buffer/popn buffer n)", + "Removes the last n bytes from the buffer. Returns the modified buffer.") { janet_fixarity(argc, 2); JanetBuffer *buffer = janet_getbuffer(argv, 0); int32_t n = janet_getinteger(argv, 1); @@ -290,7 +325,12 @@ static Janet cfun_buffer_popn(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_buffer_slice(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_slice, + "(buffer/slice bytes &opt start end)", + "Takes a slice of a byte sequence from start to end. The range is half open, " + "[start, end). Indexes can also be negative, indicating indexing from the end of the " + "end of the array. By default, start is 0 and end is the length of the buffer. " + "Returns a new buffer.") { JanetByteView view = janet_getbytes(argv, 0); JanetRange range = janet_getslice(argc, argv); JanetBuffer *buffer = janet_buffer(range.end - range.start); @@ -314,7 +354,9 @@ static void bitloc(int32_t argc, Janet *argv, JanetBuffer **b, int32_t *index, i *bit = which_bit; } -static Janet cfun_buffer_bitset(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_bitset, + "(buffer/bit-set buffer index)", + "Sets the bit at the given bit-index. Returns the buffer.") { int bit; int32_t index; JanetBuffer *buffer; @@ -323,7 +365,9 @@ static Janet cfun_buffer_bitset(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_buffer_bitclear(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_bitclear, + "(buffer/bit-clear buffer index)", + "Clears the bit at the given bit-index. Returns the buffer.") { int bit; int32_t index; JanetBuffer *buffer; @@ -332,7 +376,9 @@ static Janet cfun_buffer_bitclear(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_buffer_bitget(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_bitget, + "(buffer/bit buffer index)", + "Gets the bit at the given bit-index. Returns true if the bit is set, false if not.") { int bit; int32_t index; JanetBuffer *buffer; @@ -340,7 +386,9 @@ static Janet cfun_buffer_bitget(int32_t argc, Janet *argv) { return janet_wrap_boolean(buffer->data[index] & (1 << bit)); } -static Janet cfun_buffer_bittoggle(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_bittoggle, + "(buffer/bit-toggle buffer index)", + "Toggles the bit at the given bit index in buffer. Returns the buffer.") { int bit; int32_t index; JanetBuffer *buffer; @@ -349,7 +397,11 @@ static Janet cfun_buffer_bittoggle(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_buffer_blit(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_blit, + "(buffer/blit dest src &opt dest-start src-start src-end)", + "Insert the contents of src into dest. Can optionally take indices that " + "indicate which part of src to copy into which part of dest. Indices can be " + "negative to index from the end of src or dest. Returns dest.") { janet_arity(argc, 2, 5); JanetBuffer *dest = janet_getbuffer(argv, 0); JanetByteView src = janet_getbytes(argv, 1); @@ -386,7 +438,10 @@ static Janet cfun_buffer_blit(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_buffer_format(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_buffer_format, + "(buffer/format buffer format & args)", + "Snprintf like functionality for printing values into a buffer. Returns " + " the modified buffer.") { janet_arity(argc, 2, -1); JanetBuffer *buffer = janet_getbuffer(argv, 0); const char *strfrmt = (const char *) janet_getstring(argv, 1); @@ -394,116 +449,26 @@ static Janet cfun_buffer_format(int32_t argc, Janet *argv) { return argv[0]; } -static const JanetReg buffer_cfuns[] = { - { - "buffer/new", cfun_buffer_new, - JDOC("(buffer/new capacity)\n\n" - "Creates a new, empty buffer with enough backing memory for capacity bytes. " - "Returns a new buffer of length 0.") - }, - { - "buffer/new-filled", cfun_buffer_new_filled, - JDOC("(buffer/new-filled count &opt byte)\n\n" - "Creates a new buffer of length count filled with byte. By default, byte is 0. " - "Returns the new buffer.") - }, - { - "buffer/fill", cfun_buffer_fill, - JDOC("(buffer/fill buffer &opt byte)\n\n" - "Fill up a buffer with bytes, defaulting to 0s. Does not change the buffer's length. " - "Returns the modified buffer.") - }, - { - "buffer/trim", cfun_buffer_trim, - JDOC("(buffer/trim buffer)\n\n" - "Set the backing capacity of the buffer to the current length of the buffer. Returns the " - "modified buffer.") - }, - { - "buffer/push-byte", cfun_buffer_u8, - JDOC("(buffer/push-byte buffer & xs)\n\n" - "Append bytes to a buffer. Will expand the buffer as necessary. " - "Returns the modified buffer. Will throw an error if the buffer overflows.") - }, - { - "buffer/push-word", cfun_buffer_word, - JDOC("(buffer/push-word buffer & xs)\n\n" - "Append machine words to a buffer. The 4 bytes of the integer are appended " - "in twos complement, little endian order, unsigned for all x. Returns the modified buffer. Will " - "throw an error if the buffer overflows.") - }, - { - "buffer/push-string", cfun_buffer_chars, - JDOC("(buffer/push-string buffer & xs)\n\n" - "Push byte sequences onto the end of a buffer. " - "Will accept any of strings, keywords, symbols, and buffers. " - "Returns the modified buffer. " - "Will throw an error if the buffer overflows.") - }, - { - "buffer/push", cfun_buffer_push, - JDOC("(buffer/push buffer & xs)\n\n" - "Push both individual bytes and byte sequences to a buffer. For each x in xs, " - "push the byte if x is an integer, otherwise push the bytesequence to the buffer. " - "Thus, this function behaves like both `buffer/push-string` and `buffer/push-byte`. " - "Returns the modified buffer. " - "Will throw an error if the buffer overflows.") - }, - { - "buffer/popn", cfun_buffer_popn, - JDOC("(buffer/popn buffer n)\n\n" - "Removes the last n bytes from the buffer. Returns the modified buffer.") - }, - { - "buffer/clear", cfun_buffer_clear, - JDOC("(buffer/clear buffer)\n\n" - "Sets the size of a buffer to 0 and empties it. The buffer retains " - "its memory so it can be efficiently refilled. Returns the modified buffer.") - }, - { - "buffer/slice", cfun_buffer_slice, - JDOC("(buffer/slice bytes &opt start end)\n\n" - "Takes a slice of a byte sequence from start to end. The range is half open, " - "[start, end). Indexes can also be negative, indicating indexing from the end of the " - "end of the array. By default, start is 0 and end is the length of the buffer. " - "Returns a new buffer.") - }, - { - "buffer/bit-set", cfun_buffer_bitset, - JDOC("(buffer/bit-set buffer index)\n\n" - "Sets the bit at the given bit-index. Returns the buffer.") - }, - { - "buffer/bit-clear", cfun_buffer_bitclear, - JDOC("(buffer/bit-clear buffer index)\n\n" - "Clears the bit at the given bit-index. Returns the buffer.") - }, - { - "buffer/bit", cfun_buffer_bitget, - JDOC("(buffer/bit buffer index)\n\n" - "Gets the bit at the given bit-index. Returns true if the bit is set, false if not.") - }, - { - "buffer/bit-toggle", cfun_buffer_bittoggle, - JDOC("(buffer/bit-toggle buffer index)\n\n" - "Toggles the bit at the given bit index in buffer. Returns the buffer.") - }, - { - "buffer/blit", cfun_buffer_blit, - JDOC("(buffer/blit dest src &opt dest-start src-start src-end)\n\n" - "Insert the contents of src into dest. Can optionally take indices that " - "indicate which part of src to copy into which part of dest. Indices can be " - "negative to index from the end of src or dest. Returns dest.") - }, - { - "buffer/format", cfun_buffer_format, - JDOC("(buffer/format buffer format & args)\n\n" - "Snprintf like functionality for printing values into a buffer. Returns " - " the modified buffer.") - }, - {NULL, NULL, NULL} -}; - void janet_lib_buffer(JanetTable *env) { - janet_core_cfuns(env, NULL, buffer_cfuns); + JanetRegExt buffer_cfuns[] = { + JANET_CORE_REG("buffer/new", cfun_buffer_new), + JANET_CORE_REG("buffer/new-filled", cfun_buffer_new_filled), + JANET_CORE_REG("buffer/fill", cfun_buffer_fill), + JANET_CORE_REG("buffer/trim", cfun_buffer_trim), + JANET_CORE_REG("buffer/push-byte", cfun_buffer_u8), + JANET_CORE_REG("buffer/push-word", cfun_buffer_word), + JANET_CORE_REG("buffer/push-string", cfun_buffer_chars), + JANET_CORE_REG("buffer/push", cfun_buffer_push), + JANET_CORE_REG("buffer/popn", cfun_buffer_popn), + JANET_CORE_REG("buffer/clear", cfun_buffer_clear), + JANET_CORE_REG("buffer/slice", cfun_buffer_slice), + JANET_CORE_REG("buffer/bit-set", cfun_buffer_bitset), + JANET_CORE_REG("buffer/bit-clear", cfun_buffer_bitclear), + JANET_CORE_REG("buffer/bit", cfun_buffer_bitget), + JANET_CORE_REG("buffer/bit-toggle", cfun_buffer_bittoggle), + JANET_CORE_REG("buffer/blit", cfun_buffer_blit), + JANET_CORE_REG("buffer/format", cfun_buffer_format), + JANET_REG_END + }; + janet_core_cfuns_ext(env, NULL, buffer_cfuns); } diff --git a/src/core/corelib.c b/src/core/corelib.c index 063c77c5..e05ace40 100644 --- a/src/core/corelib.c +++ b/src/core/corelib.c @@ -143,7 +143,18 @@ static int is_path_sep(char c) { } /* Used for module system. */ -static Janet janet_core_expand_path(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_expand_path, + "(module/expand-path path template)", + "Expands a path template as found in `module/paths` for `module/find`. " + "This takes in a path (the argument to require) and a template string, " + "to expand the path to a path that can be " + "used for importing files. The replacements are as follows:\n\n" + "* :all: -- the value of path verbatim\n\n" + "* :cur: -- the current file, or (dyn :current-file)\n\n" + "* :dir: -- the directory containing the current file\n\n" + "* :name: -- the name component of path, with extension if given\n\n" + "* :native: -- the extension used to load natives, .so or .dll\n\n" + "* :sys: -- the system path, or (dyn :syspath)") { janet_fixarity(argc, 2); const char *input = janet_getcstring(argv, 0); const char *template = janet_getcstring(argv, 1); @@ -266,7 +277,9 @@ static Janet janet_core_expand_path(int32_t argc, Janet *argv) { return janet_wrap_buffer(out); } -static Janet janet_core_dyn(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_dyn, + "(dyn key &opt default)", + "Get a dynamic binding. Returns the default value (or nil) if no binding found.") { janet_arity(argc, 1, 2); Janet value; if (janet_vm.fiber->env) { @@ -280,7 +293,9 @@ static Janet janet_core_dyn(int32_t argc, Janet *argv) { return value; } -static Janet janet_core_setdyn(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_setdyn, + "(setdyn key value)", + "Set a dynamic binding. Returns value.") { janet_fixarity(argc, 2); if (!janet_vm.fiber->env) { janet_vm.fiber->env = janet_table(2); @@ -289,7 +304,13 @@ static Janet janet_core_setdyn(int32_t argc, Janet *argv) { return argv[1]; } -static Janet janet_core_native(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_native, + "(native path &opt env)", + "Load a native module from the given path. The path " + "must be an absolute or relative path on the file system, and is " + "usually a .so file on Unix systems, and a .dll file on Windows. " + "Returns an environment table that contains functions and other values " + "from the native module.") { JanetModule init; janet_arity(argc, 1, 2); const uint8_t *path = janet_getstring(argv, 0); @@ -309,47 +330,72 @@ static Janet janet_core_native(int32_t argc, Janet *argv) { return janet_wrap_table(env); } -static Janet janet_core_describe(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_describe, + "(describe x)", + "Returns a string that is a human-readable description of a value x.") { JanetBuffer *b = janet_buffer(0); for (int32_t i = 0; i < argc; ++i) janet_description_b(b, argv[i]); return janet_stringv(b->data, b->count); } -static Janet janet_core_string(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_string, + "(string & xs)", + "Creates a string by concatenating the elements of `xs` together. If an " + "element is not a byte sequence, it is converted to bytes via `describe`. " + "Returns the new string.") { JanetBuffer *b = janet_buffer(0); for (int32_t i = 0; i < argc; ++i) janet_to_string_b(b, argv[i]); return janet_stringv(b->data, b->count); } -static Janet janet_core_symbol(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_symbol, + "(symbol & xs)", + "Creates a symbol by concatenating the elements of `xs` together. If an " + "element is not a byte sequence, it is converted to bytes via `describe`. " + "Returns the new symbol.") { JanetBuffer *b = janet_buffer(0); for (int32_t i = 0; i < argc; ++i) janet_to_string_b(b, argv[i]); return janet_symbolv(b->data, b->count); } -static Janet janet_core_keyword(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_keyword, + "(keyword & xs)", + "Creates a keyword by concatenating the elements of `xs` together. If an " + "element is not a byte sequence, it is converted to bytes via `describe`. " + "Returns the new keyword.") { JanetBuffer *b = janet_buffer(0); for (int32_t i = 0; i < argc; ++i) janet_to_string_b(b, argv[i]); return janet_keywordv(b->data, b->count); } -static Janet janet_core_buffer(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_buffer, + "(buffer & xs)", + "Creates a buffer by concatenating the elements of `xs` together. If an " + "element is not a byte sequence, it is converted to bytes via `describe`. " + "Returns the new buffer.") { JanetBuffer *b = janet_buffer(0); for (int32_t i = 0; i < argc; ++i) janet_to_string_b(b, argv[i]); return janet_wrap_buffer(b); } -static Janet janet_core_is_abstract(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_is_abstract, + "(abstract? x)", + "Check if x is an abstract type.") { janet_fixarity(argc, 1); return janet_wrap_boolean(janet_checktype(argv[0], JANET_ABSTRACT)); } -static Janet janet_core_scannumber(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_scannumber, + "(scan-number str)", + "Parse a number from a byte sequence an return that number, either and integer " + "or a real. The number " + "must be in the same format as numbers in janet source code. Will return nil " + "on an invalid number.") { double number; janet_fixarity(argc, 1); JanetByteView view = janet_getbytes(argv, 0); @@ -358,18 +404,24 @@ static Janet janet_core_scannumber(int32_t argc, Janet *argv) { return janet_wrap_number(number); } -static Janet janet_core_tuple(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_tuple, + "(tuple & items)", + "Creates a new tuple that contains items. Returns the new tuple.") { return janet_wrap_tuple(janet_tuple_n(argv, argc)); } -static Janet janet_core_array(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_array, + "(array & items)", + "Create a new array that contains items. Returns the new array.") { JanetArray *array = janet_array(argc); array->count = argc; safe_memcpy(array->data, argv, argc * sizeof(Janet)); return janet_wrap_array(array); } -static Janet janet_core_slice(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_slice, + "(slice x &opt start end)", + "Extract a sub-range of an indexed data structure or byte sequence.") { JanetRange range; JanetByteView bview; JanetView iview; @@ -384,7 +436,12 @@ static Janet janet_core_slice(int32_t argc, Janet *argv) { } } -static Janet janet_core_table(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_table, + "(table & kvs)", + "Creates a new table from a variadic number of keys and values. " + "kvs is a sequence k1, v1, k2, v2, k3, v3, ... If kvs has " + "an odd number of elements, an error will be thrown. Returns the " + "new table.") { int32_t i; if (argc & 1) janet_panic("expected even number of arguments"); @@ -395,7 +452,12 @@ static Janet janet_core_table(int32_t argc, Janet *argv) { return janet_wrap_table(table); } -static Janet janet_core_struct(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_struct, + "(struct & kvs)", + "Create a new struct from a sequence of key value pairs. " + "kvs is a sequence k1, v1, k2, v2, k3, v3, ... If kvs has " + "an odd number of elements, an error will be thrown. Returns the " + "new struct.") { int32_t i; if (argc & 1) janet_panic("expected even number of arguments"); @@ -406,20 +468,30 @@ static Janet janet_core_struct(int32_t argc, Janet *argv) { return janet_wrap_struct(janet_struct_end(st)); } -static Janet janet_core_gensym(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_gensym, + "(gensym)", + "Returns a new symbol that is unique across the runtime. This means it " + "will not collide with any already created symbols during compilation, so " + "it can be used in macros to generate automatic bindings.") { (void) argv; janet_fixarity(argc, 0); return janet_wrap_symbol(janet_symbol_gen()); } -static Janet janet_core_gccollect(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_gccollect, + "(gccollect)", + "Run garbage collection. You should probably not call this manually.") { (void) argv; (void) argc; janet_collect(); return janet_wrap_nil(); } -static Janet janet_core_gcsetinterval(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_gcsetinterval, + "(gcsetinterval interval)", + "Set an integer number of bytes to allocate before running garbage collection. " + "Low values for interval will be slower but use less memory. " + "High values will be faster but use more memory.") { janet_fixarity(argc, 1); size_t s = janet_getsize(argv, 0); /* limit interval to 48 bits */ @@ -432,13 +504,33 @@ static Janet janet_core_gcsetinterval(int32_t argc, Janet *argv) { return janet_wrap_nil(); } -static Janet janet_core_gcinterval(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_gcinterval, + "(gcinterval)", + "Returns the integer number of bytes to allocate before running an iteration " + "of garbage collection.") { (void) argv; janet_fixarity(argc, 0); return janet_wrap_number((double) janet_vm.gc_interval); } -static Janet janet_core_type(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_type, + "(type x)", + "Returns the type of `x` as a keyword. `x` is one of:\n\n" + "* :nil\n\n" + "* :boolean\n\n" + "* :number\n\n" + "* :array\n\n" + "* :tuple\n\n" + "* :table\n\n" + "* :struct\n\n" + "* :string\n\n" + "* :buffer\n\n" + "* :symbol\n\n" + "* :keyword\n\n" + "* :function\n\n" + "* :cfunction\n\n" + "* :fiber\n\n" + "or another keyword for an abstract type.") { janet_fixarity(argc, 1); JanetType t = janet_type(argv[0]); if (t == JANET_ABSTRACT) { @@ -448,12 +540,21 @@ static Janet janet_core_type(int32_t argc, Janet *argv) { } } -static Janet janet_core_hash(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_hash, + "(hash value)", + "Gets a hash for any value. The hash is an integer can be used " + "as a cheap hash function for all values. If two values are strictly equal, " + "then they will have the same hash value.") { janet_fixarity(argc, 1); return janet_wrap_number(janet_hash(argv[0])); } -static Janet janet_core_getline(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_getline, + "(getline &opt prompt buf env)", + "Reads a line of input into a buffer, including the newline character, using a prompt. " + "An optional environment table can be provided for auto-complete. " + "Returns the modified buffer. " + "Use this function to implement a simple interface for a terminal program.") { FILE *in = janet_dynfile("in", stdin); FILE *out = janet_dynfile("out", stdout); janet_arity(argc, 0, 3); @@ -478,21 +579,27 @@ static Janet janet_core_getline(int32_t argc, Janet *argv) { return janet_wrap_buffer(buf); } -static Janet janet_core_trace(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_trace, + "(trace func)", + "Enable tracing on a function. Returns the function.") { janet_fixarity(argc, 1); JanetFunction *func = janet_getfunction(argv, 0); func->gc.flags |= JANET_FUNCFLAG_TRACE; return argv[0]; } -static Janet janet_core_untrace(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_untrace, + "(untrace func)", + "Disables tracing on a function. Returns the function.") { janet_fixarity(argc, 1); JanetFunction *func = janet_getfunction(argv, 0); func->gc.flags &= ~JANET_FUNCFLAG_TRACE; return argv[0]; } -static Janet janet_core_check_int(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_check_int, + "(int? x)", + "Check if x can be exactly represented as a 32 bit signed two's complement integer.") { janet_fixarity(argc, 1); if (!janet_checktype(argv[0], JANET_NUMBER)) goto ret_false; double num = janet_unwrap_number(argv[0]); @@ -501,7 +608,9 @@ ret_false: return janet_wrap_false(); } -static Janet janet_core_check_nat(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_check_nat, + "(nat? x)", + "Check if x can be exactly represented as a non-negative 32 bit signed two's complement integer.") { janet_fixarity(argc, 1); if (!janet_checktype(argv[0], JANET_NUMBER)) goto ret_false; double num = janet_unwrap_number(argv[0]); @@ -510,7 +619,9 @@ ret_false: return janet_wrap_false(); } -static Janet janet_core_signal(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_core_signal, + "(signal what x)", + "Raise a signal with payload x. ") { janet_arity(argc, 1, 2); int sig; if (janet_checkint(argv[0])) { @@ -535,205 +646,6 @@ static Janet janet_core_signal(int32_t argc, Janet *argv) { janet_signalv(sig, payload); } -static const JanetReg corelib_cfuns[] = { - { - "native", janet_core_native, - JDOC("(native path &opt env)\n\n" - "Load a native module from the given path. The path " - "must be an absolute or relative path on the file system, and is " - "usually a .so file on Unix systems, and a .dll file on Windows. " - "Returns an environment table that contains functions and other values " - "from the native module.") - }, - { - "describe", janet_core_describe, - JDOC("(describe x)\n\n" - "Returns a string that is a human-readable description of a value x.") - }, - { - "string", janet_core_string, - JDOC("(string & xs)\n\n" - "Creates a string by concatenating the elements of `xs` together. If an " - "element is not a byte sequence, it is converted to bytes via `describe`. " - "Returns the new string.") - }, - { - "symbol", janet_core_symbol, - JDOC("(symbol & xs)\n\n" - "Creates a symbol by concatenating the elements of `xs` together. If an " - "element is not a byte sequence, it is converted to bytes via `describe`. " - "Returns the new symbol.") - }, - { - "keyword", janet_core_keyword, - JDOC("(keyword & xs)\n\n" - "Creates a keyword by concatenating the elements of `xs` together. If an " - "element is not a byte sequence, it is converted to bytes via `describe`. " - "Returns the new keyword.") - }, - { - "buffer", janet_core_buffer, - JDOC("(buffer & xs)\n\n" - "Creates a buffer by concatenating the elements of `xs` together. If an " - "element is not a byte sequence, it is converted to bytes via `describe`. " - "Returns the new buffer.") - }, - { - "abstract?", janet_core_is_abstract, - JDOC("(abstract? x)\n\n" - "Check if x is an abstract type.") - }, - { - "table", janet_core_table, - JDOC("(table & kvs)\n\n" - "Creates a new table from a variadic number of keys and values. " - "kvs is a sequence k1, v1, k2, v2, k3, v3, ... If kvs has " - "an odd number of elements, an error will be thrown. Returns the " - "new table.") - }, - { - "array", janet_core_array, - JDOC("(array & items)\n\n" - "Create a new array that contains items. Returns the new array.") - }, - { - "scan-number", janet_core_scannumber, - JDOC("(scan-number str)\n\n" - "Parse a number from a byte sequence an return that number, either and integer " - "or a real. The number " - "must be in the same format as numbers in janet source code. Will return nil " - "on an invalid number.") - }, - { - "tuple", janet_core_tuple, - JDOC("(tuple & items)\n\n" - "Creates a new tuple that contains items. Returns the new tuple.") - }, - { - "struct", janet_core_struct, - JDOC("(struct & kvs)\n\n" - "Create a new struct from a sequence of key value pairs. " - "kvs is a sequence k1, v1, k2, v2, k3, v3, ... If kvs has " - "an odd number of elements, an error will be thrown. Returns the " - "new struct.") - }, - { - "gensym", janet_core_gensym, - JDOC("(gensym)\n\n" - "Returns a new symbol that is unique across the runtime. This means it " - "will not collide with any already created symbols during compilation, so " - "it can be used in macros to generate automatic bindings.") - }, - { - "gccollect", janet_core_gccollect, - JDOC("(gccollect)\n\n" - "Run garbage collection. You should probably not call this manually.") - }, - { - "gcsetinterval", janet_core_gcsetinterval, - JDOC("(gcsetinterval interval)\n\n" - "Set an integer number of bytes to allocate before running garbage collection. " - "Low values for interval will be slower but use less memory. " - "High values will be faster but use more memory.") - }, - { - "gcinterval", janet_core_gcinterval, - JDOC("(gcinterval)\n\n" - "Returns the integer number of bytes to allocate before running an iteration " - "of garbage collection.") - }, - { - "type", janet_core_type, - JDOC("(type x)\n\n" - "Returns the type of `x` as a keyword. `x` is one of:\n\n" - "* :nil\n\n" - "* :boolean\n\n" - "* :number\n\n" - "* :array\n\n" - "* :tuple\n\n" - "* :table\n\n" - "* :struct\n\n" - "* :string\n\n" - "* :buffer\n\n" - "* :symbol\n\n" - "* :keyword\n\n" - "* :function\n\n" - "* :cfunction\n\n" - "* :fiber\n\n" - "or another keyword for an abstract type.") - }, - { - "hash", janet_core_hash, - JDOC("(hash value)\n\n" - "Gets a hash for any value. The hash is an integer can be used " - "as a cheap hash function for all values. If two values are strictly equal, " - "then they will have the same hash value.") - }, - { - "getline", janet_core_getline, - JDOC("(getline &opt prompt buf env)\n\n" - "Reads a line of input into a buffer, including the newline character, using a prompt. " - "An optional environment table can be provided for auto-complete. " - "Returns the modified buffer. " - "Use this function to implement a simple interface for a terminal program.") - }, - { - "dyn", janet_core_dyn, - JDOC("(dyn key &opt default)\n\n" - "Get a dynamic binding. Returns the default value (or nil) if no binding found.") - }, - { - "setdyn", janet_core_setdyn, - JDOC("(setdyn key value)\n\n" - "Set a dynamic binding. Returns value.") - }, - { - "trace", janet_core_trace, - JDOC("(trace func)\n\n" - "Enable tracing on a function. Returns the function.") - }, - { - "untrace", janet_core_untrace, - JDOC("(untrace func)\n\n" - "Disables tracing on a function. Returns the function.") - }, - { - "module/expand-path", janet_core_expand_path, - JDOC("(module/expand-path path template)\n\n" - "Expands a path template as found in `module/paths` for `module/find`. " - "This takes in a path (the argument to require) and a template string, " - "to expand the path to a path that can be " - "used for importing files. The replacements are as follows:\n\n" - "* :all: -- the value of path verbatim\n\n" - "* :cur: -- the current file, or (dyn :current-file)\n\n" - "* :dir: -- the directory containing the current file\n\n" - "* :name: -- the name component of path, with extension if given\n\n" - "* :native: -- the extension used to load natives, .so or .dll\n\n" - "* :sys: -- the system path, or (dyn :syspath)") - }, - { - "int?", janet_core_check_int, - JDOC("(int? x)\n\n" - "Check if x can be exactly represented as a 32 bit signed two's complement integer.") - }, - { - "nat?", janet_core_check_nat, - JDOC("(nat? x)\n\n" - "Check if x can be exactly represented as a non-negative 32 bit signed two's complement integer.") - }, - { - "slice", janet_core_slice, - JDOC("(slice x &opt start end)\n\n" - "Extract a sub-range of an indexed data structure or byte sequence.") - }, - { - "signal", janet_core_signal, - JDOC("(signal what x)\n\n" - "Raise a signal with payload x. ") - }, - {NULL, NULL, NULL} -}; - #ifdef JANET_BOOTSTRAP /* Utility for inline assembly */ @@ -1006,7 +918,38 @@ static const uint32_t cmp_asm[] = { */ static void janet_load_libs(JanetTable *env) { - janet_core_cfuns(env, NULL, corelib_cfuns); + JanetRegExt corelib_cfuns[] = { + JANET_CORE_REG("native", janet_core_native), + JANET_CORE_REG("describe", janet_core_describe), + JANET_CORE_REG("string", janet_core_string), + JANET_CORE_REG("symbol", janet_core_symbol), + JANET_CORE_REG("keyword", janet_core_keyword), + JANET_CORE_REG("buffer", janet_core_buffer), + JANET_CORE_REG("abstract?", janet_core_is_abstract), + JANET_CORE_REG("table", janet_core_table), + JANET_CORE_REG("array", janet_core_array), + JANET_CORE_REG("scan-number", janet_core_scannumber), + JANET_CORE_REG("tuple", janet_core_tuple), + JANET_CORE_REG("struct", janet_core_struct), + JANET_CORE_REG("gensym", janet_core_gensym), + JANET_CORE_REG("gccollect", janet_core_gccollect), + JANET_CORE_REG("gcsetinterval", janet_core_gcsetinterval), + JANET_CORE_REG("gcinterval", janet_core_gcinterval), + JANET_CORE_REG("type", janet_core_type), + JANET_CORE_REG("hash", janet_core_hash), + JANET_CORE_REG("getline", janet_core_getline), + JANET_CORE_REG("dyn", janet_core_dyn), + JANET_CORE_REG("setdyn", janet_core_setdyn), + JANET_CORE_REG("trace", janet_core_trace), + JANET_CORE_REG("untrace", janet_core_untrace), + JANET_CORE_REG("module/expand-path", janet_core_expand_path), + JANET_CORE_REG("int?", janet_core_check_int), + JANET_CORE_REG("nat?", janet_core_check_nat), + JANET_CORE_REG("slice", janet_core_slice), + JANET_CORE_REG("signal", janet_core_signal), + JANET_REG_END + }; + janet_core_cfuns_ext(env, NULL, corelib_cfuns); janet_lib_io(env); janet_lib_math(env); janet_lib_array(env); diff --git a/src/core/debug.c b/src/core/debug.c index ff4b55f8..e1047035 100644 --- a/src/core/debug.c +++ b/src/core/debug.c @@ -195,7 +195,13 @@ static void helper_find_fun(int32_t argc, Janet *argv, JanetFuncDef **def, int32 *bytecode_offset = offset; } -static Janet cfun_debug_break(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_debug_break, + "(debug/break source line col)", + "Sets a breakpoint in `source` at a given line and column. " + "Will throw an error if the breakpoint location " + "cannot be found. For example\n\n" + "\t(debug/break \"core.janet\" 10 4)\n\n" + "will set a breakpoint at line 10, 4th column of the file core.janet.") { JanetFuncDef *def; int32_t offset; helper_find(argc, argv, &def, &offset); @@ -203,7 +209,11 @@ static Janet cfun_debug_break(int32_t argc, Janet *argv) { return janet_wrap_nil(); } -static Janet cfun_debug_unbreak(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_debug_unbreak, + "(debug/unbreak source line column)", + "Remove a breakpoint with a source key at a given line and column. " + "Will throw an error if the breakpoint " + "cannot be found.") { JanetFuncDef *def; int32_t offset = 0; helper_find(argc, argv, &def, &offset); @@ -211,7 +221,11 @@ static Janet cfun_debug_unbreak(int32_t argc, Janet *argv) { return janet_wrap_nil(); } -static Janet cfun_debug_fbreak(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_debug_fbreak, + "(debug/fbreak fun &opt pc)", + "Set a breakpoint in a given function. pc is an optional offset, which " + "is in bytecode instructions. fun is a function value. Will throw an error " + "if the offset is too large or negative.") { JanetFuncDef *def; int32_t offset = 0; helper_find_fun(argc, argv, &def, &offset); @@ -219,7 +233,9 @@ static Janet cfun_debug_fbreak(int32_t argc, Janet *argv) { return janet_wrap_nil(); } -static Janet cfun_debug_unfbreak(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_debug_unfbreak, + "(debug/unfbreak fun &opt pc)", + "Unset a breakpoint set with debug/fbreak.") { JanetFuncDef *def; int32_t offset; helper_find_fun(argc, argv, &def, &offset); @@ -227,7 +243,12 @@ static Janet cfun_debug_unfbreak(int32_t argc, Janet *argv) { return janet_wrap_nil(); } -static Janet cfun_debug_lineage(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_debug_lineage, + "(debug/lineage fib)", + "Returns an array of all child fibers from a root fiber. This function " + "is useful when a fiber signals or errors to an ancestor fiber. Using this function, " + "the fiber handling the error can see which fiber raised the signal. This function should " + "be used mostly for debugging purposes.") { janet_fixarity(argc, 1); JanetFiber *fiber = janet_getfiber(argv, 0); JanetArray *array = janet_array(0); @@ -284,7 +305,21 @@ static Janet doframe(JanetStackFrame *frame) { return janet_wrap_table(t); } -static Janet cfun_debug_stack(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_debug_stack, + "(debug/stack fib)", + "Gets information about the stack as an array of tables. Each table " + "in the array contains information about a stack frame. The top-most, current " + "stack frame is the first table in the array, and the bottom-most stack frame " + "is the last value. Each stack frame contains some of the following attributes:\n\n" + "* :c - true if the stack frame is a c function invocation\n\n" + "* :column - the current source column of the stack frame\n\n" + "* :function - the function that the stack frame represents\n\n" + "* :line - the current source line of the stack frame\n\n" + "* :name - the human-friendly name of the function\n\n" + "* :pc - integer indicating the location of the program counter\n\n" + "* :source - string with the file path or other identifier for the source code\n\n" + "* :slots - array of all values in each slot\n\n" + "* :tail - boolean indicating a tail call") { janet_fixarity(argc, 1); JanetFiber *fiber = janet_getfiber(argv, 0); JanetArray *array = janet_array(0); @@ -300,7 +335,11 @@ static Janet cfun_debug_stack(int32_t argc, Janet *argv) { return janet_wrap_array(array); } -static Janet cfun_debug_stacktrace(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_debug_stacktrace, + "(debug/stacktrace fiber &opt err)", + "Prints a nice looking stacktrace for a fiber. Can optionally provide " + "an error value to print the stack trace with. If `err` is nil or not " + "provided, will skip the error line. Returns the fiber.") { janet_arity(argc, 1, 2); JanetFiber *fiber = janet_getfiber(argv, 0); Janet x = argc == 1 ? janet_wrap_nil() : argv[1]; @@ -308,7 +347,11 @@ static Janet cfun_debug_stacktrace(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_debug_argstack(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_debug_argstack, + "(debug/arg-stack fiber)", + "Gets all values currently on the fiber's argument stack. Normally, " + "this should be empty unless the fiber signals while pushing arguments " + "to make a function call. Returns a new array.") { janet_fixarity(argc, 1); JanetFiber *fiber = janet_getfiber(argv, 0); JanetArray *array = janet_array(fiber->stacktop - fiber->stackstart); @@ -317,7 +360,11 @@ static Janet cfun_debug_argstack(int32_t argc, Janet *argv) { return janet_wrap_array(array); } -static Janet cfun_debug_step(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_debug_step, + "(debug/step fiber &opt x)", + "Run a fiber for one virtual instruction of the Janet machine. Can optionally " + "pass in a value that will be passed as the resuming value. Returns the signal value, " + "which will usually be nil, as breakpoints raise nil signals.") { janet_arity(argc, 1, 2); JanetFiber *fiber = janet_getfiber(argv, 0); Janet out = janet_wrap_nil(); @@ -325,85 +372,19 @@ static Janet cfun_debug_step(int32_t argc, Janet *argv) { return out; } -static const JanetReg debug_cfuns[] = { - { - "debug/break", cfun_debug_break, - JDOC("(debug/break source line col)\n\n" - "Sets a breakpoint in `source` at a given line and column. " - "Will throw an error if the breakpoint location " - "cannot be found. For example\n\n" - "\t(debug/break \"core.janet\" 10 4)\n\n" - "will set a breakpoint at line 10, 4th column of the file core.janet.") - }, - { - "debug/unbreak", cfun_debug_unbreak, - JDOC("(debug/unbreak source line column)\n\n" - "Remove a breakpoint with a source key at a given line and column. " - "Will throw an error if the breakpoint " - "cannot be found.") - }, - { - "debug/fbreak", cfun_debug_fbreak, - JDOC("(debug/fbreak fun &opt pc)\n\n" - "Set a breakpoint in a given function. pc is an optional offset, which " - "is in bytecode instructions. fun is a function value. Will throw an error " - "if the offset is too large or negative.") - }, - { - "debug/unfbreak", cfun_debug_unfbreak, - JDOC("(debug/unfbreak fun &opt pc)\n\n" - "Unset a breakpoint set with debug/fbreak.") - }, - { - "debug/arg-stack", cfun_debug_argstack, - JDOC("(debug/arg-stack fiber)\n\n" - "Gets all values currently on the fiber's argument stack. Normally, " - "this should be empty unless the fiber signals while pushing arguments " - "to make a function call. Returns a new array.") - }, - { - "debug/stack", cfun_debug_stack, - JDOC("(debug/stack fib)\n\n" - "Gets information about the stack as an array of tables. Each table " - "in the array contains information about a stack frame. The top-most, current " - "stack frame is the first table in the array, and the bottom-most stack frame " - "is the last value. Each stack frame contains some of the following attributes:\n\n" - "* :c - true if the stack frame is a c function invocation\n\n" - "* :column - the current source column of the stack frame\n\n" - "* :function - the function that the stack frame represents\n\n" - "* :line - the current source line of the stack frame\n\n" - "* :name - the human-friendly name of the function\n\n" - "* :pc - integer indicating the location of the program counter\n\n" - "* :source - string with the file path or other identifier for the source code\n\n" - "* :slots - array of all values in each slot\n\n" - "* :tail - boolean indicating a tail call") - }, - { - "debug/stacktrace", cfun_debug_stacktrace, - JDOC("(debug/stacktrace fiber &opt err)\n\n" - "Prints a nice looking stacktrace for a fiber. Can optionally provide " - "an error value to print the stack trace with. If `err` is nil or not " - "provided, will skip the error line. Returns the fiber.") - }, - { - "debug/lineage", cfun_debug_lineage, - JDOC("(debug/lineage fib)\n\n" - "Returns an array of all child fibers from a root fiber. This function " - "is useful when a fiber signals or errors to an ancestor fiber. Using this function, " - "the fiber handling the error can see which fiber raised the signal. This function should " - "be used mostly for debugging purposes.") - }, - { - "debug/step", cfun_debug_step, - JDOC("(debug/step fiber &opt x)\n\n" - "Run a fiber for one virtual instruction of the Janet machine. Can optionally " - "pass in a value that will be passed as the resuming value. Returns the signal value, " - "which will usually be nil, as breakpoints raise nil signals.") - }, - {NULL, NULL, NULL} -}; - /* Module entry point */ void janet_lib_debug(JanetTable *env) { - janet_core_cfuns(env, NULL, debug_cfuns); + JanetRegExt debug_cfuns[] = { + JANET_CORE_REG("debug/break", cfun_debug_break), + JANET_CORE_REG("debug/unbreak", cfun_debug_unbreak), + JANET_CORE_REG("debug/fbreak", cfun_debug_fbreak), + JANET_CORE_REG("debug/unfbreak", cfun_debug_unfbreak), + JANET_CORE_REG("debug/arg-stack", cfun_debug_argstack), + JANET_CORE_REG("debug/stack", cfun_debug_stack), + JANET_CORE_REG("debug/stacktrace", cfun_debug_stacktrace), + JANET_CORE_REG("debug/lineage", cfun_debug_lineage), + JANET_CORE_REG("debug/step", cfun_debug_step), + JANET_REG_END + }; + janet_core_cfuns_ext(env, NULL, debug_cfuns); } diff --git a/src/core/ev.c b/src/core/ev.c index b4f189fd..6dee347f 100644 --- a/src/core/ev.c +++ b/src/core/ev.c @@ -721,7 +721,10 @@ static int janet_channel_pop(JanetChannel *channel, Janet *item, int is_choice) /* Channel Methods */ -static Janet cfun_channel_push(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_channel_push, + "(ev/give channel value)", + "Write a value to a channel, suspending the current fiber if the channel is full." + ) { janet_fixarity(argc, 2); JanetChannel *channel = janet_getabstract(argv, 0, &ChannelAT); if (janet_channel_push(channel, argv[1], 0)) { @@ -730,7 +733,10 @@ static Janet cfun_channel_push(int32_t argc, Janet *argv) { return argv[0]; } -static Janet cfun_channel_pop(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_channel_pop, + "(ev/take channel)", + "Read from a channel, suspending the current fiber if no value is available." + ) { janet_fixarity(argc, 1); JanetChannel *channel = janet_getabstract(argv, 0, &ChannelAT); Janet item; @@ -740,7 +746,13 @@ static Janet cfun_channel_pop(int32_t argc, Janet *argv) { janet_await(); } -static Janet cfun_channel_choice(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_channel_choice, + "(ev/select & clauses)", + "Block until the first of several channel operations occur. Returns a tuple of the form [:give chan] or [:take chan x], where " + "a :give tuple is the result of a write and :take tuple is the result of a write. Each clause must be either a channel (for " + "a channel take operation) or a tuple [channel x] for a channel give operation. Operations are tried in order, such that the first " + "clauses will take precedence over later clauses." + ) { janet_arity(argc, 1, -1); int32_t len; const Janet *data; @@ -782,19 +794,28 @@ static Janet cfun_channel_choice(int32_t argc, Janet *argv) { janet_await(); } -static Janet cfun_channel_full(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_channel_full, + "(ev/full channel)", + "Check if a channel is full or not." + ) { janet_fixarity(argc, 1); JanetChannel *channel = janet_getabstract(argv, 0, &ChannelAT); return janet_wrap_boolean(janet_q_count(&channel->items) >= channel->limit); } -static Janet cfun_channel_capacity(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_channel_capacity, + "(ev/capacity channel)", + "Get the number of items a channel will store before blocking writers." + ) { janet_fixarity(argc, 1); JanetChannel *channel = janet_getabstract(argv, 0, &ChannelAT); return janet_wrap_integer(channel->limit); } -static Janet cfun_channel_count(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_channel_count, + "(ev/count channel)", + "Get the number of items currently waiting in a channel." + ) { janet_fixarity(argc, 1); JanetChannel *channel = janet_getabstract(argv, 0, &ChannelAT); return janet_wrap_integer(janet_q_count(&channel->items)); @@ -810,12 +831,19 @@ static void fisher_yates_args(int32_t argc, Janet *argv) { } } -static Janet cfun_channel_rchoice(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_channel_rchoice, + "(ev/rselect & clauses)", + "Similar to ev/select, but will try clauses in a random order for fairness." + ) { fisher_yates_args(argc, argv); return cfun_channel_choice(argc, argv); } -static Janet cfun_channel_new(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_channel_new, + "(ev/chan &opt capacity)", + "Create a new channel. capacity is the number of values to queue before " + "blocking writers, defaults to 0 if not provided. Returns a new channel." + ) { janet_arity(argc, 0, 1); int32_t limit = janet_optnat(argv, argc, 0, 0); JanetChannel *channel = janet_abstract(&ChannelAT, sizeof(JanetChannel)); @@ -2116,7 +2144,14 @@ error: /* C functions */ -static Janet cfun_ev_go(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_ev_go, + "(ev/go fiber &opt value supervisor)", + "Put a fiber on the event loop to be resumed later. Optionally pass " + "a value to resume with, otherwise resumes with nil. Returns the fiber. " + "An optional `core/channel` can be provided as well as a supervisor. When various " + "events occur in the newly scheduled fiber, an event will be pushed to the supervisor. " + "If not provided, the new fiber will inherit the current supervisor." + ) { janet_arity(argc, 1, 3); JanetFiber *fiber = janet_getfiber(argv, 0); Janet value = argc >= 2 ? argv[1] : janet_wrap_nil(); @@ -2168,7 +2203,14 @@ static JanetEVGenericMessage janet_go_thread_subr(JanetEVGenericMessage args) { return args; } -static Janet cfun_ev_thread(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_ev_thread, + "(ev/thread fiber &opt value flags)", + "Resume a (copy of a) `fiber` in a new operating system thread, optionally passing `value` " + "to resume with. " + "Unlike `ev/go`, this function will suspend the current fiber until the thread is complete. " + "If you want to run the thread without waiting for a result, pass the `:n` flag to return nil immediately. " + "Otherwise, returns (a copy of) the final result from the fiber on the new thread." + ) { janet_arity(argc, 1, 3); janet_getfiber(argv, 0); Janet value = argc >= 2 ? argv[1] : janet_wrap_nil(); @@ -2200,7 +2242,12 @@ static Janet cfun_ev_thread(int32_t argc, Janet *argv) { } } -static Janet cfun_ev_give_supervisor(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_ev_give_supervisor, + "(ev/give-supervisor tag & payload)", + "Send a message to the current supervior channel if there is one. The message will be a " + "tuple of all of the arguments combined into a single message, where the first element is tag. " + "By convention, tag should be a keyword indicating the type of message. Returns nil." + ) { janet_arity(argc, 1, -1); JanetChannel *chan = janet_vm.root_fiber->supervisor_channel; if (NULL != chan) { @@ -2222,13 +2269,22 @@ JANET_NO_RETURN void janet_sleep_await(double sec) { janet_await(); } -static Janet cfun_ev_sleep(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_ev_sleep, + "(ev/sleep sec)", + "Suspend the current fiber for sec seconds without blocking the event loop." + ) { janet_fixarity(argc, 1); double sec = janet_getnumber(argv, 0); janet_sleep_await(sec); } -static Janet cfun_ev_deadline(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_ev_deadline, + "(ev/deadline sec &opt tocancel tocheck)", + "Set a deadline for a fiber `tocheck`. If `tocheck` is not finished after `sec` seconds, " + "`tocancel` will be canceled as with `ev/cancel`. " + "If `tocancel` and `tocheck` are not given, they default to `(fiber/root)` and " + "`(fiber/current)` respectively. Returns `tocancel`." + ) { janet_arity(argc, 1, 3); double sec = janet_getnumber(argv, 0); JanetFiber *tocancel = janet_optfiber(argv, argc, 1, janet_vm.root_fiber); @@ -2243,7 +2299,10 @@ static Janet cfun_ev_deadline(int32_t argc, Janet *argv) { return janet_wrap_fiber(tocancel); } -static Janet cfun_ev_cancel(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_ev_cancel, + "(ev/cancel fiber err)", + "Cancel a suspended fiber in the event loop. Differs from cancel in that it returns the canceled fiber immediately" + ) { janet_fixarity(argc, 2); JanetFiber *fiber = janet_getfiber(argv, 0); Janet err = argv[1]; @@ -2251,14 +2310,25 @@ static Janet cfun_ev_cancel(int32_t argc, Janet *argv) { return argv[0]; } -Janet janet_cfun_stream_close(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_cfun_stream_close, + "(ev/close stream)", + "Close a stream. This should be the same as calling (:close stream) for all streams." + ) { janet_fixarity(argc, 1); JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type); janet_stream_close(stream); return argv[0]; } -Janet janet_cfun_stream_read(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_cfun_stream_read, + "(ev/read stream n &opt buffer timeout)", + "Read up to n bytes into a buffer asynchronously from a stream. `n` can also be the keyword " + "`:all` to read into the buffer until end of stream. " + "Optionally provide a buffer to write into " + "as well as a timeout in seconds after which to cancel the operation and raise an error. " + "Returns the buffer if the read was successful or nil if end-of-stream reached. Will raise an " + "error if there are problems with the IO operation." + ) { janet_arity(argc, 2, 4); JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type); janet_stream_flags(stream, JANET_STREAM_READABLE); @@ -2275,7 +2345,11 @@ Janet janet_cfun_stream_read(int32_t argc, Janet *argv) { janet_await(); } -Janet janet_cfun_stream_chunk(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_cfun_stream_chunk, + "(ev/chunk stream n &opt buffer timeout)", + "Same as ev/read, but will not return early if less than n bytes are available. If an end of " + "stream is reached, will also return early with the collected bytes." + ) { janet_arity(argc, 2, 4); JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type); janet_stream_flags(stream, JANET_STREAM_READABLE); @@ -2287,7 +2361,11 @@ Janet janet_cfun_stream_chunk(int32_t argc, Janet *argv) { janet_await(); } -Janet janet_cfun_stream_write(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_cfun_stream_write, + "(ev/write stream data &opt timeout)", + "Write data to a stream, suspending the current fiber until the write " + "completes. Takes an optional timeout in seconds, after which will return nil. " + "Returns nil, or raises an error if the write failed.") { janet_arity(argc, 2, 3); JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type); janet_stream_flags(stream, JANET_STREAM_WRITABLE); @@ -2303,127 +2381,30 @@ Janet janet_cfun_stream_write(int32_t argc, Janet *argv) { janet_await(); } -static const JanetReg ev_cfuns[] = { - { - "ev/go", cfun_ev_go, - JDOC("(ev/go fiber &opt value supervisor)\n\n" - "Put a fiber on the event loop to be resumed later. Optionally pass " - "a value to resume with, otherwise resumes with nil. Returns the fiber. " - "An optional `core/channel` can be provided as well as a supervisor. When various " - "events occur in the newly scheduled fiber, an event will be pushed to the supervisor. " - "If not provided, the new fiber will inherit the current supervisor.") - }, - { - "ev/thread", cfun_ev_thread, - JDOC("(ev/thread fiber &opt value flags)\n\n" - "Resume a (copy of a) `fiber` in a new operating system thread, optionally passing `value` " - "to resume with. " - "Unlike `ev/go`, this function will suspend the current fiber until the thread is complete. " - "If you want to run the thread without waiting for a result, pass the `:n` flag to return nil immediately. " - "Otherwise, returns (a copy of) the final result from the fiber on the new thread.") - }, - { - "ev/give-supervisor", cfun_ev_give_supervisor, - JDOC("(ev/give-supervsior tag & payload)\n\n" - "Send a message to the current supervior channel if there is one. The message will be a " - "tuple of all of the arguments combined into a single message, where the first element is tag. " - "By convention, tag should be a keyword indicating the type of message. Returns nil.") - }, - { - "ev/sleep", cfun_ev_sleep, - JDOC("(ev/sleep sec)\n\n" - "Suspend the current fiber for sec seconds without blocking the event loop.") - }, - { - "ev/deadline", cfun_ev_deadline, - JDOC("(ev/deadline sec &opt tocancel tocheck)\n\n" - "Set a deadline for a fiber `tocheck`. If `tocheck` is not finished after `sec` seconds, " - "`tocancel` will be canceled as with `ev/cancel`. " - "If `tocancel` and `tocheck` are not given, they default to `(fiber/root)` and " - "`(fiber/current)` respectively. Returns `tocancel`.") - }, - { - "ev/chan", cfun_channel_new, - JDOC("(ev/chan &opt capacity)\n\n" - "Create a new channel. capacity is the number of values to queue before " - "blocking writers, defaults to 0 if not provided. Returns a new channel.") - }, - { - "ev/give", cfun_channel_push, - JDOC("(ev/give channel value)\n\n" - "Write a value to a channel, suspending the current fiber if the channel is full.") - }, - { - "ev/take", cfun_channel_pop, - JDOC("(ev/take channel)\n\n" - "Read from a channel, suspending the current fiber if no value is available.") - }, - { - "ev/full", cfun_channel_full, - JDOC("(ev/full channel)\n\n" - "Check if a channel is full or not.") - }, - { - "ev/capacity", cfun_channel_capacity, - JDOC("(ev/capacity channel)\n\n" - "Get the number of items a channel will store before blocking writers.") - }, - { - "ev/count", cfun_channel_count, - JDOC("(ev/count channel)\n\n" - "Get the number of items currently waiting in a channel.") - }, - { - "ev/cancel", cfun_ev_cancel, - JDOC("(ev/cancel fiber err)\n\n" - "Cancel a suspended fiber in the event loop. Differs from cancel in that it returns the canceled fiber immediately") - }, - { - "ev/select", cfun_channel_choice, - JDOC("(ev/select & clauses)\n\n" - "Block until the first of several channel operations occur. Returns a tuple of the form [:give chan] or [:take chan x], where " - "a :give tuple is the result of a write and :take tuple is the result of a write. Each clause must be either a channel (for " - "a channel take operation) or a tuple [channel x] for a channel give operation. Operations are tried in order, such that the first " - "clauses will take precedence over later clauses.") - }, - { - "ev/rselect", cfun_channel_rchoice, - JDOC("(ev/rselect & clauses)\n\n" - "Similar to ev/select, but will try clauses in a random order for fairness.") - }, - { - "ev/close", janet_cfun_stream_close, - JDOC("(ev/close stream)\n\n" - "Close a stream. This should be the same as calling (:close stream) for all streams.") - }, - { - "ev/read", janet_cfun_stream_read, - JDOC("(ev/read stream n &opt buffer timeout)\n\n" - "Read up to n bytes into a buffer asynchronously from a stream. `n` can also be the keyword " - "`:all` to read into the buffer until end of stream. " - "Optionally provide a buffer to write into " - "as well as a timeout in seconds after which to cancel the operation and raise an error. " - "Returns the buffer if the read was successful or nil if end-of-stream reached. Will raise an " - "error if there are problems with the IO operation.") - }, - { - "ev/chunk", janet_cfun_stream_chunk, - JDOC("(ev/chunk stream n &opt buffer timeout)\n\n" - "Same as ev/read, but will not return early if less than n bytes are available. If an end of " - "stream is reached, will also return early with the collected bytes.") - }, - { - "ev/write", janet_cfun_stream_write, - JDOC("(ev/write stream data &opt timeout)\n\n" - "Write data to a stream, suspending the current fiber until the write " - "completes. Takes an optional timeout in seconds, after which will return nil. " - "Returns nil, or raises an error if the write failed.") - }, - {NULL, NULL, NULL} -}; - void janet_lib_ev(JanetTable *env) { - janet_core_cfuns(env, NULL, ev_cfuns); + JanetRegExt ev_cfuns_ext[] = { + JANET_CORE_REG("ev/give", cfun_channel_push), + JANET_CORE_REG("ev/take", cfun_channel_pop), + JANET_CORE_REG("ev/full", cfun_channel_full), + JANET_CORE_REG("ev/capacity", cfun_channel_capacity), + JANET_CORE_REG("ev/count", cfun_channel_count), + JANET_CORE_REG("ev/select", cfun_channel_choice), + JANET_CORE_REG("ev/rselect", cfun_channel_rchoice), + JANET_CORE_REG("ev/chan", cfun_channel_new), + JANET_CORE_REG("ev/go", cfun_ev_go), + JANET_CORE_REG("ev/thread", cfun_ev_thread), + JANET_CORE_REG("ev/give-supervisor", cfun_ev_give_supervisor), + JANET_CORE_REG("ev/sleep", cfun_ev_sleep), + JANET_CORE_REG("ev/deadline", cfun_ev_deadline), + JANET_CORE_REG("ev/cancel", cfun_ev_cancel), + JANET_CORE_REG("ev/close", janet_cfun_stream_close), + JANET_CORE_REG("ev/read", janet_cfun_stream_read), + JANET_CORE_REG("ev/chunk", janet_cfun_stream_chunk), + JANET_CORE_REG("ev/write", janet_cfun_stream_write), + JANET_REG_END + }; + + janet_core_cfuns_ext(env, NULL, ev_cfuns_ext); janet_register_abstract_type(&janet_stream_type); } diff --git a/src/core/math.c b/src/core/math.c index 1eaf7852..10a9fbfc 100644 --- a/src/core/math.c +++ b/src/core/math.c @@ -117,7 +117,12 @@ double janet_rng_double(JanetRNG *rng) { return ldexp((double)(big >> (64 - 52)), -52); } -static Janet cfun_rng_make(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_rng_make, + "(math/rng &opt seed)", + "Creates a Psuedo-Random number generator, with an optional seed. " + "The seed should be an unsigned 32 bit integer or a buffer. " + "Do not use this for cryptography. Returns a core/rng abstract type." + ) { janet_arity(argc, 0, 1); JanetRNG *rng = janet_abstract(&janet_rng_type, sizeof(JanetRNG)); if (argc == 1) { @@ -134,13 +139,21 @@ static Janet cfun_rng_make(int32_t argc, Janet *argv) { return janet_wrap_abstract(rng); } -static Janet cfun_rng_uniform(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_rng_uniform, + "(math/rng-uniform rng)", + "Extract a random random integer in the range [0, max] from the RNG. If " + "no max is given, the default is 2^31 - 1." + ) { janet_fixarity(argc, 1); JanetRNG *rng = janet_getabstract(argv, 0, &janet_rng_type); return janet_wrap_number(janet_rng_double(rng)); } -static Janet cfun_rng_int(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_rng_int, + "(math/rng-int rng &opt max)", + "Extract a random random integer in the range [0, max] from the RNG. If " + "no max is given, the default is 2^31 - 1." + ) { janet_arity(argc, 1, 2); JanetRNG *rng = janet_getabstract(argv, 0, &janet_rng_type); if (argc == 1) { @@ -168,7 +181,11 @@ static void rng_get_4bytes(JanetRNG *rng, uint8_t *buf) { buf[3] = (word >> 24) & 0xFF; } -static Janet cfun_rng_buffer(int32_t argc, Janet *argv) { +JANET_CORE_FN(cfun_rng_buffer, + "(math/rng-buffer rng n &opt buf)", + "Get n random bytes and put them in a buffer. Creates a new buffer if no buffer is " + "provided, otherwise appends to the given buffer. Returns the buffer." + ) { janet_arity(argc, 2, 3); JanetRNG *rng = janet_getabstract(argv, 0, &janet_rng_type); int32_t n = janet_getnat(argv, 1); @@ -213,14 +230,20 @@ static Janet janet_rng_next(void *p, Janet key) { } /* Get a random number */ -static Janet janet_rand(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_rand, + "(math/random)", + "Returns a uniformly distributed random number between 0 and 1") { (void) argv; janet_fixarity(argc, 0); return janet_wrap_number(janet_rng_double(&janet_vm.rng)); } /* Seed the random number generator */ -static Janet janet_srand(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_srand, + "(math/seedrandom seed)", + "Set the seed for the random number generator. seed should be " + "an integer or a buffer." + ) { janet_fixarity(argc, 1); if (janet_checkint(argv[0])) { uint32_t seed = (uint32_t)(janet_getinteger(argv, 0)); @@ -232,295 +255,130 @@ static Janet janet_srand(int32_t argc, Janet *argv) { return janet_wrap_nil(); } -#define JANET_DEFINE_MATHOP(name, fop)\ -static Janet janet_##name(int32_t argc, Janet *argv) {\ +#define JANET_DEFINE_MATHOP(name, fop, doc)\ +JANET_CORE_FN(janet_##name, "(math/" #name " x)", doc) {\ janet_fixarity(argc, 1); \ double x = janet_getnumber(argv, 0); \ return janet_wrap_number(fop(x)); \ } -JANET_DEFINE_MATHOP(acos, acos) -JANET_DEFINE_MATHOP(asin, asin) -JANET_DEFINE_MATHOP(atan, atan) -JANET_DEFINE_MATHOP(cos, cos) -JANET_DEFINE_MATHOP(cosh, cosh) -JANET_DEFINE_MATHOP(acosh, acosh) -JANET_DEFINE_MATHOP(sin, sin) -JANET_DEFINE_MATHOP(sinh, sinh) -JANET_DEFINE_MATHOP(asinh, asinh) -JANET_DEFINE_MATHOP(tan, tan) -JANET_DEFINE_MATHOP(tanh, tanh) -JANET_DEFINE_MATHOP(atanh, atanh) -JANET_DEFINE_MATHOP(exp, exp) -JANET_DEFINE_MATHOP(exp2, exp2) -JANET_DEFINE_MATHOP(expm1, expm1) -JANET_DEFINE_MATHOP(log, log) -JANET_DEFINE_MATHOP(log10, log10) -JANET_DEFINE_MATHOP(log2, log2) -JANET_DEFINE_MATHOP(sqrt, sqrt) -JANET_DEFINE_MATHOP(cbrt, cbrt) -JANET_DEFINE_MATHOP(ceil, ceil) -JANET_DEFINE_MATHOP(fabs, fabs) -JANET_DEFINE_MATHOP(floor, floor) -JANET_DEFINE_MATHOP(trunc, trunc) -JANET_DEFINE_MATHOP(round, round) -JANET_DEFINE_MATHOP(gamma, lgamma) -JANET_DEFINE_MATHOP(log1p, log1p) -JANET_DEFINE_MATHOP(erf, erf) -JANET_DEFINE_MATHOP(erfc, erfc) +JANET_DEFINE_MATHOP(acos, acos, "Returns the arccosize of x.") +JANET_DEFINE_MATHOP(asin, asin, "Returns the arcsin of x.") +JANET_DEFINE_MATHOP(atan, atan, "Returns the arctangent of x.") +JANET_DEFINE_MATHOP(cos, cos, "Returns the cosine of x.") +JANET_DEFINE_MATHOP(cosh, cosh, "Returns the hyperbolic cosine of x.") +JANET_DEFINE_MATHOP(acosh, acosh, "Returns the hyperbolic arccosine of x.") +JANET_DEFINE_MATHOP(sin, sin, "Returns the sine of x.") +JANET_DEFINE_MATHOP(sinh, sinh, "Returns the hyperbolic sine of x.") +JANET_DEFINE_MATHOP(asinh, asinh, "Returns the hypberbolic arcsine of x.") +JANET_DEFINE_MATHOP(tan, tan, "Returns the tangent of x.") +JANET_DEFINE_MATHOP(tanh, tanh, "Returns the hyperbolic tangent of x.") +JANET_DEFINE_MATHOP(atanh, atanh, "Returns the hyperbolic arctangent of x.") +JANET_DEFINE_MATHOP(exp, exp, "Returns e to the power of x.") +JANET_DEFINE_MATHOP(exp2, exp2, "Returns 2 to the power of x.") +JANET_DEFINE_MATHOP(expm1, expm1, "Returns e to the power of x minus 1.") +JANET_DEFINE_MATHOP(log, log, "Returns the natural logarithm of x.") +JANET_DEFINE_MATHOP(log10, log10, "Returns the log base 10 of x.") +JANET_DEFINE_MATHOP(log2, log2, "Returns the log base 2 of x.") +JANET_DEFINE_MATHOP(sqrt, sqrt, "Returns the square root of x.") +JANET_DEFINE_MATHOP(cbrt, cbrt, "Returns the cube root of x.") +JANET_DEFINE_MATHOP(ceil, ceil, "Returns the smallest integer value number that is not less than x.") +JANET_DEFINE_MATHOP(fabs, fabs, "Return the absolute value of x.") +JANET_DEFINE_MATHOP(floor, floor, "Returns the largest integer value number that is not greater than x.") +JANET_DEFINE_MATHOP(trunc, trunc, "Returns the integer between x and 0 nearest to x.") +JANET_DEFINE_MATHOP(round, round, "Returns the integer nearest to x.") +JANET_DEFINE_MATHOP(gamma, lgamma, "Returns gamma(x).") +JANET_DEFINE_MATHOP(log1p, log1p, "Returns (log base e of x) + 1 more accurately than (+ (math/log x) 1)") +JANET_DEFINE_MATHOP(erf, erf, "Returns the error function of x.") +JANET_DEFINE_MATHOP(erfc, erfc, "Returns the complementary error function of x.") -#define JANET_DEFINE_MATH2OP(name, fop)\ -static Janet janet_##name(int32_t argc, Janet *argv) {\ +#define JANET_DEFINE_MATH2OP(name, fop, signature, doc)\ +JANET_CORE_FN(janet_##name, signature, doc) {\ janet_fixarity(argc, 2); \ double lhs = janet_getnumber(argv, 0); \ double rhs = janet_getnumber(argv, 1); \ return janet_wrap_number(fop(lhs, rhs)); \ -}\ +} -JANET_DEFINE_MATH2OP(atan2, atan2) -JANET_DEFINE_MATH2OP(pow, pow) -JANET_DEFINE_MATH2OP(hypot, hypot) -JANET_DEFINE_MATH2OP(nextafter, nextafter) +JANET_DEFINE_MATH2OP(atan2, atan2, "(math/atan2 y x)", "Returns the arctangent of y/x. Works even when x is 0.") +JANET_DEFINE_MATH2OP(pow, pow, "(math/pow a x)", "Returns a to the power of x.") +JANET_DEFINE_MATH2OP(hypot, hypot, "(math/hypot a b)", "Returns c from the equation c^2 = a^2 + b^2.") +JANET_DEFINE_MATH2OP(nextafter, nextafter, "(math/next x y)", "Returns the next representable floating point vaue after x in the direction of y.") -static Janet janet_not(int32_t argc, Janet *argv) { +JANET_CORE_FN(janet_not, "(not x)", "Returns the boolean inverse of x.") { janet_fixarity(argc, 1); return janet_wrap_boolean(!janet_truthy(argv[0])); } -static const JanetReg math_cfuns[] = { - { - "not", janet_not, - JDOC("(not x)\n\nReturns the boolean inverse of x.") - }, - { - "math/random", janet_rand, - JDOC("(math/random)\n\n" - "Returns a uniformly distributed random number between 0 and 1.") - }, - { - "math/seedrandom", janet_srand, - JDOC("(math/seedrandom seed)\n\n" - "Set the seed for the random number generator. seed should be " - "an integer or a buffer.") - }, - { - "math/cos", janet_cos, - JDOC("(math/cos x)\n\n" - "Returns the cosine of x.") - }, - { - "math/sin", janet_sin, - JDOC("(math/sin x)\n\n" - "Returns the sine of x.") - }, - { - "math/tan", janet_tan, - JDOC("(math/tan x)\n\n" - "Returns the tangent of x.") - }, - { - "math/acos", janet_acos, - JDOC("(math/acos x)\n\n" - "Returns the arccosine of x.") - }, - { - "math/asin", janet_asin, - JDOC("(math/asin x)\n\n" - "Returns the arcsine of x.") - }, - { - "math/atan", janet_atan, - JDOC("(math/atan x)\n\n" - "Returns the arctangent of x.") - }, - { - "math/exp", janet_exp, - JDOC("(math/exp x)\n\n" - "Returns e to the power of x.") - }, - { - "math/log", janet_log, - JDOC("(math/log x)\n\n" - "Returns log base natural number of x.") - }, - { - "math/log10", janet_log10, - JDOC("(math/log10 x)\n\n" - "Returns log base 10 of x.") - }, - { - "math/log2", janet_log2, - JDOC("(math/log2 x)\n\n" - "Returns log base 2 of x.") - }, - { - "math/sqrt", janet_sqrt, - JDOC("(math/sqrt x)\n\n" - "Returns the square root of x.") - }, - { - "math/cbrt", janet_cbrt, - JDOC("(math/cbrt x)\n\n" - "Returns the cube root of x.") - }, - { - "math/floor", janet_floor, - JDOC("(math/floor x)\n\n" - "Returns the largest integer value number that is not greater than x.") - }, - { - "math/ceil", janet_ceil, - JDOC("(math/ceil x)\n\n" - "Returns the smallest integer value number that is not less than x.") - }, - { - "math/pow", janet_pow, - JDOC("(math/pow a x)\n\n" - "Return a to the power of x.") - }, - { - "math/abs", janet_fabs, - JDOC("(math/abs x)\n\n" - "Return the absolute value of x.") - }, - { - "math/sinh", janet_sinh, - JDOC("(math/sinh x)\n\n" - "Return the hyperbolic sine of x.") - }, - { - "math/cosh", janet_cosh, - JDOC("(math/cosh x)\n\n" - "Return the hyperbolic cosine of x.") - }, - { - "math/tanh", janet_tanh, - JDOC("(math/tanh x)\n\n" - "Return the hyperbolic tangent of x.") - }, - { - "math/atanh", janet_atanh, - JDOC("(math/atanh x)\n\n" - "Return the hyperbolic arctangent of x.") - }, - { - "math/asinh", janet_asinh, - JDOC("(math/asinh x)\n\n" - "Return the hyperbolic arcsine of x.") - }, - { - "math/acosh", janet_acosh, - JDOC("(math/acosh x)\n\n" - "Return the hyperbolic arccosine of x.") - }, - { - "math/atan2", janet_atan2, - JDOC("(math/atan2 y x)\n\n" - "Return the arctangent of y/x. Works even when x is 0.") - }, - { - "math/rng", cfun_rng_make, - JDOC("(math/rng &opt seed)\n\n" - "Creates a Psuedo-Random number generator, with an optional seed. " - "The seed should be an unsigned 32 bit integer or a buffer. " - "Do not use this for cryptography. Returns a core/rng abstract type.") - }, - { - "math/rng-uniform", cfun_rng_uniform, - JDOC("(math/rng-seed rng seed)\n\n" - "Extract a random number in the range [0, 1) from the RNG.") - }, - { - "math/rng-int", cfun_rng_int, - JDOC("(math/rng-int rng &opt max)\n\n" - "Extract a random random integer in the range [0, max] from the RNG. If " - "no max is given, the default is 2^31 - 1.") - }, - { - "math/rng-buffer", cfun_rng_buffer, - JDOC("(math/rng-buffer rng n &opt buf)\n\n" - "Get n random bytes and put them in a buffer. Creates a new buffer if no buffer is " - "provided, otherwise appends to the given buffer. Returns the buffer.") - }, - { - "math/hypot", janet_hypot, - JDOC("(math/hypot a b)\n\n" - "Returns the c from the equation c^2 = a^2 + b^2") - }, - { - "math/exp2", janet_exp2, - JDOC("(math/exp2 x)\n\n" - "Returns 2 to the power of x.") - }, - { - "math/log1p", janet_log1p, - JDOC("(math/log1p x)\n\n" - "Returns (log base e of x) + 1 more accurately than (+ (math/log x) 1)") - }, - { - "math/gamma", janet_gamma, - JDOC("(math/gamma x)\n\n" - "Returns gamma(x).") - }, - { - "math/erfc", janet_erfc, - JDOC("(math/erfc x)\n\n" - "Returns the complementary error function of x.") - }, - { - "math/erf", janet_erf, - JDOC("(math/erf x)\n\n" - "Returns the error function of x.") - }, - { - "math/expm1", janet_expm1, - JDOC("(math/expm1 x)\n\n" - "Returns e to the power of x minus 1.") - }, - { - "math/trunc", janet_trunc, - JDOC("(math/trunc x)\n\n" - "Returns the integer between x and 0 nearest to x.") - }, - { - "math/round", janet_round, - JDOC("(math/round x)\n\n" - "Returns the integer nearest to x.") - }, - { - "math/next", janet_nextafter, - JDOC("(math/next x y)\n\n" - "Returns the next representable floating point value after x in the direction of y.") - }, - {NULL, NULL, NULL} -}; /* Module entry point */ void janet_lib_math(JanetTable *env) { - janet_core_cfuns(env, NULL, math_cfuns); + JanetRegExt math_cfuns[] = { + JANET_CORE_REG("not", janet_not), + JANET_CORE_REG("math/random", janet_rand), + JANET_CORE_REG("math/seedrandom", janet_srand), + JANET_CORE_REG("math/cos", janet_cos), + JANET_CORE_REG("math/sin", janet_sin), + JANET_CORE_REG("math/tan", janet_tan), + JANET_CORE_REG("math/acos", janet_acos), + JANET_CORE_REG("math/asin", janet_asin), + JANET_CORE_REG("math/atan", janet_atan), + JANET_CORE_REG("math/exp", janet_exp), + JANET_CORE_REG("math/log", janet_log), + JANET_CORE_REG("math/log10", janet_log10), + JANET_CORE_REG("math/log2", janet_log2), + JANET_CORE_REG("math/sqrt", janet_sqrt), + JANET_CORE_REG("math/cbrt", janet_cbrt), + JANET_CORE_REG("math/floor", janet_floor), + JANET_CORE_REG("math/ceil", janet_ceil), + JANET_CORE_REG("math/pow", janet_pow), + JANET_CORE_REG("math/abs", janet_fabs), + JANET_CORE_REG("math/sinh", janet_sinh), + JANET_CORE_REG("math/cosh", janet_cosh), + JANET_CORE_REG("math/tanh", janet_tanh), + JANET_CORE_REG("math/atanh", janet_atanh), + JANET_CORE_REG("math/asinh", janet_asinh), + JANET_CORE_REG("math/acosh", janet_acosh), + JANET_CORE_REG("math/atan2", janet_atan2), + JANET_CORE_REG("math/rng", cfun_rng_make), + JANET_CORE_REG("math/rng-uniform", cfun_rng_uniform), + JANET_CORE_REG("math/rng-int", cfun_rng_int), + JANET_CORE_REG("math/rng-buffer", cfun_rng_buffer), + JANET_CORE_REG("math/hypot", janet_hypot), + JANET_CORE_REG("math/exp2", janet_exp2), + JANET_CORE_REG("math/log1p", janet_log1p), + JANET_CORE_REG("math/gamma", janet_gamma), + JANET_CORE_REG("math/erfc", janet_erfc), + JANET_CORE_REG("math/erf", janet_erf), + JANET_CORE_REG("math/expm1", janet_expm1), + JANET_CORE_REG("math/trunc", janet_trunc), + JANET_CORE_REG("math/round", janet_round), + JANET_CORE_REG("math/next", janet_nextafter), + JANET_REG_END + }; + janet_core_cfuns_ext(env, NULL, math_cfuns); janet_register_abstract_type(&janet_rng_type); #ifdef JANET_BOOTSTRAP - janet_def(env, "math/pi", janet_wrap_number(3.1415926535897931), - JDOC("The value pi.")); - janet_def(env, "math/e", janet_wrap_number(2.7182818284590451), - JDOC("The base of the natural log.")); - janet_def(env, "math/inf", janet_wrap_number(INFINITY), - JDOC("The number representing positive infinity")); - janet_def(env, "math/-inf", janet_wrap_number(-INFINITY), - JDOC("The number representing negative infinity")); - janet_def(env, "math/int32-min", janet_wrap_number(INT32_MIN), - JDOC("The minimum contiguous integer representable by a 32 bit signed integer")); - janet_def(env, "math/int32-max", janet_wrap_number(INT32_MAX), - JDOC("The maximum contiguous integer represtenable by a 32 bit signed integer")); - janet_def(env, "math/int-min", janet_wrap_number(JANET_INTMIN_DOUBLE), - JDOC("The minimum contiguous integer representable by a double (2^53)")); - janet_def(env, "math/int-max", janet_wrap_number(JANET_INTMAX_DOUBLE), - JDOC("The maximum contiguous integer represtenable by a double (-(2^53))")); + JANET_CORE_DEF(env, "math/pi", janet_wrap_number(3.1415926535897931), + "The value pi."); + JANET_CORE_DEF(env, "math/e", janet_wrap_number(2.7182818284590451), + "The base of the natural log."); + JANET_CORE_DEF(env, "math/inf", janet_wrap_number(INFINITY), + "The number representing positive infinity"); + JANET_CORE_DEF(env, "math/-inf", janet_wrap_number(-INFINITY), + "The number representing negative infinity"); + JANET_CORE_DEF(env, "math/int32-min", janet_wrap_number(INT32_MIN), + "The minimum contiguous integer representable by a 32 bit signed integer"); + JANET_CORE_DEF(env, "math/int32-max", janet_wrap_number(INT32_MAX), + "The maximum contiguous integer represtenable by a 32 bit signed integer"); + JANET_CORE_DEF(env, "math/int-min", janet_wrap_number(JANET_INTMIN_DOUBLE), + "The minimum contiguous integer representable by a double (2^53)"); + JANET_CORE_DEF(env, "math/int-max", janet_wrap_number(JANET_INTMAX_DOUBLE), + "The maximum contiguous integer represtenable by a double (-(2^53))"); #ifdef NAN - janet_def(env, "math/nan", janet_wrap_number(NAN), + JANET_CORE_DEF(env, "math/nan", janet_wrap_number(NAN), "Not a number (IEEE-754 NaN"); #else - janet_def(env, "math/nan", janet_wrap_number(0.0 / 0.0), + JANET_CORE_DEF(env, "math/nan", janet_wrap_number(0.0 / 0.0), "Not a number (IEEE-754 NaN)"); #endif - JDOC("Not a number (IEEE-754 NaN)")); #endif } diff --git a/src/core/net.c b/src/core/net.c index 5a701f0c..7fde0711 100644 --- a/src/core/net.c +++ b/src/core/net.c @@ -713,7 +713,6 @@ static const JanetMethod net_stream_methods[] = { {"accept-loop", cfun_stream_accept_loop}, {"send-to", cfun_stream_send_to}, {"recv-from", cfun_stream_recv_from}, - {"recv-from", cfun_stream_recv_from}, {"evread", janet_cfun_stream_read}, {"evchunk", janet_cfun_stream_chunk}, {"evwrite", janet_cfun_stream_write}, diff --git a/src/core/util.h b/src/core/util.h index 90bf690c..7e1abea2 100644 --- a/src/core/util.h +++ b/src/core/util.h @@ -92,6 +92,7 @@ Janet janet_next_impl(Janet ds, Janet key, int is_interpreter); #ifdef JANET_BOOTSTRAP #define JANET_CORE_REG JANET_REG #define JANET_CORE_FN JANET_FN +#define JANET_CORE_DEF JANET_DEF #define janet_core_def janet_def #define janet_core_cfuns janet_cfuns #define janet_core_def_sm janet_def_sm @@ -99,6 +100,7 @@ Janet janet_next_impl(Janet ds, Janet key, int is_interpreter); #else #define JANET_CORE_REG JANET_REG_ #define JANET_CORE_FN JANET_FN_ +#define JANET_CORE_DEF JANET_DEF_ void janet_core_def(JanetTable *env, const char *name, Janet x, const void *p); void janet_core_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns); void janet_core_def_sm(JanetTable *env, const char *name, Janet x, const void *p, const void *sf, int32_t sl); diff --git a/src/include/janet.h b/src/include/janet.h index 13a235f8..5d8f6913 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1765,40 +1765,53 @@ JANET_API Janet janet_resolve_core(const char *name); /* no docstrings or sourcemaps */ #define JANET_REG_(JNAME, CNAME) {JNAME, CNAME, NULL, NULL, 0} #define JANET_FN_(CNAME, USAGE, DOCSTRING) \ - static Janet CNAME (int32_t argc, Janet *argv) + Janet CNAME (int32_t argc, Janet *argv) +#define JANET_DEF_(ENV, JNAME, VAL, DOC) \ + janet_def(ENV, JNAME, VAL, NULL) /* sourcemaps only */ #define JANET_REG_S(JNAME, CNAME) {JNAME, CNAME, NULL, __FILE__, CNAME##_sourceline_} #define JANET_FN_S(CNAME, USAGE, DOCSTRING) \ static int32_t CNAME##_sourceline_ = __LINE__; \ - static Janet CNAME (int32_t argc, Janet *argv) + Janet CNAME (int32_t argc, Janet *argv) +#define JANET_DEF_S(ENV, JNAME, VAL, DOC) \ + janet_def_sm(ENV, JNAME, VAL, NULL, __FILE__, __LINE__) /* docstring only */ #define JANET_REG_D(JNAME, CNAME) {JNAME, CNAME, CNAME##_docstring_, NULL, 0} #define JANET_FN_D(CNAME, USAGE, DOCSTRING) \ static const char CNAME##_docstring_[] = USAGE "\n\n" DOCSTRING; \ - static Janet CNAME (int32_t argc, Janet *argv) + Janet CNAME (int32_t argc, Janet *argv) +#define JANET_DEF_D(ENV, JNAME, VAL, DOC) \ + janet_def(ENV, JNAME, VAL, DOC) /* sourcemaps and docstrings */ #define JANET_REG_SD(JNAME, CNAME) {JNAME, CNAME, CNAME##_docstring_, __FILE__, CNAME##_sourceline_} #define JANET_FN_SD(CNAME, USAGE, DOCSTRING) \ static int32_t CNAME##_sourceline_ = __LINE__; \ static const char CNAME##_docstring_[] = USAGE "\n\n" DOCSTRING; \ - static Janet CNAME (int32_t argc, Janet *argv) + Janet CNAME (int32_t argc, Janet *argv) +#define JANET_DEF_SD(ENV, JNAME, VAL, DOC) \ + janet_def_sm(ENV, JNAME, VAL, DOC, __FILE__, __LINE__) + /* Choose defaults for source mapping and docstring based on config defs */ #if defined(JANET_NO_SOURCEMAPS) && defined(JANET_NO_DOCSTRINGS) #define JANET_REG JANET_REG_ #define JANET_FN JANET_FN_ +#define JANET_DEF JANET_DEF_ #elif defined(JANET_NO_SOURCEMAPS) && !defined(JANET_NO_DOCSTRINGS) #define JANET_REG JANET_REG_D #define JANET_FN JANET_FN_D +#define JANET_DEF JANET_DEF_D #elif !defined(JANET_NO_SOURCEMAPS) && defined(JANET_NO_DOCSTRINGS) #define JANET_REG JANET_REG_S #define JANET_FN JANET_FN_S +#define JANET_DEF JANET_DEF_S #elif !defined(JANET_NO_SOURCEMAPS) && !defined(JANET_NO_DOCSTRINGS) #define JANET_REG JANET_REG_SD #define JANET_FN JANET_FN_SD +#define JANET_DEF JANET_DEF_SD #endif /* Define things with source mapping information */