tmacrogensym.nim 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import nativesockets, asyncdispatch, macros
  2. var p = newDispatcher()
  3. var sock = createAsyncNativeSocket()
  4. proc convertReturns(node, retFutureSym: NimNode): NimNode {.compileTime.} =
  5. case node.kind
  6. of nnkReturnStmt:
  7. result = newCall(newIdentNode("complete"), retFutureSym, node[0])
  8. else:
  9. result = node
  10. for i in 0 ..< node.len:
  11. result[i] = convertReturns(node[i], retFutureSym)
  12. macro async2(prc: untyped): untyped =
  13. expectKind(prc, nnkProcDef)
  14. var outerProcBody = newNimNode(nnkStmtList)
  15. # -> var retFuture = newFuture[T]()
  16. var retFutureSym = newIdentNode("retFuture") #genSym(nskVar, "retFuture")
  17. outerProcBody.add(
  18. newVarStmt(retFutureSym,
  19. newCall(
  20. newNimNode(nnkBracketExpr).add(
  21. newIdentNode("newFuture"),
  22. prc[3][0][1])))) # Get type from return type of this proc.
  23. # -> iterator nameIter(): FutureBase {.closure.} = <proc_body>
  24. # Changing this line to: newIdentNode($prc[0].ident & "Iter") # will make it work.
  25. var iteratorNameSym = genSym(nskIterator, $prc[0] & "Iter")
  26. assert iteratorNameSym.symKind == nskIterator
  27. #var iteratorNameSym = newIdentNode($prc[0].ident & "Iter")
  28. var procBody = prc[6].convertReturns(retFutureSym)
  29. var closureIterator = newProc(iteratorNameSym, [newIdentNode("FutureBase")],
  30. procBody, nnkIteratorDef)
  31. closureIterator[4] = newNimNode(nnkPragma).add(newIdentNode("closure"))
  32. outerProcBody.add(closureIterator)
  33. # -> var nameIterVar = nameIter
  34. # -> var first = nameIterVar()
  35. var varNameIterSym = newIdentNode($prc[0] & "IterVar") #genSym(nskVar, $prc[0].ident & "IterVar")
  36. var varNameIter = newVarStmt(varNameIterSym, iteratorNameSym)
  37. outerProcBody.add varNameIter
  38. var varFirstSym = genSym(nskVar, "first")
  39. assert varFirstSym.symKind == nskVar
  40. var varFirst = newVarStmt(varFirstSym, newCall(varNameIterSym))
  41. outerProcBody.add varFirst
  42. result = prc
  43. # Remove the 'closure' pragma.
  44. for i in 0 ..< result[4].len:
  45. if result[4][i] == newIdentNode("async"):
  46. result[4].del(i)
  47. result[6] = outerProcBody
  48. proc readStuff(): Future[string] {.async2.} =
  49. var fut = connect(sock, "irc.freenode.org", Port(6667))
  50. yield fut
  51. var fut2 = recv(sock, 50)
  52. yield fut2
  53. return fut2.read