From 6c4e30e3677c404c1cbec8086acd49ed9152a786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Crist=C3=B3v=C3=A3o=20Duarte=20Sousa?= Date: Mon, 2 Oct 2017 17:24:34 +0100 Subject: [PATCH] Allow juxtaposition of macro and array literal. fixes #23519 (#23547) --- NEWS.md | 3 +++ doc/src/manual/metaprogramming.md | 7 +++++++ src/julia-parser.scm | 22 ++++++++++++---------- test/parse.jl | 8 ++++++++ 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/NEWS.md b/NEWS.md index 21f113a946741..58bd5372cd8a3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -16,6 +16,9 @@ New language features For example, `+̂ₐ″` is parsed as an infix operator with the same precedence as `+` ([#22089]). + * The macro call syntax `@macroname[args]` is now available and is parsed + as `@macroname([args])` ([#23519]). + Language changes ---------------- diff --git a/doc/src/manual/metaprogramming.md b/doc/src/manual/metaprogramming.md index 3c4c12d1cde5d..743881b9a5d86 100644 --- a/doc/src/manual/metaprogramming.md +++ b/doc/src/manual/metaprogramming.md @@ -583,6 +583,13 @@ above; it passes the tuple `(expr1, expr2, ...)` as one argument to the macro: @name (expr1, expr2, ...) ``` +An alternative way to invoke a macro over an array literal (or comprehension) is to juxtapose both without using parentheses. In this case, the array will be the only expression fed to the macro. The following syntax is equivalent (and different from `@name [a b] * v`): + +```julia +@name[a b] * v +@name([a b]) * v +``` + It is important to emphasize that macros receive their arguments as expressions, literals, or symbols. One way to explore macro arguments is to call the [`show`](@ref) function within the macro body: diff --git a/src/julia-parser.scm b/src/julia-parser.scm index ebe7c79eb3fe8..02de2b130336d 100644 --- a/src/julia-parser.scm +++ b/src/julia-parser.scm @@ -1189,16 +1189,18 @@ ;; ref(a,i) = x (let* ((es end-symbol) (al (with-end-symbol (parse-cat s #\] es)))) - (if (null? al) - (loop (list 'ref ex)) - (case (car al) - ((vect) (loop (list* 'ref ex (cdr al)))) - ((hcat) (loop (list* 'typed_hcat ex (cdr al)))) - ((vcat) - (loop (list* 'typed_vcat ex (cdr al)))) - ((comprehension) - (loop (list* 'typed_comprehension ex (cdr al)))) - (else (error "unknown parse-cat result (internal error)")))))) + (if macrocall? + (list 'call ex al) + (if (null? al) + (loop (list 'ref ex)) + (case (car al) + ((vect) (loop (list* 'ref ex (cdr al)))) + ((hcat) (loop (list* 'typed_hcat ex (cdr al)))) + ((vcat) + (loop (list* 'typed_vcat ex (cdr al)))) + ((comprehension) + (loop (list* 'typed_comprehension ex (cdr al)))) + (else (error "unknown parse-cat result (internal error)"))))))) ((|.|) (if (ts:space? s) (disallowed-space ex t)) (take-token s) diff --git a/test/parse.jl b/test/parse.jl index 62a3f786684a0..369585998667a 100644 --- a/test/parse.jl +++ b/test/parse.jl @@ -1366,3 +1366,11 @@ let xs = [:(1+2), :(3+4), :(5+6)] ex2 = eval(ex) @test ex2.args[2:end] == [3,7,11] end + +# issue #23519 +@test parse("@foo[1]") == parse("@foo([1])") +@test parse("@foo[1 2; 3 4]") == parse("@foo([1 2; 3 4])") +@test parse("@foo[1] + [2]") == parse("@foo([1]) + [2]") +@test parse("@foo [1] + [2]") == parse("@foo([1] + [2])") +@test parse("@Mdl.foo[1] + [2]") == parse("@Mdl.foo([1]) + [2]") +@test parse("@Mdl.foo [1] + [2]") == parse("@Mdl.foo([1] + [2])")