From 2a09e61f2bd0044adb9c6497a7b0bee2f5f1d8f5 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Fri, 27 Aug 2021 22:03:02 +0200 Subject: [PATCH] Adapt to non-throwing fromPreserve Use the new fromPreserve proc that indicates failure with its return value to test if a handler can process a pattern match. --- src/syndicate.nim | 42 +++++++++++++++++++++----------- src/syndicate/dataspaces.nim | 3 ++- src/syndicate/drivers/timers.nim | 10 ++++---- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/syndicate.nim b/src/syndicate.nim index 6b57165..84cb9ec 100644 --- a/src/syndicate.nim +++ b/src/syndicate.nim @@ -1,10 +1,12 @@ # SPDX-License-Identifier: ISC import std/[asyncdispatch, macros, options] -import preserves +import preserves, preserves/records import syndicate/[assertions, dataspaces, events, skeletons] export preserves.`%` +export preserves.fromPreserve +export records.init export assertions.`?_` export assertions.`?*` export assertions.Observe @@ -28,6 +30,7 @@ export events.EventKind export skeletons.Analysis export asyncdispatch.`callback=` +export options.get proc getCurrentFacet*(): Facet = raiseAssert("must be called from within the DSL") ## Return the current `Facet` for this context. @@ -50,13 +53,13 @@ proc wrapDoHandler(pattern, handler: NimNode): NimNode = ## Generate a procedure that unpacks a `pattern` match to fit the ## parameters of `handler`, and calls the body of `handler`. handler.expectKind nnkDo - let + var formalArgs = handler[3] cbFacetSym = genSym(nskParam, "facet") scriptFacetSym = genSym(nskParam, "facet") recSym = genSym(nskParam, "bindings") - var - letSection = newNimNode(nnkLetSection, handler) + varSection = newNimNode(nnkVarSection, handler) + conditional: NimNode argCount: int for i, arg in formalArgs: if i > 0: @@ -67,16 +70,27 @@ proc wrapDoHandler(pattern, handler: NimNode): NimNode = else: if arg[1].kind == nnkEmpty: error("type required for capture", arg) - var letDef = newNimNode(nnkIdentDefs, arg) - arg.copyChildrenTo letDef - letDef[2] = newCall("preserveTo", - newNimNode(nnkBracketExpr).add(recSym, newLit(pred i)), - letDef[1]) - letSection.add(letDef) + var varDef = newNimNode(nnkIdentDefs, arg) + arg.copyChildrenTo varDef + varSection.add(varDef) + var conversion = newCall("fromPreserve", varDef[0], + newNimNode(nnkBracketExpr).add(recSym, newLit(pred i))) + if conditional.isNil: + conditional = conversion + else: + conditional = infix(conditional, "and", conversion) inc(argCount) - let + var scriptBody = newStmtList() + if argCount > 0: + scriptBody.add( + varSection, + newNimNode(nnkIfStmt).add( + newNimNode(nnkElifBranch).add( + conditional, handler[6]))) + else: + scriptBody.add(handler[6]) + var scriptSym = genSym(nskProc, "script") - scriptBody = newStmtList(letSection, handler[6]) handlerSym = genSym(nskProc, "handler") litArgCount = newLit argCount quote do: @@ -85,7 +99,7 @@ proc wrapDoHandler(pattern, handler: NimNode): NimNode = # this should be a compile-time check assert( `litArgCount` == len(`recSym`), - "cannot unpack " & $`litArgCount` & " bindings from " & $(%`recSym`)) + "cannot unpack " & $`litArgCount` & " bindings from " & $(toPreserve `recSym`)) proc `scriptSym`(`scriptFacetSym`: Facet) = proc getCurrentFacet(): Facet {.inject, used.} = `scriptFacetSym` `scriptBody` @@ -114,7 +128,7 @@ proc onEvent(event: EventKind, pattern, handler: NimNode): NimNode = proc getCurrentFacet(): Facet {.inject, used.} = facet `handler` let a = `pattern` - result.assertion = Observe % a + result.assertion = Observe.init(a) result.analysis = some(analyzeAssertion(a)) result.callback = wrap(facet, EventKind(`event`), `handlerSym`) diff --git a/src/syndicate/dataspaces.nim b/src/syndicate/dataspaces.nim index 8b24e35..d0d5de3 100644 --- a/src/syndicate/dataspaces.nim +++ b/src/syndicate/dataspaces.nim @@ -553,7 +553,8 @@ template declareField*(facet: Facet; F: untyped; T: typedesc; initial: T): untyp facet.fields[fieldOff] = x proc get(f: DistinctField): T {.used.} = facet.actor.dataspace.dataflow.recordObservation(f.id) - fromPreserve[T](result, facet.fields[fieldOff]) + if not fromPreserve[T](result, facet.fields[fieldOff]): + raise newException(ValueError, "cannot convert field " & $F & " to " & $T) proc getPreserve(f: DistinctField): Preserve {.used.} = facet.actor.dataspace.dataflow.recordObservation(f.id) facet.fields[fieldOff] diff --git a/src/syndicate/drivers/timers.nim b/src/syndicate/drivers/timers.nim index a4d3ef0..e5e8489 100644 --- a/src/syndicate/drivers/timers.nim +++ b/src/syndicate/drivers/timers.nim @@ -7,12 +7,12 @@ import syndicate const TimeLaterThan* = RecordClass(label: symbol"TimeLaterThan", arity: 1) proc toPreserveHook*(time: Monotime): Preserve = - %time.ticks + time.ticks.toPreserve -proc fromPreserveHook*(result: var Monotime; p: Preserve) = - if p.kind != pkSignedInteger: - raise newException(ValueError, "not a preserved time: " & $p) - result = cast[MonoTime]((p.int.int64,)) +proc fromPreserveHook*(mt: var Monotime; p: Preserve): bool = + if p.kind == pkSignedInteger: + mt = cast[MonoTime]((p.int.int64,)) + result = true syndicate timerDriver: