From 202cc489034f6e4f41140d7af82e93b112fcd3dd Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Mon, 3 Aug 2015 21:28:33 +0100 Subject: [PATCH 1/2] The async macro now supports transforming multiple async procs. This is a workaround for #3182, no forward declarations. You can now do this: ```nim async: proc bar(): Future[T] proc foo() = await bar() proc bar() {.async.} = echo(123); await foo() ``` --- lib/pure/asyncdispatch.nim | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/pure/asyncdispatch.nim b/lib/pure/asyncdispatch.nim index 7523b29d5a..f49388b174 100644 --- a/lib/pure/asyncdispatch.nim +++ b/lib/pure/asyncdispatch.nim @@ -124,7 +124,8 @@ export Port, SocketFlag ## ## * The effect system (``raises: []``) does not work with async procedures. ## * Can't await in a ``except`` body - +## * Forward declarations for async procs are broken, +## link includes workaround: https://github.com/nim-lang/Nim/issues/3182. # TODO: Check if yielded future is nil and throw a more meaningful exception @@ -1412,12 +1413,12 @@ proc getName(node: NimNode): string {.compileTime.} = else: error("Unknown name.") -macro async*(prc: stmt): stmt {.immediate.} = - ## Macro which processes async procedures into the appropriate - ## iterators and yield statements. +proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} = + ## This macro transforms a single procedure into a closure iterator. + ## The ``async`` macro supports a stmtList holding multiple async procedures. if prc.kind notin {nnkProcDef, nnkLambda}: - error("Cannot transform this node kind into an async proc." & - " Proc definition or lambda node expected.") + error("Cannot transform this node kind into an async proc." & + " Proc definition or lambda node expected.") hint("Processing " & prc[0].getName & " as an async proc.") @@ -1504,9 +1505,19 @@ macro async*(prc: stmt): stmt {.immediate.} = result[6] = outerProcBody #echo(treeRepr(result)) - if prc[0].getName == "getAsync": + if prc[0].getName == "hubConnectionLoop": echo(toStrLit(result)) +macro async*(prc: stmt): stmt {.immediate.} = + ## Macro which processes async procedures into the appropriate + ## iterators and yield statements. + if prc.kind == nnkStmtList: + for oneProc in prc: + result = newStmtList() + result.add asyncSingleProc(oneProc) + else: + result = asyncSingleProc(prc) + proc recvLine*(socket: AsyncFD): Future[string] {.async.} = ## Reads a line of data from ``socket``. Returned future will complete once ## a full line is read or an error occurs. From f8f967720598ad75ec0e0db68a983cbcdd39145d Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Tue, 4 Aug 2015 09:06:47 +0100 Subject: [PATCH 2/2] Updated documentation of system.new. Ref #2699. --- lib/system.nim | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/system.nim b/lib/system.nim index 383002fcfc..93d76e78b8 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -178,7 +178,10 @@ proc new*[T](a: var ref T) {.magic: "New", noSideEffect.} proc new*(T: typedesc): auto = ## creates a new object of type ``T`` and returns a safe (traced) - ## reference to it as result value + ## reference to it as result value. + ## + ## When ``T`` is a ref type then the resulting type will be ``T``, + ## otherwise it will be ``ref T``. when (T is ref): var r: T else: