Skip to content

Commit

Permalink
Merge pull request #21466 from JuliaLang/jb/fix21440
Browse files Browse the repository at this point in the history
fix #21440, parsing `+(x::T,y::T) where {T}`
  • Loading branch information
JeffBezanson committed Apr 21, 2017
2 parents 5444473 + 6955932 commit 3ccbcf7
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 8 deletions.
19 changes: 11 additions & 8 deletions src/julia-parser.scm
Expand Up @@ -25,9 +25,11 @@
(define prec-bitshift (add-dots '(<< >> >>>)))
(define prec-times (add-dots '(* / ÷ % & ⋅ ∘ × |\\| ∩ ∧ ⊗ ⊘ ⊙ ⊚ ⊛ ⊠ ⊡ ⊓ ∗ ∙ ∤ ⅋ ≀ ⊼ ⋄ ⋆ ⋇ ⋉ ⋊ ⋋ ⋌ ⋏ ⋒ ⟑ ⦸ ⦼ ⦾ ⦿ ⧶ ⧷ ⨇ ⨰ ⨱ ⨲ ⨳ ⨴ ⨵ ⨶ ⨷ ⨸ ⨻ ⨼ ⨽ ⩀ ⩃ ⩄ ⩋ ⩍ ⩎ ⩑ ⩓ ⩕ ⩘ ⩚ ⩜ ⩞ ⩟ ⩠ ⫛ ⊍ ▷ ⨝ ⟕ ⟖ ⟗)))
(define prec-rational (add-dots '(//)))
;; `where`
;; unary
(define prec-power (add-dots '(^ ↑ ↓ ⇵ ⟰ ⟱ ⤈ ⤉ ⤊ ⤋ ⤒ ⤓ ⥉ ⥌ ⥍ ⥏ ⥑ ⥔ ⥕ ⥘ ⥙ ⥜ ⥝ ⥠ ⥡ ⥣ ⥥ ⥮ ⥯ ↑ ↓)))
(define prec-decl '(|::|))
;; `where`
;; `where` occurring after `::`
(define prec-dot '(|.|))

(define prec-names '(prec-assignment
Expand Down Expand Up @@ -593,8 +595,9 @@
(peek-token s))))
ex))))

(define (parse-where s)
(let ((ex (parse-call s)))
(define (parse-where s down)
;; `where` needs to be below unary for `+(x::T,y::T) where {T} = ...` to work
(let ((ex (down s)))
(if (and where-enabled
(eq? (peek-token s) 'where))
(parse-where-chain s ex)
Expand Down Expand Up @@ -819,7 +822,7 @@

(define (parse-term s) (parse-with-chains s parse-rational is-prec-times? '(*)))

(define (parse-rational s) (parse-LtoR s parse-unary is-prec-rational?))
(define (parse-rational s) (parse-LtoR s (lambda (s) (parse-where s parse-unary)) is-prec-rational?))

(define (parse-pipes s) (parse-LtoR s parse-range is-prec-pipe?))

Expand Down Expand Up @@ -954,11 +957,11 @@
(parse-factor-h s parse-decl is-prec-power?))

(define (parse-decl s)
(let loop ((ex (parse-where s)))
(let loop ((ex (parse-call s)))
(let ((t (peek-token s)))
(case t
((|::|) (take-token s)
(loop (list t ex (parse-where s))))
(loop (list t ex (parse-where s parse-call))))
((->) (take-token s)
;; -> is unusual: it binds tightly on the left and
;; loosely on the right.
Expand All @@ -973,7 +976,7 @@
(begin (take-token s)
(cond ((let ((next (peek-token s)))
(or (closing-token? next) (newline? next))) op)
((memq op '(& |::|)) (list op (parse-where s)))
((memq op '(& |::|)) (list op (parse-where s parse-call)))
(else (list op (parse-unary-prefix s)))))
(parse-atom s))))

Expand Down Expand Up @@ -1312,7 +1315,7 @@
(list 'bitstype nb spec)))
((typealias)
(let ((lhs (with-space-sensitive (parse-call s)))
(rhs (parse-where s)))
(rhs (parse-where s parse-call)))
(syntax-deprecation s (string "typealias " (deparse lhs) " " (deparse rhs))
(string (if (symbol? lhs) "const " "")
(deparse lhs) " = " (deparse rhs)))
Expand Down
4 changes: 4 additions & 0 deletions test/parse.jl
Expand Up @@ -1103,3 +1103,7 @@ end
Expr(:toplevel,
Expr(:using, Symbol("."), :B),
Expr(:using, Symbol("."), :C))

# issue #21440
@test parse("+(x::T,y::T) where {T} = 0") == parse("(+)(x::T,y::T) where {T} = 0")
@test parse("a::b::c") == Expr(:(::), Expr(:(::), :a, :b), :c)

0 comments on commit 3ccbcf7

Please sign in to comment.