summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@googlemail.com>2014-04-20 14:33:44 +0100
committerDominik Picheta <dominikpicheta@googlemail.com>2014-04-20 14:33:44 +0100
commit232d2528859f7eb6a47bdc274bcba67c8fdaedff (patch)
treeed01daa2986ee65c80767398b00b4ec060dc625a /lib/pure
parentcf3b54fdcb2a3a5f7a061632c8f9156fa9cddbb4 (diff)
downloadNim-232d2528859f7eb6a47bdc274bcba67c8fdaedff.tar.gz
Added new future module with a closure macro.
Diffstat (limited to 'lib/pure')
-rw-r--r--lib/pure/future.nim111
1 files changed, 111 insertions, 0 deletions
diff --git a/lib/pure/future.nim b/lib/pure/future.nim
new file mode 100644
index 000000000..1eb95df2c
--- /dev/null
+++ b/lib/pure/future.nim
@@ -0,0 +1,111 @@
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2014 Dominik Picheta
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## This module implements experimental features which may soon be moved to
+## the system module (or other more appropriate modules).
+
+import macros
+
+proc createProcType(p, b: PNimrodNode): PNimrodNode {.compileTime.} =
+  #echo treeRepr(p)
+  #echo treeRepr(b)
+  result = newNimNode(nnkProcTy)
+  var formalParams = newNimNode(nnkFormalParams)
+
+  expectKind(b, nnkIdent)
+  formalParams.add b
+
+  case p.kind
+  of nnkPar:
+    for i in 0 .. <p.len:
+      let ident = p[i]
+      var identDefs = newNimNode(nnkIdentDefs)
+      identDefs.add newIdentNode("i" & $i)
+      identDefs.add(ident)
+      identDefs.add newEmptyNode()
+      formalParams.add identDefs
+  of nnkIdent:
+    var identDefs = newNimNode(nnkIdentDefs)
+    identDefs.add newIdentNode("i0")
+    identDefs.add(p)
+    identDefs.add newEmptyNode()
+    formalParams.add identDefs
+  else:
+    error("Incorrect type list in proc type declaration.")
+  
+  result.add formalParams
+  result.add newEmptyNode()
+  #echo(treeRepr(result))
+  #echo(result.toStrLit())
+
+macro `=>`*(p, b: expr): expr {.immediate.} =
+  ## Syntax sugar for anonymous procedures.
+  ##
+  ## ..code-block:: nimrod
+  ##
+  ##   proc passTwoAndTwo(f: (int, int) -> int): int =
+  ##     f(2, 2)
+  ##
+  ##   passTwoAndTwo((x, y) => x + y) # 4
+  
+  echo treeRepr(p)
+  #echo(treeRepr(b))
+  var params: seq[PNimrodNode] = @[newIdentNode("auto")]
+
+  case p.kind
+  of nnkPar:
+    for c in children(p):
+      var identDefs = newNimNode(nnkIdentDefs)
+      case c.kind
+      of nnkExprColonExpr:
+        identDefs.add(c[0])
+        identDefs.add(c[1])
+        identDefs.add(newEmptyNode())
+      of nnkIdent:
+        identDefs.add(c)
+        identDefs.add(newEmptyNode())
+        identDefs.add(newEmptyNode())
+      else:
+        error("Incorrect procedure parameter list.")
+      params.add(identDefs)
+  of nnkIdent:
+    var identDefs = newNimNode(nnkIdentDefs)
+    identDefs.add(p)
+    identDefs.add(newEmptyNode())
+    identDefs.add(newEmptyNode())
+    params.add(identDefs)
+  of nnkInfix:
+    if p[0].kind == nnkIdent and p[0].ident == !"->":
+      var procTy = createProcType(p[1], p[2])
+      params[0] = procTy[0][0]
+      for i in 1 .. <procTy[0].len:
+        params.add(procTy[0][i])
+    else:
+      error("Expected proc type (->) got (" & $p[0].ident & ").")
+  else:
+    error("Incorrect procedure parameter list.")
+  result = newProc(params = params, body = b, procType = nnkLambda)
+  #echo(result.treeRepr)
+  echo(result.toStrLit())
+  #return result # TODO: Bug?
+
+macro `->`*(p, b: expr): expr {.immediate.} =
+  ## Syntax sugar for procedure types.
+  ##
+  ## ..code-block:: nimrod
+  ##
+  ##   proc pass2(f: (float, float) -> float): float =
+  ##     f(2, 2)
+  ##   
+  ##   # is the same as:
+  ##
+  ##   proc pass2(f: proc (x, y: float): float): float =
+  ##     f(2, 2)
+
+  createProcType(p, b)