Merge pull request #7681 from nim-lang/typedesc-reforms
Typedesc reforms
This commit is contained in:
commit
7cec5d1cfb
39 changed files with 1702 additions and 270 deletions
26
tests/concepts/libs/trie.nim
Normal file
26
tests/concepts/libs/trie.nim
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import
|
||||
hashes, tables, trie_database
|
||||
|
||||
type
|
||||
MemDBTable = Table[KeccakHash, string]
|
||||
|
||||
MemDB* = object
|
||||
tbl: MemDBTable
|
||||
|
||||
proc hash*(key: KeccakHash): int =
|
||||
hashes.hash(key.data)
|
||||
|
||||
proc get*(db: MemDB, key: KeccakHash): string =
|
||||
db.tbl[key]
|
||||
|
||||
proc del*(db: var MemDB, key: KeccakHash): bool =
|
||||
if db.tbl.hasKey(key):
|
||||
db.tbl.del(key)
|
||||
return true
|
||||
else:
|
||||
return false
|
||||
|
||||
proc put*(db: var MemDB, key: KeccakHash, value: string): bool =
|
||||
db.tbl[key] = value
|
||||
return true
|
||||
|
||||
12
tests/concepts/libs/trie_database.nim
Normal file
12
tests/concepts/libs/trie_database.nim
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
type
|
||||
KeccakHash* = object
|
||||
data*: string
|
||||
|
||||
BytesRange* = object
|
||||
bytes*: string
|
||||
|
||||
TrieDatabase* = concept db
|
||||
put(var db, KeccakHash, string) is bool
|
||||
del(var db, KeccakHash) is bool
|
||||
get(db, KeccakHash) is string
|
||||
|
||||
7
tests/concepts/ttrieconcept.nim
Normal file
7
tests/concepts/ttrieconcept.nim
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import libs/[trie_database, trie]
|
||||
|
||||
proc takeDb(d: TrieDatabase) = discard
|
||||
var mdb: MemDB
|
||||
|
||||
takeDb(mdb)
|
||||
|
||||
145
tests/generics/tlateboundgenericparams.nim
Normal file
145
tests/generics/tlateboundgenericparams.nim
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
discard """
|
||||
output: "1\n10\n1\n10"
|
||||
nimout: '''
|
||||
bar instantiated with 1
|
||||
bar instantiated with 10
|
||||
'''
|
||||
"""
|
||||
|
||||
import typetraits
|
||||
|
||||
type
|
||||
Foo = object
|
||||
|
||||
proc defaultFoo: Foo = discard
|
||||
proc defaultInt: int = 1
|
||||
proc defaultTInt(T: type): int = 2
|
||||
proc defaultTFoo[T](x: typedesc[T]): Foo = discard
|
||||
proc defaultTOldSchool[T](x: typedesc[T]): T = discard
|
||||
proc defaultTModern(T: type): T = discard
|
||||
|
||||
proc specializedDefault(T: type int): int = 10
|
||||
proc specializedDefault(T: type string): string = "default"
|
||||
|
||||
converter intFromFoo(x: Foo): int = 3
|
||||
|
||||
proc consumeInt(x: int) =
|
||||
discard
|
||||
|
||||
const activeTests = {1..100}
|
||||
|
||||
when true:
|
||||
template test(n, body) =
|
||||
when n in activeTests:
|
||||
block:
|
||||
body
|
||||
|
||||
template reject(x) =
|
||||
static: assert(not compiles(x))
|
||||
|
||||
test 1:
|
||||
proc t[T](val: T = defaultInt()) =
|
||||
consumeInt val
|
||||
|
||||
t[int]()
|
||||
reject t[string]()
|
||||
|
||||
test 2:
|
||||
proc t1[T](val: T = defaultFoo()) =
|
||||
static:
|
||||
assert type(val).name == "int"
|
||||
assert T.name == "int"
|
||||
|
||||
consumeInt val
|
||||
|
||||
# here, the converter should kick in, but notice
|
||||
# how `val` is still typed `int` inside the proc.
|
||||
t1[int]()
|
||||
|
||||
proc t2[T](val: T = defaultFoo()) =
|
||||
discard
|
||||
|
||||
reject t2[string]()
|
||||
|
||||
test 3:
|
||||
proc tInt[T](val = defaultInt()): string =
|
||||
return type(val).name
|
||||
|
||||
doAssert tInt[int]() == "int"
|
||||
doAssert tInt[string]() == "int"
|
||||
|
||||
proc tInt2[T](val = defaultTInt(T)): string =
|
||||
return type(val).name
|
||||
|
||||
doAssert tInt2[int]() == "int"
|
||||
doAssert tInt2[string]() == "int"
|
||||
|
||||
proc tDefTModern[T](val = defaultTModern(T)): string =
|
||||
return type(val).name
|
||||
|
||||
doAssert tDefTModern[int]() == "int"
|
||||
doAssert tDefTModern[string]() == "string"
|
||||
doAssert tDefTModern[Foo]() == "Foo"
|
||||
|
||||
proc tDefTOld[T](val = defaultTOldSchool(T)): string =
|
||||
return type(val).name
|
||||
|
||||
doAssert tDefTOld[int]() == "int"
|
||||
doAssert tDefTOld[string]() == "string"
|
||||
doAssert tDefTOld[Foo]() == "Foo"
|
||||
|
||||
test 4:
|
||||
proc t[T](val: T = defaultTFoo(T)): string =
|
||||
return type(val).name
|
||||
|
||||
doAssert t[int]() == "int"
|
||||
doAssert t[Foo]() == "Foo"
|
||||
reject t[string]()
|
||||
|
||||
test 5:
|
||||
proc t1[T](a: T = specializedDefault(T)): T =
|
||||
return a
|
||||
|
||||
doAssert t1[int]() == 10
|
||||
doAssert t1[string]() == "default"
|
||||
|
||||
proc t2[T](a: T, b = specializedDefault(T)): auto =
|
||||
return $a & $b
|
||||
|
||||
doAssert t2(5) == "510"
|
||||
doAssert t2("string ") == "string default"
|
||||
|
||||
proc t3[T](a: T, b = specializedDefault(type(a))): auto =
|
||||
return $a & $b
|
||||
|
||||
doAssert t3(100) == "10010"
|
||||
doAssert t3("another ") == "another default"
|
||||
|
||||
test 6:
|
||||
# https://github.com/nim-lang/Nim/issues/5595
|
||||
type
|
||||
Point[T] = object
|
||||
x, y: T
|
||||
|
||||
proc getOrigin[T](): Point[T] = Point[T](x: 0, y: 0)
|
||||
|
||||
proc rotate[T](point: Point[T], radians: float,
|
||||
origin = getOrigin[T]()): Point[T] =
|
||||
discard
|
||||
|
||||
var p = getOrigin[float]()
|
||||
var rotated = p.rotate(2.1)
|
||||
|
||||
test 7:
|
||||
proc bar(x: static[int]) =
|
||||
static: echo "bar instantiated with ", x
|
||||
echo x
|
||||
|
||||
proc foo(x: static[int] = 1) =
|
||||
bar(x)
|
||||
|
||||
foo()
|
||||
foo(10)
|
||||
foo(1)
|
||||
foo(10)
|
||||
|
||||
|
|
@ -4,7 +4,7 @@ discard """
|
|||
errormsg: "invalid indentation"
|
||||
"""
|
||||
|
||||
import strutils var s: seq[int] = @[0, 1, 2, 3, 4, 5, 6]
|
||||
import strutils let s: seq[int] = @[0, 1, 2, 3, 4, 5, 6]
|
||||
|
||||
#s[1..3] = @[]
|
||||
|
||||
|
|
|
|||
|
|
@ -5,15 +5,16 @@ type
|
|||
x: T
|
||||
y: U
|
||||
|
||||
proc getTypeName(t: typedesc): string = t.name
|
||||
proc getTypeName1(t: typedesc): string = t.name
|
||||
proc getTypeName2(t: type): string = t.name
|
||||
|
||||
proc foo(T: typedesc[float], a: auto): string =
|
||||
proc foo(T: type float, a: auto): string =
|
||||
result = "float " & $(a.len > 5)
|
||||
|
||||
proc foo(T: typedesc[TFoo], a: int): string =
|
||||
result = "TFoo " & $(a)
|
||||
|
||||
proc foo(T: typedesc[int or bool]): string =
|
||||
proc foo(T: type[int or bool]): string =
|
||||
var a: T
|
||||
a = 10
|
||||
result = "int or bool " & ($a)
|
||||
|
|
@ -23,8 +24,8 @@ template foo(T: typedesc[seq]): string = "seq"
|
|||
test "types can be used as proc params":
|
||||
# XXX: `check` needs to know that TFoo[int, float] is a type and
|
||||
# cannot be assigned for a local variable for later inspection
|
||||
check ((string.getTypeName == "string"))
|
||||
check ((getTypeName(int) == "int"))
|
||||
check ((string.getTypeName1 == "string"))
|
||||
check ((getTypeName2(int) == "int"))
|
||||
|
||||
check ((foo(TFoo[int, float], 1000) == "TFoo 1000"))
|
||||
|
||||
|
|
@ -37,6 +38,25 @@ test "types can be used as proc params":
|
|||
check ((foo(seq[int]) == "seq"))
|
||||
check ((foo(seq[TFoo[bool, string]]) == "seq"))
|
||||
|
||||
when false:
|
||||
proc foo(T: typedesc[seq], s: T) = nil
|
||||
template accept(x) =
|
||||
static: assert(compiles(x))
|
||||
|
||||
template reject(x) =
|
||||
static: assert(not compiles(x))
|
||||
|
||||
var
|
||||
si: seq[int]
|
||||
ss: seq[string]
|
||||
|
||||
proc foo(T: typedesc[seq], s: T) =
|
||||
discard
|
||||
|
||||
accept:
|
||||
foo seq[int], si
|
||||
|
||||
reject:
|
||||
foo seq[string], si
|
||||
|
||||
reject:
|
||||
foo seq[int], ss
|
||||
|
||||
|
|
|
|||
|
|
@ -34,3 +34,17 @@ when true:
|
|||
type Point[T] = tuple[x, y: T]
|
||||
proc origin(T: typedesc): Point[T] = discard
|
||||
discard origin(int)
|
||||
|
||||
# https://github.com/nim-lang/Nim/issues/7516
|
||||
import typetraits
|
||||
|
||||
proc hasDefault1(T: type = int): auto = return T.name
|
||||
doAssert hasDefault1(int) == "int"
|
||||
doAssert hasDefault1(string) == "string"
|
||||
doAssert hasDefault1() == "int"
|
||||
|
||||
proc hasDefault2(T = string): auto = return T.name
|
||||
doAssert hasDefault2(int) == "int"
|
||||
doAssert hasDefault2(string) == "string"
|
||||
doAssert hasDefault2() == "string"
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ type
|
|||
Base = object of RootObj
|
||||
Child = object of Base
|
||||
|
||||
proc pr(T: typedesc[Base]) = echo "proc " & T.name
|
||||
method me(T: typedesc[Base]) = echo "method " & T.name
|
||||
iterator it(T: typedesc[Base]): auto = yield "yield " & T.name
|
||||
proc pr(T: type[Base]) = echo "proc " & T.name
|
||||
method me(T: type[Base]) = echo "method " & T.name
|
||||
iterator it(T: type[Base]): auto = yield "yield " & T.name
|
||||
|
||||
Base.pr
|
||||
Child.pr
|
||||
|
|
|
|||
|
|
@ -5,16 +5,16 @@ output: "8\n8\n4"
|
|||
import
|
||||
macros, typetraits
|
||||
|
||||
template selectType(x: int): typeDesc =
|
||||
template selectType(x: int): type =
|
||||
when x < 10:
|
||||
int
|
||||
else:
|
||||
string
|
||||
|
||||
template simpleTypeTempl: typeDesc =
|
||||
template simpleTypeTempl: type =
|
||||
string
|
||||
|
||||
macro typeFromMacro: typedesc = string
|
||||
macro typeFromMacro: type = string
|
||||
|
||||
# The tests below check that the result variable of the
|
||||
# selected type matches the literal types in the code:
|
||||
|
|
|
|||
114
tests/misc/tparamsindefault.nim
Normal file
114
tests/misc/tparamsindefault.nim
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
discard """
|
||||
output: '''
|
||||
@[1, 2, 3]@[1, 2, 3]
|
||||
a
|
||||
a
|
||||
1
|
||||
3 is an int
|
||||
2 is an int
|
||||
miau is a string
|
||||
f1 1 1 1
|
||||
f1 2 3 3
|
||||
f1 10 20 30
|
||||
f2 100 100 100
|
||||
f2 200 300 300
|
||||
f2 300 400 400
|
||||
f3 10 10 20
|
||||
f3 10 15 25
|
||||
true true
|
||||
false true
|
||||
world
|
||||
'''
|
||||
"""
|
||||
|
||||
template reject(x) =
|
||||
assert(not compiles(x))
|
||||
|
||||
block:
|
||||
# https://github.com/nim-lang/Nim/issues/7756
|
||||
proc foo[T](x: seq[T], y: seq[T] = x) =
|
||||
echo x, y
|
||||
|
||||
let a = @[1, 2, 3]
|
||||
foo(a)
|
||||
|
||||
block:
|
||||
# https://github.com/nim-lang/Nim/issues/1201
|
||||
proc issue1201(x: char|int = 'a') = echo x
|
||||
|
||||
issue1201()
|
||||
issue1201('a')
|
||||
issue1201(1)
|
||||
|
||||
# https://github.com/nim-lang/Nim/issues/7000
|
||||
proc test(a: int|string = 2) =
|
||||
when a is int:
|
||||
echo a, " is an int"
|
||||
elif a is string:
|
||||
echo a, " is a string"
|
||||
|
||||
test(3) # works
|
||||
test() # works
|
||||
test("miau")
|
||||
|
||||
block:
|
||||
# https://github.com/nim-lang/Nim/issues/3002 and similar
|
||||
proc f1(a: int, b = a, c = b) =
|
||||
echo "f1 ", a, " ", b, " ", c
|
||||
|
||||
proc f2(a: int, b = a, c: int = b) =
|
||||
echo "f2 ", a, " ", b, " ", c
|
||||
|
||||
proc f3(a: int, b = a, c = a + b) =
|
||||
echo "f3 ", a, " ", b, " ", c
|
||||
|
||||
f1 1
|
||||
f1(2, 3)
|
||||
f1 10, 20, 30
|
||||
100.f2
|
||||
200.f2 300
|
||||
300.f2(400)
|
||||
|
||||
10.f3()
|
||||
10.f3(15)
|
||||
|
||||
reject:
|
||||
# This is a type mismatch error:
|
||||
proc f4(a: int, b = a, c: float = b) = discard
|
||||
|
||||
reject:
|
||||
# undeclared identifier
|
||||
proc f5(a: int, b = c, c = 10) = discard
|
||||
|
||||
reject:
|
||||
# undeclared identifier
|
||||
proc f6(a: int, b = b) = discard
|
||||
|
||||
reject:
|
||||
# undeclared identifier
|
||||
proc f7(a = a) = discard
|
||||
|
||||
block:
|
||||
proc f(a: var int, b: ptr int, c = addr(a)) =
|
||||
echo addr(a) == b, " ", b == c
|
||||
|
||||
var x = 10
|
||||
f(x, addr(x))
|
||||
f(x, nil, nil)
|
||||
|
||||
block:
|
||||
# https://github.com/nim-lang/Nim/issues/1046
|
||||
proc pySubstr(s: string, start: int, endd = s.len()): string =
|
||||
var
|
||||
revStart = start
|
||||
revEnd = endd
|
||||
|
||||
if start < 0:
|
||||
revStart = s.len() + start
|
||||
if endd < 0:
|
||||
revEnd = s.len() + endd
|
||||
|
||||
return s[revStart .. revEnd-1]
|
||||
|
||||
echo pySubstr("Hello world", -5)
|
||||
|
||||
|
|
@ -1,17 +1,42 @@
|
|||
discard """
|
||||
action: run
|
||||
"""
|
||||
|
||||
type
|
||||
R = ref
|
||||
V = var
|
||||
D = distinct
|
||||
P = ptr
|
||||
T = type
|
||||
S = static
|
||||
OBJ = object
|
||||
TPL = tuple
|
||||
SEQ = seq
|
||||
|
||||
var i: int
|
||||
var x: ref int
|
||||
var y: distinct int
|
||||
var z: ptr int
|
||||
const C = @[1, 2, 3]
|
||||
|
||||
static:
|
||||
assert x is ref
|
||||
assert y is distinct
|
||||
assert z is ptr
|
||||
assert C is static
|
||||
assert C[1] is static[int]
|
||||
assert C[0] is static[SomeInteger]
|
||||
assert C isnot static[string]
|
||||
assert C is SEQ|OBJ
|
||||
assert C isnot OBJ|TPL
|
||||
assert int is int
|
||||
assert int is T
|
||||
assert int is SomeInteger
|
||||
assert seq[int] is type
|
||||
assert seq[int] is type[seq]
|
||||
assert seq[int] isnot type[seq[float]]
|
||||
assert i isnot type[int]
|
||||
assert type(i) is type[int]
|
||||
assert x isnot T
|
||||
assert y isnot S
|
||||
assert z isnot enum
|
||||
assert x isnot object
|
||||
assert y isnot tuple
|
||||
assert z isnot seq
|
||||
|
||||
doAssert x is ref
|
||||
doAssert y is distinct
|
||||
doAssert z is ptr
|
||||
527
tests/parser/ttypemodifiers.nim
Normal file
527
tests/parser/ttypemodifiers.nim
Normal file
|
|
@ -0,0 +1,527 @@
|
|||
discard """
|
||||
nimout: '''
|
||||
StmtList
|
||||
TypeSection
|
||||
TypeDef
|
||||
Ident "BarePtr"
|
||||
Empty
|
||||
PtrTy
|
||||
TypeDef
|
||||
Ident "GenericPtr"
|
||||
Empty
|
||||
PtrTy
|
||||
Bracket
|
||||
Ident "int"
|
||||
TypeDef
|
||||
Ident "PrefixPtr"
|
||||
Empty
|
||||
PtrTy
|
||||
Ident "int"
|
||||
TypeDef
|
||||
Ident "PtrTuple"
|
||||
Empty
|
||||
PtrTy
|
||||
Par
|
||||
Ident "int"
|
||||
Ident "string"
|
||||
TypeDef
|
||||
Ident "BareRef"
|
||||
Empty
|
||||
RefTy
|
||||
TypeDef
|
||||
Ident "GenericRef"
|
||||
Empty
|
||||
RefTy
|
||||
Bracket
|
||||
Ident "int"
|
||||
TypeDef
|
||||
Ident "RefTupleCl"
|
||||
Empty
|
||||
RefTy
|
||||
TupleTy
|
||||
TypeDef
|
||||
Ident "RefTupleType"
|
||||
Empty
|
||||
RefTy
|
||||
Par
|
||||
Ident "int"
|
||||
Ident "string"
|
||||
TypeDef
|
||||
Ident "RefTupleVars"
|
||||
Empty
|
||||
RefTy
|
||||
Par
|
||||
Ident "a"
|
||||
Ident "b"
|
||||
TypeDef
|
||||
Ident "BareStatic"
|
||||
Empty
|
||||
Ident "static"
|
||||
TypeDef
|
||||
Ident "GenericStatic"
|
||||
Empty
|
||||
BracketExpr
|
||||
Ident "static"
|
||||
Ident "int"
|
||||
TypeDef
|
||||
Ident "PrefixStatic"
|
||||
Empty
|
||||
Command
|
||||
Ident "static"
|
||||
Ident "int"
|
||||
TypeDef
|
||||
Ident "StaticTupleCl"
|
||||
Empty
|
||||
Command
|
||||
Ident "static"
|
||||
TupleClassTy
|
||||
TypeDef
|
||||
Ident "StaticTuple"
|
||||
Empty
|
||||
Command
|
||||
Ident "static"
|
||||
Par
|
||||
Ident "int"
|
||||
Ident "string"
|
||||
TypeDef
|
||||
Ident "BareType"
|
||||
Empty
|
||||
Ident "type"
|
||||
TypeDef
|
||||
Ident "GenericType"
|
||||
Empty
|
||||
BracketExpr
|
||||
Ident "type"
|
||||
Ident "float"
|
||||
TypeDef
|
||||
Ident "TypeTupleGen"
|
||||
Empty
|
||||
BracketExpr
|
||||
Ident "type"
|
||||
TupleClassTy
|
||||
TypeDef
|
||||
Ident "TypeTupleCl"
|
||||
Empty
|
||||
Command
|
||||
Ident "type"
|
||||
TupleClassTy
|
||||
TypeDef
|
||||
Ident "TypeInstance"
|
||||
Empty
|
||||
Command
|
||||
Ident "type"
|
||||
BracketExpr
|
||||
Ident "Foo"
|
||||
RefTy
|
||||
TypeDef
|
||||
Ident "bareTypeDesc"
|
||||
Empty
|
||||
Ident "typedesc"
|
||||
TypeDef
|
||||
Ident "TypeOfVar"
|
||||
Empty
|
||||
Call
|
||||
Ident "type"
|
||||
Ident "a"
|
||||
TypeDef
|
||||
Ident "TypeOfVarAlt"
|
||||
Empty
|
||||
Command
|
||||
Ident "type"
|
||||
Par
|
||||
Ident "a"
|
||||
TypeDef
|
||||
Ident "TypeOfTuple1"
|
||||
Empty
|
||||
Call
|
||||
Ident "type"
|
||||
Ident "a"
|
||||
TypeDef
|
||||
Ident "TypeOfTuple2"
|
||||
Empty
|
||||
Call
|
||||
Ident "type"
|
||||
Ident "a"
|
||||
Ident "b"
|
||||
TypeDef
|
||||
Ident "TypeOfTuple1A"
|
||||
Empty
|
||||
Command
|
||||
Ident "type"
|
||||
TupleConstr
|
||||
Ident "a"
|
||||
TypeDef
|
||||
Ident "TypeOfTuple2A"
|
||||
Empty
|
||||
Command
|
||||
Ident "type"
|
||||
Par
|
||||
Ident "a"
|
||||
Ident "b"
|
||||
TypeDef
|
||||
Ident "TypeTuple"
|
||||
Empty
|
||||
Command
|
||||
Ident "type"
|
||||
Par
|
||||
Ident "int"
|
||||
Ident "string"
|
||||
TypeDef
|
||||
Ident "GenericTypedesc"
|
||||
Empty
|
||||
BracketExpr
|
||||
Ident "typedesc"
|
||||
Ident "int"
|
||||
TypeDef
|
||||
Ident "T"
|
||||
Empty
|
||||
Ident "type"
|
||||
ProcDef
|
||||
Ident "foo"
|
||||
Empty
|
||||
Empty
|
||||
FormalParams
|
||||
Ident "type"
|
||||
IdentDefs
|
||||
Ident "bareType"
|
||||
Ident "type"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "genType"
|
||||
BracketExpr
|
||||
Ident "type"
|
||||
Ident "int"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "typeInt"
|
||||
Command
|
||||
Ident "type"
|
||||
Ident "int"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "typeIntAlt"
|
||||
Call
|
||||
Ident "type"
|
||||
Ident "int"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "typeOfVar"
|
||||
Call
|
||||
Ident "type"
|
||||
Ident "a"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "typeDotType"
|
||||
DotExpr
|
||||
Ident "foo"
|
||||
Ident "type"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "typeTupleCl"
|
||||
Command
|
||||
Ident "type"
|
||||
TupleClassTy
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "bareStatic"
|
||||
Ident "static"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "genStatic"
|
||||
BracketExpr
|
||||
Ident "static"
|
||||
Ident "int"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "staticInt"
|
||||
Command
|
||||
Ident "static"
|
||||
Ident "int"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "staticVal1"
|
||||
Command
|
||||
Ident "static"
|
||||
IntLit 10
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "staticVal2"
|
||||
Call
|
||||
Ident "static"
|
||||
StrLit "str"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "staticVal3"
|
||||
Command
|
||||
Ident "static"
|
||||
StrLit "str"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "staticVal4"
|
||||
CallStrLit
|
||||
Ident "static"
|
||||
RStrLit "str"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "staticDotVal"
|
||||
DotExpr
|
||||
IntLit 10
|
||||
Ident "static"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "bareRef"
|
||||
RefTy
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "refTuple1"
|
||||
RefTy
|
||||
Par
|
||||
Ident "int"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "refTuple1A"
|
||||
RefTy
|
||||
TupleConstr
|
||||
Ident "int"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "refTuple2"
|
||||
RefTy
|
||||
Par
|
||||
Ident "int"
|
||||
Ident "string"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "genRef"
|
||||
RefTy
|
||||
Bracket
|
||||
Ident "int"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "refInt"
|
||||
RefTy
|
||||
Ident "int"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "refCall"
|
||||
RefTy
|
||||
Par
|
||||
Ident "a"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "macroCall1"
|
||||
Command
|
||||
Ident "foo"
|
||||
Ident "bar"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "macroCall2"
|
||||
Call
|
||||
Ident "foo"
|
||||
Ident "bar"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "macroCall3"
|
||||
Call
|
||||
DotExpr
|
||||
Ident "foo"
|
||||
Ident "bar"
|
||||
Ident "baz"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "macroCall4"
|
||||
Call
|
||||
BracketExpr
|
||||
Ident "foo"
|
||||
Ident "bar"
|
||||
Ident "baz"
|
||||
Empty
|
||||
IdentDefs
|
||||
Ident "macroCall5"
|
||||
Command
|
||||
Ident "foo"
|
||||
Command
|
||||
Ident "bar"
|
||||
Ident "baz"
|
||||
IntLit 10
|
||||
Empty
|
||||
Empty
|
||||
StmtList
|
||||
Asgn
|
||||
Ident "staticTen"
|
||||
Command
|
||||
Ident "static"
|
||||
IntLit 10
|
||||
Asgn
|
||||
Ident "staticA"
|
||||
Call
|
||||
Ident "static"
|
||||
Ident "a"
|
||||
Asgn
|
||||
Ident "staticCall"
|
||||
Command
|
||||
Ident "static"
|
||||
Call
|
||||
Ident "foo"
|
||||
IntLit 1
|
||||
Asgn
|
||||
Ident "staticStrCall"
|
||||
Command
|
||||
Ident "static"
|
||||
CallStrLit
|
||||
Ident "foo"
|
||||
RStrLit "x"
|
||||
Asgn
|
||||
Ident "staticChainCall"
|
||||
Command
|
||||
Ident "static"
|
||||
Command
|
||||
Ident "foo"
|
||||
Ident "bar"
|
||||
Asgn
|
||||
Ident "typeTen"
|
||||
Command
|
||||
Ident "type"
|
||||
IntLit 10
|
||||
Asgn
|
||||
Ident "typeA"
|
||||
Call
|
||||
Ident "type"
|
||||
Ident "a"
|
||||
Asgn
|
||||
Ident "typeCall"
|
||||
Command
|
||||
Ident "type"
|
||||
Call
|
||||
Ident "foo"
|
||||
IntLit 1
|
||||
Asgn
|
||||
Ident "typeStrCall"
|
||||
Command
|
||||
Ident "type"
|
||||
CallStrLit
|
||||
Ident "foo"
|
||||
RStrLit "x"
|
||||
Asgn
|
||||
Ident "typeChainCall"
|
||||
Command
|
||||
Ident "type"
|
||||
Command
|
||||
Ident "foo"
|
||||
Ident "bar"
|
||||
Asgn
|
||||
Ident "normalChainCall"
|
||||
Command
|
||||
Ident "foo"
|
||||
Command
|
||||
Ident "bar"
|
||||
Ident "baz"
|
||||
Asgn
|
||||
Ident "normalTupleCall2"
|
||||
Call
|
||||
Ident "foo"
|
||||
Ident "a"
|
||||
Ident "b"
|
||||
StaticStmt
|
||||
StmtList
|
||||
Ident "singleStaticStmt"
|
||||
StaticStmt
|
||||
StmtList
|
||||
Ident "staticStmtList1"
|
||||
Ident "staticStmtList2"
|
||||
'''
|
||||
"""
|
||||
|
||||
import macros
|
||||
|
||||
dumpTree:
|
||||
type
|
||||
BarePtr = ptr
|
||||
GenericPtr = ptr[int]
|
||||
PrefixPtr = ptr int
|
||||
PtrTuple = ptr (int, string)
|
||||
BareRef = ref
|
||||
GenericRef = ref[int]
|
||||
RefTupleCl = ref tuple
|
||||
RefTupleType = ref (int, string)
|
||||
RefTupleVars = ref (a, b)
|
||||
BareStatic = static # Used to be Error: invalid indentation
|
||||
GenericStatic = static[int]
|
||||
PrefixStatic = static int
|
||||
StaticTupleCl = static tuple
|
||||
StaticTuple = static (int, string)
|
||||
BareType = type
|
||||
GenericType = type[float]
|
||||
TypeTupleGen = type[tuple]
|
||||
TypeTupleCl = type tuple # Used to be Error: invalid indentation
|
||||
TypeInstance = type Foo[ref]
|
||||
bareTypeDesc = typedesc
|
||||
TypeOfVar = type(a)
|
||||
TypeOfVarAlt = type (a) # Used to be Error: invalid indentation
|
||||
TypeOfTuple1 = type(a,)
|
||||
TypeOfTuple2 = type(a,b)
|
||||
TypeOfTuple1A = type (a,) # Used to be Error: invalid indentation
|
||||
TypeOfTuple2A = type (a,b) # Used to be Error: invalid indentation
|
||||
TypeTuple = type (int, string) # Used to be Error: invalid indentation
|
||||
GenericTypedesc = typedesc[int]
|
||||
T = type
|
||||
|
||||
proc foo(
|
||||
bareType : type,
|
||||
genType : type[int],
|
||||
typeInt : type int,
|
||||
typeIntAlt : type(int),
|
||||
typeOfVar : type(a),
|
||||
typeDotType : foo.type,
|
||||
typeTupleCl : type tuple, # Used to be Error: ')' expected
|
||||
bareStatic : static, # Used to be Error: expression expected, but found ','
|
||||
genStatic : static[int],
|
||||
staticInt : static int,
|
||||
staticVal1 : static 10,
|
||||
staticVal2 : static("str"),
|
||||
staticVal3 : static "str",
|
||||
staticVal4 : static"str", # Used to be Error: expression expected, but found 'str'
|
||||
staticDotVal : 10.static,
|
||||
bareRef : ref,
|
||||
refTuple1 : ref (int),
|
||||
refTuple1A : ref (int,),
|
||||
refTuple2 : ref (int,string),
|
||||
genRef : ref[int],
|
||||
refInt : ref int,
|
||||
refCall : ref(a),
|
||||
macroCall1 : foo bar,
|
||||
macroCall2 : foo(bar),
|
||||
macroCall3 : foo.bar(baz),
|
||||
macroCall4 : foo[bar](baz),
|
||||
macroCall5 : foo bar baz = 10
|
||||
): type =
|
||||
staticTen = static 10
|
||||
staticA = static(a)
|
||||
# staticAspace = static (a) # With newTypedesc: Error: invalid indentation
|
||||
# staticAtuple = static (a,) # With newTypedesc: Error: invalid indentation
|
||||
# staticTuple = static (a,b) # With newTypedesc: Error: invalid indentation
|
||||
# staticTypeTuple = static (int,string) # With newTypedesc: Error: invalid indentation
|
||||
staticCall = static foo(1)
|
||||
staticStrCall = static foo"x"
|
||||
staticChainCall = static foo bar
|
||||
|
||||
typeTen = type 10
|
||||
typeA = type(a)
|
||||
# typeAspace = type (a) # Error: invalid indentation
|
||||
# typeAtuple = type (a,) # Error: invalid indentation
|
||||
# typeTuple = type (a,b) # Error: invalid indentation
|
||||
# typeTypeTuple = type (int,string) # Error: invalid indentation
|
||||
typeCall = type foo(1)
|
||||
typeStrCall = type foo"x"
|
||||
typeChainCall = type foo bar
|
||||
|
||||
normalChainCall = foo bar baz
|
||||
# normalTupleCall1 = foo(a,) # Error: invalid indentation
|
||||
normalTupleCall2 = foo(a,b)
|
||||
# normalTupleCall3 = foo (a,b) # Error: invalid indentation
|
||||
|
||||
static: singleStaticStmt
|
||||
static:
|
||||
staticStmtList1
|
||||
staticStmtList2
|
||||
|
||||
109
tests/statictypes/tstatictypes.nim
Normal file
109
tests/statictypes/tstatictypes.nim
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
discard """
|
||||
nimout: '''
|
||||
staticAlialProc instantiated with 358
|
||||
staticAlialProc instantiated with 368
|
||||
'''
|
||||
output: '''
|
||||
16
|
||||
16
|
||||
b is 2 times a
|
||||
17
|
||||
'''
|
||||
"""
|
||||
|
||||
import macros
|
||||
|
||||
template ok(x) = assert(x)
|
||||
template no(x) = assert(not x)
|
||||
|
||||
template accept(x) =
|
||||
static: assert(compiles(x))
|
||||
|
||||
template reject(x) =
|
||||
static: assert(not compiles(x))
|
||||
|
||||
proc plus(a, b: int): int = a + b
|
||||
|
||||
template isStatic(x: static): bool = true
|
||||
template isStatic(x: auto): bool = false
|
||||
|
||||
var v = 1
|
||||
|
||||
when true:
|
||||
# test that `isStatic` works as expected
|
||||
const C = 2
|
||||
|
||||
static:
|
||||
ok C.isStatic
|
||||
ok isStatic(plus(1, 2))
|
||||
ok plus(C, 2).isStatic
|
||||
|
||||
no isStatic(v)
|
||||
no plus(1, v).isStatic
|
||||
|
||||
when true:
|
||||
# test that proc instantiation works as expected
|
||||
type
|
||||
StaticTypeAlias = static[int]
|
||||
|
||||
proc staticAliasProc(a: StaticTypeAlias,
|
||||
b: static[int],
|
||||
c: static int) =
|
||||
static:
|
||||
assert a.isStatic and b.isStatic and c.isStatic
|
||||
assert isStatic(a + plus(b, c))
|
||||
echo "staticAlialProc instantiated with ", a, b, c
|
||||
|
||||
when b mod a == 0:
|
||||
echo "b is ", b div a, " times a"
|
||||
|
||||
echo a + b + c
|
||||
|
||||
staticAliasProc 1+2, 5, 8
|
||||
staticAliasProc 3, 2+3, 9-1
|
||||
staticAliasProc 3, 3+3, 4+4
|
||||
|
||||
when true:
|
||||
# test static coercions. normal cases that should work:
|
||||
accept:
|
||||
var s1 = static[int] plus(1, 2)
|
||||
var s2 = static(plus(1,2))
|
||||
var s3 = static plus(1,2)
|
||||
var s4 = static[SomeInteger](1 + 2)
|
||||
|
||||
# the sub-script operator can be used only with types:
|
||||
reject:
|
||||
var just_static3 = static[plus(1,2)]
|
||||
|
||||
# static coercion takes into account the type:
|
||||
reject:
|
||||
var x = static[string](plus(1, 2))
|
||||
reject:
|
||||
var x = static[string] plus(1, 2)
|
||||
reject:
|
||||
var x = static[SomeFloat] plus(3, 4)
|
||||
|
||||
# you cannot coerce a run-time variable
|
||||
reject:
|
||||
var x = static(v)
|
||||
|
||||
when true:
|
||||
type
|
||||
ArrayWrapper1[S: static int] = object
|
||||
data: array[S + 1, int]
|
||||
|
||||
ArrayWrapper2[S: static[int]] = object
|
||||
data: array[S.plus(2), int]
|
||||
|
||||
ArrayWrapper3[S: static[(int, string)]] = object
|
||||
data: array[S[0], int]
|
||||
|
||||
var aw1: ArrayWrapper1[5]
|
||||
var aw2: ArrayWrapper2[5]
|
||||
var aw3: ArrayWrapper3[(10, "str")]
|
||||
|
||||
static:
|
||||
assert aw1.data.high == 5
|
||||
assert aw2.data.high == 6
|
||||
assert aw3.data.high == 9
|
||||
|
||||
|
|
@ -5,7 +5,7 @@ false
|
|||
false
|
||||
true
|
||||
true
|
||||
no'''
|
||||
yes'''
|
||||
"""
|
||||
|
||||
proc IsVoid[T](): string =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue