This commit is contained in:
2026-01-16 20:55:57 -06:00
parent b46406f755
commit ce7d83ec91
9 changed files with 48 additions and 246 deletions

View File

@@ -28,7 +28,7 @@ function get_local_dir() {
// Replace sigils in a string
// Currently supports: $LOCAL -> .cell/local full path
function replace_sigils(str) {
return str.replaceAll('$LOCAL', get_local_dir())
return replace(str, '$LOCAL', get_local_dir())
}
// Replace sigils in an array of flags

View File

@@ -54,6 +54,7 @@ globalThis.ends_with = function(str, suffix) {
}
var js = use_embed('js')
os.print(js)
var fd = use_embed('fd')
// Get the shop path from HOME environment
@@ -78,7 +79,7 @@ function use_core(path) {
if (use_cache[cache_key])
return use_cache[cache_key];
var sym = use_embed(path.replaceAll('/','_'))
var sym = use_embed(replace(path, '/', '_'))
// Core scripts are in packages/core/
var file_path = core_path + '/' + path + MOD_EXT

View File

@@ -247,13 +247,13 @@ function safe_package_path(pkg)
// For absolute paths, replace / with _ to create a valid directory name
// Also replace @ with _
if (pkg && starts_with(pkg, '/'))
return pkg.replaceAll('/', '_').replaceAll('@', '_')
return pkg.replaceAll('@', '_')
return replace(replace(pkg, '/', '_'), '@', '_')
return replace(pkg, '@', '_')
}
function package_cache_path(pkg)
{
return global_shop_path + '/cache/' + pkg.replaceAll('/', '_').replaceAll('@', '_')
return global_shop_path + '/cache/' + replace(replace(pkg, '/', '_'), '@', '_')
}
function get_shared_lib_path()
@@ -519,15 +519,15 @@ function resolve_locator(path, ctx)
// Uses the same format as Shop.c_symbol_for_file
// Symbol names are based on canonical package names, not link targets
function make_c_symbol(pkg, file) {
var pkg_safe = pkg.replace(/\//g, '_').replace(/\./g, '_').replace(/-/g, '_')
var file_safe = file.replace(/\//g, '_').replace(/\./g, '_').replace(/-/g, '_')
var pkg_safe = replace(replace(replace(pkg, '/', '_'), '.', '_'), '-', '_')
var file_safe = replace(replace(replace(file, '/', '_'), '.', '_'), '-', '_')
return 'js_' + pkg_safe + '_' + file_safe + '_use'
}
// Get the library path for a package in .cell/lib
// Library names are based on canonical package names, not link targets
function get_lib_path(pkg) {
var lib_name = pkg.replace(/\//g, '_').replace(/\./g, '_').replace(/-/g, '_')
var lib_name = replace(replace(replace(pkg, '/', '_'), '.', '_'), '-', '_')
return global_shop_path + '/lib/' + lib_name + dylib_ext
}
@@ -615,7 +615,7 @@ function resolve_c_symbol(path, package_context) {
// If no package context, only check core internal symbols
if (!package_context || package_context == 'core') {
path = path.replaceAll('/', '_')
path = replace(path, '/', '_')
var core_sym = `js_${path}_use`
if (os.internal_exists(core_sym)) {
return {
@@ -684,7 +684,7 @@ function resolve_c_symbol(path, package_context) {
}
// 3. Check core internal symbols (core is never a dynamic library)
var core_sym = `js_${path.replaceAll('/', '_')}_use`
var core_sym = `js_${replace(path, '/', '_')}_use`
if (os.internal_exists(core_sym)) {
return {
symbol: function() { return os.load_internal(core_sym) },
@@ -846,7 +846,7 @@ Shop.resolve_locator = resolve_locator
// Get cache path for a package and commit
function get_cache_path(pkg, commit) {
return global_shop_path + '/cache/' + pkg.replaceAll('@','_').replaceAll('/','_') + '_' + commit + '.zip'
return global_shop_path + '/cache/' + replace(replace(pkg, '@','_'), '/','_') + '_' + commit + '.zip'
}
function get_package_abs_dir(package)
@@ -1250,22 +1250,22 @@ Shop.get_package_dir = function(pkg) {
// e.g., c_symbol_for_file('gitea.pockle.world/john/prosperon', 'sprite.c')
// -> 'js_gitea_pockle_world_john_prosperon_sprite_use'
Shop.c_symbol_for_file = function(pkg, file) {
var pkg_safe = pkg.replaceAll(/\//g, '_').replaceAll(/\./g, '_').replaceAll(/-/g, '_')
var file_safe = text(file, 0, file.lastIndexOf('.')).replaceAll(/\//g, '_').replaceAll(/\./g, '_').replaceAll(/-/g, '_')
var pkg_safe = replace(replace(replace(pkg, '/', '_'), '.', '_'), '-', '_')
var file_safe = replace(replace(text(file, 0, file.lastIndexOf('.')), '/', '_'), '.', '_')
return 'js_' + pkg_safe + '_' + file_safe + '_use'
}
// Generate C symbol prefix for a package
// e.g., c_symbol_prefix('gitea.pockle.world/john/prosperon') -> 'js_gitea_pockle_world_john_prosperon_'
Shop.c_symbol_prefix = function(pkg) {
var pkg_safe = pkg.replaceAll(/\//g, '_').replaceAll(/\./g, '_').replaceAll(/-/g, '_')
var pkg_safe = replace(replace(replace(pkg, '/', '_'), '.', '_'), '-', '_')
return 'js_' + pkg_safe + '_'
}
// Get the library name for a package (without extension)
// e.g., 'gitea.pockle.world/john/prosperon' -> 'gitea_pockle_world_john_prosperon'
Shop.lib_name_for_package = function(pkg) {
return pkg.replaceAll(/\//g, '_').replaceAll(/\./g, '_').replaceAll(/-/g, '_')
return replace(replace(replace(pkg, '/', '_'), '.', '_'), '-', '_')
}
// Returns { ok: bool, results: [{pkg, ok, error}] }

View File

@@ -22,8 +22,8 @@ function get_packages_dir() {
function safe_package_path(pkg) {
// For absolute paths, replace / with _ to create a valid directory name
if (pkg && starts_with(pkg, '/'))
return pkg.replaceAll('/', '_').replaceAll('@', '_')
return pkg.replaceAll('@', '_')
return replace(replace(pkg, '/', '_'), '@', '_')
return replace(pkg, '@', '_')
}
function get_package_abs_dir(package) {

View File

@@ -12,8 +12,8 @@ var link = use('link')
function safe_package_path(pkg) {
if (!pkg) return pkg
if (starts_with(pkg, '/'))
return pkg.replaceAll('/', '_').replaceAll('@', '_')
return pkg.replaceAll('@', '_')
return replace(replace(pkg, '/', '_'), '@', '_')
return replace(pkg, '@', '_')
}
function get_path(name)
@@ -33,11 +33,11 @@ function get_path(name)
if (starts_with(link_target, '/'))
return link_target
// Otherwise it's another package name, resolve that
return os.global_shop_path + '/packages/' + link_target.replaceAll('@', '_')
return os.global_shop_path + '/packages/' + replace(replace(link_target, '/', '_'), '@', '_')
}
// Remote packages use nested directories, so don't transform slashes
return os.global_shop_path + '/packages/' + name.replaceAll('@', '_')
return os.global_shop_path + '/packages/' + replace(name, '@', '_')
}
package.load_config = function(name)
@@ -261,13 +261,13 @@ package.get_flags = function(name, flag_type, target) {
// Base flags
if (config.compilation && config.compilation[flag_type]) {
var base = config.compilation[flag_type]
flags = flags.concat(filter(array(base, /\s+/), function(f) { return f.length > 0 }))
flags = array(flags, filter(array(base, /\s+/), function(f) { return f.length > 0 }))
}
// Target-specific flags
if (target && config.compilation && config.compilation[target] && config.compilation[target][flag_type]) {
var target_flags = config.compilation[target][flag_type]
flags = flags.concat(filter(array(target_flags, /\s+/), function(f) { return f.length > 0 }))
flags = array(flags, filter(array(target_flags, /\s+/), function(f) { return f.length > 0 }))
}
return flags

View File

@@ -29592,72 +29592,6 @@ static int JS_isConcatSpreadable(JSContext *ctx, JSValueConst obj)
return JS_IsArray(ctx, obj);
}
static JSValue js_array_concat(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
JSValue obj, arr, val;
JSValueConst e;
int64_t len, k, n;
int i, res;
arr = JS_NULL;
obj = JS_ToObject(ctx, this_val);
if (JS_IsException(obj))
goto exception;
arr = JS_ArraySpeciesCreate(ctx, obj, JS_NewInt32(ctx, 0));
if (JS_IsException(arr))
goto exception;
n = 0;
for (i = -1; i < argc; i++) {
if (i < 0)
e = obj;
else
e = argv[i];
res = JS_isConcatSpreadable(ctx, e);
if (res < 0)
goto exception;
if (res) {
if (js_get_length64(ctx, &len, e))
goto exception;
if (n + len > MAX_SAFE_INTEGER) {
JS_ThrowTypeError(ctx, "Array loo long");
goto exception;
}
for (k = 0; k < len; k++, n++) {
res = JS_TryGetPropertyInt64(ctx, e, k, &val);
if (res < 0)
goto exception;
if (res) {
if (JS_DefinePropertyValueInt64(ctx, arr, n, val,
JS_PROP_C_W_E | JS_PROP_THROW) < 0)
goto exception;
}
}
} else {
if (n >= MAX_SAFE_INTEGER) {
JS_ThrowTypeError(ctx, "Array loo long");
goto exception;
}
if (JS_DefinePropertyValueInt64(ctx, arr, n, JS_DupValue(ctx, e),
JS_PROP_C_W_E | JS_PROP_THROW) < 0)
goto exception;
n++;
}
}
if (JS_SetProperty(ctx, arr, JS_ATOM_length, JS_NewInt64(ctx, n)) < 0)
goto exception;
JS_FreeValue(ctx, obj);
return arr;
exception:
JS_FreeValue(ctx, arr);
JS_FreeValue(ctx, obj);
return JS_EXCEPTION;
}
static JSValue js_array_includes(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
@@ -29990,50 +29924,6 @@ fail:
return -1;
}
static JSValue js_array_flatten(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv, int map)
{
JSValue obj, arr;
JSValueConst mapperFunction, thisArg;
int64_t sourceLen;
int depthNum;
arr = JS_NULL;
obj = JS_ToObject(ctx, this_val);
if (js_get_length64(ctx, &sourceLen, obj))
goto exception;
depthNum = 1;
mapperFunction = JS_NULL;
thisArg = JS_NULL;
if (map) {
mapperFunction = argv[0];
if (argc > 1) {
thisArg = argv[1];
}
if (check_function(ctx, mapperFunction))
goto exception;
} else {
if (argc > 0 && !JS_IsNull(argv[0])) {
if (JS_ToInt32Sat(ctx, &depthNum, argv[0]) < 0)
goto exception;
}
}
arr = JS_ArraySpeciesCreate(ctx, obj, JS_NewInt32(ctx, 0));
if (JS_IsException(arr))
goto exception;
if (JS_FlattenIntoArray(ctx, arr, obj, sourceLen, 0, depthNum,
mapperFunction, thisArg) < 0)
goto exception;
JS_FreeValue(ctx, obj);
return arr;
exception:
JS_FreeValue(ctx, obj);
JS_FreeValue(ctx, arr);
return JS_EXCEPTION;
}
typedef struct JSArrayIteratorData {
JSValue obj;
JSIteratorKindEnum kind;
@@ -30177,7 +30067,6 @@ static const JSCFunctionListEntry js_iterator_proto_funcs[] = {
};
static const JSCFunctionListEntry js_array_proto_funcs[] = {
JS_CFUNC_DEF("concat", 1, js_array_concat ),
JS_CFUNC_DEF("toString", 0, js_array_toString ),
JS_CFUNC_MAGIC_DEF("pop", 0, js_array_pop, 0 ),
JS_CFUNC_MAGIC_DEF("push", 1, js_array_push, 0 ),
@@ -30185,8 +30074,6 @@ static const JSCFunctionListEntry js_array_proto_funcs[] = {
JS_CFUNC_MAGIC_DEF("unshift", 1, js_array_push, 1 ),
JS_CFUNC_MAGIC_DEF("slice", 2, js_array_slice, 0 ),
JS_CFUNC_MAGIC_DEF("splice", 2, js_array_slice, 1 ),
JS_CFUNC_MAGIC_DEF("flatMap", 1, js_array_flatten, 1 ),
JS_CFUNC_MAGIC_DEF("flat", 0, js_array_flatten, 0 ),
JS_CFUNC_MAGIC_DEF("values", 0, js_create_array_iterator, JS_ITERATOR_KIND_VALUE ),
JS_ALIAS_DEF("[Symbol.iterator]", "values" ),
JS_CFUNC_MAGIC_DEF("keys", 0, js_create_array_iterator, JS_ITERATOR_KIND_KEY ),
@@ -30336,24 +30223,6 @@ static JSValue js_thisStringValue(JSContext *ctx, JSValueConst this_val)
return JS_ThrowTypeError(ctx, "not a string");
}
static JSValue js_string_concat(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
JSValue r;
int i;
/* XXX: Use more efficient method */
/* XXX: This method is OK if r has a single refcount */
/* XXX: should use string_buffer? */
r = JS_ToStringCheckObject(ctx, this_val);
for (i = 0; i < argc; i++) {
if (JS_IsException(r))
break;
r = JS_ConcatString(ctx, r, JS_DupValue(ctx, argv[i]));
}
return r;
}
static int string_cmp(JSString *p1, JSString *p2, int x1, int x2, int len)
{
int i, c1, c2;
@@ -30801,59 +30670,6 @@ exception:
return JS_EXCEPTION;
}
/* return 0 if before the first char */
static int string_prevc(JSString *p, int *pidx)
{
int idx, c, c1;
idx = *pidx;
if (idx <= 0)
return 0;
idx--;
if (p->is_wide_char) {
c = p->u.str16[idx];
if (is_lo_surrogate(c) && idx > 0) {
c1 = p->u.str16[idx - 1];
if (is_hi_surrogate(c1)) {
c = from_surrogate(c1, c);
idx--;
}
}
} else {
c = p->u.str8[idx];
}
*pidx = idx;
return c;
}
static BOOL test_final_sigma(JSString *p, int sigma_pos)
{
int k, c1;
/* before C: skip case ignorable chars and check there is
a cased letter */
k = sigma_pos;
for(;;) {
c1 = string_prevc(p, &k);
if (!lre_is_case_ignorable(c1))
break;
}
if (!lre_is_cased(c1))
return FALSE;
/* after C: skip case ignorable chars and check there is
no cased letter */
k = sigma_pos + 1;
for(;;) {
if (k >= p->len)
return TRUE;
c1 = string_getc(p, &k);
if (!lre_is_case_ignorable(c1))
break;
}
return !lre_is_cased(c1);
}
/* also used for String.prototype.valueOf */
static JSValue js_string_toString(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
@@ -30901,7 +30717,6 @@ static JSValue js_string_iterator_next(JSContext *ctx, JSValueConst this_val,
static const JSCFunctionListEntry js_string_proto_funcs[] = {
JS_PROP_INT32_DEF("length", 0, JS_PROP_CONFIGURABLE ),
JS_CFUNC_DEF("concat", 1, js_string_concat ),
JS_CFUNC_MAGIC_DEF("indexOf", 1, js_string_indexOf, 0 ),
JS_CFUNC_MAGIC_DEF("lastIndexOf", 1, js_string_indexOf, 1 ),
JS_CFUNC_MAGIC_DEF("match", 1, js_string_match, JS_ATOM_Symbol_match ),

View File

@@ -1528,7 +1528,7 @@ return {
test_array_concat: function() {
var arr1 = [1, 2]
var arr2 = [3, 4]
var combined = arr1.concat(arr2)
var combined = array(arr1, arr2)
if (length(combined) != 4) throw "array concat length failed"
if (combined[2] != 3) throw "array concat values failed"
},
@@ -1592,12 +1592,6 @@ return {
if (parts[1] != "b") throw "string split values failed"
},
test_string_replace: function() {
var str = "hello world"
var replaced = str.replace("world", "universe")
if (replaced != "hello universe") throw "string replace failed"
},
test_string_match: function() {
var str = "hello123"
var hasNumbers = /\d/.test(str)
@@ -3422,12 +3416,6 @@ return {
if (some(arr, x => x > 5)) throw "array some no match failed"
},
test_array_flat: function() {
var arr = [1, [2, 3], [4, [5]]]
var flat = arr.flat()
if (flat[0] != 1 || flat[1] != 2 || flat[2] != 3) throw "array flat failed"
},
// ============================================================================
// LOGICAL FUNCTION
// ============================================================================

46
time.cm
View File

@@ -162,41 +162,41 @@ function time_text(num = now(),
/* am/pm */
if (search(fmt, "a") != null) {
if (rec.hour >= 13) { rec.hour -= 12; fmt = fmt.replaceAll("a", "PM"); }
else if (rec.hour == 12) { fmt = fmt.replaceAll("a", "PM"); }
else if (rec.hour == 0) { rec.hour = 12; fmt = fmt.replaceAll("a", "AM"); }
else fmt = fmt.replaceAll("a", "AM");
if (rec.hour >= 13) { rec.hour -= 12; fmt = replace(fmt, "a", "PM"); }
else if (rec.hour == 12) { fmt = replace(fmt, "a", "PM"); }
else if (rec.hour == 0) { rec.hour = 12; fmt = replace(fmt, "a", "AM"); }
else fmt = replace(fmt, "a", "AM");
}
/* BCE/CE */
var year = rec.year > 0 ? rec.year : rec.year - 1;
if (search(fmt, "c") != null) {
if (year < 0) { year = abs(year); fmt = fmt.replaceAll("c", "BC"); }
else fmt = fmt.replaceAll("c", "AD");
if (year < 0) { year = abs(year); fmt = replace(fmt, "c", "BC"); }
else fmt = replace(fmt, "c", "AD");
}
/* substitutions */
var full_offset = zone + (dst ? 1 : 0);
fmt = fmt.replaceAll("yyyy", text(year, "i4"))
fmt = fmt.replaceAll("y", year);
fmt = fmt.replaceAll("eee", rec.yday + 1);
fmt = fmt.replaceAll("dd", text(rec.day, "i2"))
fmt = fmt.replaceAll("d", rec.day);
fmt = fmt.replaceAll("hh", text(rec.hour, "i2"));
fmt = fmt.replaceAll("h", rec.hour);
fmt = fmt.replaceAll("nn", text(rec.minute, "i2"));
fmt = fmt.replaceAll("n", rec.minute);
fmt = fmt.replaceAll("ss", text(rec.second, "i2"));
fmt = fmt.replaceAll("s", rec.second);
fmt = fmt.replaceAll("x", dst ? "DST" : ""); /* new */
fmt = fmt.replaceAll("z", (full_offset >= 0 ? "+" : "") + text(full_offset));
fmt = replace(fmt, "yyyy", text(year, "i4"))
fmt = replace(fmt, "y", year);
fmt = replace(fmt, "eee", rec.yday + 1);
fmt = replace(fmt, "dd", text(rec.day, "i2"))
fmt = replace(fmt, "d", rec.day);
fmt = replace(fmt, "hh", text(rec.hour, "i2"));
fmt = replace(fmt, "h", rec.hour);
fmt = replace(fmt, "nn", text(rec.minute, "i2"));
fmt = replace(fmt, "n", rec.minute);
fmt = replace(fmt, "ss", text(rec.second, "i2"));
fmt = replace(fmt, "s", rec.second);
fmt = replace(fmt, "x", dst ? "DST" : ""); /* new */
fmt = replace(fmt, "z", (full_offset >= 0 ? "+" : "") + text(full_offset));
fmt = fmt.replaceAll(/mm[^bB]/g, rec.month + 1);
fmt = fmt.replaceAll(/m[^bB]/g, rec.month + 1);
fmt = fmt.replaceAll(/v[^bB]/g, rec.weekday);
fmt = fmt.replaceAll("mb", text(time.monthstr[rec.month], 0, 3));
fmt = fmt.replaceAll("mB", time.monthstr[rec.month]);
fmt = fmt.replaceAll("vB", time.weekdays[rec.weekday]);
fmt = fmt.replaceAll("vb", text(time.weekdays[rec.weekday], 0, 3));
fmt = replace(fmt, "mb", text(time.monthstr[rec.month], 0, 3));
fmt = replace(fmt, "mB", time.monthstr[rec.month]);
fmt = replace(fmt, "vB", time.weekdays[rec.weekday]);
fmt = replace(fmt, "vb", text(time.weekdays[rec.weekday], 0, 3));
return fmt;
}

View File

@@ -1,7 +1,5 @@
// Simple TOML parser for cell modules
// Supports basic TOML features needed for the module system
//
// Avoids regex .replace(/.../g, ...) so no global-regex state issues.
function toml_unescape(s) {
if (!is_text(s)) return null