From f3eb0a5970ff0b9ec5ed8b95551c79cea395e279 Mon Sep 17 00:00:00 2001 From: Clyybber Date: Sat, 15 Feb 2020 19:53:40 +0100 Subject: [PATCH] capture macro now accepts variables of different types (#13356) * Capture macro can now accept variables of different types * Add test * Update examples * Use let instead of var --- lib/pure/sugar.nim | 8 +++++--- tests/closure/tcapture.nim | 14 +++++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/pure/sugar.nim b/lib/pure/sugar.nim index fa28ffcf47cf..f18557e0e6a5 100644 --- a/lib/pure/sugar.nim +++ b/lib/pure/sugar.nim @@ -165,7 +165,7 @@ template distinctBase*(T: typedesc): typedesc {.deprecated: "use distinctBase fr ## reverses ``type T = distinct A``; works recursively. typetraits.distinctBase(T) -macro capture*(locals: openArray[typed], body: untyped): untyped {.since: (1, 1).} = +macro capture*(locals: varargs[typed], body: untyped): untyped {.since: (1, 1).} = ## Useful when creating a closure in a loop to capture some local loop variables ## by their current iteration values. Example: ## @@ -175,14 +175,16 @@ macro capture*(locals: openArray[typed], body: untyped): untyped {.since: (1, 1) ## for i in 5..7: ## for j in 7..9: ## if i * j == 42: - ## capture [i, j]: + ## capture i, j: ## myClosure = proc () = echo fmt"{i} * {j} = 42" ## myClosure() # output: 6 * 7 == 42 ## let m = @[proc (s: string): string = "to " & s, proc (s: string): string = "not to " & s] - ## var l = m.mapIt(capture([it], proc (s: string): string = it(s))) + ## var l = m.mapIt(capture(it, proc (s: string): string = it(s))) ## let r = l.mapIt(it("be")) ## echo r[0] & ", or " & r[1] # output: to be, or not to be var params = @[newIdentNode("auto")] + let locals = if locals.len == 1 and locals[0].kind == nnkBracket: locals[0] + else: locals for arg in locals: params.add(newIdentDefs(ident(arg.strVal), freshIdentNodes getTypeInst arg)) result = newNimNode(nnkCall) diff --git a/tests/closure/tcapture.nim b/tests/closure/tcapture.nim index ff3490f07eb1..dafc44739292 100644 --- a/tests/closure/tcapture.nim +++ b/tests/closure/tcapture.nim @@ -2,7 +2,9 @@ discard """ output: ''' to be, or not to be (v: 1) +(w: -1) (v: 1) +(w: -1) ''' joinable: false """ @@ -14,13 +16,19 @@ var l = m.mapIt(capture([it], proc (s: string): string = it(s))) let r = l.mapIt(it("be")) echo r[0] & ", or " & r[1] -type O = object - v: int +type + O = object + v: int + U = object + w: int var o = O(v: 1) +var u = U(w: -1) var execute: proc() -capture [o]: +capture o, u: execute = proc() = echo o + echo u execute() o.v = -1 +u.w = 1 execute()