Merge tests into a larger file (part 8 of ∞) (#9583)

* merge tuple tests

* merge trmacros tests

* merge template tests
This commit is contained in:
Miran
2018-11-06 18:33:58 +01:00
committed by Arne Döring
parent c735b75f6f
commit 66a76d3165
51 changed files with 862 additions and 835 deletions

View File

@@ -1,2 +0,0 @@
import i2416
i2416()

View File

@@ -1,23 +0,0 @@
discard """
output: "8.0"
"""
# bug #2057
proc mpf_get_d(x: int): float = float(x)
proc mpf_cmp_d(a: int; b: float): int = 0
template toFloatHelper(result, tooSmall, tooLarge: untyped) =
result = mpf_get_d(a)
if result == 0.0 and mpf_cmp_d(a,0.0) != 0:
tooSmall
if result == Inf:
tooLarge
proc toFloat*(a: int): float =
toFloatHelper(result) do:
raise newException(ValueError, "number too small")
do:
raise newException(ValueError, "number too large")
echo toFloat(8)

View File

@@ -1,9 +0,0 @@
discard """
output: 33
"""
import mcan_access_hidden_field
var myfoo = createFoo(33, 44)
echo myfoo.geta

View File

@@ -1,14 +0,0 @@
# bug #2629
import sequtils, os
template glob_rst(basedir: string = ""): untyped =
if baseDir.len == 0:
to_seq(walk_files("*.rst"))
else:
to_seq(walk_files(basedir/"*.rst"))
let
rst_files = concat(glob_rst(), glob_rst("docs"))
when isMainModule: echo rst_files

View File

@@ -0,0 +1,209 @@
discard """
output: '''
@[]
5
0
a
hi
'''
"""
import macros, json
block t2057:
proc mpf_get_d(x: int): float = float(x)
proc mpf_cmp_d(a: int; b: float): int = 0
template toFloatHelper(result, tooSmall, tooLarge: untyped) =
result = mpf_get_d(a)
if result == 0.0 and mpf_cmp_d(a,0.0) != 0:
tooSmall
if result == Inf:
tooLarge
proc toFloat(a: int): float =
toFloatHelper(result) do:
raise newException(ValueError, "number too small")
do:
raise newException(ValueError, "number too large")
doAssert toFloat(8) == 8.0
import sequtils, os
block t2629:
template glob_rst(basedir: string = ""): untyped =
if baseDir.len == 0:
to_seq(walk_files("*.rst"))
else:
to_seq(walk_files(basedir/"*.rst"))
let rst_files = concat(glob_rst(), glob_rst("docs"))
when isMainModule: echo rst_files
block t5417:
macro genBody: untyped =
let sbx = genSym(nskLabel, "test")
when true:
result = quote do:
block `sbx`:
break `sbx`
else:
template foo(s1, s2) =
block s1:
break s2
result = getAst foo(sbx, sbx)
proc test() =
genBody()
block t909:
template baz() =
proc bar() =
var x = 5
iterator foo(): int {.closure.} =
echo x
var y = foo
discard y()
macro test(): untyped =
result = getAst(baz())
test()
bar()
block t993:
type PNode = ref object of RootObj
template litNode(name, ty) =
type name = ref object of PNode
val: ty
litNode PIntNode, int
template withKey(j: JsonNode; key: string; varname,
body: untyped): typed =
if j.hasKey(key):
let varname{.inject.}= j[key]
block:
body
var j = parsejson("{\"zzz\":1}")
withkey(j, "foo", x):
echo(x)
block t1337:
template someIt(a, pred): untyped =
var it {.inject.} = 0
pred
proc aProc(n: auto) =
n.someIt(echo(it))
aProc(89)
import mlt
block t4564:
type Bar = ref object of RootObj
proc foo(a: Bar): int = 0
var a: Bar
let b = a.foo() > 0
block t8052:
type
UintImpl[N: static[int], T: SomeUnsignedInt] = object
raw_data: array[N, T]
template genLoHi(TypeImpl: untyped): untyped =
template loImpl[N: static[int], T: SomeUnsignedInt](dst: TypeImpl[N div 2, T], src: TypeImpl[N, T]) =
let halfSize = N div 2
for i in 0 ..< halfSize:
dst.raw_data[i] = src.raw_data[i]
proc lo[N: static[int], T: SomeUnsignedInt](x: TypeImpl[N,T]): TypeImpl[N div 2, T] {.inline.}=
loImpl(result, x)
genLoHi(UintImpl)
var a: UintImpl[4, uint32]
a.raw_data = [1'u32, 2'u32, 3'u32, 4'u32]
doAssert a.lo.raw_data.len == 2
doAssert a.lo.raw_data[0] == 1
doAssert a.lo.raw_data[1] == 2
block t2585:
type
RenderPass = object
state: ref int
RenderData = object
fb: int
walls: seq[RenderPass]
Mat2 = int
Vector2[T] = T
Pixels=int
template use(fb: int, st: untyped): untyped =
echo "a ", $fb
st
echo "a ", $fb
proc render(rdat: var RenderData; passes: var openarray[RenderPass]; proj: Mat2;
indexType = 1) =
for i in 0 ..< len(passes):
echo "blah ", repr(passes[i])
proc render2(rdat: var RenderData; screenSz: Vector2[Pixels]; proj: Mat2) =
use rdat.fb:
render(rdat, rdat.walls, proj, 1)
block t4292:
template foo(s: string): string = s
proc variadicProc(v: varargs[string, foo]) = echo v[0]
variadicProc("a")
block t2670:
template testTemplate(b: bool): typed =
when b:
var a = "hi"
else:
var a = 5
echo a
testTemplate(true)
block t4097:
var i {.compileTime.} = 2
template defineId(t: typedesc) =
const id {.genSym.} = i
static: inc(i)
proc idFor(T: typedesc[t]): int {.inline, raises: [].} = id
defineId(int8)
defineId(int16)
doAssert idFor(int8) == 2
doAssert idFor(int16) == 3

View File

@@ -0,0 +1,251 @@
discard """
output: '''
i2416
33
foo55
foo8.0
fooaha
bar7
immediate
10
4true
132
'''
"""
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")
block tgetast_typeliar:
proc error(s: string) = quit s
macro assertOrReturn(condition: bool; message: string): typed =
var line = condition.lineInfo()
result = quote do:
block:
if not likely(`condition`):
error("Assertion failed: " & $(`message`) & "\n" & `line`)
return
macro assertOrReturn(condition: bool): typed =
var message = condition.toStrLit()
result = getAst assertOrReturn(condition, message)
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 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) =
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.tmpl"
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): typed =
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: typed =
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

