From 672be2521196653fdeea7c123378526e904667f0 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Sat, 11 Dec 2021 16:54:47 +0100 Subject: [PATCH] Autolink during...spawn --- packages/compiler/src/compiler/codegen.ts | 25 ++++++++++++++++------- packages/compiler/src/compiler/grammar.ts | 6 +++--- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/packages/compiler/src/compiler/codegen.ts b/packages/compiler/src/compiler/codegen.ts index b88943e..5c745c7 100644 --- a/packages/compiler/src/compiler/codegen.ts +++ b/packages/compiler/src/compiler/codegen.ts @@ -16,6 +16,7 @@ import { Binder, compilePattern, + SpawnStatement, } from './grammar.js'; export function stripShebang(items: Items): Items { @@ -138,7 +139,16 @@ export function expand(tree: Items, ctx: ExpansionContext): Items { // following transformations matters. xf(ctx.parser.duringStatement, (s, t) => { - // TODO: untyped template + let spawn = match(ctx.parser.spawn, s.body, null); + if (spawn !== null) { + if (spawn.linkedToken !== null) { + ctx.emitError(`during ... spawn doesn't need "linked", it's always linked`, + spawn.linkedToken); + } + spawn.linkedToken = getRange(s.body); + } + let body = (spawn == null) ? walk(s.body) : expandSpawn(spawn, t); + const sa = compilePattern(s.pattern); return t`assertDataflow(() => ({ target: currentSyndicateTarget, @@ -148,7 +158,7 @@ export function expand(tree: Items, ctx: ExpansionContext): Items { (${ctx.argDecl(t, '__vs', '__SYNDICATE__.AnyValue')}) => { if (Array.isArray(__vs)) { ${joinItems(sa.captureBinders.map(binderTypeGuard(ctx, t)), '\n')} - ${walk(s.body)} + ${body} } } )) @@ -156,17 +166,18 @@ ${joinItems(sa.captureBinders.map(binderTypeGuard(ctx, t)), '\n')} }));`; }); - xf(ctx.parser.spawn, (s, t) => { + function expandSpawn(spawn: SpawnStatement, t: TemplateFunction): Items { // TODO: parentBinders, parentInits - let body = walk(s.body); /* let assertions = (s.initialAssertions.length > 0) ? t`, new __SYNDICATE__.Set([${commaJoin(s.initialAssertions.map(walk))}])` : ``; */ - const n = s.name === void 0 ? '' : t` __SYNDICATE__.Turn.activeFacet.actor.name = ${walk(s.name)};`; - return t`_spawn${s.isLink ? 'Link': ''}(() => {${n} ${body} });`; - }); + const n = spawn.name === void 0 ? '' : t` __SYNDICATE__.Turn.activeFacet.actor.name = ${walk(spawn.name)};`; + return t`_spawn${spawn.linkedToken ? 'Link': ''}(() => {${n} ${walk(spawn.body)} });`; + } + + xf(ctx.parser.spawn, expandSpawn); x(ctx.parser.fieldDeclarationStatement, (s, t) => { const ft = ctx.typescript ? t`<${s.field.type ?? '__SYNDICATE__.AnyValue'}>` : ''; diff --git a/packages/compiler/src/compiler/grammar.ts b/packages/compiler/src/compiler/grammar.ts index e57e376..d07632a 100644 --- a/packages/compiler/src/compiler/grammar.ts +++ b/packages/compiler/src/compiler/grammar.ts @@ -30,7 +30,7 @@ export interface FacetSetupAction extends TurnAction { export interface SpawnStatement extends FacetSetupAction { name?: Expr; - isLink: boolean; + linkedToken: TokenBase | null; parentBinders: Binder[]; parentInits: Expr[]; } @@ -207,12 +207,12 @@ export class SyndicateParser { // Principal: Turn readonly spawn: Pattern = this.turnAction(o => { - o.isLink = false; + o.linkedToken = null; o.parentBinders = []; o.parentInits = []; o.body = []; return seq(atom('spawn'), - option(map(atom('linked'), _ => o.isLink = true)), + option(map(atom('linked'), tok => o.linkedToken = tok)), option(seq(atom('named'), bind(o, 'name', this.headerExpr))), repeat(alt( /* seq(kw('asserting'), map(this.headerExpr, e => o.initialAssertions.push(e))), */