Skip to content

Commit 836d7bf

Browse files
authored
New implementation of block commets (#168)
The behavior of block comments is changed, as proposed in the documentation of Fram.
1 parent e5220f6 commit 836d7bf

File tree

6 files changed

+61
-20
lines changed

6 files changed

+61
-20
lines changed

examples/Modules/Main.fram

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
Relative imports refer to the module which is the closest to the importing
2222
module, working upwards through the hierarchy. In this example the module
2323
`/Main/B/C/D` imports the relative path `A`, and the nearest matching
24-
module is `/Main/B/A`. #}
24+
module is `/Main/B/A`. ##}
2525

2626
import List
2727

src/DblParser/Error.ml

+5-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@ let unexpected_token pos tok =
3131
let invalid_character pos ch =
3232
(Some pos, Printf.sprintf "Invalid character `%s'" (Char.escaped ch))
3333

34-
let eof_in_comment pos =
35-
(Some pos, "Unexpected end of file inside a block comment")
34+
let eof_in_comment pos name =
35+
(Some pos,
36+
Printf.sprintf
37+
"Unexpected end of file inside a block comment (`%s#}' was expected)"
38+
name)
3639

3740
let invalid_number pos str =
3841
(Some pos, Printf.sprintf "Invalid integer literal `%s'" str)

src/DblParser/Error.mli

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ val module_dependency_cycle : string -> t
2222
val unexpected_token : Position.t -> string -> t
2323
val invalid_character : Position.t -> char -> t
2424

25-
val eof_in_comment : Position.t -> t
25+
val eof_in_comment : Position.t -> string -> t
2626

2727
val invalid_number : Position.t -> string -> t
2828
val number_out_of_bounds : Position.t -> string -> t

src/DblParser/Lexer.mll

+12-16
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,12 @@ let op_char = [
149149
'~' '*' '%' ';' ',' '=' '|' ':' '.' '/'
150150
]
151151

152+
let comment_name = [^'\000'-' ' '\x7f' '{' '}']*
153+
152154
rule token = parse
153155
whitespace+ { token lexbuf }
154156
| '\n' { Lexing.new_line lexbuf; token lexbuf }
155-
| "{#" { block_comment 1 lexbuf }
157+
| "{#" (comment_name as name) { block_comment name lexbuf }
156158
| "#" { skip_line lexbuf; token lexbuf }
157159
| '(' { YaccParser.BR_OPN }
158160
| ')' { YaccParser.BR_CLS }
@@ -205,25 +207,19 @@ and string_token pos buf = parse
205207
(Position.of_lexing 0 lexbuf.Lexing.lex_start_p))
206208
}
207209

208-
and block_comment depth = parse
209-
'\n' { Lexing.new_line lexbuf; block_comment depth lexbuf }
210-
| "{#" { block_comment (depth+1) lexbuf }
211-
| "#}" {
212-
if depth = 1 then token lexbuf
213-
else block_comment (depth-1) lexbuf
210+
and block_comment name = parse
211+
'\n' { Lexing.new_line lexbuf; block_comment name lexbuf }
212+
| (comment_name as name') "#}" {
213+
if String.ends_with ~suffix:name name' then token lexbuf
214+
else block_comment name lexbuf
214215
}
215-
| '"' {
216-
let buf = Buffer.create 32 in
217-
let _ : YaccParser.token =
218-
string_token lexbuf.Lexing.lex_start_p buf lexbuf in
219-
block_comment depth lexbuf
220-
}
221-
| "#" { skip_line lexbuf; block_comment depth lexbuf }
216+
| comment_name { block_comment name lexbuf }
222217
| eof {
223218
Error.fatal (Error.eof_in_comment
224-
(Position.of_lexing 0 lexbuf.Lexing.lex_start_p))
219+
(Position.of_lexing 0 lexbuf.Lexing.lex_start_p)
220+
name)
225221
}
226-
| _ { block_comment depth lexbuf }
222+
| _ { block_comment name lexbuf }
227223

228224
and skip_line = parse
229225
'\n' { Lexing.new_line lexbuf }

test/err/lexer_0002_eofInComment.fram

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# @stderr:!!#}
2+
{#!!
3+
{# #}

test/ok/ok0117_comments.fram

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# This is a single-line comment.
2+
{# This is a block comment. #}
3+
{# Block comments
4+
may span multiple lines.
5+
#}
6+
let id x = x # A single-line comment may appear at the end of a line.
7+
8+
let n {# A block comment may span a part of a single line. #} = 42
9+
{#aaa
10+
Comments cannot be nested,
11+
{# but the programmer may choose the comment delimiters. #}
12+
aaa#}
13+
14+
{#!a! Comment names may contain operators. !a!#}
15+
16+
{#abc
17+
This comment is ended by `abc` immediately followed by `#}`,
18+
even if the closing sequence is preceded by other characters.
19+
zzabc#}
20+
21+
let {#
22+
# This is not a single-line comment,
23+
# because comments are not nested.
24+
# This comment can be ended #} here = 13
25+
26+
## This is a documentation comment.
27+
let foo x = x
28+
29+
{## This is another documentation comment. ##}
30+
let bar = foo
31+
32+
{###
33+
Documentation comments can contain some code
34+
```
35+
{## with another documentation comment (with a different name). ##}
36+
let some_code = 42
37+
```
38+
###}
39+
let baz = bar

0 commit comments

Comments
 (0)