Skip to content

Instantly share code, notes, and snippets.

@dom96
Last active August 29, 2015 13:56
Show Gist options
  • Save dom96/9155536 to your computer and use it in GitHub Desktop.
Save dom96/9155536 to your computer and use it in GitHub Desktop.
import macros
macro `=>`(p, b: expr): expr {.immediate.} =
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)
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.} =
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())
when isMainModule:
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)
assert twoParams(proc (a, b): auto = a + b) == 10
assert twoParams((x, y) => x + y) == 10
assert oneParam(x => x+5) == 10
assert noParams(() => 3) == 3
assert doWithOneAndTwo((x, y) => x + y) == 3
# Limitations:
when false:
var prc = (x: int, y: int) => x * y # Error: internal error: mapType
echo(prc(3, 3)) # Error: type mismatch: got (auto)
# Error: can not infer the return type of the proc
noReturn(() => echo("noReturn"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment