Last active
August 29, 2015 14:17
-
-
Save fowlmouth/48f3340b797c12cb3043 to your computer and use it in GitHub Desktop.
nim variadic templates
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import macros | |
macro first (va_expr: expr): expr = | |
if va_expr.kind == nnkBracket: | |
return va_expr[0] | |
else: | |
return va_expr | |
macro rest (va_expr: expr): expr = | |
echo treerepr(va_expr) | |
va_expr.expectKind nnkBracket | |
result = newNimNode(va_expr.kind) | |
for i in 1 .. <len(va_expr): | |
echo i, ": ", va_expr[i].repr | |
result.add va_expr[i] | |
echo treerepr result | |
macro show (xs: expr): expr = | |
toStrLit(xs) | |
proc recurseApply (f:NimNode; xs:NimNode): NimNode{.compileTime.} = | |
result = newStmtList() | |
var xs = xs | |
while xs.len > 0: | |
let item = getAst(first(xs)) | |
xs = getAst(rest(xs)) | |
result.add quote do: `f`(`item`) | |
discard | |
echo repr(result) | |
macro `&&` (args:varargs[expr]): expr = | |
echo treerepr(args) | |
if args.kind == nnkBracket: return args | |
else: return newNimNode(nnkBracket).add(args) | |
macro cleanup(destructor; xs:varargs[expr]): stmt = | |
result = recurseApply(destructor, xs) | |
#bind destructor | |
#echo first(xs) | |
#echo len(xs) | |
#echo repr(xs) | |
#echo repr(rest(xs)) | |
#destructor(first(xs)) | |
#when len(xs) > 1: | |
# cleanup(destructor, getAst(rest(xs))) | |
proc destroy (i:int) = | |
echo "destroying ", i | |
proc destroy (f:float) = | |
echo "destroying ", f | |
let | |
i1 = 1 | |
f1 = 2.0 | |
i2 = 3 | |
cleanup(destroy, i1, f1, i2) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import macros | |
macro first (va_expr: expr): expr = | |
if va_expr.kind == nnkBracket: | |
return va_expr[0] | |
else: | |
return va_expr | |
macro rest (va_expr: expr): expr = | |
echo treerepr(va_expr) | |
va_expr.expectKind nnkBracket | |
result = newNimNode(va_expr.kind) | |
for i in 1 .. <len(va_expr): | |
echo i, ": ", va_expr[i].repr | |
result.add va_expr[i] | |
echo treerepr result | |
template cleanup_tmpl (destructor; xs:varargs[expr]): stmt = | |
destructor(first(xs)) | |
when len(xs) > 1: | |
cleanup_tmpl(destructor, rest(xs)) | |
proc destroy (i:int) = | |
echo "destroying ", i | |
proc destroy (f:float) = | |
echo "destroying ", f | |
let | |
i1 = 1 | |
f1 = 2.0 | |
i2 = 3 | |
cleanup_tmpl(destroy, i1, f1, i2) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
using namespace std; | |
void destroy(int some) | |
{ | |
cout << "destroying " << some << endl; | |
} | |
void destroy(float some) | |
{ | |
cout << "destroying " << some << endl; | |
} | |
template <typename first, typename... rest> | |
void destroy(first& a, rest&... b) | |
{ | |
destroy(a); | |
destroy(b...); | |
} | |
int main(void) | |
{ | |
int a = 1, b = 2; | |
float c = 1.0/9.0; | |
destroy(a,c,b); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment