Fixes issues with 'discard' in async macro.
This commit is contained in:
parent
fb7598d25a
commit
7d2ed73a62
1 changed files with 15 additions and 8 deletions
|
|
@ -104,6 +104,7 @@ when defined(windows):
|
||||||
|
|
||||||
PDispatcher* = ref object
|
PDispatcher* = ref object
|
||||||
ioPort: THandle
|
ioPort: THandle
|
||||||
|
hasHandles: bool
|
||||||
|
|
||||||
TCustomOverlapped = object
|
TCustomOverlapped = object
|
||||||
Internal*: DWORD
|
Internal*: DWORD
|
||||||
|
|
@ -125,9 +126,13 @@ when defined(windows):
|
||||||
if CreateIOCompletionPort(sock.THandle, p.ioPort,
|
if CreateIOCompletionPort(sock.THandle, p.ioPort,
|
||||||
cast[TCompletionKey](sock), 1) == 0:
|
cast[TCompletionKey](sock), 1) == 0:
|
||||||
OSError(OSLastError())
|
OSError(OSLastError())
|
||||||
|
p.hasHandles = true
|
||||||
|
|
||||||
proc poll*(p: PDispatcher, timeout = 500) =
|
proc poll*(p: PDispatcher, timeout = 500) =
|
||||||
## Waits for completion events and processes them.
|
## Waits for completion events and processes them.
|
||||||
|
if not p.hasHandles:
|
||||||
|
raise newException(EInvalidValue, "No handles registered in dispatcher.")
|
||||||
|
|
||||||
let llTimeout =
|
let llTimeout =
|
||||||
if timeout == -1: winlean.INFINITE
|
if timeout == -1: winlean.INFINITE
|
||||||
else: timeout.int32
|
else: timeout.int32
|
||||||
|
|
@ -483,6 +488,7 @@ template createVar(futSymName: string, asyncProc: PNimrodNode,
|
||||||
valueReceiver = newDotExpr(futSym, newIdentNode("read")) # -> future<x>.read
|
valueReceiver = newDotExpr(futSym, newIdentNode("read")) # -> future<x>.read
|
||||||
|
|
||||||
proc processBody(node, retFutureSym: PNimrodNode): PNimrodNode {.compileTime.} =
|
proc processBody(node, retFutureSym: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||||
|
result = node
|
||||||
case node.kind
|
case node.kind
|
||||||
of nnkReturnStmt:
|
of nnkReturnStmt:
|
||||||
result = newNimNode(nnkStmtList)
|
result = newNimNode(nnkStmtList)
|
||||||
|
|
@ -490,8 +496,6 @@ proc processBody(node, retFutureSym: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||||
if node[0].kind == nnkEmpty: newIdentNode("result") else: node[0])
|
if node[0].kind == nnkEmpty: newIdentNode("result") else: node[0])
|
||||||
result.add newNimNode(nnkYieldStmt).add(newNilLit())
|
result.add newNimNode(nnkYieldStmt).add(newNilLit())
|
||||||
of nnkCommand:
|
of nnkCommand:
|
||||||
result = node
|
|
||||||
echo(treeRepr(node))
|
|
||||||
if node[0].ident == !"await":
|
if node[0].ident == !"await":
|
||||||
case node[1].kind
|
case node[1].kind
|
||||||
of nnkIdent, nnkCall:
|
of nnkIdent, nnkCall:
|
||||||
|
|
@ -500,13 +504,13 @@ proc processBody(node, retFutureSym: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||||
result = newNimNode(nnkYieldStmt).add(node[1]) # -> yield x
|
result = newNimNode(nnkYieldStmt).add(node[1]) # -> yield x
|
||||||
else:
|
else:
|
||||||
error("Invalid node kind in 'await', got: " & $node[1].kind)
|
error("Invalid node kind in 'await', got: " & $node[1].kind)
|
||||||
elif node[1].kind == nnkIdent and node[1][0].ident == !"await":
|
elif node[1].kind == nnkCommand and node[1][0].kind == nnkIdent and
|
||||||
|
node[1][0].ident == !"await":
|
||||||
# foo await x
|
# foo await x
|
||||||
var newCommand = node
|
var newCommand = node
|
||||||
createVar("future" & $node[0].ident, node[1][0], newCommand[1])
|
createVar("future" & $node[0].ident, node[1][0], newCommand[1])
|
||||||
result.add newCommand
|
result.add newCommand
|
||||||
of nnkVarSection, nnkLetSection:
|
of nnkVarSection, nnkLetSection:
|
||||||
result = node
|
|
||||||
case node[0][2].kind
|
case node[0][2].kind
|
||||||
of nnkCommand:
|
of nnkCommand:
|
||||||
if node[0][2][0].ident == !"await":
|
if node[0][2][0].ident == !"await":
|
||||||
|
|
@ -517,7 +521,6 @@ proc processBody(node, retFutureSym: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||||
result.add newVarSection
|
result.add newVarSection
|
||||||
else: discard
|
else: discard
|
||||||
of nnkAsgn:
|
of nnkAsgn:
|
||||||
result = node
|
|
||||||
case node[1].kind
|
case node[1].kind
|
||||||
of nnkCommand:
|
of nnkCommand:
|
||||||
if node[1][0].ident == !"await":
|
if node[1][0].ident == !"await":
|
||||||
|
|
@ -532,10 +535,12 @@ proc processBody(node, retFutureSym: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||||
var dummy = newNimNode(nnkStmtList)
|
var dummy = newNimNode(nnkStmtList)
|
||||||
createVar("futureDiscard_" & $toStrLit(node[0][1]), node[0][1], dummy)
|
createVar("futureDiscard_" & $toStrLit(node[0][1]), node[0][1], dummy)
|
||||||
else:
|
else:
|
||||||
result = node
|
|
||||||
for i in 0 .. <node.len:
|
for i in 0 .. <node.len:
|
||||||
result[i] = processBody(node[i], retFutureSym)
|
result[i] = processBody(node[i], retFutureSym)
|
||||||
|
|
||||||
|
assert(not result.isNil)
|
||||||
|
#echo(treeRepr(result))
|
||||||
|
|
||||||
proc getName(node: PNimrodNode): string {.compileTime.} =
|
proc getName(node: PNimrodNode): string {.compileTime.} =
|
||||||
case node.kind
|
case node.kind
|
||||||
of nnkPostfix:
|
of nnkPostfix:
|
||||||
|
|
@ -548,6 +553,8 @@ proc getName(node: PNimrodNode): string {.compileTime.} =
|
||||||
macro async*(prc: stmt): stmt {.immediate.} =
|
macro async*(prc: stmt): stmt {.immediate.} =
|
||||||
expectKind(prc, nnkProcDef)
|
expectKind(prc, nnkProcDef)
|
||||||
|
|
||||||
|
hint("Processing " & prc[0].getName & " as an async proc.")
|
||||||
|
|
||||||
# Verify that the return type is a PFuture[T]
|
# Verify that the return type is a PFuture[T]
|
||||||
if prc[3][0].kind == nnkIdent:
|
if prc[3][0].kind == nnkIdent:
|
||||||
error("Expected return type of 'PFuture' got '" & $prc[3][0] & "'")
|
error("Expected return type of 'PFuture' got '" & $prc[3][0] & "'")
|
||||||
|
|
@ -658,7 +665,7 @@ when isMainModule:
|
||||||
p.register(sock)
|
p.register(sock)
|
||||||
|
|
||||||
|
|
||||||
when true:
|
when false:
|
||||||
# Await tests
|
# Await tests
|
||||||
proc main(p: PDispatcher): PFuture[int] {.async.} =
|
proc main(p: PDispatcher): PFuture[int] {.async.} =
|
||||||
discard await p.connect(sock, "irc.freenode.net", TPort(6667))
|
discard await p.connect(sock, "irc.freenode.net", TPort(6667))
|
||||||
|
|
@ -684,7 +691,7 @@ when isMainModule:
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
when true:
|
when false:
|
||||||
|
|
||||||
var f = p.connect(sock, "irc.freenode.org", TPort(6667))
|
var f = p.connect(sock, "irc.freenode.org", TPort(6667))
|
||||||
f.callback =
|
f.callback =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue