Skip to content

Commit 0029ab6

Browse files
committed
RFC: Allow macrocall as function sig
@KristofferC requested that `function @main(args) end` should work. This is currently a parse error. This PR makes it work as expected by allowing macrocall as a valid signature in function (needs to exapand to a call expr). Note that this is only the flisp changes. If this PR is accepted, an equivalent change would need to be made in JuliaSyntax.
1 parent bbb4403 commit 0029ab6

File tree

3 files changed

+38
-10
lines changed

3 files changed

+38
-10
lines changed

base/client.jl

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ The `@main` macro may be used standalone or as part of the function definition,
599599
case, parentheses are required. In particular, the following are equivalent:
600600
601601
```
602-
function (@main)(args)
602+
function @main(args)
603603
println("Hello World")
604604
end
605605
```
@@ -618,7 +618,7 @@ imported into `Main`, it will be treated as an entrypoint in `Main`:
618618
```
619619
module MyApp
620620
export main
621-
(@main)(args) = println("Hello World")
621+
@main(args) = println("Hello World")
622622
end
623623
using .MyApp
624624
# `julia` Will execute MyApp.main at the conclusion of script execution
@@ -628,7 +628,7 @@ Note that in particular, the semantics do not attach to the method
628628
or the name:
629629
```
630630
module MyApp
631-
(@main)(args) = println("Hello World")
631+
@main(args) = println("Hello World")
632632
end
633633
const main = MyApp.main
634634
# `julia` Will *NOT* execute MyApp.main unless there is a separate `@main` annotation in `Main`
@@ -638,9 +638,6 @@ const main = MyApp.main
638638
This macro is new in Julia 1.11. At present, the precise semantics of `@main` are still subject to change.
639639
"""
640640
macro main(args...)
641-
if !isempty(args)
642-
error("`@main` is expected to be used as `(@main)` without macro arguments.")
643-
end
644641
if isdefined(__module__, :main)
645642
if Base.binding_module(__module__, :main) !== __module__
646643
error("Symbol `main` is already a resolved import in module $(__module__). `@main` must be used in the defining module.")
@@ -651,5 +648,9 @@ macro main(args...)
651648
global main
652649
global var"#__main_is_entrypoint__#"::Bool = true
653650
end)
654-
esc(:main)
651+
if !isempty(args)
652+
Expr(:call, esc(:main), map(esc, args)...)
653+
else
654+
esc(:main)
655+
end
655656
end

src/julia-parser.scm

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,13 +1329,12 @@
13291329

13301330
(define (valid-func-sig? paren sig)
13311331
(and (pair? sig)
1332-
(or (eq? (car sig) 'call)
1333-
(eq? (car sig) 'tuple)
1332+
(or (memq (car sig) '(macrocall call tuple))
13341333
(and paren (eq? (car sig) 'block))
13351334
(and paren (eq? (car sig) '...))
13361335
(and (eq? (car sig) '|::|)
13371336
(pair? (cadr sig))
1338-
(eq? (car (cadr sig)) 'call))
1337+
(memq (car (cadr sig)) '(call macrocall)))
13391338
(and (eq? (car sig) 'where)
13401339
(valid-func-sig? paren (cadr sig))))))
13411340

test/syntax.jl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3904,3 +3904,31 @@ module ExtendedIsDefined
39043904
@test !$(Expr(:isdefined, GlobalRef(@__MODULE__, :x4), false))
39053905
end
39063906
end
3907+
3908+
# PR# 55040 - Macrocall as function sig
3909+
@test :(function @f()() end) == :(function (@f)() end)
3910+
3911+
function callme end
3912+
macro callmemacro(args...)
3913+
Expr(:call, esc(:callme), map(esc, args)...)
3914+
end
3915+
function @callmemacro(a::Int)
3916+
return 1
3917+
end
3918+
@callmemacro(b::Float64) = 2
3919+
function @callmemacro(a::T, b::T) where T <: Int64
3920+
return 3
3921+
end
3922+
function @callmemacro(a::Int, b::Int, c::Int)::Float64
3923+
return 4
3924+
end
3925+
function @callmemacro(d::String)
3926+
(a, b, c)
3927+
# ^ Should not be accidentally parsed as an argument list
3928+
return 4
3929+
end
3930+
3931+
@test callme(1) === 1
3932+
@test callme(2.0) === 2
3933+
@test callme(3, 3) === 3
3934+
@test callme(4, 4, 4) === 4.0

0 commit comments

Comments
 (0)