Support optional "when" in "during"

This commit is contained in:
Tony Garnock-Jones 2021-12-13 12:21:11 +01:00
parent 4d42968cd6
commit 09ae5ddb5b
2 changed files with 23 additions and 16 deletions

View File

@ -148,25 +148,29 @@ export function expand(tree: Items, ctx: ExpansionContext): Items {
spawn.linkedToken = getRange(s.body); spawn.linkedToken = getRange(s.body);
} }
let body = (spawn == null) let body = (spawn === null)
? walk(s.body) ? walk(s.body)
: expandSpawn(spawn, t, t`__SYNDICATE__.Turn.activeFacet.preventInertCheck();`); : expandSpawn(spawn, t, t`__SYNDICATE__.Turn.activeFacet.preventInertCheck();`);
const sa = compilePattern(s.pattern); const sa = compilePattern(s.pattern);
return t`assertDataflow(() => ({ const assertion = t`__SYNDICATE__.fromObserve(__SYNDICATE__.Observe({
target: currentSyndicateTarget, pattern: __SYNDICATE__.QuasiValue.finish(${sa.skeleton}),
assertion: __SYNDICATE__.fromObserve(__SYNDICATE__.Observe({ observer: __SYNDICATE__.Turn.ref(__SYNDICATE__.assertionFacetObserver(
pattern: __SYNDICATE__.QuasiValue.finish(${sa.skeleton}), (${ctx.argDecl(t, '__vs', '__SYNDICATE__.AnyValue')}) => {
observer: __SYNDICATE__.Turn.ref(__SYNDICATE__.assertionFacetObserver( if (Array.isArray(__vs)) {
(${ctx.argDecl(t, '__vs', '__SYNDICATE__.AnyValue')}) => {
if (Array.isArray(__vs)) {
${joinItems(sa.captureBinders.map(binderTypeGuard(ctx, t)), '\n')} ${joinItems(sa.captureBinders.map(binderTypeGuard(ctx, t)), '\n')}
${body} ${body}
}
} }
)) }
})), ))
}));`; }))`;
if (s.test === void 0) {
return t`assertDataflow(() => ({ target: currentSyndicateTarget, assertion: ${assertion} }));`;
} else {
return t`assertDataflow(() => (${walk(s.test)})
? ({ target: currentSyndicateTarget, assertion: ${assertion} })
: ({ target: void 0, assertion: void 0 }));`;
}
}); });
function expandSpawn(spawn: SpawnStatement, t: TemplateFunction, inject: Items = []): Items { function expandSpawn(spawn: SpawnStatement, t: TemplateFunction, inject: Items = []): Items {
@ -197,7 +201,7 @@ ${joinItems(sa.captureBinders.map(binderTypeGuard(ctx, t)), '\n')}
xf(ctx.parser.assertionEndpointStatement, (s, t) => { xf(ctx.parser.assertionEndpointStatement, (s, t) => {
if (s.isDynamic) { if (s.isDynamic) {
if (s.test == void 0) { if (s.test === void 0) {
return t`assertDataflow(() => ({ target: currentSyndicateTarget, assertion: ${walk(s.template)} }));`; return t`assertDataflow(() => ({ target: currentSyndicateTarget, assertion: ${walk(s.template)} }));`;
} else { } else {
return t`assertDataflow(() => (${walk(s.test)}) return t`assertDataflow(() => (${walk(s.test)})
@ -205,7 +209,7 @@ ${joinItems(sa.captureBinders.map(binderTypeGuard(ctx, t)), '\n')}
: ({ target: void 0, assertion: void 0 }));`; : ({ target: void 0, assertion: void 0 }));`;
} }
} else { } else {
if (s.test == void 0) { if (s.test === void 0) {
return t`assert(currentSyndicateTarget, ${walk(s.template)});`; return t`assert(currentSyndicateTarget, ${walk(s.template)});`;
} else { } else {
return t`replace(currentSyndicateTarget, void 0, (${walk(s.test)}) ? (${walk(s.template)}) : void 0);`; return t`replace(currentSyndicateTarget, void 0, (${walk(s.test)}) ? (${walk(s.template)}) : void 0);`;

View File

@ -85,6 +85,7 @@ export interface MessageSendStatement extends TurnAction {
export interface DuringStatement extends FacetSetupAction { export interface DuringStatement extends FacetSetupAction {
pattern: ValuePattern; pattern: ValuePattern;
test?: Expr,
} }
export interface ReactStatement extends FacetSetupAction { export interface ReactStatement extends FacetSetupAction {
@ -314,7 +315,9 @@ export class SyndicateParser {
this.turnAction(o => { this.turnAction(o => {
o.body = []; o.body = [];
return seq(atom('during'), return seq(atom('during'),
bind(o, 'pattern', this.valuePattern(1, atom('=>'))), bind(o, 'pattern',
this.valuePattern(1, atom('=>'), seq(atom('when'), group('(', discard)))),
option(seq(atom('when'), group('(', bind(o, 'test', this.expr())))),
seq(atom('=>'), this.statement(o.body))); seq(atom('=>'), this.statement(o.body)));
}); });