diff --git a/NEWS.md b/NEWS.md index 861210f4df5af..c9e23ca39c934 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,6 +6,8 @@ New language features * Types written with `where` syntax can now be used to define constructors, e.g. `(Foo{T} where T)(x) = ...`. +* `<--` and `<-->` are now available as infix operators, with the same precedence + and associativity as other arrow-like operators ([#36666]). Language changes ---------------- diff --git a/src/julia-parser.scm b/src/julia-parser.scm index dfce9770a2fbe..7c5ae157f5252 100644 --- a/src/julia-parser.scm +++ b/src/julia-parser.scm @@ -15,7 +15,7 @@ (define prec-conditional '(?)) (define prec-arrow (append! '(-- -->) - (add-dots '(← → ↔ ↚ ↛ ↞ ↠ ↢ ↣ ↦ ↤ ↮ ⇎ ⇍ ⇏ ⇐ ⇒ ⇔ ⇴ ⇶ ⇷ ⇸ ⇹ ⇺ ⇻ ⇼ ⇽ ⇾ ⇿ ⟵ ⟶ ⟷ ⟹ ⟺ ⟻ ⟼ ⟽ ⟾ ⟿ ⤀ ⤁ ⤂ ⤃ ⤄ ⤅ ⤆ ⤇ ⤌ ⤍ ⤎ ⤏ ⤐ ⤑ ⤔ ⤕ ⤖ ⤗ ⤘ ⤝ ⤞ ⤟ ⤠ ⥄ ⥅ ⥆ ⥇ ⥈ ⥊ ⥋ ⥎ ⥐ ⥒ ⥓ ⥖ ⥗ ⥚ ⥛ ⥞ ⥟ ⥢ ⥤ ⥦ ⥧ ⥨ ⥩ ⥪ ⥫ ⥬ ⥭ ⥰ ⧴ ⬱ ⬰ ⬲ ⬳ ⬴ ⬵ ⬶ ⬷ ⬸ ⬹ ⬺ ⬻ ⬼ ⬽ ⬾ ⬿ ⭀ ⭁ ⭂ ⭃ ⭄ ⭇ ⭈ ⭉ ⭊ ⭋ ⭌ ← → ⇜ ⇝ ↜ ↝ ↩ ↪ ↫ ↬ ↼ ↽ ⇀ ⇁ ⇄ ⇆ ⇇ ⇉ ⇋ ⇌ ⇚ ⇛ ⇠ ⇢ ↷ ↶ ↺ ↻)))) + (add-dots '(← → ↔ ↚ ↛ ↞ ↠ ↢ ↣ ↦ ↤ ↮ ⇎ ⇍ ⇏ ⇐ ⇒ ⇔ ⇴ ⇶ ⇷ ⇸ ⇹ ⇺ ⇻ ⇼ ⇽ ⇾ ⇿ ⟵ ⟶ ⟷ ⟹ ⟺ ⟻ ⟼ ⟽ ⟾ ⟿ ⤀ ⤁ ⤂ ⤃ ⤄ ⤅ ⤆ ⤇ ⤌ ⤍ ⤎ ⤏ ⤐ ⤑ ⤔ ⤕ ⤖ ⤗ ⤘ ⤝ ⤞ ⤟ ⤠ ⥄ ⥅ ⥆ ⥇ ⥈ ⥊ ⥋ ⥎ ⥐ ⥒ ⥓ ⥖ ⥗ ⥚ ⥛ ⥞ ⥟ ⥢ ⥤ ⥦ ⥧ ⥨ ⥩ ⥪ ⥫ ⥬ ⥭ ⥰ ⧴ ⬱ ⬰ ⬲ ⬳ ⬴ ⬵ ⬶ ⬷ ⬸ ⬹ ⬺ ⬻ ⬼ ⬽ ⬾ ⬿ ⭀ ⭁ ⭂ ⭃ ⭄ ⭇ ⭈ ⭉ ⭊ ⭋ ⭌ ← → ⇜ ⇝ ↜ ↝ ↩ ↪ ↫ ↬ ↼ ↽ ⇀ ⇁ ⇄ ⇆ ⇇ ⇉ ⇋ ⇌ ⇚ ⇛ ⇠ ⇢ ↷ ↶ ↺ ↻ <-- <-->)))) (define prec-lazy-or '(|\|\||)) (define prec-lazy-and '(&&)) (define prec-comparison @@ -249,7 +249,14 @@ (or sufchar? (opchar? c))) (let* ((newop (string str c)) (opsym (string->symbol newop))) - (if (operator? opsym) + (if (or (operator? opsym) + (and (eq? opsym '<---) + (error (string "invalid operator \"" newop "\""))) + ;; <- is not an operator but <-- and <--> are + (and (eq? opsym '<-) + (read-char port) + (begin0 (eqv? (peek-char port) #\-) + (io.ungetc port #\-)))) (begin (read-char port) (loop newop (peek-char port) sufchar?)) str)) diff --git a/test/syntax.jl b/test/syntax.jl index 9feb7bfa709a3..992b17de0f29f 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -2292,3 +2292,7 @@ end @test (Int .<: [Integer] .<: [Real]) == [true] end + +@test :(a <-- b <-- c) == Expr(:call, :<--, :a, Expr(:call, :<--, :b, :c)) +@test :(a<-->b<-->c) == Expr(:call, :<-->, :a, Expr(:call, :<-->, :b, :c)) +@test_throws ParseError("invalid operator \"<---\"") Meta.parse("1<---2")