DSL support for handler bodies without parameters

This commit is contained in:
Emery Hemingway 2022-06-12 14:09:34 -05:00
parent be22238ca3
commit 7ca28768d4
1 changed files with 39 additions and 35 deletions

View File

@ -139,30 +139,32 @@ method message(e: ClosureEntity; turn: var Turn; v: Assertion) =
if not e.messageImpl.isNil: e.messageImpl(turn, v) if not e.messageImpl.isNil: e.messageImpl(turn, v)
proc wrapPublishHandler(handler: NimNode): NimNode = proc wrapPublishHandler(handler: NimNode): NimNode =
handler.expectKind nnkDo handler.expectKind {nnkDo, nnkStmtList}
var innerProc = newNimNode(nnkProcDef) var innerProc = newNimNode(nnkProcDef)
handler.copyChildrenTo innerProc handler.copyChildrenTo innerProc
innerProc[0] = genSym(nskProc, "message") innerProc[0] = genSym(nskProc, "message")
var var
formalArgs = handler[3]
valuesSym = genSym(nskVar, "values") valuesSym = genSym(nskVar, "values")
valuesTuple = newNimNode(nnkTupleTy, handler) valuesTuple = newNimNode(nnkTupleTy, handler)
innerTuple = newNimNode(nnkVarTuple, handler) innerTuple = newNimNode(nnkVarTuple, handler)
varSectionInner = newNimNode(nnkVarSection, handler).add(innerTuple) varSectionInner = newNimNode(nnkVarSection, handler).add(innerTuple)
for i, arg in formalArgs: if handler.kind == nnkDo:
if i > 0: for i, arg in handler[3]:
arg.expectKind nnkIdentDefs if i > 0:
if arg[1].kind == nnkEmpty: arg.expectKind nnkIdentDefs
error("type required for capture", arg) if arg[1].kind == nnkEmpty:
var def = newNimNode(nnkIdentDefs, arg) error("type required for capture", arg)
arg.copyChildrenTo def var def = newNimNode(nnkIdentDefs, arg)
valuesTuple.add(def) arg.copyChildrenTo def
innerTuple.add(arg[0]) valuesTuple.add(def)
innerTuple.add(arg[0])
innerTuple.add(newEmptyNode(), valuesSym) innerTuple.add(newEmptyNode(), valuesSym)
var var
varSectionOuter = newNimNode(nnkVarSection, handler).add( varSectionOuter = newNimNode(nnkVarSection, handler).add(
newIdentDefs(valuesSym, valuesTuple)) newIdentDefs(valuesSym, valuesTuple))
publishBody = newStmtList(varSectionInner, handler[6]) publishBody =
if handler.kind == nnkStmtList: handler
else: newStmtList(varSectionInner, handler[6])
turnSym = ident"turn" turnSym = ident"turn"
handleSym = ident"handle" handleSym = ident"handle"
handlerSym = genSym(nskProc, "publish") handlerSym = genSym(nskProc, "publish")
@ -173,25 +175,25 @@ proc wrapPublishHandler(handler: NimNode): NimNode =
`publishBody` `publishBody`
proc wrapMessageHandler(handler: NimNode): NimNode = proc wrapMessageHandler(handler: NimNode): NimNode =
handler.expectKind nnkDo handler.expectKind {nnkDo, nnkStmtList}
var innerProc = newNimNode(nnkProcDef) var innerProc = newNimNode(nnkProcDef)
handler.copyChildrenTo innerProc handler.copyChildrenTo innerProc
innerProc[0] = genSym(nskProc, "message") innerProc[0] = genSym(nskProc, "message")
var var
formalArgs = handler[3]
valuesSym = genSym(nskVar, "values") valuesSym = genSym(nskVar, "values")
valuesTuple = newNimNode(nnkTupleTy, handler) valuesTuple = newNimNode(nnkTupleTy, handler)
innerTuple = newNimNode(nnkVarTuple, handler) innerTuple = newNimNode(nnkVarTuple, handler)
varSectionInner = newNimNode(nnkVarSection, handler).add(innerTuple) varSectionInner = newNimNode(nnkVarSection, handler).add(innerTuple)
for i, arg in formalArgs: if handler.kind == nnkDo:
if i > 0: for i, arg in handler[3]:
arg.expectKind nnkIdentDefs if i > 0:
if arg[1].kind == nnkEmpty: arg.expectKind nnkIdentDefs
error("type required for capture", arg) if arg[1].kind == nnkEmpty:
var def = newNimNode(nnkIdentDefs, arg) error("type required for capture", arg)
arg.copyChildrenTo def var def = newNimNode(nnkIdentDefs, arg)
valuesTuple.add(def) arg.copyChildrenTo def
innerTuple.add(arg[0]) valuesTuple.add(def)
innerTuple.add(arg[0])
innerTuple.add(newEmptyNode(), valuesSym) innerTuple.add(newEmptyNode(), valuesSym)
var var
varSectionOuter = newNimNode(nnkVarSection, handler).add( varSectionOuter = newNimNode(nnkVarSection, handler).add(
@ -224,30 +226,32 @@ macro onMessage*(turn: Turn; ds: Ref; pattern: Pattern; handler: untyped) =
discard observe(`turn`, `ds`, `pattern`, ClosureEntity(messageImpl: `handlerSym`)) discard observe(`turn`, `ds`, `pattern`, ClosureEntity(messageImpl: `handlerSym`))
proc wrapDuringHandler(entryBody, exitBody: NimNode): NimNode = proc wrapDuringHandler(entryBody, exitBody: NimNode): NimNode =
entryBody.expectKind nnkDo entryBody.expectKind {nnkDo, nnkStmtList}
var innerProc = newNimNode(nnkProcDef) var innerProc = newNimNode(nnkProcDef)
entryBody.copyChildrenTo innerProc entryBody.copyChildrenTo innerProc
innerProc[0] = genSym(nskProc, "during") innerProc[0] = genSym(nskProc, "during")
var var
formalArgs = entryBody[3]
valuesSym = ident("rawValues") valuesSym = ident("rawValues")
valuesTuple = newNimNode(nnkTupleTy, entryBody) valuesTuple = newNimNode(nnkTupleTy, entryBody)
innerTuple = newNimNode(nnkVarTuple, entryBody) innerTuple = newNimNode(nnkVarTuple, entryBody)
varSectionInner = newNimNode(nnkVarSection, entryBody).add(innerTuple) varSectionInner = newNimNode(nnkVarSection, entryBody).add(innerTuple)
for i, arg in formalArgs: if entryBody.kind == nnkDo:
if i > 0: for i, arg in entryBody[3]:
arg.expectKind nnkIdentDefs if i > 0:
if arg[1].kind == nnkEmpty: arg.expectKind nnkIdentDefs
error("type required for capture", arg) if arg[1].kind == nnkEmpty:
var def = newNimNode(nnkIdentDefs, arg) error("type required for capture", arg)
arg.copyChildrenTo def var def = newNimNode(nnkIdentDefs, arg)
valuesTuple.add(def) arg.copyChildrenTo def
innerTuple.add(arg[0]) valuesTuple.add(def)
innerTuple.add(arg[0])
innerTuple.add(newEmptyNode(), valuesSym) innerTuple.add(newEmptyNode(), valuesSym)
var var
varSectionOuter = newNimNode(nnkVarSection, entryBody).add( varSectionOuter = newNimNode(nnkVarSection, entryBody).add(
newIdentDefs(valuesSym, valuesTuple)) newIdentDefs(valuesSym, valuesTuple))
publishBody = newStmtList(varSectionInner, entryBody[6]) publishBody =
if entryBody.kind == nnkStmtList: entryBody
else: newStmtList(varSectionInner, entryBody[6])
turnSym = ident"turn" turnSym = ident"turn"
bindingsSym = ident"bindings" bindingsSym = ident"bindings"
handleSym = ident"duringHandle" handleSym = ident"duringHandle"