diff options
Diffstat (limited to 'tests/parser')
41 files changed, 1717 insertions, 114 deletions
diff --git a/tests/parser/t12274.nim b/tests/parser/t12274.nim new file mode 100644 index 000000000..6b7c9f55a --- /dev/null +++ b/tests/parser/t12274.nim @@ -0,0 +1,13 @@ +discard """ + joinable: false +""" + +var s: seq[int] +s.add block: + let i = 1 + i +s.add try: + 2 +except: + 3 +doAssert s == @[1, 2] diff --git a/tests/parser/t15667.nim b/tests/parser/t15667.nim new file mode 100644 index 000000000..fcb862825 --- /dev/null +++ b/tests/parser/t15667.nim @@ -0,0 +1,61 @@ +discard """ + cmd: "nim check $options $file" + action: "reject" + nimout: ''' +t15667.nim(23, 5) Error: invalid indentation, maybe you forgot a '=' at t15667.nim(22, 13) ? +t15667.nim(28, 5) Error: invalid indentation, maybe you forgot a '=' at t15667.nim(26, 13) ? +t15667.nim(33, 5) Error: invalid indentation, maybe you forgot a '=' at t15667.nim(31, 25) ? +t15667.nim(42, 5) Error: invalid indentation, maybe you forgot a '=' at t15667.nim(38, 12) ? +t15667.nim(56, 5) Error: invalid indentation, maybe you forgot a '=' at t15667.nim(55, 13) ? +t15667.nim(61, 48) Error: expression expected, but found ',' +''' +""" + + + + + + + +# line 20 +block: + proc fn1() + discard + +block: + proc fn2() + # + discard + +block: + proc fn3() {.exportc.} + # + discard + +block: # complex example + proc asdfasdfsd() {. exportc, + inline + .} # foo + #[ + bar + ]# + discard + +block: # xxx this doesn't work yet (only a bare `invalid indentation` error) + proc fn5() + ## + discard + +block: # ditto + proc fn6*() + ## foo bar + runnableExamples: discard + +block: + proc fn8() + runnableExamples: + discard + discard + +# semiStmtList loop issue +proc bar(k:static bool):SomeNumber = (when k: 3, else: 3.0) diff --git a/tests/parser/t19430.nim b/tests/parser/t19430.nim new file mode 100644 index 000000000..c1aa6a92d --- /dev/null +++ b/tests/parser/t19430.nim @@ -0,0 +1,3 @@ +let x = proc() = ## abc +let y = 3 #[tt.Error +^ invalid indentation]# diff --git a/tests/parser/t19662.nim b/tests/parser/t19662.nim new file mode 100644 index 000000000..7a1864ac6 --- /dev/null +++ b/tests/parser/t19662.nim @@ -0,0 +1,6 @@ + var i: int # bug #19662 +echo i + +discard """ + errormsg: "invalid indentation" +""" \ No newline at end of file diff --git a/tests/parser/t20922.nim b/tests/parser/t20922.nim new file mode 100644 index 000000000..110610fb1 --- /dev/null +++ b/tests/parser/t20922.nim @@ -0,0 +1,35 @@ +discard """ + cmd: "nim check $options --verbosity:0 --hints:off $file" + action: "reject" + nimout: ''' +t20922.nim(26, 5) Error: expression expected, but found ':' +t20922.nim(34, 7) Error: expression expected, but found ':' +t20922.nim(35, 5) Error: ':' or '=' expected, but got 'keyword of' +Error: in expression ' '+'': identifier expected, but found '' +t20922.nim(26, 7) Error: attempting to call undeclared routine: '<Error>' +Error: in expression ' '+'': identifier expected, but found '' +t20922.nim(26, 7) Error: attempting to call undeclared routine: '<Error>' +t20922.nim(26, 7) Error: expression '' cannot be called +t20922.nim(26, 7) Error: expression '' has no type (or is ambiguous) +t20922.nim(26, 7) Error: VM problem: dest register is not set +''' +""" +# original test case issue #20922 +type Token = enum + incDataPtr, + incDataPtrByte + +proc mapInstrToToken(instr: char): Token = + case instr: + of '>': + incDataPtr + of: '+': + incDataPtrByte + +# same issue with `of` in object branches (different parser procs calling `exprList`) +type + Bar = enum A, B + Foo = object + case kind: Bar + of: x: int + of B: y: float diff --git a/tests/parser/tbinarynotindented.nim b/tests/parser/tbinarynotindented.nim new file mode 100644 index 000000000..8d124aade --- /dev/null +++ b/tests/parser/tbinarynotindented.nim @@ -0,0 +1,3 @@ +type Foo = ref int + not nil #[tt.Error + ^ invalid indentation]# diff --git a/tests/parser/tbinarynotsameline.nim b/tests/parser/tbinarynotsameline.nim new file mode 100644 index 000000000..ca417e023 --- /dev/null +++ b/tests/parser/tbinarynotsameline.nim @@ -0,0 +1,10 @@ +# issue #23565 + +func foo: bool = + true + +const bar = block: + type T = int + not foo() + +doAssert not bar diff --git a/tests/parser/tcommand_as_expr.nim b/tests/parser/tcommand_as_expr.nim index b25ec4bd8..f37c34f63 100644 --- a/tests/parser/tcommand_as_expr.nim +++ b/tests/parser/tcommand_as_expr.nim @@ -36,3 +36,12 @@ echo f -4 echo int -1 # doesn't compile echo int `-` 1 # compiles + +var num = 1 +num += int 2 +doAssert num == 3 + +import options +var opt = some some none int +opt = some some none int +opt = some none Option[int] diff --git a/tests/parser/tcommandequals.nim b/tests/parser/tcommandequals.nim new file mode 100644 index 000000000..f41b318ac --- /dev/null +++ b/tests/parser/tcommandequals.nim @@ -0,0 +1,17 @@ +discard """ + output: ''' +5 +''' +""" + +proc foo(a, b: int) = + echo a + b + +foo a = 2, b = 3 + +import macros + +macro bar(args: varargs[untyped]): untyped = + doAssert args[0].kind == nnkExprEqExpr + +bar "a" = 1 diff --git a/tests/parser/tcommandindent.nim b/tests/parser/tcommandindent.nim new file mode 100644 index 000000000..449c218db --- /dev/null +++ b/tests/parser/tcommandindent.nim @@ -0,0 +1,16 @@ +when false: # parse the following + let foo = Obj( + field1: proc (src: pointer, srcLen: Natural) + {.nimcall, gcsafe, raises: [IOError, Defect].} = + var file = FileOutputStream(s).file + + implementWrites s.buffers, src, srcLen, "FILE", + writeStartAddr, writeLen, + file.writeBuffer(writeStartAddr, writeLen) + , + field2: proc {.nimcall, gcsafe, raises: [IOError, Defect].} = + flushFile FileOutputStream(s).file + , + field3: proc () {.nimcall, gcsafe, raises: [IOError, Defect].} = + close FileOutputStream(s).file + ) diff --git a/tests/parser/tdo.nim b/tests/parser/tdo.nim index 7bd1f7411..382d03398 100644 --- a/tests/parser/tdo.nim +++ b/tests/parser/tdo.nim @@ -1,8 +1,12 @@ discard """ - output: '''true + output: ''' true true -true inner B''' +true +true inner B +running with pragma +ran with pragma +''' """ template withValue(a, b, c, d, e: untyped) = @@ -77,3 +81,14 @@ proc main2 = echo "true inner B" main2() + +proc withPragma(foo: int, bar: proc() {.raises: [].}) = + echo "running with pragma" + bar() + +withPragma(3) do {.raises: [].}: + echo "ran with pragma" + +doAssert not (compiles do: + withPragma(3) do {.raises: [].}: + raise newException(Exception)) diff --git a/tests/parser/tdoc_comments.nim b/tests/parser/tdoc_comments.nim index fa1374b45..3c86e69ea 100644 --- a/tests/parser/tdoc_comments.nim +++ b/tests/parser/tdoc_comments.nim @@ -69,3 +69,7 @@ type MyEnum3* = enum value5 ## only document the enum value + +# bug #18847 +proc close*() = ## asdfasdfsdfa + discard ## adsfasdfads diff --git a/tests/parser/tdomulttest.nim b/tests/parser/tdomulttest.nim index 418192ac8..9e1afd034 100644 --- a/tests/parser/tdomulttest.nim +++ b/tests/parser/tdomulttest.nim @@ -1,14 +1,14 @@ discard """ - file: "tdomulttest.nim" output: "555\ntest\nmulti lines\n99999999\nend" - disabled: true """ + proc foo(bar, baz: proc (x: int): int) = echo bar(555) echo baz(99999999) foo do (x: int) -> int: return x + do (x: int) -> int: echo("test") echo("multi lines") diff --git a/tests/parser/tdotlikeoperators.nim b/tests/parser/tdotlikeoperators.nim new file mode 100644 index 000000000..c2d23bd15 --- /dev/null +++ b/tests/parser/tdotlikeoperators.nim @@ -0,0 +1,30 @@ +discard """ + matrix: "-d:nimPreviewDotLikeOps" +""" +# test for https://github.com/nim-lang/RFCs/issues/341 +import std/json +import std/jsonutils +import std/macros + +macro fn1(a: untyped): string = newLit a.lispRepr + +doAssert fn1(a.?b.c) == """(DotExpr (Infix (Ident ".?") (Ident "a") (Ident "b")) (Ident "c"))""" + +template `.?`(a: JsonNode, b: untyped{ident}): JsonNode = + a[astToStr(b)] + +proc identity[T](a: T): T = a +proc timesTwo[T](a: T): T = a * 2 + +template main = + let a = (a1: 1, a2: "abc", a3: (a4: 2.5)) + let j = a.toJson + doAssert j.?a1.getInt == 1 + doAssert j.?a3.?a4.getFloat == 2.5 + doAssert j.?a3.?a4.getFloat.timesTwo == 5.0 + doAssert j.?a3.identity.?a4.getFloat.timesTwo == 5.0 + doAssert j.identity.?a3.identity.?a4.identity.getFloat.timesTwo == 5.0 + doAssert j.identity.?a3.?a4.identity.getFloat.timesTwo == 5.0 + +static: main() +main() diff --git a/tests/parser/tdoublenotnil.nim b/tests/parser/tdoublenotnil.nim new file mode 100644 index 000000000..c61008c54 --- /dev/null +++ b/tests/parser/tdoublenotnil.nim @@ -0,0 +1,3 @@ +when false: + type Foo = Bar not nil not nil #[tt.Error + ^ invalid indentation]# diff --git a/tests/parser/tifexprs.nim b/tests/parser/tifexprs.nim new file mode 100644 index 000000000..3a7e2bddc --- /dev/null +++ b/tests/parser/tifexprs.nim @@ -0,0 +1,12 @@ +discard """ + output: ''' +1 +''' +""" + +var a, b: int +let x = if a > b: + 0 + else: 1 + +echo x diff --git a/tests/parser/tifextracolon.nim b/tests/parser/tifextracolon.nim new file mode 100644 index 000000000..171569111 --- /dev/null +++ b/tests/parser/tifextracolon.nim @@ -0,0 +1,8 @@ +# issue #21982 + +if true: + if true: + discard default int: +else: #[tt.Error +^ invalid indentation]# + discard diff --git a/tests/parser/tinvcolonlocation1.nim b/tests/parser/tinvcolonlocation1.nim index 2fddab2f8..7fca5deb7 100644 --- a/tests/parser/tinvcolonlocation1.nim +++ b/tests/parser/tinvcolonlocation1.nim @@ -1,8 +1,8 @@ discard """ + errormsg: "expected: ':', but got: 'echo'" file: "tinvcolonlocation1.nim" line: 8 column: 7 - errormsg: "expected: ':', but got: 'echo'" """ try #<- missing ':' echo "try" diff --git a/tests/parser/tinvcolonlocation2.nim b/tests/parser/tinvcolonlocation2.nim index 4251598b9..e3de393b8 100644 --- a/tests/parser/tinvcolonlocation2.nim +++ b/tests/parser/tinvcolonlocation2.nim @@ -1,8 +1,8 @@ discard """ + errormsg: "expected: ':', but got: 'keyword finally'" file: "tinvcolonlocation2.nim" line: 11 column: 8 - errormsg: "expected: ':', but got: 'keyword finally'" """ try: echo "try" diff --git a/tests/parser/tinvcolonlocation3.nim b/tests/parser/tinvcolonlocation3.nim index a8db658eb..46252f24e 100644 --- a/tests/parser/tinvcolonlocation3.nim +++ b/tests/parser/tinvcolonlocation3.nim @@ -1,8 +1,8 @@ discard """ + errormsg: "expected: ':', but got: 'echo'" file: "tinvcolonlocation3.nim" line: 12 column: 7 - errormsg: "expected: ':', but got: 'echo'" """ try: echo "try" diff --git a/tests/parser/tinvifstmt.nim b/tests/parser/tinvifstmt.nim new file mode 100644 index 000000000..0455bce60 --- /dev/null +++ b/tests/parser/tinvifstmt.nim @@ -0,0 +1,12 @@ +discard """ + errormsg: "invalid indentation" + line: 9 + column: 3 +""" + +if true: + echo "a" + elif: + echo "b" + else: + echo "c" diff --git a/tests/parser/tinvwhen.nim b/tests/parser/tinvwhen.nim index 99701bdf5..7a47f69a4 100644 --- a/tests/parser/tinvwhen.nim +++ b/tests/parser/tinvwhen.nim @@ -1,7 +1,7 @@ discard """ + errormsg: "invalid indentation" file: "tinvwhen.nim" line: 11 - errormsg: "invalid indentation" """ # This was parsed even though it should not! @@ -11,5 +11,3 @@ proc getcwd(buf: cstring, buflen: cint): cstring when defined(unix): {.importc: "getcwd", header: "<unistd.h>".} #ERROR_MSG invalid indentation elif defined(windows): {.importc: "getcwd", header: "<direct.h>"} else: {.error: "os library not ported to your OS. Please help!".} - - diff --git a/tests/parser/tletcolon.nim b/tests/parser/tletcolon.nim index 7eaa5e3e5..a2dde148a 100644 --- a/tests/parser/tletcolon.nim +++ b/tests/parser/tletcolon.nim @@ -58,4 +58,18 @@ block: var y = 2 echo "block expression works" y*y - doAssert x == 4 \ No newline at end of file + doAssert x == 4 + + +# bug 10861 +macro foo(a: untyped): untyped = + a + +let c1 = foo: + 1 + 1 + +const c2 = foo: + 1 + 1 + +const c3 = + foo: 1 + 1 diff --git a/tests/parser/toprprec.nim b/tests/parser/toprprec.nim index 1acd381e7..e6a43d42e 100644 --- a/tests/parser/toprprec.nim +++ b/tests/parser/toprprec.nim @@ -1,10 +1,9 @@ discard """ - file: "toprprec.nim" output: "done" """ # Test operator precedence: -template `@` (x: untyped): untyped {.immediate.} = +template `@@` (x: untyped): untyped = `self`.x template `@!` (x: untyped): untyped = x @@ -16,11 +15,11 @@ type TA = tuple[a, b: int, obj: TO] proc init(self: var TA): string = - @a = 3 - === @b = 4 - @obj.x = 4 + @@a = 3 + === @@b = 4 + @@obj.x = 4 @! === result = "abc" - result = @b.`$` + result = @@b.`$` assert 3+5*5-2 == 28- -26-28 diff --git a/tests/parser/tpostexprblocks.nim b/tests/parser/tpostexprblocks.nim index c27bbf321..6cd4a8350 100644 --- a/tests/parser/tpostexprblocks.nim +++ b/tests/parser/tpostexprblocks.nim @@ -406,6 +406,105 @@ StmtList DiscardStmt Empty IntLit 0 + Command + Ident "foo390" + Call + Ident "x" + Do + Empty + Empty + Empty + FormalParams + Empty + IdentDefs + Ident "y" + Empty + Empty + Empty + Empty + StmtList + DiscardStmt + Empty + Do + Empty + Empty + Empty + FormalParams + Ident "int" + IdentDefs + Ident "z" + Empty + Empty + Empty + Empty + StmtList + DiscardStmt + Empty + Do + Empty + Empty + Empty + FormalParams + Ident "int" + IdentDefs + Ident "w" + Ident "int" + Empty + Empty + Empty + StmtList + DiscardStmt + Empty + StmtList + DiscardStmt + Empty + OfBranch + Ident "a" + StmtList + DiscardStmt + Empty + OfBranch + TupleConstr + Ident "a" + Ident "b" + StmtList + DiscardStmt + Empty + ElifBranch + Ident "a" + StmtList + DiscardStmt + Empty + ElifBranch + TupleConstr + Ident "a" + Ident "b" + StmtList + DiscardStmt + Empty + ExceptBranch + Ident "a" + StmtList + DiscardStmt + Empty + ExceptBranch + TupleConstr + Ident "a" + Ident "b" + StmtList + DiscardStmt + Empty + Finally + StmtList + DiscardStmt + Empty + + Call + Ident "foo" + Finally + StmtList + DiscardStmt + Empty ''' """ @@ -540,3 +639,30 @@ dumpTree: foo380.add((quote do: discard )[0]) + + foo390 x do (y): + discard + do (z) -> int: + discard + do (w: int) -> int: + discard + do: + discard + of a: + discard + of (a, b): + discard + elif a: + discard + elif (a, b): + discard + except a: + discard + except (a, b): + discard + finally: + discard + + foo: + finally: + discard diff --git a/tests/parser/tprecedence.nim b/tests/parser/tprecedence.nim index d586f14a3..9be79543b 100644 --- a/tests/parser/tprecedence.nim +++ b/tests/parser/tprecedence.nim @@ -1,7 +1,8 @@ discard """ output: '''holla true -defabc 4''' +defabc 4 +0''' """ # Test top level semicolon works properly: @@ -19,3 +20,44 @@ proc foo[S, T](x: S, y: T): T = x & y proc bar[T](x: T): T = x echo "def".foo[:string, string]("abc"), " ", 4.bar[:int] + +# bug #9574 +proc isFalse(a: int): bool = false + +assert not isFalse(3) + +# bug #9633 + +type + MyField = object + b: seq[string] + + MyObject = object + f: MyField + +proc getX(x: MyObject): lent MyField {.inline.} = + x.f + +let a = MyObject() +echo a.getX.b.len + + +# bug #10458 +template t(x: untyped): untyped = "x" + +let + aaa = t 2 + 4 + ccc = t (1, 1) + 6 + ddd = t [0, 1, 2] + 5 + +# bug #10896 +const + test = + proc(): int = 1 + +# bug #8759 +block: + template `=>`(a, b): untyped = (a, b) + template `+=`(a, b): untyped = a * b + + doAssert ("abc" => 3 += 5) == ("abc", 15) diff --git a/tests/parser/tprocexprasstmt.nim b/tests/parser/tprocexprasstmt.nim new file mode 100644 index 000000000..22fb4a7c8 --- /dev/null +++ b/tests/parser/tprocexprasstmt.nim @@ -0,0 +1,14 @@ +func r(): auto = + func(): int = 2 +doAssert r()() == 2 + +block: # issue #11726 + let foo = block: + var x: int + proc = inc x # "identifier expected, but got '='" + + template paint(): untyped = + proc (s: string): string = s + + let s = paint() + doAssert s("abc") == "abc" diff --git a/tests/parser/tstatementoperators.nim b/tests/parser/tstatementoperators.nim new file mode 100644 index 000000000..d2b85bb4b --- /dev/null +++ b/tests/parser/tstatementoperators.nim @@ -0,0 +1,12 @@ +discard """ + nimout: ''' +Infix + Ident "from" + Ident "a" + Ident "b" +''' +""" + +from macros import dumpTree + +dumpTree(a from b) \ No newline at end of file diff --git a/tests/parser/tstmtlists.nim b/tests/parser/tstmtlists.nim new file mode 100644 index 000000000..158c93340 --- /dev/null +++ b/tests/parser/tstmtlists.nim @@ -0,0 +1,180 @@ +discard """ + output: ''' +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +hello +1 +hello +2 +hello +3 +hello +4 +hello +5 +hello +6 +hello +7 +hello +8 +hello +9 +hello +10 +hello +1 +hello +2 +hello +3 +hello +4 +hello +5 +hello +6 +hello +7 +hello +8 +hello +9 +hello +10 +lucky +lucky +''' +""" + +block: ( + discard; + echo 1 + 1; + ) + +block: ( + discard; #Haha + #haha + echo 1 + 1; +) + +block: ( + discard; + #Hmm + echo 1 + + 1; +) + +block: ( + discard + echo "2" +) + +block: ( + discard; + echo 1 + + 1 +) + +block: ( + discard + echo 1 + + 1 +) + +block: ( + discard; + discard +) + +block: ( + discard + echo 1 + 1; + ) + +block: ( + discard + echo 1 + 1; +) + +block: ( + discard + echo 1 + + 1; +) + +block: ( + discard; + ) + +block: ( discard; echo 1 + #heh + 1; +) + +for i in 1..10: + echo "hello" + echo i + +for i in 1..10: ( + echo "hello"; + echo i; +) + +proc square(inSeq: seq[float]): seq[float] = ( + result = newSeq[float](len(inSeq)); + for i, v in inSeq: ( + result[i] = v * v; + ) +) + +proc square2(inSeq: seq[float]): seq[float] = + result = newSeq[float](len(inSeq)); + for i, v in inSeq: ( + result[i] = v * v; + ) + +proc cstringCheck(tracked: int; n: int) = + if true == false and (let a = high(int); let b = high(int); + a.int8 == 8 and a.int8 notin {3..9}): + echo(tracked, n) + +template dim: int = + (if int.high == 0: + int.high + else: + int.high) + +template dim2: int = + (if int.high == 0: + int.high + else: + int.high) + +template dim3: int = + ( + if int.high == 0: + int.high + else: + int.high) + +# lenient indentation: + +echo (if 0 == 1: + "0 == 1" +else: + "lucky") + +# bug #16426 +echo (when 0 == 1: + "0 == 1" +else: + "lucky") + diff --git a/tests/parser/tstrongspaces.nim b/tests/parser/tstrongspaces.nim deleted file mode 100644 index adab7f709..000000000 --- a/tests/parser/tstrongspaces.nim +++ /dev/null @@ -1,83 +0,0 @@ -#? strongSpaces - -discard """ - output: '''35 -true -true -4 -true -1 -false -77 -(Field0: 1, Field1: 2, Field2: 2) -ha -true -tester args -all -all args -19 --3 -false --2 -''' -""" - -echo 2+5 * 5 - -# Keyword operators -echo 1 + 16 shl 1 == 1 + (16 shl 1) -echo 2 and 1 in {0, 30} -echo 2+2 * 2 shr 1 -echo false or 2 and 1 in {0, 30} - -proc `^`(a, b: int): int = a + b div 2 -echo 19 mod 16 ^ 4 + 2 and 1 -echo 18 mod 16 ^ 4 > 0 - -# echo $foo gotcha -let foo = 77 -echo $foo - -echo (1, 2, 2) - -template `&`(a, b: int): int = a and b -template `|`(a, b: int): int = a - b -template `++`(a, b: int): bool = a + b == 8009 - -when true: - let b = 66 - let c = 90 - let bar = 8000 - if foo+4 * 4 == 8 and b&c | 9 ++ - bar: - echo "ho" - else: - echo "ha" - - let booA = foo+4 * 4 - b&c | 9 + - bar - # is parsed as - let booB = ((foo+4)*4) - ((b&c) | 9) + bar - - echo booA == booB - - -template `|`(a, b): untyped = (if a.len > 0: a else: b) - -const - tester = "tester" - args = "args" - -echo tester & " " & args|"all" -echo "all" | tester & " " & args -echo "all"|tester & " " & args - -# Test arrow like operators. See also tests/macros/tclosuremacro.nim -proc `+->`(a, b: int): int = a + b*4 -template `===>`(a, b: int): int = a - b shr 1 - -echo 3 +-> 2 + 2 and 4 -var arrowed = 3+->2 + 2 and 4 # arrowed = 4 -echo arrowed ===> 15 -echo (2 * 3+->2) == (2*3 +-> 2) -echo arrowed ===> 2 + 3+->2 diff --git a/tests/parser/ttry.nim b/tests/parser/ttry.nim new file mode 100644 index 000000000..190b0b8dc --- /dev/null +++ b/tests/parser/ttry.nim @@ -0,0 +1,27 @@ +# bug #21144 +block: + try: + let c = try: + 10 + except ValueError as exc: + 10 + except ValueError as exc: + discard + +if true: + block: + let c = try: + 10 + except ValueError as exc: + 10 + except OSError: + 99 + + +try: + let c = try: + 10 + except ValueError as exc: + 10 +except ValueError as exc: + discard \ No newline at end of file diff --git a/tests/parser/ttupleunpack.nim b/tests/parser/ttupleunpack.nim index aaa06f9f4..993501fbb 100644 --- a/tests/parser/ttupleunpack.nim +++ b/tests/parser/ttupleunpack.nim @@ -1,9 +1,3 @@ -discard """ - file: "ttupleunpack.nim" - output: "" - exitcode: 0 -""" - proc returnsTuple(): (int, int, int) = (4, 2, 3) proc main2 = @@ -33,3 +27,68 @@ proc main() = main() main2() + +block: # nested unpacking + block: # simple let + let (a, (b, c), d) = (1, (2, 3), 4) + doAssert (a, b, c, d) == (1, 2, 3, 4) + let foo = (a, (b, c), d) + let (a2, (b2, c2), d2) = foo + doAssert (a, b, c, d) == (a2, b2, c2, d2) + + block: # var and assignment + var (x, (y, z), t) = ('a', (true, @[123]), "abc") + doAssert (x, y, z, t) == ('a', true, @[123], "abc") + (x, (y, z), t) = ('b', (false, @[456]), "def") + doAssert (x, y, z, t) == ('b', false, @[456], "def") + + block: # very nested + let (_, (_, (_, (_, (_, a))))) = (1, (2, (3, (4, (5, 6))))) + doAssert a == 6 + + block: # const + const (a, (b, c), d) = (1, (2, 3), 4) + doAssert (a, b, c, d) == (1, 2, 3, 4) + const foo = (a, (b, c), d) + const (a2, (b2, c2), d2) = foo + doAssert (a, b, c, d) == (a2, b2, c2, d2) + + block: # evaluation semantics preserved between literal and not literal + var s: seq[string] + block: # literal + let (a, (b, c), d) = ((s.add("a"); 1), ((s.add("b"); 2), (s.add("c"); 3)), (s.add("d"); 4)) + doAssert (a, b, c, d) == (1, 2, 3, 4) + doAssert s == @["a", "b", "c", "d"] + block: # underscore + s = @[] + let (a, (_, c), _) = ((s.add("a"); 1), ((s.add("b"); 2), (s.add("c"); 3)), (s.add("d"); 4)) + doAssert (a, c) == (1, 3) + doAssert s == @["a", "b", "c", "d"] + block: # temp + s = @[] + let foo = ((s.add("a"); 1), ((s.add("b"); 2), (s.add("c"); 3)), (s.add("d"); 4)) + let (a, (b, c), d) = foo + doAssert (a, b, c, d) == (1, 2, 3, 4) + doAssert s == @["a", "b", "c", "d"] + +block: # unary assignment unpacking + var a: int + (a,) = (1,) + doAssert a == 1 + +block: # type annotations + block: # basic + let (a, b): (int, int) = (1, 2) + doAssert (a, b) == (1, 2) + block: # type inference + let (a, b): (byte, float) = (1, 2) + doAssert (a, b) == (1.byte, 2.0) + block: # type mismatch + doAssert not (compiles do: + let (a, b): (int, string) = (1, 2)) + block: # nested + let (a, (b, c)): (int, (int, int)) = (1, (2, 3)) + doAssert (a, b, c) == (1, 2, 3) + block: # nested type inference + let (a, (b, c)): (byte, (float, cstring)) = (1, (2, "abc")) + doAssert (a, b, c) == (1.byte, 2.0, cstring"abc") diff --git a/tests/parser/ttypeclasses.nim b/tests/parser/ttypeclasses.nim index 9f487c7a8..e6e7a48b8 100644 --- a/tests/parser/ttypeclasses.nim +++ b/tests/parser/ttypeclasses.nim @@ -1,17 +1,46 @@ -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: + doAssert x is ref + doAssert y is distinct + doAssert z is ptr + doAssert C is static + doAssert C[1] is static[int] + doAssert C[0] is static[SomeInteger] + doAssert C isnot static[string] + doAssert C is SEQ|OBJ + doAssert C isnot OBJ|TPL + doAssert int is int + doAssert int is T + doAssert int is SomeInteger + doAssert seq[int] is type + doAssert seq[int] is type[seq] + doAssert seq[int] isnot type[seq[float]] + doAssert i isnot type[int] + doAssert type(i) is type[int] + doAssert x isnot T + doAssert y isnot S + doAssert z isnot enum + doAssert x isnot object + doAssert y isnot tuple + doAssert z isnot seq + + # XXX: These cases don't work properly at the moment: + # doAssert type[int] isnot int + # doAssert type(int) isnot int -doAssert x is ref -doAssert y is distinct -doAssert z is ptr \ No newline at end of file diff --git a/tests/parser/ttypecommandcomma.nim b/tests/parser/ttypecommandcomma.nim new file mode 100644 index 000000000..7ca59a799 --- /dev/null +++ b/tests/parser/ttypecommandcomma.nim @@ -0,0 +1,9 @@ +discard """ + errormsg: "invalid indentation" + line: 8 + column: 19 +""" + +type + Foo = call(1, 2), 3: + 4 \ No newline at end of file diff --git a/tests/parser/ttypecommandindent1.nim b/tests/parser/ttypecommandindent1.nim new file mode 100644 index 000000000..9aa274e2a --- /dev/null +++ b/tests/parser/ttypecommandindent1.nim @@ -0,0 +1,9 @@ +discard """ + errormsg: "invalid indentation" + line: 9 + column: 3 +""" + +type + Foo = call x, y, z: + abc diff --git a/tests/parser/ttypecommandindent2.nim b/tests/parser/ttypecommandindent2.nim new file mode 100644 index 000000000..0883df90f --- /dev/null +++ b/tests/parser/ttypecommandindent2.nim @@ -0,0 +1,11 @@ +discard """ + errormsg: "invalid indentation" + line: 10 + column: 5 +""" + +type + Foo = call x, y, z: + abc + do: + def diff --git a/tests/parser/ttypecommandindent3.nim b/tests/parser/ttypecommandindent3.nim new file mode 100644 index 000000000..f9fdcc1e4 --- /dev/null +++ b/tests/parser/ttypecommandindent3.nim @@ -0,0 +1,11 @@ +discard """ + errormsg: "expression expected, but found 'keyword do'" + line: 10 + column: 1 +""" + +type + Foo = call x, y, z: + abc +do: + def diff --git a/tests/parser/ttypeexprobject.nim b/tests/parser/ttypeexprobject.nim new file mode 100644 index 000000000..6895f1731 --- /dev/null +++ b/tests/parser/ttypeexprobject.nim @@ -0,0 +1,10 @@ +discard """ + errormsg: "invalid indentation" + line: 10 + column: 14 +""" + +type + A = (object | tuple | int) + B = int | object | tuple + C = object | tuple | int # issue #8846 diff --git a/tests/parser/ttypeexprs.nim b/tests/parser/ttypeexprs.nim new file mode 100644 index 000000000..e40efc7d9 --- /dev/null +++ b/tests/parser/ttypeexprs.nim @@ -0,0 +1,25 @@ +proc foo[T: ptr int | ptr string](x: T) = discard +var x = "abc" +foo(addr x) + +let n = 3'u32 +type Double = ( + when n.sizeof == 4: uint64 + elif n.sizeof == 2: uint32 + else: uint16 +) + +type + A = (ref | ptr | pointer) + B = pointer | ptr | ref + C = ref | ptr | pointer + +template `+`(a, b): untyped = (b, a) +template `*`(a, b): untyped = (a, b) + +doAssert (ref int + ref float * ref string + ref bool) is + (ref bool, ((ref float, ref string), ref int)) +type X = ref int + ref float * ref string + ref bool +doAssert X is (ref bool, ((ref float, ref string), ref int)) + +type SomePointer = proc | ref | ptr | pointer diff --git a/tests/parser/ttypemodifiers.nim b/tests/parser/ttypemodifiers.nim new file mode 100644 index 000000000..9a1ccb1a5 --- /dev/null +++ b/tests/parser/ttypemodifiers.nim @@ -0,0 +1,526 @@ +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 + TupleConstr + 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 + TupleConstr + Ident "int" + Ident "string" + TypeDef + Ident "RefTupleVars" + Empty + RefTy + TupleConstr + 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" + TupleConstr + 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" + TupleConstr + Ident "a" + Ident "b" + TypeDef + Ident "TypeTuple" + Empty + Command + Ident "type" + TupleConstr + 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 + TupleConstr + 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 diff --git a/tests/parser/ttypesectioncalls.nim b/tests/parser/ttypesectioncalls.nim new file mode 100644 index 000000000..003444fc5 --- /dev/null +++ b/tests/parser/ttypesectioncalls.nim @@ -0,0 +1,328 @@ +discard """ +nimout: ''' +StmtList + TypeSection + TypeDef + Ident "A" + Empty + Call + Ident "call" + IntLit 1 + TypeSection + TypeDef + Ident "B" + Empty + Command + Ident "call" + IntLit 2 + TypeDef + Ident "C" + Empty + Call + Ident "call" + StmtList + IntLit 3 + TypeDef + Ident "D" + Empty + Call + Ident "call" + StmtList + IntLit 4 + TypeSection + TypeDef + Ident "E" + Empty + Call + Ident "call" + IntLit 5 + IntLit 6 + TypeDef + Ident "F" + Empty + Command + Ident "call" + IntLit 7 + IntLit 8 + TypeDef + Ident "G" + Empty + Call + Ident "call" + IntLit 9 + StmtList + IntLit 10 + TypeDef + Ident "H" + Empty + Call + Ident "call" + IntLit 11 + StmtList + IntLit 12 + TypeDef + Ident "I" + Empty + Command + Ident "call" + IntLit 13 + StmtList + IntLit 14 + TypeDef + Ident "J" + Empty + Command + Ident "call" + IntLit 15 + StmtList + IntLit 16 + TypeSection + TypeDef + Ident "K" + Empty + Call + Ident "call" + IntLit 17 + IntLit 18 + IntLit 19 + TypeDef + Ident "L" + Empty + Command + Ident "call" + IntLit 20 + IntLit 21 + IntLit 22 + TypeDef + Ident "M" + Empty + Call + Ident "call" + IntLit 23 + IntLit 24 + StmtList + IntLit 25 + TypeDef + Ident "N" + Empty + Command + Ident "call" + IntLit 26 + IntLit 27 + StmtList + IntLit 28 + TypeDef + Ident "O" + Empty + Command + Ident "call" + IntLit 29 + IntLit 30 + StmtList + IntLit 31 + TypeSection + TypeDef + Ident "P" + Empty + Command + Ident "call" + TupleConstr + IntLit 32 + IntLit 33 + Infix + Ident "+" + Infix + Ident "*" + IntLit 34 + IntLit 35 + IntLit 36 + StmtList + IntLit 37 + TypeDef + Ident "R" + Empty + Command + Ident "call" + Infix + Ident "@" + TupleConstr + IntLit 38 + IntLit 39 + Infix + Ident "shl" + IntLit 40 + IntLit 41 + Infix + Ident "-" + Infix + Ident "*" + IntLit 42 + IntLit 43 + IntLit 44 + StmtList + IntLit 45 + TypeDef + Ident "S" + Empty + Command + Ident "call" + IntLit 46 + StmtList + IntLit 47 + StmtList + IntLit 48 + TypeDef + Ident "T" + Empty + Call + Ident "call" + StmtList + IntLit 49 + StmtList + IntLit 50 + StmtList + IntLit 51 +a: IntLit 1 +a: IntLit 2 +a: StmtList + IntLit 3 +a: StmtList + IntLit 4 +a: IntLit 5 +b: IntLit 6 +a: IntLit 7 +b: IntLit 8 +a: IntLit 9 +b: StmtList + IntLit 10 +a: IntLit 11 +b: StmtList + IntLit 12 +a: IntLit 13 +b: StmtList + IntLit 14 +a: IntLit 15 +b: StmtList + IntLit 16 +a: IntLit 17 +b: IntLit 18 +c: IntLit 19 +a: IntLit 20 +b: IntLit 21 +c: IntLit 22 +a: IntLit 23 +b: IntLit 24 +c: StmtList + IntLit 25 +a: IntLit 26 +b: IntLit 27 +c: StmtList + IntLit 28 +a: IntLit 29 +b: IntLit 30 +c: StmtList + IntLit 31 +a: TupleConstr + IntLit 32 + IntLit 33 +b: Infix + Ident "+" + Infix + Ident "*" + IntLit 34 + IntLit 35 + IntLit 36 +c: StmtList + IntLit 37 +a: Infix + Ident "@" + TupleConstr + IntLit 38 + IntLit 39 + Infix + Ident "shl" + IntLit 40 + IntLit 41 +b: Infix + Ident "-" + Infix + Ident "*" + IntLit 42 + IntLit 43 + IntLit 44 +c: StmtList + IntLit 45 +a: IntLit 46 +b: StmtList + IntLit 47 +c: StmtList + IntLit 48 +a: StmtList + IntLit 49 +b: StmtList + IntLit 50 +c: StmtList + IntLit 51 +''' +""" +import macros + +macro call(a): untyped = + echo "a: ", a.treeRepr + result = ident"int" +macro call(a, b): untyped = + echo "a: ", a.treeRepr + echo "b: ", b.treeRepr + result = ident"int" +macro call(a, b, c): untyped = + echo "a: ", a.treeRepr + echo "b: ", b.treeRepr + echo "c: ", c.treeRepr + result = ident"int" + +macro sections(x): untyped = + echo x.treeRepr + result = newStmtList(x) + for ts in x: + for td in ts: + let t = td[0] + result.add quote do: + doAssert `t` is int + +sections: + type A = call(1) + type + B = call 2 + C = call: 3 + D = call(): 4 + type + E = call(5, 6) + F = call 7, 8 + G = call(9): 10 + H = call(11): + 12 + I = call 13: 14 + J = call 15: + 16 + type + K = call(17, 18, 19) + L = call 20, 21, 22 + M = call(23, 24): 25 + N = call 26, 27: 28 + O = call 29, 30: + 31 + type + P = call (32, 33), 34 * 35 + 36: + 37 + R = call (38, 39) @ 40 shl 41, 42 * 43 - 44: + 45 + S = call 46: + 47 + do: + 48 + T = call: + 49 + do: + 50 + do: + 51 |