diff --git a/cps.nim b/cps.nim index 22f6724d..258d237d 100644 --- a/cps.nim +++ b/cps.nim @@ -941,13 +941,21 @@ proc cpsXfrm(T: NimNode, n: NimNode): NimNode = result = copy n result = workaroundRewrites(result) -macro cps*(T: typed, n: typed): untyped = +macro cps2(T: typed, n: typed): untyped = # I hate doing stuff inside macros, call the proc to do the work when defined(nimdoc): result = n else: result = cpsXfrm(T, n) +macro cps*(T: typed, n: typed): untyped = + case n.kind + of nnkProcDef: + result = getImplTransformed n.name + result.addPragma newColonExpr(bindSym"cps2", T) + else: + result = cpsXfrm(T, n) + macro cpsMagic*(n: untyped): untyped = ## upgrade cps primitives to generate errors out of context ## and take continuations as input inside {.cps.} blocks diff --git a/cps/spec.nim b/cps/spec.nim index 42f535f8..d770fd28 100644 --- a/cps/spec.nim +++ b/cps/spec.nim @@ -324,7 +324,12 @@ proc normalizingRewrites*(n: NimNode): NimNode = if n.len == 2: n.add newEmptyNode() elif n[1].isEmpty: # add explicit type symbol - n[1] = getTypeInst n[2] + if not n[2].isEmpty: + n[1] = getTypeInst n[2] + else: + # get the type from the symbol as the last resort. + # walkaround for #48. + n[1] = getTypeInst n[0] n[2] = normalizingRewrites n[2] result = n @@ -439,6 +444,15 @@ proc normalizingRewrites*(n: NimNode): NimNode = else: discard + proc rewriteFastAsgn(n: NimNode): NimNode = + ## Rewrite nnkFastAsgn into nnkAsgn because sem don't like them + case n.kind + of nnkFastAsgn: + result = newNimNode(nnkAsgn, n) + for child in n.items: + result.add child + else: discard + case n.kind of nnkIdentDefs: rewriteIdentDefs n @@ -452,6 +466,8 @@ proc normalizingRewrites*(n: NimNode): NimNode = rewriteReturn n of CallNodes: rewriteHidden n + of nnkFastAsgn: + rewriteFastAsgn n else: nil diff --git a/tests/taste.nim b/tests/taste.nim index 076d16e1..f32cc131 100644 --- a/tests/taste.nim +++ b/tests/taste.nim @@ -998,19 +998,16 @@ suite "tasteful tests": block: ## for loops with continue, break and a split - when true: - skip"pending #48" - else: - r = 0 - proc foo() {.cps: Cont.} = - inc r - for i in 0 .. 3: - noop() - if i == 0: - continue - if i > 2: - break - r.inc i + r = 0 + proc foo() {.cps: Cont.} = + inc r + for i in 0 .. 3: + noop() + if i == 0: + continue + if i > 2: + break + r.inc i - trampoline foo() - check r == 4 + trampoline foo() + check r == 4