commit
693f741c8d
|
@ -29,7 +29,7 @@ template createCb(retFutureSym, iteratorNameSym,
|
||||||
bind finished
|
bind finished
|
||||||
|
|
||||||
var nameIterVar = iteratorNameSym
|
var nameIterVar = iteratorNameSym
|
||||||
#{.push stackTrace: off.}
|
{.push stackTrace: off.}
|
||||||
proc identName(udata: pointer = nil) {.closure.} =
|
proc identName(udata: pointer = nil) {.closure.} =
|
||||||
try:
|
try:
|
||||||
if not(nameIterVar.finished()):
|
if not(nameIterVar.finished()):
|
||||||
|
@ -63,7 +63,7 @@ template createCb(retFutureSym, iteratorNameSym,
|
||||||
retFutureSym.fail(getCurrentException())
|
retFutureSym.fail(getCurrentException())
|
||||||
|
|
||||||
identName()
|
identName()
|
||||||
#{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
proc createFutureVarCompletions(futureVarIdents: seq[NimNode],
|
proc createFutureVarCompletions(futureVarIdents: seq[NimNode],
|
||||||
fromNode: NimNode): NimNode {.compileTime.} =
|
fromNode: NimNode): NimNode {.compileTime.} =
|
||||||
|
@ -151,6 +151,9 @@ proc verifyReturnType(typeName: string) {.compileTime.} =
|
||||||
error("Expected return type of 'Future' got '$1'" %
|
error("Expected return type of 'Future' got '$1'" %
|
||||||
typeName)
|
typeName)
|
||||||
|
|
||||||
|
macro unsupported(s: static[string]): untyped =
|
||||||
|
error s
|
||||||
|
|
||||||
proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
||||||
## This macro transforms a single procedure into a closure iterator.
|
## This macro transforms a single procedure into a closure iterator.
|
||||||
## The ``async`` macro supports a stmtList holding multiple async procedures.
|
## The ``async`` macro supports a stmtList holding multiple async procedures.
|
||||||
|
@ -188,13 +191,8 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
||||||
var subRetType =
|
var subRetType =
|
||||||
if returnType.kind == nnkEmpty: newIdentNode("void")
|
if returnType.kind == nnkEmpty: newIdentNode("void")
|
||||||
else: baseType
|
else: baseType
|
||||||
outerProcBody.add(
|
outerProcBody.add quote do:
|
||||||
newVarStmt(retFutureSym,
|
var `retFutureSym` = newFuture[`subRetType`](`prcName`)
|
||||||
newCall(
|
|
||||||
newNimNode(nnkBracketExpr, prc.body).add(
|
|
||||||
newIdentNode("newFuture"),
|
|
||||||
subRetType),
|
|
||||||
newLit(prcName)))) # Get type from return type of this proc
|
|
||||||
|
|
||||||
# -> iterator nameIter(): FutureBase {.closure.} =
|
# -> iterator nameIter(): FutureBase {.closure.} =
|
||||||
# -> {.push warning[resultshadowed]: off.}
|
# -> {.push warning[resultshadowed]: off.}
|
||||||
|
@ -202,7 +200,7 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
||||||
# -> {.pop.}
|
# -> {.pop.}
|
||||||
# -> <proc_body>
|
# -> <proc_body>
|
||||||
# -> complete(retFuture, result)
|
# -> complete(retFuture, result)
|
||||||
var iteratorNameSym = genSym(nskIterator, $prcName & "Iter")
|
var iteratorNameSym = genSym(nskIterator, $prcName)
|
||||||
var procBody = prc.body.processBody(retFutureSym, subtypeIsVoid,
|
var procBody = prc.body.processBody(retFutureSym, subtypeIsVoid,
|
||||||
futureVarIdents)
|
futureVarIdents)
|
||||||
# don't do anything with forward bodies (empty)
|
# don't do anything with forward bodies (empty)
|
||||||
|
@ -251,6 +249,8 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
||||||
# -> return retFuture
|
# -> return retFuture
|
||||||
outerProcBody.add newNimNode(nnkReturnStmt, prc.body[^1]).add(retFutureSym)
|
outerProcBody.add newNimNode(nnkReturnStmt, prc.body[^1]).add(retFutureSym)
|
||||||
|
|
||||||
|
prc.addPragma(newColonExpr(ident "stackTrace", ident "off"))
|
||||||
|
|
||||||
result = prc
|
result = prc
|
||||||
|
|
||||||
if subtypeIsVoid:
|
if subtypeIsVoid:
|
||||||
|
@ -266,8 +266,8 @@ proc asyncSingleProc(prc: NimNode): NimNode {.compileTime.} =
|
||||||
|
|
||||||
template await*[T](f: Future[T]): auto =
|
template await*[T](f: Future[T]): auto =
|
||||||
when declared(chronosInternalRetFuture):
|
when declared(chronosInternalRetFuture):
|
||||||
when not declared(chronosInternalTmpFuture):
|
when not declaredInScope(chronosInternalTmpFuture):
|
||||||
var chronosInternalTmpFuture: FutureBase
|
var chronosInternalTmpFuture {.inject.}: FutureBase
|
||||||
chronosInternalTmpFuture = f
|
chronosInternalTmpFuture = f
|
||||||
chronosInternalRetFuture.child = chronosInternalTmpFuture
|
chronosInternalRetFuture.child = chronosInternalTmpFuture
|
||||||
yield chronosInternalTmpFuture
|
yield chronosInternalTmpFuture
|
||||||
|
@ -275,21 +275,19 @@ template await*[T](f: Future[T]): auto =
|
||||||
chronosInternalRetFuture.child = nil
|
chronosInternalRetFuture.child = nil
|
||||||
cast[type(f)](chronosInternalTmpFuture).internalRead()
|
cast[type(f)](chronosInternalTmpFuture).internalRead()
|
||||||
else:
|
else:
|
||||||
static:
|
unsupported "await is only available within {.async.}"
|
||||||
assert(false, "Await only available within {.async.}")
|
|
||||||
|
|
||||||
template awaitne*[T](f: Future[T]): Future[T] =
|
template awaitne*[T](f: Future[T]): Future[T] =
|
||||||
when declared(chronosInternalRetFuture):
|
when declared(chronosInternalRetFuture):
|
||||||
when not declared(chronosInternalTmpFuture):
|
when not declaredInScope(chronosInternalTmpFuture):
|
||||||
var chronosInternalTmpFuture: FutureBase
|
var chronosInternalTmpFuture {.inject.}: FutureBase
|
||||||
chronosInternalTmpFuture = f
|
chronosInternalTmpFuture = f
|
||||||
chronosInternalRetFuture.child = chronosInternalTmpFuture
|
chronosInternalRetFuture.child = chronosInternalTmpFuture
|
||||||
yield chronosInternalTmpFuture
|
yield chronosInternalTmpFuture
|
||||||
chronosInternalRetFuture.child = nil
|
chronosInternalRetFuture.child = nil
|
||||||
cast[type(f)](chronosInternalTmpFuture)
|
cast[type(f)](chronosInternalTmpFuture)
|
||||||
else:
|
else:
|
||||||
static:
|
unsupported "awaitne is only available within {.async.}"
|
||||||
assert(false, "Await only available within {.async.}")
|
|
||||||
|
|
||||||
macro async*(prc: untyped): untyped =
|
macro async*(prc: untyped): untyped =
|
||||||
## Macro which processes async procedures into the appropriate
|
## Macro which processes async procedures into the appropriate
|
||||||
|
|
Loading…
Reference in New Issue