Skip to content

Commit 4d6f70f

Browse files
committed
fix #7669, always parse assignments the same inside macro calls
1 parent cfa2312 commit 4d6f70f

File tree

3 files changed

+34
-17
lines changed

3 files changed

+34
-17
lines changed

NEWS.md

+3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ This section lists changes that do not have deprecation warnings.
7575

7676
* `quadgk` has been moved from Base into a separate package. ([#19741])
7777

78+
* In macro calls with parentheses, e.g. `@m(a=1)`, assignments are now parsed as
79+
`=` expressions, instead of as `kw` expressions. ([#7669])
80+
7881
Library improvements
7982
--------------------
8083

src/julia-parser.scm

+28-17
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@
984984
((#\") '_str)
985985
((#\`) '_cmd)))
986986

987-
(define (parse-call-chain s ex one-call)
987+
(define (parse-call-chain s ex macrocall?)
988988
(let loop ((ex ex))
989989
(let ((t (peek-token s)))
990990
(if (or (and space-sensitive (ts:space? s)
@@ -997,20 +997,27 @@
997997
((#\( )
998998
(if (ts:space? s) (disallowed-space ex t))
999999
(take-token s)
1000-
(let ((c (let ((al (parse-arglist s #\) )))
1001-
(receive
1002-
(params args) (separate (lambda (x)
1003-
(and (pair? x)
1004-
(eq? (car x) 'parameters)))
1005-
al)
1006-
(if (eq? (peek-token s) 'do)
1007-
(begin
1008-
(take-token s)
1009-
`(call ,ex ,@params ,(parse-do s) ,@args))
1010-
`(call ,ex ,@al))))))
1011-
(if one-call
1012-
c
1013-
(loop c))))
1000+
(if macrocall?
1001+
(let ((args (if (eqv? (require-token s) #\) )
1002+
(begin (take-token s) '())
1003+
(begin0 (with-normal-ops
1004+
(with-whitespace-newline
1005+
(parse-comma-separated s parse-eq* #t)))
1006+
(if (not (eqv? (require-token s) #\) ))
1007+
(error "missing ) in argument list"))
1008+
(take-token s)))))
1009+
`(call ,ex ,@args))
1010+
(loop (let ((al (parse-arglist s #\) )))
1011+
(receive
1012+
(params args) (separate (lambda (x)
1013+
(and (pair? x)
1014+
(eq? (car x) 'parameters)))
1015+
al)
1016+
(if (eq? (peek-token s) 'do)
1017+
(begin
1018+
(take-token s)
1019+
`(call ,ex ,@params ,(parse-do s) ,@args))
1020+
`(call ,ex ,@al)))))))
10141021
((#\[ )
10151022
(if (ts:space? s) (disallowed-space ex t))
10161023
(take-token s)
@@ -1400,11 +1407,15 @@
14001407
`(,word ,@(reverse path)))))))
14011408

14021409
;; parse comma-separated assignments, like "i=1:n,j=1:m,..."
1403-
(define (parse-comma-separated s what)
1410+
(define (parse-comma-separated s what (in-parens #f))
14041411
(let loop ((exprs '()))
14051412
(let ((r (what s)))
14061413
(case (peek-token s)
1407-
((#\,) (take-token s) (loop (cons r exprs)))
1414+
((#\,)
1415+
(take-token s)
1416+
(if (and in-parens (eqv? (require-token s) #\) ))
1417+
(reverse! (cons r exprs))
1418+
(loop (cons r exprs))))
14081419
(else (reverse! (cons r exprs)))))))
14091420

14101421
(define (parse-comma-separated-assignments s)

test/parse.jl

+3
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,9 @@ let ..(x,y) = x + y
868868
@test 3 .. 4 === 7
869869
end
870870

871+
# issue #7669
872+
@test parse("@a(b=1, c=2)") == Expr(:macrocall, Symbol("@a"), :(b=1), :(c=2))
873+
871874
# issue #19685
872875
let f = function (x; kw...)
873876
return (x, kw)

0 commit comments

Comments
 (0)