renamed future.nim to sugar.nim
This commit is contained in:
parent
5a5ee93784
commit
0872e7a27e
5 changed files with 207 additions and 202 deletions
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
### Changes affecting backwards compatibility
|
### Changes affecting backwards compatibility
|
||||||
|
|
||||||
|
- The stdlib module ``future`` has been renamed to ``sugar``.
|
||||||
|
|
||||||
#### Breaking changes in the standard library
|
#### Breaking changes in the standard library
|
||||||
|
|
||||||
- ``re.split`` for empty regular expressions now yields every character in
|
- ``re.split`` for empty regular expressions now yields every character in
|
||||||
|
|
|
||||||
|
|
@ -412,9 +412,8 @@ Miscellaneous
|
||||||
* `options <options.html>`_
|
* `options <options.html>`_
|
||||||
Types which encapsulate an optional value.
|
Types which encapsulate an optional value.
|
||||||
|
|
||||||
* `future <future.html>`_
|
* `sugar <sugar.html>`_
|
||||||
This module implements new experimental features. Currently the syntax
|
This module implements nice syntactic sugar based on Nim's macro system.
|
||||||
sugar for anonymous procedures.
|
|
||||||
|
|
||||||
* `coro <coro.html>`_
|
* `coro <coro.html>`_
|
||||||
This module implements experimental coroutines in Nim.
|
This module implements experimental coroutines in Nim.
|
||||||
|
|
|
||||||
|
|
@ -1,200 +1,4 @@
|
||||||
#
|
|
||||||
#
|
|
||||||
# Nim's Runtime Library
|
|
||||||
# (c) Copyright 2015 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
|
{.deprecated: "Use the new 'sugar' module instead".}
|
||||||
## the system module (or other more appropriate modules).
|
|
||||||
|
|
||||||
import macros
|
include sugar
|
||||||
|
|
||||||
proc createProcType(p, b: NimNode): NimNode {.compileTime.} =
|
|
||||||
#echo treeRepr(p)
|
|
||||||
#echo treeRepr(b)
|
|
||||||
result = newNimNode(nnkProcTy)
|
|
||||||
var formalParams = newNimNode(nnkFormalParams)
|
|
||||||
|
|
||||||
formalParams.add b
|
|
||||||
|
|
||||||
case p.kind
|
|
||||||
of nnkPar:
|
|
||||||
for i in 0 ..< p.len:
|
|
||||||
let ident = p[i]
|
|
||||||
var identDefs = newNimNode(nnkIdentDefs)
|
|
||||||
case ident.kind
|
|
||||||
of nnkExprColonExpr:
|
|
||||||
identDefs.add ident[0]
|
|
||||||
identDefs.add ident[1]
|
|
||||||
else:
|
|
||||||
identDefs.add newIdentNode("i" & $i)
|
|
||||||
identDefs.add(ident)
|
|
||||||
identDefs.add newEmptyNode()
|
|
||||||
formalParams.add identDefs
|
|
||||||
else:
|
|
||||||
var identDefs = newNimNode(nnkIdentDefs)
|
|
||||||
identDefs.add newIdentNode("i0")
|
|
||||||
identDefs.add(p)
|
|
||||||
identDefs.add newEmptyNode()
|
|
||||||
formalParams.add identDefs
|
|
||||||
|
|
||||||
result.add formalParams
|
|
||||||
result.add newEmptyNode()
|
|
||||||
#echo(treeRepr(result))
|
|
||||||
#echo(result.toStrLit())
|
|
||||||
|
|
||||||
macro `=>`*(p, b: untyped): untyped =
|
|
||||||
## Syntax sugar for anonymous procedures.
|
|
||||||
##
|
|
||||||
## .. code-block:: nim
|
|
||||||
##
|
|
||||||
## 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[NimNode] = @[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(newIdentNode("auto"))
|
|
||||||
identDefs.add(newEmptyNode())
|
|
||||||
of nnkInfix:
|
|
||||||
if c[0].kind == nnkIdent and c[0].ident == !"->":
|
|
||||||
var procTy = createProcType(c[1], c[2])
|
|
||||||
params[0] = procTy[0][0]
|
|
||||||
for i in 1 ..< procTy[0].len:
|
|
||||||
params.add(procTy[0][i])
|
|
||||||
else:
|
|
||||||
error("Expected proc type (->) got (" & $c[0].ident & ").")
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
echo treeRepr c
|
|
||||||
error("Incorrect procedure parameter list.")
|
|
||||||
params.add(identDefs)
|
|
||||||
of nnkIdent:
|
|
||||||
var identDefs = newNimNode(nnkIdentDefs)
|
|
||||||
identDefs.add(p)
|
|
||||||
identDefs.add(newIdentNode("auto"))
|
|
||||||
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: untyped): untyped =
|
|
||||||
## Syntax sugar for procedure types.
|
|
||||||
##
|
|
||||||
## .. code-block:: nim
|
|
||||||
##
|
|
||||||
## 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)
|
|
||||||
|
|
||||||
result = createProcType(p, b)
|
|
||||||
|
|
||||||
type ListComprehension = object
|
|
||||||
var lc*: ListComprehension
|
|
||||||
|
|
||||||
macro `[]`*(lc: ListComprehension, comp, typ: untyped): untyped =
|
|
||||||
## List comprehension, returns a sequence. `comp` is the actual list
|
|
||||||
## comprehension, for example ``x | (x <- 1..10, x mod 2 == 0)``. `typ` is
|
|
||||||
## the type that will be stored inside the result seq.
|
|
||||||
##
|
|
||||||
## .. code-block:: nim
|
|
||||||
##
|
|
||||||
## echo lc[x | (x <- 1..10, x mod 2 == 0), int]
|
|
||||||
##
|
|
||||||
## const n = 20
|
|
||||||
## echo lc[(x,y,z) | (x <- 1..n, y <- x..n, z <- y..n, x*x + y*y == z*z),
|
|
||||||
## tuple[a,b,c: int]]
|
|
||||||
|
|
||||||
expectLen(comp, 3)
|
|
||||||
expectKind(comp, nnkInfix)
|
|
||||||
expectKind(comp[0], nnkIdent)
|
|
||||||
assert($comp[0].ident == "|")
|
|
||||||
|
|
||||||
result = newCall(
|
|
||||||
newDotExpr(
|
|
||||||
newIdentNode("result"),
|
|
||||||
newIdentNode("add")),
|
|
||||||
comp[1])
|
|
||||||
|
|
||||||
for i in countdown(comp[2].len-1, 0):
|
|
||||||
let x = comp[2][i]
|
|
||||||
expectMinLen(x, 1)
|
|
||||||
if x[0].kind == nnkIdent and $x[0].ident == "<-":
|
|
||||||
expectLen(x, 3)
|
|
||||||
result = newNimNode(nnkForStmt).add(x[1], x[2], result)
|
|
||||||
else:
|
|
||||||
result = newIfStmt((x, result))
|
|
||||||
|
|
||||||
result = newNimNode(nnkCall).add(
|
|
||||||
newNimNode(nnkPar).add(
|
|
||||||
newNimNode(nnkLambda).add(
|
|
||||||
newEmptyNode(),
|
|
||||||
newEmptyNode(),
|
|
||||||
newEmptyNode(),
|
|
||||||
newNimNode(nnkFormalParams).add(
|
|
||||||
newNimNode(nnkBracketExpr).add(
|
|
||||||
newIdentNode("seq"),
|
|
||||||
typ)),
|
|
||||||
newEmptyNode(),
|
|
||||||
newEmptyNode(),
|
|
||||||
newStmtList(
|
|
||||||
newAssignment(
|
|
||||||
newIdentNode("result"),
|
|
||||||
newNimNode(nnkPrefix).add(
|
|
||||||
newIdentNode("@"),
|
|
||||||
newNimNode(nnkBracket))),
|
|
||||||
result))))
|
|
||||||
|
|
||||||
|
|
||||||
macro dump*(x: typed): untyped =
|
|
||||||
## Dumps the content of an expression, useful for debugging.
|
|
||||||
## It accepts any expression and prints a textual representation
|
|
||||||
## of the tree representing the expression - as it would appear in
|
|
||||||
## source code - together with the value of the expression.
|
|
||||||
##
|
|
||||||
## As an example,
|
|
||||||
##
|
|
||||||
## .. code-block:: nim
|
|
||||||
## let
|
|
||||||
## x = 10
|
|
||||||
## y = 20
|
|
||||||
## dump(x + y)
|
|
||||||
##
|
|
||||||
## will print ``x + y = 30``.
|
|
||||||
let s = x.toStrLit
|
|
||||||
let r = quote do:
|
|
||||||
debugEcho `s`, " = ", `x`
|
|
||||||
return r
|
|
||||||
|
|
|
||||||
200
lib/pure/sugar.nim
Normal file
200
lib/pure/sugar.nim
Normal file
|
|
@ -0,0 +1,200 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Nim's Runtime Library
|
||||||
|
# (c) Copyright 2015 Dominik Picheta
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
|
||||||
|
## This module implements nice syntactic sugar based on Nim's
|
||||||
|
## macro system.
|
||||||
|
|
||||||
|
import macros
|
||||||
|
|
||||||
|
proc createProcType(p, b: NimNode): NimNode {.compileTime.} =
|
||||||
|
#echo treeRepr(p)
|
||||||
|
#echo treeRepr(b)
|
||||||
|
result = newNimNode(nnkProcTy)
|
||||||
|
var formalParams = newNimNode(nnkFormalParams)
|
||||||
|
|
||||||
|
formalParams.add b
|
||||||
|
|
||||||
|
case p.kind
|
||||||
|
of nnkPar:
|
||||||
|
for i in 0 ..< p.len:
|
||||||
|
let ident = p[i]
|
||||||
|
var identDefs = newNimNode(nnkIdentDefs)
|
||||||
|
case ident.kind
|
||||||
|
of nnkExprColonExpr:
|
||||||
|
identDefs.add ident[0]
|
||||||
|
identDefs.add ident[1]
|
||||||
|
else:
|
||||||
|
identDefs.add newIdentNode("i" & $i)
|
||||||
|
identDefs.add(ident)
|
||||||
|
identDefs.add newEmptyNode()
|
||||||
|
formalParams.add identDefs
|
||||||
|
else:
|
||||||
|
var identDefs = newNimNode(nnkIdentDefs)
|
||||||
|
identDefs.add newIdentNode("i0")
|
||||||
|
identDefs.add(p)
|
||||||
|
identDefs.add newEmptyNode()
|
||||||
|
formalParams.add identDefs
|
||||||
|
|
||||||
|
result.add formalParams
|
||||||
|
result.add newEmptyNode()
|
||||||
|
#echo(treeRepr(result))
|
||||||
|
#echo(result.toStrLit())
|
||||||
|
|
||||||
|
macro `=>`*(p, b: untyped): untyped =
|
||||||
|
## Syntax sugar for anonymous procedures.
|
||||||
|
##
|
||||||
|
## .. code-block:: nim
|
||||||
|
##
|
||||||
|
## 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[NimNode] = @[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(newIdentNode("auto"))
|
||||||
|
identDefs.add(newEmptyNode())
|
||||||
|
of nnkInfix:
|
||||||
|
if c[0].kind == nnkIdent and c[0].ident == !"->":
|
||||||
|
var procTy = createProcType(c[1], c[2])
|
||||||
|
params[0] = procTy[0][0]
|
||||||
|
for i in 1 ..< procTy[0].len:
|
||||||
|
params.add(procTy[0][i])
|
||||||
|
else:
|
||||||
|
error("Expected proc type (->) got (" & $c[0].ident & ").")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
echo treeRepr c
|
||||||
|
error("Incorrect procedure parameter list.")
|
||||||
|
params.add(identDefs)
|
||||||
|
of nnkIdent:
|
||||||
|
var identDefs = newNimNode(nnkIdentDefs)
|
||||||
|
identDefs.add(p)
|
||||||
|
identDefs.add(newIdentNode("auto"))
|
||||||
|
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: untyped): untyped =
|
||||||
|
## Syntax sugar for procedure types.
|
||||||
|
##
|
||||||
|
## .. code-block:: nim
|
||||||
|
##
|
||||||
|
## 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)
|
||||||
|
|
||||||
|
result = createProcType(p, b)
|
||||||
|
|
||||||
|
type ListComprehension = object
|
||||||
|
var lc*: ListComprehension
|
||||||
|
|
||||||
|
macro `[]`*(lc: ListComprehension, comp, typ: untyped): untyped =
|
||||||
|
## List comprehension, returns a sequence. `comp` is the actual list
|
||||||
|
## comprehension, for example ``x | (x <- 1..10, x mod 2 == 0)``. `typ` is
|
||||||
|
## the type that will be stored inside the result seq.
|
||||||
|
##
|
||||||
|
## .. code-block:: nim
|
||||||
|
##
|
||||||
|
## echo lc[x | (x <- 1..10, x mod 2 == 0), int]
|
||||||
|
##
|
||||||
|
## const n = 20
|
||||||
|
## echo lc[(x,y,z) | (x <- 1..n, y <- x..n, z <- y..n, x*x + y*y == z*z),
|
||||||
|
## tuple[a,b,c: int]]
|
||||||
|
|
||||||
|
expectLen(comp, 3)
|
||||||
|
expectKind(comp, nnkInfix)
|
||||||
|
expectKind(comp[0], nnkIdent)
|
||||||
|
assert($comp[0].ident == "|")
|
||||||
|
|
||||||
|
result = newCall(
|
||||||
|
newDotExpr(
|
||||||
|
newIdentNode("result"),
|
||||||
|
newIdentNode("add")),
|
||||||
|
comp[1])
|
||||||
|
|
||||||
|
for i in countdown(comp[2].len-1, 0):
|
||||||
|
let x = comp[2][i]
|
||||||
|
expectMinLen(x, 1)
|
||||||
|
if x[0].kind == nnkIdent and $x[0].ident == "<-":
|
||||||
|
expectLen(x, 3)
|
||||||
|
result = newNimNode(nnkForStmt).add(x[1], x[2], result)
|
||||||
|
else:
|
||||||
|
result = newIfStmt((x, result))
|
||||||
|
|
||||||
|
result = newNimNode(nnkCall).add(
|
||||||
|
newNimNode(nnkPar).add(
|
||||||
|
newNimNode(nnkLambda).add(
|
||||||
|
newEmptyNode(),
|
||||||
|
newEmptyNode(),
|
||||||
|
newEmptyNode(),
|
||||||
|
newNimNode(nnkFormalParams).add(
|
||||||
|
newNimNode(nnkBracketExpr).add(
|
||||||
|
newIdentNode("seq"),
|
||||||
|
typ)),
|
||||||
|
newEmptyNode(),
|
||||||
|
newEmptyNode(),
|
||||||
|
newStmtList(
|
||||||
|
newAssignment(
|
||||||
|
newIdentNode("result"),
|
||||||
|
newNimNode(nnkPrefix).add(
|
||||||
|
newIdentNode("@"),
|
||||||
|
newNimNode(nnkBracket))),
|
||||||
|
result))))
|
||||||
|
|
||||||
|
|
||||||
|
macro dump*(x: typed): untyped =
|
||||||
|
## Dumps the content of an expression, useful for debugging.
|
||||||
|
## It accepts any expression and prints a textual representation
|
||||||
|
## of the tree representing the expression - as it would appear in
|
||||||
|
## source code - together with the value of the expression.
|
||||||
|
##
|
||||||
|
## As an example,
|
||||||
|
##
|
||||||
|
## .. code-block:: nim
|
||||||
|
## let
|
||||||
|
## x = 10
|
||||||
|
## y = 20
|
||||||
|
## dump(x + y)
|
||||||
|
##
|
||||||
|
## will print ``x + y = 30``.
|
||||||
|
let s = x.toStrLit
|
||||||
|
let r = quote do:
|
||||||
|
debugEcho `s`, " = ", `x`
|
||||||
|
return r
|
||||||
|
|
@ -59,7 +59,7 @@ srcdoc2: "deprecated/pure/asyncio;deprecated/pure/actors;core/locks;core/rlocks;
|
||||||
srcdoc2: "pure/nimprof;pure/unittest;packages/docutils/highlite"
|
srcdoc2: "pure/nimprof;pure/unittest;packages/docutils/highlite"
|
||||||
srcdoc2: "packages/docutils/rst;packages/docutils/rstast"
|
srcdoc2: "packages/docutils/rst;packages/docutils/rstast"
|
||||||
srcdoc2: "packages/docutils/rstgen;pure/logging;pure/options;pure/asyncdispatch;pure/asyncnet;pure/asyncstreams;pure/asyncfutures"
|
srcdoc2: "packages/docutils/rstgen;pure/logging;pure/options;pure/asyncdispatch;pure/asyncnet;pure/asyncstreams;pure/asyncfutures"
|
||||||
srcdoc2: "pure/nativesockets;pure/asynchttpserver;pure/net;pure/selectors;pure/future"
|
srcdoc2: "pure/nativesockets;pure/asynchttpserver;pure/net;pure/selectors;pure/sugar"
|
||||||
srcdoc2: "deprecated/pure/ftpclient;pure/collections/chains"
|
srcdoc2: "deprecated/pure/ftpclient;pure/collections/chains"
|
||||||
srcdoc2: "pure/asyncfile;pure/asyncftpclient;pure/lenientops"
|
srcdoc2: "pure/asyncfile;pure/asyncftpclient;pure/lenientops"
|
||||||
srcdoc2: "pure/md5;pure/rationals"
|
srcdoc2: "pure/md5;pure/rationals"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue