Merge branch 'araq2' into devel
This commit is contained in:
commit
8f67b90997
54 changed files with 2479 additions and 340 deletions
|
|
@ -7,7 +7,7 @@ discard """
|
|||
import macros
|
||||
|
||||
macro mixer(n: typed): untyped =
|
||||
expectKind(n, nnkCharLit)
|
||||
|
||||
expectKind(n[0], nnkCharLit)
|
||||
|
||||
mixer:
|
||||
echo "owh"
|
||||
echo "owh"
|
||||
|
|
|
|||
45
tests/closure/tdonotation.nim
Normal file
45
tests/closure/tdonotation.nim
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
discard """
|
||||
output: '''
|
||||
click at 10,20
|
||||
lost focus 1
|
||||
lost focus 2
|
||||
registered handler for UserEvent 1
|
||||
registered handler for UserEvent 2
|
||||
registered handler for UserEvent 3'''
|
||||
"""
|
||||
|
||||
import future
|
||||
|
||||
type
|
||||
Button = object
|
||||
Event = object
|
||||
x, y: int
|
||||
|
||||
proc onClick(x: Button, handler: proc(x: Event)) =
|
||||
handler(Event(x: 10, y: 20))
|
||||
|
||||
proc onFocusLost(x: Button, handler: proc()) =
|
||||
handler()
|
||||
|
||||
proc onUserEvent(x: Button, eventName: string, handler: proc) =
|
||||
echo "registered handler for ", eventName
|
||||
|
||||
var b = Button()
|
||||
|
||||
b.onClick do (e: Event):
|
||||
echo "click at ", e.x, ",", e.y
|
||||
|
||||
b.onFocusLost:
|
||||
echo "lost focus 1"
|
||||
|
||||
b.onFocusLost do:
|
||||
echo "lost focus 2"
|
||||
|
||||
b.onUserEvent "UserEvent 1" do:
|
||||
discard
|
||||
|
||||
b.onUserEvent "UserEvent 2":
|
||||
discard
|
||||
|
||||
b.onUserEvent("UserEvent 3", () => echo "event 3")
|
||||
|
||||
25
tests/concepts/t5642.nim
Normal file
25
tests/concepts/t5642.nim
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
discard """
|
||||
output: 9
|
||||
"""
|
||||
|
||||
type DataTable = concept x
|
||||
x is object
|
||||
for f in fields(x):
|
||||
f is seq
|
||||
|
||||
type Students = object
|
||||
id : seq[int]
|
||||
name : seq[string]
|
||||
age: seq[int]
|
||||
|
||||
proc nrow*(dt: DataTable) : Natural =
|
||||
var totalLen = 0
|
||||
for f in fields(dt):
|
||||
totalLen += f.len
|
||||
return totalLen
|
||||
|
||||
let
|
||||
stud = Students (id : @[1,2,3], name : @["Vas", "Pas", "NafNaf"], age : @[10,16,32])
|
||||
|
||||
echo nrow(stud)
|
||||
|
||||
53
tests/concepts/tconceptinclosure.nim
Normal file
53
tests/concepts/tconceptinclosure.nim
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
discard """
|
||||
output: '''
|
||||
10
|
||||
20
|
||||
int
|
||||
20
|
||||
3
|
||||
'''
|
||||
"""
|
||||
|
||||
import typetraits
|
||||
|
||||
type
|
||||
FonConcept = concept x
|
||||
x.x is int
|
||||
|
||||
GenericConcept[T] = concept x
|
||||
x.x is T
|
||||
const L = T.name.len
|
||||
|
||||
Implementation = object
|
||||
x: int
|
||||
|
||||
Closure = object
|
||||
f: proc()
|
||||
|
||||
proc f1(x: FonConcept): Closure =
|
||||
result.f = proc () =
|
||||
echo x.x
|
||||
|
||||
proc f2(x: GenericConcept): Closure =
|
||||
result.f = proc () =
|
||||
echo x.x
|
||||
echo GenericConcept.T.name
|
||||
|
||||
proc f3[T](x: GenericConcept[T]): Closure =
|
||||
result.f = proc () =
|
||||
echo x.x
|
||||
echo x.L
|
||||
|
||||
let x = Implementation(x: 10)
|
||||
let y = Implementation(x: 20)
|
||||
|
||||
let a = x.f1
|
||||
let b = x.f2
|
||||
let c = x.f1
|
||||
let d = y.f2
|
||||
let e = y.f3
|
||||
|
||||
a.f()
|
||||
d.f()
|
||||
e.f()
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ echo p2 is AbstractPointOfFloat # true
|
|||
echo p2.x is float and p2.y is float # true
|
||||
|
||||
# https://github.com/nim-lang/Nim/issues/2018
|
||||
type ProtocolFollower = generic
|
||||
type ProtocolFollower = concept
|
||||
true # not a particularly involved protocol
|
||||
|
||||
type ImplementorA = object
|
||||
|
|
|
|||
42
tests/concepts/trandom_vars.nim
Normal file
42
tests/concepts/trandom_vars.nim
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
discard """
|
||||
output: "11.0"
|
||||
"""
|
||||
|
||||
type
|
||||
# A random number generator
|
||||
Random = object
|
||||
random: proc(): float
|
||||
# A generic typeclass for a random var
|
||||
RandomVar[A] = concept x
|
||||
var rng: Random
|
||||
rng.sample(x) is A
|
||||
# A few concrete instances
|
||||
Uniform = object
|
||||
a, b: float
|
||||
ClosureVar[A] = object
|
||||
f: proc(rng: var Random): A
|
||||
|
||||
# How to sample from various concrete instances
|
||||
proc sample(rng: var Random, u: Uniform): float = u.a + (u.b - u.a) * rng.random()
|
||||
|
||||
proc sample[A](rng: var Random, c: ClosureVar[A]): A = c.f(rng)
|
||||
|
||||
proc uniform(a, b: float): Uniform = Uniform(a: a, b: b)
|
||||
|
||||
# How to lift a function on values to a function on random variables
|
||||
proc map[A, B](x: RandomVar[A], f: proc(a: A): B): ClosureVar[B] =
|
||||
proc inner(rng: var Random): B =
|
||||
f(rng.sample(x))
|
||||
|
||||
result.f = inner
|
||||
|
||||
import future
|
||||
|
||||
proc fakeRandom(): Random =
|
||||
result.random = () => 0.5
|
||||
|
||||
let x = uniform(1, 10).map((x: float) => 2 * x)
|
||||
|
||||
var rng = fakeRandom()
|
||||
|
||||
echo rng.sample(x)
|
||||
424
tests/cpp/tcovariancerules.nim
Normal file
424
tests/cpp/tcovariancerules.nim
Normal file
|
|
@ -0,0 +1,424 @@
|
|||
discard """
|
||||
cmd: "nim cpp $file"
|
||||
output: '''
|
||||
cat
|
||||
cat
|
||||
dog
|
||||
dog
|
||||
cat
|
||||
cat
|
||||
dog
|
||||
dog X
|
||||
cat
|
||||
cat
|
||||
dog
|
||||
dog
|
||||
dog value
|
||||
cat value
|
||||
dog value
|
||||
cat value
|
||||
dog
|
||||
dog
|
||||
dog value
|
||||
cat value
|
||||
dog 1
|
||||
dog 2
|
||||
'''
|
||||
"""
|
||||
|
||||
template accept(x) =
|
||||
static: assert(compiles(x))
|
||||
|
||||
template reject(x) =
|
||||
static: assert(not compiles(x))
|
||||
|
||||
import macros
|
||||
|
||||
macro skipElse(n: untyped): typed = n[0]
|
||||
|
||||
template acceptWithCovariance(x, otherwise): typed =
|
||||
when nimEnableCovariance:
|
||||
x
|
||||
else:
|
||||
reject(x)
|
||||
skipElse(otherwise)
|
||||
|
||||
type
|
||||
Animal = object of RootObj
|
||||
x: string
|
||||
|
||||
Dog = object of Animal
|
||||
y: int
|
||||
|
||||
Cat = object of Animal
|
||||
z: int
|
||||
|
||||
AnimalRef = ref Animal
|
||||
AnimalPtr = ptr Animal
|
||||
|
||||
RefAlias[T] = ref T
|
||||
|
||||
var dog = new(Dog)
|
||||
dog.x = "dog"
|
||||
|
||||
var cat = new(Cat)
|
||||
cat.x = "cat"
|
||||
|
||||
proc makeDerivedRef(x: string): ref Dog =
|
||||
new(result)
|
||||
result.x = x
|
||||
|
||||
proc makeDerived(x: string): Dog =
|
||||
result.x = x
|
||||
|
||||
var covariantSeq = @[makeDerivedRef("dog 1"), makeDerivedRef("dog 2")]
|
||||
var nonCovariantSeq = @[makeDerived("dog 1"), makeDerived("dog 2")]
|
||||
var covariantArr = [makeDerivedRef("dog 1"), makeDerivedRef("dog 2")]
|
||||
var nonCovariantArr = [makeDerived("dog 1"), makeDerived("dog 2")]
|
||||
|
||||
proc wantsCovariantSeq1(s: seq[ref Animal]) =
|
||||
for a in s: echo a.x
|
||||
|
||||
proc wantsCovariantSeq2(s: seq[AnimalRef]) =
|
||||
for a in s: echo a.x
|
||||
|
||||
proc wantsCovariantSeq3(s: seq[RefAlias[Animal]]) =
|
||||
for a in s: echo a.x
|
||||
|
||||
proc wantsCovariantOperArray(s: openarray[ref Animal]) =
|
||||
for a in s: echo a.x
|
||||
|
||||
proc modifiesCovariantOperArray(s: var openarray[ref Animal]) =
|
||||
for a in s: echo a.x
|
||||
|
||||
proc modifiesDerivedOperArray(s: var openarray[ref Dog]) =
|
||||
for a in s: echo a.x
|
||||
|
||||
proc wantsNonCovariantOperArray(s: openarray[Animal]) =
|
||||
for a in s: echo a.x
|
||||
|
||||
proc wantsCovariantArray(s: array[2, ref Animal]) =
|
||||
for a in s: echo a.x
|
||||
|
||||
proc wantsNonCovariantSeq(s: seq[Animal]) =
|
||||
for a in s: echo a.x
|
||||
|
||||
proc wantsNonCovariantArray(s: array[2, Animal]) =
|
||||
for a in s: echo a.x
|
||||
|
||||
proc modifiesCovariantSeq(s: var seq[ref Animal]) =
|
||||
for a in s: echo a.x
|
||||
|
||||
proc modifiesCovariantArray(s: var array[2, ref Animal]) =
|
||||
for a in s: echo a.x
|
||||
|
||||
proc modifiesCovariantSeq(s: ptr seq[ref Animal]) =
|
||||
for a in s[]: echo a.x
|
||||
|
||||
proc modifiesCovariantArray(s: ptr array[2, ref Animal]) =
|
||||
for a in s[]: echo a.x
|
||||
|
||||
proc modifiesDerivedSeq(s: var seq[ref Dog]) =
|
||||
for a in s: echo a.x
|
||||
|
||||
proc modifiesDerivedArray(s: var array[2, ref Dog]) =
|
||||
for a in s: echo a.x
|
||||
|
||||
proc modifiesDerivedSeq(s: ptr seq[ref Dog]) =
|
||||
for a in s[]: echo a.x
|
||||
|
||||
proc modifiesDerivedArray(s: ptr array[2, ref Dog]) =
|
||||
for a in s[]: echo a.x
|
||||
|
||||
accept:
|
||||
wantsCovariantArray([AnimalRef(dog), AnimalRef(dog)])
|
||||
wantsCovariantArray([AnimalRef(cat), AnimalRef(dog)])
|
||||
wantsCovariantArray([AnimalRef(cat), dog])
|
||||
|
||||
# there is a special rule that detects the base
|
||||
# type of polymorphic arrays
|
||||
wantsCovariantArray([cat, dog])
|
||||
|
||||
acceptWithCovariance:
|
||||
wantsCovariantArray([cat, cat])
|
||||
else:
|
||||
echo "cat"
|
||||
echo "cat"
|
||||
|
||||
var animalRefArray: array[2, ref Animal]
|
||||
|
||||
accept:
|
||||
animalRefArray = [AnimalRef(dog), AnimalRef(dog)]
|
||||
animalRefArray = [AnimalRef(cat), dog]
|
||||
|
||||
acceptWithCovariance:
|
||||
animalRefArray = [dog, dog]
|
||||
wantsCovariantArray animalRefArray
|
||||
else:
|
||||
echo "dog"
|
||||
echo "dog"
|
||||
|
||||
accept:
|
||||
var animal: AnimalRef = dog
|
||||
animal = cat
|
||||
|
||||
var vdog: Dog
|
||||
vdog.x = "dog value"
|
||||
var vcat: Cat
|
||||
vcat.x = "cat value"
|
||||
|
||||
reject:
|
||||
vcat = vdog
|
||||
|
||||
# XXX: The next two cases seem incosistent, perhaps we should change the rules
|
||||
accept:
|
||||
# truncating copies are allowed
|
||||
var vanimal: Animal = vdog
|
||||
vanimal = vdog
|
||||
|
||||
reject:
|
||||
# truncating copies are not allowed with arrays
|
||||
var vanimalArray: array[2, Animal]
|
||||
var vdogArray = [vdog, vdog]
|
||||
vanimalArray = vdogArray
|
||||
|
||||
accept:
|
||||
# a more explicit version of a truncating copy that
|
||||
# should probably always remain allowed
|
||||
var vnextnimal: Animal = Animal(vdog)
|
||||
|
||||
proc wantsRefSeq(x: seq[AnimalRef]) = discard
|
||||
|
||||
accept:
|
||||
wantsCovariantSeq1(@[AnimalRef(dog), AnimalRef(dog)])
|
||||
wantsCovariantSeq1(@[AnimalRef(cat), AnimalRef(dog)])
|
||||
wantsCovariantSeq1(@[AnimalRef(cat), dog])
|
||||
wantsCovariantSeq1(@[cat, dog])
|
||||
|
||||
wantsCovariantSeq2(@[AnimalRef(dog), AnimalRef(dog)])
|
||||
wantsCovariantSeq2(@[AnimalRef(cat), AnimalRef(dog)])
|
||||
wantsCovariantSeq2(@[AnimalRef(cat), dog])
|
||||
wantsCovariantSeq2(@[cat, dog])
|
||||
|
||||
wantsCovariantSeq3(@[AnimalRef(dog), AnimalRef(dog)])
|
||||
wantsCovariantSeq3(@[AnimalRef(cat), AnimalRef(dog)])
|
||||
wantsCovariantSeq3(@[AnimalRef(cat), dog])
|
||||
wantsCovariantSeq3(@[cat, dog])
|
||||
|
||||
wantsCovariantOperArray([cat, dog])
|
||||
|
||||
acceptWithCovariance:
|
||||
wantsCovariantSeq1(@[cat, cat])
|
||||
wantsCovariantSeq2(@[dog, makeDerivedRef("dog X")])
|
||||
# XXX: wantsCovariantSeq3(@[cat, cat])
|
||||
|
||||
wantsCovariantOperArray(@[cat, cat])
|
||||
wantsCovariantOperArray([dog, dog])
|
||||
else:
|
||||
echo "cat"
|
||||
echo "cat"
|
||||
echo "dog"
|
||||
echo "dog X"
|
||||
echo "cat"
|
||||
echo "cat"
|
||||
echo "dog"
|
||||
echo "dog"
|
||||
|
||||
var dogRefs = @[dog, dog]
|
||||
var dogRefsArray = [dog, dog]
|
||||
var animalRefs = @[dog, cat]
|
||||
|
||||
accept:
|
||||
modifiesDerivedArray(dogRefsArray)
|
||||
modifiesDerivedSeq(dogRefs)
|
||||
|
||||
reject modifiesCovariantSeq(dogRefs)
|
||||
reject modifiesCovariantSeq(addr(dogRefs))
|
||||
reject modifiesCovariantSeq(dogRefs.addr)
|
||||
|
||||
reject modifiesCovariantArray([dog, dog])
|
||||
reject modifiesCovariantArray(dogRefsArray)
|
||||
reject modifiesCovariantArray(addr(dogRefsArray))
|
||||
reject modifiesCovariantArray(dogRefsArray.addr)
|
||||
|
||||
var dogValues = @[vdog, vdog]
|
||||
var dogValuesArray = [vdog, vdog]
|
||||
var animalValues = @[Animal(vdog), Animal(vcat)]
|
||||
var animalValuesArray = [Animal(vdog), Animal(vcat)]
|
||||
|
||||
wantsNonCovariantSeq animalValues
|
||||
wantsNonCovariantArray animalValuesArray
|
||||
|
||||
reject wantsNonCovariantSeq(dogRefs)
|
||||
reject modifiesCovariantOperArray(dogRefs)
|
||||
reject wantsNonCovariantArray(dogRefsArray)
|
||||
reject wantsNonCovariantSeq(dogValues)
|
||||
reject wantsNonCovariantArray(dogValuesArray)
|
||||
reject modifiesValueArray()
|
||||
|
||||
modifiesDerivedOperArray dogRefs
|
||||
reject modifiesDerivedOperArray(dogValues)
|
||||
reject modifiesDerivedOperArray(animalRefs)
|
||||
|
||||
wantsNonCovariantOperArray animalValues
|
||||
reject wantsNonCovariantOperArray(animalRefs)
|
||||
reject wantsNonCovariantOperArray(dogRefs)
|
||||
reject wantsNonCovariantOperArray(dogValues)
|
||||
|
||||
var animalRefSeq: seq[ref Animal]
|
||||
|
||||
accept:
|
||||
animalRefSeq = @[AnimalRef(dog), AnimalRef(dog)]
|
||||
animalRefSeq = @[AnimalRef(cat), dog]
|
||||
|
||||
acceptWithCovariance:
|
||||
animalRefSeq = @[makeDerivedRef("dog 1"), makeDerivedRef("dog 2")]
|
||||
wantsCovariantSeq1(animalRefSeq)
|
||||
else:
|
||||
echo "dog 1"
|
||||
echo "dog 2"
|
||||
|
||||
var pdog: ptr Dog
|
||||
var pcat: ptr Cat
|
||||
|
||||
proc wantsPointer(x: ptr Animal) =
|
||||
discard
|
||||
|
||||
accept:
|
||||
wantsPointer pdog
|
||||
wantsPointer pcat
|
||||
|
||||
# covariance should be disabled when var is involved
|
||||
proc wantsVarPointer1(x: var ptr Animal) =
|
||||
discard
|
||||
|
||||
proc wantsVarPointer2(x: var AnimalPtr) =
|
||||
discard
|
||||
|
||||
reject wantsVarPointer1(pdog)
|
||||
reject wantsVarPointer2(pcat)
|
||||
|
||||
# covariance may be allowed for certain extern types
|
||||
|
||||
{.emit: """
|
||||
template <class T> struct FN { typedef void (*type)(T); };
|
||||
template <class T> struct ARR { typedef T DataType[2]; DataType data; };
|
||||
""".}
|
||||
|
||||
type
|
||||
MyPtr {.importcpp: "'0 *"} [out T] = object
|
||||
|
||||
MySeq {.importcpp: "ARR<'0>", nodecl} [out T] = object
|
||||
data: array[2, T]
|
||||
|
||||
MyAction {.importcpp: "FN<'0>::type"} [in T] = object
|
||||
|
||||
var
|
||||
cAnimal: MyPtr[Animal]
|
||||
cDog: MyPtr[Dog]
|
||||
cCat: MyPtr[Cat]
|
||||
|
||||
cAnimalFn: MyAction[Animal]
|
||||
cCatFn: MyAction[Cat]
|
||||
cDogFn: MyAction[Dog]
|
||||
|
||||
cRefAnimalFn: MyAction[ref Animal]
|
||||
cRefCatFn: MyAction[ref Cat]
|
||||
cRefDogFn: MyAction[ref Dog]
|
||||
|
||||
accept:
|
||||
cAnimal = cDog
|
||||
cAnimal = cCat
|
||||
|
||||
cDogFn = cAnimalFn
|
||||
cCatFn = cAnimalFn
|
||||
|
||||
cRefDogFn = cRefAnimalFn
|
||||
cRefCatFn = cRefAnimalFn
|
||||
|
||||
reject: cDogFn = cRefAnimalFn
|
||||
reject: cCatFn = cRefAnimalFn
|
||||
|
||||
reject: cCat = cDog
|
||||
reject: cAnimalFn = cDogFn
|
||||
reject: cAnimalFn = cCatFn
|
||||
reject: cRefAnimalFn = cRefDogFn
|
||||
reject: cRefAnimalFn = cRefCatFn
|
||||
reject: cRefAnimalFn = cDogFn
|
||||
|
||||
var
|
||||
ptrPtrDog: ptr ptr Dog
|
||||
ptrPtrAnimal: ptr ptr Animal
|
||||
|
||||
reject: ptrPtrDog = ptrPtrAnimal
|
||||
|
||||
# Try to break the rules by introducing some tricky
|
||||
# double indirection types:
|
||||
var
|
||||
cPtrRefAnimal: MyPtr[ref Animal]
|
||||
cPtrRefDog: MyPtr[ref Dog]
|
||||
|
||||
cPtrAliasRefAnimal: MyPtr[RefAlias[Animal]]
|
||||
cPtrAliasRefDog: MyPtr[RefAlias[Dog]]
|
||||
|
||||
cDoublePtrAnimal: MyPtr[MyPtr[Animal]]
|
||||
cDoublePtrDog: MyPtr[MyPtr[Dog]]
|
||||
|
||||
reject: cPtrRefAnimal = cPtrRefDog
|
||||
reject: cDoublePtrAnimal = cDoublePtrDog
|
||||
reject: cRefAliasPtrAnimal = cRefAliasPtrDog
|
||||
reject: cPtrRefAnimal = cRefAliasPtrDog
|
||||
reject: cPtrAliasRefAnimal = cPtrRefDog
|
||||
|
||||
var
|
||||
# Array and Sequence types are covariant only
|
||||
# when instantiated with ref or ptr types:
|
||||
cAnimals: MySeq[ref Animal]
|
||||
cDogs: MySeq[ref Dog]
|
||||
|
||||
# "User-defined" pointer types should be OK too:
|
||||
cAnimalPtrSeq: MySeq[MyPtr[Animal]]
|
||||
cDogPtrSeq: MySeq[MyPtr[Dog]]
|
||||
|
||||
# Value types shouldn't work:
|
||||
cAnimalValues: MySeq[Animal]
|
||||
cDogValues: MySeq[Dog]
|
||||
|
||||
# Double pointer types should not work either:
|
||||
cAnimalRefPtrSeq: MySeq[ref MyPtr[Animal]]
|
||||
cDogRefPtrSeq: MySeq[ref MyPtr[Dog]]
|
||||
cAnimalPtrPtrSeq: MySeq[ptr ptr Animal]
|
||||
cDogPtrPtrSeq: MySeq[ptr ptr Dog]
|
||||
|
||||
accept:
|
||||
cAnimals = cDogs
|
||||
cAnimalPtrSeq = cDogPtrSeq
|
||||
|
||||
reject: cAnimalValues = cDogValues
|
||||
reject: cAnimalRefPtrSeq = cDogRefPtrSeq
|
||||
reject: cAnimalPtrPtrSeq = cDogPtrPtrSeq
|
||||
|
||||
proc wantsAnimalSeq(x: MySeq[Animal]) = discard
|
||||
proc wantsAnimalRefSeq(x: MySeq[ref Animal]) = discard
|
||||
proc modifiesAnimalRefSeq(x: var MySeq[ref Animal]) = discard
|
||||
proc usesAddressOfAnimalRefSeq(x: ptr MySeq[ref Animal]) = discard
|
||||
|
||||
accept wantsAnimalSeq(cAnimalValues)
|
||||
reject wantsAnimalSeq(cDogValues)
|
||||
reject wantsAnimalSeq(cAnimals)
|
||||
|
||||
reject wantsAnimalRefSeq(cAnimalValues)
|
||||
reject wantsAnimalRefSeq(cDogValues)
|
||||
accept wantsAnimalRefSeq(cAnimals)
|
||||
accept wantsAnimalRefSeq(cDogs)
|
||||
|
||||
reject modifiesAnimalRefSeq(cAnimalValues)
|
||||
reject modifiesAnimalRefSeq(cDogValues)
|
||||
accept modifiesAnimalRefSeq(cAnimals)
|
||||
reject modifiesAnimalRefSeq(cDogs)
|
||||
|
||||
reject usesAddressOfAnimalRefSeq(addr cAnimalValues)
|
||||
reject usesAddressOfAnimalRefSeq(addr cDogValues)
|
||||
accept usesAddressOfAnimalRefSeq(addr cAnimals)
|
||||
reject usesAddressOfAnimalRefSeq(addr cDogs)
|
||||
|
||||
26
tests/errmsgs/tinvalidinout.nim
Normal file
26
tests/errmsgs/tinvalidinout.nim
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
discard """
|
||||
cmd: "nim check $file"
|
||||
errormsg: "The `in` modifier can be used only with imported types"
|
||||
nimout: '''
|
||||
tinvalidinout.nim(14, 7) Error: The `out` modifier can be used only with imported types
|
||||
tinvalidinout.nim(17, 9) Error: The `in` modifier can be used only with imported types
|
||||
tinvalidinout.nim(18, 9) Error: The `in` modifier can be used only with imported types
|
||||
'''
|
||||
"""
|
||||
|
||||
type
|
||||
Foo {.header: "foo.h", importcpp.} [in T] = object
|
||||
|
||||
Bar[out X] = object
|
||||
x: int
|
||||
|
||||
proc f1[in T](x: T) = discard
|
||||
proc f2[in T](x: T) {.importc: "f", header: "foo.h"}
|
||||
|
||||
var
|
||||
f: Foo[int]
|
||||
b: Bar[string]
|
||||
|
||||
f1 f
|
||||
f2 b
|
||||
|
||||
27
tests/generics/t5570.nim
Normal file
27
tests/generics/t5570.nim
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
discard """
|
||||
nimout: "type uint32\ntype uint32"
|
||||
output: "(weight: 17.0, color: 100)"
|
||||
"""
|
||||
|
||||
import macros
|
||||
|
||||
type
|
||||
BaseFruit[T] = object of RootObj
|
||||
color: T
|
||||
|
||||
Banana[T] = object of BaseFruit[uint32]
|
||||
weight: T
|
||||
|
||||
macro printTypeName(typ: typed): untyped =
|
||||
echo "type ", getType(typ).repr
|
||||
|
||||
proc setColor[K](self: var BaseFruit[K], c: int) =
|
||||
printTypeName(self.color)
|
||||
self.color = uint32(c)
|
||||
|
||||
var x: Banana[float64]
|
||||
x.weight = 17
|
||||
printTypeName(x.color)
|
||||
x.setColor(100)
|
||||
echo x
|
||||
|
||||
18
tests/generics/t5602_inheritence.nim
Normal file
18
tests/generics/t5602_inheritence.nim
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
discard """
|
||||
output: "seq[float]\n0"
|
||||
"""
|
||||
|
||||
# https://github.com/nim-lang/Nim/issues/5602
|
||||
|
||||
import typetraits
|
||||
|
||||
type
|
||||
Foo[T] = object of RootObj
|
||||
Bar[T] = object of Foo[seq[T]]
|
||||
|
||||
proc p[T](f: Foo[T]): T =
|
||||
echo T.name
|
||||
|
||||
var s: Bar[float]
|
||||
echo p(s).len # the bug was: p(s) should return seq[float], but returns float instead
|
||||
|
||||
30
tests/generics/t5643.nim
Normal file
30
tests/generics/t5643.nim
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
type
|
||||
Matrix*[M, N: static[int], T: SomeReal] = object
|
||||
data: ref array[N * M, T]
|
||||
|
||||
Matrix64*[M, N: static[int]] = Matrix[M, N, float64]
|
||||
|
||||
proc zeros64(M,N: static[int]): Matrix64[M,N] =
|
||||
new result.data
|
||||
for i in 0 .. < (M * N):
|
||||
result.data[i] = 0'f64
|
||||
|
||||
proc bar*[M,N: static[int], T](a: Matrix[M,N,T], b: Matrix[M,N,T]) =
|
||||
discard
|
||||
|
||||
let a = zeros64(2,2)
|
||||
bar(a,a)
|
||||
# https://github.com/nim-lang/Nim/issues/5643
|
||||
#
|
||||
# The test case was failing here, because the compiler failed to
|
||||
# detect the two matrix instantiations as the same type.
|
||||
#
|
||||
# The root cause was that the `T` type variable is a different
|
||||
# type after the first Matrix type has been matched.
|
||||
#
|
||||
# Sigmatch was failing to match the second version of `T`, but
|
||||
# due to some complex interplay between tyOr, tyTypeDesc and
|
||||
# tyGenericParam this was allowed to went through. The generic
|
||||
# instantiation of the second matrix was incomplete and the
|
||||
# generic cache lookup failed, producing two separate types.
|
||||
|
||||
31
tests/generics/t5683.nim
Normal file
31
tests/generics/t5683.nim
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
discard """
|
||||
output: "perm: 22 det: 22"
|
||||
"""
|
||||
|
||||
type Matrix[M,N: static[int]] = array[M, array[N, float]]
|
||||
|
||||
proc det[M,N](a: Matrix[M,N]): int = N*10 + M
|
||||
proc perm[M,N](a: Matrix[M,N]): int = M*10 + N
|
||||
|
||||
const
|
||||
a = [ [1.0, 2.0]
|
||||
, [3.0, 4.0]
|
||||
]
|
||||
|
||||
echo "perm: ", a.perm, " det: ", a.det
|
||||
|
||||
# This tests multiple instantiations of a generic
|
||||
# proc involving static params:
|
||||
type
|
||||
Vector64*[N: static[int]] = ref array[N, float64]
|
||||
Array64[N: static[int]] = array[N, float64]
|
||||
|
||||
proc vector*[N: static[int]](xs: Array64[N]): Vector64[N] =
|
||||
new result
|
||||
for i in 0 .. < N:
|
||||
result[i] = xs[i]
|
||||
|
||||
let v1 = vector([1.0, 2.0, 3.0, 4.0, 5.0])
|
||||
let v2 = vector([1.0, 2.0, 3.0, 4.0, 5.0])
|
||||
let v3 = vector([1.0, 2.0, 3.0, 4.0])
|
||||
|
||||
68
tests/generics/tbindoncevsbindmany.nim
Normal file
68
tests/generics/tbindoncevsbindmany.nim
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
template accept(x) =
|
||||
static: assert(compiles(x))
|
||||
|
||||
template reject(x) =
|
||||
static: assert(not compiles(x))
|
||||
|
||||
type
|
||||
ObjectWithNumber = concept obj
|
||||
obj.number is int
|
||||
|
||||
Foo[T] = object
|
||||
x: T
|
||||
|
||||
type A = object
|
||||
anumber: int
|
||||
|
||||
type B = object
|
||||
bnumber: int
|
||||
|
||||
proc number(a: A): int = a.anumber
|
||||
proc number(b: B): int = b.bnumber
|
||||
|
||||
proc notDistincConcept1(a: ObjectWithNumber, b: ObjectWithNumber) = discard
|
||||
proc notDistincConcept2(a, b: ObjectWithNumber) = discard
|
||||
proc distinctConcept1(a, b: distinct ObjectWithNumber) = discard
|
||||
proc distinctConcept2(a: ObjectWithNumber, b: distinct ObjectWithNumber) = discard
|
||||
proc distinctConcept3(a: distinct ObjectWithNumber, b: ObjectWithNumber) = discard
|
||||
proc distinctConcept4(a: distinct ObjectWithNumber, b: distinct ObjectWithNumber) = discard
|
||||
|
||||
var a = A(anumber: 5)
|
||||
var b = B(bnumber: 6)
|
||||
|
||||
accept notDistincConcept1(a, a)
|
||||
accept notDistincConcept1(b, b)
|
||||
reject notDistincConcept2(a, b)
|
||||
|
||||
accept notDistincConcept2(a, a)
|
||||
accept notDistincConcept2(b, b)
|
||||
reject notDistincConcept2(a, b)
|
||||
|
||||
accept distinctConcept1(a, b)
|
||||
accept distinctConcept2(a, b)
|
||||
accept distinctConcept3(a, b)
|
||||
accept distinctConcept4(a, b)
|
||||
|
||||
proc nonDistincGeneric1(a: Foo, b: Foo) = discard
|
||||
proc nonDistincGeneric2(a, b: Foo) = discard
|
||||
proc distinctGeneric1(a, b: distinct Foo) = discard
|
||||
proc distinctGeneric2(a: distinct Foo, b: Foo) = discard
|
||||
proc distinctGeneric3(a: Foo, b: distinct Foo) = discard
|
||||
proc distinctGeneric4(a: distinct Foo, b: distinct Foo) = discard
|
||||
|
||||
var f1 = Foo[int](x: 10)
|
||||
var f2 = Foo[string](x: "x")
|
||||
|
||||
accept nonDistincGeneric1(f1, f1)
|
||||
accept nonDistincGeneric1(f2, f2)
|
||||
reject nonDistincGeneric1(f1, f2)
|
||||
|
||||
accept nonDistincGeneric2(f1, f1)
|
||||
accept nonDistincGeneric2(f2, f2)
|
||||
reject nonDistincGeneric2(f1, f2)
|
||||
|
||||
accept distinctGeneric1(f1, f1)
|
||||
accept distinctGeneric2(f1, f1)
|
||||
accept distinctGeneric3(f1, f1)
|
||||
accept distinctGeneric4(f1, f1)
|
||||
|
||||
78
tests/generics/tfakecovariance.nim
Normal file
78
tests/generics/tfakecovariance.nim
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
template accept(x) =
|
||||
static: assert(compiles(x))
|
||||
|
||||
template reject(x) =
|
||||
static: assert(not compiles(x))
|
||||
|
||||
type
|
||||
BaseObj = object of RootObj
|
||||
DerivedObj = object of BaseObj
|
||||
NonDerivedObj = object
|
||||
|
||||
Container[T] = object
|
||||
|
||||
var base: BaseObj
|
||||
var derived: DerivedObj
|
||||
var nonDerived: NonDerivedObj
|
||||
|
||||
var baseContainer: Container[BaseObj]
|
||||
var derivedContainer: Container[DerivedObj]
|
||||
var nonDerivedContainer: Container[NonDerivedObj]
|
||||
|
||||
# We can fake covariance by listing some specific derived types that
|
||||
# will be allowed with our overload. This is not a real covariance,
|
||||
# because there will be multiple instantiations of the proc, but for
|
||||
# many purposes, it will suffice:
|
||||
|
||||
proc wantsSpecificContainers(c: Container[BaseObj or DerivedObj]) = discard
|
||||
|
||||
accept wantsSpecificContainers(baseContainer)
|
||||
accept wantsSpecificContainers(derivedContainer)
|
||||
|
||||
reject wantsSpecificContainers(nonDerivedContainer)
|
||||
reject wantsSpecificContainers(derived)
|
||||
|
||||
# Now, let's make a more general solution able to catch all derived types:
|
||||
|
||||
type
|
||||
DerivedFrom[T] = concept type D
|
||||
var derived: ref D
|
||||
var base: ref T = derived
|
||||
|
||||
proc wantsDerived(x: DerivedFrom[BaseObj]) = discard
|
||||
|
||||
accept wantsDerived(base)
|
||||
accept wantsDerived(derived)
|
||||
|
||||
reject wantsDerived(nonDerived)
|
||||
reject wantsDerived(baseContainer)
|
||||
|
||||
proc wantsDerivedContainer(c: Container[DerivedFrom[BaseObj]]) = discard
|
||||
|
||||
accept wantsDerivedContainer(baseContainer)
|
||||
accept wantsDerivedContainer(derivedContainer)
|
||||
|
||||
reject wantsDerivedContainer(nonDerivedContainer)
|
||||
|
||||
# The previous solutions were solving the problem for a single overload.
|
||||
# Let's solve it for multiple overloads by introducing a converter:
|
||||
|
||||
type
|
||||
OtherContainer[T] = object
|
||||
|
||||
proc wantsBaseContainer1(c: OtherContainer[BaseObj]) = discard
|
||||
proc wantsBaseContainer2(c: OtherContainer[BaseObj]) = discard
|
||||
|
||||
converter derivedToBase(c: OtherContainer[DerivedFrom[BaseObj]]): OtherContainer[BaseObj] = discard
|
||||
|
||||
block:
|
||||
var baseContainer: OtherContainer[BaseObj]
|
||||
var derivedContainer: OtherContainer[DerivedObj]
|
||||
var nonDerivedContainer: OtherContainer[NonDerivedObj]
|
||||
|
||||
accept wantsBaseContainer1(derivedContainer)
|
||||
reject wantsBaseContainer1(nonDerivedContainer)
|
||||
|
||||
accept wantsBaseContainer2(derivedContainer)
|
||||
reject wantsBaseContainer2(nonDerivedContainer)
|
||||
|
||||
39
tests/generics/tgenericconst.nim
Normal file
39
tests/generics/tgenericconst.nim
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
discard """
|
||||
output: '''
|
||||
@[1, 2]
|
||||
@[3, 4]
|
||||
1
|
||||
'''
|
||||
"""
|
||||
|
||||
# https://github.com/nim-lang/Nim/issues/5756
|
||||
|
||||
type
|
||||
Vec*[N : static[int]] = object
|
||||
x: int
|
||||
arr*: array[N, int32]
|
||||
|
||||
Mat*[M,N: static[int]] = object
|
||||
x: int
|
||||
arr*: array[M, Vec[N]]
|
||||
|
||||
proc vec2*(x,y:int32) : Vec[2] =
|
||||
result.arr = [x,y]
|
||||
result.x = 10
|
||||
|
||||
proc mat2*(a,b: Vec[2]): Mat[2,2] =
|
||||
result.arr = [a,b]
|
||||
result.x = 20
|
||||
|
||||
const M = mat2(vec2(1, 2), vec2(3, 4))
|
||||
|
||||
let m1 = M
|
||||
echo @(m1.arr[0].arr)
|
||||
echo @(m1.arr[1].arr)
|
||||
|
||||
proc foo =
|
||||
let m2 = M
|
||||
echo m1.arr[0].arr[0]
|
||||
|
||||
foo()
|
||||
|
||||
28
tests/generics/tmapping_generic_alias.nim
Normal file
28
tests/generics/tmapping_generic_alias.nim
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
discard """
|
||||
output: '''type(c) = GenAlias[system.int]
|
||||
T = int
|
||||
seq[int]
|
||||
'''
|
||||
"""
|
||||
|
||||
import typetraits
|
||||
|
||||
type
|
||||
Gen[T] = object
|
||||
x: T
|
||||
|
||||
GenAlias[T] = Gen[seq[T]]
|
||||
|
||||
proc f1[T](x: Gen[T]) =
|
||||
echo T.name
|
||||
|
||||
proc f2[T](x: GenAlias[T]) =
|
||||
echo "type(c) = ", type(x).name
|
||||
echo "T = ", T.name
|
||||
f1 x
|
||||
|
||||
let
|
||||
y = Gen[seq[int]](x: @[10])
|
||||
|
||||
f2 y
|
||||
|
||||
28
tests/generics/tparam_binding.nim
Normal file
28
tests/generics/tparam_binding.nim
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
discard """
|
||||
errormsg: "got (ref Matrix[2, 2, system.float], ref Matrix[2, 1, system.float])"
|
||||
line: 27
|
||||
"""
|
||||
|
||||
type
|
||||
Matrix[M,N: static[int]; T: SomeReal] = distinct array[0..(M*N - 1), T]
|
||||
|
||||
let a = new Matrix[2,2,float]
|
||||
let b = new Matrix[2,1,float]
|
||||
|
||||
proc foo[M,N: static[int],T](a: ref Matrix[M, N, T], b: ref Matrix[M, N, T])=
|
||||
discard
|
||||
|
||||
foo(a, a)
|
||||
|
||||
proc bar[M,N: static[int],T](a: ref Matrix[M, M, T], b: ref Matrix[M, N, T])=
|
||||
discard
|
||||
|
||||
bar(a, b)
|
||||
bar(a, a)
|
||||
|
||||
proc baz[M,N: static[int],T](a: ref Matrix[N, N, T], b: ref Matrix[M, N, T])=
|
||||
discard
|
||||
|
||||
baz(a, a)
|
||||
baz(a, b)
|
||||
|
||||
20
tests/generics/tptrinheritance.nim
Normal file
20
tests/generics/tptrinheritance.nim
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
type NSPasteboardItem* = ptr object
|
||||
type NSPasteboard* = ptr object
|
||||
type NSArrayAbstract = ptr object {.inheritable.}
|
||||
type NSMutableArrayAbstract = ptr object of NSArrayAbstract
|
||||
type NSArray*[T] = ptr object of NSArrayAbstract
|
||||
type NSMutableArray*[T] = ptr object of NSArray[T]
|
||||
|
||||
proc newMutableArrayAbstract*(): NSMutableArrayAbstract = discard
|
||||
|
||||
template newMutableArray*(T: typedesc): NSMutableArray[T] =
|
||||
cast[NSMutableArray[T]](newMutableArrayAbstract())
|
||||
|
||||
proc writeObjects*(p: NSPasteboard, o: NSArray[NSPasteboardItem]) = discard
|
||||
|
||||
let a = newMutableArray NSPasteboardItem
|
||||
var x: NSMutableArray[NSPasteboardItem]
|
||||
var y: NSArray[NSPasteboardItem] = x
|
||||
|
||||
writeObjects(nil, a)
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
discard """
|
||||
output: '''true
|
||||
output: '''
|
||||
true
|
||||
true
|
||||
true
|
||||
|
|
@ -14,10 +14,18 @@ true
|
|||
true
|
||||
true
|
||||
true
|
||||
true'''
|
||||
true
|
||||
true
|
||||
3
|
||||
2
|
||||
12
|
||||
Event { name: 'click: test' }
|
||||
Event { name: 'reloaded: test' }
|
||||
Event { name: 'updates: test' }
|
||||
'''
|
||||
"""
|
||||
|
||||
import macros, jsffi
|
||||
import macros, jsffi, jsconsole
|
||||
|
||||
# Tests for JsObject
|
||||
# Test JsObject []= and []
|
||||
|
|
@ -55,8 +63,8 @@ block:
|
|||
block:
|
||||
proc test(): bool =
|
||||
let obj = newJsObject()
|
||||
obj.`?!$` = proc(x, y, z: int, t: string): string = t & $(x + y + z)
|
||||
obj.`?!$`(1, 2, 3, "Result is: ").to(string) == "Result is: 6"
|
||||
obj.`?!$` = proc(x, y, z: int, t: cstring): cstring = t & $(x + y + z)
|
||||
obj.`?!$`(1, 2, 3, "Result is: ").to(cstring) == "Result is: 6"
|
||||
echo test()
|
||||
|
||||
# Test JsObject []()
|
||||
|
|
@ -265,3 +273,47 @@ block:
|
|||
let obj = TestObject(a: 9, onWhatever: bindMethod(handleWhatever))
|
||||
obj.onWhatever(1) == 10
|
||||
echo test()
|
||||
|
||||
block:
|
||||
{.emit: "function jsProc(n) { return n; }" .}
|
||||
proc jsProc(x: int32): JsObject {.importc: "jsProc".}
|
||||
|
||||
proc test() =
|
||||
var x = jsProc(1)
|
||||
var y = jsProc(2)
|
||||
console.log x + y
|
||||
console.log ++x
|
||||
|
||||
x += jsProc(10)
|
||||
console.log x
|
||||
|
||||
test()
|
||||
|
||||
import macros
|
||||
|
||||
block:
|
||||
{.emit:
|
||||
"""
|
||||
function Event(name) { this.name = name; }
|
||||
function on(eventName, eventHandler) { eventHandler(new Event(eventName + ": test")); }
|
||||
var jslib = { "on": on, "subscribe": on };
|
||||
"""
|
||||
.}
|
||||
|
||||
type Event = object
|
||||
name: cstring
|
||||
|
||||
proc on(event: cstring, handler: proc) {.importc: "on".}
|
||||
var jslib {.importc: "jslib", nodecl.}: JsObject
|
||||
|
||||
on("click") do (e: Event):
|
||||
console.log e
|
||||
|
||||
jslib.on "reloaded" do:
|
||||
console.log jsarguments[0]
|
||||
|
||||
# this test case is different from the above, because
|
||||
# `subscribe` is not overloaded in the current scope
|
||||
jslib.subscribe "updates":
|
||||
console.log jsarguments[0]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
import macros
|
||||
|
||||
macro match*(s: cstring|string; pos: int; sections: untyped): untyped =
|
||||
for sec in sections.children:
|
||||
macro match*(s: cstring|string; pos: int; sections: varargs[untyped]): untyped =
|
||||
for sec in sections:
|
||||
expectKind sec, nnkOfBranch
|
||||
expectLen sec, 2
|
||||
result = newStmtList()
|
||||
|
|
|
|||
513
tests/parser/tpostexprblocks.nim
Normal file
513
tests/parser/tpostexprblocks.nim
Normal file
|
|
@ -0,0 +1,513 @@
|
|||
discard """
|
||||
nimout: '''
|
||||
StmtList
|
||||
Ident !"foo"
|
||||
Call
|
||||
Ident !"foo"
|
||||
Call
|
||||
Ident !"foo"
|
||||
Ident !"x"
|
||||
Command
|
||||
Ident !"foo"
|
||||
Ident !"x"
|
||||
Call
|
||||
Ident !"foo"
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Call
|
||||
Ident !"foo"
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Call
|
||||
Ident !"foo"
|
||||
StrLit test
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Call
|
||||
Ident !"foo"
|
||||
StrLit test
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Command
|
||||
Ident !"foo"
|
||||
StrLit test
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Command
|
||||
Ident !"foo"
|
||||
StrLit test
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Command
|
||||
Ident !"foo"
|
||||
IntLit 1
|
||||
Par
|
||||
Infix
|
||||
Ident !"+"
|
||||
IntLit 2
|
||||
IntLit 3
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Command
|
||||
Ident !"foo"
|
||||
IntLit 1
|
||||
Par
|
||||
Infix
|
||||
Ident !"+"
|
||||
IntLit 2
|
||||
IntLit 3
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Call
|
||||
Ident !"foo"
|
||||
Do
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
FormalParams
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident !"x"
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Call
|
||||
Ident !"foo"
|
||||
Do
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
FormalParams
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident !"x"
|
||||
Ident !"int"
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Call
|
||||
Ident !"foo"
|
||||
Do
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
FormalParams
|
||||
Ident !"int"
|
||||
IdentDefs
|
||||
Ident !"x"
|
||||
Ident !"int"
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Command
|
||||
Ident !"foo"
|
||||
Ident !"x"
|
||||
Do
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
FormalParams
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident !"y"
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Call
|
||||
Ident !"foo"
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Else
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Call
|
||||
Ident !"foo"
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Else
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Command
|
||||
Ident !"foo"
|
||||
Ident !"x"
|
||||
Do
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
FormalParams
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident !"y"
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Do
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
FormalParams
|
||||
Ident !"int"
|
||||
IdentDefs
|
||||
Ident !"z"
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Do
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
FormalParams
|
||||
Ident !"int"
|
||||
IdentDefs
|
||||
Ident !"w"
|
||||
Ident !"int"
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Else
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Call
|
||||
Ident !"foo"
|
||||
Ident !"x"
|
||||
Call
|
||||
Ident !"bar"
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Else
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
VarSection
|
||||
IdentDefs
|
||||
Ident !"a"
|
||||
Empty
|
||||
Ident !"foo"
|
||||
VarSection
|
||||
IdentDefs
|
||||
Ident !"a"
|
||||
Empty
|
||||
Call
|
||||
Ident !"foo"
|
||||
VarSection
|
||||
IdentDefs
|
||||
Ident !"a"
|
||||
Empty
|
||||
Call
|
||||
Ident !"foo"
|
||||
Ident !"x"
|
||||
VarSection
|
||||
IdentDefs
|
||||
Ident !"a"
|
||||
Empty
|
||||
Command
|
||||
Ident !"foo"
|
||||
Ident !"x"
|
||||
VarSection
|
||||
IdentDefs
|
||||
Ident !"a"
|
||||
Empty
|
||||
Call
|
||||
Ident !"foo"
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
VarSection
|
||||
IdentDefs
|
||||
Ident !"a"
|
||||
Empty
|
||||
Call
|
||||
Ident !"foo"
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
VarSection
|
||||
IdentDefs
|
||||
Ident !"a"
|
||||
Empty
|
||||
Call
|
||||
Ident !"foo"
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Else
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
VarSection
|
||||
IdentDefs
|
||||
Ident !"a"
|
||||
Empty
|
||||
Command
|
||||
Ident !"foo"
|
||||
Ident !"x"
|
||||
Do
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
FormalParams
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident !"y"
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Else
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Asgn
|
||||
Ident !"a"
|
||||
Ident !"foo"
|
||||
Asgn
|
||||
Ident !"a"
|
||||
Call
|
||||
Ident !"foo"
|
||||
Asgn
|
||||
Ident !"a"
|
||||
Call
|
||||
Ident !"foo"
|
||||
Ident !"x"
|
||||
Asgn
|
||||
Ident !"a"
|
||||
Command
|
||||
Ident !"foo"
|
||||
Ident !"x"
|
||||
Asgn
|
||||
Ident !"a"
|
||||
Call
|
||||
Ident !"foo"
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Asgn
|
||||
Ident !"a"
|
||||
Call
|
||||
Ident !"foo"
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Asgn
|
||||
Ident !"a"
|
||||
Call
|
||||
Ident !"foo"
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Else
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Asgn
|
||||
Ident !"a"
|
||||
Command
|
||||
Ident !"foo"
|
||||
Ident !"x"
|
||||
Do
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
FormalParams
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident !"y"
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
Empty
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Else
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
Call
|
||||
DotExpr
|
||||
Ident !"result"
|
||||
Ident !"add"
|
||||
BracketExpr
|
||||
Call
|
||||
Ident !"quote"
|
||||
StmtList
|
||||
DiscardStmt
|
||||
Empty
|
||||
IntLit 0
|
||||
'''
|
||||
"""
|
||||
|
||||
import macros
|
||||
|
||||
dumpTree:
|
||||
# simple calls
|
||||
foo
|
||||
foo()
|
||||
foo(x)
|
||||
foo x
|
||||
|
||||
foo:
|
||||
discard
|
||||
|
||||
foo do:
|
||||
discard
|
||||
|
||||
foo("test"):
|
||||
discard
|
||||
|
||||
foo("test") do:
|
||||
discard
|
||||
|
||||
foo "test":
|
||||
discard
|
||||
|
||||
foo "test" do:
|
||||
discard
|
||||
|
||||
# more complicated calls
|
||||
foo 1, (2+3):
|
||||
discard
|
||||
|
||||
foo 1, (2+3) do:
|
||||
discard
|
||||
|
||||
foo do (x):
|
||||
discard
|
||||
|
||||
foo do (x: int):
|
||||
discard
|
||||
|
||||
foo do (x: int) -> int:
|
||||
discard
|
||||
|
||||
foo x do (y):
|
||||
discard
|
||||
|
||||
# extra blocks
|
||||
foo:
|
||||
discard
|
||||
else:
|
||||
discard
|
||||
|
||||
foo do:
|
||||
discard
|
||||
do:
|
||||
discard
|
||||
else:
|
||||
discard
|
||||
|
||||
foo x do (y):
|
||||
discard
|
||||
do (z) -> int:
|
||||
discard
|
||||
do (w: int) -> int:
|
||||
discard
|
||||
do:
|
||||
discard
|
||||
else:
|
||||
discard
|
||||
|
||||
# call with blocks as a param
|
||||
foo(x, bar do:
|
||||
discard
|
||||
else:
|
||||
discard
|
||||
)
|
||||
|
||||
# introduce a variable
|
||||
var a = foo
|
||||
var a = foo()
|
||||
var a = foo(x)
|
||||
var a = foo x
|
||||
|
||||
var a = foo:
|
||||
discard
|
||||
|
||||
var a = foo do:
|
||||
discard
|
||||
|
||||
var a = foo do:
|
||||
discard
|
||||
else:
|
||||
discard
|
||||
|
||||
var a = foo x do (y):
|
||||
discard
|
||||
else:
|
||||
discard
|
||||
|
||||
# assignments
|
||||
a = foo
|
||||
a = foo()
|
||||
a = foo(x)
|
||||
a = foo x
|
||||
|
||||
a = foo:
|
||||
discard
|
||||
|
||||
a = foo do:
|
||||
discard
|
||||
|
||||
a = foo do:
|
||||
discard
|
||||
else:
|
||||
discard
|
||||
|
||||
a = foo x do (y):
|
||||
discard
|
||||
else:
|
||||
discard
|
||||
|
||||
# some edge cases
|
||||
result.add((quote do:
|
||||
discard
|
||||
)[0])
|
||||
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
discard """
|
||||
output: '''{"age": 12, "bio": "\u042F Cletus", "blob": [65, 66, 67, 128], "name": "Cletus"}
|
||||
true
|
||||
true'''
|
||||
true
|
||||
alpha 100
|
||||
omega 200
|
||||
'''
|
||||
"""
|
||||
|
||||
import marshal
|
||||
|
|
@ -83,3 +86,22 @@ var instance1 = Person(name: "Cletus", age: 12,
|
|||
echo($$instance1)
|
||||
echo(to[Person]($$instance1).bio == instance1.bio)
|
||||
echo(to[Person]($$instance1).blob == instance1.blob)
|
||||
|
||||
# bug 5757
|
||||
|
||||
type
|
||||
Something = object
|
||||
x: string
|
||||
y: int
|
||||
|
||||
var data1 = """{"x": "alpha", "y": 100}"""
|
||||
var data2 = """{"x": "omega", "y": 200}"""
|
||||
|
||||
var r = to[Something](data1)
|
||||
|
||||
echo r.x, " ", r.y
|
||||
|
||||
r = to[Something](data2)
|
||||
|
||||
echo r.x, " ", r.y
|
||||
|
||||
|
|
|
|||
13
tests/template/tgenerictemplates.nim
Normal file
13
tests/template/tgenerictemplates.nim
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
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]()
|
||||
|
||||
|
|
@ -59,14 +59,13 @@ template wrap(body: typed): untyped =
|
|||
|
||||
macro makeProc(): typed =
|
||||
# Make a template tree
|
||||
result = (quote do:
|
||||
result = quote do:
|
||||
proc someProc* =
|
||||
wrap do:
|
||||
let x = 123
|
||||
# Implicit conversion here
|
||||
let s: string = x
|
||||
echo s
|
||||
)
|
||||
|
||||
makeProc()
|
||||
|
||||
|
|
|
|||
6
tests/types/t5640.nim
Normal file
6
tests/types/t5640.nim
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
type
|
||||
vecBase[I: static[int]] = distinct array[I, float32]
|
||||
vec2* = vecBase[2]
|
||||
|
||||
var v = vec2([0.0'f32, 0.0'f32])
|
||||
|
||||
21
tests/types/t5648.nim
Normal file
21
tests/types/t5648.nim
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
discard """
|
||||
output: "ptr Foo"
|
||||
"""
|
||||
|
||||
import typetraits
|
||||
|
||||
type Foo = object
|
||||
bar*: int
|
||||
|
||||
proc main() =
|
||||
var f = create(Foo)
|
||||
f.bar = 3
|
||||
echo f.type.name
|
||||
|
||||
discard realloc(f, 0)
|
||||
|
||||
var g = Foo()
|
||||
g.bar = 3
|
||||
|
||||
main()
|
||||
|
||||
22
tests/types/thard_tyforward.nim
Normal file
22
tests/types/thard_tyforward.nim
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
type
|
||||
Bar[T] = Foo[T, T]
|
||||
Baz[T] = proc (x: Foo[T, T])
|
||||
|
||||
GenericAlias[T] = Foo[T]
|
||||
GenericAlias2[T] = Foo[Baz[T]]
|
||||
|
||||
Concrete1 = Foo[int, float]
|
||||
Concrete2 = proc(x: proc(a: Foo[int, float]))
|
||||
|
||||
Foo[T, U] = object
|
||||
x: T
|
||||
y: U
|
||||
|
||||
var
|
||||
x1: Bar[float]
|
||||
x2: Baz[int]
|
||||
x3: Concrete1
|
||||
x4: Concrete2
|
||||
x5: GenericAlias[int]
|
||||
x6: GenericAlias2[string]
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue