diff options
-rw-r--r-- | compiler/lexer.nim | 38 | ||||
-rw-r--r-- | doc/manual/lexing.txt | 23 | ||||
-rw-r--r-- | lib/packages/docutils/highlite.nim | 41 | ||||
-rw-r--r-- | tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim | 4 |
4 files changed, 63 insertions, 43 deletions
diff --git a/compiler/lexer.nim b/compiler/lexer.nim index 70a555e15..4c1dd366b 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -773,9 +773,6 @@ proc skipMultiLineComment(L: var TLexer; tok: var TToken; start: int; isDoc: bool) = var pos = start var buf = L.buf - while buf[pos] == '[': - inc pos - let brackets = pos - start var toStrip = 0 # detect the amount of indentation: if isDoc: @@ -788,18 +785,31 @@ proc skipMultiLineComment(L: var TLexer; tok: var TToken; start: int; while buf[pos] == ' ': inc pos inc toStrip + var nesting = 0 while true: case buf[pos] + of '#': + if isDoc: + if buf[pos+1] == '#' and buf[pos+2] == '[': + inc nesting + tok.literal.add '#' + elif buf[pos+1] == '[': + inc nesting + inc pos of ']': - var p = pos - while buf[p] == ']': - inc p - if p-pos == brackets: - pos = p - break - else: - if isDoc: tok.literal.add ']' - inc pos + if isDoc: + if buf[pos+1] == '#' and buf[pos+2] == '#': + if nesting == 0: + inc(pos, 3) + break + dec nesting + tok.literal.add ']' + elif buf[pos+1] == '#': + if nesting == 0: + inc(pos, 2) + break + dec nesting + inc pos of '\t': lexMessagePos(L, errTabulatorsAreNotAllowed, pos) inc(pos) @@ -832,7 +842,7 @@ proc scanComment(L: var TLexer, tok: var TToken) = when not defined(nimfix): assert buf[pos+1] == '#' if buf[pos+2] == '[': - skipMultiLineComment(L, tok, pos+2, true) + skipMultiLineComment(L, tok, pos+3, true) return inc(pos, 2) @@ -923,7 +933,7 @@ proc skip(L: var TLexer, tok: var TToken) = # do not skip documentation comment: if buf[pos+1] == '#': break if buf[pos+1] == '[': - skipMultiLineComment(L, tok, pos+1, false) + skipMultiLineComment(L, tok, pos+2, false) return while buf[pos] notin {CR, LF, nimlexbase.EndOfFile}: inc(pos) else: diff --git a/doc/manual/lexing.txt b/doc/manual/lexing.txt index a5c3dfd6d..7655964ee 100644 --- a/doc/manual/lexing.txt +++ b/doc/manual/lexing.txt @@ -78,33 +78,24 @@ They look like: .. code-block:: nim #[Comment here. Multiple lines - are not a problem.] + are not a problem.]# -.. code-block:: nim - #[[comment here]] - -.. code-block:: nim - #[[[comment here]]] - -.. code-block:: nim - #[[[[comment here]]]] - -The number of opening brackets must match the number of closing brackets -but they do not nest in the traditional sense: +Multiline comments support nesting: .. code-block:: nim # Does not comment out 'p' properly: - #[ + #[ #[ Multiline comment in already + commented out code. ]# proc p[T](x: T) = discard - ] + ]# -Multiline documentation comments look like: +Multiline documentation comments look like and support nesting too: .. code-block:: nim proc foo = ##[Long documentation comment here. - ] + ]## Identifiers & Keywords diff --git a/lib/packages/docutils/highlite.nim b/lib/packages/docutils/highlite.nim index 570465e14..1bc0af1b6 100644 --- a/lib/packages/docutils/highlite.nim +++ b/lib/packages/docutils/highlite.nim @@ -174,19 +174,38 @@ proc nimNextToken(g: var GeneralTokenizer) = of '#': g.kind = gtComment inc(pos) - if g.buf[pos] == '#': inc(pos) + var isDoc = false + if g.buf[pos] == '#': + inc(pos) + isDoc = true if g.buf[pos] == '[': g.kind = gtLongComment - var brackets = 0 - while g.buf[pos] == '[': - inc(pos) - inc(brackets) - while g.buf[pos] != '\0': - if g.buf[pos] == ']': - var q = pos - while g.buf[pos] == ']': inc(pos) - if pos-q == brackets: break - inc(pos) + var nesting = 0 + while true: + case g.buf[pos] + of '\0': break + of '#': + if isDoc: + if g.buf[pos+1] == '#' and g.buf[pos+2] == '[': + inc nesting + elif g.buf[pos+1] == '[': + inc nesting + inc pos + of ']': + if isDoc: + if g.buf[pos+1] == '#' and g.buf[pos+2] == '#': + if nesting == 0: + inc(pos, 3) + break + dec nesting + elif g.buf[pos+1] == '#': + if nesting == 0: + inc(pos, 2) + break + dec nesting + inc pos + else: + inc pos else: while g.buf[pos] notin {'\0', '\x0A', '\x0D'}: inc(pos) of 'a'..'z', 'A'..'Z', '_', '\x80'..'\xFF': diff --git a/tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim b/tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim index e64b818fa..142b190ab 100644 --- a/tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim +++ b/tests/manyloc/keineschweine/dependencies/genpacket/genpacket_enet.nim @@ -131,10 +131,10 @@ macro defPacket*(typeNameN: expr, typeFields: expr): stmt {.immediate.} = emptyNode())), emptyNode(), emptyNode(), - newNimNode(nnkStmtList).und(#[6] + newNimNode(nnkStmtList).und(# [6] newNimNode(nnkAsgn).und( ^"result", ## result = - newNimNode(nnkCall).und(#[6][0][1] + newNimNode(nnkCall).und(# [6][0][1] ^"format", ## format emptyNode())))) ## "[TypeName $1 $2]" formatStr = "["& $typeName.ident |