1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-18 14:44:48 +00:00

Add lots of documentation for all functions.

This commit is contained in:
Calvin Rose 2018-11-16 16:24:10 -05:00
parent fe7c591c40
commit fcbd24cedc
15 changed files with 457 additions and 195 deletions

View File

@ -1096,7 +1096,8 @@ value, one key will be ignored."
@[parent]
(def parent (if parent parent _env))
(def newenv (table.setproto @{} parent))
(put newenv '_env @{:value newenv :private true})
(put newenv '_env @{:value newenv :private true
:doc "The environment table for the current scope."})
newenv)
(defn run-context

View File

@ -287,8 +287,8 @@ static const JanetReg cfuns[] = {
{"native", janet_core_native,
"(native path)\n\n"
"Load a native module from the given path. The path "
"must be an absolute or relative path on the filesystem, and is "
"usually a .so file on unix systems, and a .dll file on Windows. "
"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."
},
@ -425,7 +425,8 @@ static void janet_quick_asm(
int32_t arity,
int32_t slots,
const uint32_t *bytecode,
size_t bytecode_size) {
size_t bytecode_size,
const char *doc) {
JanetFuncDef *def = janet_funcdef_alloc();
def->arity = arity;
def->flags = flags;
@ -437,7 +438,7 @@ static void janet_quick_asm(
JANET_OUT_OF_MEMORY;
}
memcpy(def->bytecode, bytecode, bytecode_size);
janet_def(env, name, janet_wrap_function(janet_thunk(def)), NULL);
janet_def(env, name, janet_wrap_function(janet_thunk(def)), doc);
}
/* Macros for easier inline janet assembly */
@ -454,7 +455,8 @@ static void templatize_varop(
const char *name,
int32_t nullary,
int32_t unary,
uint32_t op) {
uint32_t op,
const char *doc) {
/* Variadic operator assembly. Must be templatized for each different opcode. */
/* Reg 0: Argument tuple (args) */
@ -504,7 +506,8 @@ static void templatize_varop(
0,
6,
varop_asm,
sizeof(varop_asm));
sizeof(varop_asm),
doc);
}
/* Templatize variadic comparators */
@ -513,7 +516,8 @@ static void templatize_comparator(
int32_t flags,
const char *name,
int invert,
uint32_t op) {
uint32_t op,
const char *doc) {
/* Reg 0: Argument tuple (args) */
/* Reg 1: Argument count (argn) */
@ -555,7 +559,8 @@ static void templatize_comparator(
0,
6,
comparator_asm,
sizeof(comparator_asm));
sizeof(comparator_asm),
doc);
}
/* Make the apply function */
@ -589,7 +594,14 @@ static void make_apply(JanetTable *env) {
S(JOP_TAILCALL, 0)
};
janet_quick_asm(env, JANET_FUN_APPLY | JANET_FUNCDEF_FLAG_VARARG,
"apply", 1, 6, apply_asm, sizeof(apply_asm));
"apply", 1, 6, apply_asm, sizeof(apply_asm),
"(apply f & args)\n\n"
"Applies a function to a variable number of arguments. Each element in args "
"is used as an argument to f, except the last element in args, which is expected to "
"be an array-like. Each element in this last argument is then also pushed as an argument to "
"f. For example:\n\n"
"\t(apply + 1000 (range 10))\n\n"
"sums the first 10 integers and 1000.)");
}
JanetTable *janet_core_env(void) {
@ -631,44 +643,132 @@ JanetTable *janet_core_env(void) {
/* Load main functions */
janet_cfuns(env, NULL, cfuns);
janet_quick_asm(env, JANET_FUN_YIELD, "debug", 0, 1, debug_asm, sizeof(debug_asm));
janet_quick_asm(env, JANET_FUN_ERROR, "error", 1, 1, error_asm, sizeof(error_asm));
janet_quick_asm(env, JANET_FUN_YIELD, "yield", 1, 2, yield_asm, sizeof(yield_asm));
janet_quick_asm(env, JANET_FUN_RESUME, "resume", 2, 2, resume_asm, sizeof(resume_asm));
janet_quick_asm(env, JANET_FUN_GET, "get", 2, 2, get_asm, sizeof(get_asm));
janet_quick_asm(env, JANET_FUN_PUT, "put", 3, 3, put_asm, sizeof(put_asm));
janet_quick_asm(env, JANET_FUN_LENGTH, "length", 1, 1, length_asm, sizeof(length_asm));
janet_quick_asm(env, JANET_FUN_BNOT, "~", 1, 1, bnot_asm, sizeof(bnot_asm));
janet_quick_asm(env, JANET_FUN_YIELD, "debug", 0, 1, debug_asm, sizeof(debug_asm),
"(debug)\n\n"
"Throws a debug signal that can be caught by a parent fiber and used to inspect "
"the running state of the current fiber. Returns nil.");
janet_quick_asm(env, JANET_FUN_ERROR, "error", 1, 1, error_asm, sizeof(error_asm),
"(error e)\n\n"
"Throws an error e that can be caught and handled by a parent fiber.");
janet_quick_asm(env, JANET_FUN_YIELD, "yield", 1, 2, yield_asm, sizeof(yield_asm),
"(yield x)\n\n"
"Yield a value to a parent fiber. When a fiber yields, its execution is paused until "
"another thread resumes it. The fiber will then resume, and the last yield call will "
"return the value that was passed to resume.");
janet_quick_asm(env, JANET_FUN_RESUME, "resume", 2, 2, resume_asm, sizeof(resume_asm),
"(resume fiber [,x])\n\n"
"Resume a new or suspended fiber and optionally pass in a value to the fiber that "
"will be returned to the last yield in the case of a pending fiber, or the argument to "
"the dispatch function in the case of a new fiber. Returns either the return result of "
"the fiber's dispatch function, or the value from the next yield call in fiber.");
janet_quick_asm(env, JANET_FUN_GET, "get", 2, 2, get_asm, sizeof(get_asm),
"(get ds key)\n\n"
"Get a value from any associative data structure. Arrays, tuples, tables, structs, strings, "
"symbols, and buffers are all associative and can be used with get. Order structures, name "
"arrays, tuples, strings, buffers, and symbols must use integer keys. Structs and tables can "
"take any value as a key except nil and return a value except nil. Byte sequences will return "
"integer representations of bytes as result of a get call.");
janet_quick_asm(env, JANET_FUN_PUT, "put", 3, 3, put_asm, sizeof(put_asm),
"(put ds key value)\n\n"
"Associate a key with a value in any mutable associative data structure. Indexed data structures "
"(arrays and buffers) only accept non-negative integer keys, and will expand if an out of bounds "
"value is provided. In an array, extra space will be filled with nils, and in a buffer, extra "
"space will be filled with 0 bytes. In a table, putting a key that is contained in the table prototype "
"will hide the association defined by the prototype, but will not mutate the prototype table. Putting "
"a value nil into a table will remove the key from the table. Returns the data structure ds.");
janet_quick_asm(env, JANET_FUN_LENGTH, "length", 1, 1, length_asm, sizeof(length_asm),
"(length ds)\n\n"
"Returns the length or count of a data structure in constant time as an integer. For "
"structs and tables, returns the number of key-value pairs in the data structure.");
janet_quick_asm(env, JANET_FUN_BNOT, "~", 1, 1, bnot_asm, sizeof(bnot_asm),
"(~ x)\n\nReturns the bitwise inverse of integer x.");
make_apply(env);
/* Variadic ops */
templatize_varop(env, JANET_FUN_ADD, "+", 0, 0, JOP_ADD);
templatize_varop(env, JANET_FUN_SUBTRACT, "-", 0, 0, JOP_SUBTRACT);
templatize_varop(env, JANET_FUN_MULTIPLY, "*", 1, 1, JOP_MULTIPLY);
templatize_varop(env, JANET_FUN_DIVIDE, "/", 1, 1, JOP_DIVIDE);
templatize_varop(env, JANET_FUN_BAND, "&", -1, -1, JOP_BAND);
templatize_varop(env, JANET_FUN_BOR, "|", 0, 0, JOP_BOR);
templatize_varop(env, JANET_FUN_BXOR, "^", 0, 0, JOP_BXOR);
templatize_varop(env, JANET_FUN_LSHIFT, "<<", 1, 1, JOP_SHIFT_LEFT);
templatize_varop(env, JANET_FUN_RSHIFT, ">>", 1, 1, JOP_SHIFT_RIGHT);
templatize_varop(env, JANET_FUN_RSHIFTU, ">>>", 1, 1, JOP_SHIFT_RIGHT_UNSIGNED);
templatize_varop(env, JANET_FUN_ADD, "+", 0, 0, JOP_ADD,
"(+ & xs)\n\n"
"Returns the sum of all xs. xs must be integers or real numbers only. If xs is empty, return 0.");
templatize_varop(env, JANET_FUN_SUBTRACT, "-", 0, 0, JOP_SUBTRACT,
"(- & xs)\n\n"
"Returns the difference of xs. If xs is empty, returns 0. If xs has one element, returns the "
"negative value of that element. Otherwise, returns the first element in xs minus the sum of "
"the rest of the elements.");
templatize_varop(env, JANET_FUN_MULTIPLY, "*", 1, 1, JOP_MULTIPLY,
"(* & xs)\n\n"
"Returns the product of all elements in xs. If xs is empty, returns 1.");
templatize_varop(env, JANET_FUN_DIVIDE, "/", 1, 1, JOP_DIVIDE,
"(/ & xs)\n\n"
"Returns the quotient of xs. If xs is empty, returns 1. If xs has one value x, returns "
"the reciprocal of x. Otherwise return the first value of xs repeatedly divided by the remaining "
"values. Division by two integers uses truncating division.");
templatize_varop(env, JANET_FUN_BAND, "&", -1, -1, JOP_BAND,
"(& & xs)\n\n"
"Returns the bitwise and of all values in xs. Each x in xs must be an integer.");
templatize_varop(env, JANET_FUN_BOR, "|", 0, 0, JOP_BOR,
"(| & xs)\n\n"
"Returns the bitwise or of all values in xs. Each x in xs must be an integer.");
templatize_varop(env, JANET_FUN_BXOR, "^", 0, 0, JOP_BXOR,
"(^ & xs)\n\n"
"Returns the bitwise xor of all values in xs. Each in xs must be an integer.");
templatize_varop(env, JANET_FUN_LSHIFT, "<<", 1, 1, JOP_SHIFT_LEFT,
"(<< x & shifts)\n\n"
"Returns the value of x bit shifted left by the sum of all values in shifts. x "
"and each element in shift must be an integer.");
templatize_varop(env, JANET_FUN_RSHIFT, ">>", 1, 1, JOP_SHIFT_RIGHT,
"(>> x & shifts)\n\n"
"Returns the value of x bit shifted right by the sum of all values in shifts. x "
"and each element in shift must be an integer.");
templatize_varop(env, JANET_FUN_RSHIFTU, ">>>", 1, 1, JOP_SHIFT_RIGHT_UNSIGNED,
"(>> x & shifts)\n\n"
"Returns the value of x bit shifted right by the sum of all values in shifts. x "
"and each element in shift must be an integer. The sign of x is not preserved, so "
"for positive shifts the return value will always be positive.");
/* Variadic comparators */
templatize_comparator(env, JANET_FUN_ORDER_GT, "order>", 0, JOP_GREATER_THAN);
templatize_comparator(env, JANET_FUN_ORDER_LT, "order<", 0, JOP_LESS_THAN);
templatize_comparator(env, JANET_FUN_ORDER_GTE, "order>=", 1, JOP_LESS_THAN);
templatize_comparator(env, JANET_FUN_ORDER_LTE, "order<=", 1, JOP_GREATER_THAN);
templatize_comparator(env, JANET_FUN_ORDER_EQ, "=", 0, JOP_EQUALS);
templatize_comparator(env, JANET_FUN_ORDER_NEQ, "not=", 1, JOP_EQUALS);
templatize_comparator(env, JANET_FUN_GT, ">", 0, JOP_NUMERIC_GREATER_THAN);
templatize_comparator(env, JANET_FUN_LT, "<", 0, JOP_NUMERIC_LESS_THAN);
templatize_comparator(env, JANET_FUN_GTE, ">=", 0, JOP_NUMERIC_GREATER_THAN_EQUAL);
templatize_comparator(env, JANET_FUN_LTE, "<=", 0, JOP_NUMERIC_LESS_THAN_EQUAL);
templatize_comparator(env, JANET_FUN_EQ, "==", 0, JOP_NUMERIC_EQUAL);
templatize_comparator(env, JANET_FUN_NEQ, "not==", 1, JOP_NUMERIC_EQUAL);
templatize_comparator(env, JANET_FUN_ORDER_GT, "order>", 0, JOP_GREATER_THAN,
"(order> & xs)\n\n"
"Check if xs is strictly descending according to a total order "
"over all values. Returns a boolean.");
templatize_comparator(env, JANET_FUN_ORDER_LT, "order<", 0, JOP_LESS_THAN,
"(order< & xs)\n\n"
"Check if xs is strictly increasing according to a total order "
"over all values. Returns a boolean.");
templatize_comparator(env, JANET_FUN_ORDER_GTE, "order>=", 1, JOP_LESS_THAN,
"(order>= & xs)\n\n"
"Check if xs is not increasing according to a total order "
"over all values. Returns a boolean.");
templatize_comparator(env, JANET_FUN_ORDER_LTE, "order<=", 1, JOP_GREATER_THAN,
"(order<= & xs)\n\n"
"Check if xs is not decreasing according to a total order "
"over all values. Returns a boolean.");
templatize_comparator(env, JANET_FUN_ORDER_EQ, "=", 0, JOP_EQUALS,
"(= & xs)\n\n"
"Returns true if all values in xs are the same, false otherwise.");
templatize_comparator(env, JANET_FUN_ORDER_NEQ, "not=", 1, JOP_EQUALS,
"(not= & xs)\n\n"
"Return true if any values in xs are not equal, otherwise false.");
templatize_comparator(env, JANET_FUN_GT, ">", 0, JOP_NUMERIC_GREATER_THAN,
"(> & xs)\n\n"
"Check if xs is in numerically descending order. Returns a boolean.");
templatize_comparator(env, JANET_FUN_LT, "<", 0, JOP_NUMERIC_LESS_THAN,
"(< & xs)\n\n"
"Check if xs is in numerically ascending order. Returns a boolean.");
templatize_comparator(env, JANET_FUN_GTE, ">=", 0, JOP_NUMERIC_GREATER_THAN_EQUAL,
"(>= & xs)\n\n"
"Check if xs is in numerically non-ascending order. Returns a boolean.");
templatize_comparator(env, JANET_FUN_LTE, "<=", 0, JOP_NUMERIC_LESS_THAN_EQUAL,
"(<= & xs)\n\n"
"Check if xs is in numerically non-descending order. Returns a boolean.");
templatize_comparator(env, JANET_FUN_EQ, "==", 0, JOP_NUMERIC_EQUAL,
"(== & xs)\n\n"
"Check if all values in xs are numerically equal (4.0 == 4). Returns a boolean.");
templatize_comparator(env, JANET_FUN_NEQ, "not==", 1, JOP_NUMERIC_EQUAL,
"(not== & xs)\n\n"
"Check if any values in xs are not numerically equal (3.0 not== 4). Returns a boolean.");
/* Platform detection */
janet_def(env, "janet.version", janet_cstringv(JANET_VERSION), NULL);
janet_def(env, "janet.version", janet_cstringv(JANET_VERSION),
"The version number of the running janet program.");
/* Set as gc root */
janet_gcroot(janet_wrap_table(env));
@ -697,7 +797,7 @@ JanetTable *janet_core_env(void) {
}
/* Allow references to the environment */
janet_def(env, "_env", ret, NULL);
janet_def(env, "_env", ret, "The environment table for the current scope.");
/* Run bootstrap source */
janet_dobytes(env, janet_gen_core, sizeof(janet_gen_core), "core.janet", NULL);

View File

@ -774,15 +774,59 @@ static int cfun_state(JanetArgs args) {
}
static const JanetReg cfuns[] = {
{"parser.new", cfun_parser, NULL},
{"parser.produce", cfun_produce, NULL},
{"parser.consume", cfun_consume, NULL},
{"parser.byte", cfun_byte, NULL},
{"parser.error", cfun_error, NULL},
{"parser.status", cfun_status, NULL},
{"parser.flush", cfun_flush, NULL},
{"parser.state", cfun_state, NULL},
{"parser.where", cfun_where, NULL},
{"parser.new", cfun_parser,
"(parser.new)\n\n"
"Creates and returns a new parser object. Parsers are state machines "
"that can receive bytes, and generate a stream of janet values. "
},
{"parser.produce", cfun_produce,
"(parser.produce parser)\n\n"
"Dequeue the next value in the parse queue. Will return nil if "
"no parsed values are in the queue, otherwise will dequeue the "
"next value."
},
{"parser.consume", cfun_consume,
"(parser.consume parser bytes)\n\n"
"Input bytes into the parser and parse them. Will not throw errors "
"if there is a parse error. Returns the parser."
},
{"parser.byte", cfun_byte,
"(parser.byte parser b)\n\n"
"Input a single byte into the parser byte stream. Returns the parser."
},
{"parser.error", cfun_error,
"(parser.error parser)\n\n"
"If the parser is in the error state, returns the message asscoiated with "
"that error. Otherwise, returns nil."
},
{"parser.status", cfun_status,
"(parser.status parser)\n\n"
"Gets the current status of the parser state machine. The status will "
"be one of:\n\n"
"\t:full - there are values in the parse queue to be consumed.\n"
"\t:pending - no values in the queue but a value is being parsed.\n"
"\t:error - a parsing error was encountered.\n"
"\t:root - the parser can either read more values or safely terminate."
},
{"parser.flush", cfun_flush,
"(parser.flush parser)\n\n"
"Clears the parser state and parse queue. Can be used to reset the parser "
"if an error was encountered. Does not reset the line and column counter, so "
"to begin parsing in a new context, create a new parser."
},
{"parser.state", cfun_state,
"(parser.state parser)\n\n"
"Returns a string representation of the internal state of the parser. "
"Each byte in the string represents a nested data structure. For example, "
"if the parser state is '([\"', then the parser is in the middle of parsing a "
"string inside of square brackets inside parens. Can be used to augment a repl prompt."
},
{"parser.where", cfun_where,
"(parser.where parser)\n\n"
"Returns the current line number and column number of the parser's location "
"in the byte stream as a tuple (line, column). Lines and columns are counted from "
"1, (the first byte is line1, column 1) and a newline is considered ascii 0x0A."
},
{NULL, NULL, NULL}
};

View File

@ -1040,21 +1040,97 @@ static int cfun_number(JanetArgs args) {
}
static const JanetReg cfuns[] = {
{"string.slice", cfun_slice, NULL},
{"string.repeat", cfun_repeat, NULL},
{"string.bytes", cfun_bytes, NULL},
{"string.from-bytes", cfun_frombytes, NULL},
{"string.ascii-lower", cfun_asciilower, NULL},
{"string.ascii-upper", cfun_asciiupper, NULL},
{"string.reverse", cfun_reverse, NULL},
{"string.find", cfun_find, NULL},
{"string.find-all", cfun_findall, NULL},
{"string.replace", cfun_replace, NULL},
{"string.replace-all", cfun_replaceall, NULL},
{"string.split", cfun_split, NULL},
{"string.check-set", cfun_checkset, NULL},
{"string.join", cfun_join, NULL},
{"string.number", cfun_number, NULL},
{"string.slice", cfun_slice,
"(string.slice bytes [,start=0 [,end=(length str)]])\n\n"
"Returns a substring from a byte sequence. The substring is from "
"index start inclusive to index end exclusive. All indexing "
"is from 0. 'start' and 'end' can also be negative to indicate indexing "
"from the end of the string."
},
{"string.repeat", cfun_repeat,
"(string.repeat bytes n)\n\n"
"Returns a string that is n copies of bytes concatenated."
},
{"string.bytes", cfun_bytes,
"(string.bytes str)\n\n"
"Returns an array of integers that are the byte values of the string."
},
{"string.from-bytes", cfun_frombytes,
"(string.from-bytes byte-array)\n\n"
"Creates a string from an array of integers with byte values. All integers "
"will be coerced to the range of 1 byte 0-255."
},
{"string.ascii-lower", cfun_asciilower,
"(string.ascii-lower str)\n\n"
"Returns a new string where all bytes are replaced with the "
"lowercase version of themselves in ascii. Does only a very simple "
"case check, meaning no unicode support."
},
{"string.ascii-upper", cfun_asciiupper,
"(string.ascii-upper str)\n\n"
"Returns a new string where all bytes are replaced with the "
"uppercase version of themselves in ascii. Does only a very simple "
"case check, meaning no unicode support."
},
{"string.reverse", cfun_reverse,
"(string.reverse str)\n\n"
"Returns a string that is the reversed version of str."
},
{"string.find", cfun_find,
"(string.find patt str)\n\n"
"Searches for the first instance of pattern patt in string "
"str. Returns the index of the first character in patt if found, "
"otherwise returns nil."
},
{"string.find-all", cfun_findall,
"(string.find patt str)\n\n"
"Searches for all instances of pattern patt in string "
"str. Returns an array of all indices of found patterns. Overlapping "
"instances of the pattern are not counted, meaning a byte in string "
"will only contribute to finding at most on occurrence of pattern. If no "
"occurrences are found, will return an empty array."
},
{"string.replace", cfun_replace,
"(string.replace patt subst str)\n\n"
"Replace the first occurrence of patt with subst in the the string str. "
"Will return the new string if patt is found, otherwise returns str."
},
{"string.replace-all", cfun_replaceall,
"(string.replace-all patt subst str)\n\n"
"Replace all instances of patt with subst in the string str. "
"Will return the new string if patt is found, otherwise returns str."
},
{"string.split", cfun_split,
"(string.split delim str)\n\n"
"Splits a string str with delimiter delim and returns an array of "
"substrings. The substrings will not contain the delimiter delim. If delim "
"is not found, the returned array will have one element."
},
{"string.check-set", cfun_checkset,
"(string.check-set set str)\n\n"
"Checks if any of the bytes in the string set appear in the string str. "
"Returns true if some bytes in set do appear in str, false if no bytes do."
},
{"string.join", cfun_join,
"(string.join parts [,sep])\n\n"
"Joins an array of strings into one string, optionally separated by "
"a separator string sep."
},
{"string.number", cfun_number,
"(string.number x [,format [,maxlen [,precision]]])\n\n"
"Formats a number as string. The format parameter indicates how "
"to display the number, either as floating point, scientific, or "
"whichever representation is shorter. format can be:\n\n"
"\t:g - (default) shortest representation with lowercase e.\n"
"\t:G - shortest representation with uppercase E.\n"
"\t:e - scientific with lowercase e.\n"
"\t:E - scientific with uppercase E.\n"
"\t:f - floating point representation.\n"
"\t:F - same as :f\n\n"
"The programmer can also specify the max length of the output string "
"and the precision (number of places after decimal) in the output number. "
"Returns a string representation of x."
},
{NULL, NULL, NULL}
};

View File

@ -252,11 +252,33 @@ static int cfun_rawget(JanetArgs args) {
}
static const JanetReg cfuns[] = {
{"table.new", cfun_new, NULL},
{"table.to-struct", cfun_tostruct, NULL},
{"table.getproto", cfun_getproto, NULL},
{"table.setproto", cfun_setproto, NULL},
{"table.rawget", cfun_rawget, NULL},
{"table.new", cfun_new,
"(table.new capacity)\n\n"
"Creates a new empty table with pre-allocated memory "
"for capacity entries. This means that if one knows the number of "
"entries going to go in a table on creation, extra memory allocation "
"can be avoided. Returns the new table."
},
{"table.to-struct", cfun_tostruct,
"(table.to-struct tab)\n\n"
"Convert a table to a struct. Returns a new struct. This function "
"does not take into account prototype tables."
},
{"table.getproto", cfun_getproto,
"(table.getproto tab)\n\n"
"Get the prototype table of a table. Returns nil if a table "
"has no prototype, otherwise returns the prototype."
},
{"table.setproto", cfun_setproto,
"(table.setproto tab proto)\n\n"
"Set the prototype of a table. Returns the original table tab."
},
{"table.rawget", cfun_rawget,
"(table.rawget tab key)\n\n"
"Gets a value from a table without looking at the prototype table. "
"If a table tab does not contain t directly, the function will return "
"nil without checking the prototype. Returns the value in the table."
},
{NULL, NULL, NULL}
};

View File

@ -127,13 +127,16 @@ static int cfun_slice(JanetArgs args) {
static int cfun_prepend(JanetArgs args) {
const Janet *t;
int32_t len;
int32_t len, i;
Janet *n;
JANET_FIXARITY(args, 2);
if (!janet_indexed_view(args.v[0], &t, &len)) JANET_THROW(args, "expected tuple/array");
n = janet_tuple_begin(len + 1);
memcpy(n + 1, t, sizeof(Janet) * len);
n[0] = args.v[1];
JANET_MINARITY(args, 1);
if (!janet_indexed_view(args.v[0], &t, &len))
JANET_THROW(args, "expected tuple/array");
n = janet_tuple_begin(len - 1 + args.n);
memcpy(n - 1 + args.n, t, sizeof(Janet) * len);
for (i = 1; i < args.n; i++) {
n[args.n - i - 1] = args.v[i];
}
JANET_RETURN_TUPLE(args, janet_tuple_end(n));
}
@ -141,18 +144,34 @@ static int cfun_append(JanetArgs args) {
const Janet *t;
int32_t len;
Janet *n;
JANET_FIXARITY(args, 2);
if (!janet_indexed_view(args.v[0], &t, &len)) JANET_THROW(args, "expected tuple/array");
n = janet_tuple_begin(len + 1);
JANET_MINARITY(args, 1);
if (!janet_indexed_view(args.v[0], &t, &len))
JANET_THROW(args, "expected tuple/array");
n = janet_tuple_begin(len - 1 + args.n);
memcpy(n, t, sizeof(Janet) * len);
n[len] = args.v[1];
memcpy(n + len, args.v + 1, sizeof(Janet) * (args.n - 1));
JANET_RETURN_TUPLE(args, janet_tuple_end(n));
}
static const JanetReg cfuns[] = {
{"tuple.slice", cfun_slice, NULL},
{"tuple.append", cfun_append, NULL},
{"tuple.prepend", cfun_prepend, NULL},
{"tuple.slice", cfun_slice,
"(tuple.slice arrtup [,start=0 [,end=(length arrtup)]])\n\n"
"Take a sub sequence of an array or tuple from index start "
"inclusive to index end exclusive. If start or end are not provided, "
"they default to 0 and the length of arrtup respectively."
"Returns the new tuple."
},
{"tuple.append", cfun_append,
"(tuple.append tup & items)\n\n"
"Returns a new tuple that is the result of appending "
"each element in items to tup."
},
{"tuple.prepend", cfun_prepend,
"(tuple.prepend tup & items)\n\n"
"Prepends each element in items to tuple and "
"returns a new tuple. Items are prepended such that the "
"last element in items is the first element in the new tuple."
},
{NULL, NULL, NULL}
};