View File

@@ -1,37 +0,0 @@
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")

View File

@@ -1,14 +0,0 @@
discard """
output: '''foo55
foo8.0
fooaha
bar7'''
"""
# bug #5419
import mgensym_generic_cross_module
foo(55)
foo 8.0
foo "aha"
bar 7

View File

@@ -1,18 +0,0 @@
# bug #5417
import macros
macro genBody: untyped =
let sbx = genSym(nskLabel, "test")
when true:
result = quote do:
block `sbx`:
break `sbx`
else:
template foo(s1, s2) =
block s1:
break s2
result = getAst foo(sbx, sbx)
proc test() =
genBody()

View File

@@ -1,23 +0,0 @@
# just ensure this keeps compiling:
import macros
proc error(s: string) = quit s
macro assertOrReturn*(condition: bool; message: string): typed =
var line = condition.lineInfo()
result = quote do:
block:
if not likely(`condition`):
error("Assertion failed: " & $(`message`) & "\n" & `line`)
return
macro assertOrReturn*(condition: bool): typed =
var message = condition.toStrLit()
result = getAst assertOrReturn(condition, message)
proc point*(size: int16): tuple[x, y: int16] =
# returns random point in square area with given `size`
assertOrReturn size > 0

View File

@@ -1,16 +0,0 @@
import macros
template baz() =
proc bar() =
var x = 5
iterator foo(): int {.closure.} =
echo x
var y = foo
discard y()
macro test(): untyped =
result = getAst(baz())
echo(treeRepr(result))
test()
bar()

View File

@@ -1,20 +0,0 @@
type PNode* = ref object of RootObj
template litNode(name, ty) =
type name* = ref object of PNode
val*: ty
litNode PIntNode, int
import json
template withKey*(j: JsonNode; key: string; varname,
body: untyped): typed =
if j.hasKey(key):
let varname{.inject.}= j[key]
block:
body
var j = parsejson("{\"zzz\":1}")
withkey(j, "foo", x):
echo(x)

View File

@@ -1,11 +0,0 @@
# bug #1337
template someIt(a, pred): untyped =
var it {.inject.} = 0
pred
proc aProc(n: auto) =
n.someIt(echo(it))
aProc(89)

View File

@@ -1,7 +0,0 @@
import mlt
# bug #4564
type Bar* = ref object of RootObj
proc foo(a: Bar): int = 0
var a: Bar
let b = a.foo() > 0

View File

@@ -1,23 +0,0 @@
# bug #8052
type
UintImpl*[N: static[int], T: SomeUnsignedInt] = object
raw_data*: array[N, T]
template genLoHi(TypeImpl: untyped): untyped =
template loImpl[N: static[int], T: SomeUnsignedInt](dst: TypeImpl[N div 2, T], src: TypeImpl[N, T]) =
let halfSize = N div 2
for i in 0 ..< halfSize:
dst.raw_data[i] = src.raw_data[i]
proc lo*[N: static[int], T: SomeUnsignedInt](x: TypeImpl[N,T]): TypeImpl[N div 2, T] {.inline.}=
loImpl(result, x)
genLoHi(UintImpl)
var a: UintImpl[4, uint32]
a.raw_data = [1'u32, 2'u32, 3'u32, 4'u32]
assert a.lo.raw_data.len == 2
assert a.lo.raw_data[0] == 1
assert a.lo.raw_data[1] == 2

View File

@@ -1,27 +0,0 @@
discard """
output: 10.0
"""
type
MyFloat = object
val: float
converter to_myfloat*(x: float): MyFloat {.inline.} =
MyFloat(val: x)
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
echo floatDouble(5)

View File

@@ -1,15 +0,0 @@
discard """
output: '''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)

View File

@@ -1,30 +0,0 @@
discard """
output: "10"
"""
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)

View File

@@ -1,30 +0,0 @@
# bug #2585
type
RenderPass = object
state: ref int
RenderData* = object
fb: int
walls: seq[RenderPass]
Mat2 = int
Vector2[T] = T
Pixels=int
template use*(fb: int, st: untyped): untyped =
echo "a ", $fb
st
echo "a ", $fb
proc render(rdat: var RenderData; passes: var openarray[RenderPass]; proj: Mat2;
indexType = 1) =
for i in 0 .. <len(passes):
echo "blah ", repr(passes[i])
proc render2*(rdat: var RenderData; screenSz: Vector2[Pixels]; proj: Mat2) =
use rdat.fb:
render(rdat, rdat.walls, proj, 1)

View File

@@ -1,11 +0,0 @@
type Foo = object
len: int
var f = Foo(len: 40)
template getLen(f: Foo): int = f.len
echo f.getLen
# This fails, because `len` gets the nkOpenSymChoice
# treatment inside the template early pass and then
# it can't be recognized as a field anymore

View File

@@ -1,9 +0,0 @@
discard """
output: '''a'''
"""
# bug #4292
template foo(s: string): string = s
proc variadicProc*(v: varargs[string, foo]) = echo v[0]
variadicProc("a")

View File

@@ -1,27 +0,0 @@
# Test the new template file mechanism
import
os, times
include "sunset.tmpl"
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)

View File

@@ -1,7 +0,0 @@
template `:=`(name, val: untyped): typed =
var name = val
ha := 1 * 4
hu := "ta-da" == "ta-da"
echo ha, hu

View File

@@ -1,28 +0,0 @@
import mtempl5
echo templ()
#bug #892
proc parse_to_close(value: string, index: int, open='(', close=')'): int =
discard
# Call parse_to_close
template get_next_ident: typed =
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

View File

@@ -1,4 +0,0 @@
template `=~` (a: int, b: int): bool = false
var foo = 2 =~ 3

View File

@@ -1,13 +0,0 @@
discard """
output: "hi"
"""
# bug #2670
template testTemplate(b: bool): typed =
when b:
var a = "hi"
else:
var a = 5
echo a
testTemplate(true)

View File

@@ -1,17 +0,0 @@
discard """
output: '''2 3'''
"""
# bug #4097
var i {.compileTime.} = 2
template defineId*(t: typedesc) =
const id {.genSym.} = i
static: inc(i)
proc idFor*(T: typedesc[t]): int {.inline, raises: [].} = id
defineId(int8)
defineId(int16)
echo idFor(int8), " ", idFor(int16)

View File

@@ -1,9 +0,0 @@
discard """
output: "12false3ha"
"""
proc f(x: varargs[string, `$`]) = discard
template optF{f(x)}(x: varargs[untyped]) =
writeLine(stdout, x)
f 1, 2, false, 3, "ha"

View File

@@ -1,13 +0,0 @@
discard """
output: "4"
"""
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
echo a[i] + a[i]

View File

@@ -1,13 +0,0 @@
discard """
output: '''true
true'''
"""
import pegs
template optPeg{peg(pattern)}(pattern: string{lit}): Peg =
var gl {.global, gensym.} = peg(pattern)
gl
echo match("(a b c)", peg"'(' @ ')'")
echo match("W_HI_Le", peg"\y 'while'")

View File

@@ -1,29 +0,0 @@
discard """
output: "21"
"""
import macros
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 =
echo treeRepr(a)
result = newCall(bindSym"mat21")
#macro optPlus{ `+` * a }(a: varargs[TMat]): expr =
# result = newIntLitNode(21)
var x, y, z: TMat
echo x + y * z - x
#echo x + y + z

View File

@@ -1,16 +0,0 @@
discard """
output: "23"
"""
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
echo x

View File

@@ -1,19 +0,0 @@
discard """
output: '''0'''
"""
# 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

View File

@@ -1,10 +0,0 @@
discard """
output: "4"
"""
# test that an endless recursion is avoided:
template optLen{len(x)}(x: typed): int = len(x)
var s = "lala"
echo len(s)

View File

@@ -1,11 +0,0 @@
discard """
output: '''-2'''
"""
proc p(x, y: int; cond: bool): int =
result = if cond: x + y else: x - y
template optP{p(x, y, true)}(x, y): untyped = x - y
template optP{p(x, y, false)}(x, y): untyped = x + y
echo p(2, 4, true)

View File

@@ -1,23 +0,0 @@
discard """
output: '''48
hel
lo'''
"""
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")

View File

@@ -0,0 +1,110 @@
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 =
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()

View File

@@ -0,0 +1,79 @@
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 optP{p(x, y, true)}(x, y): untyped = x - y
template optP{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 = &&a
let space = " "
echo "my" && (space & "awe" && "some " ) && "concat"
# check that it's been optimized properly:
doAssert calls == 1

View File

@@ -1,19 +0,0 @@
discard """
output: "my awesome concat"
"""
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 = &&a
let space = " "
echo "my" && (space & "awe" && "some " ) && "concat"
# check that it's been optimized properly:
doAssert calls == 1

View File

@@ -1,24 +0,0 @@
discard """
output: "optimized"
"""
# 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()

View File

@@ -1,26 +0,0 @@
discard """
output: '''61, 125
(Field0: 0) (Field0: 13)'''
"""
import macros
proc `^` (a, b: int): int =
result = 1
for i in 1..b: result = result * a
var m = (0, 5)
var n = (56, 3)
m = (n[0] + m[1], m[1] ^ n[1])
echo m[0], ", ", m[1]
# also test we can produce unary anon tuples in a macro:
macro mm(): untyped =
result = newTree(nnkTupleConstr, newLit(13))
proc nowTuple(): (int,) =
result = (0,)
echo nowTuple(), " ", mm()

View File

@@ -1,23 +0,0 @@
# Bug 4479
type
MyTuple = tuple
num: int
strings: seq[string]
ints: seq[int]
var foo = MyTuple((
num: 7,
strings: @[],
ints: @[],
))
var bar = (
num: 7,
strings: @[],
ints: @[],
).MyTuple
var fooUnnamed = MyTuple((7, @[], @[]))
var n = 7
var fooSym = MyTuple((num: n, strings: @[], ints: @[]))

View File

@@ -1,9 +0,0 @@
# bug #1910
import tables
var p: OrderedTable[tuple[a:int], int]
var q: OrderedTable[tuple[x:int], int]
for key in p.keys:
echo key.a
for key in q.keys:
echo key.x

View File

@@ -1,9 +0,0 @@
# bug #2121
type
Item[K,V] = tuple
key: K
value: V
var q = newseq[Item[int,int]](0)
let (x,y) = q[0]

View File

@@ -1,17 +0,0 @@
# bug #2369
type HashedElem[T] = tuple[num: int, storedVal: ref T]
proc append[T](tab: var seq[HashedElem[T]], n: int, val: ref T) =
#tab.add((num: n, storedVal: val))
var he: HashedElem[T] = (num: n, storedVal: val)
#tab.add(he)
var g: seq[HashedElem[int]] = @[]
proc foo() =
var x: ref int
new(x)
x[] = 77
g.append(44, x)

View File

@@ -0,0 +1,77 @@
discard """
output: '''
'''
"""
import tables
block t4479:
type
MyTuple = tuple
num: int
strings: seq[string]
ints: seq[int]
var foo = MyTuple((
num: 7,
strings: @[],
ints: @[],
))
var bar = (
num: 7,
strings: @[],
ints: @[],
).MyTuple
var fooUnnamed = MyTuple((7, @[], @[]))
var n = 7
var fooSym = MyTuple((num: n, strings: @[], ints: @[]))
block t1910:
var p = newOrderedTable[tuple[a:int], int]()
var q = newOrderedTable[tuple[x:int], int]()
for key in p.keys:
echo key.a
for key in q.keys:
echo key.x
block t2121:
type
Item[K,V] = tuple
key: K
value: V
var q = newseq[Item[int,int]](1)
let (x,y) = q[0]
block t2369:
type HashedElem[T] = tuple[num: int, storedVal: ref T]
proc append[T](tab: var seq[HashedElem[T]], n: int, val: ref T) =
#tab.add((num: n, storedVal: val))
var he: HashedElem[T] = (num: n, storedVal: val)
#tab.add(he)
var g: seq[HashedElem[int]] = @[]
proc foo() =
var x: ref int
new(x)
x[] = 77
g.append(44, x)
block t1986:
proc test(): int64 =
return 0xdeadbeef.int64
const items = [
(var1: test(), var2: 100'u32),
(var1: test(), var2: 192'u32)
]

View File

@@ -0,0 +1,136 @@
discard """
output: '''
it's nil
@[1, 2, 3]
'''
"""
import macros
block anontuples:
proc `^` (a, b: int): int =
result = 1
for i in 1..b: result = result * a
var m = (0, 5)
var n = (56, 3)
m = (n[0] + m[1], m[1] ^ n[1])
doAssert m == (61, 125)
# also test we can produce unary anon tuples in a macro:
macro mm(): untyped =
result = newTree(nnkTupleConstr, newLit(13))
proc nowTuple(): (int,) =
result = (0,)
doAssert nowTuple() == (Field0: 0)
doAssert mm() == (Field0: 13)
block unpack_asgn:
proc foobar(): (int, int) = (2, 4)
# test within a proc:
proc pp(x: var int) =
var y: int
(y, x) = foobar()
template pt(x) =
var y: int
(x, y) = foobar()
# test within a generic:
proc pg[T](x, y: var T) =
pt(x)
# test as a top level statement:
var x, y, a, b: int
# test for regression:
(x, y) = (1, 2)
(x, y) = fooBar()
doAssert x == 2
doAssert y == 4
pp(a)
doAssert a == 4
pg(a, b)
doAssert a == 2
doAssert b == 0
block tuple_subscript:
proc`[]` (t: tuple, key: string): string =
for name, field in fieldPairs(t):
if name == key:
return $field
return ""
proc`[]` [A,B](t: tuple, key: string, op: (proc(x: A): B)): B =
for name, field in fieldPairs(t):
when field is A:
if name == key:
return op(field)
proc`[]=`[T](t: var tuple, key: string, val: T) =
for name, field in fieldPairs(t):
when field is T:
if name == key:
field = val
var tt = (a: 1, b: "str1")
# test built in operator
tt[0] = 5
doAssert tt[0] == 5
doAssert `[]`(tt, 0) == 5
# test overloaded operator
tt["b"] = "str2"
doAssert tt["b"] == "str2"
doAssert `[]`(tt, "b") == "str2"
doAssert tt["b", proc(s: string): int = s.len] == 4
block tuple_with_seq:
template foo(s: string = "") =
if s.len == 0:
echo "it's nil"
else:
echo s
foo
# bug #2632
proc takeTup(x: tuple[s: string;x: seq[int]]) =
discard
takeTup(("foo", @[]))
#proc foobar(): () =
proc f(xs: seq[int]) =
discard
proc g(t: tuple[n:int, xs:seq[int]]) =
discard
when isMainModule:
f(@[]) # OK
g((1,@[1])) # OK
g((0,@[])) # NG
# bug #2630
type T = tuple[a: seq[int], b: int]
var t: T = (@[1,2,3], 7)
proc test(s: seq[int]): T =
echo s
(s, 7)
t = test(t.a)

View File

@@ -1,10 +0,0 @@
# bug #1986 found by gdmoore
proc test(): int64 =
return 0xdeadbeef.int64
const items = [
(var1: test(), var2: 100'u32),
(var1: test(), var2: 192'u32)
]

View File

@@ -1,34 +0,0 @@
discard """
output: '''2 4
4
2 0'''
"""
proc foobar(): (int, int) = (2, 4)
# test within a proc:
proc pp(x: var int) =
var y: int
(y, x) = foobar()
template pt(x) =
var y: int
(x, y) = foobar()
# test within a generic:
proc pg[T](x, y: var T) =
pt(x)
# test as a top level statement:
var x, y, a, b: int
# test for regression:
(x, y) = (1, 2)
(x, y) = fooBar()
echo x, " ", y
pp(a)
echo a
pg(a, b)
echo a, " ", b

View File

@@ -1,40 +0,0 @@
discard """
output: '''5
5
str2
str2
4'''
"""
proc`[]` (t: tuple, key: string): string =
for name, field in fieldPairs(t):
if name == key:
return $field
return ""
proc`[]` [A,B](t: tuple, key: string, op: (proc(x: A): B)): B =
for name, field in fieldPairs(t):
when field is A:
if name == key:
return op(field)
proc`[]=`[T](t: var tuple, key: string, val: T) =
for name, field in fieldPairs(t):
when field is T:
if name == key:
field = val
var tt = (a: 1, b: "str1")
# test built in operator
tt[0] = 5
echo tt[0]
echo `[]`(tt, 0)
# test overloaded operator
tt["b"] = "str2"
echo tt["b"]
echo `[]`(tt, "b")
echo tt["b", proc(s: string) : int = s.len]

View File

@@ -1,46 +0,0 @@
discard """
output: '''it's nil
@[1, 2, 3]'''
"""
template foo(s: string = "") =
if s.len == 0:
echo "it's nil"
else:
echo s
foo
# bug #2632
proc takeTup(x: tuple[s: string;x: seq[int]]) =
discard
takeTup(("foo", @[]))
#proc foobar(): () =
proc f(xs: seq[int]) =
discard
proc g(t: tuple[n:int, xs:seq[int]]) =
discard
when isMainModule:
f(@[]) # OK
g((1,@[1])) # OK
g((0,@[])) # NG
# bug #2630
type T = tuple[a: seq[int], b: int]
var t: T = (@[1,2,3], 7)
proc test(s: seq[int]): T =
echo s
(s, 7)
t = test(t.a)