diff options
Diffstat (limited to 'tests/template/template_various.nim')
-rw-r--r-- | tests/template/template_various.nim | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/tests/template/template_various.nim b/tests/template/template_various.nim new file mode 100644 index 000000000..2088b1739 --- /dev/null +++ b/tests/template/template_various.nim @@ -0,0 +1,406 @@ +discard """ +output: ''' +i2416 +33 +foo55 +foo8.0 +fooaha +bar7 +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 +''' +""" + +import macros + + + + +import i2416 +i2416() + + +import mcan_access_hidden_field +var myfoo = createFoo(33, 44) +echo myfoo.geta + + +import mgensym_generic_cross_module +foo(55) +foo 8.0 +foo "aha" +bar 7 + + + +block generic_templates: + type + SomeObj = object of RootObj + Foo[T, U] = object + x: T + y: U + + template someTemplate[T](): tuple[id: int32, obj: T] = + var result: tuple[id: int32, obj: T] = (0'i32, T()) + result + + let ret = someTemplate[SomeObj]() + + # https://github.com/nim-lang/Nim/issues/7829 + proc inner[T](): int = + discard + + template outer[A](): untyped = + inner[A]() + + template outer[B](x: int): untyped = + inner[B]() + + var i1 = outer[int]() + var i2 = outer[int](i1) + + # https://github.com/nim-lang/Nim/issues/7883 + template t1[T: int|int64](s: string): T = + var t: T + t + + template t1[T: int|int64](x: int, s: string): T = + var t: T + t + + var i3: int = t1[int]("xx") + +from strutils import contains + +block tgetast_typeliar: + proc error(s: string) = quit s + + macro assertOrReturn2(condition: bool; message: string) = + var line = condition.lineInfo() + result = quote do: + block: + if not likely(`condition`): + error("Assertion failed: " & $(`message`) & "\n" & `line`) + return + + macro assertOrReturn(condition: bool) = + var message : NimNode = newLit(condition.repr) + # echo message + result = getAst assertOrReturn2(condition, message) + # 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` + assertOrReturn size > 0 + + + +type + MyFloat = object + val: float +converter to_myfloat(x: float): MyFloat {.inline.} = + MyFloat(val: x) + +block pattern_with_converter: + proc `+`(x1, x2: MyFloat): MyFloat = + MyFloat(val: x1.val + x2.val) + + proc `*`(x1, x2: MyFloat): MyFloat = + MyFloat(val: x1.val * x2.val) + + template optMul{`*`(a, 2.0)}(a: MyFloat): MyFloat = + a + a + + func floatMyFloat(x: MyFloat): MyFloat = + result = x * 2.0 + + func floatDouble(x: float): float = + result = x * 2.0 + + doAssert floatDouble(5) == 10.0 + + + + +block procparshadow: + template something(name: untyped) = + proc name(x: int) = + var x = x # this one should not be rejected by the compiler (#5225) + echo x + + something(what) + what(10) + + # bug #4750 + type + O = object + i: int + OP = ptr O + + template alf(p: pointer): untyped = + cast[OP](p) + + proc t1(al: pointer) = + var o = alf(al) + + proc t2(alf: pointer) = + var x = alf + var o = alf(x) + + + +block symchoicefield: + type Foo = object + len: int + + var f = Foo(len: 40) + + template getLen(f: Foo): int = f.len + + doAssert f.getLen == 40 + # This fails, because `len` gets the nkOpenSymChoice + # treatment inside the template early pass and then + # it can't be recognized as a field anymore + + + +import os, times +include "sunset.nimf" +block ttempl: + const + tabs = [["home", "index"], + ["news", "news"], + ["documentation", "documentation"], + ["download", "download"], + ["FAQ", "question"], + ["links", "links"]] + + + var i = 0 + for item in items(tabs): + var content = $i + var file: File + if open(file, changeFileExt(item[1], "html"), fmWrite): + write(file, sunsetTemplate(current=item[1], ticker="", content=content, + tabs=tabs)) + close(file) + else: + write(stdout, "cannot open file for writing") + inc(i) + + + +block ttempl4: + template `:=`(name, val: untyped) = + var name = val + + ha := 1 * 4 + hu := "ta-da" == "ta-da" + echo ha, hu + + + + +import mtempl5 +block ttempl5: + echo templ() + + #bug #892 + proc parse_to_close(value: string, index: int, open='(', close=')'): int = + discard + + # Call parse_to_close + template get_next_ident = + discard "{something}".parse_to_close(0, open = '{', close = '}') + + get_next_ident() + + #identifier expected, but found '(open|open|open)' + #bug #880 (also example in the manual!) + template typedef(name: untyped, typ: typedesc) = + type + `T name` {.inject.} = typ + `P name` {.inject.} = ref `T name` + + typedef(myint, int) + var x: PMyInt + + + +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" |