intrinsics rewritten without ++, --, etc

This commit is contained in:
2026-02-10 07:19:45 -06:00
parent 3f7e34cd7a
commit c4ff0bc109
13 changed files with 545 additions and 468 deletions

View File

@@ -1,5 +1,6 @@
// Hidden vars (os, args, core_path, use_mcode) come from env
// args[0] = script name, args[1..] = user args
// Hidden vars come from env:
// CLI mode (cell_init): os, args, core_path, use_mcode
// Actor spawn (script_startup): os, json, nota, wota, actorsym, init, core_path
var load_internal = os.load_internal
function use_embed(name) {
return load_internal("js_" + name + "_use")
@@ -24,13 +25,14 @@ function use_basic(path) {
// Load a module from .mach bytecode, falling back to .ast.json
function boot_load(name, env) {
var mach_path = name + ".mach"
var mach_path = core_path + '/' + name + ".mach"
var data = null
if (fd.is_file(mach_path)) {
data = fd.slurp(mach_path)
return mach_load(data, env)
}
data = text(fd.slurp(name + ".ast.json"))
var ast_path = core_path + '/' + name + ".ast.json"
data = text(fd.slurp(ast_path))
return mach_eval_ast(name, data, env)
}
@@ -91,7 +93,7 @@ function run_ast(name, ast, env) {
}
// use() with ƿit pipeline for .cm modules
function use(path) {
function use_fn(path) {
var file_path = path + '.cm'
var script = null
var ast = null
@@ -106,7 +108,7 @@ function use(path) {
if (fd.is_file(file_path)) {
script = text(fd.slurp(file_path))
ast = analyze(script, file_path)
result = run_ast(path, ast, {use: use})
result = run_ast(path, ast, {use: use_fn})
use_cache[path] = result
return result
}
@@ -117,21 +119,46 @@ function use(path) {
return result
}
// Load and run the user's program
var program = args[0]
var script_file = program
// Add .ce extension if not already present
if (!ends_with(script_file, '.ce') && !ends_with(script_file, '.cm'))
script_file = program + '.ce'
var user_args = []
var _j = 1
while (_j < length(args)) {
push(user_args, args[_j])
_j = _j + 1
// Helper to load engine.cm and run it with given env
function load_engine(env) {
var engine_path = core_path + '/internal/engine.mach'
if (fd.is_file(engine_path)) {
var data = fd.slurp(engine_path)
return mach_load(data, env)
}
engine_path = core_path + '/internal/engine.cm'
var engine_src = text(fd.slurp(engine_path))
var engine_ast = analyze(engine_src, engine_path)
return run_ast('engine', engine_ast, env)
}
var script = text(fd.slurp(script_file))
var ast = analyze(script, script_file)
run_ast(program, ast, {use: use, args: user_args, json: json})
// Detect mode and route
// CLI mode has 'args'; actor spawn mode has 'init'
if (args != null) {
// CLI mode — run script directly
var program = args[0]
var user_args = []
var _j = 1
while (_j < length(args)) {
push(user_args, args[_j])
_j = _j + 1
}
var script_file = program
if (!ends_with(script_file, '.ce') && !ends_with(script_file, '.cm'))
script_file = program + '.cm'
if (!fd.is_file(script_file))
script_file = core_path + '/' + program + '.cm'
var script = text(fd.slurp(script_file))
var ast = analyze(script, script_file)
run_ast(program, ast, {use: use_fn, args: user_args, json: json})
} else {
// Actor spawn mode — load engine.cm with full actor env
load_engine({
os: os, actorsym: actorsym, init: init,
core_path: core_path, json: json, nota: nota, wota: wota,
analyze: analyze, run_ast_fn: run_ast
})
}

Binary file not shown.

View File

@@ -1,4 +1,5 @@
// Hidden vars (os, actorsym, init, core_path) come from env
// Hidden vars (os, actorsym, init, core_path, analyze, run_ast_fn, json) come from env
// In actor spawn mode, also: nota, wota
var ACTORDATA = actorsym
var SYSYM = '__SYSTEM__'
@@ -49,23 +50,12 @@ function ends_with(str, suffix) {
return search(str, suffix, -length(suffix)) != null
}
var js = use_embed('js')
var fd = use_embed('fd')
var js = use_embed('js')
// Get the shop path from HOME environment
var home = os.getenv('HOME') || os.getenv('USERPROFILE')
if (!home) {
os.print('Could not determine home directory\n')
os.exit(1)
}
var shop_path = home + '/.cell'
var packages_path = shop_path + '/packages'
var core_path = packages_path + '/core'
if (!fd.is_dir(core_path)) {
os.print('Cell shop not found at ' + shop_path + '. Run "cell install" to set up.\n')
os.exit(1)
}
// Derive shop path from core_path (core_path = ~/.cell/packages/core)
var packages_path = core_path + '/..'
var shop_path = packages_path + '/..'
var use_cache = {}
use_cache['core/os'] = os
@@ -74,25 +64,31 @@ use_cache['core/os'] = os
function use_core(path) {
var cache_key = 'core/' + path
if (use_cache[cache_key])
return use_cache[cache_key];
return use_cache[cache_key]
var sym = use_embed(replace(path, '/', '_'))
// Core scripts are in packages/core/
var file_path = core_path + '/' + path + MOD_EXT
if (fd.is_file(file_path)) {
var script_blob = fd.slurp(file_path)
var script = text(script_blob)
var mod = `(function setup_module(use){${script}})`
var fn = mach_eval('core:' + path, mod)
var result = call(fn,sym, [use_core])
use_cache[cache_key] = result;
return result;
// Check for pre-compiled .mach file first
var mach_path = core_path + '/' + path + '.mach'
if (fd.is_file(mach_path)) {
var result = mach_load(fd.slurp(mach_path), {use: use_core})
use_cache[cache_key] = result
return result
}
use_cache[cache_key] = sym;
return sym;
// Fall back to source .cm file — compile at runtime
var file_path = core_path + '/' + path + MOD_EXT
if (fd.is_file(file_path)) {
var script = text(fd.slurp(file_path))
var ast = analyze(script, file_path)
var result = run_ast_fn('core:' + path, ast, {use: use_core})
use_cache[cache_key] = result
return result
}
// Embedded C module only
use_cache[cache_key] = sym
return sym
}
var blob = use_core('blob')
@@ -191,7 +187,7 @@ function actor_die(err)
actor_mod.on_exception(actor_die)
//actor_mod.on_exception(actor_die)
_cell.args = init != null ? init : {}
_cell.id = "newguy"
@@ -208,10 +204,12 @@ $_.self = create_actor()
os.use_cache = use_cache
os.global_shop_path = shop_path
os.$_ = $_
os.analyze = analyze
os.run_ast_fn = run_ast_fn
os.json = json
use_cache['core/json'] = json
var shop = use_core('internal/shop')
var json = use_core('json')
var time = use_core('time')
var pronto = use_core('pronto')
@@ -801,41 +799,49 @@ var prog = _cell.args.program
var package = use_core('package')
var locator = shop.resolve_locator(_cell.args.program + ".ce", null)
if (!locator) {
var pkg = package.find_package_dir(_cell.args.program + ".ce")
locator = shop.resolve_locator(_cell.args.program + ".ce", pkg)
// Find the .ce file
var prog_path = prog + ".ce"
if (!fd.is_file(prog_path)) {
var pkg_dir = package.find_package_dir(prog_path)
if (pkg_dir)
prog_path = pkg_dir + '/' + prog + '.ce'
}
if (!locator) {
os.print(`Main program ${_cell.args.program} could not be found\n`)
if (!fd.is_file(prog_path)) {
// Check core packages
var core_dir = core_path
prog_path = core_dir + '/' + prog + '.ce'
}
if (!fd.is_file(prog_path)) {
os.print(`Main program ${prog} could not be found\n`)
os.exit(1)
}
$_.clock(_ => {
// Get capabilities for the main program
var file_info = shop.file_info ? shop.file_info(locator.path) : null
var file_info = shop.file_info ? shop.file_info(prog_path) : null
var inject = shop.script_inject_for ? shop.script_inject_for(file_info) : []
// Build env object for injection
// Build env with runtime functions + capability injections
var env = {}
for (var i = 0; i < length(inject); i++) {
var key = inject[i]
arrfor(array(runtime_env), function(k) { env[k] = runtime_env[k] })
var _ki = 0
while (_ki < length(inject)) {
var inj = inject[_ki]
var key = inj
if (key && key[0] == '$') key = text(key, 1)
if (key == 'fd') env[key] = fd
else env[key] = $_[key]
if (key == 'fd') env['$fd'] = fd
else env['$' + key] = $_[key]
_ki = _ki + 1
}
// Create use function bound to the program's package
var pkg = file_info ? file_info.package : null
var use_fn = function(path) { return shop.use(path, pkg) }
env.use = function(path) { return shop.use(path, pkg) }
env.args = _cell.args.arg
// Call with signature: setup_module(args, use, env)
// The script wrapper binds $delay, $start, etc. from env
var val = call(locator.symbol, null, [_cell.args.arg, use_fn, env])
if (val)
var script = text(fd.slurp(prog_path))
var ast = analyze(script, prog_path)
var val = run_ast_fn(prog, ast, env)
if (val) {
log.error('Program must not return anything')
disrupt
}
})

View File

@@ -5,7 +5,6 @@ var fd = use('fd')
var http = use('http')
var miniz = use('miniz')
var time = use('time')
var js = use('js')
var crypto = use('crypto')
var blob = use('blob')
@@ -13,6 +12,10 @@ var pkg_tools = use('package')
var os = use('os')
var link = use('link')
var analyze = os.analyze
var run_ast_fn = os.run_ast_fn
var shop_json = os.json
var core = "core"
function pull_from_cache(content)
@@ -34,7 +37,7 @@ function ensure_dir(path) {
var current = starts_with(path, '/') ? '/' : ''
for (var i = 0; i < length(parts); i++) {
if (parts[i] == '') continue
current += parts[i] + '/'
current = current + parts[i] + '/'
if (!fd.stat(current).isDirectory) {
fd.mkdir(current)
}
@@ -142,8 +145,10 @@ function package_in_shop(package) {
function abs_path_to_package(package_dir)
{
if (!fd.is_file(package_dir + '/cell.toml'))
throw Error('Not a valid package directory (no cell.toml): ' + package_dir)
if (!fd.is_file(package_dir + '/cell.toml')) {
print('Not a valid package directory (no cell.toml): ' + package_dir)
disrupt
}
var packages_prefix = get_packages_dir() + '/'
var core_dir = packages_prefix + core_package
@@ -175,13 +180,12 @@ function abs_path_to_package(package_dir)
return package_dir
// For local directories (e.g., linked targets), read the package name from cell.toml
try {
var content = text(fd.slurp(package_dir + '/cell.toml'))
var _toml_path = package_dir + '/cell.toml'
if (fd.is_file(_toml_path)) {
var content = text(fd.slurp(_toml_path))
var cfg = toml.decode(content)
if (cfg.package)
return cfg.package
} catch (e) {
// Fall through
}
return null
@@ -299,12 +303,14 @@ Shop.resolve_package_info = function(pkg) {
// Verify if a package name is valid and return status
Shop.verify_package_name = function(pkg) {
if (!pkg) throw Error("Empty package name")
if (pkg == 'local') throw Error("local is not a valid package name")
if (pkg == 'core') throw Error("core is not a valid package name")
if (search(pkg, '://') != null)
throw Error(`Invalid package name: ${pkg}; did you mean ${array(pkg, '://')[1]}?`)
if (!pkg) { print("Empty package name"); disrupt }
if (pkg == 'local') { print("local is not a valid package name"); disrupt }
if (pkg == 'core') { print("core is not a valid package name"); disrupt }
if (search(pkg, '://') != null) {
print(`Invalid package name: ${pkg}; did you mean ${array(pkg, '://')[1]}?`)
disrupt
}
}
// Convert module package to download URL
@@ -383,9 +389,7 @@ function inject_env(inject) {
var env = {}
var rt = my$_.os ? my$_.os.runtime_env : null
if (rt) {
for (var k in rt) {
env[k] = rt[k]
}
arrfor(array(rt), function(k) { env[k] = rt[k] })
}
// Add capability injections
@@ -441,28 +445,30 @@ ${script}
// Resolve module function, hashing it in the process
// path is the exact path to the script file
function resolve_mod_fn(path, pkg) {
if (!fd.is_file(path)) throw Error(`path ${path} is not a file`)
if (!fd.is_file(path)) { print(`path ${path} is not a file`); disrupt }
var file_info = Shop.file_info(path)
var file_pkg = file_info.package
var inject = Shop.script_inject_for(file_info)
var content = text(fd.slurp(path))
var script = script_form(path, content, file_pkg, inject);
var script = script_form(path, content, file_pkg, inject)
var obj = pull_from_cache(stone(blob(script)))
if (obj) {
var fn = js.compile_unblob(obj)
return js.integrate(fn, null)
// Check cache for pre-compiled .mach blob
var cached = pull_from_cache(stone(blob(script)))
if (cached) {
return mach_load(cached)
}
// Compile name is just for debug/stack traces
var compile_name = path
// Compile via new pipeline
var ast = analyze(script, path)
var ast_json = shop_json.encode(ast)
var fn = js.compile(compile_name, script)
// Cache compiled binary
var compiled = mach_compile_ast(path, ast_json)
put_into_cache(stone(blob(script)), compiled)
put_into_cache(stone(blob(script)), js.compile_blob(fn))
return js.integrate(fn, null)
// Evaluate to get the function object
return mach_eval_ast(path, ast_json)
}
// given a path and a package context
@@ -576,33 +582,20 @@ Shop.open_package_dylib = function(pkg) {
var toml_path = pkg_dir + '/cell.toml'
if (fd.is_file(toml_path)) {
try {
var content = text(fd.slurp(toml_path))
var cfg = toml.decode(content)
if (cfg.dependencies) {
arrfor(array(cfg.dependencies), function(alias, i) {
var dep_pkg = cfg.dependencies[alias]
try {
Shop.open_package_dylib(dep_pkg)
} catch (dep_e) {
// Dependency dylib load failed, continue with others
}
})
}
} catch (e) {
// Error reading toml, continue
var content = text(fd.slurp(toml_path))
var cfg = toml.decode(content)
if (cfg.dependencies) {
arrfor(array(cfg.dependencies), function(alias, i) {
var dep_pkg = cfg.dependencies[alias]
Shop.open_package_dylib(dep_pkg)
})
}
}
var dl_path = get_lib_path(pkg)
if (fd.is_file(dl_path)) {
if (!open_dls[dl_path]) {
try {
open_dls[dl_path] = os.dylib_open(dl_path)
} catch (e) {
dylib_visited[pkg] = false
throw e
}
open_dls[dl_path] = os.dylib_open(dl_path)
}
}
}
@@ -642,8 +635,8 @@ function resolve_c_symbol(path, package_context) {
// If no package context, only check core internal symbols
if (!package_context || package_context == 'core') {
path = replace(path, '/', '_')
var core_sym = `js_${path}_use`
var _path = replace(path, '/', '_')
var core_sym = `js_${_path}_use`
if (os.internal_exists(core_sym)) {
return {
symbol: function() { return os.load_internal(core_sym) },
@@ -836,14 +829,13 @@ function execute_module(info)
// C only
used = call_c_module(c_resolve)
} else {
throw Error(`Module ${info.path} could not be found`)
print(`Module ${info.path} could not be found`); disrupt
}
// if (is_function(used))
// throw Error('C module loader returned a function; did you forget to call it?')
if (!used)
throw Error(`Module ${info} returned null`)
if (!used) { print(`Module ${info} returned null`); disrupt }
// stone(used)
return used
@@ -852,16 +844,14 @@ function execute_module(info)
function get_module(path, package_context) {
var info = resolve_module_info(path, package_context)
if (!info)
throw Error(`Module ${path} could not be found in ${package_context}`)
if (!info) { print(`Module ${path} could not be found in ${package_context}`); disrupt }
return execute_module(info)
}
Shop.use = function use(path, package_context) {
var info = resolve_module_info(path, package_context)
if (!info)
throw Error(`Module ${path} could not be found in ${package_context}`)
if (!info) { print(`Module ${path} could not be found in ${package_context}`); disrupt }
if (use_cache[info.cache_key])
return use_cache[info.cache_key]
@@ -889,13 +879,13 @@ function fetch_remote_hash(pkg) {
if (!api_url) return null
try {
var _fetch_hash = function() {
var resp = http.fetch(api_url)
return Shop.extract_commit_hash(pkg, text(resp))
} catch (e) {
log.console("Warning: Could not check for updates for " + pkg)
} disruption {
return null
}
return _fetch_hash()
}
// Download a zip for a package at a specific commit and cache it
@@ -909,14 +899,14 @@ function download_zip(pkg, commit_hash) {
return null
}
try {
var _download = function() {
var zip_blob = http.fetch(download_url)
fd.slurpwrite(cache_path, zip_blob)
return zip_blob
} catch (e) {
log.error("Download failed for " + pkg + ": " + e)
} disruption {
return null
}
return _download()
}
// Get zip from cache, returns null if not cached
@@ -1028,7 +1018,7 @@ Shop.extract = function(pkg) {
var zip_blob = get_package_zip(pkg)
if (!zip_blob)
throw Error("No zip blob available for " + pkg)
print("No zip blob available for " + pkg); disrupt
// Extract zip for remote package
install_zip(zip_blob, target_dir)
@@ -1113,7 +1103,7 @@ Shop.update = function(pkg) {
function install_zip(zip_blob, target_dir) {
var zip = miniz.read(zip_blob)
if (!zip) throw Error("Failed to read zip archive")
if (!zip) { print("Failed to read zip archive"); disrupt }
if (fd.is_link(target_dir)) fd.unlink(target_dir)
if (fd.is_dir(target_dir)) fd.rmdir(target_dir, 1)
@@ -1165,14 +1155,14 @@ Shop.get = function(pkg) {
if (!lock[pkg]) {
var info = Shop.resolve_package_info(pkg)
if (!info) {
throw Error("Invalid package: " + pkg)
print("Invalid package: " + pkg); disrupt
}
var commit = null
if (info != 'local') {
commit = fetch_remote_hash(pkg)
if (!commit) {
throw Error("Could not resolve commit for " + pkg)
print("Could not resolve commit for " + pkg); disrupt
}
}
@@ -1188,8 +1178,6 @@ Shop.get = function(pkg) {
// Compile a module
// List all files in a package
var debug = use('debug')
Shop.file_reload = function(file)
{
var info = Shop.file_info(file)