remove global
This commit is contained in:
4
add.ce
4
add.ce
@@ -7,7 +7,7 @@ if (args.length < 1) {
|
||||
log.console("Examples:")
|
||||
log.console(" cell get gitea.pockle.world/john/prosperon@main")
|
||||
log.console(" cell get github.com/user/repo@v1.0.0 myalias")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -16,4 +16,4 @@ var alias = args.length > 1 ? args[1] : null
|
||||
|
||||
shop.get(locator, alias)
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
@@ -40,4 +40,4 @@ function bottomUpTree(depth) {
|
||||
|
||||
mainThread()
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
@@ -22,4 +22,4 @@ for (var i = 0; i < sieve.length; i++)
|
||||
|
||||
log.console(c)
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
@@ -55,4 +55,4 @@ var n = arg[0] || 10
|
||||
|
||||
log.console(`Pfannkuchen(${n}) = ${fannkuch(n)}`)
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
@@ -13,4 +13,4 @@ for (var i in arr) {
|
||||
|
||||
log.console(`elapsed: ${time.number()-now}`)
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
@@ -393,4 +393,4 @@ log.console("");
|
||||
log.console("---------------------------------------------------------");
|
||||
log.console("Benchmark complete.\n");
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
|
||||
@@ -37,4 +37,4 @@ for (let y = 0; y < h; ++y) {
|
||||
log.console(text(row, 'b'));
|
||||
}
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
@@ -2,11 +2,11 @@ var math = use('math/radians')
|
||||
var N = 1000000;
|
||||
var num = 0;
|
||||
for (var i = 0; i < N; i ++) {
|
||||
var x = 2 * $_.random();
|
||||
var y = $_.random();
|
||||
var x = 2 * $random();
|
||||
var y = $random();
|
||||
if (y < math.sine(x * x))
|
||||
num++;
|
||||
}
|
||||
log.console(2 * num / N);
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
@@ -185,4 +185,4 @@ log.console(` stack_size: ${fn_info.stack_size}`)
|
||||
log.console(js.disassemble(advance))
|
||||
log.console(js.disassemble(advance).length)
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
@@ -49,4 +49,4 @@ function spectralnorm(n) {
|
||||
|
||||
log.console(spectralnorm(arg[0]).toFixed(9));
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
@@ -15,7 +15,7 @@
|
||||
// Parse command line arguments
|
||||
if (arg.length != 2) {
|
||||
log.console('Usage: cell benchmark_wota_nota_json.ce <LibraryName> <ScenarioName>');
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
|
||||
var lib_name = arg[0];
|
||||
@@ -172,13 +172,13 @@ var bench = benchmarks.find(b => b.name == scenario_name);
|
||||
if (!lib) {
|
||||
log.console('Unknown library:', lib_name);
|
||||
log.console('Available libraries:', libraries.map(l => l.name).join(', '));
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
|
||||
if (!bench) {
|
||||
log.console('Unknown scenario:', scenario_name);
|
||||
log.console('Available scenarios:', benchmarks.map(b => b.name).join(', '));
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
|
||||
// Run the benchmark for this library/scenario combination
|
||||
@@ -201,4 +201,4 @@ var result = {
|
||||
|
||||
log.console(result);
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
|
||||
16
build.ce
16
build.ce
@@ -20,25 +20,25 @@ for (var i = 0; i < args.length; i++) {
|
||||
target = args[++i]
|
||||
} else {
|
||||
log.error('-t requires a target')
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
} else if (args[i] == '-p' || args[i] == '--package') {
|
||||
if (i + 1 < args.length) {
|
||||
target_package = args[++i]
|
||||
} else {
|
||||
log.error('-p requires a package name')
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
} else if (args[i] == '-b' || args[i] == '--buildtype') {
|
||||
if (i + 1 < args.length) {
|
||||
buildtype = args[++i]
|
||||
if (buildtype != 'release' && buildtype != 'debug' && buildtype != 'minsize') {
|
||||
log.error('Invalid buildtype: ' + buildtype + '. Must be release, debug, or minsize')
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
} else {
|
||||
log.error('-b requires a buildtype (release, debug, minsize)')
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
} else if (args[i] == '--list-targets') {
|
||||
log.console('Available targets:')
|
||||
@@ -46,7 +46,7 @@ for (var i = 0; i < args.length; i++) {
|
||||
for (var t = 0; t < targets.length; t++) {
|
||||
log.console(' ' + targets[t])
|
||||
}
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ if (!target) {
|
||||
if (target && !build.has_target(target)) {
|
||||
log.error('Invalid target: ' + target)
|
||||
log.console('Available targets: ' + build.list_targets().join(', '))
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
|
||||
var packages = shop.list_packages()
|
||||
@@ -79,7 +79,7 @@ if (target_package) {
|
||||
}
|
||||
} catch (e) {
|
||||
log.error('Build failed: ' + e)
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
} else {
|
||||
// Build all packages
|
||||
@@ -99,4 +99,4 @@ if (target_package) {
|
||||
log.console(`Build complete: ${success} libraries built${failed > 0 ? `, ${failed} failed` : ''}`)
|
||||
}
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
|
||||
4
clean.ce
4
clean.ce
@@ -7,7 +7,7 @@ var build_dir = shop.get_shop_path() + '/build'
|
||||
|
||||
if (!fd.is_dir(build_dir)) {
|
||||
log.console("No build directory found at " + build_dir)
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -23,4 +23,4 @@ try {
|
||||
|
||||
log.console("Clean complete!")
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
18
config.ce
18
config.ce
@@ -99,14 +99,14 @@ function print_config(obj, prefix = '') {
|
||||
// Main command handling
|
||||
if (args.length == 0) {
|
||||
print_help()
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
|
||||
var config = pkg.load_config()
|
||||
if (!config) {
|
||||
log.error("Failed to load cell.toml")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ switch (command) {
|
||||
case 'get':
|
||||
if (args.length < 2) {
|
||||
log.error("Usage: cell config get <key>")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
var key = args[1]
|
||||
@@ -148,7 +148,7 @@ switch (command) {
|
||||
case 'set':
|
||||
if (args.length < 3) {
|
||||
log.error("Usage: cell config set <key> <value>")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
var key = args[1]
|
||||
@@ -164,7 +164,7 @@ switch (command) {
|
||||
]
|
||||
if (!valid_system_keys.includes(path[1])) {
|
||||
log.error("Invalid system key. Valid keys: " + valid_system_keys.join(', '))
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -178,7 +178,7 @@ switch (command) {
|
||||
// Handle actor-specific configuration
|
||||
if (args.length < 3) {
|
||||
log.error("Usage: cell config actor <name> <command> [options]")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ switch (command) {
|
||||
case 'get':
|
||||
if (args.length < 4) {
|
||||
log.error("Usage: cell config actor <name> get <key>")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
var key = args[3]
|
||||
@@ -220,7 +220,7 @@ switch (command) {
|
||||
case 'set':
|
||||
if (args.length < 5) {
|
||||
log.error("Usage: cell config actor <name> set <key> <value>")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
var key = args[3]
|
||||
@@ -244,4 +244,4 @@ switch (command) {
|
||||
print_help()
|
||||
}
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
@@ -62,7 +62,7 @@ An actor is a script that **does not return a value**. It runs as an independent
|
||||
// worker.ce
|
||||
log.console("Worker started")
|
||||
|
||||
$_.on_message = function(msg) {
|
||||
$on_message = function(msg) {
|
||||
log.console("Received:", msg)
|
||||
// Process message...
|
||||
}
|
||||
@@ -86,12 +86,12 @@ Reference to the current actor.
|
||||
log.console($me) // actor reference
|
||||
```
|
||||
|
||||
### $_.stop()
|
||||
### $stop()
|
||||
|
||||
Stop the current actor.
|
||||
|
||||
```javascript
|
||||
$_.stop()
|
||||
$stop()
|
||||
```
|
||||
|
||||
### $send(actor, message, callback)
|
||||
@@ -207,7 +207,7 @@ $start(function(worker) {
|
||||
|
||||
$delay(function() {
|
||||
log.console("Shutting down")
|
||||
$_.stop()
|
||||
$stop()
|
||||
}, 10)
|
||||
```
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ Cell is an actor-based scripting language for building concurrent applications.
|
||||
```javascript
|
||||
// hello.ce - A simple actor
|
||||
log.console("Hello, Cell!")
|
||||
$_.stop()
|
||||
$stop()
|
||||
```
|
||||
|
||||
```bash
|
||||
|
||||
@@ -48,7 +48,7 @@ function get_status() {
|
||||
}
|
||||
|
||||
// Main message receiver
|
||||
$_.receiver(function(msg) {
|
||||
$receiver(function(msg) {
|
||||
switch (msg.type) {
|
||||
case 'download':
|
||||
if (state.downloading) {
|
||||
@@ -86,7 +86,7 @@ $_.receiver(function(msg) {
|
||||
}
|
||||
|
||||
// Schedule the first chunk read
|
||||
$_.delay(read_next_chunk, 0);
|
||||
$delay(read_next_chunk, 0);
|
||||
|
||||
} catch (e) {
|
||||
state.error = e.toString();
|
||||
@@ -167,7 +167,7 @@ function read_next_chunk() {
|
||||
}
|
||||
|
||||
// Schedule next chunk read
|
||||
$_.delay(read_next_chunk, 0);
|
||||
$delay(read_next_chunk, 0);
|
||||
|
||||
} catch (e) {
|
||||
// Error during download
|
||||
|
||||
@@ -7,7 +7,7 @@ var json = use('json');
|
||||
var waiting_client = null;
|
||||
var match_id = 0;
|
||||
|
||||
$_.portal(e => {
|
||||
$portal(e => {
|
||||
log.console("NAT server: received connection request");
|
||||
|
||||
if (!isa(e.actor, actor))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
log.console(`nat client starting`)
|
||||
|
||||
$_.contact((actor, reason) => {
|
||||
$contact((actor, reason) => {
|
||||
if (actor) {
|
||||
log.console(`trying to message ${actor}`)
|
||||
send(actor, {type:"greet"})
|
||||
@@ -10,10 +10,10 @@ $_.contact((actor, reason) => {
|
||||
}, {
|
||||
address: "108.210.60.32", // NAT server's public IP
|
||||
port: 4000,
|
||||
actor: $_
|
||||
actor: $self
|
||||
})
|
||||
|
||||
$_.receiver(e => {
|
||||
$receiver(e => {
|
||||
switch(e.type) {
|
||||
case 'greet':
|
||||
log.console(`hello!`)
|
||||
|
||||
6
fetch.ce
6
fetch.ce
@@ -23,7 +23,7 @@ for (var i = 0; i < args.length; i++) {
|
||||
log.console("")
|
||||
log.console("This command ensures that the zip files on disk match what's in")
|
||||
log.console("the lock file. For local packages, this is a no-op.")
|
||||
$_.stop()
|
||||
$stop()
|
||||
} else if (!args[i].startsWith('-')) {
|
||||
target_pkg = args[i]
|
||||
}
|
||||
@@ -37,7 +37,7 @@ if (target_pkg) {
|
||||
// Fetch specific package
|
||||
if (!all_packages.includes(target_pkg)) {
|
||||
log.error("Package not found: " + target_pkg)
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
packages_to_fetch.push(target_pkg)
|
||||
} else {
|
||||
@@ -83,4 +83,4 @@ for (var pkg of packages_to_fetch) {
|
||||
log.console("")
|
||||
log.console("Fetch complete: " + text(success_count) + " fetched, " + text(skip_count) + " skipped, " + text(fail_count) + " failed")
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
|
||||
4
help.ce
4
help.ce
@@ -15,7 +15,7 @@ if (command) {
|
||||
log.error("No help available for command: " + command)
|
||||
log.console("Run 'cell help' to see available commands.")
|
||||
}
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -44,4 +44,4 @@ if (stat && stat.isFile) {
|
||||
log.console("Run 'cell help <command>' for more information on a command.")
|
||||
}
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
@@ -6,7 +6,7 @@ var build = use('build')
|
||||
|
||||
if (args.length < 1) {
|
||||
log.console("Usage: cell install <locator>")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ var locator = args[0]
|
||||
log.console("Installing " + locator + "...")
|
||||
if (!shop.update(locator)) {
|
||||
log.console("Failed to install " + locator)
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -29,4 +29,4 @@ for (var dep of deps) {
|
||||
build.build_package(locator)
|
||||
log.console("Installed " + locator)
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
(function engine() {
|
||||
var ACTORDATA = cell.hidden.actorsym
|
||||
var _cell = globalThis.cell
|
||||
delete globalThis.cell
|
||||
var ACTORDATA = _cell.hidden.actorsym
|
||||
var SYSYM = '__SYSTEM__'
|
||||
|
||||
var hidden = cell.hidden
|
||||
var __cell = globalThis._cell
|
||||
|
||||
var hidden = _cell.hidden
|
||||
|
||||
var os = hidden.os;
|
||||
cell.os = null
|
||||
_cell.os = null
|
||||
|
||||
var dylib_ext
|
||||
|
||||
cell.id ??= "newguy"
|
||||
_cell.id ??= "newguy"
|
||||
|
||||
switch(os.platform()) {
|
||||
case 'Windows': dylib_ext = '.dll'; break;
|
||||
@@ -25,7 +29,6 @@ function use_embed(name) {
|
||||
return load_internal(`js_${name}_use`)
|
||||
}
|
||||
|
||||
globalThis.use = use_embed
|
||||
globalThis.meme = function(obj) {
|
||||
return {
|
||||
__proto__: obj
|
||||
@@ -77,9 +80,9 @@ function use_core(path) {
|
||||
if (fd.is_file(file_path)) {
|
||||
var script_blob = fd.slurp(file_path)
|
||||
var script = utf8.decode(script_blob)
|
||||
var mod = `(function setup_module($_){${script}})`
|
||||
var mod = `(function setup_module(use){${script}})`
|
||||
var fn = js.eval('core:' + path, mod)
|
||||
var result = fn.call(sym);
|
||||
var result = fn.call(sym, use_core);
|
||||
use_cache[cache_key] = result;
|
||||
return result;
|
||||
}
|
||||
@@ -88,9 +91,7 @@ function use_core(path) {
|
||||
return sym;
|
||||
}
|
||||
|
||||
globalThis.use = use_core
|
||||
|
||||
var blob = use('blob')
|
||||
var blob = use_core('blob')
|
||||
var blob_stone = blob.prototype.stone
|
||||
var blob_stonep = blob.prototype.stonep;
|
||||
delete blob.prototype.stone;
|
||||
@@ -141,16 +142,16 @@ stone.p = function(object)
|
||||
return _ObjectIsFrozen(object)
|
||||
}
|
||||
|
||||
var actor_mod = use('actor')
|
||||
var wota = use('wota')
|
||||
var nota = use('nota')
|
||||
var actor_mod = use_core('actor')
|
||||
var wota = use_core('wota')
|
||||
var nota = use_core('nota')
|
||||
|
||||
// Load internal modules for global functions
|
||||
globalThis.text = use('internal/text')
|
||||
globalThis.number = use('internal/number')
|
||||
globalThis.array = use('internal/array')
|
||||
globalThis.object = use('internal/object')
|
||||
globalThis.fn = use('internal/fn')
|
||||
globalThis.text = use_core('internal/text')
|
||||
globalThis.number = use_core('internal/number')
|
||||
globalThis.array = use_core('internal/array')
|
||||
globalThis.object = use_core('internal/object')
|
||||
globalThis.fn = use_core('internal/fn')
|
||||
|
||||
// Global utility functions (use already-captured references)
|
||||
var _isArray = _ArrayIsArray
|
||||
@@ -319,7 +320,7 @@ function caller_data(depth = 0)
|
||||
}
|
||||
|
||||
function console_rec(line, file, msg) {
|
||||
return `[${cell.id.slice(0,5)}] [${file}:${line}]: ${msg}\n`
|
||||
return `[${_cell.id.slice(0,5)}] [${file}:${line}]: ${msg}\n`
|
||||
// time: [${time.text("mb d yyyy h:nn:ss")}]
|
||||
}
|
||||
|
||||
@@ -374,9 +375,9 @@ function disrupt(err)
|
||||
|
||||
actor_mod.on_exception(disrupt)
|
||||
|
||||
cell.args = cell.hidden.init
|
||||
cell.args ??= {}
|
||||
cell.id ??= "newguy"
|
||||
_cell.args = _cell.hidden.init
|
||||
_cell.args ??= {}
|
||||
_cell.id ??= "newguy"
|
||||
|
||||
function create_actor(desc = {id:guid()}) {
|
||||
var actor = {}
|
||||
@@ -384,24 +385,85 @@ function create_actor(desc = {id:guid()}) {
|
||||
return actor
|
||||
}
|
||||
|
||||
var $_ = create_actor()
|
||||
var $_ = {}
|
||||
$_.self = create_actor()
|
||||
|
||||
os.use_cache = use_cache
|
||||
os.global_shop_path = shop_path
|
||||
os.$_ = $_
|
||||
|
||||
var shop = use('shop')
|
||||
var shop = use_core('shop')
|
||||
|
||||
globalThis.use = shop.use
|
||||
var json = use('json')
|
||||
var time = use('time')
|
||||
var json = use_core('json')
|
||||
var time = use_core('time')
|
||||
|
||||
var pronto = use('pronto')
|
||||
var pronto = use_core('pronto')
|
||||
globalThis.fallback = pronto.fallback
|
||||
globalThis.parallel = pronto.parallel
|
||||
globalThis.race = pronto.race
|
||||
globalThis.sequence = pronto.sequence
|
||||
|
||||
$_.time_limit = function(requestor, seconds)
|
||||
{
|
||||
if (!pronto.is_requestor(requestor))
|
||||
throw new Error('time_limit: first argument must be a requestor');
|
||||
if (!isa(seconds, number) || seconds <= 0)
|
||||
throw new Error('time_limit: seconds must be a positive number');
|
||||
|
||||
return function time_limit_requestor(callback, value) {
|
||||
pronto.check_callback(callback, 'time_limit')
|
||||
var finished = false
|
||||
var requestor_cancel = null
|
||||
var timer_cancel = null
|
||||
|
||||
function cancel(reason) {
|
||||
if (finished) return
|
||||
finished = true
|
||||
if (timer_cancel) {
|
||||
timer_cancel()
|
||||
timer_cancel = null
|
||||
}
|
||||
if (requestor_cancel) {
|
||||
try { pronto.requestor_cancel(reason) } catch (_) {}
|
||||
requestor_cancel = null
|
||||
}
|
||||
}
|
||||
|
||||
timer_cancel = $_.delay(function() {
|
||||
if (finished) return
|
||||
def reason = make_reason(factory, 'Timeout.', seconds)
|
||||
if (requestor_cancel) {
|
||||
try { requestor_cancel(reason) } catch (_) {}
|
||||
requestor_cancel = null
|
||||
}
|
||||
finished = true
|
||||
callback(null, reason)
|
||||
}, seconds)
|
||||
|
||||
try {
|
||||
requestor_cancel = requestor(function(val, reason) {
|
||||
if (finished) return
|
||||
finished = true
|
||||
if (timer_cancel) {
|
||||
timer_cancel()
|
||||
timer_cancel = null
|
||||
}
|
||||
callback(val, reason)
|
||||
}, value)
|
||||
} catch (ex) {
|
||||
cancel(ex)
|
||||
callback(null, ex)
|
||||
}
|
||||
|
||||
return function(reason) {
|
||||
if (requestor_cancel) {
|
||||
try { requestor_cancel(reason) } catch (_) {}
|
||||
requestor_cancel = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var config = {
|
||||
ar_timer: 60,
|
||||
actor_memory:0,
|
||||
@@ -410,7 +472,7 @@ var config = {
|
||||
main: true
|
||||
}
|
||||
|
||||
cell.config = config
|
||||
_cell.config = config
|
||||
|
||||
ENETSERVICE = config.net_service
|
||||
REPLYTIMEOUT = config.reply_timeout
|
||||
@@ -575,7 +637,7 @@ $_.start = function start(cb, program, ...args) {
|
||||
if (args.length == 1 && Array.isArray(args[0])) args = args[0]
|
||||
var startup = {
|
||||
id,
|
||||
overling: $_,
|
||||
overling: $_.self,
|
||||
root,
|
||||
arg: args,
|
||||
program,
|
||||
@@ -618,14 +680,14 @@ $_.delay = function delay(fn, seconds = 0) {
|
||||
return function() { actor_mod.removetimer(id) }
|
||||
}
|
||||
|
||||
var enet = use('enet')
|
||||
var enet = use_core('enet')
|
||||
|
||||
// causes this actor to stop when another actor stops.
|
||||
var couplings = new Set()
|
||||
$_.couple = function couple(actor) {
|
||||
if (actor == $_) return // can't couple to self
|
||||
if (actor == $_.self) return // can't couple to self
|
||||
couplings.add(actor[ACTORDATA].id)
|
||||
sys_msg(actor, {kind:'couple', from: $_})
|
||||
sys_msg(actor, {kind:'couple', from: $_.self})
|
||||
log.system(`coupled to ${actor}`)
|
||||
}
|
||||
|
||||
@@ -651,7 +713,7 @@ function actor_send(actor, message) {
|
||||
if (typeof message != 'object') throw new Error('Must send an object record.')
|
||||
|
||||
// message to self
|
||||
if (actor[ACTORDATA].id == cell.id) {
|
||||
if (actor[ACTORDATA].id == _cell.id) {
|
||||
if (receive_fn) receive_fn(message.data)
|
||||
return
|
||||
}
|
||||
@@ -742,7 +804,7 @@ globalThis.send = function send(actor, message, reply) {
|
||||
}
|
||||
}, REPLYTIMEOUT)
|
||||
send.reply = id
|
||||
send.replycc = $_
|
||||
send.replycc = $_.self
|
||||
}
|
||||
|
||||
// Instead of sending immediately, queue it
|
||||
@@ -751,10 +813,10 @@ globalThis.send = function send(actor, message, reply) {
|
||||
|
||||
stone(send)
|
||||
|
||||
if (!cell.args.id) cell.id = guid()
|
||||
else cell.id = cell.args.id
|
||||
if (!_cell.args.id) _cell.id = guid()
|
||||
else _cell.id = _cell.args.id
|
||||
|
||||
$_[ACTORDATA].id = cell.id
|
||||
$_.self[ACTORDATA].id = _cell.id
|
||||
|
||||
// Actor's timeslice for processing a single message
|
||||
function turn(msg)
|
||||
@@ -767,7 +829,7 @@ function turn(msg)
|
||||
//log.console(`FIXME: need to get main from config, not just set to true`)
|
||||
//log.console(`FIXME: remove global access (ie globalThis.use)`)
|
||||
//log.console(`FIXME: add freeze/unfreeze at this level, so we can do it (but scripts cannot)`)
|
||||
actor_mod.register_actor(cell.id, turn, true, config.ar_timer)
|
||||
actor_mod.register_actor(_cell.id, turn, true, config.ar_timer)
|
||||
|
||||
if (config.actor_memory)
|
||||
js.mem_limit(config.actor_memory)
|
||||
@@ -775,14 +837,16 @@ if (config.actor_memory)
|
||||
if (config.stack_max)
|
||||
js.max_stacksize(config.system.stack_max);
|
||||
|
||||
overling = cell.args.overling
|
||||
root = cell.args.root
|
||||
root ??= $_
|
||||
overling = _cell.args.overling
|
||||
$_.overling = overling
|
||||
|
||||
root = _cell.args.root
|
||||
root ??= $_.self
|
||||
|
||||
if (overling) {
|
||||
$_.couple(overling) // auto couple to overling
|
||||
|
||||
report_to_overling({type:'greet', actor: $_})
|
||||
report_to_overling({type:'greet', actor: $_.self})
|
||||
}
|
||||
|
||||
// sys messages are always dispatched immediately
|
||||
@@ -795,11 +859,11 @@ function sys_msg(actor, msg)
|
||||
function report_to_overling(msg)
|
||||
{
|
||||
if (!overling) return
|
||||
sys_msg(overling, {kind:'underling', message:msg, from: $_})
|
||||
sys_msg(overling, {kind:'underling', message:msg, from: $_.self})
|
||||
}
|
||||
|
||||
// Determine the program to run from command line
|
||||
var program = cell.args.program
|
||||
var program = _cell.args.program
|
||||
|
||||
if (!program) {
|
||||
log.error('No program specified. Usage: cell <program.ce> [args...]')
|
||||
@@ -890,21 +954,21 @@ var init_end = time.number()
|
||||
var load_program_start = time.number()
|
||||
|
||||
// Finally, run the program
|
||||
actor_mod.setname(cell.args.program)
|
||||
actor_mod.setname(_cell.args.program)
|
||||
|
||||
var prog = cell.args.program
|
||||
var prog = _cell.args.program
|
||||
|
||||
var package = use('package')
|
||||
var package = use_core('package')
|
||||
|
||||
var locator = shop.resolve_locator(cell.args.program + ".ce", null)
|
||||
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)
|
||||
var pkg = package.find_package_dir(_cell.args.program + ".ce")
|
||||
locator = shop.resolve_locator(_cell.args.program + ".ce", pkg)
|
||||
}
|
||||
|
||||
if (!locator)
|
||||
throw new Error(`Main program ${cell.args.program} could not be found`)
|
||||
throw new Error(`Main program ${_cell.args.program} could not be found`)
|
||||
|
||||
// Hide JavaScript built-ins - make them inaccessible
|
||||
// Store references we need internally before deleting
|
||||
@@ -921,9 +985,9 @@ var _JSON = JSON
|
||||
|
||||
// juicing these before Math is gone
|
||||
|
||||
use('math/radians')
|
||||
use('math/cycles')
|
||||
use('math/degrees')
|
||||
use_core('math/radians')
|
||||
use_core('math/cycles')
|
||||
use_core('math/degrees')
|
||||
|
||||
// Delete from globalThis
|
||||
delete globalThis.Object
|
||||
@@ -974,7 +1038,26 @@ delete globalThis.RegExp
|
||||
_ObjectFreeze(globalThis)
|
||||
|
||||
$_.clock(_ => {
|
||||
var val = locator.symbol.call(null, $_, cell.args.arg);
|
||||
// Get capabilities for the main program
|
||||
var file_info = shop.file_info ? shop.file_info(locator.path) : null
|
||||
var inject = shop.script_inject_for ? shop.script_inject_for(file_info) : []
|
||||
|
||||
// Build values array for injection
|
||||
var vals = []
|
||||
for (var i = 0; i < inject.length; i++) {
|
||||
var key = inject[i]
|
||||
if (key && key[0] == '$') key = key.substring(1)
|
||||
if (key == 'fd') vals.push(fd)
|
||||
else vals.push($_[key])
|
||||
}
|
||||
|
||||
// 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) }
|
||||
|
||||
// Call with signature: setup_module(args, use, ...capabilities)
|
||||
// The script wrapper builds $_ from the injected capabilities for backward compatibility
|
||||
var val = locator.symbol.call(null, _cell.args.arg, use_fn, ...vals)
|
||||
|
||||
if (val)
|
||||
throw new Error('Program must not return anything');
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
/* number.cm - number conversion and math utilities */
|
||||
|
||||
var math = use('math/radians')
|
||||
|
||||
var _floor = Math.floor
|
||||
var _ceil = Math.ceil
|
||||
var _round = Math.round
|
||||
@@ -9,7 +6,7 @@ var _abs = Math.abs
|
||||
var _trunc = Math.trunc
|
||||
var _min = Math.min
|
||||
var _max = Math.max
|
||||
var _pow = math.power
|
||||
var _pow = Math.pow
|
||||
var _parseInt = parseInt
|
||||
var _parseFloat = parseFloat
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/* text.cm - text conversion and formatting utilities */
|
||||
|
||||
var blob = use('blob')
|
||||
var utf8 = use('utf8')
|
||||
|
||||
|
||||
18
link.ce
18
link.ce
@@ -26,7 +26,7 @@ if (args.length < 1) {
|
||||
log.console(" clear Remove all links")
|
||||
log.console(" <path> Link the package in <path> to that path")
|
||||
log.console(" <package> <target> Link <package> to <target> (path or package)")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ if (cmd == 'list') {
|
||||
} else if (cmd == 'delete' || cmd == 'rm') {
|
||||
if (args.length < 2) {
|
||||
log.console("Usage: link delete <package>")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ if (cmd == 'list') {
|
||||
|
||||
if (!arg1) {
|
||||
log.console("Error: target or package required")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ if (cmd == 'list') {
|
||||
if (!fd.is_file(toml_path)) {
|
||||
log.console("Error: No cell.toml found at " + target)
|
||||
log.console("For linking to another package, use: link <package> <target>")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -147,12 +147,12 @@ if (cmd == 'list') {
|
||||
pkg_name = content.package
|
||||
} else {
|
||||
log.console("Error: cell.toml at " + target + " does not define 'package'")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
} catch (e) {
|
||||
log.console("Error reading cell.toml: " + e)
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -161,7 +161,7 @@ if (cmd == 'list') {
|
||||
if (target.startsWith('/')) {
|
||||
if (!fd.is_file(target + '/cell.toml')) {
|
||||
log.console("Error: " + target + " is not a valid package (no cell.toml)")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -171,9 +171,9 @@ if (cmd == 'list') {
|
||||
link.add(pkg_name, target, shop)
|
||||
} catch (e) {
|
||||
log.console("Error: " + e.message)
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
6
list.ce
6
list.ce
@@ -17,7 +17,7 @@ if (args && args.length > 0) {
|
||||
} else if (args[0] == 'package') {
|
||||
if (args.length < 2) {
|
||||
log.console("Usage: cell list package <name>")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
mode = 'package'
|
||||
@@ -28,7 +28,7 @@ if (args && args.length > 0) {
|
||||
log.console(" cell list all : list all recursive packages")
|
||||
log.console(" cell list package <name>: list dependencies of <name>")
|
||||
log.console(" cell list shop : list all packages in shop")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -82,4 +82,4 @@ function print_deps(ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
|
||||
20
pack.ce
20
pack.ce
@@ -23,7 +23,7 @@ if (args.length < 1) {
|
||||
log.error(' -b, --buildtype <type> Build type: release, debug, minsize (default: release)')
|
||||
log.error('')
|
||||
log.error('Available targets: ' + build.list_targets().join(', '))
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -35,25 +35,25 @@ for (var i = 1; i < args.length; i++) {
|
||||
target = args[++i]
|
||||
} else {
|
||||
log.error('-t requires a target')
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
} else if (args[i] == '-o' || args[i] == '--output') {
|
||||
if (i + 1 < args.length) {
|
||||
output_name = args[++i]
|
||||
} else {
|
||||
log.error('-o requires an output name')
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
} else if (args[i] == '-b' || args[i] == '--buildtype') {
|
||||
if (i + 1 < args.length) {
|
||||
buildtype = args[++i]
|
||||
if (buildtype != 'release' && buildtype != 'debug' && buildtype != 'minsize') {
|
||||
log.error('Invalid buildtype: ' + buildtype + '. Must be release, debug, or minsize')
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
} else {
|
||||
log.error('-b requires a buildtype (release, debug, minsize)')
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
} else if (args[i] == '-h' || args[i] == '--help') {
|
||||
log.console('Usage: cell pack <package> [options]')
|
||||
@@ -64,10 +64,10 @@ for (var i = 1; i < args.length; i++) {
|
||||
log.console(' -b, --buildtype <type> Build type: release, debug, minsize (default: release)')
|
||||
log.console('')
|
||||
log.console('Available targets: ' + build.list_targets().join(', '))
|
||||
$_.stop()
|
||||
$stop()
|
||||
} else {
|
||||
log.error('Unknown option: ' + args[i])
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ if (!target) {
|
||||
if (target && !build.has_target(target)) {
|
||||
log.error('Invalid target: ' + target)
|
||||
log.console('Available targets: ' + build.list_targets().join(', '))
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
|
||||
// Prepare packages: core + dependencies + target package
|
||||
@@ -117,7 +117,7 @@ try {
|
||||
} catch (e) {
|
||||
log.error('Build failed: ')
|
||||
log.error(e)
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
|
||||
71
pronto.cm
71
pronto.cm
@@ -3,9 +3,6 @@
|
||||
// Based on Douglas Crockford's parseq, adapted for Cell.
|
||||
// Time is in seconds.
|
||||
|
||||
var os = use('os')
|
||||
var $_ = os.$_
|
||||
|
||||
function make_reason(factory, excuse, evidence) {
|
||||
def reason = new Error(`pronto.${factory}${excuse ? ': ' + excuse : ''}`)
|
||||
reason.evidence = evidence
|
||||
@@ -303,69 +300,6 @@ function sequence(requestor_array) {
|
||||
}
|
||||
}
|
||||
|
||||
// time_limit(requestor, seconds)
|
||||
// Wraps a requestor with a time limit.
|
||||
function time_limit(requestor, seconds) {
|
||||
def factory = 'time_limit'
|
||||
if (!is_requestor(requestor))
|
||||
throw make_reason(factory, 'Not a requestor.', requestor)
|
||||
if (typeof seconds != 'number' || seconds <= 0)
|
||||
throw make_reason(factory, 'Bad time limit.', seconds)
|
||||
|
||||
return function time_limit_requestor(callback, value) {
|
||||
check_callback(callback, factory)
|
||||
let finished = false
|
||||
let requestor_cancel = null
|
||||
let timer_cancel = null
|
||||
|
||||
function cancel(reason) {
|
||||
if (finished) return
|
||||
finished = true
|
||||
if (timer_cancel) {
|
||||
timer_cancel()
|
||||
timer_cancel = null
|
||||
}
|
||||
if (requestor_cancel) {
|
||||
try { requestor_cancel(reason) } catch (_) {}
|
||||
requestor_cancel = null
|
||||
}
|
||||
}
|
||||
|
||||
timer_cancel = $_.delay(function() {
|
||||
if (finished) return
|
||||
def reason = make_reason(factory, 'Timeout.', seconds)
|
||||
if (requestor_cancel) {
|
||||
try { requestor_cancel(reason) } catch (_) {}
|
||||
requestor_cancel = null
|
||||
}
|
||||
finished = true
|
||||
callback(null, reason)
|
||||
}, seconds)
|
||||
|
||||
try {
|
||||
requestor_cancel = requestor(function(val, reason) {
|
||||
if (finished) return
|
||||
finished = true
|
||||
if (timer_cancel) {
|
||||
timer_cancel()
|
||||
timer_cancel = null
|
||||
}
|
||||
callback(val, reason)
|
||||
}, value)
|
||||
} catch (ex) {
|
||||
cancel(ex)
|
||||
callback(null, ex)
|
||||
}
|
||||
|
||||
return function(reason) {
|
||||
if (requestor_cancel) {
|
||||
try { requestor_cancel(reason) } catch (_) {}
|
||||
requestor_cancel = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// requestorize(unary)
|
||||
// Converts a unary function into a requestor.
|
||||
function requestorize(unary) {
|
||||
@@ -421,7 +355,8 @@ return {
|
||||
parallel,
|
||||
race,
|
||||
sequence,
|
||||
time_limit,
|
||||
requestorize,
|
||||
objectify
|
||||
objectify,
|
||||
is_requestor,
|
||||
check_callback
|
||||
}
|
||||
|
||||
@@ -143,4 +143,4 @@ if (typeof arg == 'undefined' || arg.length < 1) {
|
||||
}
|
||||
}
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
@@ -4,10 +4,10 @@ var shop = use('shop')
|
||||
|
||||
if (args.length < 1) {
|
||||
log.console("Usage: cell remove <alias|path>")
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
|
||||
shop.remove(args[0])
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
|
||||
101
shop.cm
101
shop.cm
@@ -180,11 +180,12 @@ Shop.file_info = function(file) {
|
||||
if (pkg_dir) {
|
||||
info.package = abs_path_to_package(pkg_dir)
|
||||
|
||||
info.name = file.substring(pkg_dir.length + 1)
|
||||
if (info.is_actor)
|
||||
info.name = info.path.substring(0, info.path.length - ACTOR_EXT.length)
|
||||
info.name = file.substring(pkg_dir.length + 1, file.length - ACTOR_EXT.length)
|
||||
else if (info.is_module)
|
||||
info.name = info.path.substring(0, info.path.length - MOD_EXT.length)
|
||||
info.name = file.substring(pkg_dir.length + 1, file.length - MOD_EXT.length)
|
||||
else
|
||||
info.name = file.substring(pkg_dir.length + 1)
|
||||
}
|
||||
|
||||
return info
|
||||
@@ -325,11 +326,73 @@ Shop.extract_commit_hash = function(pkg, response) {
|
||||
|
||||
var open_dls = {}
|
||||
|
||||
// Default capabilities injected into scripts
|
||||
// These map to $_ properties in engine.cm
|
||||
var SHOP_DEFAULT_INJECT = ['$self', '$overling', '$clock', '$delay', '$start', '$receiver', '$contact', '$portal', '$time_limit', '$couple', '$stop', '$unneeded', '$connection', '$fd']
|
||||
|
||||
function strip_dollar(name) {
|
||||
if (name && name[0] == '$') return name.substring(1)
|
||||
return name
|
||||
}
|
||||
|
||||
// Decide what a given module is allowed to see.
|
||||
// This is the capability gate - tweak as needed.
|
||||
Shop.script_inject_for = function(file_info) {
|
||||
if (!file_info) return []
|
||||
|
||||
// For now, grant everything to all scripts
|
||||
// Later this can be tuned per package/script
|
||||
return array(SHOP_DEFAULT_INJECT)
|
||||
}
|
||||
|
||||
// Get capabilities for a script path (public API)
|
||||
Shop.get_script_capabilities = function(path) {
|
||||
var file_info = Shop.file_info(path)
|
||||
return Shop.script_inject_for(file_info)
|
||||
}
|
||||
|
||||
function inject_params(inject) {
|
||||
if (!inject || !inject.length) return ''
|
||||
return ', ' + inject.join(', ')
|
||||
}
|
||||
|
||||
function inject_values(inject) {
|
||||
var vals = []
|
||||
for (var i = 0; i < inject.length; i++) {
|
||||
var key = strip_dollar(inject[i])
|
||||
if (key == 'fd') vals.push(fd)
|
||||
else vals.push($_[key])
|
||||
}
|
||||
return vals
|
||||
}
|
||||
|
||||
// Build the use function for a specific package context
|
||||
function make_use_fn_code(pkg_arg) {
|
||||
return `function(path) { return globalThis.use(path, ${pkg_arg}); }`
|
||||
}
|
||||
|
||||
// for script forms, path is the canonical path of the module
|
||||
var script_form = function(path, script, pkg) {
|
||||
var script_form = function(path, script, pkg, inject) {
|
||||
var pkg_arg = pkg ? `'${pkg}'` : 'null'
|
||||
var relative_use_fn = `def PACKAGE = ${pkg_arg}; def use = function(path) { return globalThis.use(path, ${pkg_arg});}`
|
||||
var fn = `(function setup_module($_, args){ def arg = args; ${relative_use_fn}; ${script}})`
|
||||
var params = inject_params(inject)
|
||||
|
||||
// Build $_ object from injected capabilities for backward compatibility
|
||||
var build_compat = ''
|
||||
if (inject && inject.length) {
|
||||
var compat_props = []
|
||||
for (var i = 0; i < inject.length; i++) {
|
||||
var name = inject[i]
|
||||
var key = name
|
||||
if (key && key[0] == '$') key = key.substring(1)
|
||||
compat_props.push(key + ': ' + name)
|
||||
}
|
||||
build_compat = 'var $_ = {' + compat_props.join(', ') + '};'
|
||||
}
|
||||
|
||||
// use is passed as a parameter, not on globalThis for the script
|
||||
// $fd is injected as a capability, but we still allow use('fd') for now
|
||||
// $_ is built from injected capabilities for backward compatibility
|
||||
var fn = `(function setup_module(args, use${params}){ def arg = args; def PACKAGE = ${pkg_arg}; ${build_compat} ${script}})`
|
||||
return fn
|
||||
}
|
||||
|
||||
@@ -340,8 +403,9 @@ function resolve_mod_fn(path, pkg) {
|
||||
|
||||
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);
|
||||
var script = script_form(path, content, file_pkg, inject);
|
||||
|
||||
var obj = pull_from_cache(utf8.encode(script))
|
||||
if (obj) {
|
||||
@@ -570,7 +634,9 @@ function resolve_module_info(path, package_context) {
|
||||
// This ensures linked packages resolve to the same cache entry
|
||||
// whether accessed via symlink or directly
|
||||
var cache_key
|
||||
if (mod_resolve.scope < 900 && mod_resolve.path) {
|
||||
if (mod_resolve.scope == SCOPE_CORE) {
|
||||
cache_key = 'core/' + path
|
||||
} else if (mod_resolve.scope < 900 && mod_resolve.path) {
|
||||
// Use realpath to resolve symlinks and get the actual file location
|
||||
var real_path = fd.realpath(mod_resolve.path)
|
||||
if (real_path) {
|
||||
@@ -628,6 +694,13 @@ Shop.is_loaded = function(path, package_context) {
|
||||
return use_cache[cache_key] != null
|
||||
}
|
||||
|
||||
// Create a use function bound to a specific package context
|
||||
function make_use_fn(pkg) {
|
||||
return function(path) {
|
||||
return Shop.use(path, pkg)
|
||||
}
|
||||
}
|
||||
|
||||
function execute_module(info)
|
||||
{
|
||||
var c_resolve = info.c_resolve
|
||||
@@ -640,7 +713,17 @@ function execute_module(info)
|
||||
if (c_resolve.scope < 900) {
|
||||
context = c_resolve.symbol(null, $_)
|
||||
}
|
||||
used = mod_resolve.symbol.call(context, $_)
|
||||
|
||||
// Get file info to determine inject list
|
||||
var file_info = Shop.file_info(mod_resolve.path)
|
||||
var inject = Shop.script_inject_for(file_info)
|
||||
var vals = inject_values(inject)
|
||||
var pkg = file_info.package
|
||||
var use_fn = make_use_fn(pkg)
|
||||
|
||||
// Call with signature: setup_module(args, use, ...capabilities)
|
||||
// args is null for module loading
|
||||
used = mod_resolve.symbol.call(context, null, use_fn, ...vals)
|
||||
} else if (c_resolve.scope < 900) {
|
||||
// C only
|
||||
used = c_resolve.symbol(null, $_)
|
||||
|
||||
@@ -146,7 +146,7 @@ void script_startup(cell_rt *prt)
|
||||
JS_SetPropertyStr(js, cell, "hidden", hidden_fn);
|
||||
JS_SetPropertyStr(js, hidden_fn, "os", js_os_use(js));
|
||||
|
||||
const char actorsym_script[] = "var sym = Symbol(`actordata`); sym;";
|
||||
const char actorsym_script[] = "Symbol('actordata');";
|
||||
|
||||
JSValue actorsym = JS_Eval(js, actorsym_script, sizeof(actorsym_script)-1, "internal", 0);
|
||||
JS_SetPropertyStr(js, hidden_fn, "actorsym", actorsym);
|
||||
|
||||
20
test.ce
20
test.ce
@@ -18,7 +18,7 @@ if (args.length > 0) {
|
||||
if (args[0] == 'package') {
|
||||
if (args.length < 2) {
|
||||
log.console(`Usage: cell test package <name>`)
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
var name = args[1]
|
||||
@@ -28,7 +28,7 @@ if (args.length > 0) {
|
||||
log.console(`Testing package: ${resolved.alias} (${resolved.pkg})`)
|
||||
} else {
|
||||
log.console(`Package not found: ${name}`)
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
} else if (args[0] == 'all') {
|
||||
@@ -36,7 +36,7 @@ if (args.length > 0) {
|
||||
log.console(`Testing all packages...`)
|
||||
} else {
|
||||
log.console(`Usage: cell test [package <name> | all]`)
|
||||
$_.stop()
|
||||
$stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -95,9 +95,9 @@ function spawn_actor_test(test_info) {
|
||||
|
||||
try {
|
||||
// Spawn the actor test - it should send back results
|
||||
// The actor receives $_.parent which it can use to send results
|
||||
// The actor receives $parent which it can use to send results
|
||||
var actor_path = test_info.path.substring(0, test_info.path.length - 3) // remove .ce
|
||||
entry.actor = $_.start(actor_path)
|
||||
entry.actor = $start(actor_path)
|
||||
pending_actor_tests.push(entry)
|
||||
} catch (e) {
|
||||
entry.status = "failed"
|
||||
@@ -356,7 +356,7 @@ function check_timeouts() {
|
||||
}
|
||||
|
||||
if (pending_actor_tests.length > 0) {
|
||||
$_.delay(check_timeouts, 1000)
|
||||
$delay(check_timeouts, 1000)
|
||||
}
|
||||
check_completion()
|
||||
}
|
||||
@@ -424,7 +424,7 @@ function finalize_results() {
|
||||
log.console(`Tests: ${totals.passed} passed, ${totals.failed} failed, ${totals.total} total`)
|
||||
|
||||
generate_reports(totals)
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
|
||||
// If no actor tests, finalize immediately
|
||||
@@ -441,7 +441,7 @@ if (all_actor_tests.length == 0) {
|
||||
log.console(`Tests: ${totals.passed} passed, ${totals.failed} failed, ${totals.total} total`)
|
||||
} else {
|
||||
// Start timeout checker
|
||||
$_.delay(check_timeouts, 1000)
|
||||
$delay(check_timeouts, 1000)
|
||||
}
|
||||
|
||||
|
||||
@@ -533,10 +533,10 @@ Total: ${totals.total}, Passed: ${totals.passed}, Failed: ${totals.failed}
|
||||
// If no actor tests, generate reports and stop immediately
|
||||
if (all_actor_tests.length == 0) {
|
||||
generate_reports(totals)
|
||||
$_.stop()
|
||||
$stop()
|
||||
} else {
|
||||
// Set up portal to receive messages from actor tests
|
||||
$_.portal(function(msg) {
|
||||
$portal(function(msg) {
|
||||
handle_actor_message(msg)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
return {
|
||||
test_clock: function() {
|
||||
// Original test verified $_.clock callbacks.
|
||||
// Original test verified $clock callbacks.
|
||||
// This cannot be easily tested in a synchronous function return.
|
||||
// We assume the runtime works.
|
||||
var i = 0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var parseq = use('parseq', $_.delay)
|
||||
var parseq = use('parseq', $delay)
|
||||
var time = use('time')
|
||||
|
||||
return {
|
||||
@@ -9,14 +9,14 @@ return {
|
||||
|
||||
function load_comment_from_api_requestor(id) {
|
||||
return function(cb) {
|
||||
return $_.delay(() => cb({ id, title: `Comment #${id}` }), 0.5)
|
||||
// returning the $_.delay return lets them be cancelled up the chain
|
||||
return $delay(() => cb({ id, title: `Comment #${id}` }), 0.5)
|
||||
// returning the $delay return lets them be cancelled up the chain
|
||||
}
|
||||
}
|
||||
|
||||
$_.receiver(tree => {
|
||||
$receiver(tree => {
|
||||
var child_reqs = tree.children.map(child => cb => {
|
||||
$_.start(e => send(e.actor, child, cb), "tests/comments")
|
||||
$start(e => send(e.actor, child, cb), "tests/comments")
|
||||
})
|
||||
|
||||
var job = parseq.par_all({
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
var parseq = use('parseq', $_.delay)
|
||||
var parseq = use('parseq', $delay)
|
||||
var time = use('time')
|
||||
|
||||
function load_comment_from_api_requestor(id) {
|
||||
return function(cb) {
|
||||
return $_.delay(() => cb({ id, title: `Comment #${id}` }), 0.5)
|
||||
// returning the $_.delay return lets them be cancelled up the chain
|
||||
return $delay(() => cb({ id, title: `Comment #${id}` }), 0.5)
|
||||
// returning the $delay return lets them be cancelled up the chain
|
||||
}
|
||||
}
|
||||
|
||||
$_.receiver(tree => {
|
||||
$receiver(tree => {
|
||||
var child_reqs = tree.children.map(child => cb => {
|
||||
$_.start(e => send(e.actor, child, cb), "tests/comments") // Note: recursively calls itself? Original used "tests/comments"
|
||||
$start(e => send(e.actor, child, cb), "tests/comments") // Note: recursively calls itself? Original used "tests/comments"
|
||||
// We should probably change this to "tests/comments_actor" if it's recursive
|
||||
})
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ return {
|
||||
log.console(`Did not get an actor: ${reason}`)
|
||||
}
|
||||
|
||||
$_.contact(contact_fn,
|
||||
$contact(contact_fn,
|
||||
{
|
||||
address: "localhost",
|
||||
port: 5678,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
return {
|
||||
test_couple: function() {
|
||||
$_.start(e => {
|
||||
$_.couple(e.actor)
|
||||
$start(e => {
|
||||
$couple(e.actor)
|
||||
}, "tests/delay_actor")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ function loop()
|
||||
count++;
|
||||
log.console(`loop ${count}`);
|
||||
if (count < 60)
|
||||
$_.delay(loop, 0.01);
|
||||
$delay(loop, 0.01);
|
||||
else
|
||||
$_.stop()
|
||||
$stop()
|
||||
}
|
||||
|
||||
$_.delay(loop,0.01)
|
||||
$delay(loop,0.01)
|
||||
|
||||
@@ -4,7 +4,7 @@ var time = use('time')
|
||||
return {
|
||||
test_guid: function() {
|
||||
var st = time.number()
|
||||
var guid = new blob(256, $_.random_fit)
|
||||
var guid = new blob(256, $random_fit)
|
||||
stone(guid)
|
||||
var btime = time.number()-st
|
||||
st = time.number()
|
||||
|
||||
@@ -7,7 +7,7 @@ return {
|
||||
var host = 'google.com'
|
||||
var path = '/'
|
||||
|
||||
$_.start(e => {
|
||||
$start(e => {
|
||||
send(e.actor, { op: 'get', domain: host, port: 80}, addrs => {
|
||||
log.console(addrs[0])
|
||||
})
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
$_.start(e => {
|
||||
$start(e => {
|
||||
log.console(`got message from hanger: ${e.type}`)
|
||||
if (e.type == 'greet')
|
||||
$_.delay(_ => {
|
||||
$delay(_ => {
|
||||
log.console(`sending stop message to hanger`)
|
||||
$_.stop(e.actor)
|
||||
$stop(e.actor)
|
||||
}, 1)
|
||||
|
||||
if (e.type == 'disrupt') {
|
||||
log.console(`underling successfully killed.`)
|
||||
send($_.parent, { type: "test_result", passed: true })
|
||||
$_.stop()
|
||||
send($parent, { type: "test_result", passed: true })
|
||||
$stop()
|
||||
}
|
||||
}, 'tests/hang_actor')
|
||||
|
||||
@@ -15,14 +15,14 @@ return {
|
||||
|
||||
// Spawn several underlings
|
||||
for (var i = 0; i < targetCount; i++) {
|
||||
$_.start(function(greet) {
|
||||
$start(function(greet) {
|
||||
underlingCount++;
|
||||
log.console("Underling spawned: " + underlingCount);
|
||||
}, "tests/underling_actor", ["test" + i]);
|
||||
}
|
||||
|
||||
// We can't easily wait here without a loop that yields, but this is a single threaded JS env usually.
|
||||
// If $_.delay is async, we return immediately.
|
||||
// If $delay is async, we return immediately.
|
||||
|
||||
log.console("Spawned " + targetCount + " underlings (async)");
|
||||
}
|
||||
|
||||
@@ -29,9 +29,9 @@ return {
|
||||
// The original 'comments.ce' was an actor script.
|
||||
// We should probably restore 'comments.ce' as 'comments_actor.ce' for this test to work if it relies on spawning it.
|
||||
// But 'comments.cm' (the new test file) also has the logic.
|
||||
// We need an actor file for $_.start to work with.
|
||||
// We need an actor file for $start to work with.
|
||||
|
||||
$_.start(e => {
|
||||
$start(e => {
|
||||
if (actor) return
|
||||
actor = e.actor
|
||||
send(actor, tree, (result, reason) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
return {
|
||||
test_portal: function() {
|
||||
// Starts the portal actor
|
||||
$_.start(e => {}, "tests/portal_actor")
|
||||
$start(e => {}, "tests/portal_actor")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
var password = "abc123"
|
||||
|
||||
$_.portal(e => {
|
||||
$portal(e => {
|
||||
if (e.password != password)
|
||||
send(e, {reason:"Password does not match."});
|
||||
else
|
||||
send(e, $_)
|
||||
send(e, $self)
|
||||
}, 5678);
|
||||
|
||||
$_.receiver(e => {
|
||||
$receiver(e => {
|
||||
log.console(`Got message: ${e}`)
|
||||
send(e, {greet: "Hello back!"})
|
||||
$_.delay(_ => $_.stop(), 0.2)
|
||||
$delay(_ => $stop(), 0.2)
|
||||
})
|
||||
|
||||
@@ -7,7 +7,7 @@ function make_requestor(name, delay_seconds, should_succeed) {
|
||||
return function(callback, value) {
|
||||
log.console(`Starting ${name} with value: ${value}`)
|
||||
if (delay_seconds > 0) {
|
||||
$_.delay(function() {
|
||||
$delay(function() {
|
||||
if (should_succeed) {
|
||||
log.console(`${name} succeeded with: ${value + 1}`)
|
||||
callback(value + 1)
|
||||
|
||||
@@ -1 +1 @@
|
||||
$_.start(e => {}, "tests/reply_actor")
|
||||
$start(e => {}, "tests/reply_actor")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
$_.receiver(e => {
|
||||
$receiver(e => {
|
||||
log.console(`Got a message: ${e}`)
|
||||
|
||||
send(e, {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
return {
|
||||
test_send: function() {
|
||||
$_.start(e => {
|
||||
$start(e => {
|
||||
send(e.actor, { message: "Hello! Good to go?" }, msg => {
|
||||
log.console(`Original sender got message back: ${msg}. Stopping!`)
|
||||
// $_.stop() // Removed
|
||||
// $stop() // Removed
|
||||
})
|
||||
}, "tests/reply_actor")
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
return {
|
||||
test_stop: function() {
|
||||
log.console(`About to stop.`)
|
||||
// $_.stop() // Removed
|
||||
// $stop() // Removed
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
var cmds = {
|
||||
stop: $_.stop,
|
||||
stop: $stop,
|
||||
disrupt: _ => {
|
||||
$_.delay(_ => { throw new Error() }, 0.5)
|
||||
$delay(_ => { throw new Error() }, 0.5)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
return {
|
||||
test_unneeded: function() {
|
||||
$_.start(e => {}, "tests/unneeded_actor")
|
||||
$start(e => {}, "tests/unneeded_actor")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
$_.unneeded(_ => {
|
||||
$unneeded(_ => {
|
||||
log.console("Unneded function fired.");
|
||||
$_.start(null, "tests/unneeded_actor")
|
||||
$start(null, "tests/unneeded_actor")
|
||||
}, 1);
|
||||
|
||||
@@ -23,7 +23,7 @@ for (var i = 0; i < args.length; i++) {
|
||||
log.console("")
|
||||
log.console("This command checks for updates to all packages and downloads")
|
||||
log.console("new versions. For local packages, ensures the symlink is correct.")
|
||||
$_.stop()
|
||||
$stop()
|
||||
} else if (!args[i].startsWith('-')) {
|
||||
target_pkg = args[i]
|
||||
}
|
||||
@@ -74,4 +74,4 @@ if (target_pkg) {
|
||||
}
|
||||
}
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
|
||||
@@ -34,4 +34,4 @@ if (cmd == 'link') {
|
||||
}
|
||||
}
|
||||
|
||||
$_.stop()
|
||||
$stop()
|
||||
@@ -1,3 +1,2 @@
|
||||
var shop = use('shop')
|
||||
log.console("0.1.0")
|
||||
$_.stop()
|
||||
$stop()
|
||||
Reference in New Issue
Block a user