Merge branch 'devel' into experimentalize-reorder

This commit is contained in:
awr1 2018-09-04 16:33:52 -05:00 • committed by GitHub
commit eb668003bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
241 changed files with 6388 additions and 12619 deletions

60
tests/arithm/tcast.nim Normal file
View 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)

View file

@ -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]

View 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"

View file

@ -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")

View 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
View 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
View 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()

View file

@ -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
View 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
View 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
View 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)

View file

@ -3,8 +3,8 @@ discard """
0
0
0
[[a = nil,
b = nil]]'''
[[a = "",
b = []]]'''
"""
# bug #1475

View file

@ -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:

View file

@ -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!"

View 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

View file

@ -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>.}

View 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

View 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)

View file

@ -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

View file

@ -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

View 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)

View file

@ -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"

View file

@ -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

View file

@ -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
View 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
View 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()

View file

@ -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

View file

@ -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
View 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

View file

@ -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:

View file

@ -7,3 +7,4 @@ path = "dependencies/genpacket"
path = "enet_server"
debugger = off
warning[SmallLshouldNotBeUsed] = off
nilseqs = on

View file

@ -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

View 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
View 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()

View 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
View 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

View 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)

View file

@ -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

View file

@ -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":

View file

@ -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\""

View file

@ -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"))

View 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

View file

@ -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)

View 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

View file

@ -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"