implements final version of multiline comments

This commit is contained in:
Andreas Rumpf 2016-01-17 20:29:50 +01:00
commit a4aeb6fbec
4 changed files with 63 additions and 43 deletions

View file

@ -773,9 +773,6 @@ proc skipMultiLineComment(L: var TLexer; tok: var TToken; start: int;
isDoc: bool) = isDoc: bool) =
var pos = start var pos = start
var buf = L.buf var buf = L.buf
while buf[pos] == '[':
inc pos
let brackets = pos - start
var toStrip = 0 var toStrip = 0
# detect the amount of indentation: # detect the amount of indentation:
if isDoc: if isDoc:
@ -788,17 +785,30 @@ proc skipMultiLineComment(L: var TLexer; tok: var TToken; start: int;
while buf[pos] == ' ': while buf[pos] == ' ':
inc pos inc pos
inc toStrip inc toStrip
var nesting = 0
while true: while true:
case buf[pos] 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 ']': of ']':
var p = pos if isDoc:
while buf[p] == ']': if buf[pos+1] == '#' and buf[pos+2] == '#':
inc p if nesting == 0:
if p-pos == brackets: inc(pos, 3)
pos = p
break break
else: dec nesting
if isDoc: tok.literal.add ']' tok.literal.add ']'
elif buf[pos+1] == '#':
if nesting == 0:
inc(pos, 2)
break
dec nesting
inc pos inc pos
of '\t': of '\t':
lexMessagePos(L, errTabulatorsAreNotAllowed, pos) lexMessagePos(L, errTabulatorsAreNotAllowed, pos)
@ -832,7 +842,7 @@ proc scanComment(L: var TLexer, tok: var TToken) =
when not defined(nimfix): when not defined(nimfix):
assert buf[pos+1] == '#' assert buf[pos+1] == '#'
if buf[pos+2] == '[': if buf[pos+2] == '[':
skipMultiLineComment(L, tok, pos+2, true) skipMultiLineComment(L, tok, pos+3, true)
return return
inc(pos, 2) inc(pos, 2)
@ -923,7 +933,7 @@ proc skip(L: var TLexer, tok: var TToken) =
# do not skip documentation comment: # do not skip documentation comment:
if buf[pos+1] == '#': break if buf[pos+1] == '#': break
if buf[pos+1] == '[': if buf[pos+1] == '[':
skipMultiLineComment(L, tok, pos+1, false) skipMultiLineComment(L, tok, pos+2, false)
return return
while buf[pos] notin {CR, LF, nimlexbase.EndOfFile}: inc(pos) while buf[pos] notin {CR, LF, nimlexbase.EndOfFile}: inc(pos)
else: else:

View file

@ -78,33 +78,24 @@ They look like:
.. code-block:: nim .. code-block:: nim
#[Comment here. #[Comment here.
Multiple lines Multiple lines
are not a problem.] are not a problem.]#
.. code-block:: nim Multiline comments support nesting:
#[[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:
.. code-block:: nim .. code-block:: nim
# Does not comment out 'p' properly: # Does not comment out 'p' properly:
#[ #[ #[ Multiline comment in already
commented out code. ]#
proc p[T](x: T) = discard proc p[T](x: T) = discard
] ]#
Multiline documentation comments look like: Multiline documentation comments look like and support nesting too:
.. code-block:: nim .. code-block:: nim
proc foo = proc foo =
##[Long documentation comment ##[Long documentation comment
here. here.
] ]##
Identifiers & Keywords Identifiers & Keywords

View file

@ -174,19 +174,38 @@ proc nimNextToken(g: var GeneralTokenizer) =
of '#': of '#':
g.kind = gtComment g.kind = gtComment
inc(pos) inc(pos)
if g.buf[pos] == '#': inc(pos) var isDoc = false
if g.buf[pos] == '#':
inc(pos)
isDoc = true
if g.buf[pos] == '[': if g.buf[pos] == '[':
g.kind = gtLongComment g.kind = gtLongComment
var brackets = 0 var nesting = 0
while g.buf[pos] == '[': while true:
inc(pos) case g.buf[pos]
inc(brackets) of '\0': break
while g.buf[pos] != '\0': of '#':
if g.buf[pos] == ']': if isDoc:
var q = pos if g.buf[pos+1] == '#' and g.buf[pos+2] == '[':
while g.buf[pos] == ']': inc(pos) inc nesting
if pos-q == brackets: break elif g.buf[pos+1] == '[':
inc(pos) 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: else:
while g.buf[pos] notin {'\0', '\x0A', '\x0D'}: inc(pos) while g.buf[pos] notin {'\0', '\x0A', '\x0D'}: inc(pos)
of 'a'..'z', 'A'..'Z', '_', '\x80'..'\xFF': of 'a'..'z', 'A'..'Z', '_', '\x80'..'\xFF':