Skip to content

Commit 0103a2a

Browse files
committed
fix #37393: interpolation in for outer
1 parent 594ac89 commit 0103a2a

File tree

2 files changed

+50
-27
lines changed

2 files changed

+50
-27
lines changed

src/julia-parser.scm

+21-27
Original file line numberDiff line numberDiff line change
@@ -1650,33 +1650,27 @@
16501650

16511651
;; as above, but allows both "i=r" and "i in r"
16521652
(define (parse-iteration-spec s)
1653-
(let* ((outer? (if (eq? (peek-token s) 'outer)
1654-
(begin
1655-
(take-token s)
1656-
(let ((nxt (peek-token s)))
1657-
(if (or (memq nxt '(= in ∈))
1658-
(not (symbol? nxt))
1659-
(operator? nxt))
1660-
(begin (ts:put-back! s 'outer #t)
1661-
#f)
1662-
#t)))
1663-
#f))
1664-
(lhs (parse-pipe< s))
1665-
(t (peek-token s)))
1666-
(cond ((memq t '(= in ∈))
1667-
(take-token s)
1668-
(let* ((rhs (parse-pipe< s))
1669-
(t (peek-token s)))
1670-
#;(if (not (or (closing-token? t) (newline? t)))
1671-
;; should be: (error "invalid iteration specification")
1672-
(parser-depwarn s (string "for " (deparse `(= ,lhs ,rhs)) " " t)
1673-
(string "for " (deparse `(= ,lhs ,rhs)) "; " t)))
1674-
(if outer?
1675-
`(= (outer ,lhs) ,rhs)
1676-
`(= ,lhs ,rhs))))
1677-
((and (eq? lhs ':) (closing-token? t))
1678-
':)
1679-
(else (error "invalid iteration specification")))))
1653+
;; FIXME: this is just for backwards compatibility, allows newline before =/in/∈ in
1654+
;; generator expressions
1655+
(define (peek-token- s)
1656+
(let ((t (peek-token s)))
1657+
(if (and for-generator (newline? t))
1658+
(begin (take-token s)
1659+
(peek-token s))
1660+
t)))
1661+
(let* ((lhs (let ((lhs- (with-space-sensitive (parse-pipe< s))))
1662+
(if (eq? lhs- 'outer)
1663+
(let ((nxt (peek-token- s)))
1664+
(if (memq nxt '(= in ∈))
1665+
lhs-
1666+
`(outer ,(parse-pipe< s))))
1667+
lhs-)))
1668+
(t (peek-token- s)))
1669+
(if (memq t '(= in ∈))
1670+
(begin
1671+
(take-token s)
1672+
`(= ,lhs ,(parse-pipe< s)))
1673+
(error "invalid iteration specification"))))
16801674

16811675
(define (parse-comma-separated-iters s)
16821676
(let loop ((ranges '()))

test/syntax.jl

+29
Original file line numberDiff line numberDiff line change
@@ -2335,3 +2335,32 @@ if isodd(1) && all(iseven(2) for c in ())
23352335
else
23362336
@test false
23372337
end
2338+
2339+
@testset "issue #37393" begin
2340+
@test :(for outer i = 1:3; end) == Expr(:for, Expr(:(=), Expr(:outer, :i), :(1:3)), :(;;))
2341+
i = :i
2342+
@test :(for outer $i = 1:3; end) == Expr(:for, Expr(:(=), Expr(:outer, :i), :(1:3)), :(;;))
2343+
@test :(for outer = 1:3; end) == Expr(:for, Expr(:(=), :outer, :(1:3)), :(;;))
2344+
# TIL that this is possible
2345+
for outer $ i = 1:3
2346+
@test 1 $ 2 in 1:3
2347+
end
2348+
2349+
# 😭
2350+
@test Meta.isexpr(Meta.parse("""
2351+
[i for i
2352+
in 1:3]"""), :comprehension)
2353+
@test Meta.isexpr(Meta.parse("""
2354+
[i for outer
2355+
in 1:3]"""), :comprehension)
2356+
@test Meta.isexpr(Meta.parse("""
2357+
[i for outer
2358+
i in 1:3]"""), :comprehension)
2359+
@test Meta.isexpr(Meta.parse("""
2360+
f(i for i
2361+
in 1:3)""").args[2], :generator)
2362+
@test_throws Meta.ParseError Meta.parse("""
2363+
for i
2364+
in 1:3
2365+
end""")
2366+
end

0 commit comments

Comments
 (0)