Skip to content

Commit 371bfa8

Browse files
authored
normalize parsing of --> (#36793)
1 parent d862442 commit 371bfa8

File tree

6 files changed

+24
-12
lines changed

6 files changed

+24
-12
lines changed

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ New language features
1212
Language changes
1313
----------------
1414

15+
* The `-->` operator now lowers to a `:call` expression, so it can be defined as
16+
a function like other operators. The dotted version `.-->` is now parsed as well.
17+
For backwards compatibility, `-->` still parses using its own expression head
18+
instead of `:call`.
1519

1620
Compiler/Runtime improvements
1721
-----------------------------

base/show.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ const uni_ops = Set{Symbol}([:(+), :(-), :(!), :(¬), :(~), :(<:), :(>:), :(√)
10771077
const expr_infix_wide = Set{Symbol}([
10781078
:(=), :(+=), :(-=), :(*=), :(/=), :(\=), :(^=), :(&=), :(|=), :(÷=), :(%=), :(>>>=), :(>>=), :(<<=),
10791079
:(.=), :(.+=), :(.-=), :(.*=), :(./=), :(.\=), :(.^=), :(.&=), :(.|=), :(.÷=), :(.%=), :(.>>>=), :(.>>=), :(.<<=),
1080-
:(&&), :(||), :(<:), :($=), :(⊻=), :(>:)])
1080+
:(&&), :(||), :(<:), :($=), :(⊻=), :(>:), :(-->)])
10811081
const expr_infix = Set{Symbol}([:(:), :(->), Symbol("::")])
10821082
const expr_infix_any = union(expr_infix, expr_infix_wide)
10831083
const expr_calls = Dict(:call => ('(',')'), :calldecl => ('(',')'),

src/ast.scm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
(string #\( (deparse (caddr e)) #\))))))
6868
((memq (car e) '(... |'|))
6969
(string (deparse (cadr e)) (car e)))
70-
((or (syntactic-op? (car e)) (eq? (car e) '|<:|) (eq? (car e) '|>:|))
70+
((or (syntactic-op? (car e)) (eq? (car e) '|<:|) (eq? (car e) '|>:|) (eq? (car e) '-->))
7171
(if (length= e 2)
7272
(string (car e) (deparse (cadr e)))
7373
(string (deparse (cadr e)) " " (car e) " " (deparse (caddr e)))))

src/julia-parser.scm

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,14 @@
33
; for most operators X there is a .X "elementwise" equivalent
44
(define (add-dots ops) (append! ops (map (lambda (op) (symbol (string "." op))) ops)))
55

6-
;; note: there are some strange-looking things in here because
7-
;; the way the lexer works, every prefix of an operator must also
8-
;; be an operator.
96
(define prec-assignment
107
(append! (add-dots '(= += -= *= /= //= |\\=| ^= ÷= %= <<= >>= >>>= |\|=| &= ⊻= ≔ ⩴ ≕))
118
(add-dots '(~))
129
'(:= $=)))
1310
;; comma - higher than assignment outside parentheses, lower when inside
1411
(define prec-pair (add-dots '(=>)))
1512
(define prec-conditional '(?))
16-
(define prec-arrow (append!
17-
'(-- -->)
18-
(add-dots '(← → ↔ ↚ ↛ ↞ ↠ ↢ ↣ ↦ ↤ ↮ ⇎ ⇍ ⇏ ⇐ ⇒ ⇔ ⇴ ⇶ ⇷ ⇸ ⇹ ⇺ ⇻ ⇼ ⇽ ⇾ ⇿ ⟵ ⟶ ⟷ ⟹ ⟺ ⟻ ⟼ ⟽ ⟾ ⟿ ⤀ ⤁ ⤂ ⤃ ⤄ ⤅ ⤆ ⤇ ⤌ ⤍ ⤎ ⤏ ⤐ ⤑ ⤔ ⤕ ⤖ ⤗ ⤘ ⤝ ⤞ ⤟ ⤠ ⥄ ⥅ ⥆ ⥇ ⥈ ⥊ ⥋ ⥎ ⥐ ⥒ ⥓ ⥖ ⥗ ⥚ ⥛ ⥞ ⥟ ⥢ ⥤ ⥦ ⥧ ⥨ ⥩ ⥪ ⥫ ⥬ ⥭ ⥰ ⧴ ⬱ ⬰ ⬲ ⬳ ⬴ ⬵ ⬶ ⬷ ⬸ ⬹ ⬺ ⬻ ⬼ ⬽ ⬾ ⬿ ⭀ ⭁ ⭂ ⭃ ⭄ ⭇ ⭈ ⭉ ⭊ ⭋ ⭌ ← → ⇜ ⇝ ↜ ↝ ↩ ↪ ↫ ↬ ↼ ↽ ⇀ ⇁ ⇄ ⇆ ⇇ ⇉ ⇋ ⇌ ⇚ ⇛ ⇠ ⇢ ↷ ↶ ↺ ↻ <-- <-->))))
13+
(define prec-arrow (add-dots '(← → ↔ ↚ ↛ ↞ ↠ ↢ ↣ ↦ ↤ ↮ ⇎ ⇍ ⇏ ⇐ ⇒ ⇔ ⇴ ⇶ ⇷ ⇸ ⇹ ⇺ ⇻ ⇼ ⇽ ⇾ ⇿ ⟵ ⟶ ⟷ ⟹ ⟺ ⟻ ⟼ ⟽ ⟾ ⟿ ⤀ ⤁ ⤂ ⤃ ⤄ ⤅ ⤆ ⤇ ⤌ ⤍ ⤎ ⤏ ⤐ ⤑ ⤔ ⤕ ⤖ ⤗ ⤘ ⤝ ⤞ ⤟ ⤠ ⥄ ⥅ ⥆ ⥇ ⥈ ⥊ ⥋ ⥎ ⥐ ⥒ ⥓ ⥖ ⥗ ⥚ ⥛ ⥞ ⥟ ⥢ ⥤ ⥦ ⥧ ⥨ ⥩ ⥪ ⥫ ⥬ ⥭ ⥰ ⧴ ⬱ ⬰ ⬲ ⬳ ⬴ ⬵ ⬶ ⬷ ⬸ ⬹ ⬺ ⬻ ⬼ ⬽ ⬾ ⬿ ⭀ ⭁ ⭂ ⭃ ⭄ ⭇ ⭈ ⭉ ⭊ ⭋ ⭌ ← → ⇜ ⇝ ↜ ↝ ↩ ↪ ↫ ↬ ↼ ↽ ⇀ ⇁ ⇄ ⇆ ⇇ ⇉ ⇋ ⇌ ⇚ ⇛ ⇠ ⇢ ↷ ↶ ↺ ↻ --> <-- <-->)))
1914
(define prec-lazy-or '(|\|\||))
2015
(define prec-lazy-and '(&&))
2116
(define prec-comparison
@@ -66,7 +61,7 @@
6661
; only allow/strip suffixes for some operators
6762
(define no-suffix? (Set (append prec-assignment prec-conditional prec-lazy-or prec-lazy-and
6863
prec-colon prec-decl prec-dot
69-
'(-- --> -> |<:| |>:| in isa $)
64+
'(-> |<:| |>:| in isa $)
7065
(list ctrans-op trans-op vararg-op))))
7166
(define (maybe-strip-op-suffix op)
7267
(if (symbol? op)
@@ -115,7 +110,7 @@
115110
; operators that are special forms, not function names
116111
(define syntactic-operators
117112
(append! (add-dots '(= += -= *= /= //= |\\=| ^= ÷= %= <<= >>= >>>= |\|=| &= ⊻=))
118-
'(:= --> $= && |\|\|| |.| ... ->)))
113+
'(:= $= && |\|\|| |.| ... ->)))
119114
(define syntactic-unary-operators '($ & |::|))
120115

121116
(define syntactic-op? (Set syntactic-operators))
@@ -252,6 +247,12 @@
252247
(if (or (operator? opsym)
253248
(and (or (eq? opsym '<---) (eq? opsym '.<---))
254249
(error (string "invalid operator \"" newop "\"")))
250+
;; -- is not an operator but --> is
251+
(and (or (eq? opsym '--) (eq? opsym '.--))
252+
(read-char port)
253+
(or (begin0 (eqv? (peek-char port) #\>)
254+
(io.ungetc port #\-))
255+
(error (string "invalid operator \"" newop "\""))))
255256
;; <- is not an operator but <-- and <--> are
256257
(and (or (eq? opsym '<-) (eq? opsym '.<-))
257258
(read-char port)
@@ -261,8 +262,6 @@
261262
(loop newop (peek-char port) sufchar?))
262263
str))
263264
str))))))
264-
(if (equal? str "--")
265-
(error (string "invalid operator \"" str "\"")))
266265
(string->symbol str))))
267266

268267
(define (accum-digits c pred port _-digit-sep)

src/julia-syntax.scm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1960,6 +1960,8 @@
19601960
(lambda (e) (expand-forms `(call |<:| ,@(cdr e))))
19611961
'|>:|
19621962
(lambda (e) (expand-forms `(call |>:| ,@(cdr e))))
1963+
'-->
1964+
(lambda (e) (expand-forms `(call --> ,@(cdr e))))
19631965

19641966
'where
19651967
(lambda (e) (expand-forms (expand-wheres (cadr e) (cddr e))))

test/syntax.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2297,5 +2297,12 @@ end
22972297
@test :(a .<-- b.<--c) == Expr(:call, :.<--, :a, Expr(:call, :.<--, :b, :c))
22982298
@test :(a<-->b<-->c) == Expr(:call, :<-->, :a, Expr(:call, :<-->, :b, :c))
22992299
@test :(a.<-->b .<--> c) == Expr(:call, :.<-->, :a, Expr(:call, :.<-->, :b, :c))
2300+
@test :(a --> b --> c) == Expr(:-->, :a, Expr(:-->, :b, :c))
2301+
@test :(a --> b.-->c) == Expr(:-->, :a, Expr(:call, :.-->, :b, :c))
2302+
let (-->) = (+)
2303+
@test (40 --> 2) == 42
2304+
end
23002305
@test_throws ParseError("invalid operator \"<---\"") Meta.parse("1<---2")
23012306
@test_throws ParseError("invalid operator \".<---\"") Meta.parse("1 .<--- 2")
2307+
@test_throws ParseError("invalid operator \"--\"") Meta.parse("a---b")
2308+
@test_throws ParseError("invalid operator \".--\"") Meta.parse("a.---b")

0 commit comments

Comments
 (0)