mirror of
https://github.com/janet-lang/janet
synced 2025-06-05 16:14:12 +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 */
|
/* Set environments */
|
||||||
def->environments =
|
def->environments =
|
||||||
realloc(def->environments, def->environments_length * sizeof(int32_t));
|
realloc(def->environments, def->environments_length * sizeof(int32_t));
|
||||||
|
|
||||||
/* Verify the func def */
|
/* Verify the func def */
|
||||||
if (janet_verify(def)) {
|
if (janet_verify(def)) {
|
||||||
janet_asm_error(&a, "invalid assembly");
|
janet_asm_error(&a, "invalid assembly");
|
||||||
@ -924,7 +924,7 @@ static int cfun_disasm(JanetArgs args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const JanetReg cfuns[] = {
|
static const JanetReg cfuns[] = {
|
||||||
{"asm", cfun_asm,
|
{"asm", cfun_asm,
|
||||||
"(asm assembly)\n\n"
|
"(asm assembly)\n\n"
|
||||||
"Returns a new function that is the compiled result of the assembly.\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"
|
"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[] = {
|
static const JanetReg cfuns[] = {
|
||||||
{"buffer.new", cfun_new,
|
{"buffer.new", cfun_new,
|
||||||
"(buffer.new capacity)\n\n"
|
"(buffer.new capacity)\n\n"
|
||||||
"Creates a new, empty buffer with enough memory for capacity bytes. "
|
"Creates a new, empty buffer with enough memory for capacity bytes. "
|
||||||
"Returns a new buffer."
|
"Returns a new buffer."
|
||||||
},
|
},
|
||||||
{"buffer.push-byte", cfun_u8,
|
{"buffer.push-byte", cfun_u8,
|
||||||
"(buffer.push-byte buffer x)\n\n"
|
"(buffer.push-byte buffer x)\n\n"
|
||||||
"Append a byte to a buffer. Will expand the buffer as necessary. "
|
"Append a byte to a buffer. Will expand the buffer as necessary. "
|
||||||
"Returns the modified buffer. Will throw an error if the buffer overflows."
|
"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. "
|
"to strings before being pushed. Returns the modified buffer. "
|
||||||
"Will throw an error if the buffer overflows."
|
"Will throw an error if the buffer overflows."
|
||||||
},
|
},
|
||||||
{"buffer.popn", cfun_popn,
|
{"buffer.popn", cfun_popn,
|
||||||
"(buffer.popn buffer n)\n\n"
|
"(buffer.popn buffer n)\n\n"
|
||||||
"Removes the last n bytes from the buffer. Returns the modified buffer."
|
"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"
|
"(buffer.clear buffer)\n\n"
|
||||||
"Sets the size of a buffer to 0 and empties it. The buffer retains "
|
"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."
|
"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) {
|
static JanetSlot janetc_tablector(JanetFopts opts, Janet x, int op) {
|
||||||
JanetCompiler *c = opts.compiler;
|
JanetCompiler *c = opts.compiler;
|
||||||
return janetc_maker(opts,
|
return janetc_maker(opts,
|
||||||
janetc_toslotskv(c, x),
|
janetc_toslotskv(c, x),
|
||||||
op);
|
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
|
/* Expand a macro one time. Also get the special form compiler if we
|
||||||
* find that instead. */
|
* find that instead. */
|
||||||
static int macroexpand1(
|
static int macroexpand1(
|
||||||
JanetCompiler *c,
|
JanetCompiler *c,
|
||||||
Janet x,
|
Janet x,
|
||||||
Janet *out,
|
Janet *out,
|
||||||
const JanetSpecial **spec) {
|
const JanetSpecial **spec) {
|
||||||
if (!janet_checktype(x, JANET_TUPLE))
|
if (!janet_checktype(x, JANET_TUPLE))
|
||||||
return 0;
|
return 0;
|
||||||
@ -466,9 +466,9 @@ static int macroexpand1(
|
|||||||
JanetFunction *macro = janet_unwrap_function(macroval);
|
JanetFunction *macro = janet_unwrap_function(macroval);
|
||||||
int lock = janet_gclock();
|
int lock = janet_gclock();
|
||||||
JanetSignal status = janet_call(
|
JanetSignal status = janet_call(
|
||||||
macro,
|
macro,
|
||||||
janet_tuple_length(form) - 1,
|
janet_tuple_length(form) - 1,
|
||||||
form + 1,
|
form + 1,
|
||||||
&x,
|
&x,
|
||||||
&fiberp);
|
&fiberp);
|
||||||
janet_gcunlock(lock);
|
janet_gcunlock(lock);
|
||||||
@ -612,7 +612,7 @@ JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) {
|
|||||||
if (scope->flags & JANET_SCOPE_ENV) {
|
if (scope->flags & JANET_SCOPE_ENV) {
|
||||||
def->flags |= JANET_FUNCDEF_FLAG_NEEDSENV;
|
def->flags |= JANET_FUNCDEF_FLAG_NEEDSENV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pop the scope */
|
/* Pop the scope */
|
||||||
janetc_popscope(c);
|
janetc_popscope(c);
|
||||||
|
|
||||||
@ -706,7 +706,7 @@ static int cfun(JanetArgs args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const JanetReg cfuns[] = {
|
static const JanetReg cfuns[] = {
|
||||||
{"compile", cfun,
|
{"compile", cfun,
|
||||||
"(compile ast)\n\n"
|
"(compile ast)\n\n"
|
||||||
"Compiles an Abstract Sytnax Tree (ast) into a janet function. "
|
"Compiles an Abstract Sytnax Tree (ast) into a janet function. "
|
||||||
"Pair the compile function with parsing functionality to implement "
|
"Pair the compile function with parsing functionality to implement "
|
||||||
@ -718,6 +718,6 @@ static const JanetReg cfuns[] = {
|
|||||||
|
|
||||||
int janet_lib_compile(JanetArgs args) {
|
int janet_lib_compile(JanetArgs args) {
|
||||||
JanetTable *env = janet_env(args);
|
JanetTable *env = janet_env(args);
|
||||||
janet_cfuns(env, NULL, cfuns);
|
janet_cfuns(env, NULL, cfuns);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -49,14 +49,14 @@
|
|||||||
#define JANET_FUN_ORDER_GT 20
|
#define JANET_FUN_ORDER_GT 20
|
||||||
#define JANET_FUN_ORDER_LT 21
|
#define JANET_FUN_ORDER_LT 21
|
||||||
#define JANET_FUN_ORDER_GTE 22
|
#define JANET_FUN_ORDER_GTE 22
|
||||||
#define JANET_FUN_ORDER_LTE 23
|
#define JANET_FUN_ORDER_LTE 23
|
||||||
#define JANET_FUN_ORDER_EQ 24
|
#define JANET_FUN_ORDER_EQ 24
|
||||||
#define JANET_FUN_ORDER_NEQ 25
|
#define JANET_FUN_ORDER_NEQ 25
|
||||||
#define JANET_FUN_GT 26
|
#define JANET_FUN_GT 26
|
||||||
#define JANET_FUN_LT 27
|
#define JANET_FUN_LT 27
|
||||||
#define JANET_FUN_GTE 28
|
#define JANET_FUN_GTE 28
|
||||||
#define JANET_FUN_LTE 29
|
#define JANET_FUN_LTE 29
|
||||||
#define JANET_FUN_EQ 30
|
#define JANET_FUN_EQ 30
|
||||||
#define JANET_FUN_NEQ 31
|
#define JANET_FUN_NEQ 31
|
||||||
|
|
||||||
/* Compiler typedefs */
|
/* Compiler typedefs */
|
||||||
@ -135,7 +135,7 @@ struct JanetScope {
|
|||||||
|
|
||||||
/* Compilation state */
|
/* Compilation state */
|
||||||
struct JanetCompiler {
|
struct JanetCompiler {
|
||||||
|
|
||||||
/* Pointer to current scope */
|
/* Pointer to current scope */
|
||||||
JanetScope *scope;
|
JanetScope *scope;
|
||||||
|
|
||||||
|
@ -1096,7 +1096,8 @@ value, one key will be ignored."
|
|||||||
@[parent]
|
@[parent]
|
||||||
(def parent (if parent parent _env))
|
(def parent (if parent parent _env))
|
||||||
(def newenv (table.setproto @{} parent))
|
(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)
|
newenv)
|
||||||
|
|
||||||
(defn run-context
|
(defn run-context
|
||||||
|
@ -284,105 +284,105 @@ static int janet_core_hash(JanetArgs args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const JanetReg cfuns[] = {
|
static const JanetReg cfuns[] = {
|
||||||
{"native", janet_core_native,
|
{"native", janet_core_native,
|
||||||
"(native path)\n\n"
|
"(native path)\n\n"
|
||||||
"Load a native module from the given path. The path "
|
"Load a native module from the given path. The path "
|
||||||
"must be an absolute or relative path on the filesystem, and is "
|
"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. "
|
"usually a .so file on Unix systems, and a .dll file on Windows. "
|
||||||
"Returns an environment table that contains functions and other values "
|
"Returns an environment table that contains functions and other values "
|
||||||
"from the native module."
|
"from the native module."
|
||||||
},
|
},
|
||||||
{"print", janet_core_print,
|
{"print", janet_core_print,
|
||||||
"(print & xs)\n\n"
|
"(print & xs)\n\n"
|
||||||
"Print values to the console (standard out). Value are converted "
|
"Print values to the console (standard out). Value are converted "
|
||||||
"to strings if they are not already. After printing all values, a "
|
"to strings if they are not already. After printing all values, a "
|
||||||
"newline character is printed. Returns nil."
|
"newline character is printed. Returns nil."
|
||||||
},
|
},
|
||||||
{"describe", janet_core_describe,
|
{"describe", janet_core_describe,
|
||||||
"(describe x)\n\n"
|
"(describe x)\n\n"
|
||||||
"Returns a string that is a human readable description of a value x."
|
"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"
|
"(string & parts)\n\n"
|
||||||
"Creates a string by concatenating values together. Values are "
|
"Creates a string by concatenating values together. Values are "
|
||||||
"converted to bytes via describe if they are not byte sequences. "
|
"converted to bytes via describe if they are not byte sequences. "
|
||||||
"Returns the new string."
|
"Returns the new string."
|
||||||
},
|
},
|
||||||
{"symbol", janet_core_symbol,
|
{"symbol", janet_core_symbol,
|
||||||
"(symbol & xs)\n\n"
|
"(symbol & xs)\n\n"
|
||||||
"Creates a symbol by concatenating values together. Values are "
|
"Creates a symbol by concatenating values together. Values are "
|
||||||
"converted to bytes via describe if they are not byte sequences. Returns "
|
"converted to bytes via describe if they are not byte sequences. Returns "
|
||||||
"the new symbol."
|
"the new symbol."
|
||||||
},
|
},
|
||||||
{"buffer", janet_core_buffer,
|
{"buffer", janet_core_buffer,
|
||||||
"(buffer & xs)\n\n"
|
"(buffer & xs)\n\n"
|
||||||
"Creates a new buffer by concatenating values together. Values are "
|
"Creates a new buffer by concatenating values together. Values are "
|
||||||
"converted to bytes via describe if they are not byte sequences. Returns "
|
"converted to bytes via describe if they are not byte sequences. Returns "
|
||||||
"the new symbol."
|
"the new symbol."
|
||||||
},
|
},
|
||||||
{"table", janet_core_table,
|
{"table", janet_core_table,
|
||||||
"(table & kvs)\n\n"
|
"(table & kvs)\n\n"
|
||||||
"Creates a new table from a variadic number of keys and values. "
|
"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 "
|
"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 "
|
"an odd number of elements, an error will be thrown. Returns the "
|
||||||
"new table."
|
"new table."
|
||||||
},
|
},
|
||||||
{"array", janet_core_array,
|
{"array", janet_core_array,
|
||||||
"(array & items)\n\n"
|
"(array & items)\n\n"
|
||||||
"Create a new array that contains items. Returns the new array."
|
"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"
|
"(scan-number str)\n\n"
|
||||||
"Parse a number from a byte sequence an return that number, either and integer "
|
"Parse a number from a byte sequence an return that number, either and integer "
|
||||||
"or a real. The number "
|
"or a real. The number "
|
||||||
"must be in the same format as numbers in janet source code. Will return nil "
|
"must be in the same format as numbers in janet source code. Will return nil "
|
||||||
"on an invalid number."
|
"on an invalid number."
|
||||||
},
|
},
|
||||||
{"scan-integer", janet_core_scaninteger,
|
{"scan-integer", janet_core_scaninteger,
|
||||||
"(scan-integer str)\n\n"
|
"(scan-integer str)\n\n"
|
||||||
"Parse an integer from a byte sequence an return that number. The integer "
|
"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 "
|
"must be in the same format as integers in janet source code. Will return nil "
|
||||||
"on an invalid integer."
|
"on an invalid integer."
|
||||||
},
|
},
|
||||||
{"scan-real", janet_core_scanreal,
|
{"scan-real", janet_core_scanreal,
|
||||||
"(scan-real str)\n\n"
|
"(scan-real str)\n\n"
|
||||||
"Parse a real number from a byte sequence an return that number. The number "
|
"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 "
|
"must be in the same format as numbers in janet source code. Will return nil "
|
||||||
"on an invalid number."
|
"on an invalid number."
|
||||||
},
|
},
|
||||||
{"tuple", janet_core_tuple,
|
{"tuple", janet_core_tuple,
|
||||||
"(tuple & items)\n\n"
|
"(tuple & items)\n\n"
|
||||||
"Creates a new tuple that contains items. Returns the new tuple."
|
"Creates a new tuple that contains items. Returns the new tuple."
|
||||||
},
|
},
|
||||||
{"struct", janet_core_struct,
|
{"struct", janet_core_struct,
|
||||||
"(struct & kvs)\n\n"
|
"(struct & kvs)\n\n"
|
||||||
"Create a new struct from a sequence of key value pairs. "
|
"Create a new struct from a sequence of key value pairs. "
|
||||||
"kvs is a sequence k1, v1, k2, v2, k3, v3, ... If kvs has "
|
"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 "
|
"an odd number of elements, an error will be thrown. Returns the "
|
||||||
"new struct."
|
"new struct."
|
||||||
},
|
},
|
||||||
{"gensym", janet_core_gensym,
|
{"gensym", janet_core_gensym,
|
||||||
"(gensym)\n\n"
|
"(gensym)\n\n"
|
||||||
"Returns a new symbol that is unique across the runtime. This means it "
|
"Returns a new symbol that is unique across the runtime. This means it "
|
||||||
"will not collide with any already created symbols during compilation, so "
|
"will not collide with any already created symbols during compilation, so "
|
||||||
"it can be used in macros to generate automatic bindings."
|
"it can be used in macros to generate automatic bindings."
|
||||||
},
|
},
|
||||||
{"gccollect", janet_core_gccollect,
|
{"gccollect", janet_core_gccollect,
|
||||||
"(gccollect)\n\n"
|
"(gccollect)\n\n"
|
||||||
"Run garbage collection. You should probably not call this manually."
|
"Run garbage collection. You should probably not call this manually."
|
||||||
},
|
},
|
||||||
{"gcsetinterval", janet_core_gcsetinterval,
|
{"gcsetinterval", janet_core_gcsetinterval,
|
||||||
"(gcsetinterval interval)\n\n"
|
"(gcsetinterval interval)\n\n"
|
||||||
"Set an integer number of bytes to allocate before running garbage collection. "
|
"Set an integer number of bytes to allocate before running garbage collection. "
|
||||||
"Low values interval will be slower but use less memory. "
|
"Low values interval will be slower but use less memory. "
|
||||||
"High values will be faster but use more memory."
|
"High values will be faster but use more memory."
|
||||||
},
|
},
|
||||||
{"gcinterval", janet_core_gcinterval,
|
{"gcinterval", janet_core_gcinterval,
|
||||||
"(gcinterval)\n\n"
|
"(gcinterval)\n\n"
|
||||||
"Returns the integer number of bytes to allocate before running an iteration "
|
"Returns the integer number of bytes to allocate before running an iteration "
|
||||||
"of garbage collection."
|
"of garbage collection."
|
||||||
},
|
},
|
||||||
{"type", janet_core_type,
|
{"type", janet_core_type,
|
||||||
"(type x)\n\n"
|
"(type x)\n\n"
|
||||||
"Returns the type of x as a keyword symbol. x is one of\n"
|
"Returns the type of x as a keyword symbol. x is one of\n"
|
||||||
"\t:nil\n"
|
"\t:nil\n"
|
||||||
@ -400,7 +400,7 @@ static const JanetReg cfuns[] = {
|
|||||||
"\t:function\n"
|
"\t:function\n"
|
||||||
"\t:cfunction"
|
"\t:cfunction"
|
||||||
},
|
},
|
||||||
{"next", janet_core_next,
|
{"next", janet_core_next,
|
||||||
"(next dict key)\n\n"
|
"(next dict key)\n\n"
|
||||||
"Gets the next key in a struct or table. Can be used to iterate through "
|
"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 "
|
"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 "
|
"during iteration. If key is nil, next returns the first key. If next "
|
||||||
"returns nil, there are no more keys to iterate through. "
|
"returns nil, there are no more keys to iterate through. "
|
||||||
},
|
},
|
||||||
{"hash", janet_core_hash,
|
{"hash", janet_core_hash,
|
||||||
"(hash value)\n\n"
|
"(hash value)\n\n"
|
||||||
"Gets a hash value for any janet value. The hash is an integer can be used "
|
"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, "
|
"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 arity,
|
||||||
int32_t slots,
|
int32_t slots,
|
||||||
const uint32_t *bytecode,
|
const uint32_t *bytecode,
|
||||||
size_t bytecode_size) {
|
size_t bytecode_size,
|
||||||
|
const char *doc) {
|
||||||
JanetFuncDef *def = janet_funcdef_alloc();
|
JanetFuncDef *def = janet_funcdef_alloc();
|
||||||
def->arity = arity;
|
def->arity = arity;
|
||||||
def->flags = flags;
|
def->flags = flags;
|
||||||
@ -437,7 +438,7 @@ static void janet_quick_asm(
|
|||||||
JANET_OUT_OF_MEMORY;
|
JANET_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
memcpy(def->bytecode, bytecode, bytecode_size);
|
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 */
|
/* Macros for easier inline janet assembly */
|
||||||
@ -454,7 +455,8 @@ static void templatize_varop(
|
|||||||
const char *name,
|
const char *name,
|
||||||
int32_t nullary,
|
int32_t nullary,
|
||||||
int32_t unary,
|
int32_t unary,
|
||||||
uint32_t op) {
|
uint32_t op,
|
||||||
|
const char *doc) {
|
||||||
|
|
||||||
/* Variadic operator assembly. Must be templatized for each different opcode. */
|
/* Variadic operator assembly. Must be templatized for each different opcode. */
|
||||||
/* Reg 0: Argument tuple (args) */
|
/* Reg 0: Argument tuple (args) */
|
||||||
@ -504,7 +506,8 @@ static void templatize_varop(
|
|||||||
0,
|
0,
|
||||||
6,
|
6,
|
||||||
varop_asm,
|
varop_asm,
|
||||||
sizeof(varop_asm));
|
sizeof(varop_asm),
|
||||||
|
doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Templatize variadic comparators */
|
/* Templatize variadic comparators */
|
||||||
@ -513,7 +516,8 @@ static void templatize_comparator(
|
|||||||
int32_t flags,
|
int32_t flags,
|
||||||
const char *name,
|
const char *name,
|
||||||
int invert,
|
int invert,
|
||||||
uint32_t op) {
|
uint32_t op,
|
||||||
|
const char *doc) {
|
||||||
|
|
||||||
/* Reg 0: Argument tuple (args) */
|
/* Reg 0: Argument tuple (args) */
|
||||||
/* Reg 1: Argument count (argn) */
|
/* Reg 1: Argument count (argn) */
|
||||||
@ -555,7 +559,8 @@ static void templatize_comparator(
|
|||||||
0,
|
0,
|
||||||
6,
|
6,
|
||||||
comparator_asm,
|
comparator_asm,
|
||||||
sizeof(comparator_asm));
|
sizeof(comparator_asm),
|
||||||
|
doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make the apply function */
|
/* Make the apply function */
|
||||||
@ -589,7 +594,14 @@ static void make_apply(JanetTable *env) {
|
|||||||
S(JOP_TAILCALL, 0)
|
S(JOP_TAILCALL, 0)
|
||||||
};
|
};
|
||||||
janet_quick_asm(env, JANET_FUN_APPLY | JANET_FUNCDEF_FLAG_VARARG,
|
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) {
|
JanetTable *janet_core_env(void) {
|
||||||
@ -631,44 +643,132 @@ JanetTable *janet_core_env(void) {
|
|||||||
/* Load main functions */
|
/* Load main functions */
|
||||||
janet_cfuns(env, NULL, cfuns);
|
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_YIELD, "debug", 0, 1, debug_asm, sizeof(debug_asm),
|
||||||
janet_quick_asm(env, JANET_FUN_ERROR, "error", 1, 1, error_asm, sizeof(error_asm));
|
"(debug)\n\n"
|
||||||
janet_quick_asm(env, JANET_FUN_YIELD, "yield", 1, 2, yield_asm, sizeof(yield_asm));
|
"Throws a debug signal that can be caught by a parent fiber and used to inspect "
|
||||||
janet_quick_asm(env, JANET_FUN_RESUME, "resume", 2, 2, resume_asm, sizeof(resume_asm));
|
"the running state of the current fiber. Returns nil.");
|
||||||
janet_quick_asm(env, JANET_FUN_GET, "get", 2, 2, get_asm, sizeof(get_asm));
|
janet_quick_asm(env, JANET_FUN_ERROR, "error", 1, 1, error_asm, sizeof(error_asm),
|
||||||
janet_quick_asm(env, JANET_FUN_PUT, "put", 3, 3, put_asm, sizeof(put_asm));
|
"(error e)\n\n"
|
||||||
janet_quick_asm(env, JANET_FUN_LENGTH, "length", 1, 1, length_asm, sizeof(length_asm));
|
"Throws an error e that can be caught and handled by a parent fiber.");
|
||||||
janet_quick_asm(env, JANET_FUN_BNOT, "~", 1, 1, bnot_asm, sizeof(bnot_asm));
|
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);
|
make_apply(env);
|
||||||
|
|
||||||
/* Variadic ops */
|
/* Variadic ops */
|
||||||
templatize_varop(env, JANET_FUN_ADD, "+", 0, 0, JOP_ADD);
|
templatize_varop(env, JANET_FUN_ADD, "+", 0, 0, JOP_ADD,
|
||||||
templatize_varop(env, JANET_FUN_SUBTRACT, "-", 0, 0, JOP_SUBTRACT);
|
"(+ & xs)\n\n"
|
||||||
templatize_varop(env, JANET_FUN_MULTIPLY, "*", 1, 1, JOP_MULTIPLY);
|
"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_DIVIDE, "/", 1, 1, JOP_DIVIDE);
|
templatize_varop(env, JANET_FUN_SUBTRACT, "-", 0, 0, JOP_SUBTRACT,
|
||||||
templatize_varop(env, JANET_FUN_BAND, "&", -1, -1, JOP_BAND);
|
"(- & xs)\n\n"
|
||||||
templatize_varop(env, JANET_FUN_BOR, "|", 0, 0, JOP_BOR);
|
"Returns the difference of xs. If xs is empty, returns 0. If xs has one element, returns the "
|
||||||
templatize_varop(env, JANET_FUN_BXOR, "^", 0, 0, JOP_BXOR);
|
"negative value of that element. Otherwise, returns the first element in xs minus the sum of "
|
||||||
templatize_varop(env, JANET_FUN_LSHIFT, "<<", 1, 1, JOP_SHIFT_LEFT);
|
"the rest of the elements.");
|
||||||
templatize_varop(env, JANET_FUN_RSHIFT, ">>", 1, 1, JOP_SHIFT_RIGHT);
|
templatize_varop(env, JANET_FUN_MULTIPLY, "*", 1, 1, JOP_MULTIPLY,
|
||||||
templatize_varop(env, JANET_FUN_RSHIFTU, ">>>", 1, 1, JOP_SHIFT_RIGHT_UNSIGNED);
|
"(* & 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 */
|
/* Variadic comparators */
|
||||||
templatize_comparator(env, JANET_FUN_ORDER_GT, "order>", 0, JOP_GREATER_THAN);
|
templatize_comparator(env, JANET_FUN_ORDER_GT, "order>", 0, JOP_GREATER_THAN,
|
||||||
templatize_comparator(env, JANET_FUN_ORDER_LT, "order<", 0, JOP_LESS_THAN);
|
"(order> & xs)\n\n"
|
||||||
templatize_comparator(env, JANET_FUN_ORDER_GTE, "order>=", 1, JOP_LESS_THAN);
|
"Check if xs is strictly descending according to a total order "
|
||||||
templatize_comparator(env, JANET_FUN_ORDER_LTE, "order<=", 1, JOP_GREATER_THAN);
|
"over all values. Returns a boolean.");
|
||||||
templatize_comparator(env, JANET_FUN_ORDER_EQ, "=", 0, JOP_EQUALS);
|
templatize_comparator(env, JANET_FUN_ORDER_LT, "order<", 0, JOP_LESS_THAN,
|
||||||
templatize_comparator(env, JANET_FUN_ORDER_NEQ, "not=", 1, JOP_EQUALS);
|
"(order< & xs)\n\n"
|
||||||
templatize_comparator(env, JANET_FUN_GT, ">", 0, JOP_NUMERIC_GREATER_THAN);
|
"Check if xs is strictly increasing according to a total order "
|
||||||
templatize_comparator(env, JANET_FUN_LT, "<", 0, JOP_NUMERIC_LESS_THAN);
|
"over all values. Returns a boolean.");
|
||||||
templatize_comparator(env, JANET_FUN_GTE, ">=", 0, JOP_NUMERIC_GREATER_THAN_EQUAL);
|
templatize_comparator(env, JANET_FUN_ORDER_GTE, "order>=", 1, JOP_LESS_THAN,
|
||||||
templatize_comparator(env, JANET_FUN_LTE, "<=", 0, JOP_NUMERIC_LESS_THAN_EQUAL);
|
"(order>= & xs)\n\n"
|
||||||
templatize_comparator(env, JANET_FUN_EQ, "==", 0, JOP_NUMERIC_EQUAL);
|
"Check if xs is not increasing according to a total order "
|
||||||
templatize_comparator(env, JANET_FUN_NEQ, "not==", 1, JOP_NUMERIC_EQUAL);
|
"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 */
|
/* 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 */
|
/* Set as gc root */
|
||||||
janet_gcroot(janet_wrap_table(env));
|
janet_gcroot(janet_wrap_table(env));
|
||||||
@ -697,7 +797,7 @@ JanetTable *janet_core_env(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Allow references to the environment */
|
/* 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 */
|
/* Run bootstrap source */
|
||||||
janet_dobytes(env, janet_gen_core, sizeof(janet_gen_core), "core.janet", NULL);
|
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. */
|
/* Call this to release a register after emitting the instruction. */
|
||||||
static void janetc_free_regnear(JanetCompiler *c, JanetSlot s, int32_t reg, JanetcRegisterTemp tag) {
|
static void janetc_free_regnear(JanetCompiler *c, JanetSlot s, int32_t reg, JanetcRegisterTemp tag) {
|
||||||
if (reg != s.index ||
|
if (reg != s.index ||
|
||||||
s.envindex >= 0 ||
|
s.envindex >= 0 ||
|
||||||
s.flags & (JANET_SLOT_CONSTANT | JANET_SLOT_REF)) {
|
s.flags & (JANET_SLOT_CONSTANT | JANET_SLOT_REF)) {
|
||||||
/* We need to free the temporary slot */
|
/* We need to free the temporary slot */
|
||||||
janetc_regalloc_freetemp(&c->scope->ra, reg, tag);
|
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) {
|
void janet_fiber_popframe(JanetFiber *fiber) {
|
||||||
JanetStackFrame *frame = janet_fiber_frame(fiber);
|
JanetStackFrame *frame = janet_fiber_frame(fiber);
|
||||||
if (fiber->frame == 0) return;
|
if (fiber->frame == 0) return;
|
||||||
|
|
||||||
/* Clean up the frame (detach environments) */
|
/* Clean up the frame (detach environments) */
|
||||||
if (NULL != frame->func)
|
if (NULL != frame->func)
|
||||||
janet_env_detach(frame->env);
|
janet_env_detach(frame->env);
|
||||||
@ -305,7 +305,7 @@ static int cfun_new(JanetArgs args) {
|
|||||||
case ':':
|
case ':':
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
fiber->flags |=
|
fiber->flags |=
|
||||||
JANET_FIBER_MASK_DEBUG |
|
JANET_FIBER_MASK_DEBUG |
|
||||||
JANET_FIBER_MASK_ERROR |
|
JANET_FIBER_MASK_ERROR |
|
||||||
JANET_FIBER_MASK_USER |
|
JANET_FIBER_MASK_USER |
|
||||||
@ -455,7 +455,7 @@ static int cfun_setmaxstack(JanetArgs args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const JanetReg cfuns[] = {
|
static const JanetReg cfuns[] = {
|
||||||
{"fiber.new", cfun_new,
|
{"fiber.new", cfun_new,
|
||||||
"(fiber.new func [,sigmask])\n\n"
|
"(fiber.new func [,sigmask])\n\n"
|
||||||
"Create a new fiber with function body func. Can optionally "
|
"Create a new fiber with function body func. Can optionally "
|
||||||
"take a set of signals to block from the current parent fiber "
|
"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"
|
"\ty - block yield signals\n"
|
||||||
"\t0-9 - block a specific user signal"
|
"\t0-9 - block a specific user signal"
|
||||||
},
|
},
|
||||||
{"fiber.status", cfun_status,
|
{"fiber.status", cfun_status,
|
||||||
"(fiber.status fib)\n\n"
|
"(fiber.status fib)\n\n"
|
||||||
"Get the status of a fiber. The status will be one of:\n\n"
|
"Get the status of a fiber. The status will be one of:\n\n"
|
||||||
"\t:dead - the fiber has finished\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:alive - the fiber is currently running and cannot be resumed\n"
|
||||||
"\t:new - the fiber has just been created and not yet run"
|
"\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"
|
"(fiber.stack fib)\n\n"
|
||||||
"Gets information about the stack as an array of tables. Each table "
|
"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 "
|
"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:source - string with filename or other identifier for the source code\n"
|
||||||
"\t:tail - boolean indicating a tail call"
|
"\t:tail - boolean indicating a tail call"
|
||||||
},
|
},
|
||||||
{"fiber.current", cfun_current,
|
{"fiber.current", cfun_current,
|
||||||
"(fiber.current)\n\n"
|
"(fiber.current)\n\n"
|
||||||
"Returns the currently running fiber."
|
"Returns the currently running fiber."
|
||||||
},
|
},
|
||||||
{"fiber.lineage", cfun_lineage,
|
{"fiber.lineage", cfun_lineage,
|
||||||
"(fiber.lineage fib)\n\n"
|
"(fiber.lineage fib)\n\n"
|
||||||
"Returns an array of all child fibers from a root fiber. This function "
|
"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, "
|
"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 "
|
"the fiber handling the error can see which fiber raised the signal. This function should "
|
||||||
"be used mostly for debugging purposes."
|
"be used mostly for debugging purposes."
|
||||||
},
|
},
|
||||||
{"fiber.maxstack", cfun_maxstack,
|
{"fiber.maxstack", cfun_maxstack,
|
||||||
"(fiber.maxstack fib)\n\n"
|
"(fiber.maxstack fib)\n\n"
|
||||||
"Gets the maximum stack size in janet values allowed for a fiber. While memory for "
|
"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 "
|
"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. "
|
"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"
|
"(fiber.setmaxstack fib maxstack)\n\n"
|
||||||
"Sets the maximum stack size in janet values for a fiber. By default, the "
|
"Sets the maximum stack size in janet values for a fiber. By default, the "
|
||||||
"maximum stacksize is usually 8192."
|
"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)))
|
if (!(iof->flags & (IO_READ | IO_UPDATE)))
|
||||||
return "file is not readable";
|
return "file is not readable";
|
||||||
/* Ensure buffer size */
|
/* Ensure buffer size */
|
||||||
if (janet_buffer_extra(buffer, nBytesMax))
|
if (janet_buffer_extra(buffer, nBytesMax))
|
||||||
return "buffer overflow";
|
return "buffer overflow";
|
||||||
size_t ntoread = nBytesMax;
|
size_t ntoread = nBytesMax;
|
||||||
size_t nread = fread((char *)(buffer->data + buffer->count), 1, ntoread, iof->file);
|
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";
|
return "could not read file";
|
||||||
buffer->count += (int32_t) nread;
|
buffer->count += (int32_t) nread;
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -366,7 +366,7 @@ static int janet_io_fseek(JanetArgs args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const JanetReg cfuns[] = {
|
static const JanetReg cfuns[] = {
|
||||||
{"file.open", janet_io_fopen,
|
{"file.open", janet_io_fopen,
|
||||||
"(file.open path [,mode])\n\n"
|
"(file.open path [,mode])\n\n"
|
||||||
"Open a file. path is files absolute or relative path, and "
|
"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. "
|
"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"
|
"\tb - open the file in binary mode (rather than text mode)\n"
|
||||||
"\t+ - append to the file instead of overwriting it"
|
"\t+ - append to the file instead of overwriting it"
|
||||||
},
|
},
|
||||||
{"file.close", janet_io_fclose,
|
{"file.close", janet_io_fclose,
|
||||||
"(file.close f)\n\n"
|
"(file.close f)\n\n"
|
||||||
"Close a file and release all related resources. When you are "
|
"Close a file and release all related resources. When you are "
|
||||||
"done reading a file, close it to prevent a resource leak and let "
|
"done reading a file, close it to prevent a resource leak and let "
|
||||||
"other processes read the file."
|
"other processes read the file."
|
||||||
},
|
},
|
||||||
{"file.read", janet_io_fread,
|
{"file.read", janet_io_fread,
|
||||||
"(file.read f what [,buf])\n\n"
|
"(file.read f what [,buf])\n\n"
|
||||||
"Read a number of bytes from a file into a buffer. A buffer can "
|
"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 "
|
"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"
|
"\t:line - read up to and including the next newline character\n"
|
||||||
"\tn (integer) - read up to n bytes from the file"
|
"\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"
|
"(file.write f bytes)\n\n"
|
||||||
"Writes to a file. 'bytes' must be string, buffer, or symbol. Returns the "
|
"Writes to a file. 'bytes' must be string, buffer, or symbol. Returns the "
|
||||||
"file"
|
"file"
|
||||||
},
|
},
|
||||||
{"file.flush", janet_io_fflush,
|
{"file.flush", janet_io_fflush,
|
||||||
"(file.flush f)\n\n"
|
"(file.flush f)\n\n"
|
||||||
"Flush any buffered bytes to the filesystem. In most files, writes are "
|
"Flush any buffered bytes to the filesystem. In most files, writes are "
|
||||||
"buffered for efficiency reasons. Returns the file handle."
|
"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"
|
"(file.seek f [,whence [,n]])\n\n"
|
||||||
"Jump to a relative location in the file. 'whence' must be one of\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"
|
"\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 "
|
"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."
|
"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"
|
"(file.popen path [,mode])\n\n"
|
||||||
"Open a file that is backed by a process. The file must be opened in either "
|
"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 "
|
"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 */
|
/* stdout */
|
||||||
janet_def(env, "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.");
|
"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);
|
marshal_one(st, janet_wrap_string(def->name), flags);
|
||||||
if (def->flags & JANET_FUNCDEF_FLAG_HASSOURCE)
|
if (def->flags & JANET_FUNCDEF_FLAG_HASSOURCE)
|
||||||
marshal_one(st, janet_wrap_string(def->source), flags);
|
marshal_one(st, janet_wrap_string(def->source), flags);
|
||||||
|
|
||||||
/* marshal constants */
|
/* marshal constants */
|
||||||
for (int32_t i = 0; i < def->constants_length; i++)
|
for (int32_t i = 0; i < def->constants_length; i++)
|
||||||
marshal_one(st, def->constants[i], flags);
|
marshal_one(st, def->constants[i], flags);
|
||||||
|
|
||||||
/* marshal the bytecode */
|
/* marshal the bytecode */
|
||||||
for (int32_t i = 0; i < def->bytecode_length; i++) {
|
for (int32_t i = 0; i < def->bytecode_length; i++) {
|
||||||
pushbyte(st, def->bytecode[i] & 0xFF);
|
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] >> 16) & 0xFF);
|
||||||
pushbyte(st, (def->bytecode[i] >> 24) & 0xFF);
|
pushbyte(st, (def->bytecode[i] >> 24) & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* marshal the environments if needed */
|
/* marshal the environments if needed */
|
||||||
for (int32_t i = 0; i < def->environments_length; i++)
|
for (int32_t i = 0; i < def->environments_length; i++)
|
||||||
pushint(st, def->environments[i]);
|
pushint(st, def->environments[i]);
|
||||||
|
|
||||||
/* marshal the sub funcdefs if needed */
|
/* marshal the sub funcdefs if needed */
|
||||||
for (int32_t i = 0; i < def->defs_length; i++)
|
for (int32_t i = 0; i < def->defs_length; i++)
|
||||||
marshal_one_def(st, def->defs[i], flags);
|
marshal_one_def(st, def->defs[i], flags);
|
||||||
@ -457,7 +457,7 @@ done:
|
|||||||
|
|
||||||
nyi:
|
nyi:
|
||||||
longjmp(st->err, MR_NYI);
|
longjmp(st->err, MR_NYI);
|
||||||
|
|
||||||
noregval:
|
noregval:
|
||||||
longjmp(st->err, MR_NRV);
|
longjmp(st->err, MR_NRV);
|
||||||
}
|
}
|
||||||
@ -469,7 +469,7 @@ int janet_marshal(
|
|||||||
JanetTable *rreg,
|
JanetTable *rreg,
|
||||||
int flags) {
|
int flags) {
|
||||||
int status;
|
int status;
|
||||||
MarshalState st;
|
MarshalState st;
|
||||||
st.buf = buf;
|
st.buf = buf;
|
||||||
st.nextid = 0;
|
st.nextid = 0;
|
||||||
st.seen_defs = NULL;
|
st.seen_defs = NULL;
|
||||||
@ -641,7 +641,7 @@ static const uint8_t *unmarshal_one_def(
|
|||||||
int32_t constants_length = 0;
|
int32_t constants_length = 0;
|
||||||
int32_t environments_length = 0;
|
int32_t environments_length = 0;
|
||||||
int32_t defs_length = 0;
|
int32_t defs_length = 0;
|
||||||
|
|
||||||
/* Read flags and other fixed values */
|
/* Read flags and other fixed values */
|
||||||
def->flags = readint(st, &data);
|
def->flags = readint(st, &data);
|
||||||
def->slotcount = 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);
|
if (!janet_checktype(x, JANET_STRING)) longjmp(st->err, UMR_EXPECTED_STRING);
|
||||||
def->source = janet_unwrap_string(x);
|
def->source = janet_unwrap_string(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unmarshal constants */
|
/* Unmarshal constants */
|
||||||
if (constants_length) {
|
if (constants_length) {
|
||||||
def->constants = malloc(sizeof(Janet) * 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 = NULL;
|
||||||
}
|
}
|
||||||
def->constants_length = constants_length;
|
def->constants_length = constants_length;
|
||||||
|
|
||||||
/* Unmarshal bytecode */
|
/* Unmarshal bytecode */
|
||||||
def->bytecode = malloc(sizeof(uint32_t) * bytecode_length);
|
def->bytecode = malloc(sizeof(uint32_t) * bytecode_length);
|
||||||
if (!def->bytecode) {
|
if (!def->bytecode) {
|
||||||
@ -689,7 +689,7 @@ static const uint8_t *unmarshal_one_def(
|
|||||||
}
|
}
|
||||||
for (int32_t i = 0; i < bytecode_length; i++) {
|
for (int32_t i = 0; i < bytecode_length; i++) {
|
||||||
if (data + 4 > end) longjmp(st->err, UMR_EOS);
|
if (data + 4 > end) longjmp(st->err, UMR_EOS);
|
||||||
def->bytecode[i] =
|
def->bytecode[i] =
|
||||||
(uint32_t)(data[0]) |
|
(uint32_t)(data[0]) |
|
||||||
((uint32_t)(data[1]) << 8) |
|
((uint32_t)(data[1]) << 8) |
|
||||||
((uint32_t)(data[2]) << 16) |
|
((uint32_t)(data[2]) << 16) |
|
||||||
@ -697,7 +697,7 @@ static const uint8_t *unmarshal_one_def(
|
|||||||
data += 4;
|
data += 4;
|
||||||
}
|
}
|
||||||
def->bytecode_length = bytecode_length;
|
def->bytecode_length = bytecode_length;
|
||||||
|
|
||||||
/* Unmarshal environments */
|
/* Unmarshal environments */
|
||||||
if (def->flags & JANET_FUNCDEF_FLAG_HASENVS) {
|
if (def->flags & JANET_FUNCDEF_FLAG_HASENVS) {
|
||||||
def->environments = calloc(1, sizeof(int32_t) * environments_length);
|
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 = NULL;
|
||||||
}
|
}
|
||||||
def->environments_length = environments_length;
|
def->environments_length = environments_length;
|
||||||
|
|
||||||
/* Unmarshal sub funcdefs */
|
/* Unmarshal sub funcdefs */
|
||||||
if (def->flags & JANET_FUNCDEF_FLAG_HASDEFS) {
|
if (def->flags & JANET_FUNCDEF_FLAG_HASDEFS) {
|
||||||
def->defs = calloc(1, sizeof(JanetFuncDef *) * defs_length);
|
def->defs = calloc(1, sizeof(JanetFuncDef *) * defs_length);
|
||||||
@ -719,13 +719,13 @@ static const uint8_t *unmarshal_one_def(
|
|||||||
JANET_OUT_OF_MEMORY;
|
JANET_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
for (int32_t i = 0; i < defs_length; i++) {
|
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 {
|
} else {
|
||||||
def->defs = NULL;
|
def->defs = NULL;
|
||||||
}
|
}
|
||||||
def->defs_length = defs_length;
|
def->defs_length = defs_length;
|
||||||
|
|
||||||
/* Unmarshal source maps if needed */
|
/* Unmarshal source maps if needed */
|
||||||
if (def->flags & JANET_FUNCDEF_FLAG_HASSOURCEMAP) {
|
if (def->flags & JANET_FUNCDEF_FLAG_HASSOURCEMAP) {
|
||||||
def->sourcemap = malloc(sizeof(JanetSourceMapping) * bytecode_length);
|
def->sourcemap = malloc(sizeof(JanetSourceMapping) * bytecode_length);
|
||||||
@ -738,11 +738,11 @@ static const uint8_t *unmarshal_one_def(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
def->sourcemap = NULL;
|
def->sourcemap = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate */
|
/* Validate */
|
||||||
if (janet_verify(def)) longjmp(st->err, UMR_INVALID_BYTECODE);
|
if (janet_verify(def)) longjmp(st->err, UMR_INVALID_BYTECODE);
|
||||||
|
|
||||||
/* Set def */
|
/* Set def */
|
||||||
*out = def;
|
*out = def;
|
||||||
}
|
}
|
||||||
@ -1061,14 +1061,14 @@ static const uint8_t *unmarshal_one(
|
|||||||
|
|
||||||
int janet_unmarshal(
|
int janet_unmarshal(
|
||||||
const uint8_t *bytes,
|
const uint8_t *bytes,
|
||||||
size_t len,
|
size_t len,
|
||||||
int flags,
|
int flags,
|
||||||
Janet *out,
|
Janet *out,
|
||||||
JanetTable *reg,
|
JanetTable *reg,
|
||||||
const uint8_t **next) {
|
const uint8_t **next) {
|
||||||
int status;
|
int status;
|
||||||
/* Avoid longjmp clobber warning in GCC */
|
/* Avoid longjmp clobber warning in GCC */
|
||||||
UnmarshalState st;
|
UnmarshalState st;
|
||||||
st.end = bytes + len;
|
st.end = bytes + len;
|
||||||
st.lookup_defs = NULL;
|
st.lookup_defs = NULL;
|
||||||
st.lookup_envs = NULL;
|
st.lookup_envs = NULL;
|
||||||
@ -1144,7 +1144,7 @@ static int cfun_unmarshal(JanetArgs args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const JanetReg cfuns[] = {
|
static const JanetReg cfuns[] = {
|
||||||
{"marshal", cfun_marshal,
|
{"marshal", cfun_marshal,
|
||||||
"(marshal x [,reverse-lookup [,buffer]])\n\n"
|
"(marshal x [,reverse-lookup [,buffer]])\n\n"
|
||||||
"Marshal a janet value into a buffer and return the buffer. The buffer "
|
"Marshal a janet value into a buffer and return the buffer. The buffer "
|
||||||
"can the later be unmarshalled to reconstruct the initial value. "
|
"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 "
|
"lookup table can be used to recover the origrinal janet value when "
|
||||||
"unmarshaling."
|
"unmarshaling."
|
||||||
},
|
},
|
||||||
{"unmarshal", cfun_unmarshal,
|
{"unmarshal", cfun_unmarshal,
|
||||||
"(unmarshal buffer [,lookup])\n\n"
|
"(unmarshal buffer [,lookup])\n\n"
|
||||||
"Unmarshal a janet value from a buffer. An optional lookup table "
|
"Unmarshal a janet value from a buffer. An optional lookup table "
|
||||||
"can be provided to allow for aliases to be resolved. Returns the value "
|
"can be provided to allow for aliases to be resolved. Returns the value "
|
||||||
"unmarshaled from the buffer."
|
"unmarshaled from the buffer."
|
||||||
},
|
},
|
||||||
{"env-lookup", cfun_env_lookup,
|
{"env-lookup", cfun_env_lookup,
|
||||||
"(env-lookup env)\n\n"
|
"(env-lookup env)\n\n"
|
||||||
"Creates a forward lookup table for unmarshaling from an environment. "
|
"Creates a forward lookup table for unmarshaling from an environment. "
|
||||||
"To create a reverse lookup table, use the invert function to swap keys "
|
"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);
|
si.cb = sizeof(si);
|
||||||
ZeroMemory(&pi, sizeof(pi));
|
ZeroMemory(&pi, sizeof(pi));
|
||||||
|
|
||||||
// Start the child process.
|
// Start the child process.
|
||||||
if(!CreateProcess(NULL,
|
if(!CreateProcess(NULL,
|
||||||
(LPSTR) sys_str,
|
(LPSTR) sys_str,
|
||||||
NULL,
|
NULL,
|
||||||
@ -234,7 +234,7 @@ static int gettime(struct timespec *spec) {
|
|||||||
spec->tv_nsec = mts.tv_nsec;
|
spec->tv_nsec = mts.tv_nsec;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define gettime(TV) clock_gettime(CLOCK_MONOTONIC, (TV))
|
#define gettime(TV) clock_gettime(CLOCK_MONOTONIC, (TV))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -283,52 +283,52 @@ static int os_cwd(JanetArgs args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const JanetReg cfuns[] = {
|
static const JanetReg cfuns[] = {
|
||||||
{"os.which", os_which,
|
{"os.which", os_which,
|
||||||
"(os.which)\n\n"
|
"(os.which)\n\n"
|
||||||
"Check the current operating system. Returns one of:\n\n"
|
"Check the current operating system. Returns one of:\n\n"
|
||||||
"\t:windows - Microsoft Windows\n"
|
"\t:windows - Microsoft Windows\n"
|
||||||
"\t:macos - Apple macos\n"
|
"\t:macos - Apple macos\n"
|
||||||
"\t:posix - A POSIX compatible system (default)"
|
"\t:posix - A POSIX compatible system (default)"
|
||||||
},
|
},
|
||||||
{"os.execute", os_execute,
|
{"os.execute", os_execute,
|
||||||
"(os.execute program & args)\n\n"
|
"(os.execute program & args)\n\n"
|
||||||
"Execute a program on the system and pass it string arguments. Returns "
|
"Execute a program on the system and pass it string arguments. Returns "
|
||||||
"the exit status of the program."
|
"the exit status of the program."
|
||||||
},
|
},
|
||||||
{"os.shell", os_shell,
|
{"os.shell", os_shell,
|
||||||
"(os.shell str)\n\n"
|
"(os.shell str)\n\n"
|
||||||
"Pass a command string str directly to the system shell."
|
"Pass a command string str directly to the system shell."
|
||||||
},
|
},
|
||||||
{"os.exit", os_exit,
|
{"os.exit", os_exit,
|
||||||
"(os.exit x)\n\n"
|
"(os.exit x)\n\n"
|
||||||
"Exit from janet with an exit code equal to x. If x is not an integer, "
|
"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."
|
"the exit with status equal the hash of x."
|
||||||
},
|
},
|
||||||
{"os.getenv", os_getenv,
|
{"os.getenv", os_getenv,
|
||||||
"(os.getenv variable)\n\n"
|
"(os.getenv variable)\n\n"
|
||||||
"Get the string value of an environment variable."
|
"Get the string value of an environment variable."
|
||||||
},
|
},
|
||||||
{"os.setenv", os_setenv,
|
{"os.setenv", os_setenv,
|
||||||
"(os.setenv variable value)\n\n"
|
"(os.setenv variable value)\n\n"
|
||||||
"Set an environment variable."
|
"Set an environment variable."
|
||||||
},
|
},
|
||||||
{"os.time", os_time,
|
{"os.time", os_time,
|
||||||
"(os.time)\n\n"
|
"(os.time)\n\n"
|
||||||
"Get the current time expressed as the number of seconds since "
|
"Get the current time expressed as the number of seconds since "
|
||||||
"January 1, 1970, the Unix epoch. Returns a real number."
|
"January 1, 1970, the Unix epoch. Returns a real number."
|
||||||
},
|
},
|
||||||
{"os.clock", os_clock,
|
{"os.clock", os_clock,
|
||||||
"(os.clock)\n\n"
|
"(os.clock)\n\n"
|
||||||
"Return the number of seconds since some fixed point in time. The clock "
|
"Return the number of seconds since some fixed point in time. The clock "
|
||||||
"is guaranteed to be non decreased in real time."
|
"is guaranteed to be non decreased in real time."
|
||||||
},
|
},
|
||||||
{"os.sleep", os_sleep,
|
{"os.sleep", os_sleep,
|
||||||
"(os.sleep nsec)\n\n"
|
"(os.sleep nsec)\n\n"
|
||||||
"Suspend the program for nsec seconds. 'nsec' can be a real number. Returns "
|
"Suspend the program for nsec seconds. 'nsec' can be a real number. Returns "
|
||||||
"nil."
|
"nil."
|
||||||
|
|
||||||
},
|
},
|
||||||
{"os.cwd", os_cwd,
|
{"os.cwd", os_cwd,
|
||||||
"(os.cwd)\n\n"
|
"(os.cwd)\n\n"
|
||||||
"Returns the current working directory."
|
"Returns the current working directory."
|
||||||
},
|
},
|
||||||
|
@ -32,7 +32,7 @@ static Janet quote(Janet x) {
|
|||||||
|
|
||||||
/* Check if a character is whitespace */
|
/* Check if a character is whitespace */
|
||||||
static int is_whitespace(uint8_t c) {
|
static int is_whitespace(uint8_t c) {
|
||||||
return c == ' '
|
return c == ' '
|
||||||
|| c == '\t'
|
|| c == '\t'
|
||||||
|| c == '\n'
|
|| c == '\n'
|
||||||
|| c == '\r'
|
|| c == '\r'
|
||||||
@ -42,7 +42,7 @@ static int is_whitespace(uint8_t c) {
|
|||||||
|| c == ',';
|
|| c == ',';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Code generated by tools/symcharsgen.c.
|
/* Code generated by tools/symcharsgen.c.
|
||||||
* The table contains 256 bits, where each bit is 1
|
* The table contains 256 bits, where each bit is 1
|
||||||
* if the corresponding ascci code is a symbol char, and 0
|
* if the corresponding ascci code is a symbol char, and 0
|
||||||
* if not. The upper characters are also considered symbol
|
* 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;
|
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 ((nexti == i + 2) && str[i] < 0xC2) return 0;
|
||||||
if ((str[i] == 0xE0) && str[i + 1] < 0xA0) return 0;
|
if ((str[i] == 0xE0) && str[i + 1] < 0xA0) return 0;
|
||||||
if ((str[i] == 0xF0) && str[i + 1] < 0x90) return 0;
|
if ((str[i] == 0xF0) && str[i + 1] < 0x90) return 0;
|
||||||
@ -192,15 +192,15 @@ static int checkescape(uint8_t c) {
|
|||||||
switch (c) {
|
switch (c) {
|
||||||
default: return -1;
|
default: return -1;
|
||||||
case 'x': return 1;
|
case 'x': return 1;
|
||||||
case 'n': return '\n';
|
case 'n': return '\n';
|
||||||
case 't': return '\t';
|
case 't': return '\t';
|
||||||
case 'r': return '\r';
|
case 'r': return '\r';
|
||||||
case '0': return '\0';
|
case '0': return '\0';
|
||||||
case 'z': return '\0';
|
case 'z': return '\0';
|
||||||
case 'f': return '\f';
|
case 'f': return '\f';
|
||||||
case 'e': return 27;
|
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[] = {
|
static const JanetReg cfuns[] = {
|
||||||
{"parser.new", cfun_parser, NULL},
|
{"parser.new", cfun_parser,
|
||||||
{"parser.produce", cfun_produce, NULL},
|
"(parser.new)\n\n"
|
||||||
{"parser.consume", cfun_consume, NULL},
|
"Creates and returns a new parser object. Parsers are state machines "
|
||||||
{"parser.byte", cfun_byte, NULL},
|
"that can receive bytes, and generate a stream of janet values. "
|
||||||
{"parser.error", cfun_error, NULL},
|
},
|
||||||
{"parser.status", cfun_status, NULL},
|
{"parser.produce", cfun_produce,
|
||||||
{"parser.flush", cfun_flush, NULL},
|
"(parser.produce parser)\n\n"
|
||||||
{"parser.state", cfun_state, NULL},
|
"Dequeue the next value in the parse queue. Will return nil if "
|
||||||
{"parser.where", cfun_where, NULL},
|
"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}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1040,21 +1040,97 @@ static int cfun_number(JanetArgs args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const JanetReg cfuns[] = {
|
static const JanetReg cfuns[] = {
|
||||||
{"string.slice", cfun_slice, NULL},
|
{"string.slice", cfun_slice,
|
||||||
{"string.repeat", cfun_repeat, NULL},
|
"(string.slice bytes [,start=0 [,end=(length str)]])\n\n"
|
||||||
{"string.bytes", cfun_bytes, NULL},
|
"Returns a substring from a byte sequence. The substring is from "
|
||||||
{"string.from-bytes", cfun_frombytes, NULL},
|
"index start inclusive to index end exclusive. All indexing "
|
||||||
{"string.ascii-lower", cfun_asciilower, NULL},
|
"is from 0. 'start' and 'end' can also be negative to indicate indexing "
|
||||||
{"string.ascii-upper", cfun_asciiupper, NULL},
|
"from the end of the string."
|
||||||
{"string.reverse", cfun_reverse, NULL},
|
},
|
||||||
{"string.find", cfun_find, NULL},
|
{"string.repeat", cfun_repeat,
|
||||||
{"string.find-all", cfun_findall, NULL},
|
"(string.repeat bytes n)\n\n"
|
||||||
{"string.replace", cfun_replace, NULL},
|
"Returns a string that is n copies of bytes concatenated."
|
||||||
{"string.replace-all", cfun_replaceall, NULL},
|
},
|
||||||
{"string.split", cfun_split, NULL},
|
{"string.bytes", cfun_bytes,
|
||||||
{"string.check-set", cfun_checkset, NULL},
|
"(string.bytes str)\n\n"
|
||||||
{"string.join", cfun_join, NULL},
|
"Returns an array of integers that are the byte values of the string."
|
||||||
{"string.number", cfun_number, NULL},
|
},
|
||||||
|
{"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}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -252,11 +252,33 @@ static int cfun_rawget(JanetArgs args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const JanetReg cfuns[] = {
|
static const JanetReg cfuns[] = {
|
||||||
{"table.new", cfun_new, NULL},
|
{"table.new", cfun_new,
|
||||||
{"table.to-struct", cfun_tostruct, NULL},
|
"(table.new capacity)\n\n"
|
||||||
{"table.getproto", cfun_getproto, NULL},
|
"Creates a new empty table with pre-allocated memory "
|
||||||
{"table.setproto", cfun_setproto, NULL},
|
"for capacity entries. This means that if one knows the number of "
|
||||||
{"table.rawget", cfun_rawget, NULL},
|
"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}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -127,13 +127,16 @@ static int cfun_slice(JanetArgs args) {
|
|||||||
|
|
||||||
static int cfun_prepend(JanetArgs args) {
|
static int cfun_prepend(JanetArgs args) {
|
||||||
const Janet *t;
|
const Janet *t;
|
||||||
int32_t len;
|
int32_t len, i;
|
||||||
Janet *n;
|
Janet *n;
|
||||||
JANET_FIXARITY(args, 2);
|
JANET_MINARITY(args, 1);
|
||||||
if (!janet_indexed_view(args.v[0], &t, &len)) JANET_THROW(args, "expected tuple/array");
|
if (!janet_indexed_view(args.v[0], &t, &len))
|
||||||
n = janet_tuple_begin(len + 1);
|
JANET_THROW(args, "expected tuple/array");
|
||||||
memcpy(n + 1, t, sizeof(Janet) * len);
|
n = janet_tuple_begin(len - 1 + args.n);
|
||||||
n[0] = args.v[1];
|
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));
|
JANET_RETURN_TUPLE(args, janet_tuple_end(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,18 +144,34 @@ static int cfun_append(JanetArgs args) {
|
|||||||
const Janet *t;
|
const Janet *t;
|
||||||
int32_t len;
|
int32_t len;
|
||||||
Janet *n;
|
Janet *n;
|
||||||
JANET_FIXARITY(args, 2);
|
JANET_MINARITY(args, 1);
|
||||||
if (!janet_indexed_view(args.v[0], &t, &len)) JANET_THROW(args, "expected tuple/array");
|
if (!janet_indexed_view(args.v[0], &t, &len))
|
||||||
n = janet_tuple_begin(len + 1);
|
JANET_THROW(args, "expected tuple/array");
|
||||||
|
n = janet_tuple_begin(len - 1 + args.n);
|
||||||
memcpy(n, t, sizeof(Janet) * len);
|
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));
|
JANET_RETURN_TUPLE(args, janet_tuple_end(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const JanetReg cfuns[] = {
|
static const JanetReg cfuns[] = {
|
||||||
{"tuple.slice", cfun_slice, NULL},
|
{"tuple.slice", cfun_slice,
|
||||||
{"tuple.append", cfun_append, NULL},
|
"(tuple.slice arrtup [,start=0 [,end=(length arrtup)]])\n\n"
|
||||||
{"tuple.prepend", cfun_prepend, NULL},
|
"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}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user