Skip to content

Commit 7108212

Browse files
authored
Suppress successive forms with stacked #_ reader macros (#1227)
Fixes #1207
1 parent 7d1d925 commit 7108212

File tree

3 files changed

+55
-58
lines changed

3 files changed

+55
-58
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
* Single arity functions can be tagged with `^:allow-unsafe-names` to preserve their parameter names (#1212)
1010

1111
### Fixed
12-
* Fix an issue where the compiler would generate an illegal `return` statement for asynchronous generators (#1180)
12+
* Fix an issue where the compiler would generate an illegal `return` statement for asynchronous generators (#1180)
13+
* Fix an issue where consecutive reader comment forms would not be ignored (#1207)
1314

1415
## [v0.3.7]
1516
### Fixed

src/basilisp/lang/reader.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1667,7 +1667,7 @@ def _read_reader_macro(ctx: ReaderContext) -> LispReaderForm: # noqa: MC0001
16671667
return _read_regex(ctx)
16681668
elif char == "_":
16691669
ctx.reader.advance()
1670-
_read_next(ctx) # Ignore the entire next form
1670+
_read_next_consuming_comment(ctx) # Ignore the entire next form
16711671
return COMMENT
16721672
elif char == "!":
16731673
return _read_comment(ctx)

tests/basilisp/reader_test.py

Lines changed: 52 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,65 +1524,61 @@ def test_syntax_error_attaching_metadata_to_unsupported_type(self, s: str):
15241524
read_str_first(s)
15251525

15261526

1527-
def test_comment_reader_macro():
1528-
with pytest.raises(EOFError):
1529-
read_str_first("#_ (a list)", is_eof_error=True)
1530-
1531-
with pytest.raises(EOFError):
1532-
read_str_first("#_1", is_eof_error=True)
1533-
1534-
with pytest.raises(EOFError):
1535-
read_str_first('#_"string"', is_eof_error=True)
1536-
1537-
with pytest.raises(EOFError):
1538-
read_str_first("#_:keyword", is_eof_error=True)
1539-
1540-
with pytest.raises(EOFError):
1541-
read_str_first("#_symbol", is_eof_error=True)
1542-
1543-
with pytest.raises(EOFError):
1544-
read_str_first("#_[]", is_eof_error=True)
1545-
1546-
with pytest.raises(EOFError):
1547-
read_str_first("#_{}", is_eof_error=True)
1548-
1549-
with pytest.raises(EOFError):
1550-
read_str_first("#_()", is_eof_error=True)
1551-
1552-
with pytest.raises(EOFError):
1553-
read_str_first("#_#{}", is_eof_error=True)
1554-
1555-
assert kw.keyword("kw2") == read_str_first("#_:kw1 :kw2")
1556-
1557-
assert llist.EMPTY == read_str_first("(#_sym)")
1558-
assert llist.l(sym.symbol("inc"), 5) == read_str_first("(inc #_counter 5)")
1559-
assert llist.l(sym.symbol("dec"), 8) == read_str_first("(#_inc dec #_counter 8)")
1560-
1561-
assert vec.EMPTY == read_str_first("[#_m]")
1562-
assert vec.v(1) == read_str_first("[#_m 1]")
1563-
assert vec.v(1) == read_str_first("[#_m 1 #_2]")
1564-
assert vec.v(1, 2) == read_str_first("[#_m 1 2]")
1565-
assert vec.v(1, 4) == read_str_first("[#_m 1 #_2 4]")
1566-
assert vec.v(1, 4) == read_str_first("[#_m 1 #_2 4 #_5]")
1567-
1568-
assert lset.EMPTY == read_str_first("#{#_m}")
1569-
assert lset.s(1) == read_str_first("#{#_m 1}")
1570-
assert lset.s(1) == read_str_first("#{#_m 1 #_2}")
1571-
assert lset.s(1, 2) == read_str_first("#{#_m 1 2}")
1572-
assert lset.s(1, 4) == read_str_first("#{#_m 1 #_2 4}")
1573-
assert lset.s(1, 4) == read_str_first("#{#_m 1 #_2 4 #_5}")
1574-
1575-
assert lmap.EMPTY == read_str_first("{#_:key}")
1576-
assert lmap.EMPTY == read_str_first('{#_:key #_"value"}')
1577-
assert lmap.map({kw.keyword("key"): "value"}) == read_str_first(
1578-
'{:key #_"other" "value"}'
1527+
class TestCommentReaderMacro:
1528+
@pytest.mark.parametrize(
1529+
"s",
1530+
[
1531+
"#_ (a list)",
1532+
"#_1",
1533+
'#_"string"',
1534+
"#_:keyword",
1535+
"#_symbol",
1536+
"#_[]",
1537+
"#_{}",
1538+
"#_()",
1539+
"#_#{}",
1540+
"#_ #_ {} {}",
1541+
],
15791542
)
1580-
assert lmap.map({kw.keyword("key"): "value"}) == read_str_first(
1581-
'{:key "value" #_"other"}'
1543+
def test_comment_suppresses_form_with_eof(self, s: str):
1544+
with pytest.raises(EOFError):
1545+
read_str_first(s, is_eof_error=True)
1546+
1547+
@pytest.mark.parametrize(
1548+
"s,v",
1549+
[
1550+
("#_:kw1 :kw2", kw.keyword("kw2")),
1551+
("#_ #_ :kw1 :kw2 :kw3", kw.keyword("kw3")),
1552+
("(#_sym)", llist.EMPTY),
1553+
("(#_ #_ sym 1)", llist.EMPTY),
1554+
("(inc #_counter 5)", llist.l(sym.symbol("inc"), 5)),
1555+
("(#_inc dec #_counter 8)", llist.l(sym.symbol("dec"), 8)),
1556+
("[#_m]", vec.EMPTY),
1557+
("[#_m 1]", vec.v(1)),
1558+
("[#_m 1 #_2]", vec.v(1)),
1559+
("[#_m 1 2]", vec.v(1, 2)),
1560+
("[#_m 1 #_2 4]", vec.v(1, 4)),
1561+
("[#_m 1 #_2 4 #_5]", vec.v(1, 4)),
1562+
("#{#_m}", lset.EMPTY),
1563+
("#{#_m 1}", lset.s(1)),
1564+
("#{#_m 1 #_2}", lset.s(1)),
1565+
("#{#_m 1 2}", lset.s(1, 2)),
1566+
("#{#_m 1 #_2 4}", lset.s(1, 4)),
1567+
("#{#_m 1 #_2 4 #_5}", lset.s(1, 4)),
1568+
("{#_:key}", lmap.EMPTY),
1569+
('{#_:key #_"value"}', lmap.EMPTY),
1570+
('{#_ #_:key "value"}', lmap.EMPTY),
1571+
('{:key #_"other" "value"}', lmap.map({kw.keyword("key"): "value"})),
1572+
('{:key "value" #_"other"}', lmap.map({kw.keyword("key"): "value"})),
1573+
("{#_ #_:a 3 :b 5}", lmap.map({kw.keyword("b"): 5})),
1574+
],
15821575
)
1576+
def test_comment_suppresses_form_in_other_form(self, s: str, v):
1577+
assert v == read_str_first(s)
15831578

1584-
with pytest.raises(reader.SyntaxError):
1585-
read_str_first('{:key #_"value"}')
1579+
def test_comment_creates_syntax_error(self):
1580+
with pytest.raises(reader.SyntaxError):
1581+
read_str_first('{:key #_"value"}')
15861582

15871583

15881584
def test_comment_line():

0 commit comments

Comments
 (0)