diff options
Diffstat (limited to 'tests/template/template_various.nim')
-rw-r--r-- | tests/template/template_various.nim | 199 |
1 files changed, 178 insertions, 21 deletions
diff --git a/tests/template/template_various.nim b/tests/template/template_various.nim index 50003254a..2088b1739 100644 --- a/tests/template/template_various.nim +++ b/tests/template/template_various.nim @@ -6,10 +6,32 @@ foo55 foo8.0 fooaha bar7 -immediate 10 4true 132 +20 +1 +-1 +4 +11 +26 +57 +-1-1-1 + 4 +4 + 4 + 11 +11 + 4 + 11 + 26 +26 + 4 + 11 + 26 + 57 +57 +-1-1-1 ''' """ @@ -72,7 +94,7 @@ block generic_templates: var i3: int = t1[int]("xx") - +from strutils import contains block tgetast_typeliar: proc error(s: string) = quit s @@ -85,11 +107,13 @@ block tgetast_typeliar: error("Assertion failed: " & $(`message`) & "\n" & `line`) return - macro assertOrReturn(condition: bool): typed = + macro assertOrReturn(condition: bool) = var message : NimNode = newLit(condition.repr) # echo message result = getAst assertOrReturn2(condition, message) - echo result.repr + # echo result.repr + let s = result.repr + doAssert """error("Assertion failed:""" in s proc point(size: int16): tuple[x, y: int16] = # returns random point in square area with given `size` @@ -123,21 +147,6 @@ block pattern_with_converter: -block prefer_immediate: - # Test that immediate templates are preferred over non-immediate templates - - template foo(a, b: untyped) = echo "foo expr" - template foo(a, b: int) = echo "foo int" - template foo(a, b: float) = echo "foo float" - template foo(a, b: string) = echo "foo string" - template foo(a, b: untyped) {.immediate.} = echo "immediate" - template foo(a, b: bool) = echo "foo bool" - template foo(a, b: char) = echo "foo char" - - foo(undeclaredIdentifier, undeclaredIdentifier2) - - - block procparshadow: template something(name: untyped) = @@ -208,7 +217,7 @@ block ttempl: block ttempl4: - template `:=`(name, val: untyped): typed = + template `:=`(name, val: untyped) = var name = val ha := 1 * 4 @@ -227,7 +236,7 @@ block ttempl5: discard # Call parse_to_close - template get_next_ident: typed = + template get_next_ident = discard "{something}".parse_to_close(0, open = '{', close = '}') get_next_ident() @@ -247,3 +256,151 @@ block ttempl5: block templreturntype: template `=~` (a: int, b: int): bool = false var foo = 2 =~ 3 + +# bug #7117 +template parse9(body: untyped): untyped = + + template val9(arg: string): int {.inject.} = + var b: bool + if b: 10 + else: 20 + + body + +parse9: + echo val9("1") + + +block gensym1: + template x: untyped = -1 + template t1() = + template x: untyped {.gensym, redefine.} = 1 + echo x() # 1 + template t2() = + template x: untyped {.redefine.} = 1 # defaults to {.inject.} + echo x() # -1 injected x not available during template definition + t1() + t2() + +block gensym2: + let x,y,z = -1 + template `!`(xx,yy: typed): untyped = + template x: untyped {.gensym.} = xx + template y: untyped {.gensym.} = yy + let z = x + x + y + z + var + a = 1 + b = 2 + c = 3 + d = 4 + e = 5 + echo a ! b + echo a ! b ! c + echo a ! b ! c ! d + echo a ! b ! c ! d ! e + echo x,y,z + +block gensym3: + macro liftStmts(body: untyped): auto = + # convert + # template x: untyped {.gensym.} = + # let z = a + a + b + # echo z + # z + # to + # let z = a + a + b + # echo z + # template x: untyped {.gensym.} = + # z + #echo body.repr + body.expectKind nnkStmtList + result = newNimNode nnkStmtList + for s in body: + s.expectKind nnkTemplateDef + var sle = s[6] + while sle.kind == nnkStmtList: + doAssert(sle.len==1) + sle = sle[0] + if sle.kind == nnkStmtListExpr: + let n = sle.len + for i in 0..(n-2): + result.add sle[i] + var td = newNimNode nnkTemplateDef + for i in 0..5: + td.add s[i] + td.add sle[n-1] + result.add td + else: + result.add s + #echo result.repr + let x,y,z = -1 + template `!`(xx,yy: typed): untyped = + liftStmts: + template x: untyped {.gensym.} = xx + template y: untyped {.gensym.} = yy + let z = x + x + y + echo " ", z + z + var + a = 1 + b = 2 + c = 3 + d = 4 + e = 5 + echo a ! b + echo a ! b ! c + echo a ! b ! c ! d + echo a ! b ! c ! d ! e + echo x,y,z + +block: # issue #2465 + template t() = + template declX(str: string) {.gensym.} = + var x {.inject.} : string = str + + t() + doAssert not declared(declX) + doAssert not compiles(declX("a string")) + + template t2() = + template fooGensym() {.gensym.} = + echo 42 + + t2() + doAssert not declared(fooGensym) + doAssert not compiles(fooGensym()) + + +block identifier_construction_with_overridden_symbol: + # could use add, but wanna make sure it's an override no matter what + func examplefn = discard + func examplefn(x: int) = discard + + # the function our template wants to use + func examplefn1 = discard + + template exampletempl(n) = + # attempt to build a name using the overridden symbol "examplefn" + `examplefn n`() + + exampletempl(1) + +import typetraits + +block: # issue #4596 + type + T0 = object + T1 = object + + template printFuncsT() = + proc getV[A](a: typedesc[A]): string = + var s {. global .} = name(A) + return s + + printFuncsT() + + doAssert getV(T1) == "T1" + doAssert getV(T0) == "T0" + doAssert getV(T0) == "T0" + doAssert getV(T1) == "T1" |