summary refs log tree commit diff stats
path: root/tests/parser
diff options
context:
space:
mode:
Diffstat (limited to 'tests/parser')
-rw-r--r--tests/parser/t12274.nim13
-rw-r--r--tests/parser/t15667.nim61
-rw-r--r--tests/parser/t19430.nim3
-rw-r--r--tests/parser/t19662.nim6
-rw-r--r--tests/parser/t20922.nim35
-rw-r--r--tests/parser/tbinarynotindented.nim3
-rw-r--r--tests/parser/tbinarynotsameline.nim10
-rw-r--r--tests/parser/tcommand_as_expr.nim47
-rw-r--r--tests/parser/tcommandequals.nim17
-rw-r--r--tests/parser/tcommandindent.nim16
-rw-r--r--tests/parser/tdo.nim94
-rw-r--r--tests/parser/tdoc_comments.nim75
-rw-r--r--tests/parser/tdomulttest.nim17
-rw-r--r--tests/parser/tdotlikeoperators.nim30
-rw-r--r--tests/parser/tdoublenotnil.nim3
-rw-r--r--tests/parser/tifexprs.nim12
-rw-r--r--tests/parser/tifextracolon.nim8
-rw-r--r--tests/parser/tinvcolonlocation1.nim12
-rw-r--r--tests/parser/tinvcolonlocation2.nim15
-rw-r--r--tests/parser/tinvcolonlocation3.nim12
-rw-r--r--tests/parser/tinvifstmt.nim12
-rw-r--r--tests/parser/tinvwhen.nim13
-rw-r--r--tests/parser/tletcolon.nim75
-rw-r--r--tests/parser/tmultiline_comments.nim64
-rw-r--r--tests/parser/toprprec.nim37
-rw-r--r--tests/parser/tpostexprblocks.nim668
-rw-r--r--tests/parser/tprecedence.nim63
-rw-r--r--tests/parser/tprocexprasstmt.nim14
-rw-r--r--tests/parser/tproctype_pragmas.nim19
-rw-r--r--tests/parser/tstatementoperators.nim12
-rw-r--r--tests/parser/tstmtlists.nim180
-rw-r--r--tests/parser/ttry.nim27
-rw-r--r--tests/parser/ttupleunpack.nim94
-rw-r--r--tests/parser/ttypeclasses.nim46
-rw-r--r--tests/parser/ttypecommandcomma.nim9
-rw-r--r--tests/parser/ttypecommandindent1.nim9
-rw-r--r--tests/parser/ttypecommandindent2.nim11
-rw-r--r--tests/parser/ttypecommandindent3.nim11
-rw-r--r--tests/parser/ttypeexprobject.nim10
-rw-r--r--tests/parser/ttypeexprs.nim25
-rw-r--r--tests/parser/ttypemodifiers.nim526
-rw-r--r--tests/parser/ttypeof.nim26
-rw-r--r--tests/parser/ttypesectioncalls.nim328
-rw-r--r--tests/parser/twhen_in_enum.nim11
-rw-r--r--tests/parser/twrongcmdsyntax.nim6
45 files changed, 2785 insertions, 0 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
new file mode 100644
index 000000000..f37c34f63
--- /dev/null
+++ b/tests/parser/tcommand_as_expr.nim
@@ -0,0 +1,47 @@
+discard """
+  output: '''140
+5-120-120
+359
+77
+-4
+-1
+-1'''
+"""
+#import math
+import sequtils
+
+proc optarg(x:int, y:int = 0):int = x + 3 * y
+proc singlearg(x:int):int = 20*x
+echo optarg 1, singlearg 2
+
+
+proc foo(x: int): int = x-1
+proc foo(x, y: int): int = x-y
+
+let x = optarg foo 7.foo
+let y = singlearg foo(1, foo 8)
+let z = singlearg 1.foo foo 8
+
+echo x, y, z
+
+let a = [2,4,8].map do (d:int) -> int: d + 1
+echo a[0], a[1], a[2]
+
+echo(foo 8, foo 8)
+
+# bug #7582
+proc f(x: int): int = x
+
+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
new file mode 100644
index 000000000..382d03398
--- /dev/null
+++ b/tests/parser/tdo.nim
@@ -0,0 +1,94 @@
+discard """
+  output: '''
+true
+true
+true
+true inner B
+running with pragma
+ran with pragma
+'''
+"""
+
+template withValue(a, b, c, d, e: untyped) =
+  if c:
+    d
+  else:
+    e
+
+template withValue(a, b, c, d: untyped) =
+  if c:
+    d
+
+const
+  EVENT_READ = 1
+  EVENT_WRITE = 2
+  FLAG_HANDLE = 3
+  EVENT_MASK = 3
+
+var s: string
+
+proc main =
+  var value = false
+  var fd = 8888
+  var event = 0
+  s.withValue(fd, value) do:
+    if value:
+      var oe = (EVENT_MASK)
+      if (oe xor event) != 0:
+        if (oe and EVENT_READ) != 0 and (event and EVENT_READ) == 0:
+          discard
+        if (oe and EVENT_WRITE) != 0 and (event and EVENT_WRITE) == 0:
+          discard
+        if (oe and EVENT_READ) == 0 and (event and EVENT_READ) != 0:
+          discard
+        if (oe and EVENT_WRITE) == 0 and (event and EVENT_WRITE) != 0:
+          discard
+    else:
+      raise newException(ValueError, "error")
+  do:
+    raise newException(ValueError, "Descriptor is not registered in queue")
+
+proc main2 =
+  var unused = 8
+  # test 'then' branch:
+  s.withValue(unused, true) do:
+    echo "true"
+  do:
+    echo "false"
+
+  # test overloading:
+  s.withValue(unused, false) do:
+    echo "cannot come here"
+
+  # test 'else' branch:
+  s.withValue(unused, false) do:
+    echo "false"
+  do:
+    echo "true"
+
+  # test proper nesting:
+  s.withValue(unused, false) do:
+    echo "false"
+    s.withValue(unused, false) do:
+      echo "false inner A"
+    do:
+      echo "true inner A"
+  do:
+    echo "true"
+    s.withValue(unused, false) do:
+      echo "false inner B"
+    do:
+      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
new file mode 100644
index 000000000..3c86e69ea
--- /dev/null
+++ b/tests/parser/tdoc_comments.nim
@@ -0,0 +1,75 @@
+
+# bug #1799
+
+proc MyProc1*() = ## Comment behind procedure
+  discard
+
+proc MyProc2*() =
+  ## Comment below procedure
+  discard
+
+
+template MyTemplate1*() = discard ## Comment behind template
+
+template MyTemplate2*() = discard
+  ## Comment below template
+
+
+const
+  MyConst1* = 1 ## Comment behind constant
+  MyConst2* = 2
+    ## Comment below constant
+
+
+var
+  MyVar1* = 1 ## Comment behind variable
+  MyVar2* = 2
+    ## Comment below variable
+
+
+type
+  MyObject1* = object
+    ## Comment below declaration
+    field1*: int ## Comment behind field
+    field2*: int ## Comment behind field
+    field3*: int
+      ## Comment below field
+    field4*: int
+      ## Comment below field
+
+  MyObject2* = object ## Comment behind declaration
+    field1*: int
+
+
+type
+  MyTuple1* = tuple
+    ## Comment below declaration
+    field1: int ## Comment behind field
+    field2: int ## Comment behind field
+    field3: int
+      ## Comment below field
+    field4: int
+      ## Comment below field
+
+  MyTuple2* = tuple ## Comment behind declaration
+    field1: int
+
+
+type
+  MyEnum1* = enum
+    ## Comment below declaration
+    value1, ## Comment behind value
+    value2,
+      ## Comment below value with comma
+    value3
+      ## Comment below value without comma
+
+  MyEnum2* = enum ## Comment behind declaration
+    value4
+
+  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
new file mode 100644
index 000000000..9e1afd034
--- /dev/null
+++ b/tests/parser/tdomulttest.nim
@@ -0,0 +1,17 @@
+discard """
+  output: "555\ntest\nmulti lines\n99999999\nend"
+"""
+
+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")
+  return x
+
+echo("end")
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
new file mode 100644
index 000000000..7fca5deb7
--- /dev/null
+++ b/tests/parser/tinvcolonlocation1.nim
@@ -0,0 +1,12 @@
+discard """
+  errormsg: "expected: ':', but got: 'echo'"
+  file: "tinvcolonlocation1.nim"
+  line: 8
+  column: 7
+"""
+try #<- missing ':'
+  echo "try"
+except:
+  echo "except"
+finally:
+  echo "finally"
diff --git a/tests/parser/tinvcolonlocation2.nim b/tests/parser/tinvcolonlocation2.nim
new file mode 100644
index 000000000..e3de393b8
--- /dev/null
+++ b/tests/parser/tinvcolonlocation2.nim
@@ -0,0 +1,15 @@
+discard """
+  errormsg: "expected: ':', but got: 'keyword finally'"
+  file: "tinvcolonlocation2.nim"
+  line: 11
+  column: 8
+"""
+try:
+  echo "try"
+except #<- missing ':'
+  echo "except"
+finally:
+#<-- error will be here above, at the beginning of finally,
+#    since compiler tries to consome echo and part of except
+#    expression
+  echo "finally"
diff --git a/tests/parser/tinvcolonlocation3.nim b/tests/parser/tinvcolonlocation3.nim
new file mode 100644
index 000000000..46252f24e
--- /dev/null
+++ b/tests/parser/tinvcolonlocation3.nim
@@ -0,0 +1,12 @@
+discard """
+  errormsg: "expected: ':', but got: 'echo'"
+  file: "tinvcolonlocation3.nim"
+  line: 12
+  column: 7
+"""
+try:
+  echo "try"
+except:
+  echo "except"
+finally #<- missing ':'
+  echo "finally"
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
new file mode 100644
index 000000000..7a47f69a4
--- /dev/null
+++ b/tests/parser/tinvwhen.nim
@@ -0,0 +1,13 @@
+discard """
+  errormsg: "invalid indentation"
+  file: "tinvwhen.nim"
+  line: 11
+"""
+# This was parsed even though it should not!
+
+proc chdir(path: cstring): cint {.importc: "chdir", header: "dirHeader".}
+
+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
new file mode 100644
index 000000000..a2dde148a
--- /dev/null
+++ b/tests/parser/tletcolon.nim
@@ -0,0 +1,75 @@
+discard """
+  output: '''boo
+3
+44 3
+more body code
+yes
+yes
+block expression works'''
+"""
+
+template x(body): untyped =
+  body
+  44
+
+template y(val, body): untyped =
+  body
+  val
+
+proc mana =
+  let foo = x:
+    echo "boo"
+  var foo2: int
+  foo2 = y 3:
+    echo "3"
+  echo foo, " ", foo2
+
+mana()
+let other = x:
+  echo "more body code"
+  if true:
+    echo "yes"
+  else:
+    echo "no"
+let outer = y(5):
+  echo "yes"
+
+
+# bug #6609
+type
+  TextureInternalFormat = enum RED, RGB, RGBA
+
+const channels = 4
+
+let format =
+    if channels == 1:
+        TextureInternalFormat.RED
+    elif channels == 3:
+        TextureInternalFormat.RGB
+    elif channels == 4:
+        TextureInternalFormat.RGBA
+    else:
+        echo "Texture Format Unknown, assuming RGB"  #This echo causes an error
+        TextureInternalFormat.RGB
+
+# Block as expressions #3827
+block:
+  let x = block:
+    var y = 2
+    echo "block expression works"
+    y*y
+  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/tmultiline_comments.nim b/tests/parser/tmultiline_comments.nim
new file mode 100644
index 000000000..7a3bb5304
--- /dev/null
+++ b/tests/parser/tmultiline_comments.nim
@@ -0,0 +1,64 @@
+discard """
+  output: '''3'''
+"""
+
+proc main* =
+  ##[Mutltie akdlsf comment with #[nesting].
+  Yay, that is so cool.
+  ]##
+  echo "foo bar"
+  for s in ["one", "two", #["three",]# "four"]:
+    echo s
+
+var foo #[ Test the new inline comments ]#: int = 3
+##[ A
+novel documentation comment
+#[Nesting works to some extend]
+##[ Nested doc comment! ]##
+]#
+]##
+echo $foo
+
+  #[Comment here.
+  Multiple lines
+  are not a problem.]#
+
+  #[  #[ Multiline comment in already
+     commented out code. ]#
+  proc p[T](x: T) = discard
+  ]#
+
+proc bar =
+  ##[Long documentation comment
+  here.
+  ]##
+
+
+proc write(a: auto, x: varargs[string, `$`]) =
+  stdout.write ($a)
+  for o in x:
+    stdout.write(o)
+
+proc writeln(a: auto, x: varargs[string, `$`]) =
+  write a, x
+  stdout.write "\n"
+
+proc write() = write(stdout)
+proc writeln() =
+  stdout.write "\n"
+
+#[  #[ Multiline comment in already
+   commented out code. ]#
+proc p[T](x: T) = discard
+]#
+
+var hello = #[(x in bar)^^ "Hello" # greetings
+]#"Hello"
+proc maino =
+  write hello, " Test Me "
+  writeln()
+  write 3
+  block:
+    write()
+    write " times more"
+  #[ test ]#  writeln " Again"
diff --git a/tests/parser/toprprec.nim b/tests/parser/toprprec.nim
new file mode 100644
index 000000000..e6a43d42e
--- /dev/null
+++ b/tests/parser/toprprec.nim
@@ -0,0 +1,37 @@
+discard """
+  output: "done"
+"""
+# Test operator precedence:
+
+template `@@` (x: untyped): untyped =
+  `self`.x
+
+template `@!` (x: untyped): untyped = x
+template `===` (x: untyped): untyped = x
+
+type
+  TO = object
+    x: int
+  TA = tuple[a, b: int, obj: TO]
+
+proc init(self: var TA): string =
+  @@a = 3
+  === @@b = 4
+  @@obj.x = 4
+  @! === result = "abc"
+  result = @@b.`$`
+
+assert 3+5*5-2 == 28- -26-28
+
+proc `^-` (x, y: int): int =
+  # now right-associative!
+  result = x - y
+
+assert 34 ^- 6 ^- 2 == 30
+assert 34 - 6 - 2 == 26
+
+
+var s: TA
+assert init(s) == "4"
+
+echo "done"
diff --git a/tests/parser/tpostexprblocks.nim b/tests/parser/tpostexprblocks.nim
new file mode 100644
index 000000000..6cd4a8350
--- /dev/null
+++ b/tests/parser/tpostexprblocks.nim
@@ -0,0 +1,668 @@
+discard """
+nimout: '''
+StmtList
+  Ident "foo010"
+  Call
+    Ident "foo020"
+  Call
+    Ident "foo030"
+    Ident "x"
+  Command
+    Ident "foo040"
+    Ident "x"
+  Call
+    Ident "foo050"
+    StmtList
+      DiscardStmt
+        Empty
+  Call
+    Ident "foo060"
+    StmtList
+      DiscardStmt
+        Empty
+  Call
+    Ident "foo070"
+    StrLit "test"
+    StmtList
+      DiscardStmt
+        Empty
+  Call
+    Ident "foo080"
+    StrLit "test"
+    StmtList
+      DiscardStmt
+        Empty
+  Command
+    Ident "foo090"
+    StrLit "test"
+    StmtList
+      DiscardStmt
+        Empty
+  Command
+    Ident "foo100"
+    Call
+      StrLit "test"
+      StmtList
+        DiscardStmt
+          Empty
+  Command
+    Ident "foo101"
+    Call
+      IntLit 10
+      StmtList
+        DiscardStmt
+          Empty
+  Command
+    Ident "foo110"
+    IntLit 1
+    Par
+      Infix
+        Ident "+"
+        IntLit 2
+        IntLit 3
+    StmtList
+      DiscardStmt
+        Empty
+  Command
+    Ident "foo120"
+    IntLit 1
+    Call
+      Par
+        Infix
+          Ident "+"
+          IntLit 2
+          IntLit 3
+      StmtList
+        DiscardStmt
+          Empty
+  Call
+    Ident "foo130"
+    Do
+      Empty
+      Empty
+      Empty
+      FormalParams
+        Empty
+        IdentDefs
+          Ident "x"
+          Empty
+          Empty
+      Empty
+      Empty
+      StmtList
+        DiscardStmt
+          Empty
+  Call
+    Ident "foo140"
+    Do
+      Empty
+      Empty
+      Empty
+      FormalParams
+        Empty
+        IdentDefs
+          Ident "x"
+          Ident "int"
+          Empty
+      Empty
+      Empty
+      StmtList
+        DiscardStmt
+          Empty
+  Call
+    Ident "foo150"
+    Do
+      Empty
+      Empty
+      Empty
+      FormalParams
+        Ident "int"
+        IdentDefs
+          Ident "x"
+          Ident "int"
+          Empty
+      Empty
+      Empty
+      StmtList
+        DiscardStmt
+          Empty
+  Command
+    Ident "foo160"
+    Call
+      Ident "x"
+      Do
+        Empty
+        Empty
+        Empty
+        FormalParams
+          Empty
+          IdentDefs
+            Ident "y"
+            Empty
+            Empty
+        Empty
+        Empty
+        StmtList
+          DiscardStmt
+            Empty
+  Call
+    Ident "foo170"
+    StmtList
+      DiscardStmt
+        Empty
+    Else
+      StmtList
+        DiscardStmt
+          Empty
+  Call
+    Ident "foo180"
+    StmtList
+      DiscardStmt
+        Empty
+    StmtList
+      DiscardStmt
+        Empty
+    Else
+      StmtList
+        DiscardStmt
+          Empty
+  Command
+    Ident "foo190"
+    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
+      Else
+        StmtList
+          DiscardStmt
+            Empty
+  Call
+    Ident "foo200"
+    Ident "x"
+    Call
+      Ident "bar"
+      StmtList
+        DiscardStmt
+          Empty
+      Else
+        StmtList
+          DiscardStmt
+            Empty
+  VarSection
+    IdentDefs
+      Ident "a"
+      Empty
+      Ident "foo210"
+  VarSection
+    IdentDefs
+      Ident "a"
+      Empty
+      Call
+        Ident "foo220"
+  VarSection
+    IdentDefs
+      Ident "a"
+      Empty
+      Call
+        Ident "foo230"
+        Ident "x"
+  VarSection
+    IdentDefs
+      Ident "a"
+      Empty
+      Command
+        Ident "foo240"
+        Ident "x"
+  VarSection
+    IdentDefs
+      Ident "a"
+      Empty
+      Call
+        Ident "foo250"
+        StmtList
+          DiscardStmt
+            Empty
+  VarSection
+    IdentDefs
+      Ident "a"
+      Empty
+      Call
+        Ident "foo260"
+        StmtList
+          DiscardStmt
+            Empty
+  VarSection
+    IdentDefs
+      Ident "a"
+      Empty
+      Call
+        Ident "foo270"
+        StmtList
+          DiscardStmt
+            Empty
+        Else
+          StmtList
+            DiscardStmt
+              Empty
+  VarSection
+    IdentDefs
+      Ident "a"
+      Empty
+      Command
+        Ident "foo280"
+        Call
+          Ident "x"
+          Do
+            Empty
+            Empty
+            Empty
+            FormalParams
+              Empty
+              IdentDefs
+                Ident "y"
+                Empty
+                Empty
+            Empty
+            Empty
+            StmtList
+              DiscardStmt
+                Empty
+          Else
+            StmtList
+              DiscardStmt
+                Empty
+  Asgn
+    Ident "a"
+    Ident "foo290"
+  Asgn
+    Ident "a"
+    Call
+      Ident "foo300"
+  Asgn
+    Ident "a"
+    Call
+      Ident "foo310"
+      Ident "x"
+  Asgn
+    Ident "a"
+    Command
+      Ident "foo320"
+      Ident "x"
+  Asgn
+    Ident "a"
+    Call
+      Ident "foo330"
+      StmtList
+        DiscardStmt
+          Empty
+  Asgn
+    Ident "a"
+    Call
+      Ident "foo340"
+      StmtList
+        DiscardStmt
+          Empty
+  Asgn
+    Ident "a"
+    Call
+      Ident "foo350"
+      StmtList
+        DiscardStmt
+          Empty
+      Else
+        StmtList
+          DiscardStmt
+            Empty
+  Asgn
+    Ident "a"
+    Command
+      Ident "foo360"
+      Call
+        DotExpr
+          Ident "x"
+          Ident "bar"
+        Do
+          Empty
+          Empty
+          Empty
+          FormalParams
+            Empty
+            IdentDefs
+              Ident "y"
+              Empty
+              Empty
+          Empty
+          Empty
+          StmtList
+            DiscardStmt
+              Empty
+        Else
+          StmtList
+            DiscardStmt
+              Empty
+  Command
+    DotExpr
+      Ident "foo370"
+      Ident "add"
+    Call
+      Ident "quote"
+      StmtList
+        DiscardStmt
+          Empty
+  Call
+    DotExpr
+      Ident "foo380"
+      Ident "add"
+    BracketExpr
+      Call
+        Ident "quote"
+        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
+'''
+"""
+
+import macros
+
+dumpTree:
+  # simple calls
+  foo010
+  foo020()
+  foo030(x)
+  foo040 x
+
+  foo050:
+    discard
+
+  foo060 do:
+    discard
+
+  foo070("test"):
+    discard
+
+  foo080("test") do:
+    discard
+
+  foo090 "test":
+    discard
+
+  foo100 "test" do:
+    discard
+
+  foo101 10 do:
+    discard
+
+  # more complicated calls
+  foo110 1, (2+3):
+    discard
+
+  foo120 1, (2+3) do:
+    discard
+
+  foo130 do (x):
+    discard
+
+  foo140 do (x: int):
+    discard
+
+  foo150 do (x: int) -> int:
+    discard
+
+  foo160 x do (y):
+    discard
+
+  # extra blocks
+  foo170:
+    discard
+  else:
+    discard
+
+  foo180 do:
+    discard
+  do:
+    discard
+  else:
+    discard
+
+  foo190 x do (y):
+    discard
+  do (z) -> int:
+    discard
+  do (w: int) -> int:
+    discard
+  do:
+    discard
+  else:
+    discard
+
+  # call with blocks as a param
+  foo200(x, bar do:
+    discard
+  else:
+    discard
+  )
+
+  # introduce a variable
+  var a = foo210
+  var a = foo220()
+  var a = foo230(x)
+  var a = foo240 x
+
+  var a = foo250:
+    discard
+
+  var a = foo260 do:
+    discard
+
+  var a = foo270 do:
+    discard
+  else:
+    discard
+
+  var a = foo280 x do (y):
+    discard
+  else:
+    discard
+
+  # assignments
+  a = foo290
+  a = foo300()
+  a = foo310(x)
+  a = foo320 x
+
+  a = foo330:
+    discard
+
+  a = foo340 do:
+    discard
+
+  a = foo350 do:
+    discard
+  else:
+    discard
+
+  a = foo360 x.bar do (y):
+    discard
+  else:
+    discard
+
+  foo370.add quote do:
+    discard
+
+  # some edge cases
+  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
new file mode 100644
index 000000000..9be79543b
--- /dev/null
+++ b/tests/parser/tprecedence.nim
@@ -0,0 +1,63 @@
+discard """
+  output: '''holla
+true
+defabc 4
+0'''
+"""
+
+# Test top level semicolon works properly:
+import os; echo "holla"
+
+# Test the new predence rules
+
+proc `\+` (x, y: int): int = result = x + y
+proc `\*` (x, y: int): int = result = x * y
+
+echo 5 \+ 1 \* 9 == 6*9
+
+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/tproctype_pragmas.nim b/tests/parser/tproctype_pragmas.nim
new file mode 100644
index 000000000..8c7acd0cf
--- /dev/null
+++ b/tests/parser/tproctype_pragmas.nim
@@ -0,0 +1,19 @@
+discard """
+  output: '''39
+40'''
+"""
+
+# bug 1802
+# Ensure proc pragmas are attached properly:
+
+proc makeStdcall(s: string): (proc(i: int) {.stdcall.}) =
+  (proc (x: int) {.stdcall.} = echo x)
+
+proc makeNimcall(s: string): (proc(i: int)) {.stdcall.} =
+  (proc (x: int) {.nimcall.} = echo x)
+
+let stdc: proc (y: int) {.stdcall.} = makeStdcall("bu")
+let nimc: proc (y: int) {.closure.} = makeNimcall("ba")
+
+stdc(39)
+nimc(40)
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/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
new file mode 100644
index 000000000..993501fbb
--- /dev/null
+++ b/tests/parser/ttupleunpack.nim
@@ -0,0 +1,94 @@
+proc returnsTuple(): (int, int, int) = (4, 2, 3)
+
+proc main2 =
+  let (x, _, z) = returnsTuple()
+
+proc main() =
+
+  proc foo(): tuple[x, y, z: int] =
+    return (4, 2, 3)
+
+  var (x, _, y) = foo()
+  doAssert x == 4
+  doAssert y == 3
+
+  var (a, _, _) = foo()
+  doAssert a == 4
+
+  var (aa, _, _) = foo()
+  doAssert aa == 4
+
+  iterator bar(): tuple[x, y, z: int] =
+    yield (1,2,3)
+
+  for x, y, _ in bar():
+    doAssert x == 1
+    doAssert y == 2
+
+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
new file mode 100644
index 000000000..e6e7a48b8
--- /dev/null
+++ b/tests/parser/ttypeclasses.nim
@@ -0,0 +1,46 @@
+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
+
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/ttypeof.nim b/tests/parser/ttypeof.nim
new file mode 100644
index 000000000..24f98059e
--- /dev/null
+++ b/tests/parser/ttypeof.nim
@@ -0,0 +1,26 @@
+discard """
+  output: '''12
+int
+int
+int'''
+"""
+
+import typetraits
+
+# bug #1805
+
+proc foob(x: int): string = "foo"
+proc barb(x: string): int = 12
+
+echo(foob(10).barb()) # works
+echo(type(10).name()) # doesn't work
+
+echo(name(type(10))) # works
+echo((type(10)).name()) # works
+
+
+# test that 'addr' still works
+proc poo(x, y: ptr int) = discard
+
+var someInt: int
+poo(addr someInt, addr someInt)
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
diff --git a/tests/parser/twhen_in_enum.nim b/tests/parser/twhen_in_enum.nim
new file mode 100644
index 000000000..3890b686e
--- /dev/null
+++ b/tests/parser/twhen_in_enum.nim
@@ -0,0 +1,11 @@
+discard """
+  errormsg: "identifier expected, but got 'keyword when'"
+"""
+
+# bug #2123
+type num = enum
+    NUM_NONE = 0
+    NUM_ALL = 1
+    when defined(macosx): NUM_OSX = 10 # only this differs for real
+    NUM_XTRA = 20
+
diff --git a/tests/parser/twrongcmdsyntax.nim b/tests/parser/twrongcmdsyntax.nim
new file mode 100644
index 000000000..c2962bed4
--- /dev/null
+++ b/tests/parser/twrongcmdsyntax.nim
@@ -0,0 +1,6 @@
+discard """
+  errormsg: '''in expression '4 2': identifier expected, but found '4'''
+  line: 6
+"""
+
+echo 4 +2