diff --git a/js/compiler/compiler.js b/js/compiler/compiler.js index 30542b7..50e0859 100644 --- a/js/compiler/compiler.js +++ b/js/compiler/compiler.js @@ -42,9 +42,15 @@ var forEachChild = (function () { return forEachChild; })(); -function buildActor(constructorES5, block) { +function buildActor(constructorES5, nameExpOpt, block) { + var nameExpStr; + if (nameExpOpt.numChildren === 1) { + nameExpStr = ', ' + nameExpOpt.asES5; + } else { + nameExpStr = ''; + } return 'Syndicate.Actor.spawnActor(new '+constructorES5+', '+ - 'function() ' + block.asES5 + ');'; + 'function() ' + block.asES5 + nameExpStr + ');'; } function buildFacet(facetBlock, transitionBlock) { @@ -79,11 +85,11 @@ function buildCaseEvent(eventPattern, body) { } var modifiedSourceActions = { - ActorStatement_noConstructor: function(_actor, block) { - return buildActor('Object()', block); + ActorStatement_noConstructor: function(_actor, _namedOpt, nameExpOpt, block) { + return buildActor('Object()', nameExpOpt, block); }, - ActorStatement_withConstructor: function(_actor, ctorExp, block) { - return buildActor(ctorExp.asES5, block); + ActorStatement_withConstructor: function(_actor, ctorExp, _namedOpt, nameExpOpt, block) { + return buildActor(ctorExp.asES5, nameExpOpt, block); }, DataspaceStatement_ground: function(_ground, _dataspace, maybeId, block) { diff --git a/js/compiler/demo-proper-interest-tracking.js b/js/compiler/demo-proper-interest-tracking.js index 6beb22b..0290f06 100644 --- a/js/compiler/demo-proper-interest-tracking.js +++ b/js/compiler/demo-proper-interest-tracking.js @@ -14,7 +14,7 @@ assertion type ready(what); assertion type entry(key, val); ground dataspace { - actor { + actor named 'listener' { react { assert ready("listener"); on asserted entry($key, _) { @@ -31,7 +31,7 @@ ground dataspace { } } - actor { + actor named 'other-listener' { react { assert ready('other-listener'); during entry($key, _) { @@ -56,7 +56,7 @@ ground dataspace { } } - actor { + actor named 'driver' { react until { case asserted ready("listener") { react until { diff --git a/js/compiler/syndicate.ohm b/js/compiler/syndicate.ohm index c5c00a6..31a8ac5 100644 --- a/js/compiler/syndicate.ohm +++ b/js/compiler/syndicate.ohm @@ -16,8 +16,8 @@ Syndicate <: ES5 { FunctionBodyBlock = "{" FunctionBody "}" // odd that this isn't in es5.ohm somewhere ActorStatement - = actor CallExpression FunctionBodyBlock -- withConstructor - | actor FunctionBodyBlock -- noConstructor + = actor CallExpression (named Expression)? FunctionBodyBlock -- withConstructor + | actor (named Expression)? FunctionBodyBlock -- noConstructor DataspaceStatement = ground dataspace identifier? FunctionBodyBlock -- ground @@ -82,6 +82,7 @@ Syndicate <: ES5 { ground = "ground" ~identifierPart message = "message" ~identifierPart metalevel = "metalevel" ~identifierPart + named = "named" ~identifierPart on = "on" ~identifierPart react = "react" ~identifierPart retracted = "retracted" ~identifierPart diff --git a/js/src/actor.js b/js/src/actor.js index f337e31..ae101e2 100644 --- a/js/src/actor.js +++ b/js/src/actor.js @@ -10,11 +10,11 @@ var Util = require('./util.js'); //--------------------------------------------------------------------------- -function spawnActor(state, bootFn) { - Dataspace.spawn(new Actor(state, bootFn)); +function spawnActor(state, bootFn, optName) { + Dataspace.spawn(new Actor(state, bootFn, optName)); } -function Actor(state, bootFn) { +function Actor(state, bootFn, optName) { this.state = state; this.facets = Immutable.Set(); this.mux = new Mux.Mux(); @@ -22,6 +22,10 @@ function Actor(state, bootFn) { this.knowledge = Trie.emptyTrie; this.pendingActions = []; + if (typeof optName !== 'undefined') { + this.name = optName; + } + this.boot = function() { var self = this; withCurrentFacet(null, function () { diff --git a/js/src/dataspace.js b/js/src/dataspace.js index 449a6ef..6d9af72 100644 --- a/js/src/dataspace.js +++ b/js/src/dataspace.js @@ -113,17 +113,32 @@ Dataspace.exitDataspace = function () { Dataspace.enqueueAction(terminateDataspace()); }; -Dataspace.inertBehavior = { - handleEvent: function (e) {} +Dataspace.inertBehavior = function (oldBehavior) { + var b = { handleEvent: function (e) {} }; + if ('name' in oldBehavior) { + b.name = oldBehavior.name; + } + return b; }; // Instance methods +Dataspace.prototype.debugName = function (pid) { + var p = this.processTable.get(pid, null); + if (p === null) { + return '(dead)[' + pid + ']'; + } + if ('name' in p.behavior) { + return JSON.stringify(p.behavior.name) + '[' + pid + ']'; + } + return '(anon)[' + pid + ']'; +}; + Dataspace.prototype.asChild = function (pid, f, omitLivenessCheck) { var self = this; var p = this.processTable.get(pid, null); if (!omitLivenessCheck && (p === null)) { - console.warn("Dataspace.asChild eliding invocation of dead process", pid); + console.warn("Dataspace.asChild eliding invocation of dead process", this.debugName(pid)); return; } @@ -141,15 +156,17 @@ Dataspace.prototype.asChild = function (pid, f, omitLivenessCheck) { Dataspace.prototype.kill = function (pid, exn) { if (exn) { if (exn.stack) { - console.error("Process crashed", pid, exn, exn.stack); + console.error("Process crashed", this.debugName(pid), exn, exn.stack); } else { - console.error("Process crashed", pid, exn); + console.error("Process crashed", this.debugName(pid), exn); } } else if (Dataspace.noisy) { - console.log("Process exiting", pid); + console.log("Process exiting", this.debugName(pid)); } var p = this.processTable.get(pid); - this.processTable = this.processTable.set(pid, { behavior: Dataspace.inertBehavior }); + this.processTable = this.processTable.set(pid, { + behavior: Dataspace.inertBehavior(p.behavior) + }); if (p) { if (p.behavior.trapexit) { this.asChild(pid, function () { return p.behavior.trapexit(exn); }, true); @@ -234,7 +251,8 @@ Dataspace.prototype.interpretAction = function (pid, action) { case 'message': if (Patch.observe.isClassOf(action.message)) { - console.warn('Process ' + pid + ' send message containing query', action.message); + console.warn('Process ' + this.debugName(pid) + ' sent message containing query', + action.message); } if (pid !== 'meta' && Patch.atMeta.isClassOf(action.message)) { Dataspace.send(action.message[0]); @@ -262,7 +280,7 @@ Dataspace.prototype.interpretAction = function (pid, action) { case 'terminate': var oldMux = this.mux.shallowCopy(); this.deliverPatches(oldMux, this.mux.removeStream(pid)); - if (Dataspace.noisy) console.log("Process exit complete", pid); + if (Dataspace.noisy) console.log("Process exit complete", this.debugName(pid)); this.processTable = this.processTable.remove(pid); return true;