Merge branch 'devel' of https://github.com/Araq/Nimrod into devel
This commit is contained in:
commit
51ee524109
55 changed files with 1559 additions and 931 deletions
6
tests/compile/compilehelpers.nim
Normal file
6
tests/compile/compilehelpers.nim
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
template accept(e: expr) =
|
||||
static: assert(compiles(e))
|
||||
|
||||
template reject(e: expr) =
|
||||
static: assert(not compiles(e))
|
||||
|
||||
|
|
@ -16,10 +16,10 @@ type
|
|||
TBar = tuple
|
||||
x, y: int
|
||||
|
||||
template good(e: expr) =
|
||||
template accept(e: expr) =
|
||||
static: assert(compiles(e))
|
||||
|
||||
template bad(e: expr) =
|
||||
template reject(e: expr) =
|
||||
static: assert(not compiles(e))
|
||||
|
||||
proc genericParamRepeated[T: typedesc](a: T, b: T) =
|
||||
|
|
@ -27,22 +27,22 @@ proc genericParamRepeated[T: typedesc](a: T, b: T) =
|
|||
echo a.name
|
||||
echo b.name
|
||||
|
||||
good(genericParamRepeated(int, int))
|
||||
good(genericParamRepeated(float, float))
|
||||
accept genericParamRepeated(int, int)
|
||||
accept genericParamRepeated(float, float)
|
||||
|
||||
bad(genericParamRepeated(string, int))
|
||||
bad(genericParamRepeated(int, float))
|
||||
reject genericParamRepeated(string, int)
|
||||
reject genericParamRepeated(int, float)
|
||||
|
||||
proc genericParamOnce[T: typedesc](a, b: T) =
|
||||
static:
|
||||
echo a.name
|
||||
echo b.name
|
||||
|
||||
good(genericParamOnce(int, int))
|
||||
good(genericParamOnce(TFoo, TFoo))
|
||||
accept genericParamOnce(int, int)
|
||||
accept genericParamOnce(TFoo, TFoo)
|
||||
|
||||
bad(genericParamOnce(string, int))
|
||||
bad(genericParamOnce(TFoo, float))
|
||||
reject genericParamOnce(string, int)
|
||||
reject genericParamOnce(TFoo, float)
|
||||
|
||||
type
|
||||
type1 = typedesc
|
||||
|
|
@ -50,42 +50,42 @@ type
|
|||
|
||||
proc typePairs(A, B: type1; C, D: type2) = nil
|
||||
|
||||
good(typePairs(int, int, TFoo, TFOO))
|
||||
good(typePairs(TBAR, TBar, TBAR, TBAR))
|
||||
good(typePairs(int, int, string, string))
|
||||
accept typePairs(int, int, TFoo, TFOO)
|
||||
accept typePairs(TBAR, TBar, TBAR, TBAR)
|
||||
accept typePairs(int, int, string, string)
|
||||
|
||||
bad(typePairs(TBAR, TBar, TBar, TFoo))
|
||||
bad(typePairs(string, int, TBAR, TBAR))
|
||||
reject typePairs(TBAR, TBar, TBar, TFoo)
|
||||
reject typePairs(string, int, TBAR, TBAR)
|
||||
|
||||
proc typePairs2[T: typedesc, U: typedesc](A, B: T; C, D: U) = nil
|
||||
|
||||
good(typePairs2(int, int, TFoo, TFOO))
|
||||
good(typePairs2(TBAR, TBar, TBAR, TBAR))
|
||||
good(typePairs2(int, int, string, string))
|
||||
accept typePairs2(int, int, TFoo, TFOO)
|
||||
accept typePairs2(TBAR, TBar, TBAR, TBAR)
|
||||
accept typePairs2(int, int, string, string)
|
||||
|
||||
bad(typePairs2(TBAR, TBar, TBar, TFoo))
|
||||
bad(typePairs2(string, int, TBAR, TBAR))
|
||||
reject typePairs2(TBAR, TBar, TBar, TFoo)
|
||||
reject typePairs2(string, int, TBAR, TBAR)
|
||||
|
||||
proc dontBind(a: typedesc, b: typedesc) =
|
||||
static:
|
||||
echo a.name
|
||||
echo b.name
|
||||
|
||||
good(dontBind(int, float))
|
||||
good(dontBind(TFoo, TFoo))
|
||||
accept dontBind(int, float)
|
||||
accept dontBind(TFoo, TFoo)
|
||||
|
||||
proc dontBind2(a, b: typedesc) = nil
|
||||
|
||||
good(dontBind2(int, float))
|
||||
good(dontBind2(TBar, int))
|
||||
accept dontBind2(int, float)
|
||||
accept dontBind2(TBar, int)
|
||||
|
||||
proc bindArg(T: typedesc, U: typedesc, a, b: T, c, d: U) = nil
|
||||
|
||||
good(bindArg(int, string, 10, 20, "test", "nest"))
|
||||
good(bindArg(int, int, 10, 20, 30, 40))
|
||||
accept bindArg(int, string, 10, 20, "test", "nest")
|
||||
accept bindArg(int, int, 10, 20, 30, 40)
|
||||
|
||||
bad(bindArg(int, string, 10, "test", "test", "nest"))
|
||||
bad(bindArg(int, int, 10, 20, 30, "test"))
|
||||
bad(bindArg(int, string, 10.0, 20, "test", "nest"))
|
||||
bad(bindArg(int, string, "test", "nest", 10, 20))
|
||||
reject bindArg(int, string, 10, "test", "test", "nest")
|
||||
reject bindArg(int, int, 10, 20, 30, "test")
|
||||
reject bindArg(int, string, 10.0, 20, "test", "nest")
|
||||
reject bindArg(int, string, "test", "nest", 10, 20)
|
||||
|
||||
|
|
|
|||
59
tests/compile/tcompositetypeclasses.nim
Normal file
59
tests/compile/tcompositetypeclasses.nim
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
template accept(e) =
|
||||
static: assert(compiles(e))
|
||||
|
||||
template reject(e) =
|
||||
static: assert(not compiles(e))
|
||||
|
||||
type
|
||||
TFoo[T, U] = tuple
|
||||
x: T
|
||||
y: U
|
||||
|
||||
TBar[K] = TFoo[K, K]
|
||||
|
||||
TUserClass = int|string
|
||||
|
||||
TBaz = TBar[TUserClass]
|
||||
|
||||
var
|
||||
vfoo: TFoo[int, string]
|
||||
vbar: TFoo[string, string]
|
||||
vbaz: TFoo[int, int]
|
||||
vnotbaz: TFoo[TObject, TObject]
|
||||
|
||||
proc foo(x: TFoo) = echo "foo"
|
||||
proc bar(x: TBar) = echo "bar"
|
||||
proc baz(x: TBaz) = echo "baz"
|
||||
|
||||
accept foo(vfoo)
|
||||
accept bar(vbar)
|
||||
accept baz(vbar)
|
||||
accept baz(vbaz)
|
||||
|
||||
reject baz(vnotbaz)
|
||||
reject bar(vfoo)
|
||||
|
||||
# https://github.com/Araq/Nimrod/issues/517
|
||||
type
|
||||
TVecT*[T] = array[0..1, T]|array[0..2, T]|array[0..3, T]
|
||||
TVec2* = array[0..1, float32]
|
||||
|
||||
proc f[T](a: TVecT[T], b: TVecT[T]): T = discard
|
||||
|
||||
var x: float = f([0.0'f32, 0.0'f32], [0.0'f32, 0.0'f32])
|
||||
var y = f(TVec2([0.0'f32, 0.0'f32]), TVec2([0.0'f32, 0.0'f32]))
|
||||
|
||||
# https://github.com/Araq/Nimrod/issues/602
|
||||
type
|
||||
TTest = object
|
||||
TTest2* = object
|
||||
TUnion = TTest | TTest2
|
||||
|
||||
proc f(src: ptr TUnion, dst: ptr TUnion) =
|
||||
echo("asd")
|
||||
|
||||
var tx: TTest
|
||||
var ty: TTest2
|
||||
|
||||
accept f(addr tx, addr tx)
|
||||
reject f(addr tx, addr ty)
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
discard """
|
||||
file: "tgenericshardcases.nim"
|
||||
output: "int\nfloat\nint\nstring"
|
||||
output: "2\n5\n126\n3"
|
||||
"""
|
||||
|
||||
import typetraits
|
||||
|
|
@ -13,18 +13,24 @@ macro selectType(a, b: typedesc): typedesc =
|
|||
|
||||
type
|
||||
Foo[T] = object
|
||||
data1: array[high(T), int]
|
||||
data2: array[1..typeNameLen(T), selectType(float, string)]
|
||||
data1: array[T.high, int]
|
||||
data2: array[typeNameLen(T), float] # data3: array[0..T.typeNameLen, selectType(float, int)]
|
||||
|
||||
MyEnum = enum A, B, C,D
|
||||
MyEnum = enum A, B, C, D
|
||||
|
||||
var f1: Foo[MyEnum]
|
||||
var f2: Foo[int8]
|
||||
|
||||
static:
|
||||
assert high(f1.data1) == D
|
||||
assert high(f1.data2) == 6 # length of MyEnum
|
||||
echo high(f1.data1) # (D = 3) - 1 == 2
|
||||
echo high(f1.data2) # (MyEnum.len = 6) - 1 == 5
|
||||
|
||||
assert high(f2.data1) == 127
|
||||
assert high(f2.data2) == 4 # length of int8
|
||||
echo high(f2.data1) # 127 - 1 == 126
|
||||
echo high(f2.data2) # int8.len - 1 == 3
|
||||
|
||||
#static:
|
||||
# assert high(f1.data1) == ord(D)
|
||||
# assert high(f1.data2) == 6 # length of MyEnum
|
||||
|
||||
# assert high(f2.data1) == 127
|
||||
# assert high(f2.data2) == 4 # length of int8
|
||||
|
||||
|
|
|
|||
|
|
@ -1,67 +1,67 @@
|
|||
# Test nested loops and some other things
|
||||
|
||||
proc andTest() =
|
||||
var a = 0 == 5 and 6 == 6
|
||||
|
||||
proc incx(x: var int) = # is built-in proc
|
||||
x = x + 1
|
||||
|
||||
proc decx(x: var int) =
|
||||
x = x - 1
|
||||
|
||||
proc First(y: var int) =
|
||||
var x: int
|
||||
i_ncx(x)
|
||||
if x == 10:
|
||||
y = 0
|
||||
else:
|
||||
if x == 0:
|
||||
incx(x)
|
||||
else:
|
||||
x=11
|
||||
|
||||
proc TestLoops() =
|
||||
var i, j: int
|
||||
while i >= 0:
|
||||
if i mod 3 == 0:
|
||||
break
|
||||
i = i + 1
|
||||
while j == 13:
|
||||
j = 13
|
||||
break
|
||||
break
|
||||
|
||||
while True:
|
||||
break
|
||||
|
||||
|
||||
proc Foo(n: int): int =
|
||||
var
|
||||
a, old: int
|
||||
b, c: bool
|
||||
F_irst(a)
|
||||
if a == 10:
|
||||
a = 30
|
||||
elif a == 11:
|
||||
a = 22
|
||||
elif a == 12:
|
||||
a = 23
|
||||
elif b:
|
||||
old = 12
|
||||
else:
|
||||
a = 40
|
||||
|
||||
#
|
||||
b = false or 2 == 0 and 3 == 9
|
||||
a = 0 + 3 * 5 + 6 + 7 + +8 # 36
|
||||
while b:
|
||||
a = a + 3
|
||||
a = a + 5
|
||||
write(stdout, "Hello!")
|
||||
|
||||
|
||||
# We should come till here :-)
|
||||
discard Foo(345)
|
||||
# Test nested loops and some other things
|
||||
|
||||
proc andTest() =
|
||||
var a = 0 == 5 and 6 == 6
|
||||
|
||||
proc incx(x: var int) = # is built-in proc
|
||||
x = x + 1
|
||||
|
||||
proc decx(x: var int) =
|
||||
x = x - 1
|
||||
|
||||
proc First(y: var int) =
|
||||
var x: int
|
||||
i_ncx(x)
|
||||
if x == 10:
|
||||
y = 0
|
||||
else:
|
||||
if x == 0:
|
||||
incx(x)
|
||||
else:
|
||||
x=11
|
||||
|
||||
proc TestLoops() =
|
||||
var i, j: int
|
||||
while i >= 0:
|
||||
if i mod 3 == 0:
|
||||
break
|
||||
i = i + 1
|
||||
while j == 13:
|
||||
j = 13
|
||||
break
|
||||
break
|
||||
|
||||
while True:
|
||||
break
|
||||
|
||||
|
||||
proc Foo(n: int): int =
|
||||
var
|
||||
a, old: int
|
||||
b, c: bool
|
||||
F_irst(a)
|
||||
if a == 10:
|
||||
a = 30
|
||||
elif a == 11:
|
||||
a = 22
|
||||
elif a == 12:
|
||||
a = 23
|
||||
elif b:
|
||||
old = 12
|
||||
else:
|
||||
a = 40
|
||||
|
||||
#
|
||||
b = false or 2 == 0 and 3 == 9
|
||||
a = 0 + 3 * 5 + 6 + 7 + +8 # 36
|
||||
while b:
|
||||
a = a + 3
|
||||
a = a + 5
|
||||
write(stdout, "Hello!")
|
||||
|
||||
|
||||
# We should come till here :-)
|
||||
discard Foo(345)
|
||||
|
||||
# test the new type symbol lookup feature:
|
||||
|
||||
|
|
|
|||
41
tests/compile/tmatrix3.nim
Normal file
41
tests/compile/tmatrix3.nim
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
discard """
|
||||
output: '''0.0000000000000000e+00
|
||||
0.0000000000000000e+00
|
||||
0
|
||||
0
|
||||
0
|
||||
'''
|
||||
"""
|
||||
|
||||
include compilehelpers
|
||||
|
||||
type
|
||||
Matrix*[M, N, T] = object
|
||||
aij*: array[M, array[N, T]]
|
||||
|
||||
Matrix2*[T] = Matrix[range[0..1], range[0..1], T]
|
||||
|
||||
Matrix3*[T] = Matrix[range[0..2], range[0..2], T]
|
||||
|
||||
proc mn(x: Matrix): Matrix.T = x.aij[0][0]
|
||||
|
||||
proc m2(x: Matrix2): Matrix2.T = x.aij[0][0]
|
||||
|
||||
proc m3(x: Matrix3): auto = x.aij[0][0]
|
||||
|
||||
var
|
||||
matn: Matrix[range[0..3], range[0..2], int]
|
||||
mat2: Matrix2[int]
|
||||
mat3: Matrix3[float]
|
||||
|
||||
echo m3(mat3)
|
||||
echo mn(mat3)
|
||||
echo m2(mat2)
|
||||
echo mn(mat2)
|
||||
echo mn(matn)
|
||||
|
||||
reject m3(mat2)
|
||||
reject m3(matn)
|
||||
reject m2(mat3)
|
||||
reject m2(matn)
|
||||
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
# Module A
|
||||
var
|
||||
lastId = 0
|
||||
|
||||
template genId*: expr =
|
||||
inc(lastId)
|
||||
lastId
|
||||
|
||||
|
||||
|
|
@ -5,23 +5,23 @@ discard """
|
|||
|
||||
import tables
|
||||
|
||||
proc action1(arg: string) =
|
||||
proc action1(arg: string) =
|
||||
echo "action 1 ", arg
|
||||
|
||||
proc action2(arg: string) =
|
||||
proc action2(arg: string) =
|
||||
echo "action 2 ", arg
|
||||
|
||||
proc action3(arg: string) =
|
||||
proc action3(arg: string) =
|
||||
echo "action 3 ", arg
|
||||
|
||||
proc action4(arg: string) =
|
||||
proc action4(arg: string) =
|
||||
echo "action 4 ", arg
|
||||
|
||||
const
|
||||
actionTable = {
|
||||
"A": action1,
|
||||
"B": action2,
|
||||
"C": action3,
|
||||
"A": action1,
|
||||
"B": action2,
|
||||
"C": action3,
|
||||
"D": action4}.toTable
|
||||
|
||||
actionTable["C"]("arg")
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
discard """
|
||||
file: "mbind4.nim"
|
||||
line: 6
|
||||
errormsg: "undeclared identifier: \'lastId\'"
|
||||
"""
|
||||
# Module B
|
||||
import mbind4
|
||||
|
||||
echo genId()
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
discard """
|
||||
line: 1840
|
||||
line: 1855
|
||||
file: "system.nim"
|
||||
errormsg: "can raise an unlisted exception: ref EIO"
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -3,15 +3,14 @@ discard """
|
|||
line: 13
|
||||
errormsg: "illegal recursion in type \'TIllegal\'"
|
||||
"""
|
||||
# test illegal recursive types
|
||||
|
||||
type
|
||||
TLegal {.final.} = object
|
||||
x: int
|
||||
kids: seq[TLegal]
|
||||
|
||||
TIllegal {.final.} = object #ERROR_MSG illegal recursion in type 'TIllegal'
|
||||
y: Int
|
||||
x: array[0..3, TIllegal]
|
||||
# test illegal recursive types
|
||||
|
||||
type
|
||||
TLegal {.final.} = object
|
||||
x: int
|
||||
kids: seq[TLegal]
|
||||
|
||||
TIllegal {.final.} = object #ERROR_MSG illegal recursion in type 'TIllegal'
|
||||
y: Int
|
||||
x: array[0..3, TIllegal]
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ discard """
|
|||
line: 7
|
||||
errormsg: "illegal recursion in type \'Uint8\'"
|
||||
"""
|
||||
type
|
||||
Uint8 = Uint8 #ERROR_MSG illegal recursion in type 'Uint8'
|
||||
|
||||
|
||||
type
|
||||
Uint8 = Uint8 #ERROR_MSG illegal recursion in type 'Uint8'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,26 +1,84 @@
|
|||
discard """
|
||||
output: '''some text
|
||||
Destructor called!'''
|
||||
output: '''----
|
||||
myobj constructed
|
||||
myobj destroyed
|
||||
----
|
||||
mygeneric1 constructed
|
||||
mygeneric1 destroyed
|
||||
----
|
||||
mygeneric2 constructed
|
||||
mygeneric2 destroyed
|
||||
myobj destroyed
|
||||
----
|
||||
mygeneric3 constructed
|
||||
mygeneric1 destroyed
|
||||
'''
|
||||
"""
|
||||
|
||||
type
|
||||
TMyObj = object
|
||||
x, y: int
|
||||
p: pointer
|
||||
|
||||
|
||||
TMyGeneric1[T] = object
|
||||
x: T
|
||||
|
||||
TMyGeneric2[A, B] = object
|
||||
x: A
|
||||
y: B
|
||||
|
||||
TMyGeneric3[A, B, C] = object
|
||||
x: A
|
||||
y: B
|
||||
z: C
|
||||
|
||||
proc destruct(o: var TMyObj) {.destructor.} =
|
||||
if o.p != nil: dealloc o.p
|
||||
echo "Destructor called!"
|
||||
|
||||
echo "myobj destroyed"
|
||||
|
||||
proc destroy(o: var TMyGeneric1) {.destructor.} =
|
||||
echo "mygeneric1 destroyed"
|
||||
|
||||
proc destroy[A, B](o: var TMyGeneric2[A, B]) {.destructor.} =
|
||||
echo "mygeneric2 destroyed"
|
||||
|
||||
proc open: TMyObj =
|
||||
# allow for superfluous ()
|
||||
result = (TMyObj(x: 1, y: 2, p: alloc(3)))
|
||||
|
||||
|
||||
proc `$`(x: TMyObj): string = $x.y
|
||||
|
||||
proc main() =
|
||||
proc myobj() =
|
||||
var x = open()
|
||||
echo "some text"
|
||||
echo "myobj constructed"
|
||||
|
||||
proc mygeneric1() =
|
||||
var x = TMyGeneric1[int](x: 10)
|
||||
echo "mygeneric1 constructed"
|
||||
|
||||
proc mygeneric2[T](val: T) =
|
||||
var
|
||||
a = open()
|
||||
b = TMyGeneric2[int, T](x: 10, y: val)
|
||||
c = TMyGeneric3[int, int, string](x: 10, y: 20, z: "test")
|
||||
|
||||
echo "mygeneric2 constructed"
|
||||
|
||||
proc mygeneric3 =
|
||||
var x = TMyGeneric3[int, string, TMyGeneric1[int]](
|
||||
x: 10, y: "test", z: TMyGeneric1[int](x: 10))
|
||||
|
||||
echo "mygeneric3 constructed"
|
||||
|
||||
echo "----"
|
||||
myobj()
|
||||
|
||||
echo "----"
|
||||
mygeneric1()
|
||||
|
||||
echo "----"
|
||||
mygeneric2[int](10)
|
||||
|
||||
echo "----"
|
||||
mygeneric3()
|
||||
|
||||
main()
|
||||
|
|
|
|||
51
tests/run/tfailedassert.nim
Normal file
51
tests/run/tfailedassert.nim
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
discard """
|
||||
output: '''
|
||||
WARNING: false first asseertion from bar
|
||||
ERROR: false second assertion from bar
|
||||
-1
|
||||
tests/run/tfailedassert.nim:27 false assertion from foo
|
||||
'''
|
||||
"""
|
||||
|
||||
type
|
||||
TLineInfo = tuple[filename: string, line: int]
|
||||
|
||||
TMyError = object of E_Base
|
||||
lineinfo: TLineInfo
|
||||
|
||||
EMyError = ref TMyError
|
||||
|
||||
# module-wide policy to change the failed assert
|
||||
# exception type in order to include a lineinfo
|
||||
onFailedAssert(msg):
|
||||
var e = new(TMyError)
|
||||
e.msg = msg
|
||||
e.lineinfo = instantiationInfo(-2)
|
||||
raise e
|
||||
|
||||
proc foo =
|
||||
assert(false, "assertion from foo")
|
||||
|
||||
proc bar: int =
|
||||
# local overrides that are active only
|
||||
# in this proc
|
||||
onFailedAssert(msg): echo "WARNING: " & msg
|
||||
|
||||
assert(false, "first asseertion from bar")
|
||||
|
||||
onFailedAssert(msg):
|
||||
echo "ERROR: " & msg
|
||||
return -1
|
||||
|
||||
assert(false, "second assertion from bar")
|
||||
return 10
|
||||
|
||||
echo("")
|
||||
echo(bar())
|
||||
|
||||
try:
|
||||
foo()
|
||||
except:
|
||||
let e = EMyError(getCurrentException())
|
||||
echo e.lineinfo.filename, ":", e.lineinfo.line, " ", e.msg
|
||||
|
||||
|
|
@ -1,17 +1,17 @@
|
|||
discard """
|
||||
msg: "test 1\ntest 2"
|
||||
output: "TEST 1\nTEST 2\nTEST 2"
|
||||
msg: "test 1\ntest 2\ntest 3"
|
||||
output: "TEST 1\nTEST 2\nTEST 3"
|
||||
"""
|
||||
|
||||
import strutils
|
||||
|
||||
proc foo(s: expr[string]): string =
|
||||
proc foo(s: static[string]): string =
|
||||
static: echo s
|
||||
|
||||
const R = s.toUpper
|
||||
return R
|
||||
|
||||
|
||||
echo foo("test 1")
|
||||
echo foo("test 2")
|
||||
echo foo("test " & $2)
|
||||
echo foo("test " & $3)
|
||||
|
||||
|
|
|
|||
24
tests/run/tsemistatic.nim
Normal file
24
tests/run/tsemistatic.nim
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
discard """
|
||||
msg: "static 10\ndynamic\nstatic 20\n"
|
||||
output: "s\nd\nd\ns"
|
||||
"""
|
||||
|
||||
proc foo(x: semistatic[int]) =
|
||||
when isStatic(x):
|
||||
static: echo "static ", x
|
||||
echo "s"
|
||||
else:
|
||||
static: echo "dynamic"
|
||||
echo "d"
|
||||
|
||||
foo 10
|
||||
|
||||
var
|
||||
x = 10
|
||||
y: int
|
||||
|
||||
foo x
|
||||
foo y
|
||||
|
||||
foo 20
|
||||
|
||||
|
|
@ -4,15 +4,15 @@ discard """
|
|||
"""
|
||||
|
||||
type
|
||||
TFoo[T; Val: expr[string]] = object
|
||||
TFoo[T; Val: static[string]] = object
|
||||
data: array[4, T]
|
||||
|
||||
TBar[T; I: expr[int]] = object
|
||||
TBar[T; I: static[int]] = object
|
||||
data: array[I, T]
|
||||
|
||||
TA1[T; I: expr[int]] = array[I, T]
|
||||
TA2[T; I: expr[int]] = array[0..I, T]
|
||||
TA3[T; I: expr[int]] = array[I-1, T]
|
||||
TA1[T; I: static[int]] = array[I, T]
|
||||
# TA2[T; I: static[int]] = array[0..I, T]
|
||||
# TA3[T; I: static[int]] = array[I-1, T]
|
||||
|
||||
proc takeFoo(x: TFoo) =
|
||||
echo "abracadabra"
|
||||
|
|
@ -25,7 +25,7 @@ var y: TBar[float, 4]
|
|||
echo high(y.data)
|
||||
|
||||
var
|
||||
t1: TA1
|
||||
t2: TA2
|
||||
t3: TA3
|
||||
t1: TA1[float, 1]
|
||||
# t2: TA2[string, 4]
|
||||
# t3: TA3[int, 10]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
discard """
|
||||
msg: "int\nstring\nTBar[int]"
|
||||
output: "int\nstring\nTBar[int]\nint\nrange 0..2\nstring"
|
||||
output: "int\nstring\nTBar[int]\nint\nrange 0..2(int)\nstring"
|
||||
"""
|
||||
|
||||
import typetraits
|
||||
|
|
|
|||
|
|
@ -8,25 +8,11 @@ import
|
|||
|
||||
# This macro mimics the using statement from C#
|
||||
#
|
||||
# XXX:
|
||||
# It doen't match the C# version exactly yet.
|
||||
# In particular, it's not recursive, which prevents it from dealing
|
||||
# with exceptions thrown from the variable initializers when multiple.
|
||||
# variables are used.
|
||||
# It's kept only as a test for the macro system
|
||||
# Nimrod's destructors offer a mechanism for automatic
|
||||
# disposal of resources.
|
||||
#
|
||||
# Also, since nimrod relies less on exceptions in general, a more
|
||||
# idiomatic definition could be:
|
||||
# var x = init()
|
||||
# if opened(x):
|
||||
# try:
|
||||
# body
|
||||
# finally:
|
||||
# close(x)
|
||||
#
|
||||
# `opened` here could be an overloaded proc which any type can define.
|
||||
# A common practice can be returing an Optional[Resource] obj for which
|
||||
# `opened` is defined to `optional.hasValue`
|
||||
macro using(e: expr): stmt {.immediate.} =
|
||||
macro autoClose(e: expr): stmt {.immediate.} =
|
||||
let e = callsite()
|
||||
if e.len != 3:
|
||||
error "Using statement: unexpected number of arguments. Got " &
|
||||
|
|
@ -97,7 +83,7 @@ proc close(r: var TResource) =
|
|||
proc use(r: var TResource) =
|
||||
write(stdout, "Using " & r.field & ".")
|
||||
|
||||
using(r = openResource("test")):
|
||||
autoClose(r = openResource("test")):
|
||||
use r
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue