macro Estruct(name,arg,type,max=100,min=0,descritpion="")
:(struct $(esc(name))
$((esc(arg)))
$(esc(name))($(esc(arg)))=new(
check($(esc(type)),$(esc(arg)),$(esc(name)),$(esc(max)),$(esc(min)),$(esc(descritpion))))
end)
end
how can I imeplent this macro like this:
@Estruct begin
B
arg1
Float64
200.0
5.0
"this"
end
I don't know how to make a multiline macro. I thought I just have to add begin and end, but I'm always getting: MethodError: no method matching var"@Estruct"(::LineNumberNode, ::Module, ::Expr)
There's no such thing as a multiline macro, that's just a macro that takes a block as an argument. You can see how the macro gets invoked by writing a dummy version of it that just returns its arguments:
macro Estruct(args...); args; end
Now you can invoke that the way you want to call it and it will return its arguments as a tuple:
julia> args = @Estruct begin
B
arg1
Float64
200.0
5.0
"this"
end
(quote
#= REPL[12]:2 =#
B
#= REPL[12]:3 =#
arg1
#= REPL[12]:4 =#
Float64
#= REPL[12]:5 =#
200.0
#= REPL[12]:6 =#
5.0
#= REPL[12]:7 =#
"this"
end,)
julia> typeof(args)
Tuple{Expr}
julia> dump(args[1])
Expr
head: Symbol block
args: Array{Any}((12,))
1: LineNumberNode
line: Int64 2
file: Symbol REPL[12]
2: Symbol B
3: LineNumberNode
line: Int64 3
file: Symbol REPL[12]
4: Symbol arg1
5: LineNumberNode
line: Int64 4
file: Symbol REPL[12]
...
8: Float64 200.0
9: LineNumberNode
line: Int64 6
file: Symbol REPL[12]
10: Float64 5.0
11: LineNumberNode
line: Int64 7
file: Symbol REPL[12]
12: String "this"
julia> args[1].args
12-element Vector{Any}:
:(#= REPL[12]:2 =#)
:B
:(#= REPL[12]:3 =#)
:arg1
:(#= REPL[12]:4 =#)
:Float64
:(#= REPL[12]:5 =#)
200.0
:(#= REPL[12]:6 =#)
5.0
:(#= REPL[12]:7 =#)
"this"
This tells you that the macro gets called with a single argument which is an Expr
with head type :block
, i.e. the one argument is a quoted block. To implement your "multiline macro" you need to implement the macro body to accept a quoted block expression and process it, presumably by looking at its .args
field which is where all the expressions you're interested in are. You'll probably want to ignore all the LineNumberNode
objects in there and just process the other items in the block.