From 5a6488e353e378588906aee1018b0d5b8480fab0 Mon Sep 17 00:00:00 2001 From: Rob Day Date: Sat, 16 Sep 2017 22:19:05 +0100 Subject: [PATCH] Treat _42 etc. as a variable name, not an integer --- NEWS | 1 + docs/language/api.rst | 6 +++--- hy/models.py | 6 ++++-- tests/native_tests/language.hy | 7 +++++++ tests/test_lex.py | 8 +++++--- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 07441f9..7140361 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,7 @@ Changes from 0.13.0 as necessary, so you can write ``(eval `(+ 1 ~n))`` instead of ``(eval `(+ 1 ~(HyInteger n)))`` * Literal `Inf`s and `NaN`s must now be capitalized like that + * Numeric literals can no longer begin with a comma or underscore * `get` is available as a function * new `comment` macro * support EDN `#_` syntax to discard the next term diff --git a/docs/language/api.rst b/docs/language/api.rst index ed789eb..e201ec9 100644 --- a/docs/language/api.rst +++ b/docs/language/api.rst @@ -44,9 +44,9 @@ integers is used. ``0x`` for Hex, ``0o`` for Octal, ``0b`` for Binary. (print 0x80 0b11101 0o102 30) -Underscores and commas can appear anywhere in a numeric literal. They have no -effect on the value of the literal, but they're useful for visually separating -digits. +Underscores and commas can appear anywhere in a numeric literal except the very +beginning. They have no effect on the value of the literal, but they're useful +for visually separating digits. .. code-block:: clj diff --git a/hy/models.py b/hy/models.py index 0d6df4c..2b32142 100644 --- a/hy/models.py +++ b/hy/models.py @@ -111,8 +111,10 @@ class HyKeyword(HyObject, str_type): def strip_digit_separators(number): - return (number.replace("_", "").replace(",", "") - if isinstance(number, string_types) + # Don't strip a _ or , if it's the first character, as _42 and + # ,42 aren't valid numbers + return (number[0] + number[1:].replace("_", "").replace(",", "") + if isinstance(number, string_types) and len(number) > 1 else number) diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index 125ff51..a77858c 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -1653,3 +1653,10 @@ (with [(pytest.raises AssertionError)] (assert (do (f 1) (f 2)) (do (f 3) (f 4)))) (assert (= s #{1 2 3 4})))) + +(defn test-underscore_variables [] + ; https://github.com/hylang/hy/issues/1340 + (defclass XYZ [] + [_42 6]) + (setv x (XYZ)) + (assert (= (. x _42) 6))) diff --git a/tests/test_lex.py b/tests/test_lex.py index 5a21e7f..bdb412a 100644 --- a/tests/test_lex.py +++ b/tests/test_lex.py @@ -158,9 +158,11 @@ def test_lex_digit_separators(): HyInteger(12), HyInteger(34)])]) assert tokenize("1,0_00j") == [HyComplex(1000j)] - assert tokenize(",,,,___,__1__,,__,,2__,,,__") == [HyInteger(12)] - assert (tokenize(",,,,___,__1__,,__,,2__,q,__") == - [HySymbol(",,,,___,__1__,,__,,2__,q,__")]) + assert tokenize("1,,,,___,____,,__,,2__,,,__") == [HyInteger(12)] + assert (tokenize("_1,,,,___,____,,__,,2__,,,__") == + [HySymbol("_1,,,,___,____,,__,,2__,,,__")]) + assert (tokenize("1,,,,___,____,,__,,2__,q,__") == + [HySymbol("1,,,,___,____,,__,,2__,q,__")]) def test_lex_bad_attrs():