Implemented genSym for async function calls.
This commit is contained in:
parent
adc74f8ab0
commit
2330c95b22
2 changed files with 36 additions and 17 deletions
|
|
@ -841,18 +841,22 @@ proc len*(disp: PDispatcher): int =
|
||||||
proc createRequestNode(varName,
|
proc createRequestNode(varName,
|
||||||
reqArgs: string, sym: var PNimrodNode): PNimrodNode {.compiletime.} =
|
reqArgs: string, sym: var PNimrodNode): PNimrodNode {.compiletime.} =
|
||||||
result = newNimNode(nnkStmtList)
|
result = newNimNode(nnkStmtList)
|
||||||
sym = genSym(nskVar, varName)
|
# TODO: Using gensym here causes segfaults because hasException is not
|
||||||
|
# initialised.
|
||||||
|
sym = newIdentNode(varName) #genSym(nskVar, varName)
|
||||||
var reqObj = newVarStmt(sym,
|
var reqObj = newVarStmt(sym,
|
||||||
parseExpr("PRequest($#)" % [reqArgs]))
|
parseExpr("PRequest($#)" % [reqArgs]))
|
||||||
|
|
||||||
result.add reqObj
|
result.add reqObj
|
||||||
result.add newNimNode(nnkYieldStmt).add(sym)
|
result.add newNimNode(nnkYieldStmt).add(sym)
|
||||||
# Check for exception
|
# Check for exception
|
||||||
|
# TODO: Create a custom exception type, create a field which will store
|
||||||
|
# the original stack trace as given by getStackTrace. Maybe there is a way
|
||||||
|
# to override the stack trace? That'd be nice.
|
||||||
result.add newIfStmt(
|
result.add newIfStmt(
|
||||||
(newDotExpr(sym, newIdentNode("hasException")),
|
(newDotExpr(sym, newIdentNode("hasException")),
|
||||||
newNimNode(nnkRaiseStmt).add(
|
newNimNode(nnkRaiseStmt).add(
|
||||||
newDotExpr(sym, newIdentNode("exc")))))
|
newDotExpr(sym, newIdentNode("exc")))))
|
||||||
echo treeRepr(result)
|
|
||||||
|
|
||||||
proc toYieldVar(n: PNimrodNode): seq[PNimrodNode] {.compiletime.} =
|
proc toYieldVar(n: PNimrodNode): seq[PNimrodNode] {.compiletime.} =
|
||||||
## Transforms a var/let section
|
## Transforms a var/let section
|
||||||
|
|
@ -871,7 +875,7 @@ proc toYieldVar(n: PNimrodNode): seq[PNimrodNode] {.compiletime.} =
|
||||||
let acceptReqVar = "acceptReq"
|
let acceptReqVar = "acceptReq"
|
||||||
var sym: PNimrodNode
|
var sym: PNimrodNode
|
||||||
result.add createRequestNode(acceptReqVar,
|
result.add createRequestNode(acceptReqVar,
|
||||||
"socket: $#, kind: reqAccept, client: nil" % sockName, sym)
|
"socket: $#, kind: reqAccept, client: nil, hasException: false" % sockName, sym)
|
||||||
|
|
||||||
case n.kind
|
case n.kind
|
||||||
of nnkLetSection:
|
of nnkLetSection:
|
||||||
|
|
@ -899,16 +903,24 @@ const typeDef =
|
||||||
P$#ArgObject = ref object of TObject
|
P$#ArgObject = ref object of TObject
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc transformCallWithArg(call: PNimrodNode): PNimrodNode {.compiletime.} =
|
proc transformCallWithArg(call: PNimrodNode,
|
||||||
|
sym: var PNimrodNode): PNimrodNode {.compiletime.} =
|
||||||
result = newNimNode(nnkStmtList)
|
result = newNimNode(nnkStmtList)
|
||||||
|
|
||||||
result.add parseExpr("var argsToPass: P$#ArgObject" % [$call[1][0].ident])
|
sym = gensym(nskVar, "argsToPass")
|
||||||
result.add parseExpr("new argsToPass")
|
|
||||||
|
# var argsToPass: P$#ArgObject
|
||||||
|
result.add newNimNode(nnkVarSection).add(
|
||||||
|
newNimNode(nnkIdentDefs).add(sym,
|
||||||
|
newIdentNode("P$#ArgObject" % [$call[1][0].ident]),
|
||||||
|
newNimNode(nnkEmpty)))
|
||||||
|
|
||||||
|
result.add newCall("new", sym)
|
||||||
|
|
||||||
for i in 1 .. call[1].len-1:
|
for i in 1 .. call[1].len-1:
|
||||||
case call[1][i].kind
|
case call[1][i].kind
|
||||||
of nnkLiterals, nnkIdent:
|
of nnkLiterals, nnkIdent:
|
||||||
let dotExpr = newDotExpr(newIdentNode("argsToPass"),
|
let dotExpr = newDotExpr(sym,
|
||||||
newIdentNode("dummy" & $i))
|
newIdentNode("dummy" & $i))
|
||||||
result.add newAssignment(dotExpr, call[1][i])
|
result.add newAssignment(dotExpr, call[1][i])
|
||||||
else: assert false
|
else: assert false
|
||||||
|
|
@ -935,10 +947,15 @@ proc toYieldCall(n: PNimrodNode): seq[PNimrodNode] {.compileTime.} =
|
||||||
"socket: $#, kind: reqWrite, toWrite: $#" %
|
"socket: $#, kind: reqWrite, toWrite: $#" %
|
||||||
[socketName, $(toWrite.toStrLit)], sym)
|
[socketName, $(toWrite.toStrLit)], sym)
|
||||||
else:
|
else:
|
||||||
result.add(transformCallWithArg(n))
|
var sym: PNimrodNode
|
||||||
|
result.add(transformCallWithArg(n, sym))
|
||||||
# reqRegister
|
# reqRegister
|
||||||
result.add parseExpr("yield PRequest(socket: $#, kind: reqReg, worker: $#, param: argsToPass)" %
|
var yie = parseExpr("yield PRequest(socket: $#, kind: reqReg, worker: $#)" %
|
||||||
[$n[1][1].ident, callIdent])
|
[$n[1][1].ident, callIdent])
|
||||||
|
yie[0].add(newNimNode(nnkExprColonExpr).add(newIdentNode("param"),
|
||||||
|
sym))
|
||||||
|
|
||||||
|
result.add yie
|
||||||
|
|
||||||
proc transform(n: PNimrodNode): PNimrodNode {.compiletime.} =
|
proc transform(n: PNimrodNode): PNimrodNode {.compiletime.} =
|
||||||
result = newNimNode(nnkStmtList)
|
result = newNimNode(nnkStmtList)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import sockets, asyncio, strutils
|
import sockets, asyncio, strutils
|
||||||
|
|
||||||
proc processRequest(client: PAsyncSocket, test: string) {.async.} =
|
proc processRequest(client: PAsyncSocket, test: string, closeSock: bool) {.async.} =
|
||||||
assert test == "ahha"
|
assert test == "ahha"
|
||||||
assert client != nil
|
assert client != nil
|
||||||
echo("Test = ", test)
|
echo("Test = ", test)
|
||||||
|
|
@ -8,9 +8,10 @@ proc processRequest(client: PAsyncSocket, test: string) {.async.} =
|
||||||
echo("Read: ", line)
|
echo("Read: ", line)
|
||||||
|
|
||||||
await send(client, "Goodbye.\c\L")
|
await send(client, "Goodbye.\c\L")
|
||||||
await send(client, "Goodbye.\c\L")
|
#await send(client, "Goodbye.\c\L")
|
||||||
await send(client, "Goodbye.\c\L")
|
#await send(client, "Goodbye.\c\L")
|
||||||
client.close()
|
if closeSock:
|
||||||
|
client.close()
|
||||||
|
|
||||||
proc processServer() {.async.} =
|
proc processServer() {.async.} =
|
||||||
var sock = AsyncSocket()
|
var sock = AsyncSocket()
|
||||||
|
|
@ -23,7 +24,8 @@ proc processServer() {.async.} =
|
||||||
while true:
|
while true:
|
||||||
let client: PAsyncSocket = await(accept(sock))
|
let client: PAsyncSocket = await(accept(sock))
|
||||||
assert client != nil
|
assert client != nil
|
||||||
await processRequest(client, "ahha")
|
await processRequest(client, "ahha", false)
|
||||||
|
await processRequest(client, "ahha", true)
|
||||||
|
|
||||||
var disp = newDispatcher(false)
|
var disp = newDispatcher(false)
|
||||||
disp.register(processServer, nil)
|
disp.register(processServer, nil)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue