summary refs log tree commit diff stats
path: root/tests/template/template_various.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/template/template_various.nim')
-rw-r--r--tests/template/template_various.nim199
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"