Skip to content

Instantly share code, notes, and snippets.

@zah
zah / gist:1176526
Created August 28, 2011 10:49
Tupfile for Nimrod projects (with automatic execution after build)
!nimrod = |> ^ %f^ nimrod c %f | tee build.log |> %B build.log
!run = |> ^ running...^ ./%f > run.log && cat run.log |> run.log
: hello.nim |> !nimrod |>
: hello |> !run |>
@zah
zah / stringinterp.nim
Created August 28, 2011 10:43
String interpolation macro
import macros, parseutils
proc isEscaped(s: string, pos: int) : bool =
var
backslashes = 0
j = pos - 1
while j >= 0:
if s[j] == '\\':
inc backslashes
@zah
zah / gist:1178497
Created August 29, 2011 14:26
Surprise, Surprise
template `:=` (lhs: expr, rhs: expr) : stmt =
var lhs = rhs
proc foo =
bar := 20
template repeatStmt(N: int, code: stmt) : stmt =
when N > 0:
code
repeatStmt(N-1, code)
template repeatTemplate(N: int, tmpl: expr) : stmt =
when > 0:
tmpl(N)
repeatTemplate(N-1, tmpl)
proc myTypeMapper(x: int) : MegaInt
proc myTypeMapper(x: float) : SmartFloat
proc MappedTupleType[T, U](tp: tuple[T, U]) : tuple[
type(myTypeMapper (valueOf[T]())),
type(myTypeMapper (valueOf[U]())),
]
proc MappedTupleType[T](tp: tuple[T]) : tuple[
type(myTypeMapper (valueOf[T]()))
#the problem is this
proc `+=`, 10, left (a: int, b: int)
proc `+=`, 20, right (a: string, b: string)
# what about this?
operator `+=`, 10, left
proc `+=` (a: int, b: int)
proc `+=` (a: string, b: string)
@zah
zah / gist:1179016
Created August 29, 2011 18:23
Typesafe variadics hack
# Some generic functions that convert nimrod values to lua
proc push(ls: PState, s: string) = pushstring(ls, s)
proc push(ls: PState, i: int) = pushinteger(ls, i)
proc push(ls: PState, f: float) = pushnumber(ls, f)
# helpers for creating type safe variadic functions
proc argsToTuple(expr: PNimrodNode) : PNimrodNode {.compileTime.} =
result = newNimNode(nnkPar)
for i in 1..expr.len-1: add(result, expr[i])
@zah
zah / gist:1180457
Created August 30, 2011 08:26
How to get side effects from template instantiations
# First, we introduce advices that modify existing methods:
before foo(b: string): int =
b = "input parameters could be modified" & b
after foo(b: string): int =
result = result & "results too"
wrap foo(b: string): int =
# here, we can write arbitrary code
if flipCoin():
proc foo[T](x: T) =
var y = ...
bar(baz)
macro:
var typeOfY = inferType(y)
proc apply[OpSymbol, T: tuple](t: T) : auto =
macro:
var retType = newNimrodType(ntkTuple)
for fields in T:
retType.add(inferType(newCall(OpSymbol, T[1])) #skiping some detail
var transformedExp = .. build and expression of the type (OpSymbol(T[0]), OpSymbol(T[1]), )
template:
var x : retType = transformedExp