diff options
Diffstat (limited to 'tests/trmacros')
-rw-r--r-- | tests/trmacros/tdisallowif.nim | 28 | ||||
-rw-r--r-- | tests/trmacros/tnorewrite.nim | 20 | ||||
-rw-r--r-- | tests/trmacros/tor.nim | 34 | ||||
-rw-r--r-- | tests/trmacros/trmacros_various.nim | 111 | ||||
-rw-r--r-- | tests/trmacros/trmacros_various2.nim | 91 | ||||
-rw-r--r-- | tests/trmacros/tstmtlist.nim | 34 |
6 files changed, 318 insertions, 0 deletions
diff --git a/tests/trmacros/tdisallowif.nim b/tests/trmacros/tdisallowif.nim new file mode 100644 index 000000000..8d83f6ddf --- /dev/null +++ b/tests/trmacros/tdisallowif.nim @@ -0,0 +1,28 @@ +discard """ + errormsg: "usage of 'disallowIf' is an {.error.} defined at tdisallowif.nim(10, 1)" + line: 24 +""" + +template optZero{x+x}(x: int): int = x*3 +template andthen{`*`(x,3)}(x: int): int = x*4 +template optSubstr1{x = substr(x, 0, b)}(x: string, b: int) = setlen(x, b+1) + +template disallowIf{ + if cond: action + else: action2 +}(cond: bool, action, action2: typed) {.error.} = action + +var y = 12 +echo y+y + +var s: array[0..2, string] +s[0] = "hello" +s[0] = substr(s[0], 0, 2) + +echo s[0] + +if s[0] != "hi": + echo "do it" + echo "more branches" +else: + discard diff --git a/tests/trmacros/tnorewrite.nim b/tests/trmacros/tnorewrite.nim new file mode 100644 index 000000000..e6769246f --- /dev/null +++ b/tests/trmacros/tnorewrite.nim @@ -0,0 +1,20 @@ +block: + proc get(x: int): int = x + + template t{get(a)}(a: int): int = + {.noRewrite.}: + get(a) + 1 + + doAssert get(0) == 1 + +block: + var x: int + + template asgn{a = b}(a: int{lvalue}, b: int) = + let newVal = b + 1 + # ^ this is needed but should it be? + {.noRewrite.}: + a = newVal + + x = 10 + doAssert x == 11, $x diff --git a/tests/trmacros/tor.nim b/tests/trmacros/tor.nim new file mode 100644 index 000000000..9defc4d1b --- /dev/null +++ b/tests/trmacros/tor.nim @@ -0,0 +1,34 @@ +discard """ + output: ''' +3 +30 +true +''' +""" + + +# bug #798 +template t012{(0|1|2){x}}(x: untyped): untyped = x+1 +let z = 1 +# outputs 3 thanks to fixpoint iteration: +echo z + + +template arithOps: untyped = (`+` | `-` | `*`) +template testOr{ (arithOps{f})(a, b) }(a, b, f: untyped): untyped = + {.noRewrite.}: + f(a mod 10, b) + +let xx = 10 +echo 10*xx + +template t{x = (~x){y} and (~x){z}}(x, y, z: bool): typed = + x = y + if x: x = z + +var + a = true + b = true + c = false +a = b and a +echo a diff --git a/tests/trmacros/trmacros_various.nim b/tests/trmacros/trmacros_various.nim new file mode 100644 index 000000000..8fe51e548 --- /dev/null +++ b/tests/trmacros/trmacros_various.nim @@ -0,0 +1,111 @@ +discard """ +output: ''' +12false3ha +21 +optimized +''' +""" + +import macros, pegs + + +block arglist: + proc f(x: varargs[string, `$`]) = discard + template optF{f(x)}(x: varargs[untyped]) = + writeLine(stdout, x) + + f 1, 2, false, 3, "ha" + + + +block tcse: + template cse{f(a, a, x)}(a: typed{(nkDotExpr|call|nkBracketExpr)&noSideEffect}, + f: typed, x: varargs[typed]): untyped = + let aa = a + f(aa, aa, x)+4 + + var + a: array[0..10, int] + i = 3 + doAssert a[i] + a[i] == 4 + + + +block hoist: + template optPeg{peg(pattern)}(pattern: string{lit}): Peg = + {.noRewrite.}: + var gl {.global, gensym.} = peg(pattern) + gl + doAssert match("(a b c)", peg"'(' @ ')'") + doAssert match("W_HI_Le", peg"\y 'while'") + + + +block tmatrix: + type + TMat = object + dummy: int + + proc `*`(a, b: TMat): TMat = nil + proc `+`(a, b: TMat): TMat = nil + proc `-`(a, b: TMat): TMat = nil + proc `$`(a: TMat): string = result = $a.dummy + proc mat21(): TMat = + result.dummy = 21 + + macro optOps{ (`+`|`-`|`*`) ** a }(a: TMat): untyped = + result = newCall(bindSym"mat21") + + #macro optPlus{ `+` * a }(a: varargs[TMat]): expr = + # result = newIntLitNode(21) + + var x, y, z: TMat + echo x + y * z - x + + + +block tnoalias: + template optslice{a = b + c}(a: untyped{noalias}, b, c: untyped): typed = + a = b + inc a, c + var + x = 12 + y = 10 + z = 13 + x = y+z + doAssert x == 23 + + + +block tnoendlessrec: + # test that an endless recursion is avoided: + template optLen{len(x)}(x: typed): int = len(x) + + var s = "lala" + doAssert len(s) == 4 + + + +block tstatic_t_bug: + # bug #4227 + type Vector64[N: static[int]] = array[N, int] + + proc `*`[N: static[int]](a: Vector64[N]; b: float64): Vector64[N] = + result = a + + proc `+=`[N: static[int]](a: var Vector64[N]; b: Vector64[N]) = + echo "regular" + + proc linearCombinationMut[N: static[int]](a: float64, v: var Vector64[N], w: Vector64[N]) {. inline .} = + echo "optimized" + + template rewriteLinearCombinationMut{v += `*`(w, a)}(a: float64, v: var Vector64, w: Vector64): auto = + linearCombinationMut(a, v, w) + + proc main() = + const scaleVal = 9.0 + var a, b: Vector64[7] + a += b * scaleval + + main() + diff --git a/tests/trmacros/trmacros_various2.nim b/tests/trmacros/trmacros_various2.nim new file mode 100644 index 000000000..981df4ca6 --- /dev/null +++ b/tests/trmacros/trmacros_various2.nim @@ -0,0 +1,91 @@ +discard """ +output: ''' +0 +-2 +48 +hel +lo +my awesome concat +''' +""" + + +block tnoalias2: + # bug #206 + template optimizeOut{testFunc(a, b)}(a: int, b: int{alias}): untyped = 0 + + proc testFunc(a, b: int): int = result = a + b + var testVar = 1 + echo testFunc(testVar, testVar) + + + template ex{a = b + c}(a : int{noalias}, b, c : int) = + a = b + inc a, b + echo "came here" + + var x = 5 + x = x + x + + + +block tpartial: + proc p(x, y: int; cond: bool): int = + result = if cond: x + y else: x - y + + template optPTrue{p(x, y, true)}(x, y): untyped = x - y + template optPFalse{p(x, y, false)}(x, y): untyped = x + y + + echo p(2, 4, true) + + + +block tpatterns: + template optZero{x+x}(x: int): int = x*3 + template andthen{`*`(x,3)}(x: int): int = x*4 + template optSubstr1{x = substr(x, a, b)}(x: string, a, b: int) = setlen(x, b+1) + + var y = 12 + echo y+y + + var s: array[0..2, string] + s[0] = "hello" + s[0] = substr(s[0], 0, 2) + + echo s[0] + + # Test varargs matching + proc someVarargProc(k: varargs[string]) = doAssert(false) # this should not get called + template someVarargProcSingleArg{someVarargProc([a])}(a: string) = echo a + someVarargProc("lo") + + + +block tstar: + var + calls = 0 + + proc `&&`(s: varargs[string]): string = + result = s[0] + for i in 1..len(s)-1: result.add s[i] + inc calls + + template optConc{ `&&` * a }(a: string): string = + {.noRewrite.}: + &&a + + let space = " " + echo "my" && (space & "awe" && "some " ) && "concat" + + # check that it's been optimized properly: + doAssert calls == 1 + +# bug #7524 +template in_to_out(typIn, typOut: typedesc) = + proc to_out(x: typIn{lit}): typOut = result = ord(x) + +# Generating the proc via template doesn't work +in_to_out(char, int) + +# This works +proc to_out2(x: char{lit}): int = result = ord(x) diff --git a/tests/trmacros/tstmtlist.nim b/tests/trmacros/tstmtlist.nim new file mode 100644 index 000000000..8261e7c45 --- /dev/null +++ b/tests/trmacros/tstmtlist.nim @@ -0,0 +1,34 @@ +discard """ + output: '''0 +|12| +34 +''' +""" + +template optWrite{ + write(f, x) + ((write|writeLine){w})(f, y) +}(x, y: varargs[untyped], f, w: untyped) = + w(f, "|", x, y, "|") + +if true: + echo "0" + write stdout, "1" + writeLine stdout, "2" + write stdout, "3" + echo "4" + +# bug #7972 + +template optimizeLogWrites*{ + write(f, x) + write(f, y) +}(x, y: string{lit}, f: File) = + write(f, x & y) + +proc foo() = + const N = 1 + stdout.write("") + stdout.write("") + +foo() |