mirror of
https://github.com/janet-lang/janet
synced 2024-11-18 06:34:48 +00:00
Add lots of documentation for all functions.
This commit is contained in:
parent
fe7c591c40
commit
fcbd24cedc
@ -715,7 +715,7 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
|
||||
/* Set environments */
|
||||
def->environments =
|
||||
realloc(def->environments, def->environments_length * sizeof(int32_t));
|
||||
|
||||
|
||||
/* Verify the func def */
|
||||
if (janet_verify(def)) {
|
||||
janet_asm_error(&a, "invalid assembly");
|
||||
@ -924,7 +924,7 @@ static int cfun_disasm(JanetArgs args) {
|
||||
}
|
||||
|
||||
static const JanetReg cfuns[] = {
|
||||
{"asm", cfun_asm,
|
||||
{"asm", cfun_asm,
|
||||
"(asm assembly)\n\n"
|
||||
"Returns a new function that is the compiled result of the assembly.\n"
|
||||
"The syntax for the assembly can be found on the janet wiki. Will throw an\n"
|
||||
|
@ -268,12 +268,12 @@ static int cfun_slice(JanetArgs args) {
|
||||
}
|
||||
|
||||
static const JanetReg cfuns[] = {
|
||||
{"buffer.new", cfun_new,
|
||||
{"buffer.new", cfun_new,
|
||||
"(buffer.new capacity)\n\n"
|
||||
"Creates a new, empty buffer with enough memory for capacity bytes. "
|
||||
"Returns a new buffer."
|
||||
},
|
||||
{"buffer.push-byte", cfun_u8,
|
||||
{"buffer.push-byte", cfun_u8,
|
||||
"(buffer.push-byte buffer x)\n\n"
|
||||
"Append a byte to a buffer. Will expand the buffer as necessary. "
|
||||
"Returns the modified buffer. Will throw an error if the buffer overflows."
|
||||
@ -290,11 +290,11 @@ static const JanetReg cfuns[] = {
|
||||
"to strings before being pushed. Returns the modified buffer. "
|
||||
"Will throw an error if the buffer overflows."
|
||||
},
|
||||
{"buffer.popn", cfun_popn,
|
||||
{"buffer.popn", cfun_popn,
|
||||
"(buffer.popn buffer n)\n\n"
|
||||
"Removes the last n bytes from the buffer. Returns the modified buffer."
|
||||
},
|
||||
{"buffer.clear", cfun_clear,
|
||||
{"buffer.clear", cfun_clear,
|
||||
"(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."
|
||||
|
@ -407,7 +407,7 @@ static JanetSlot janetc_array(JanetFopts opts, Janet x) {
|
||||
|
||||
static JanetSlot janetc_tablector(JanetFopts opts, Janet x, int op) {
|
||||
JanetCompiler *c = opts.compiler;
|
||||
return janetc_maker(opts,
|
||||
return janetc_maker(opts,
|
||||
janetc_toslotskv(c, x),
|
||||
op);
|
||||
}
|
||||
@ -432,9 +432,9 @@ static JanetSlot janetc_symbol(JanetFopts opts, const uint8_t *sym) {
|
||||
/* Expand a macro one time. Also get the special form compiler if we
|
||||
* find that instead. */
|
||||
static int macroexpand1(
|
||||
JanetCompiler *c,
|
||||
Janet x,
|
||||
Janet *out,
|
||||
JanetCompiler *c,
|
||||
Janet x,
|
||||
Janet *out,
|
||||
const JanetSpecial **spec) {
|
||||
if (!janet_checktype(x, JANET_TUPLE))
|
||||
return 0;
|
||||
@ -466,9 +466,9 @@ static int macroexpand1(
|
||||
JanetFunction *macro = janet_unwrap_function(macroval);
|
||||
int lock = janet_gclock();
|
||||
JanetSignal status = janet_call(
|
||||
macro,
|
||||
macro,
|
||||
janet_tuple_length(form) - 1,
|
||||
form + 1,
|
||||
form + 1,
|
||||
&x,
|
||||
&fiberp);
|
||||
janet_gcunlock(lock);
|
||||
@ -612,7 +612,7 @@ JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) {
|
||||
if (scope->flags & JANET_SCOPE_ENV) {
|
||||
def->flags |= JANET_FUNCDEF_FLAG_NEEDSENV;
|
||||
}
|
||||
|
||||
|
||||
/* Pop the scope */
|
||||
janetc_popscope(c);
|
||||
|
||||
@ -706,7 +706,7 @@ static int cfun(JanetArgs args) {
|
||||
}
|
||||
|
||||
static const JanetReg cfuns[] = {
|
||||
{"compile", cfun,
|
||||
{"compile", cfun,
|
||||
"(compile ast)\n\n"
|
||||
"Compiles an Abstract Sytnax Tree (ast) into a janet function. "
|
||||
"Pair the compile function with parsing functionality to implement "
|
||||
@ -718,6 +718,6 @@ static const JanetReg cfuns[] = {
|
||||
|
||||
int janet_lib_compile(JanetArgs args) {
|
||||
JanetTable *env = janet_env(args);
|
||||
janet_cfuns(env, NULL, cfuns);
|
||||
janet_cfuns(env, NULL, cfuns);
|
||||
return 0;
|
||||
}
|
||||
|
@ -49,14 +49,14 @@
|
||||
#define JANET_FUN_ORDER_GT 20
|
||||
#define JANET_FUN_ORDER_LT 21
|
||||
#define JANET_FUN_ORDER_GTE 22
|
||||
#define JANET_FUN_ORDER_LTE 23
|
||||
#define JANET_FUN_ORDER_EQ 24
|
||||
#define JANET_FUN_ORDER_LTE 23
|
||||
#define JANET_FUN_ORDER_EQ 24
|
||||
#define JANET_FUN_ORDER_NEQ 25
|
||||
#define JANET_FUN_GT 26
|
||||
#define JANET_FUN_LT 27
|
||||
#define JANET_FUN_GTE 28
|
||||
#define JANET_FUN_LTE 29
|
||||
#define JANET_FUN_EQ 30
|
||||
#define JANET_FUN_GT 26
|
||||
#define JANET_FUN_LT 27
|
||||
#define JANET_FUN_GTE 28
|
||||
#define JANET_FUN_LTE 29
|
||||
#define JANET_FUN_EQ 30
|
||||
#define JANET_FUN_NEQ 31
|
||||
|
||||
/* Compiler typedefs */
|
||||
@ -135,7 +135,7 @@ struct JanetScope {
|
||||
|
||||
/* Compilation state */
|
||||
struct JanetCompiler {
|
||||
|
||||
|
||||
/* Pointer to current scope */
|
||||
JanetScope *scope;
|
||||
|
||||
|
@ -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
|
||||
|
@ -284,105 +284,105 @@ static int janet_core_hash(JanetArgs args) {
|
||||
}
|
||||
|
||||
static const JanetReg cfuns[] = {
|
||||
{"native", janet_core_native,
|
||||
{"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."
|
||||
},
|
||||
{"print", janet_core_print,
|
||||
{"print", janet_core_print,
|
||||
"(print & xs)\n\n"
|
||||
"Print values to the console (standard out). Value are converted "
|
||||
"to strings if they are not already. After printing all values, a "
|
||||
"newline character is printed. Returns nil."
|
||||
},
|
||||
{"describe", janet_core_describe,
|
||||
{"describe", janet_core_describe,
|
||||
"(describe x)\n\n"
|
||||
"Returns a string that is a human readable description of a value x."
|
||||
},
|
||||
{"string", janet_core_string,
|
||||
{"string", janet_core_string,
|
||||
"(string & parts)\n\n"
|
||||
"Creates a string by concatenating values together. Values are "
|
||||
"converted to bytes via describe if they are not byte sequences. "
|
||||
"Returns the new string."
|
||||
},
|
||||
{"symbol", janet_core_symbol,
|
||||
{"symbol", janet_core_symbol,
|
||||
"(symbol & xs)\n\n"
|
||||
"Creates a symbol by concatenating values together. Values are "
|
||||
"converted to bytes via describe if they are not byte sequences. Returns "
|
||||
"the new symbol."
|
||||
},
|
||||
{"buffer", janet_core_buffer,
|
||||
{"buffer", janet_core_buffer,
|
||||
"(buffer & xs)\n\n"
|
||||
"Creates a new buffer by concatenating values together. Values are "
|
||||
"converted to bytes via describe if they are not byte sequences. Returns "
|
||||
"the new symbol."
|
||||
},
|
||||
{"table", janet_core_table,
|
||||
{"table", janet_core_table,
|
||||
"(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,
|
||||
{"array", janet_core_array,
|
||||
"(array & items)\n\n"
|
||||
"Create a new array that contains items. Returns the new array."
|
||||
},
|
||||
{"scan-number", janet_core_scannumber,
|
||||
{"scan-number", janet_core_scannumber,
|
||||
"(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."
|
||||
},
|
||||
{"scan-integer", janet_core_scaninteger,
|
||||
{"scan-integer", janet_core_scaninteger,
|
||||
"(scan-integer str)\n\n"
|
||||
"Parse an integer from a byte sequence an return that number. The integer "
|
||||
"must be in the same format as integers in janet source code. Will return nil "
|
||||
"on an invalid integer."
|
||||
},
|
||||
{"scan-real", janet_core_scanreal,
|
||||
{"scan-real", janet_core_scanreal,
|
||||
"(scan-real str)\n\n"
|
||||
"Parse a real number from a byte sequence an return that number. 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,
|
||||
{"tuple", janet_core_tuple,
|
||||
"(tuple & items)\n\n"
|
||||
"Creates a new tuple that contains items. Returns the new tuple."
|
||||
},
|
||||
{"struct", janet_core_struct,
|
||||
{"struct", janet_core_struct,
|
||||
"(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,
|
||||
{"gensym", janet_core_gensym,
|
||||
"(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,
|
||||
{"gccollect", janet_core_gccollect,
|
||||
"(gccollect)\n\n"
|
||||
"Run garbage collection. You should probably not call this manually."
|
||||
},
|
||||
{"gcsetinterval", janet_core_gcsetinterval,
|
||||
{"gcsetinterval", janet_core_gcsetinterval,
|
||||
"(gcsetinterval interval)\n\n"
|
||||
"Set an integer number of bytes to allocate before running garbage collection. "
|
||||
"Low values interval will be slower but use less memory. "
|
||||
"High values will be faster but use more memory."
|
||||
},
|
||||
{"gcinterval", janet_core_gcinterval,
|
||||
{"gcinterval", janet_core_gcinterval,
|
||||
"(gcinterval)\n\n"
|
||||
"Returns the integer number of bytes to allocate before running an iteration "
|
||||
"of garbage collection."
|
||||
},
|
||||
{"type", janet_core_type,
|
||||
{"type", janet_core_type,
|
||||
"(type x)\n\n"
|
||||
"Returns the type of x as a keyword symbol. x is one of\n"
|
||||
"\t:nil\n"
|
||||
@ -400,7 +400,7 @@ static const JanetReg cfuns[] = {
|
||||
"\t:function\n"
|
||||
"\t:cfunction"
|
||||
},
|
||||
{"next", janet_core_next,
|
||||
{"next", janet_core_next,
|
||||
"(next dict key)\n\n"
|
||||
"Gets the next key in a struct or table. Can be used to iterate through "
|
||||
"the keys of a data structure in an unspecified order. Keys are guaranteed "
|
||||
@ -408,7 +408,7 @@ static const JanetReg cfuns[] = {
|
||||
"during iteration. If key is nil, next returns the first key. If next "
|
||||
"returns nil, there are no more keys to iterate through. "
|
||||
},
|
||||
{"hash", janet_core_hash,
|
||||
{"hash", janet_core_hash,
|
||||
"(hash value)\n\n"
|
||||
"Gets a hash value for any janet value. The hash is an integer can be used "
|
||||
"as a cheap hash function for all janet objects. If two values are strictly equal, "
|
||||
@ -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);
|
||||
|
@ -162,8 +162,8 @@ static void janetc_moveback(JanetCompiler *c,
|
||||
|
||||
/* Call this to release a register after emitting the instruction. */
|
||||
static void janetc_free_regnear(JanetCompiler *c, JanetSlot s, int32_t reg, JanetcRegisterTemp tag) {
|
||||
if (reg != s.index ||
|
||||
s.envindex >= 0 ||
|
||||
if (reg != s.index ||
|
||||
s.envindex >= 0 ||
|
||||
s.flags & (JANET_SLOT_CONSTANT | JANET_SLOT_REF)) {
|
||||
/* We need to free the temporary slot */
|
||||
janetc_regalloc_freetemp(&c->scope->ra, reg, tag);
|
||||
|
@ -265,7 +265,7 @@ void janet_fiber_cframe(JanetFiber *fiber, JanetCFunction cfun) {
|
||||
void janet_fiber_popframe(JanetFiber *fiber) {
|
||||
JanetStackFrame *frame = janet_fiber_frame(fiber);
|
||||
if (fiber->frame == 0) return;
|
||||
|
||||
|
||||
/* Clean up the frame (detach environments) */
|
||||
if (NULL != frame->func)
|
||||
janet_env_detach(frame->env);
|
||||
@ -305,7 +305,7 @@ static int cfun_new(JanetArgs args) {
|
||||
case ':':
|
||||
break;
|
||||
case 'a':
|
||||
fiber->flags |=
|
||||
fiber->flags |=
|
||||
JANET_FIBER_MASK_DEBUG |
|
||||
JANET_FIBER_MASK_ERROR |
|
||||
JANET_FIBER_MASK_USER |
|
||||
@ -455,7 +455,7 @@ static int cfun_setmaxstack(JanetArgs args) {
|
||||
}
|
||||
|
||||
static const JanetReg cfuns[] = {
|
||||
{"fiber.new", cfun_new,
|
||||
{"fiber.new", cfun_new,
|
||||
"(fiber.new func [,sigmask])\n\n"
|
||||
"Create a new fiber with function body func. Can optionally "
|
||||
"take a set of signals to block from the current parent fiber "
|
||||
@ -472,7 +472,7 @@ static const JanetReg cfuns[] = {
|
||||
"\ty - block yield signals\n"
|
||||
"\t0-9 - block a specific user signal"
|
||||
},
|
||||
{"fiber.status", cfun_status,
|
||||
{"fiber.status", cfun_status,
|
||||
"(fiber.status fib)\n\n"
|
||||
"Get the status of a fiber. The status will be one of:\n\n"
|
||||
"\t:dead - the fiber has finished\n"
|
||||
@ -483,7 +483,7 @@ static const JanetReg cfuns[] = {
|
||||
"\t:alive - the fiber is currently running and cannot be resumed\n"
|
||||
"\t:new - the fiber has just been created and not yet run"
|
||||
},
|
||||
{"fiber.stack", cfun_stack,
|
||||
{"fiber.stack", cfun_stack,
|
||||
"(fiber.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 "
|
||||
@ -498,24 +498,24 @@ static const JanetReg cfuns[] = {
|
||||
"\t:source - string with filename or other identifier for the source code\n"
|
||||
"\t:tail - boolean indicating a tail call"
|
||||
},
|
||||
{"fiber.current", cfun_current,
|
||||
{"fiber.current", cfun_current,
|
||||
"(fiber.current)\n\n"
|
||||
"Returns the currently running fiber."
|
||||
},
|
||||
{"fiber.lineage", cfun_lineage,
|
||||
{"fiber.lineage", cfun_lineage,
|
||||
"(fiber.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."
|
||||
},
|
||||
{"fiber.maxstack", cfun_maxstack,
|
||||
{"fiber.maxstack", cfun_maxstack,
|
||||
"(fiber.maxstack fib)\n\n"
|
||||
"Gets the maximum stack size in janet values allowed for a fiber. While memory for "
|
||||
"the fiber's stack is not allocated up front, the fiber will not allocated more "
|
||||
"than this amount and will throw a stackoverflow error if more memory is needed. "
|
||||
},
|
||||
{"fiber.setmaxstack", cfun_setmaxstack,
|
||||
{"fiber.setmaxstack", cfun_setmaxstack,
|
||||
"(fiber.setmaxstack fib maxstack)\n\n"
|
||||
"Sets the maximum stack size in janet values for a fiber. By default, the "
|
||||
"maximum stacksize is usually 8192."
|
||||
|
@ -207,11 +207,11 @@ static const char *read_chunk(IOFile *iof, JanetBuffer *buffer, int32_t nBytesMa
|
||||
if (!(iof->flags & (IO_READ | IO_UPDATE)))
|
||||
return "file is not readable";
|
||||
/* Ensure buffer size */
|
||||
if (janet_buffer_extra(buffer, nBytesMax))
|
||||
if (janet_buffer_extra(buffer, nBytesMax))
|
||||
return "buffer overflow";
|
||||
size_t ntoread = nBytesMax;
|
||||
size_t nread = fread((char *)(buffer->data + buffer->count), 1, ntoread, iof->file);
|
||||
if (nread != ntoread && ferror(iof->file))
|
||||
if (nread != ntoread && ferror(iof->file))
|
||||
return "could not read file";
|
||||
buffer->count += (int32_t) nread;
|
||||
return NULL;
|
||||
@ -366,7 +366,7 @@ static int janet_io_fseek(JanetArgs args) {
|
||||
}
|
||||
|
||||
static const JanetReg cfuns[] = {
|
||||
{"file.open", janet_io_fopen,
|
||||
{"file.open", janet_io_fopen,
|
||||
"(file.open path [,mode])\n\n"
|
||||
"Open a file. path is files absolute or relative path, and "
|
||||
"mode is a set of flags indicating the mode to open the file in. "
|
||||
@ -379,13 +379,13 @@ static const JanetReg cfuns[] = {
|
||||
"\tb - open the file in binary mode (rather than text mode)\n"
|
||||
"\t+ - append to the file instead of overwriting it"
|
||||
},
|
||||
{"file.close", janet_io_fclose,
|
||||
{"file.close", janet_io_fclose,
|
||||
"(file.close f)\n\n"
|
||||
"Close a file and release all related resources. When you are "
|
||||
"done reading a file, close it to prevent a resource leak and let "
|
||||
"other processes read the file."
|
||||
},
|
||||
{"file.read", janet_io_fread,
|
||||
{"file.read", janet_io_fread,
|
||||
"(file.read f what [,buf])\n\n"
|
||||
"Read a number of bytes from a file into a buffer. A buffer can "
|
||||
"be provided as an optional fourth argument. otherwise a new buffer "
|
||||
@ -396,17 +396,17 @@ static const JanetReg cfuns[] = {
|
||||
"\t:line - read up to and including the next newline character\n"
|
||||
"\tn (integer) - read up to n bytes from the file"
|
||||
},
|
||||
{"file.write", janet_io_fwrite,
|
||||
{"file.write", janet_io_fwrite,
|
||||
"(file.write f bytes)\n\n"
|
||||
"Writes to a file. 'bytes' must be string, buffer, or symbol. Returns the "
|
||||
"file"
|
||||
},
|
||||
{"file.flush", janet_io_fflush,
|
||||
{"file.flush", janet_io_fflush,
|
||||
"(file.flush f)\n\n"
|
||||
"Flush any buffered bytes to the filesystem. In most files, writes are "
|
||||
"buffered for efficiency reasons. Returns the file handle."
|
||||
},
|
||||
{"file.seek", janet_io_fseek,
|
||||
{"file.seek", janet_io_fseek,
|
||||
"(file.seek f [,whence [,n]])\n\n"
|
||||
"Jump to a relative location in the file. 'whence' must be one of\n\n"
|
||||
"\t:cur - jump relative to the current file location\n"
|
||||
@ -416,7 +416,7 @@ static const JanetReg cfuns[] = {
|
||||
"for the relative number of bytes to seek in the file. n may be a real "
|
||||
"number to handle large files of more the 4GB. Returns the file handle."
|
||||
},
|
||||
{"file.popen", janet_io_popen,
|
||||
{"file.popen", janet_io_popen,
|
||||
"(file.popen path [,mode])\n\n"
|
||||
"Open a file that is backed by a process. The file must be opened in either "
|
||||
"the :r (read) or the :w (write) mode. In :r mode, the stdout of the "
|
||||
@ -433,7 +433,7 @@ int janet_lib_io(JanetArgs args) {
|
||||
|
||||
/* stdout */
|
||||
janet_def(env, "stdout",
|
||||
makef(stdout, IO_APPEND | IO_NOT_CLOSEABLE | IO_SERIALIZABLE),
|
||||
makef(stdout, IO_APPEND | IO_NOT_CLOSEABLE | IO_SERIALIZABLE),
|
||||
"The standard output file.");
|
||||
|
||||
|
||||
|
@ -206,11 +206,11 @@ static void marshal_one_def(MarshalState *st, JanetFuncDef *def, int flags) {
|
||||
marshal_one(st, janet_wrap_string(def->name), flags);
|
||||
if (def->flags & JANET_FUNCDEF_FLAG_HASSOURCE)
|
||||
marshal_one(st, janet_wrap_string(def->source), flags);
|
||||
|
||||
|
||||
/* marshal constants */
|
||||
for (int32_t i = 0; i < def->constants_length; i++)
|
||||
marshal_one(st, def->constants[i], flags);
|
||||
|
||||
|
||||
/* marshal the bytecode */
|
||||
for (int32_t i = 0; i < def->bytecode_length; i++) {
|
||||
pushbyte(st, def->bytecode[i] & 0xFF);
|
||||
@ -218,11 +218,11 @@ static void marshal_one_def(MarshalState *st, JanetFuncDef *def, int flags) {
|
||||
pushbyte(st, (def->bytecode[i] >> 16) & 0xFF);
|
||||
pushbyte(st, (def->bytecode[i] >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
|
||||
/* marshal the environments if needed */
|
||||
for (int32_t i = 0; i < def->environments_length; i++)
|
||||
pushint(st, def->environments[i]);
|
||||
|
||||
|
||||
/* marshal the sub funcdefs if needed */
|
||||
for (int32_t i = 0; i < def->defs_length; i++)
|
||||
marshal_one_def(st, def->defs[i], flags);
|
||||
@ -457,7 +457,7 @@ done:
|
||||
|
||||
nyi:
|
||||
longjmp(st->err, MR_NYI);
|
||||
|
||||
|
||||
noregval:
|
||||
longjmp(st->err, MR_NRV);
|
||||
}
|
||||
@ -469,7 +469,7 @@ int janet_marshal(
|
||||
JanetTable *rreg,
|
||||
int flags) {
|
||||
int status;
|
||||
MarshalState st;
|
||||
MarshalState st;
|
||||
st.buf = buf;
|
||||
st.nextid = 0;
|
||||
st.seen_defs = NULL;
|
||||
@ -641,7 +641,7 @@ static const uint8_t *unmarshal_one_def(
|
||||
int32_t constants_length = 0;
|
||||
int32_t environments_length = 0;
|
||||
int32_t defs_length = 0;
|
||||
|
||||
|
||||
/* Read flags and other fixed values */
|
||||
def->flags = readint(st, &data);
|
||||
def->slotcount = readint(st, &data);
|
||||
@ -668,7 +668,7 @@ static const uint8_t *unmarshal_one_def(
|
||||
if (!janet_checktype(x, JANET_STRING)) longjmp(st->err, UMR_EXPECTED_STRING);
|
||||
def->source = janet_unwrap_string(x);
|
||||
}
|
||||
|
||||
|
||||
/* Unmarshal constants */
|
||||
if (constants_length) {
|
||||
def->constants = malloc(sizeof(Janet) * constants_length);
|
||||
@ -681,7 +681,7 @@ static const uint8_t *unmarshal_one_def(
|
||||
def->constants = NULL;
|
||||
}
|
||||
def->constants_length = constants_length;
|
||||
|
||||
|
||||
/* Unmarshal bytecode */
|
||||
def->bytecode = malloc(sizeof(uint32_t) * bytecode_length);
|
||||
if (!def->bytecode) {
|
||||
@ -689,7 +689,7 @@ static const uint8_t *unmarshal_one_def(
|
||||
}
|
||||
for (int32_t i = 0; i < bytecode_length; i++) {
|
||||
if (data + 4 > end) longjmp(st->err, UMR_EOS);
|
||||
def->bytecode[i] =
|
||||
def->bytecode[i] =
|
||||
(uint32_t)(data[0]) |
|
||||
((uint32_t)(data[1]) << 8) |
|
||||
((uint32_t)(data[2]) << 16) |
|
||||
@ -697,7 +697,7 @@ static const uint8_t *unmarshal_one_def(
|
||||
data += 4;
|
||||
}
|
||||
def->bytecode_length = bytecode_length;
|
||||
|
||||
|
||||
/* Unmarshal environments */
|
||||
if (def->flags & JANET_FUNCDEF_FLAG_HASENVS) {
|
||||
def->environments = calloc(1, sizeof(int32_t) * environments_length);
|
||||
@ -711,7 +711,7 @@ static const uint8_t *unmarshal_one_def(
|
||||
def->environments = NULL;
|
||||
}
|
||||
def->environments_length = environments_length;
|
||||
|
||||
|
||||
/* Unmarshal sub funcdefs */
|
||||
if (def->flags & JANET_FUNCDEF_FLAG_HASDEFS) {
|
||||
def->defs = calloc(1, sizeof(JanetFuncDef *) * defs_length);
|
||||
@ -719,13 +719,13 @@ static const uint8_t *unmarshal_one_def(
|
||||
JANET_OUT_OF_MEMORY;
|
||||
}
|
||||
for (int32_t i = 0; i < defs_length; i++) {
|
||||
data = unmarshal_one_def(st, data, def->defs + i, flags + 1);
|
||||
data = unmarshal_one_def(st, data, def->defs + i, flags + 1);
|
||||
}
|
||||
} else {
|
||||
def->defs = NULL;
|
||||
}
|
||||
def->defs_length = defs_length;
|
||||
|
||||
|
||||
/* Unmarshal source maps if needed */
|
||||
if (def->flags & JANET_FUNCDEF_FLAG_HASSOURCEMAP) {
|
||||
def->sourcemap = malloc(sizeof(JanetSourceMapping) * bytecode_length);
|
||||
@ -738,11 +738,11 @@ static const uint8_t *unmarshal_one_def(
|
||||
}
|
||||
} else {
|
||||
def->sourcemap = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Validate */
|
||||
if (janet_verify(def)) longjmp(st->err, UMR_INVALID_BYTECODE);
|
||||
|
||||
|
||||
/* Set def */
|
||||
*out = def;
|
||||
}
|
||||
@ -1061,14 +1061,14 @@ static const uint8_t *unmarshal_one(
|
||||
|
||||
int janet_unmarshal(
|
||||
const uint8_t *bytes,
|
||||
size_t len,
|
||||
int flags,
|
||||
Janet *out,
|
||||
size_t len,
|
||||
int flags,
|
||||
Janet *out,
|
||||
JanetTable *reg,
|
||||
const uint8_t **next) {
|
||||
int status;
|
||||
/* Avoid longjmp clobber warning in GCC */
|
||||
UnmarshalState st;
|
||||
UnmarshalState st;
|
||||
st.end = bytes + len;
|
||||
st.lookup_defs = NULL;
|
||||
st.lookup_envs = NULL;
|
||||
@ -1144,7 +1144,7 @@ static int cfun_unmarshal(JanetArgs args) {
|
||||
}
|
||||
|
||||
static const JanetReg cfuns[] = {
|
||||
{"marshal", cfun_marshal,
|
||||
{"marshal", cfun_marshal,
|
||||
"(marshal x [,reverse-lookup [,buffer]])\n\n"
|
||||
"Marshal a janet value into a buffer and return the buffer. The buffer "
|
||||
"can the later be unmarshalled to reconstruct the initial value. "
|
||||
@ -1153,13 +1153,13 @@ static const JanetReg cfuns[] = {
|
||||
"lookup table can be used to recover the origrinal janet value when "
|
||||
"unmarshaling."
|
||||
},
|
||||
{"unmarshal", cfun_unmarshal,
|
||||
{"unmarshal", cfun_unmarshal,
|
||||
"(unmarshal buffer [,lookup])\n\n"
|
||||
"Unmarshal a janet value from a buffer. An optional lookup table "
|
||||
"can be provided to allow for aliases to be resolved. Returns the value "
|
||||
"unmarshaled from the buffer."
|
||||
},
|
||||
{"env-lookup", cfun_env_lookup,
|
||||
{"env-lookup", cfun_env_lookup,
|
||||
"(env-lookup env)\n\n"
|
||||
"Creates a forward lookup table for unmarshaling from an environment. "
|
||||
"To create a reverse lookup table, use the invert function to swap keys "
|
||||
|
@ -90,7 +90,7 @@ static int os_execute(JanetArgs args) {
|
||||
si.cb = sizeof(si);
|
||||
ZeroMemory(&pi, sizeof(pi));
|
||||
|
||||
// Start the child process.
|
||||
// Start the child process.
|
||||
if(!CreateProcess(NULL,
|
||||
(LPSTR) sys_str,
|
||||
NULL,
|
||||
@ -234,7 +234,7 @@ static int gettime(struct timespec *spec) {
|
||||
spec->tv_nsec = mts.tv_nsec;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#else
|
||||
#define gettime(TV) clock_gettime(CLOCK_MONOTONIC, (TV))
|
||||
#endif
|
||||
|
||||
@ -283,52 +283,52 @@ static int os_cwd(JanetArgs args) {
|
||||
}
|
||||
|
||||
static const JanetReg cfuns[] = {
|
||||
{"os.which", os_which,
|
||||
{"os.which", os_which,
|
||||
"(os.which)\n\n"
|
||||
"Check the current operating system. Returns one of:\n\n"
|
||||
"\t:windows - Microsoft Windows\n"
|
||||
"\t:macos - Apple macos\n"
|
||||
"\t:posix - A POSIX compatible system (default)"
|
||||
},
|
||||
{"os.execute", os_execute,
|
||||
{"os.execute", os_execute,
|
||||
"(os.execute program & args)\n\n"
|
||||
"Execute a program on the system and pass it string arguments. Returns "
|
||||
"the exit status of the program."
|
||||
},
|
||||
{"os.shell", os_shell,
|
||||
{"os.shell", os_shell,
|
||||
"(os.shell str)\n\n"
|
||||
"Pass a command string str directly to the system shell."
|
||||
},
|
||||
{"os.exit", os_exit,
|
||||
{"os.exit", os_exit,
|
||||
"(os.exit x)\n\n"
|
||||
"Exit from janet with an exit code equal to x. If x is not an integer, "
|
||||
"the exit with status equal the hash of x."
|
||||
},
|
||||
{"os.getenv", os_getenv,
|
||||
{"os.getenv", os_getenv,
|
||||
"(os.getenv variable)\n\n"
|
||||
"Get the string value of an environment variable."
|
||||
},
|
||||
{"os.setenv", os_setenv,
|
||||
{"os.setenv", os_setenv,
|
||||
"(os.setenv variable value)\n\n"
|
||||
"Set an environment variable."
|
||||
},
|
||||
{"os.time", os_time,
|
||||
{"os.time", os_time,
|
||||
"(os.time)\n\n"
|
||||
"Get the current time expressed as the number of seconds since "
|
||||
"January 1, 1970, the Unix epoch. Returns a real number."
|
||||
},
|
||||
{"os.clock", os_clock,
|
||||
{"os.clock", os_clock,
|
||||
"(os.clock)\n\n"
|
||||
"Return the number of seconds since some fixed point in time. The clock "
|
||||
"is guaranteed to be non decreased in real time."
|
||||
},
|
||||
{"os.sleep", os_sleep,
|
||||
{"os.sleep", os_sleep,
|
||||
"(os.sleep nsec)\n\n"
|
||||
"Suspend the program for nsec seconds. 'nsec' can be a real number. Returns "
|
||||
"nil."
|
||||
|
||||
|
||||
},
|
||||
{"os.cwd", os_cwd,
|
||||
{"os.cwd", os_cwd,
|
||||
"(os.cwd)\n\n"
|
||||
"Returns the current working directory."
|
||||
},
|
||||
|
@ -32,7 +32,7 @@ static Janet quote(Janet x) {
|
||||
|
||||
/* Check if a character is whitespace */
|
||||
static int is_whitespace(uint8_t c) {
|
||||
return c == ' '
|
||||
return c == ' '
|
||||
|| c == '\t'
|
||||
|| c == '\n'
|
||||
|| c == '\r'
|
||||
@ -42,7 +42,7 @@ static int is_whitespace(uint8_t c) {
|
||||
|| c == ',';
|
||||
}
|
||||
|
||||
/* Code generated by tools/symcharsgen.c.
|
||||
/* Code generated by tools/symcharsgen.c.
|
||||
* The table contains 256 bits, where each bit is 1
|
||||
* if the corresponding ascci code is a symbol char, and 0
|
||||
* if not. The upper characters are also considered symbol
|
||||
@ -84,7 +84,7 @@ static int valid_utf8(const uint8_t *str, int32_t len) {
|
||||
if ((str[j] >> 6) != 2) return 0;
|
||||
}
|
||||
|
||||
/* Check for overlong encodings */
|
||||
/* Check for overlong encodings */
|
||||
if ((nexti == i + 2) && str[i] < 0xC2) return 0;
|
||||
if ((str[i] == 0xE0) && str[i + 1] < 0xA0) return 0;
|
||||
if ((str[i] == 0xF0) && str[i + 1] < 0x90) return 0;
|
||||
@ -192,15 +192,15 @@ static int checkescape(uint8_t c) {
|
||||
switch (c) {
|
||||
default: return -1;
|
||||
case 'x': return 1;
|
||||
case 'n': return '\n';
|
||||
case 't': return '\t';
|
||||
case 'r': return '\r';
|
||||
case '0': return '\0';
|
||||
case 'z': return '\0';
|
||||
case 'n': return '\n';
|
||||
case 't': return '\t';
|
||||
case 'r': return '\r';
|
||||
case '0': return '\0';
|
||||
case 'z': return '\0';
|
||||
case 'f': return '\f';
|
||||
case 'e': return 27;
|
||||
case '"': return '"';
|
||||
case '\\': return '\\';
|
||||
case '"': return '"';
|
||||
case '\\': return '\\';
|
||||
}
|
||||
}
|
||||
|
||||
@ -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}
|
||||
};
|
||||
|
||||
|
@ -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}
|
||||
};
|
||||
|
||||
|
@ -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}
|
||||
};
|
||||
|
||||
|
@ -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}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user