diff --git a/src/syndicate.nim b/src/syndicate.nim index 2658ad9..4af3041 100644 --- a/src/syndicate.nim +++ b/src/syndicate.nim @@ -196,6 +196,10 @@ method retract(e: ClosureEntity; turn: var Turn; h: Handle) = method message(e: ClosureEntity; turn: var Turn; v: Assertion) = if not e.messageImpl.isNil: e.messageImpl(turn, v) +proc argumentCount(handler: NimNode): int = + handler.expectKind {nnkDo, nnkStmtList} + if handler.kind == nnkDo: result = pred handler[3].len + proc wrapPublishHandler(handler: NimNode): NimNode = handler.expectKind {nnkDo, nnkStmtList} var innerProc = newNimNode(nnkProcDef) @@ -268,18 +272,22 @@ proc wrapMessageHandler(handler: NimNode): NimNode = macro onPublish*(turn: Turn; ds: Ref; pattern: Pattern; handler: untyped) = ## Call `handler` when an assertion matching `pattern` is published at `ds`. let + argCount = argumentCount(handler) handlerProc = wrapPublishHandler(handler) handlerSym = handlerProc[0] result = quote do: + doAssert `pattern`.analyse.capturePaths.len == `argCount`, "mismatch between pattern capture and handler arguments" `handlerProc` discard observe(`turn`, `ds`, `pattern`, ClosureEntity(publishImpl: `handlerSym`)) macro onMessage*(turn: Turn; ds: Ref; pattern: Pattern; handler: untyped) = ## Call `handler` when an message matching `pattern` is broadcasted at `ds`. let + argCount = argumentCount(handler) handlerProc = wrapMessageHandler(handler) handlerSym = handlerProc[0] result = quote do: + doAssert `pattern`.analyse.capturePaths.len == `argCount`, "mismatch between pattern capture and handler arguments" `handlerProc` discard observe(`turn`, `ds`, `pattern`, ClosureEntity(messageImpl: `handlerSym`)) @@ -341,17 +349,21 @@ macro during*(turn: var Turn; ds: Ref; pattern: Pattern; publishBody, retractBod ## - `bindings` - raw Preserves sequence that matched `pattern` ## - `duringHandle` - dataspace handle of the assertion that triggered `publishBody` let + argCount = argumentCount(publishBody) callbackProc = wrapDuringHandler(publishBody, retractBody) callbackSym = callbackProc[0] result = quote do: + doAssert `pattern`.analyse.capturePaths.len == `argCount`, "mismatch between pattern capture and handler arguments" `callbackProc` discard observe(`turn`, `ds`, `pattern`, during(`callbackSym`)) macro during*(turn: var Turn; ds: Ref; pattern: Pattern; publishBody: untyped) = ## Variant of `during` without a retract body. let + argCount = argumentCount(publishBody) callbackProc = wrapDuringHandler(publishBody, nil) callbackSym = callbackProc[0] result = quote do: + doAssert `pattern`.analyse.capturePaths.len == `argCount`, "mismatch between pattern capture and handler arguments" `callbackProc` discard observe(`turn`, `ds`, `pattern`, during(`callbackSym`))