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) { function x<T>(p: Pattern<T>, f: (v: T, t: TemplateFunction) => Items) {
tree = replace(tree, p, (v, start) => f(v, macro.template(fixPos(start)))); 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)}});`); t`_dataflow(() => {${walk(s.body)}});`);
x(ctx.parser.eventHandlerEndpointStatement, (s, t) => { x(ctx.parser.eventHandlerEndpointStatement, (s, t) => {
const wrap = s.once ? (i: Items) => facetWrap(t, i) : (i: Items) => i;
if (s.triggerType === 'dataflow') { 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') { if (s.triggerType === 'stop') {
@ -265,12 +271,14 @@ ${joinItems(sa.captureBinders.map(binderTypeGuard(t)), '\n')}
})`; })`;
if (s.isDynamic) { if (s.isDynamic) {
return t`__SYNDICATE__.Turn.active.assertDataflow(() => ({ return wrap(t`__SYNDICATE__.Turn.active.assertDataflow(() => ({
target: currentSyndicateTarget, target: currentSyndicateTarget,
assertion: ${assertion}, assertion: ${assertion},
}));`; }));`);
} else { } 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.messageSendStatement, (s, t) => t`message(currentSyndicateTarget, ${walk(s.expr)});`);
xf(ctx.parser.reactStatement, (s, t) => { x(ctx.parser.reactStatement, (s, t) => facetWrap(t, s.body));
return t`facet(() => {${s.body}});`;
});
x(ctx.parser.stopStatement, (s, t) => x(ctx.parser.stopStatement, (s, t) =>
t`__SYNDICATE__.Turn.active._stop(__SYNDICATE__.Turn.activeFacet, () => {${walk(s.body)}});`) 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 { export interface GenericEventEndpointStatement extends StatementTurnAction {
terminal: boolean; terminal: boolean;
once: boolean;
isDynamic: boolean; isDynamic: boolean;
} }
@ -278,10 +279,15 @@ export class SyndicateParser {
readonly eventHandlerEndpointStatement: Pattern<EventHandlerEndpointStatement> = readonly eventHandlerEndpointStatement: Pattern<EventHandlerEndpointStatement> =
this.turnAction(o => { this.turnAction(o => {
o.terminal = false; o.terminal = false;
o.once = false;
o.isDynamic = true; o.isDynamic = true;
o.body = []; o.body = [];
return seq(option(map(atom('stop'), _ => o.terminal = true)), return seq(alt(seq(option(map(atom('stop'), _ => o.terminal = true)),
atom('on'), atom('on')),
map(atom('once'), _ => {
o.terminal = true;
o.once = true;
})),
alt<any>(seq(map(group('(', bind(o as DataflowEndpointStatement, 'predicate', alt<any>(seq(map(group('(', bind(o as DataflowEndpointStatement, 'predicate',
this.expr())), this.expr())),
_ => o.triggerType = 'dataflow'), _ => o.triggerType = 'dataflow'),