once asserted ..., once message ..., etc

This commit is contained in:
Tony Garnock-Jones 2023-12-21 10:30:23 +13:00
parent 044ccad37c
commit 0a8975a2f6
2 changed files with 21 additions and 9 deletions

View File

@ -124,6 +124,10 @@ export function expand(tree: Items, ctx: ExpansionContext): Items {
}
}
function facetWrap(t: TemplateFunction, items: Items): Items {
return t`__SYNDICATE__.Turn.active.facet(() => {${items}})`;
}
function x<T>(p: Pattern<T>, f: (v: T, t: TemplateFunction) => Items) {
tree = replace(tree, p, (v, start) => f(v, macro.template(fixPos(start))));
}
@ -222,8 +226,10 @@ ${joinItems(sa.captureBinders.map(binderTypeGuard(t)), '\n')}
t`_dataflow(() => {${walk(s.body)}});`);
x(ctx.parser.eventHandlerEndpointStatement, (s, t) => {
const wrap = s.once ? (i: Items) => facetWrap(t, i) : (i: Items) => i;
if (s.triggerType === 'dataflow') {
return t`__SYNDICATE__.Turn.active._dataflow(() => { if (${walk(s.predicate)}) { ${terminalWrap(t, s.terminal, walk(s.body))} } });`;
return wrap(t`__SYNDICATE__.Turn.active._dataflow(() => { if (${walk(s.predicate)}) { ${terminalWrap(t, s.terminal, walk(s.body))} } });`);
}
if (s.triggerType === 'stop') {
@ -265,12 +271,14 @@ ${joinItems(sa.captureBinders.map(binderTypeGuard(t)), '\n')}
})`;
if (s.isDynamic) {
return t`__SYNDICATE__.Turn.active.assertDataflow(() => ({
return wrap(t`__SYNDICATE__.Turn.active.assertDataflow(() => ({
target: currentSyndicateTarget,
assertion: ${assertion},
}));`;
}));`);
} else {
return t`__SYNDICATE__.Turn.active.replace(currentSyndicateTarget, void 0, ${assertion});`;
return wrap(
t`__SYNDICATE__.Turn.active.replace(currentSyndicateTarget, void 0, ${assertion});`
);
}
});
@ -286,9 +294,7 @@ ${joinItems(sa.captureBinders.map(binderTypeGuard(t)), '\n')}
xf(ctx.parser.messageSendStatement, (s, t) => t`message(currentSyndicateTarget, ${walk(s.expr)});`);
xf(ctx.parser.reactStatement, (s, t) => {
return t`facet(() => {${s.body}});`;
});
x(ctx.parser.reactStatement, (s, t) => facetWrap(t, s.body));
x(ctx.parser.stopStatement, (s, t) =>
t`__SYNDICATE__.Turn.active._stop(__SYNDICATE__.Turn.activeFacet, () => {${walk(s.body)}});`)

View File

@ -52,6 +52,7 @@ export interface StatementTurnAction extends TurnAction {
export interface GenericEventEndpointStatement extends StatementTurnAction {
terminal: boolean;
once: boolean;
isDynamic: boolean;
}
@ -278,10 +279,15 @@ export class SyndicateParser {
readonly eventHandlerEndpointStatement: Pattern<EventHandlerEndpointStatement> =
this.turnAction(o => {
o.terminal = false;
o.once = false;
o.isDynamic = true;
o.body = [];
return seq(option(map(atom('stop'), _ => o.terminal = true)),
atom('on'),
return seq(alt(seq(option(map(atom('stop'), _ => o.terminal = true)),
atom('on')),
map(atom('once'), _ => {
o.terminal = true;
o.once = true;
})),
alt<any>(seq(map(group('(', bind(o as DataflowEndpointStatement, 'predicate',
this.expr())),
_ => o.triggerType = 'dataflow'),