diff --git a/src/syndicate.nim b/src/syndicate.nim index fe28aa9..86888de 100644 --- a/src/syndicate.nim +++ b/src/syndicate.nim @@ -60,7 +60,7 @@ proc argumentCount(handler: NimNode): int = handler.expectKind {nnkDo, nnkStmtList} if handler.kind == nnkDo: result = pred handler[3].len -proc wrapPublishHandler(handler: NimNode): NimNode = +proc wrapPublishHandler(turn, handler: NimNode): NimNode = handler.expectKind {nnkDo, nnkStmtList} var innerProc = newNimNode(nnkProcDef) handler.copyChildrenTo innerProc @@ -87,16 +87,15 @@ proc wrapPublishHandler(handler: NimNode): NimNode = publishBody = if handler.kind == nnkStmtList: handler else: newStmtList(varSectionInner, handler[6]) - turnSym = ident"turn" handleSym = ident"handle" handlerSym = genSym(nskProc, "publish") quote do: - proc `handlerSym`(`turnSym`: var Turn; bindings: Assertion; `handleSym`: Handle) = + proc `handlerSym`(`turn`: var Turn; bindings: Assertion; `handleSym`: Handle) = `varSectionOuter` if fromPreserve(`valuesSym`, bindings): `publishBody` -proc wrapMessageHandler(handler: NimNode): NimNode = +proc wrapMessageHandler(turn, handler: NimNode): NimNode = handler.expectKind {nnkDo, nnkStmtList} var innerProc = newNimNode(nnkProcDef) handler.copyChildrenTo innerProc @@ -121,19 +120,18 @@ proc wrapMessageHandler(handler: NimNode): NimNode = varSectionOuter = newNimNode(nnkVarSection, handler).add( newIdentDefs(valuesSym, valuesTuple)) body = newStmtList(varSectionInner, handler[6]) - turnSym = ident"turn" handlerSym = genSym(nskProc, "message") quote do: - proc `handlerSym`(`turnSym`: var Turn; bindings: Assertion) = + proc `handlerSym`(`turn`: var Turn; bindings: Assertion) = `varSectionOuter` if fromPreserve(`valuesSym`, bindings): `body` -macro onPublish*(turn: Turn; ds: Ref; pattern: Pattern; handler: untyped) = +macro onPublish*(turn: untyped; ds: Ref; pattern: Pattern; handler: untyped) = ## Call `handler` when an assertion matching `pattern` is published at `ds`. let argCount = argumentCount(handler) - handlerProc = wrapPublishHandler(handler) + handlerProc = wrapPublishHandler(turn, handler) handlerSym = handlerProc[0] result = quote do: if `pattern`.analyse.capturePaths.len != `argCount`: @@ -141,11 +139,11 @@ macro onPublish*(turn: Turn; ds: Ref; pattern: Pattern; handler: untyped) = `handlerProc` discard observe(`turn`, `ds`, `pattern`, ClosureEntity(publishImpl: `handlerSym`)) -macro onMessage*(turn: Turn; ds: Ref; pattern: Pattern; handler: untyped) = +macro onMessage*(turn: untyped; ds: Ref; pattern: Pattern; handler: untyped) = ## Call `handler` when an message matching `pattern` is broadcasted at `ds`. let argCount = argumentCount(handler) - handlerProc = wrapMessageHandler(handler) + handlerProc = wrapMessageHandler(turn, handler) handlerSym = handlerProc[0] result = quote do: if `pattern`.analyse.capturePaths.len != `argCount`: @@ -153,7 +151,7 @@ macro onMessage*(turn: Turn; ds: Ref; pattern: Pattern; handler: untyped) = `handlerProc` discard observe(`turn`, `ds`, `pattern`, ClosureEntity(messageImpl: `handlerSym`)) -proc wrapDuringHandler(entryBody, exitBody: NimNode): NimNode = +proc wrapDuringHandler(turn, entryBody, exitBody: NimNode): NimNode = entryBody.expectKind {nnkDo, nnkStmtList} var innerProc = newNimNode(nnkProcDef) entryBody.copyChildrenTo innerProc @@ -180,38 +178,36 @@ proc wrapDuringHandler(entryBody, exitBody: NimNode): NimNode = publishBody = if entryBody.kind == nnkStmtList: entryBody else: newStmtList(varSectionInner, entryBody[6]) - turnSym = ident"turn" bindingsSym = ident"bindings" handleSym = ident"duringHandle" duringSym = genSym(nskProc, "during") if exitBody.isNil: quote do: - proc `duringSym`(`turnSym`: var Turn; `bindingsSym`: Assertion; `handleSym`: Handle): TurnAction = + proc `duringSym`(`turn`: var Turn; `bindingsSym`: Assertion; `handleSym`: Handle): TurnAction = `varSectionOuter` if fromPreserve(`valuesSym`, `bindingsSym`): `publishBody` else: quote do: - proc `duringSym`(`turnSym`: var Turn; `bindingsSym`: Assertion; `handleSym`: Handle): TurnAction = + proc `duringSym`(`turn`: var Turn; `bindingsSym`: Assertion; `handleSym`: Handle): TurnAction = `varSectionOuter` if fromPreserve(`valuesSym`, `bindingsSym`): `publishBody` - proc action(`turnSym`: var Turn) = + proc action(`turn`: var Turn) = `exitBody` result = action -macro during*(turn: var Turn; ds: Ref; pattern: Pattern; publishBody, retractBody: untyped) = +macro during*(turn: untyped; ds: Ref; pattern: Pattern; publishBody, retractBody: untyped) = ## Call `publishBody` when an assertion matching `pattern` is published to `ds` and ## call `retractBody` on retraction. Assertions that match `pattern` but are not ## convertable to the arguments of `publishBody` are silently discarded. ## ## The following symbols are injected into the scope of both bodies: - ## - `turn` - active turn at entry of `publishBody` and `retractBody` ## - `bindings` - raw Preserves sequence that matched `pattern` ## - `duringHandle` - dataspace handle of the assertion that triggered `publishBody` let argCount = argumentCount(publishBody) - callbackProc = wrapDuringHandler(publishBody, retractBody) + callbackProc = wrapDuringHandler(turn, publishBody, retractBody) callbackSym = callbackProc[0] result = quote do: if `pattern`.analyse.capturePaths.len != `argCount`: @@ -219,11 +215,11 @@ macro during*(turn: var Turn; ds: Ref; pattern: Pattern; publishBody, retractBod `callbackProc` discard observe(`turn`, `ds`, `pattern`, during(`callbackSym`)) -macro during*(turn: var Turn; ds: Ref; pattern: Pattern; publishBody: untyped) = +macro during*(turn: untyped; ds: Ref; pattern: Pattern; publishBody: untyped) = ## Variant of `during` without a retract body. let argCount = argumentCount(publishBody) - callbackProc = wrapDuringHandler(publishBody, nil) + callbackProc = wrapDuringHandler(turn, publishBody, nil) callbackSym = callbackProc[0] result = quote do: if `pattern`.analyse.capturePaths.len != `argCount`: