This commit is contained in:
Tony Garnock-Jones 2016-05-08 12:26:20 -04:00
parent 7138568e3f
commit d31a5fcf58
4 changed files with 30 additions and 45 deletions

View File

@ -10,7 +10,7 @@ var path = require('path');
var ohm = require('ohm-js');
var ES5 = require('./es5.js');
var grammarSource = Buffer("Ly8gLSotIGphdmFzY3JpcHQgLSotCi8vIFN5bnRhY3RpYyBleHRlbnNpb25zIHRvIEVTNSBmb3IgU3luZGljYXRlL2pzLiBTZWUgY29tcGlsZXIuanMgZm9yCi8vIHRoZSByZXN0IG9mIHRoZSB0cmFuc2xhdG9yLgoKU3luZGljYXRlIDw6IEVTNSB7CiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBFeHRlbnNpb25zIHRvIGV4cHJlc3Npb25zLgoKICBTdGF0ZW1lbnQKICAgICs9IEFjdG9yU3RhdGVtZW50CiAgICB8IERhdGFzcGFjZVN0YXRlbWVudAogICAgfCBBY3RvckZhY2V0U3RhdGVtZW50CiAgICB8IEFzc2VydGlvblR5cGVEZWNsYXJhdGlvblN0YXRlbWVudAogICAgfCBTZW5kTWVzc2FnZVN0YXRlbWVudAoKICBBY3RvclN0YXRlbWVudAogICAgPSBhY3RvciBDYWxsRXhwcmVzc2lvbiBCbG9jayAtLSB3aXRoQ29uc3RydWN0b3IKICAgIHwgYWN0b3IgQmxvY2sgICAgICAgICAgICAgICAgLS0gbm9Db25zdHJ1Y3RvcgoKICBEYXRhc3BhY2VTdGF0ZW1lbnQKICAgID0gZ3JvdW5kIGRhdGFzcGFjZSBpZGVudGlmaWVyPyBCbG9jayAtLSBncm91bmQKICAgIHwgZGF0YXNwYWNlIEJsb2NrICAgICAgICAgICAgICAgICAgICAtLSBub3JtYWwKCiAgQWN0b3JGYWNldFN0YXRlbWVudAogICAgPSBzdGF0ZSBGYWNldEJsb2NrIHVudGlsIEZhY2V0U3RhdGVUcmFuc2l0aW9uQmxvY2sgICAtLSBzdGF0ZQogICAgfCB1bnRpbCBGYWNldFN0YXRlVHJhbnNpdGlvbkJsb2NrICAgICAgICAgICAgICAgICAgICAtLSB1bnRpbAogICAgfCBmb3JldmVyIEZhY2V0QmxvY2sgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLSBmb3JldmVyCgogIEFzc2VydGlvblR5cGVEZWNsYXJhdGlvblN0YXRlbWVudAogICAgPSBhc3NlcnRpb24gdHlwZSBpZGVudGlmaWVyICIoIiBGb3JtYWxQYXJhbWV0ZXJMaXN0ICIpIiAoIj0iIHN0cmluZ0xpdGVyYWwpPyAjKHNjKQoKICBTZW5kTWVzc2FnZVN0YXRlbWVudCA9ICI6OiIgRXhwcmVzc2lvbjx3aXRoSW4+ICMoc2MpCgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gT25nb2luZyBldmVudCBoYW5kbGVycy4KCiAgRmFjZXRCbG9jayA9ICJ7IiBGYWNldEluaXRCbG9jaz8gRmFjZXRTaXR1YXRpb24qIEZhY2V0RG9uZUJsb2NrPyAifSIKICBGYWNldFN0YXRlVHJhbnNpdGlvbkJsb2NrID0gInsiIEZhY2V0U3RhdGVUcmFuc2l0aW9uKiAifSIKCiAgRmFjZXRJbml0QmxvY2sgPSBpbml0IEJsb2NrCiAgRmFjZXREb25lQmxvY2sgPSBkb25lIEJsb2NrCgogIEZhY2V0U2l0dWF0aW9uCiAgICA9IGFzc2VydCBGYWNldFBhdHRlcm4gIyhzYykgICAgICAtLSBhc3NlcnQKICAgIHwgb24gRmFjZXRFdmVudFBhdHRlcm4gQmxvY2sgICAgICAgICAgICAgICAtLSBldmVudAogICAgfCBkdXJpbmcgRmFjZXRQYXR0ZXJuIEZhY2V0QmxvY2sgLS0gZHVyaW5nCgogIEZhY2V0RXZlbnRQYXR0ZXJuCiAgICA9IG1lc3NhZ2UgRmFjZXRQYXR0ZXJuICAgLS0gbWVzc2FnZUV2ZW50CiAgICB8IGFzc2VydGVkIEZhY2V0UGF0dGVybiAgLS0gYXNzZXJ0ZWRFdmVudAogICAgfCByZXRyYWN0ZWQgRmFjZXRQYXR0ZXJuIC0tIHJldHJhY3RlZEV2ZW50CgogIEZhY2V0VHJhbnNpdGlvbkV2ZW50UGF0dGVybgogICAgPSBGYWNldEV2ZW50UGF0dGVybiAgICAgICAgICAtLSBmYWNldEV2ZW50CiAgICB8ICIoIiBFeHByZXNzaW9uPHdpdGhJbj4gIikiIC0tIHJpc2luZ0VkZ2UKCiAgRmFjZXRTdGF0ZVRyYW5zaXRpb24KICAgID0gY2FzZSBGYWNldFRyYW5zaXRpb25FdmVudFBhdHRlcm4gQmxvY2sgLS0gd2l0aENvbnRpbnVhdGlvbgogICAgfCBjYXNlIEZhY2V0VHJhbnNpdGlvbkV2ZW50UGF0dGVybiAjKHNjKSAtLSBub0NvbnRpbnVhdGlvbgoKICBGYWNldFBhdHRlcm4KICAgID0gTGVmdEhhbmRTaWRlRXhwcmVzc2lvbiBtZXRhbGV2ZWwgZGVjaW1hbEludGVnZXJMaXRlcmFsIC0tIHdpdGhNZXRhbGV2ZWwKICAgIHwgTGVmdEhhbmRTaWRlRXhwcmVzc2lvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0tIG5vTWV0YWxldmVsCgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gS2V5d29yZHMuIFdlIGRvbid0IGFkZCB0aGVtIHRvIHRoZSAia2V5d29yZCIgcHJvZHVjdGlvbiBiZWNhdXNlCiAgLy8gd2UgZG9uJ3Qgd2FudCB0byBtYWtlIHRoZW0gdW5hdmFpbGFibGUgdG8gcHJvZ3JhbXMgYXMKICAvLyBpZGVudGlmaWVycy4KCiAgYWN0b3IgPSAiYWN0b3IiIH5pZGVudGlmaWVyUGFydAogIGFzc2VydCA9ICJhc3NlcnQiIH5pZGVudGlmaWVyUGFydAogIGFzc2VydGVkID0gImFzc2VydGVkIiB+aWRlbnRpZmllclBhcnQKICBhc3NlcnRpb24gPSAiYXNzZXJ0aW9uIiB+aWRlbnRpZmllclBhcnQKICBkYXRhc3BhY2UgPSAiZGF0YXNwYWNlIiB+aWRlbnRpZmllclBhcnQKICBkb25lID0gImRvbmUiIH5pZGVudGlmaWVyUGFydAogIGR1cmluZyA9ICJkdXJpbmciIH5pZGVudGlmaWVyUGFydAogIGZvcmV2ZXIgPSAiZm9yZXZlciIgfmlkZW50aWZpZXJQYXJ0CiAgZ3JvdW5kID0gImdyb3VuZCIgfmlkZW50aWZpZXJQYXJ0CiAgaW5pdCA9ICJpbml0IiB+aWRlbnRpZmllclBhcnQKICBtZXNzYWdlID0gIm1lc3NhZ2UiIH5pZGVudGlmaWVyUGFydAogIG1ldGFsZXZlbCA9ICJtZXRhbGV2ZWwiIH5pZGVudGlmaWVyUGFydAogIG9uID0gIm9uIiB+aWRlbnRpZmllclBhcnQKICByZXRyYWN0ZWQgPSAicmV0cmFjdGVkIiB+aWRlbnRpZmllclBhcnQKICBzdGF0ZSA9ICJzdGF0ZSIgfmlkZW50aWZpZXJQYXJ0CiAgdHlwZSA9ICJ0eXBlIiB+aWRlbnRpZmllclBhcnQKICB1bnRpbCA9ICJ1bnRpbCIgfmlkZW50aWZpZXJQYXJ0Cn0K","base64").toString();
var grammarSource = Buffer("Ly8gLSotIGphdmFzY3JpcHQgLSotCi8vIFN5bnRhY3RpYyBleHRlbnNpb25zIHRvIEVTNSBmb3IgU3luZGljYXRlL2pzLiBTZWUgY29tcGlsZXIuanMgZm9yCi8vIHRoZSByZXN0IG9mIHRoZSB0cmFuc2xhdG9yLgoKU3luZGljYXRlIDw6IEVTNSB7CiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBFeHRlbnNpb25zIHRvIGV4cHJlc3Npb25zLgoKICBTdGF0ZW1lbnQKICAgICs9IEFjdG9yU3RhdGVtZW50CiAgICB8IERhdGFzcGFjZVN0YXRlbWVudAogICAgfCBBY3RvckZhY2V0U3RhdGVtZW50CiAgICB8IEFzc2VydGlvblR5cGVEZWNsYXJhdGlvblN0YXRlbWVudAogICAgfCBTZW5kTWVzc2FnZVN0YXRlbWVudAoKICBBY3RvclN0YXRlbWVudAogICAgPSBhY3RvciBDYWxsRXhwcmVzc2lvbiBCbG9jayAtLSB3aXRoQ29uc3RydWN0b3IKICAgIHwgYWN0b3IgQmxvY2sgICAgICAgICAgICAgICAgLS0gbm9Db25zdHJ1Y3RvcgoKICBEYXRhc3BhY2VTdGF0ZW1lbnQKICAgID0gZ3JvdW5kIGRhdGFzcGFjZSBpZGVudGlmaWVyPyBCbG9jayAtLSBncm91bmQKICAgIHwgZGF0YXNwYWNlIEJsb2NrICAgICAgICAgICAgICAgICAgICAtLSBub3JtYWwKCiAgQWN0b3JGYWNldFN0YXRlbWVudAogICAgPSBzdGF0ZSBGYWNldEJsb2NrIHVudGlsIEZhY2V0U3RhdGVUcmFuc2l0aW9uQmxvY2sgICAtLSBzdGF0ZQogICAgfCB1bnRpbCBGYWNldFN0YXRlVHJhbnNpdGlvbkJsb2NrICAgICAgICAgICAgICAgICAgICAtLSB1bnRpbAogICAgfCBmb3JldmVyIEZhY2V0QmxvY2sgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLSBmb3JldmVyCgogIEFzc2VydGlvblR5cGVEZWNsYXJhdGlvblN0YXRlbWVudAogICAgPSBhc3NlcnRpb24gdHlwZSBpZGVudGlmaWVyICIoIiBGb3JtYWxQYXJhbWV0ZXJMaXN0ICIpIiAoIj0iIHN0cmluZ0xpdGVyYWwpPyAjKHNjKQoKICBTZW5kTWVzc2FnZVN0YXRlbWVudCA9ICI6OiIgRXhwcmVzc2lvbjx3aXRoSW4+ICMoc2MpCgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gT25nb2luZyBldmVudCBoYW5kbGVycy4KCiAgRmFjZXRCbG9jayA9ICJ7IiBGYWNldEluaXRCbG9jaz8gRmFjZXRTaXR1YXRpb24qIEZhY2V0RG9uZUJsb2NrPyAifSIKICBGYWNldFN0YXRlVHJhbnNpdGlvbkJsb2NrID0gInsiIEZhY2V0U3RhdGVUcmFuc2l0aW9uKiAifSIKCiAgRmFjZXRJbml0QmxvY2sgPSBpbml0IEJsb2NrCiAgRmFjZXREb25lQmxvY2sgPSBkb25lIEJsb2NrCgogIEZhY2V0U2l0dWF0aW9uCiAgICA9IGFzc2VydCBGYWNldFBhdHRlcm4gQXNzZXJ0V2hlbkNsYXVzZT8gIyhzYykgLS0gYXNzZXJ0CiAgICB8IG9uIEZhY2V0RXZlbnRQYXR0ZXJuIEJsb2NrICAgICAgICAgICAgICAgICAgLS0gZXZlbnQKICAgIHwgZHVyaW5nIEZhY2V0UGF0dGVybiBGYWNldEJsb2NrICAgICAgICAgICAgICAtLSBkdXJpbmcKCiAgQXNzZXJ0V2hlbkNsYXVzZSA9IHdoZW4gIigiIEV4cHJlc3Npb248d2l0aEluPiAiKSIKCiAgRmFjZXRFdmVudFBhdHRlcm4KICAgID0gbWVzc2FnZSBGYWNldFBhdHRlcm4gICAtLSBtZXNzYWdlRXZlbnQKICAgIHwgYXNzZXJ0ZWQgRmFjZXRQYXR0ZXJuICAtLSBhc3NlcnRlZEV2ZW50CiAgICB8IHJldHJhY3RlZCBGYWNldFBhdHRlcm4gLS0gcmV0cmFjdGVkRXZlbnQKCiAgRmFjZXRUcmFuc2l0aW9uRXZlbnRQYXR0ZXJuCiAgICA9IEZhY2V0RXZlbnRQYXR0ZXJuICAgICAgICAgIC0tIGZhY2V0RXZlbnQKICAgIHwgIigiIEV4cHJlc3Npb248d2l0aEluPiAiKSIgLS0gcmlzaW5nRWRnZQoKICBGYWNldFN0YXRlVHJhbnNpdGlvbgogICAgPSBjYXNlIEZhY2V0VHJhbnNpdGlvbkV2ZW50UGF0dGVybiBCbG9jayAtLSB3aXRoQ29udGludWF0aW9uCiAgICB8IGNhc2UgRmFjZXRUcmFuc2l0aW9uRXZlbnRQYXR0ZXJuICMoc2MpIC0tIG5vQ29udGludWF0aW9uCgogIEZhY2V0UGF0dGVybgogICAgPSBMZWZ0SGFuZFNpZGVFeHByZXNzaW9uIG1ldGFsZXZlbCBkZWNpbWFsSW50ZWdlckxpdGVyYWwgLS0gd2l0aE1ldGFsZXZlbAogICAgfCBMZWZ0SGFuZFNpZGVFeHByZXNzaW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLS0gbm9NZXRhbGV2ZWwKCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBLZXl3b3Jkcy4gV2UgZG9uJ3QgYWRkIHRoZW0gdG8gdGhlICJrZXl3b3JkIiBwcm9kdWN0aW9uIGJlY2F1c2UKICAvLyB3ZSBkb24ndCB3YW50IHRvIG1ha2UgdGhlbSB1bmF2YWlsYWJsZSB0byBwcm9ncmFtcyBhcwogIC8vIGlkZW50aWZpZXJzLgoKICBhY3RvciA9ICJhY3RvciIgfmlkZW50aWZpZXJQYXJ0CiAgYXNzZXJ0ID0gImFzc2VydCIgfmlkZW50aWZpZXJQYXJ0CiAgYXNzZXJ0ZWQgPSAiYXNzZXJ0ZWQiIH5pZGVudGlmaWVyUGFydAogIGFzc2VydGlvbiA9ICJhc3NlcnRpb24iIH5pZGVudGlmaWVyUGFydAogIGRhdGFzcGFjZSA9ICJkYXRhc3BhY2UiIH5pZGVudGlmaWVyUGFydAogIGRvbmUgPSAiZG9uZSIgfmlkZW50aWZpZXJQYXJ0CiAgZHVyaW5nID0gImR1cmluZyIgfmlkZW50aWZpZXJQYXJ0CiAgZm9yZXZlciA9ICJmb3JldmVyIiB+aWRlbnRpZmllclBhcnQKICBncm91bmQgPSAiZ3JvdW5kIiB+aWRlbnRpZmllclBhcnQKICBpbml0ID0gImluaXQiIH5pZGVudGlmaWVyUGFydAogIG1lc3NhZ2UgPSAibWVzc2FnZSIgfmlkZW50aWZpZXJQYXJ0CiAgbWV0YWxldmVsID0gIm1ldGFsZXZlbCIgfmlkZW50aWZpZXJQYXJ0CiAgb24gPSAib24iIH5pZGVudGlmaWVyUGFydAogIHJldHJhY3RlZCA9ICJyZXRyYWN0ZWQiIH5pZGVudGlmaWVyUGFydAogIHN0YXRlID0gInN0YXRlIiB+aWRlbnRpZmllclBhcnQKICB0eXBlID0gInR5cGUiIH5pZGVudGlmaWVyUGFydAogIHVudGlsID0gInVudGlsIiB+aWRlbnRpZmllclBhcnQKICB3aGVuID0gIndoZW4iIH5pZGVudGlmaWVyUGFydAp9Cg==","base64").toString();
var grammar = ohm.grammar(grammarSource, { ES5: ES5.grammar });
var semantics = grammar.extendSemantics(ES5.semantics);
@ -146,8 +146,8 @@ var modifiedSourceActions = {
return '\n.addDoneBlock((function() ' + block.asES5 + '))';
},
FacetSituation_assert: function(_assert, expr, _sc) {
return '\n.addAssertion(' + buildSubscription([expr], 'assert', 'pattern') + ')';
FacetSituation_assert: function(_assert, expr, whenClause, _sc) {
return '\n.addAssertion(' + buildSubscription([expr], 'assert', 'pattern', whenClause) + ')';
},
FacetSituation_event: function(_on, eventPattern, block) {
return buildOnEvent(false,
@ -174,6 +174,10 @@ var modifiedSourceActions = {
'.completeBuild(); }');
},
AssertWhenClause: function(_when, _lparen, expr, _rparen) {
return expr.asES5;
},
FacetStateTransition_withContinuation: function(_case, eventPattern, block) {
return buildCaseEvent(eventPattern, block.asES5);
},
@ -202,9 +206,13 @@ semantics.addAttribute('eventType', {
FacetTransitionEventPattern_risingEdge: function (_lp, expr, _rp) { return 'risingEdge'; }
});
function buildSubscription(children, patchMethod, mode) {
function buildSubscription(children, patchMethod, mode, whenClause) {
var fragments = [];
var hasWhenClause = (whenClause && (whenClause.numChildren === 1));
fragments.push('(function() { var _ = Syndicate.__; return ');
if (hasWhenClause) {
fragments.push('(' + whenClause.asES5 + ') ? ');
}
if (patchMethod) {
fragments.push('Syndicate.Patch.' + patchMethod + '(');
} else {
@ -222,31 +230,34 @@ function buildSubscription(children, patchMethod, mode) {
} else {
fragments.push(' }');
}
if (hasWhenClause) {
fragments.push(' : Syndicate.Patch.emptyPatch');
}
fragments.push('; })');
return fragments.join('');
}
semantics.addAttribute('subscription', {
_default: function(children) {
return buildSubscription(children, 'sub', 'pattern');
return buildSubscription(children, 'sub', 'pattern', null);
}
});
semantics.addAttribute('instantiatedSubscription', {
_default: function(children) {
return buildSubscription(children, 'sub', 'instantiated');
return buildSubscription(children, 'sub', 'instantiated', null);
}
});
semantics.addAttribute('instantiatedProjection', {
_default: function(children) {
return buildSubscription(children, null, 'instantiated');
return buildSubscription(children, null, 'instantiated', null);
}
});
semantics.addAttribute('projection', {
_default: function(children) {
return buildSubscription(children, null, 'projection');
return buildSubscription(children, null, 'projection', null);
}
});

File diff suppressed because one or more lines are too long

View File

@ -19,7 +19,7 @@
<section>
<h3>TV</h3>
<div id="tv-container">
&nbsp;<div id="tv"></div>
&nbsp;<div><ul id="tv" class="alerts"></ul></div>
</div>
</section>

View File

@ -14,28 +14,9 @@ var jQueryEvent = Syndicate.JQuery.jQueryEvent;
function spawnTV() {
actor {
this.alerts = [];
this.alertFragment = ["ul"];
this.computeDisplay = function () {
var self = this; // omg javascript
this.alertFragment = ["ul"];
this.alerts.forEach(function (t) {
self.alertFragment.push(["li", t]);
});
};
forever {
assert DOM('#tv', 'alerts', Syndicate.seal(this.alertFragment));
on asserted tvAlert($text) {
this.alerts.push(text);
this.computeDisplay();
}
on retracted tvAlert($text) {
this.alerts = this.alerts.filter(function (t) { return t !== text; });
this.computeDisplay();
during tvAlert($text) {
assert DOM('#tv', 'alert', Syndicate.seal(["li", text]));
}
}
}
@ -140,7 +121,6 @@ function spawnClock() {
}
function spawnTimeoutListener() {
var message = tvAlert('Stove on too long?');
actor {
this.mostRecentTime = 0;
this.powerOnTime = null;
@ -151,12 +131,9 @@ function spawnTimeoutListener() {
}
on message time($now) {
this.mostRecentTime = now;
if (this.powerOnTime !== null && this.mostRecentTime - this.powerOnTime > 3000) {
Syndicate.Dataspace.stateChange(Syndicate.assert(message));
} else {
Syndicate.Dataspace.stateChange(Syndicate.retract(message));
}
}
assert tvAlert('Stove on too long?')
when (this.powerOnTime !== null && this.mostRecentTime - this.powerOnTime > 3000);
}
}
}
@ -165,17 +142,14 @@ function spawnTimeoutListener() {
// Failure monitor
function spawnFailureMonitor() {
function messageFor(who) {
return tvAlert('FAILURE: ' + who);
}
actor {
forever {
on asserted componentPresent($who) {
Syndicate.Dataspace.stateChange(Syndicate.retract(messageFor(who)));
}
on retracted componentPresent($who) {
Syndicate.Dataspace.stateChange(Syndicate.assert(messageFor(who)));
state {
assert tvAlert('FAILURE: ' + who);
} until {
case asserted componentPresent(who);
}
}
}
}