diff options
author | Dominik Picheta <dominikpicheta@googlemail.com> | 2014-04-20 14:33:44 +0100 |
---|---|---|
committer | Dominik Picheta <dominikpicheta@googlemail.com> | 2014-04-20 14:33:44 +0100 |
commit | 232d2528859f7eb6a47bdc274bcba67c8fdaedff (patch) | |
tree | ed01daa2986ee65c80767398b00b4ec060dc625a | |
parent | cf3b54fdcb2a3a5f7a061632c8f9156fa9cddbb4 (diff) | |
download | Nim-232d2528859f7eb6a47bdc274bcba67c8fdaedff.tar.gz |
Added new future module with a closure macro.
-rw-r--r-- | doc/lib.txt | 3 | ||||
-rw-r--r-- | lib/pure/future.nim | 111 | ||||
-rw-r--r-- | tests/closure/tclosuremacro.nim | 43 | ||||
-rw-r--r-- | web/nimrod.ini | 2 |
4 files changed, 158 insertions, 1 deletions
diff --git a/doc/lib.txt b/doc/lib.txt index a209357f7..3ca519c9e 100644 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -373,6 +373,9 @@ Miscellaneous * `logging <logging.html>`_ This module implements a simple logger. +* `future <future.html>`_ + This module implements new experimental features. Currently the syntax + sugar for anonymous procedures. Database support ---------------- 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) diff --git a/tests/closure/tclosuremacro.nim b/tests/closure/tclosuremacro.nim new file mode 100644 index 000000000..80d89a090 --- /dev/null +++ b/tests/closure/tclosuremacro.nim @@ -0,0 +1,43 @@ +discard """ + output: '''10 +10 +10 +3 +3 +noReturn +''' +""" + +import future + +when false: + proc twoParams(x: (int, int) -> int): int = + result = x(5, 5) + + proc oneParam(x: int -> int): int = + x(5) + + proc noParams(x: () -> int): int = + result = x() + + proc noReturn(x: () -> void) = + x() + + proc doWithOneAndTwo(f: (int, int) -> int): int = + f(1,2) + + echo twoParams(proc (a, b): auto = a + b) + echo twoParams((x, y) => x + y) + + echo oneParam(x => x+5) + + echo noParams(() => 3) + + echo doWithOneAndTwo((x, y) => x + y) + + noReturn(() -> void => echo("noReturn")) + +proc pass2(f: (int, int) -> int): (int) -> int = + (x: int) -> int => f(2, x) + +#echo pass2((x, y) => x + y) diff --git a/web/nimrod.ini b/web/nimrod.ini index b29bcff30..14701ecea 100644 --- a/web/nimrod.ini +++ b/web/nimrod.ini @@ -63,7 +63,7 @@ srcdoc2: "pure/asyncio;pure/actors;core/locks;pure/oids;pure/endians;pure/uri" srcdoc2: "pure/nimprof;pure/unittest;packages/docutils/highlite" srcdoc2: "packages/docutils/rst;packages/docutils/rstast" srcdoc2: "packages/docutils/rstgen;pure/logging;pure/asyncdispatch;pure/asyncnet" -srcdoc2: "pure/rawsockets;pure/asynchttpserver;pure/net;pure/selectors" +srcdoc2: "pure/rawsockets;pure/asynchttpserver;pure/net;pure/selectors;pure/future" webdoc: "wrappers/libcurl;pure/md5;wrappers/mysql;wrappers/iup" webdoc: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc" |