diff --git a/cps.nim b/cps.nim index 1fb58e6d..7ca154e0 100644 --- a/cps.nim +++ b/cps.nim @@ -1,7 +1,7 @@ import std/[genasts, deques] import cps/[spec, transform, rewrites, hooks, exprs, normalizedast] import std/macros except newStmtList, newTree -export Continuation, ContinuationProc, State +export Continuation, ContinuationProc, State, Whelp export cpsCall, cpsMagicCall, cpsVoodooCall, cpsMustJump export cpsMagic, cpsVoodoo, trampoline, trampolineIt export writeStackFrames, writeTraceDeque @@ -63,6 +63,12 @@ macro cps*(T: typed, n: typed): untyped = # Add the flattening phase which will be run first newCall(bindSym"cpsFlattenExpr"): n + of nnkProcTy: + # converting a cps callback + result = cpsCallbackTypeDef(T, n) + result = workaroundRewrites result.NormNode + echo treeRepr(result) + echo repr(result) else: result = getAst(cpsTransform(T, n)) diff --git a/cps/spec.nim b/cps/spec.nim index 108eca90..8f3c695c 100644 --- a/cps/spec.nim +++ b/cps/spec.nim @@ -54,6 +54,10 @@ type ContinuationProc*[T] = proc(c: T): T {.nimcall.} + Whelp*[C: Continuation; R; P: proc] = object + fn: P ## a pointer to a specific `whelp` function + rs: proc (cont: C): R ## the type signature of the `()` functions + TraceFrame* = object ## a record of where the continuation has been hook*: Hook ## the hook that provoked the trace entry fun*: string ## a short label for the notable symbol diff --git a/cps/transform.nim b/cps/transform.nim index 6777e6d5..83d665b7 100644 --- a/cps/transform.nim +++ b/cps/transform.nim @@ -1102,6 +1102,16 @@ macro cpsHandleUnhandledException(contType: typed; n: typed): untyped = debugAnnotation cpsHandleUnhandledException, n: it = it.filter(handle) +proc cpsCallbackTypeDef*(T: NimNode, n: NimNode): NimNode = + ## looks like cpsTransformProc but applies to proc typedefs; + ## this is where we create our calling convention concept + let params = copyNimTree n[0] + let R = copyNimTree params[0] + params[0] = T + let P = nnkProcTy.newTree(params, newEmptyNode()) + result = nnkBracketExpr.newTree(bindSym"Whelp", T, R, P) + result = workaroundRewrites result.NormNode + proc cpsTransformProc(T: NimNode, n: NimNode): NormNode = ## rewrite the target procedure in Continuation-Passing Style