Hello. I am trying to create a struct through a macro with types that will be know at runtime. It would work something like this: the user would pass a string “a::A b::B” and the macro would create a struct:
struct MyStruct
a::A
b::B
end
The problem is I don’t know how to break the types from the string to create the struct in the macro. Any help would be appreciated.
I’d suggest avoiding strings entirely. There’s no need to manually construct or parse strings for metaprogramming in Julia, since we have much better tools for working directly with expressions.
For example, you could do something like this:
julia> macro make_struct(fields...)
quote
struct MyStruct
$(esc.(fields)...)
end
end
end
@make_struct (macro with 2 methods)
julia> @make_struct(x::Int, y::Float64)
We can use @macroexpand
to verify the macro’s behavior:
julia> @macroexpand @make_struct(x::Int, y::Float64)
quote
#= REPL[7]:3 =#
struct MyStruct
#= REPL[7]:4 =#
x::Int
y::Float64
end
end
The @make_struct
macro takes the field definitions as expressions, so there’s no need to try to split up the string or extract the types because the Julia parser has already done that for you.
2 Likes
Right, but the problem is, the types will come from a TOML file, and so will live as a string inside the Julia program.
Ok, then I’d suggest:
- Use
Meta.parse
to turn a string into an expression
- Don’t use a macro at all–just write a function that calls
eval
, something like:
julia> function make_struct(fields)
eval(quote
struct MyStruct
$(fields...)
end
end)
end
where fields
is a collection of Expr
s from Meta.parse
4 Likes
Alright, I will try that. Thanks!