From 2330c95b227d8e780e0cc09acee69588809334e0 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Sun, 28 Jul 2013 13:50:32 +0100 Subject: [PATCH] Implemented genSym for async function calls. --- lib/pure/asyncio.nim | 41 ++++++++++++++++++++++--------- tests/compile/tasyncitermacro.nim | 12 +++++---- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/lib/pure/asyncio.nim b/lib/pure/asyncio.nim index d590863f7..53054a738 100644 --- a/lib/pure/asyncio.nim +++ b/lib/pure/asyncio.nim @@ -841,18 +841,22 @@ proc len*(disp: PDispatcher): int = proc createRequestNode(varName, reqArgs: string, sym: var PNimrodNode): PNimrodNode {.compiletime.} = 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, parseExpr("PRequest($#)" % [reqArgs])) result.add reqObj result.add newNimNode(nnkYieldStmt).add(sym) # 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( (newDotExpr(sym, newIdentNode("hasException")), newNimNode(nnkRaiseStmt).add( - newDotExpr(sym, newIdentNode("exc"))))) - echo treeRepr(result) + newDotExpr(sym, newIdentNode("exc"))))) proc toYieldVar(n: PNimrodNode): seq[PNimrodNode] {.compiletime.} = ## Transforms a var/let section @@ -871,7 +875,7 @@ proc toYieldVar(n: PNimrodNode): seq[PNimrodNode] {.compiletime.} = let acceptReqVar = "acceptReq" var sym: PNimrodNode result.add createRequestNode(acceptReqVar, - "socket: $#, kind: reqAccept, client: nil" % sockName, sym) + "socket: $#, kind: reqAccept, client: nil, hasException: false" % sockName, sym) case n.kind of nnkLetSection: @@ -899,16 +903,24 @@ const typeDef = 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.add parseExpr("var argsToPass: P$#ArgObject" % [$call[1][0].ident]) - result.add parseExpr("new argsToPass") + sym = gensym(nskVar, "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: case call[1][i].kind of nnkLiterals, nnkIdent: - let dotExpr = newDotExpr(newIdentNode("argsToPass"), + let dotExpr = newDotExpr(sym, newIdentNode("dummy" & $i)) result.add newAssignment(dotExpr, call[1][i]) else: assert false @@ -919,7 +931,7 @@ proc transformCallWithArg(call: PNimrodNode): PNimrodNode {.compiletime.} = var args: seq[PNimrodNode] = @[] for i in 1 .. call[1].len-1: args.add(call[1][i]) - result.add newCall(call[1][0], args) + result.add newCall(call[1][0], args) proc toYieldCall(n: PNimrodNode): seq[PNimrodNode] {.compileTime.} = ## Transforms a call/command @@ -935,10 +947,15 @@ proc toYieldCall(n: PNimrodNode): seq[PNimrodNode] {.compileTime.} = "socket: $#, kind: reqWrite, toWrite: $#" % [socketName, $(toWrite.toStrLit)], sym) else: - result.add(transformCallWithArg(n)) + var sym: PNimrodNode + result.add(transformCallWithArg(n, sym)) # reqRegister - result.add parseExpr("yield PRequest(socket: $#, kind: reqReg, worker: $#, param: argsToPass)" % - [$n[1][1].ident, callIdent]) + var yie = parseExpr("yield PRequest(socket: $#, kind: reqReg, worker: $#)" % + [$n[1][1].ident, callIdent]) + yie[0].add(newNimNode(nnkExprColonExpr).add(newIdentNode("param"), + sym)) + + result.add yie proc transform(n: PNimrodNode): PNimrodNode {.compiletime.} = result = newNimNode(nnkStmtList) diff --git a/tests/compile/tasyncitermacro.nim b/tests/compile/tasyncitermacro.nim index acf2ba412..e1ec3f849 100644 --- a/tests/compile/tasyncitermacro.nim +++ b/tests/compile/tasyncitermacro.nim @@ -1,6 +1,6 @@ import sockets, asyncio, strutils -proc processRequest(client: PAsyncSocket, test: string) {.async.} = +proc processRequest(client: PAsyncSocket, test: string, closeSock: bool) {.async.} = assert test == "ahha" assert client != nil echo("Test = ", test) @@ -8,9 +8,10 @@ proc processRequest(client: PAsyncSocket, test: string) {.async.} = echo("Read: ", line) await send(client, "Goodbye.\c\L") - await send(client, "Goodbye.\c\L") - await send(client, "Goodbye.\c\L") - client.close() + #await send(client, "Goodbye.\c\L") + #await send(client, "Goodbye.\c\L") + if closeSock: + client.close() proc processServer() {.async.} = var sock = AsyncSocket() @@ -23,7 +24,8 @@ proc processServer() {.async.} = while true: let client: PAsyncSocket = await(accept(sock)) assert client != nil - await processRequest(client, "ahha") + await processRequest(client, "ahha", false) + await processRequest(client, "ahha", true) var disp = newDispatcher(false) disp.register(processServer, nil)