Generate an array in a macro

macros
#1

I have some variables, eg

a=1;b=2;c=3;

What I want is to generate an array (or tuple) of the following:

[("a", 1),
 ("b", 2),
 ("c", 3)]

So far I got the conversion for one variable

macro convertarg(var)
    return :(($(string(var))), $(esc(var)))
end
julia> @convertarg(a)
("a", 1)

My first idea was to call convertarg in a loop from within another macro:

macro convertargs(vars...)
	pairs = []
	for var in vars
		append!(pairs, (@convertarg(var),))
	end
	return pairs
end

which does not work since it variables must be quoted also in convertargs. Also directly putting the code of convertarg at the position of the macro call does not work for the same reason. When quoting the whole expression I cannot access the macro arguments.

How can I obtain in array as wanted? I cannot wrap around that the expressions within the array must be quoted but not the returned array itself.

I am also thankfull for some explanations since I seemingly misunderstand something in how macros work.

0 Likes

#2

This macro should do what you want:

macro cas(args...)
    ret = Expr(:vect)
    for a in args
        push!(ret.args, :(($(string(a)), $(esc(a)))))
    end
    return ret
end

The head of an expression tells us the type of expression, and the args describe the expression. The first line creates an expression with symbol vect as first element, and the for loop adds the ast representations of the tuples to the args of the vector, which define the contents of a vector.

0 Likes

#3

Thank you!

I tried out the followingto get out a tuple from the code:

macro cas(args...)
    ret = Expr(:tuple)
    for a in args
        push!(ret.args, :(($(string(a)), $(esc(a)))))
    end
    return ret
end

and it works. So :vect for Arrays and :tuple for tuples. Can this be generalized? Or are those things documented?

0 Likes

#4

Why do you want to use a macro for this? It would be simpler and just as efficient to use a function to construct the result you’re asking for.

0 Likes

#5

afaik it is not possible to obtain the name of a variable as string in a function

0 Likes

#6

Oh, my mistake, I didn’t notice that you wanted the names of the variables, not their values. Carry on :slightly_smiling_face:

0 Likes

#7

Try dump(:(1+1 == 2))

2 Likes

#8

thank you again!

0 Likes