extensive C testing

This commit is contained in:
2026-02-02 21:26:46 -06:00
parent 0b86af1d4c
commit bdf0461e1f
3 changed files with 1546 additions and 12 deletions

View File

@@ -1709,6 +1709,39 @@ static JSValue js_cell_text (JSContext *ctx, JSValue this_val, int argc, JSValue
static JSValue js_cell_push (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_pop (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_array_find (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_stone (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_length (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_reverse (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_proto (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_splat (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_meme (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_fn_apply (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_call (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_modulo (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_neg (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_not (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_text_lower (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_text_upper (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_text_trim (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_text_codepoint (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_text_replace (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_text_search (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_text_extract (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_character (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_number (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_number_abs (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_number_sign (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_number_floor (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_number_ceiling (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_number_round (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_number_trunc (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_number_whole (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_number_fraction (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_number_min (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_number_max (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_number_remainder (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_object (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
JSValue JS_ThrowOutOfMemory (JSContext *ctx);
static JSVarRef *get_var_ref (JSContext *ctx, JSStackFrame *sf, int var_idx, BOOL is_arg);
static JSValue JS_EvalInternal (JSContext *ctx, JSValue this_obj, const char *input, size_t input_len, const char *filename, int flags, int scope_idx);
@@ -3255,7 +3288,7 @@ JSValue JS_NewObject (JSContext *ctx) {
/* Helper to check if a value is a bytecode function */
static BOOL js_is_bytecode_function (JSValue val) {
if (JS_VALUE_GET_TAG (val) != JS_TAG_FUNCTION) return FALSE;
if (!JS_IsFunction (val)) return FALSE;
JSFunction *f = JS_VALUE_GET_FUNCTION (val);
return f->kind == JS_FUNC_KIND_BYTECODE;
}
@@ -3263,7 +3296,7 @@ static BOOL js_is_bytecode_function (JSValue val) {
/* return NULL without exception if not a function or no bytecode */
static JSFunctionBytecode *JS_GetFunctionBytecode (JSValue val) {
JSFunction *f;
if (JS_VALUE_GET_TAG (val) != JS_TAG_FUNCTION) return NULL;
if (!JS_IsFunction (val)) return NULL;
f = JS_VALUE_GET_FUNCTION (val);
if (f->kind != JS_FUNC_KIND_BYTECODE) return NULL;
return f->u.func.function_bytecode;
@@ -3280,7 +3313,7 @@ static int js_method_set_properties (JSContext *ctx, JSValue func_obj, JSValue n
(void)ctx;
(void)flags;
(void)home_obj;
if (JS_VALUE_GET_TAG (func_obj) != JS_TAG_FUNCTION) return -1;
if (!JS_IsFunction (func_obj)) return -1;
JSFunction *f = JS_VALUE_GET_FUNCTION (func_obj);
/* name is now JSValue text */
if (JS_IsText (name)) { f->name = name; }
@@ -3735,7 +3768,7 @@ static void build_backtrace (JSContext *ctx, JSValue error_obj, const char *file
dbuf_printf (&dbuf, " at %s", str1);
JS_FreeCString (ctx, func_name_str);
if (JS_VALUE_GET_TAG (sf->cur_func) == JS_TAG_FUNCTION) {
if (JS_IsFunction (sf->cur_func)) {
JSFunction *fn = JS_VALUE_GET_FUNCTION (sf->cur_func);
if (fn->kind == JS_FUNC_KIND_BYTECODE) {
JSFunctionBytecode *b;
@@ -4622,7 +4655,7 @@ int JS_DeleteProperty (JSContext *ctx, JSValue obj, JSValue prop) {
BOOL JS_IsCFunction (JSValue val, JSCFunction *func, int magic) {
JSFunction *f;
if (JS_VALUE_GET_TAG (val) != JS_TAG_FUNCTION) return FALSE;
if (!JS_IsFunction (val)) return FALSE;
f = JS_VALUE_GET_FUNCTION (val);
if (f->kind == JS_FUNC_KIND_C)
return (f->u.cfunc.c_function.generic == func
@@ -6396,7 +6429,7 @@ static JSValue JS_CallInternal (JSContext *caller_ctx, JSValue func_obj, JSValue
#endif
if (js_poll_interrupts (caller_ctx)) return JS_EXCEPTION;
if (unlikely (JS_VALUE_GET_TAG (func_obj) != JS_TAG_FUNCTION)) {
if (unlikely (!JS_IsFunction (func_obj))) {
not_a_function:
return JS_ThrowTypeError (caller_ctx, "not a function");
}
@@ -21722,6 +21755,178 @@ static JSValue js_cell_text_extract (JSContext *ctx, JSValue this_val, int argc,
return arr;
}
/* format(text, collection, transformer) - string interpolation
* Finds {name} or {name:format} patterns and substitutes from collection.
* Collection can be array (index by number) or record (index by key).
* Transformer can be function(value, format) or record of functions.
*/
static JSValue js_cell_text_format (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
if (argc < 2) return JS_NULL;
if (!JS_IsText (argv[0])) return JS_NULL;
JSValue text_val = argv[0];
JSValue collection = argv[1];
JSValue transformer = argc > 2 ? argv[2] : JS_NULL;
int is_array = JS_IsArray (collection);
int is_record = JS_IsRecord (collection);
if (!is_array && !is_record) return JS_NULL;
JSText *sp = JS_VALUE_GET_STRING (text_val);
int len = (int)JSText_len (sp);
JSText *result = pretext_init (ctx, len);
if (!result) return JS_EXCEPTION;
int pos = 0;
while (pos < len) {
/* Find next '{' */
int brace_start = -1;
for (int i = pos; i < len; i++) {
if (string_get (sp, i) == '{') {
brace_start = i;
break;
}
}
if (brace_start < 0) {
/* No more braces, copy rest of string */
JSValue tail = js_sub_string (ctx, sp, pos, len);
if (JS_IsException (tail)) return JS_EXCEPTION;
result = pretext_concat_value (ctx, result, tail);
break;
}
/* Copy text before brace */
if (brace_start > pos) {
JSValue prefix = js_sub_string (ctx, sp, pos, brace_start);
if (JS_IsException (prefix)) return JS_EXCEPTION;
result = pretext_concat_value (ctx, result, prefix);
if (!result) return JS_EXCEPTION;
}
/* Find closing '}' */
int brace_end = -1;
for (int i = brace_start + 1; i < len; i++) {
if (string_get (sp, i) == '}') {
brace_end = i;
break;
}
}
if (brace_end < 0) {
/* No closing brace, copy '{' and continue */
JSValue ch = js_sub_string (ctx, sp, brace_start, brace_start + 1);
if (JS_IsException (ch)) return JS_EXCEPTION;
result = pretext_concat_value (ctx, result, ch);
if (!result) return JS_EXCEPTION;
pos = brace_start + 1;
continue;
}
/* Extract content between braces */
JSValue middle = js_sub_string (ctx, sp, brace_start + 1, brace_end);
if (JS_IsException (middle)) return JS_EXCEPTION;
/* Split on ':' to get name and format_spec */
JSText *middle_str = JS_VALUE_GET_STRING (middle);
int middle_len = (int)JSText_len (middle_str);
int colon_pos = -1;
for (int i = 0; i < middle_len; i++) {
if (string_get (middle_str, i) == ':') {
colon_pos = i;
break;
}
}
JSValue name_val, format_spec;
if (colon_pos >= 0) {
name_val = js_sub_string (ctx, middle_str, 0, colon_pos);
format_spec = js_sub_string (ctx, middle_str, colon_pos + 1, middle_len);
} else {
name_val = middle;
format_spec = JS_KEY_empty;
}
/* Get value from collection */
JSValue coll_value = JS_NULL;
if (is_array) {
/* Parse name as integer index */
int32_t idx = 0;
if (JS_ToInt32 (ctx, &idx, name_val) == 0 && idx >= 0) {
coll_value = JS_GetPropertyUint32 (ctx, collection, (uint32_t)idx);
}
} else {
/* Use name as key */
coll_value = JS_GetProperty (ctx, collection, name_val);
}
/* Try to get substitution */
JSValue substitution = JS_NULL;
int made_substitution = 0;
/* Try transformer first */
if (!JS_IsNull (transformer)) {
if (JS_IsFunction (transformer)) {
/* transformer(value, format_spec) */
JSValue args[2] = { coll_value, format_spec };
JSValue result_val = JS_Call (ctx, transformer, JS_NULL, 2, args);
if (JS_IsText (result_val)) {
substitution = result_val;
made_substitution = 1;
}
} else if (JS_IsRecord (transformer)) {
/* transformer[format_spec](value) */
JSValue func = JS_GetProperty (ctx, transformer, format_spec);
if (JS_IsFunction (func)) {
JSValue result_val = JS_Call (ctx, func, JS_NULL, 1, &coll_value);
if (JS_IsText (result_val)) {
substitution = result_val;
made_substitution = 1;
}
}
}
}
/* If no transformer match and value is number, try number.text(format) */
if (!made_substitution && JS_IsNumber (coll_value) && !JS_IsNull (format_spec)) {
JSValue text_method = JS_GetPropertyStr (ctx, coll_value, "text");
if (JS_IsFunction (text_method)) {
JSValue result_val = JS_Call (ctx, text_method, coll_value, 1, &format_spec);
if (JS_IsText (result_val)) {
substitution = result_val;
made_substitution = 1;
}
}
}
/* If still no substitution but we have a value, convert to text */
if (!made_substitution && !JS_IsNull (coll_value)) {
JSValue text_val = JS_ToString (ctx, coll_value);
if (JS_IsText (text_val)) {
substitution = text_val;
made_substitution = 1;
}
}
if (made_substitution) {
result = pretext_concat_value (ctx, result, substitution);
if (!result) return JS_EXCEPTION;
} else {
/* No substitution, keep original {name} or {name:format} */
JSValue orig = js_sub_string (ctx, sp, brace_start, brace_end + 1);
if (JS_IsException (orig)) return JS_EXCEPTION;
result = pretext_concat_value (ctx, result, orig);
if (!result) return JS_EXCEPTION;
}
pos = brace_end + 1;
}
return pretext_end (ctx, result);
}
/* ----------------------------------------------------------------------------
* array function and sub-functions
* ----------------------------------------------------------------------------
@@ -23542,6 +23747,258 @@ JSValue JS_ArrayReduce (JSContext *ctx, JSValue arr, JSValue fn, JSValue initial
return js_cell_array_reduce (ctx, JS_NULL, argc, argv);
}
/* ============================================================
C API Wrappers for Cell Intrinsic Functions
============================================================ */
/* C API: stone(val) - make value immutable */
JSValue JS_CellStone (JSContext *ctx, JSValue val) {
return js_cell_stone (ctx, JS_NULL, 1, &val);
}
/* C API: length(val) - get length of array/text/blob */
JSValue JS_CellLength (JSContext *ctx, JSValue val) {
return js_cell_length (ctx, JS_NULL, 1, &val);
}
/* C API: reverse(val) - reverse array or text */
JSValue JS_CellReverse (JSContext *ctx, JSValue val) {
return js_cell_reverse (ctx, JS_NULL, 1, &val);
}
/* C API: proto(obj) - get prototype */
JSValue JS_CellProto (JSContext *ctx, JSValue obj) {
return js_cell_proto (ctx, JS_NULL, 1, &obj);
}
/* C API: splat(val) - convert to array */
JSValue JS_CellSplat (JSContext *ctx, JSValue val) {
return js_cell_splat (ctx, JS_NULL, 1, &val);
}
/* C API: meme(obj, deep) - clone object */
JSValue JS_CellMeme (JSContext *ctx, JSValue obj, JSValue deep) {
JSValue argv[2] = { obj, deep };
int argc = JS_IsNull (deep) ? 1 : 2;
return js_cell_meme (ctx, JS_NULL, argc, argv);
}
/* C API: apply(fn, args) - apply function to array of args */
JSValue JS_CellApply (JSContext *ctx, JSValue fn, JSValue args) {
JSValue argv[2] = { fn, args };
return js_cell_fn_apply (ctx, JS_NULL, 2, argv);
}
/* C API: call(fn, this, args...) - call function */
JSValue JS_CellCall (JSContext *ctx, JSValue fn, JSValue this_val, JSValue args) {
JSValue argv[3] = { fn, this_val, args };
int argc = JS_IsNull (args) ? 2 : 3;
return js_cell_call (ctx, JS_NULL, argc, argv);
}
/* C API: modulo(a, b) - modulo operation */
JSValue JS_CellModulo (JSContext *ctx, JSValue a, JSValue b) {
JSValue argv[2] = { a, b };
return js_cell_modulo (ctx, JS_NULL, 2, argv);
}
/* C API: neg(val) - negate number */
JSValue JS_CellNeg (JSContext *ctx, JSValue val) {
return js_cell_neg (ctx, JS_NULL, 1, &val);
}
/* C API: not(val) - logical not */
JSValue JS_CellNot (JSContext *ctx, JSValue val) {
return js_cell_not (ctx, JS_NULL, 1, &val);
}
/* Text functions */
/* C API: text(val) - convert to text */
JSValue JS_CellText (JSContext *ctx, JSValue val) {
return js_cell_text (ctx, JS_NULL, 1, &val);
}
/* C API: lower(text) - convert to lowercase */
JSValue JS_CellLower (JSContext *ctx, JSValue text) {
return js_cell_text_lower (ctx, JS_NULL, 1, &text);
}
/* C API: upper(text) - convert to uppercase */
JSValue JS_CellUpper (JSContext *ctx, JSValue text) {
return js_cell_text_upper (ctx, JS_NULL, 1, &text);
}
/* C API: trim(text, chars) - trim whitespace or specified chars */
JSValue JS_CellTrim (JSContext *ctx, JSValue text, JSValue chars) {
JSValue argv[2] = { text, chars };
int argc = JS_IsNull (chars) ? 1 : 2;
return js_cell_text_trim (ctx, JS_NULL, argc, argv);
}
/* C API: codepoint(text, idx) - get codepoint at index */
JSValue JS_CellCodepoint (JSContext *ctx, JSValue text, JSValue idx) {
JSValue argv[2] = { text, idx };
int argc = JS_IsNull (idx) ? 1 : 2;
return js_cell_text_codepoint (ctx, JS_NULL, argc, argv);
}
/* C API: replace(text, pattern, replacement) - replace in text */
JSValue JS_CellReplace (JSContext *ctx, JSValue text, JSValue pattern, JSValue replacement) {
JSValue argv[3] = { text, pattern, replacement };
return js_cell_text_replace (ctx, JS_NULL, 3, argv);
}
/* C API: search(text, pattern, from) - search in text */
JSValue JS_CellSearch (JSContext *ctx, JSValue text, JSValue pattern, JSValue from) {
JSValue argv[3] = { text, pattern, from };
int argc = JS_IsNull (from) ? 2 : 3;
return js_cell_text_search (ctx, JS_NULL, argc, argv);
}
/* C API: extract(text, from, to) - extract substring */
JSValue JS_CellExtract (JSContext *ctx, JSValue text, JSValue from, JSValue to) {
JSValue argv[3] = { text, from, to };
int argc = 3;
if (JS_IsNull (to)) argc = 2;
if (JS_IsNull (from)) argc = 1;
return js_cell_text_extract (ctx, JS_NULL, argc, argv);
}
/* C API: character(codepoint) - create single character text */
JSValue JS_CellCharacter (JSContext *ctx, JSValue codepoint) {
return js_cell_character (ctx, JS_NULL, 1, &codepoint);
}
/* Number functions */
/* C API: number(val) - convert to number */
JSValue JS_CellNumber (JSContext *ctx, JSValue val) {
return js_cell_number (ctx, JS_NULL, 1, &val);
}
/* C API: abs(num) - absolute value */
JSValue JS_CellAbs (JSContext *ctx, JSValue num) {
return js_cell_number_abs (ctx, JS_NULL, 1, &num);
}
/* C API: sign(num) - sign of number (-1, 0, 1) */
JSValue JS_CellSign (JSContext *ctx, JSValue num) {
return js_cell_number_sign (ctx, JS_NULL, 1, &num);
}
/* C API: floor(num) - floor */
JSValue JS_CellFloor (JSContext *ctx, JSValue num) {
return js_cell_number_floor (ctx, JS_NULL, 1, &num);
}
/* C API: ceiling(num) - ceiling */
JSValue JS_CellCeiling (JSContext *ctx, JSValue num) {
return js_cell_number_ceiling (ctx, JS_NULL, 1, &num);
}
/* C API: round(num) - round to nearest integer */
JSValue JS_CellRound (JSContext *ctx, JSValue num) {
return js_cell_number_round (ctx, JS_NULL, 1, &num);
}
/* C API: trunc(num) - truncate towards zero */
JSValue JS_CellTrunc (JSContext *ctx, JSValue num) {
return js_cell_number_trunc (ctx, JS_NULL, 1, &num);
}
/* C API: whole(num) - integer part */
JSValue JS_CellWhole (JSContext *ctx, JSValue num) {
return js_cell_number_whole (ctx, JS_NULL, 1, &num);
}
/* C API: fraction(num) - fractional part */
JSValue JS_CellFraction (JSContext *ctx, JSValue num) {
return js_cell_number_fraction (ctx, JS_NULL, 1, &num);
}
/* C API: min(a, b) - minimum of two numbers */
JSValue JS_CellMin (JSContext *ctx, JSValue a, JSValue b) {
JSValue argv[2] = { a, b };
return js_cell_number_min (ctx, JS_NULL, 2, argv);
}
/* C API: max(a, b) - maximum of two numbers */
JSValue JS_CellMax (JSContext *ctx, JSValue a, JSValue b) {
JSValue argv[2] = { a, b };
return js_cell_number_max (ctx, JS_NULL, 2, argv);
}
/* C API: remainder(a, b) - remainder after division */
JSValue JS_CellRemainder (JSContext *ctx, JSValue a, JSValue b) {
JSValue argv[2] = { a, b };
return js_cell_number_remainder (ctx, JS_NULL, 2, argv);
}
/* Object functions */
/* C API: object(proto, props) - create object */
JSValue JS_CellObject (JSContext *ctx, JSValue proto, JSValue props) {
JSValue argv[2] = { proto, props };
int argc = JS_IsNull (props) ? 1 : 2;
if (JS_IsNull (proto)) argc = 0;
return js_cell_object (ctx, JS_NULL, argc, argv);
}
/* C API: format(text, collection, transformer) - string interpolation */
JSValue JS_CellFormat (JSContext *ctx, JSValue text, JSValue collection, JSValue transformer) {
JSValue argv[3] = { text, collection, transformer };
int argc = JS_IsNull (transformer) ? 2 : 3;
return js_cell_text_format (ctx, JS_NULL, argc, argv);
}
/* ============================================================
Helper Functions for C API
============================================================ */
/* Create an array from a list of JSValues */
JSValue JS_NewArrayFrom (JSContext *ctx, int count, JSValue *values) {
JSValue arr = JS_NewArray (ctx);
if (JS_IsException (arr)) return arr;
for (int i = 0; i < count; i++) {
if (JS_ArrayPush (ctx, &arr, values[i]) < 0) {
return JS_EXCEPTION;
}
}
return arr;
}
/* Print a JSValue text to stdout */
void JS_PrintText (JSContext *ctx, JSValue val) {
if (!JS_IsText (val)) {
/* Try to convert to string first */
val = JS_ToString (ctx, val);
if (JS_IsException (val) || !JS_IsText (val)) {
printf ("[non-text value]");
return;
}
}
const char *str = JS_ToCString (ctx, val);
if (str) {
printf ("%s", str);
JS_FreeCString (ctx, str);
}
}
/* Print a JSValue text to stdout with newline */
void JS_PrintTextLn (JSContext *ctx, JSValue val) {
JS_PrintText (ctx, val);
printf ("\n");
}
/* Format and print - convenience function */
void JS_PrintFormatted (JSContext *ctx, const char *fmt, int count, JSValue *values) {
JSValue fmt_str = JS_NewString (ctx, fmt);
JSValue arr = JS_NewArrayFrom (ctx, count, values);
JSValue result = JS_CellFormat (ctx, fmt_str, arr, JS_NULL);
JS_PrintText (ctx, result);
}
static JSValue js_cell_push (JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
if (argc < 1) return JS_NULL;
@@ -24079,6 +24536,8 @@ void JS_AddIntrinsicBaseObjects (JSContext *ctx) {
ctx, ctx->global_obj, "search", JS_NewCFunction (ctx, js_cell_text_search, "search", 3));
JS_SetPropertyStr (
ctx, ctx->global_obj, "extract", JS_NewCFunction (ctx, js_cell_text_extract, "extract", 4));
JS_SetPropertyStr (
ctx, ctx->global_obj, "format", JS_NewCFunction (ctx, js_cell_text_format, "format", 3));
JS_SetPropertyStr (
ctx, ctx->global_obj, "reduce", JS_NewCFunction (ctx, js_cell_array_reduce, "reduce", 4));
JS_SetPropertyStr (ctx, ctx->global_obj, "arrfor", JS_NewCFunction (ctx, js_cell_array_for, "for", 4));

View File

@@ -653,6 +653,59 @@ JSValue JS_ArraySort (JSContext *ctx, JSValue arr, JSValue selector);
JSValue JS_ArrayFind (JSContext *ctx, JSValue arr, JSValue target_or_fn, JSValue reverse, JSValue from);
JSValue JS_ArrFor (JSContext *ctx, JSValue arr, JSValue fn, JSValue reverse, JSValue exit_val);
JSValue JS_ArrayReduce (JSContext *ctx, JSValue arr, JSValue fn, JSValue initial, JSValue reverse);
/* Cell intrinsic functions - C API wrappers */
/* Core functions */
JSValue JS_CellStone (JSContext *ctx, JSValue val);
JSValue JS_CellLength (JSContext *ctx, JSValue val);
JSValue JS_CellReverse (JSContext *ctx, JSValue val);
JSValue JS_CellProto (JSContext *ctx, JSValue obj);
JSValue JS_CellSplat (JSContext *ctx, JSValue val);
JSValue JS_CellMeme (JSContext *ctx, JSValue obj, JSValue deep);
JSValue JS_CellApply (JSContext *ctx, JSValue fn, JSValue args);
JSValue JS_CellCall (JSContext *ctx, JSValue fn, JSValue this_val, JSValue args);
JSValue JS_CellModulo (JSContext *ctx, JSValue a, JSValue b);
JSValue JS_CellNeg (JSContext *ctx, JSValue val);
JSValue JS_CellNot (JSContext *ctx, JSValue val);
/* Text functions */
JSValue JS_CellText (JSContext *ctx, JSValue val);
JSValue JS_CellLower (JSContext *ctx, JSValue text);
JSValue JS_CellUpper (JSContext *ctx, JSValue text);
JSValue JS_CellTrim (JSContext *ctx, JSValue text, JSValue chars);
JSValue JS_CellCodepoint (JSContext *ctx, JSValue text, JSValue idx);
JSValue JS_CellReplace (JSContext *ctx, JSValue text, JSValue pattern, JSValue replacement);
JSValue JS_CellSearch (JSContext *ctx, JSValue text, JSValue pattern, JSValue from);
JSValue JS_CellExtract (JSContext *ctx, JSValue text, JSValue from, JSValue to);
JSValue JS_CellCharacter (JSContext *ctx, JSValue codepoint);
/* Number functions */
JSValue JS_CellNumber (JSContext *ctx, JSValue val);
JSValue JS_CellAbs (JSContext *ctx, JSValue num);
JSValue JS_CellSign (JSContext *ctx, JSValue num);
JSValue JS_CellFloor (JSContext *ctx, JSValue num);
JSValue JS_CellCeiling (JSContext *ctx, JSValue num);
JSValue JS_CellRound (JSContext *ctx, JSValue num);
JSValue JS_CellTrunc (JSContext *ctx, JSValue num);
JSValue JS_CellWhole (JSContext *ctx, JSValue num);
JSValue JS_CellFraction (JSContext *ctx, JSValue num);
JSValue JS_CellMin (JSContext *ctx, JSValue a, JSValue b);
JSValue JS_CellMax (JSContext *ctx, JSValue a, JSValue b);
JSValue JS_CellRemainder (JSContext *ctx, JSValue a, JSValue b);
/* Object functions */
JSValue JS_CellObject (JSContext *ctx, JSValue proto, JSValue props);
/* Format function */
JSValue JS_CellFormat (JSContext *ctx, JSValue text, JSValue collection, JSValue transformer);
/* Helper functions */
JSValue JS_NewArrayFrom (JSContext *ctx, int count, JSValue *values);
void JS_PrintText (JSContext *ctx, JSValue val);
void JS_PrintTextLn (JSContext *ctx, JSValue val);
void JS_PrintFormatted (JSContext *ctx, const char *fmt, int count, JSValue *values);
JSValue JS_GetProperty (JSContext *ctx, JSValue this_obj, JSValue prop);
// For records

File diff suppressed because it is too large Load Diff