From 28ce83524bc8e674f03cbf6160b1396c24dcd2c0 Mon Sep 17 00:00:00 2001 From: Kodi Arfer Date: Sun, 23 Jul 2017 11:43:19 -0700 Subject: [PATCH] Don't try to lex tag-macro calls as shebangs --- NEWS | 2 ++ hy/importer.py | 5 ++++- hy/lex/lexer.py | 1 - hy/lex/parser.py | 16 +++------------- tests/native_tests/tag_macros.hy | 9 +++++++++ tests/test_lex.py | 6 ------ 6 files changed, 18 insertions(+), 21 deletions(-) diff --git a/NEWS b/NEWS index 3bae0ca..3785792 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,8 @@ Changes from 0.13.0 and a symbol * Hy now respects the environment variable PYTHONDONTWRITEBYTECODE * String literals should no longer be interpreted as special forms or macros + * Tag macros (née sharp macros) whose names begin with `!` are no longer + mistaken for shebang lines Changes from 0.12.1 diff --git a/hy/importer.py b/hy/importer.py index 63b87d4..a1c7abe 100644 --- a/hy/importer.py +++ b/hy/importer.py @@ -39,7 +39,10 @@ def import_file_to_hst(fpath): """Import content from fpath and return a Hy AST.""" try: with open(fpath, 'r', encoding='utf-8') as f: - return import_buffer_to_hst(f.read()) + buf = f.read() + # Strip the shebang line, if there is one. + buf = re.sub(r'\A#!.*', '', buf) + return import_buffer_to_hst(buf) except IOError as e: raise HyIOError(e.errno, e.strerror, e.filename) diff --git a/hy/lex/lexer.py b/hy/lex/lexer.py index 9779eda..b73c284 100755 --- a/hy/lex/lexer.py +++ b/hy/lex/lexer.py @@ -25,7 +25,6 @@ lg.add('QUOTE', r'\'%s' % end_quote) lg.add('QUASIQUOTE', r'`%s' % end_quote) lg.add('UNQUOTESPLICE', r'~@%s' % end_quote) lg.add('UNQUOTE', r'~%s' % end_quote) -lg.add('HASHBANG', r'#!.*[^\r\n]') lg.add('HASHSTARS', r'#\*+') lg.add('HASHOTHER', r'#%s' % identifier) diff --git a/hy/lex/parser.py b/hy/lex/parser.py index d60cec5..0c73652 100755 --- a/hy/lex/parser.py +++ b/hy/lex/parser.py @@ -90,23 +90,13 @@ def set_quote_boundaries(fun): return wrapped -@pg.production("main : HASHBANG real_main") -def main_hashbang(p): - return p[1] - - -@pg.production("main : real_main") +@pg.production("main : list_contents") def main(p): return p[0] -@pg.production("real_main : list_contents") -def real_main(p): - return p[0] - - -@pg.production("real_main : $end") -def real_main_empty(p): +@pg.production("main : $end") +def main_empty(p): return [] diff --git a/tests/native_tests/tag_macros.hy b/tests/native_tests/tag_macros.hy index 18beaa7..3ba7182 100644 --- a/tests/native_tests/tag_macros.hy +++ b/tests/native_tests/tag_macros.hy @@ -36,6 +36,15 @@ (assert (= #spam_eggs 42 ['spam 42 'eggs]))) +(defn test-bang-tag-macro [] + "Test tag macros whose names start with `!`" + ; https://github.com/hylang/hy/issues/1334 + (deftag !a [x] `["foo" ~x]) + (assert (= #!a 3 ["foo" 3])) + (deftag ! [x] `["bar" ~x]) + (assert (= #! 4 ["bar" 4]))) + + (defn test-tag-macro-whitespace [] "Test whitespace after a tag macro" (deftag foo [expr] diff --git a/tests/test_lex.py b/tests/test_lex.py index dfac923..2f7a207 100644 --- a/tests/test_lex.py +++ b/tests/test_lex.py @@ -301,12 +301,6 @@ def test_unicode_escapes(): assert [ord(x) for x in entry] == [97, 172, 4660, 8364, 32768] -def test_hashbang(): - """ Ensure we can escape things """ - entry = tokenize("#!this is a comment\n") - assert entry == [] - - def test_complex(): """Ensure we tokenize complex numbers properly""" # This is a regression test for #143