Skip to content

Commit 912cd3f

Browse files
authored
fix #37393: interpolation in for outer (#37402)
1 parent 04433fc commit 912cd3f

File tree

2 files changed

+50
-27
lines changed

2 files changed

+50
-27
lines changed

src/julia-parser.scm

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,33 +1690,27 @@
16901690

16911691
;; as above, but allows both "i=r" and "i in r"
16921692
(define (parse-iteration-spec s)
1693-
(let* ((outer? (if (eq? (peek-token s) 'outer)
1694-
(begin
1695-
(take-token s)
1696-
(let ((nxt (peek-token s)))
1697-
(if (or (memq nxt '(= in ∈))
1698-
(not (symbol? nxt))
1699-
(operator? nxt))
1700-
(begin (ts:put-back! s 'outer #t)
1701-
#f)
1702-
#t)))
1703-
#f))
1704-
(lhs (parse-pipe< s))
1705-
(t (peek-token s)))
1706-
(cond ((memq t '(= in ∈))
1707-
(take-token s)
1708-
(let* ((rhs (parse-pipe< s))
1709-
(t (peek-token s)))
1710-
#;(if (not (or (closing-token? t) (newline? t)))
1711-
;; should be: (error "invalid iteration specification")
1712-
(parser-depwarn s (string "for " (deparse `(= ,lhs ,rhs)) " " t)
1713-
(string "for " (deparse `(= ,lhs ,rhs)) "; " t)))
1714-
(if outer?
1715-
`(= (outer ,lhs) ,rhs)
1716-
`(= ,lhs ,rhs))))
1717-
((and (eq? lhs ':) (closing-token? t))
1718-
':)
1719-
(else (error "invalid iteration specification")))))
1693+
;; FIXME: this is just for backwards compatibility, allows newline before =/in/∈ in
1694+
;; generator expressions
1695+
(define (peek-token- s)
1696+
(let ((t (peek-token s)))
1697+
(if (and for-generator (newline? t))
1698+
(begin (take-token s)
1699+
(peek-token s))
1700+
t)))
1701+
(let* ((lhs (let ((lhs- (with-space-sensitive (parse-pipe< s))))
1702+
(if (eq? lhs- 'outer)
1703+
(let ((nxt (peek-token- s)))
1704+
(if (memq nxt '(= in ∈))
1705+
lhs-
1706+
`(outer ,(parse-pipe< s))))
1707+
lhs-)))
1708+
(t (peek-token- s)))
1709+
(if (memq t '(= in ∈))
1710+
(begin
1711+
(take-token s)
1712+
`(= ,lhs ,(parse-pipe< s)))
1713+
(error "invalid iteration specification"))))
17201714

17211715
(define (parse-comma-separated-iters s)
17221716
(let loop ((ranges '()))

test/syntax.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2461,3 +2461,32 @@ import .TestImportAs.Mod2 as M2
24612461
@test Meta.parse("a'ᵀb") == Expr(:call, :*, Expr(:call, Symbol("'ᵀ"), :a), :b)
24622462
@test Meta.parse("a'⁻¹b") == Expr(:call, :*, Expr(:call, Symbol("'⁻¹"), :a), :b)
24632463
end
2464+
2465+
@testset "issue #37393" begin
2466+
@test :(for outer i = 1:3; end) == Expr(:for, Expr(:(=), Expr(:outer, :i), :(1:3)), :(;;))
2467+
i = :i
2468+
@test :(for outer $i = 1:3; end) == Expr(:for, Expr(:(=), Expr(:outer, :i), :(1:3)), :(;;))
2469+
@test :(for outer = 1:3; end) == Expr(:for, Expr(:(=), :outer, :(1:3)), :(;;))
2470+
# TIL that this is possible
2471+
for outer $ i = 1:3
2472+
@test 1 $ 2 in 1:3
2473+
end
2474+
2475+
# 😭
2476+
@test Meta.isexpr(Meta.parse("""
2477+
[i for i
2478+
in 1:3]"""), :comprehension)
2479+
@test Meta.isexpr(Meta.parse("""
2480+
[i for outer
2481+
in 1:3]"""), :comprehension)
2482+
@test Meta.isexpr(Meta.parse("""
2483+
[i for outer
2484+
i in 1:3]"""), :comprehension)
2485+
@test Meta.isexpr(Meta.parse("""
2486+
f(i for i
2487+
in 1:3)""").args[2], :generator)
2488+
@test_throws Meta.ParseError Meta.parse("""
2489+
for i
2490+
in 1:3
2491+
end""")
2492+
end

0 commit comments

Comments
 (0)