Merge branch 'devel' into experimentalize-reorder
This commit is contained in:
commit
eb668003bf
241 changed files with 6388 additions and 12619 deletions
60
tests/arithm/tcast.nim
Normal file
60
tests/arithm/tcast.nim
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
discard """
|
||||
output: '''
|
||||
B0
|
||||
B1
|
||||
B2
|
||||
B3
|
||||
'''
|
||||
"""
|
||||
|
||||
template crossCheck(ty: untyped, exp: untyped) =
|
||||
let rt = ty(exp)
|
||||
const ct = ty(exp)
|
||||
if $rt != $ct:
|
||||
echo "Got ", ct
|
||||
echo "Expected ", rt
|
||||
|
||||
block:
|
||||
when true:
|
||||
echo "B0"
|
||||
crossCheck(int8, 0'i16 - 5'i16)
|
||||
crossCheck(int16, 0'i32 - 5'i32)
|
||||
crossCheck(int32, 0'i64 - 5'i64)
|
||||
|
||||
echo "B1"
|
||||
crossCheck(uint8, 0'u8 - 5'u8)
|
||||
crossCheck(uint16, 0'u16 - 5'u16)
|
||||
crossCheck(uint32, 0'u32 - 5'u32)
|
||||
crossCheck(uint64, 0'u64 - 5'u64)
|
||||
|
||||
echo "B2"
|
||||
crossCheck(uint8, uint8.high + 5'u8)
|
||||
crossCheck(uint16, uint16.high + 5'u16)
|
||||
crossCheck(uint32, uint32.high + 5'u32)
|
||||
crossCheck(uint64, (-1).uint64 + 5'u64)
|
||||
|
||||
echo "B3"
|
||||
crossCheck(int8, 0'u8 - 5'u8)
|
||||
crossCheck(int16, 0'u16 - 5'u16)
|
||||
crossCheck(int32, 0'u32 - 5'u32)
|
||||
crossCheck(int64, 0'u64 - 5'u64)
|
||||
|
||||
# crossCheck(int8, 0'u16 - 129'u16)
|
||||
# crossCheck(uint8, 0'i16 + 257'i16)
|
||||
|
||||
# Signed integer {under,over}flow is guarded against
|
||||
|
||||
# crossCheck(int8, int8.high + 5'i8)
|
||||
# crossCheck(int16, int16.high + 5'i16)
|
||||
# crossCheck(int32, int32.high + 5'i32)
|
||||
# crossCheck(int64, int64.high + 5'i64)
|
||||
|
||||
# crossCheck(int8, int8.low - 5'i8)
|
||||
# crossCheck(int16, int16.low - 5'i16)
|
||||
# crossCheck(int32, int32.low - 5'i32)
|
||||
# crossCheck(int64, int64.low - 5'i64)
|
||||
|
||||
# crossCheck(uint8, 0'i8 - 5'i8)
|
||||
# crossCheck(uint16, 0'i16 - 5'i16)
|
||||
# crossCheck(uint32, 0'i32 - 5'i32)
|
||||
# crossCheck(uint64, 0'i64 - 5'i64)
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
discard """
|
||||
output: '''0
|
||||
0'''
|
||||
0
|
||||
bc
|
||||
bcdefg'''
|
||||
"""
|
||||
|
||||
# test another strange bug ... (I hate this compiler; it is much too buggy!)
|
||||
|
|
@ -29,3 +31,13 @@ var
|
|||
|
||||
echo obj.s1[0]
|
||||
echo obj.s1[0u]
|
||||
|
||||
|
||||
# bug #8049
|
||||
|
||||
when true:
|
||||
type ustring* = distinct string
|
||||
converter toUString*(s: string): ustring = ustring(s)
|
||||
proc `[]`*(s: ustring, i: int): ustring = s
|
||||
echo "abcdefgh"[1..2]
|
||||
echo "abcdefgh"[1..^2]
|
||||
|
|
|
|||
12
tests/assert/testhelper.nim
Normal file
12
tests/assert/testhelper.nim
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
from strutils import endsWith, split
|
||||
from ospaths import isAbsolute
|
||||
|
||||
proc checkMsg*(msg, expectedEnd, name: string)=
|
||||
let filePrefix = msg.split(' ', maxSplit = 1)[0]
|
||||
if not filePrefix.isAbsolute:
|
||||
echo name, ":not absolute: `", msg & "`"
|
||||
elif not msg.endsWith expectedEnd:
|
||||
echo name, ":expected suffix:\n`" & expectedEnd & "`\ngot:\n`" & msg & "`"
|
||||
else:
|
||||
echo name, ":ok"
|
||||
|
||||
|
|
@ -1,20 +1,65 @@
|
|||
discard """
|
||||
output: '''
|
||||
WARNING: false first assertion from bar
|
||||
ERROR: false second assertion from bar
|
||||
test1:ok
|
||||
test2:ok
|
||||
test3:ok
|
||||
test4:ok
|
||||
test5:ok
|
||||
test6:ok
|
||||
test7:ok
|
||||
-1
|
||||
tfailedassert.nim:27 false assertion from foo
|
||||
tfailedassert.nim
|
||||
test7:ok
|
||||
'''
|
||||
"""
|
||||
|
||||
import testhelper
|
||||
|
||||
type
|
||||
TLineInfo = tuple[filename: string, line: int, column: int]
|
||||
|
||||
TMyError = object of Exception
|
||||
lineinfo: TLineInfo
|
||||
|
||||
EMyError = ref TMyError
|
||||
|
||||
echo("")
|
||||
|
||||
|
||||
# NOTE: when entering newlines, adjust `expectedEnd` ouptuts
|
||||
|
||||
try:
|
||||
doAssert(false, "msg1") # doAssert test
|
||||
except AssertionError as e:
|
||||
checkMsg(e.msg, "tfailedassert.nim(30, 11) `false` msg1", "test1")
|
||||
|
||||
try:
|
||||
assert false, "msg2" # assert test
|
||||
except AssertionError as e:
|
||||
checkMsg(e.msg, "tfailedassert.nim(35, 10) `false` msg2", "test2")
|
||||
|
||||
try:
|
||||
assert false # assert test with no msg
|
||||
except AssertionError as e:
|
||||
checkMsg(e.msg, "tfailedassert.nim(40, 10) `false` ", "test3")
|
||||
|
||||
try:
|
||||
let a = 1
|
||||
doAssert(a+a==1) # assert test with Ast expression
|
||||
# BUG: const folding would make "1+1==1" appear as `false` in
|
||||
# assert message
|
||||
except AssertionError as e:
|
||||
checkMsg(e.msg, "`a + a == 1` ", "test4")
|
||||
|
||||
try:
|
||||
let a = 1
|
||||
doAssert a+a==1 # ditto with `doAssert` and no parens
|
||||
except AssertionError as e:
|
||||
checkMsg(e.msg, "`a + a == 1` ", "test5")
|
||||
|
||||
proc fooStatic() =
|
||||
# protect against https://github.com/nim-lang/Nim/issues/8758
|
||||
static: doAssert(true)
|
||||
fooStatic()
|
||||
|
||||
# module-wide policy to change the failed assert
|
||||
# exception type in order to include a lineinfo
|
||||
onFailedAssert(msg):
|
||||
|
|
@ -26,26 +71,26 @@ onFailedAssert(msg):
|
|||
proc foo =
|
||||
assert(false, "assertion from foo")
|
||||
|
||||
|
||||
proc bar: int =
|
||||
# local overrides that are active only
|
||||
# in this proc
|
||||
onFailedAssert(msg): echo "WARNING: " & msg
|
||||
# local overrides that are active only in this proc
|
||||
onFailedAssert(msg):
|
||||
checkMsg(msg, "tfailedassert.nim(80, 9) `false` first assertion from bar", "test6")
|
||||
|
||||
assert(false, "first assertion from bar")
|
||||
|
||||
onFailedAssert(msg):
|
||||
echo "ERROR: " & msg
|
||||
checkMsg(msg, "tfailedassert.nim(86, 9) `false` second assertion from bar", "test7")
|
||||
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
|
||||
|
||||
echo e.lineinfo.filename
|
||||
checkMsg(e.msg, "tfailedassert.nim(72, 9) `false` assertion from foo", "test7")
|
||||
|
|
|
|||
20
tests/assert/tfaileddoassert.nim
Normal file
20
tests/assert/tfaileddoassert.nim
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
discard """
|
||||
cmd: "nim $target -d:release $options $file"
|
||||
output: '''
|
||||
test1:ok
|
||||
test2:ok
|
||||
'''
|
||||
"""
|
||||
|
||||
import testhelper
|
||||
|
||||
onFailedAssert(msg):
|
||||
checkMsg(msg, "tfaileddoassert.nim(15, 9) `a == 2` foo", "test1")
|
||||
|
||||
var a = 1
|
||||
doAssert(a == 2, "foo")
|
||||
|
||||
onFailedAssert(msg):
|
||||
checkMsg(msg, "tfaileddoassert.nim(20, 10) `a == 3` ", "test2")
|
||||
|
||||
doAssert a == 3
|
||||
16
tests/async/t6846.nim
Normal file
16
tests/async/t6846.nim
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
discard """
|
||||
exitcode: 0
|
||||
output: "hello world"
|
||||
disabled: windows
|
||||
"""
|
||||
|
||||
import asyncdispatch
|
||||
import asyncfile
|
||||
import times
|
||||
|
||||
var asyncStdout = 1.AsyncFD.newAsyncFile()
|
||||
proc doStuff: Future[void] {.async.} =
|
||||
await asyncStdout.write "hello world\n"
|
||||
|
||||
let fut = doStuff()
|
||||
doAssert fut.finished, "Poll is needed unnecessarily. See #6846."
|
||||
19
tests/async/t7758.nim
Normal file
19
tests/async/t7758.nim
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
discard """
|
||||
file: "t7758.nim"
|
||||
exitcode: 0
|
||||
"""
|
||||
import asyncdispatch
|
||||
|
||||
proc task() {.async.} =
|
||||
await sleepAsync(40)
|
||||
|
||||
proc main() =
|
||||
var counter = 0
|
||||
var f = task()
|
||||
while not f.finished:
|
||||
inc(counter)
|
||||
poll(10)
|
||||
|
||||
doAssert counter <= 4
|
||||
|
||||
for i in 0 .. 10: main()
|
||||
|
|
@ -35,7 +35,7 @@ proc main() {.async.} =
|
|||
fut = newFutureVar[string]()
|
||||
let retFut = failureTest(fut, true)
|
||||
yield retFut
|
||||
doAssert(fut.read().isNil)
|
||||
doAssert(fut.read().len == 0)
|
||||
doAssert(fut.finished)
|
||||
|
||||
fut = newFutureVar[string]()
|
||||
|
|
|
|||
10
tests/ccgbugs/t5345.nim
Normal file
10
tests/ccgbugs/t5345.nim
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
discard """
|
||||
output: true
|
||||
"""
|
||||
|
||||
proc cmpx(d: int): bool {.inline.} = d > 0
|
||||
|
||||
proc abc[C](cx: C, d: int) =
|
||||
echo cx(d)
|
||||
|
||||
abc(cmpx, 10)
|
||||
17
tests/ccgbugs/t5701.nim
Normal file
17
tests/ccgbugs/t5701.nim
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
discard """
|
||||
output: '''(Field0: 1, Field1: 1)
|
||||
(Field0: 2, Field1: 2)
|
||||
(Field0: 3, Field1: 3)
|
||||
'''
|
||||
"""
|
||||
|
||||
iterator zip[T1, T2](a: openarray[T1], b: openarray[T2]): iterator() {.inline.} =
|
||||
let len = min(a.len, b.len)
|
||||
for i in 0..<len:
|
||||
echo (a[i], b[i])
|
||||
|
||||
proc foo(args: varargs[int]) =
|
||||
for i in zip(args,args):
|
||||
discard
|
||||
|
||||
foo(1,2,3)
|
||||
25
tests/ccgbugs/t8781.nim
Normal file
25
tests/ccgbugs/t8781.nim
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
discard """
|
||||
output: ""
|
||||
"""
|
||||
|
||||
type
|
||||
Drawable = object of RootObj
|
||||
discard
|
||||
|
||||
# issue #8781, following type was broken due to 'U' suffix
|
||||
# on `animatedU`. U also added as union identifier for C.
|
||||
# replaced by "_U" prefix, which is not allowed as an
|
||||
# identifier
|
||||
TypeOne = ref object of Drawable
|
||||
animatedU: bool
|
||||
case animated: bool
|
||||
of true:
|
||||
frames: seq[int]
|
||||
of false:
|
||||
region: float
|
||||
|
||||
when isMainModule:
|
||||
let r = 1.5
|
||||
let a = TypeOne(animatedU: true,
|
||||
animated: false,
|
||||
region: r)
|
||||
|
|
@ -3,8 +3,8 @@ discard """
|
|||
0
|
||||
0
|
||||
0
|
||||
[[a = nil,
|
||||
b = nil]]'''
|
||||
[[a = "",
|
||||
b = []]]'''
|
||||
"""
|
||||
|
||||
# bug #1475
|
||||
|
|
|
|||
|
|
@ -43,9 +43,10 @@ proc `=destroy`*[T](x: var myseq[T]) =
|
|||
proc `=`*[T](a: var myseq[T]; b: myseq[T]) =
|
||||
if a.data == b.data: return
|
||||
if a.data != nil:
|
||||
dealloc(a.data)
|
||||
inc deallocCount
|
||||
a.data = nil
|
||||
`=destroy`(a)
|
||||
#dealloc(a.data)
|
||||
#inc deallocCount
|
||||
#a.data = nil
|
||||
a.len = b.len
|
||||
a.cap = b.cap
|
||||
if b.data != nil:
|
||||
|
|
|
|||
|
|
@ -42,18 +42,21 @@ when isMainModule:
|
|||
# bug #985
|
||||
|
||||
type
|
||||
Pony = object
|
||||
name: string
|
||||
Pony = object
|
||||
name: string
|
||||
|
||||
proc `=destroy`(o: var Pony) =
|
||||
echo "Pony is dying!"
|
||||
|
||||
proc getPony: Pony =
|
||||
result.name = "Sparkles"
|
||||
result.name = "Sparkles"
|
||||
|
||||
iterator items(p: Pony): int =
|
||||
for i in 1..4:
|
||||
yield i
|
||||
for i in 1..4:
|
||||
yield i
|
||||
|
||||
for x in getPony():
|
||||
echo x
|
||||
echo x
|
||||
# XXX this needs to be enabled once top level statements
|
||||
# produce destructor calls again.
|
||||
echo "Pony is dying!"
|
||||
|
|
|
|||
19
tests/enum/tpure_enums_conflict.nim
Normal file
19
tests/enum/tpure_enums_conflict.nim
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
discard """
|
||||
errormsg: "ambiguous identifier: 'amb'"
|
||||
line: 19
|
||||
"""
|
||||
|
||||
# bug #8066
|
||||
|
||||
when true:
|
||||
type
|
||||
MyEnum {.pure.} = enum
|
||||
valueA, valueB, valueC, valueD, amb
|
||||
|
||||
OtherEnum {.pure.} = enum
|
||||
valueX, valueY, valueZ, amb
|
||||
|
||||
|
||||
echo valueA # MyEnum.valueA
|
||||
echo MyEnum.amb # OK.
|
||||
echo amb # Error: Unclear whether it's MyEnum.amb or OtherEnum.amb
|
||||
|
|
@ -5,7 +5,8 @@ nimout: '''
|
|||
type mismatch: got <AsyncHttpServer, Port, proc (req: Request): Future[system.void]{.locks: <unknown>.}>
|
||||
but expected one of:
|
||||
proc serve(server: AsyncHttpServer; port: Port;
|
||||
callback: proc (request: Request): Future[void]; address = ""): Future[void]
|
||||
callback: proc (request: Request): Future[void] {.closure, gcsafe.};
|
||||
address = ""): Future[void]
|
||||
first type mismatch at position: 3
|
||||
required type: proc (request: Request): Future[system.void]{.closure, gcsafe.}
|
||||
but expression 'cb' is of type: proc (req: Request): Future[system.void]{.locks: <unknown>.}
|
||||
|
|
|
|||
19
tests/errmsgs/tnested_generic_instantiation.nim
Normal file
19
tests/errmsgs/tnested_generic_instantiation.nim
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
discard """
|
||||
errormsg: "generic instantiation too nested"
|
||||
file: "system.nim"
|
||||
"""
|
||||
|
||||
# bug #4766
|
||||
|
||||
type
|
||||
Plain = ref object
|
||||
discard
|
||||
|
||||
Wrapped[T] = object
|
||||
value: T
|
||||
|
||||
converter toWrapped[T](value: T): Wrapped[T] =
|
||||
Wrapped[T](value: value)
|
||||
|
||||
let result = Plain()
|
||||
discard $result
|
||||
24
tests/errmsgs/tunknown_named_parameter.nim
Normal file
24
tests/errmsgs/tunknown_named_parameter.nim
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
discard """
|
||||
cmd: "nim check $file"
|
||||
errormsg: "type mismatch: got <string, set[char], maxsplits: int literal(1)>"
|
||||
nimout: '''
|
||||
proc rsplit(s: string; sep: string; maxsplit: int = -1): seq[string]
|
||||
first type mismatch at position: 2
|
||||
required type: string
|
||||
but expression '{':'}' is of type: set[char]
|
||||
proc rsplit(s: string; sep: char; maxsplit: int = -1): seq[string]
|
||||
first type mismatch at position: 2
|
||||
required type: char
|
||||
but expression '{':'}' is of type: set[char]
|
||||
proc rsplit(s: string; seps: set[char] = Whitespace; maxsplit: int = -1): seq[string]
|
||||
first type mismatch at position: 3
|
||||
unknown named parameter: maxsplits
|
||||
|
||||
expression: rsplit("abc:def", {':'}, maxsplits = 1)
|
||||
'''
|
||||
"""
|
||||
|
||||
# bug #8043
|
||||
|
||||
import strutils
|
||||
"abc:def".rsplit({':'}, maxsplits = 1)
|
||||
|
|
@ -66,8 +66,7 @@ proc caseTree(lvl: int = 0): PCaseNode =
|
|||
proc finalizeNode(n: PNode) =
|
||||
assert(n != nil)
|
||||
write(stdout, "finalizing: ")
|
||||
if isNil(n.data): writeLine(stdout, "nil!")
|
||||
else: writeLine(stdout, "not nil")
|
||||
writeLine(stdout, "not nil")
|
||||
|
||||
var
|
||||
id: int = 1
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ proc findLoops(self: var HavlakLoopFinder): int =
|
|||
# - the list of backedges (backPreds) or
|
||||
# - the list of non-backedges (nonBackPreds)
|
||||
#
|
||||
for w in 0 .. <size:
|
||||
for w in 0 ..< size:
|
||||
header[w] = 0
|
||||
types[w] = BB_NONHEADER
|
||||
|
||||
|
|
|
|||
36
tests/generics/tgenerics_and_inheritance.nim
Normal file
36
tests/generics/tgenerics_and_inheritance.nim
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
# bug #7854
|
||||
|
||||
type
|
||||
Stream* = ref StreamObj
|
||||
StreamObj* = object of RootObj
|
||||
|
||||
InhStream* = ref InhStreamObj
|
||||
InhStreamObj* = object of Stream
|
||||
f: string
|
||||
|
||||
proc newInhStream*(f: string): InhStream =
|
||||
new(result)
|
||||
result.f = f
|
||||
|
||||
var val: int
|
||||
let str = newInhStream("input_file.json")
|
||||
|
||||
block:
|
||||
# works:
|
||||
proc load[T](data: var T, s: Stream) =
|
||||
discard
|
||||
load(val, str)
|
||||
|
||||
block:
|
||||
# works
|
||||
proc load[T](s: Stream, data: T) =
|
||||
discard
|
||||
load(str, val)
|
||||
|
||||
block:
|
||||
# broken
|
||||
proc load[T](s: Stream, data: var T) =
|
||||
discard
|
||||
load(str, val)
|
||||
|
||||
|
|
@ -403,5 +403,18 @@ block: # yield in blockexpr
|
|||
|
||||
test(it, 1, 2, 3)
|
||||
|
||||
block: #8851
|
||||
type
|
||||
Foo = ref object of RootObj
|
||||
template someFoo(): Foo =
|
||||
var f: Foo
|
||||
yield 1
|
||||
f
|
||||
iterator it(): int {.closure.} =
|
||||
var o: RootRef
|
||||
o = someFoo()
|
||||
|
||||
test(it, 1)
|
||||
|
||||
|
||||
echo "ok"
|
||||
|
|
|
|||
|
|
@ -267,8 +267,8 @@ block:
|
|||
type TestObject = object
|
||||
a: int
|
||||
onWhatever: proc(e: int): int
|
||||
proc handleWhatever(that: TestObject, e: int): int =
|
||||
e + that.a
|
||||
proc handleWhatever(this: TestObject, e: int): int =
|
||||
e + this.a
|
||||
proc test(): bool =
|
||||
let obj = TestObject(a: 9, onWhatever: bindMethod(handleWhatever))
|
||||
obj.onWhatever(1) == 10
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
discard """
|
||||
output: '''(x: 0, y: 0)
|
||||
(x: 5, y: 0)
|
||||
@[(x: 2, y: 4), (x: 4, y: 5), (x: 4, y: 5)]
|
||||
@[(a: 3, b: 3), (a: 1, b: 1), (a: 2, b: 2)]
|
||||
@[(x: "2", y: 4), (x: "4", y: 5), (x: "4", y: 5)]
|
||||
@[(a: "3", b: 3), (a: "1", b: 1), (a: "2", b: 2)]
|
||||
'''
|
||||
"""
|
||||
|
||||
|
|
|
|||
23
tests/js/tthismangle.nim
Normal file
23
tests/js/tthismangle.nim
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
proc moo1(this: int) =
|
||||
doAssert this == 42
|
||||
|
||||
proc moo2(x: int) =
|
||||
var this = x
|
||||
doAssert this == 42
|
||||
|
||||
proc moo3() =
|
||||
for this in [1,1,1]:
|
||||
doAssert this == 1
|
||||
|
||||
proc moo4() =
|
||||
type
|
||||
X = object
|
||||
this: int
|
||||
|
||||
var q = X(this: 42)
|
||||
doAssert q.this == 42
|
||||
|
||||
moo1(42)
|
||||
moo2(42)
|
||||
moo3()
|
||||
moo4()
|
||||
21
tests/macros/t8706.nim
Normal file
21
tests/macros/t8706.nim
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
discard """
|
||||
output: '''0
|
||||
0
|
||||
'''
|
||||
"""
|
||||
|
||||
import macros
|
||||
|
||||
macro varargsLen(args:varargs[untyped]): untyped =
|
||||
doAssert args.kind == nnkArglist
|
||||
doAssert args.len == 0
|
||||
result = newLit(args.len)
|
||||
|
||||
template bar(a0:varargs[untyped]): untyped =
|
||||
varargsLen(a0)
|
||||
|
||||
template foo(x: int, a0:varargs[untyped]): untyped =
|
||||
bar(a0)
|
||||
|
||||
echo foo(42)
|
||||
echo bar()
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
discard """
|
||||
msg: '''"muhaha"
|
||||
proc poo(x, y: int) =
|
||||
let y = x
|
||||
echo ["poo"]'''
|
||||
"""
|
||||
|
||||
|
|
@ -10,11 +11,39 @@ const
|
|||
foo = "muhaha"
|
||||
|
||||
proc poo(x, y: int) =
|
||||
let y = x
|
||||
echo "poo"
|
||||
|
||||
macro m(x: typed): untyped =
|
||||
echo repr x.symbol.getImpl
|
||||
echo repr x.getImpl
|
||||
result = x
|
||||
|
||||
discard m foo
|
||||
discard m poo
|
||||
|
||||
#------------
|
||||
|
||||
macro checkOwner(x: typed, check_id: static[int]): untyped =
|
||||
let sym = case check_id:
|
||||
of 0: x
|
||||
of 1: x.getImpl.body[0][0][0]
|
||||
of 2: x.getImpl.body[0][0][^1]
|
||||
of 3: x.getImpl.body[1][0]
|
||||
else: x
|
||||
result = newStrLitNode($sym.owner.symKind)
|
||||
|
||||
macro isSameOwner(x, y: typed): untyped =
|
||||
result =
|
||||
if x.owner == y.owner: bindSym"true"
|
||||
else: bindSym"false"
|
||||
|
||||
|
||||
static:
|
||||
doAssert checkOwner(foo, 0) == "nskModule"
|
||||
doAssert checkOwner(poo, 0) == "nskModule"
|
||||
doAssert checkOwner(poo, 1) == "nskProc"
|
||||
doAssert checkOwner(poo, 2) == "nskProc"
|
||||
doAssert checkOwner(poo, 3) == "nskModule"
|
||||
doAssert isSameOwner(foo, poo)
|
||||
doAssert isSameOwner(foo, echo) == false
|
||||
doAssert isSameOwner(poo, len) == false
|
||||
|
|
|
|||
|
|
@ -1,16 +1,25 @@
|
|||
discard """
|
||||
nimout: '''void
|
||||
int'''
|
||||
nimout: '''intProc; ntyProc; proc[int, int, float]; proc (a: int; b: float): int
|
||||
void; ntyVoid; void; void
|
||||
int; ntyInt; int; int
|
||||
proc (); ntyProc; proc[void]; proc ()
|
||||
voidProc; ntyProc; proc[void]; proc ()'''
|
||||
"""
|
||||
|
||||
import macros
|
||||
|
||||
macro checkType(ex: typed; expected: string): untyped =
|
||||
var t = ex.getType()
|
||||
echo t
|
||||
echo ex.getTypeInst.repr, "; ", ex.typeKind, "; ", ex.getType.repr, "; ", ex.getTypeImpl.repr
|
||||
|
||||
macro checkProcType(fn: typed): untyped =
|
||||
let fn_sym = if fn.kind == nnkProcDef: fn[0] else: fn
|
||||
echo fn_sym, "; ", fn_sym.typeKind, "; ", fn_sym.getType.repr, "; ", fn_sym.getTypeImpl.repr
|
||||
|
||||
|
||||
proc voidProc = echo "hello"
|
||||
proc intProc(a: int, b: float): int = 10
|
||||
proc intProc(a: int, b: float): int {.checkProcType.} = 10
|
||||
|
||||
checkType(voidProc(), "void")
|
||||
checkType(intProc(10, 20.0), "int")
|
||||
checkType(voidProc, "procTy")
|
||||
checkProcType(voidProc)
|
||||
|
|
|
|||
24
tests/macros/tmsginfo.nim
Normal file
24
tests/macros/tmsginfo.nim
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
discard """
|
||||
nimout: '''tmsginfo.nim(21, 1) Warning: foo1 [User]
|
||||
tmsginfo.nim(22, 11) template/generic instantiation from here
|
||||
tmsginfo.nim(15, 10) Warning: foo2 [User]
|
||||
tmsginfo.nim(23, 1) Hint: foo3 [User]
|
||||
tmsginfo.nim(19, 7) Hint: foo4 [User]
|
||||
'''
|
||||
"""
|
||||
|
||||
import macros
|
||||
|
||||
macro foo1(y: untyped): untyped =
|
||||
warning("foo1", y)
|
||||
macro foo2(y: untyped): untyped =
|
||||
warning("foo2")
|
||||
macro foo3(y: untyped): untyped =
|
||||
hint("foo3", y)
|
||||
macro foo4(y: untyped): untyped =
|
||||
hint("foo4")
|
||||
|
||||
proc x1() {.foo1.} = discard
|
||||
proc x2() {.foo2.} = discard
|
||||
proc x3() {.foo3.} = discard
|
||||
proc x4() {.foo4.} = discard
|
||||
|
|
@ -232,7 +232,7 @@ template run_custom_proc(parsed_parameter: Tparsed_parameter,
|
|||
if not custom_validator.isNil:
|
||||
try:
|
||||
let message = custom_validator(parameter, parsed_parameter)
|
||||
if not message.isNil and message.len > 0:
|
||||
if message.len > 0:
|
||||
raise_or_quit(ValueError, ("Failed to validate value for " &
|
||||
"parameter $1:\n$2" % [escape(parameter), message]))
|
||||
except:
|
||||
|
|
|
|||
|
|
@ -7,3 +7,4 @@ path = "dependencies/genpacket"
|
|||
path = "enet_server"
|
||||
debugger = off
|
||||
warning[SmallLshouldNotBeUsed] = off
|
||||
nilseqs = on
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ else:
|
|||
of cmdArgument:
|
||||
task = key
|
||||
else: discard
|
||||
if printTaskList or task.isNil or not(tasks.hasKey(task)):
|
||||
if printTaskList or task.len == 0 or not(tasks.hasKey(task)):
|
||||
echo "Available tasks:"
|
||||
for name, task in pairs(tasks):
|
||||
echo name, " - ", task.desc
|
||||
|
|
|
|||
16
tests/modules/timportas.nim
Normal file
16
tests/modules/timportas.nim
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
discard """
|
||||
action: run
|
||||
"""
|
||||
|
||||
import .. / modules / [definitions as foo]
|
||||
import .. / modules / definitions as foo
|
||||
import std / times as bar
|
||||
from times as bar2 import nil
|
||||
import times as bar3 except convert
|
||||
import definitions as baz
|
||||
|
||||
discard foo.v
|
||||
discard bar.now
|
||||
discard bar2.now
|
||||
discard bar3.now
|
||||
discard baz.v
|
||||
32
tests/osproc/tstderr.nim
Normal file
32
tests/osproc/tstderr.nim
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
discard """
|
||||
output: '''--------------------------------------
|
||||
to stderr
|
||||
to stderr
|
||||
--------------------------------------
|
||||
'''
|
||||
"""
|
||||
import osproc, os, streams
|
||||
|
||||
const filename = "ta_out".addFileExt(ExeExt)
|
||||
|
||||
doAssert fileExists(getCurrentDir() / "tests" / "osproc" / filename)
|
||||
|
||||
var p = startProcess(filename, getCurrentDir() / "tests" / "osproc",
|
||||
options={})
|
||||
|
||||
try:
|
||||
let stdoutStream = p.outputStream
|
||||
let stderrStream = p.errorStream
|
||||
var x = newStringOfCap(120)
|
||||
var output = ""
|
||||
while stderrStream.readLine(x.TaintedString):
|
||||
output.add(x & "\n")
|
||||
|
||||
echo "--------------------------------------"
|
||||
stdout.flushFile()
|
||||
stderr.write output
|
||||
stderr.flushFile()
|
||||
echo "--------------------------------------"
|
||||
stdout.flushFile()
|
||||
finally:
|
||||
p.close()
|
||||
30
tests/pragmas/mpushexperimental.nim
Normal file
30
tests/pragmas/mpushexperimental.nim
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
|
||||
import macros
|
||||
|
||||
macro enumerate(x: ForLoopStmt): untyped =
|
||||
expectKind x, nnkForStmt
|
||||
# we strip off the first for loop variable and use
|
||||
# it as an integer counter:
|
||||
result = newStmtList()
|
||||
result.add newVarStmt(x[0], newLit(0))
|
||||
var body = x[^1]
|
||||
if body.kind != nnkStmtList:
|
||||
body = newTree(nnkStmtList, body)
|
||||
body.add newCall(bindSym"inc", x[0])
|
||||
var newFor = newTree(nnkForStmt)
|
||||
for i in 1..x.len-3:
|
||||
newFor.add x[i]
|
||||
# transform enumerate(X) to 'X'
|
||||
newFor.add x[^2][1]
|
||||
newFor.add body
|
||||
result.add newFor
|
||||
|
||||
proc main*[T](x: T) =
|
||||
{.push experimental: "forLoopMacros".}
|
||||
|
||||
for a, b in enumerate(items([1, 2, 3])):
|
||||
echo a, " ", b
|
||||
|
||||
for a2, b2 in enumerate([1, 2, 3, 5]):
|
||||
echo a2, " ", b2
|
||||
{.pop.}
|
||||
10
tests/pragmas/t8741.nim
Normal file
10
tests/pragmas/t8741.nim
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
discard """
|
||||
line: 9
|
||||
errormsg: "cannot attach a custom pragma to 'a'"
|
||||
"""
|
||||
|
||||
for a {.gensym, inject.} in @[1,2,3]:
|
||||
discard
|
||||
|
||||
for a {.foobar.} in @[1,2,3]:
|
||||
discard
|
||||
13
tests/pragmas/tpushexperimental.nim
Normal file
13
tests/pragmas/tpushexperimental.nim
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
discard """
|
||||
output: '''0 1
|
||||
1 2
|
||||
2 3
|
||||
0 1
|
||||
1 2
|
||||
2 3
|
||||
3 5'''
|
||||
"""
|
||||
|
||||
import mpushexperimental
|
||||
|
||||
main(12)
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
discard """
|
||||
output: '''
|
||||
PEG AST traversal output
|
||||
------------------------
|
||||
pkNonTerminal: Sum @(2, 3)
|
||||
pkSequence: (Product (('+' / '-') Product)*)
|
||||
pkNonTerminal: Product @(3, 7)
|
||||
|
|
@ -26,6 +28,25 @@ pkNonTerminal: Sum @(2, 3)
|
|||
pkChar: '+'
|
||||
pkChar: '-'
|
||||
pkNonTerminal: Product @(3, 7)
|
||||
|
||||
Event parser output
|
||||
-------------------
|
||||
@[5.0]
|
||||
+
|
||||
@[5.0, 3.0]
|
||||
@[8.0]
|
||||
|
||||
/
|
||||
@[8.0, 2.0]
|
||||
@[4.0]
|
||||
|
||||
-
|
||||
@[4.0, 7.0]
|
||||
-*
|
||||
@[4.0, 7.0, 22.0]
|
||||
@[4.0, 154.0]
|
||||
-
|
||||
@[-150.0]
|
||||
'''
|
||||
"""
|
||||
|
||||
|
|
@ -36,43 +57,92 @@ const
|
|||
indent = " "
|
||||
|
||||
let
|
||||
pegSrc = """
|
||||
Expr <- Sum
|
||||
Sum <- Product (('+' / '-') Product)*
|
||||
Product <- Value (('*' / '/') Value)*
|
||||
Value <- [0-9]+ / '(' Expr ')'
|
||||
"""
|
||||
pegAst: Peg = pegSrc.peg
|
||||
pegAst = """
|
||||
Expr <- Sum
|
||||
Sum <- Product (('+' / '-')Product)*
|
||||
Product <- Value (('*' / '/')Value)*
|
||||
Value <- [0-9]+ / '(' Expr ')'
|
||||
""".peg
|
||||
txt = "(5+3)/2-7*22"
|
||||
|
||||
var
|
||||
outp = newStringStream()
|
||||
processed: seq[string] = @[]
|
||||
block:
|
||||
var
|
||||
outp = newStringStream()
|
||||
processed: seq[string] = @[]
|
||||
|
||||
proc prt(outp: Stream, kind: PegKind, s: string; level: int = 0) =
|
||||
outp.writeLine indent.repeat(level) & "$1: $2" % [$kind, s]
|
||||
proc prt(outp: Stream, kind: PegKind, s: string; level: int = 0) =
|
||||
outp.writeLine indent.repeat(level) & "$1: $2" % [$kind, s]
|
||||
|
||||
proc recLoop(p: Peg, level: int = 0) =
|
||||
case p.kind
|
||||
of pkEmpty..pkWhitespace:
|
||||
discard
|
||||
of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle:
|
||||
outp.prt(p.kind, $p, level)
|
||||
of pkChar, pkGreedyRepChar:
|
||||
outp.prt(p.kind, $p, level)
|
||||
of pkCharChoice, pkGreedyRepSet:
|
||||
outp.prt(p.kind, $p, level)
|
||||
of pkNonTerminal:
|
||||
outp.prt(p.kind,
|
||||
"$1 @($3, $4)" % [p.nt.name, $p.nt.rule.kind, $p.nt.line, $p.nt.col], level)
|
||||
if not(p.nt.name in processed):
|
||||
processed.add p.nt.name
|
||||
p.nt.rule.recLoop level+1
|
||||
of pkBackRef..pkBackRefIgnoreStyle:
|
||||
outp.prt(p.kind, $p, level)
|
||||
else:
|
||||
outp.prt(p.kind, $p, level)
|
||||
for s in items(p):
|
||||
s.recLoop level+1
|
||||
proc recLoop(p: Peg, level: int = 0) =
|
||||
case p.kind
|
||||
of pkEmpty..pkWhitespace:
|
||||
discard
|
||||
of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle:
|
||||
outp.prt(p.kind, $p, level)
|
||||
of pkChar, pkGreedyRepChar:
|
||||
outp.prt(p.kind, $p, level)
|
||||
of pkCharChoice, pkGreedyRepSet:
|
||||
outp.prt(p.kind, $p, level)
|
||||
of pkNonTerminal:
|
||||
outp.prt(p.kind,
|
||||
"$1 @($3, $4)" % [p.nt.name, $p.nt.rule.kind, $p.nt.line, $p.nt.col], level)
|
||||
if not(p.nt.name in processed):
|
||||
processed.add p.nt.name
|
||||
p.nt.rule.recLoop level+1
|
||||
of pkBackRef..pkBackRefIgnoreStyle:
|
||||
outp.prt(p.kind, $p, level)
|
||||
else:
|
||||
outp.prt(p.kind, $p, level)
|
||||
for s in items(p):
|
||||
s.recLoop level+1
|
||||
|
||||
pegAst.recLoop
|
||||
echo outp.data
|
||||
pegAst.recLoop
|
||||
echo "PEG AST traversal output"
|
||||
echo "------------------------"
|
||||
echo outp.data
|
||||
|
||||
block:
|
||||
var
|
||||
pStack: seq[string] = @[]
|
||||
valStack: seq[float] = @[]
|
||||
opStack = ""
|
||||
let
|
||||
parseArithExpr = pegAst.eventParser:
|
||||
pkNonTerminal:
|
||||
enter:
|
||||
pStack.add p.nt.name
|
||||
leave:
|
||||
pStack.setLen pStack.high
|
||||
if length > 0:
|
||||
let matchStr = s.substr(start, start+length-1)
|
||||
case p.nt.name
|
||||
of "Value":
|
||||
try:
|
||||
valStack.add matchStr.parseFloat
|
||||
echo valStack
|
||||
except ValueError:
|
||||
discard
|
||||
of "Sum", "Product":
|
||||
try:
|
||||
let val = matchStr.parseFloat
|
||||
except ValueError:
|
||||
if valStack.len > 1 and opStack.len > 0:
|
||||
valStack[^2] = case opStack[^1]
|
||||
of '+': valStack[^2] + valStack[^1]
|
||||
of '-': valStack[^2] - valStack[^1]
|
||||
of '*': valStack[^2] * valStack[^1]
|
||||
else: valStack[^2] / valStack[^1]
|
||||
valStack.setLen valStack.high
|
||||
echo valStack
|
||||
opStack.setLen opStack.high
|
||||
echo opStack
|
||||
pkChar:
|
||||
leave:
|
||||
if length == 1 and "Value" != pStack[^1]:
|
||||
let matchChar = s[start]
|
||||
opStack.add matchChar
|
||||
echo opStack
|
||||
echo "Event parser output"
|
||||
echo "-------------------"
|
||||
let pLen = parseArithExpr(txt)
|
||||
assert txt.len == pLen
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ discard """
|
|||
|
||||
[Suite] bug #5784
|
||||
|
||||
[Suite] test suite
|
||||
|
||||
[Suite] test name filtering
|
||||
|
||||
'''
|
||||
|
|
@ -123,6 +125,23 @@ suite "bug #5784":
|
|||
var obj: Obj
|
||||
check obj.isNil or obj.field == 0
|
||||
|
||||
type
|
||||
SomeType = object
|
||||
value: int
|
||||
children: seq[SomeType]
|
||||
|
||||
# bug #5252
|
||||
|
||||
proc `==`(a, b: SomeType): bool =
|
||||
return a.value == b.value
|
||||
|
||||
suite "test suite":
|
||||
test "test":
|
||||
let a = SomeType(value: 10)
|
||||
let b = SomeType(value: 10)
|
||||
|
||||
check(a == b)
|
||||
|
||||
when defined(testing):
|
||||
suite "test name filtering":
|
||||
test "test name":
|
||||
|
|
|
|||
|
|
@ -106,4 +106,12 @@ var nilstring: string
|
|||
bar(nilstring)
|
||||
|
||||
static:
|
||||
stringCompare()
|
||||
stringCompare()
|
||||
|
||||
# bug 8847
|
||||
var a2: cstring = "fo\"o2"
|
||||
|
||||
block:
|
||||
var s: string
|
||||
s.addQuoted a2
|
||||
doAssert s == "\"fo\\\"o2\""
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import sequtils, os
|
||||
|
||||
template glob_rst(basedir: string = ""): untyped =
|
||||
if baseDir.isNil:
|
||||
if baseDir.len == 0:
|
||||
to_seq(walk_files("*.rst"))
|
||||
else:
|
||||
to_seq(walk_files(basedir/"*.rst"))
|
||||
|
|
|
|||
23
tests/template/tnested_template.nim
Normal file
23
tests/template/tnested_template.nim
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# bug #8052
|
||||
|
||||
type
|
||||
UintImpl*[N: static[int], T: SomeUnsignedInt] = object
|
||||
raw_data*: array[N, T]
|
||||
|
||||
template genLoHi(TypeImpl: untyped): untyped =
|
||||
template loImpl[N: static[int], T: SomeUnsignedInt](dst: TypeImpl[N div 2, T], src: TypeImpl[N, T]) =
|
||||
let halfSize = N div 2
|
||||
for i in 0 ..< halfSize:
|
||||
dst.raw_data[i] = src.raw_data[i]
|
||||
|
||||
proc lo*[N: static[int], T: SomeUnsignedInt](x: TypeImpl[N,T]): TypeImpl[N div 2, T] {.inline.}=
|
||||
loImpl(result, x)
|
||||
|
||||
genLoHi(UintImpl)
|
||||
|
||||
var a: UintImpl[4, uint32]
|
||||
|
||||
a.raw_data = [1'u32, 2'u32, 3'u32, 4'u32]
|
||||
assert a.lo.raw_data.len == 2
|
||||
assert a.lo.raw_data[0] == 1
|
||||
assert a.lo.raw_data[1] == 2
|
||||
|
|
@ -9,3 +9,22 @@ template something(name: untyped) =
|
|||
|
||||
something(what)
|
||||
what(10)
|
||||
|
||||
# bug #4750
|
||||
|
||||
type
|
||||
O = object
|
||||
i: int
|
||||
|
||||
OP = ptr O
|
||||
|
||||
template alf(p: pointer): untyped =
|
||||
cast[OP](p)
|
||||
|
||||
|
||||
proc t1(al: pointer) =
|
||||
var o = alf(al)
|
||||
|
||||
proc t2(alf: pointer) =
|
||||
var x = alf
|
||||
var o = alf(x)
|
||||
|
|
|
|||
15
tests/varres/tprevent_forloopvar_mutations.nim
Normal file
15
tests/varres/tprevent_forloopvar_mutations.nim
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
discard """
|
||||
line: 15
|
||||
errmsg: "type mismatch: got <int>"
|
||||
nimout: '''type mismatch: got <int>
|
||||
but expected one of:
|
||||
proc inc[T: Ordinal | uint | uint64](x: var T; y = 1)
|
||||
for a 'var' type a variable needs to be passed, but 'i' is immutable
|
||||
|
||||
expression: inc i
|
||||
'''
|
||||
"""
|
||||
|
||||
for i in 0..10:
|
||||
echo i
|
||||
inc i
|
||||
|
|
@ -2,6 +2,8 @@ discard """
|
|||
output: '''[127, 127, 0, 255]
|
||||
[127, 127, 0, 255]
|
||||
'''
|
||||
|
||||
nimout: '''caught Exception'''
|
||||
"""
|
||||
|
||||
#bug #1009
|
||||
|
|
@ -34,3 +36,16 @@ proc ABGR*(val: int| int64): TAggRgba8 =
|
|||
const
|
||||
c1 = ABGR(0xFF007F7F)
|
||||
echo ABGR(0xFF007F7F).repr, c1.repr
|
||||
|
||||
|
||||
# bug 8740
|
||||
|
||||
static:
|
||||
try:
|
||||
raise newException(ValueError, "foo")
|
||||
except Exception:
|
||||
echo "caught Exception"
|
||||
except Defect:
|
||||
echo "caught Defect"
|
||||
except ValueError:
|
||||
echo "caught ValueError"
|
||||
Loading…
Add table
Add a link
Reference in a new issue