Preprocessor Quoting macro arguments - macros

Suppose I have some macro #define NAME name, and I want to define some other macro which will expand to the quoted value. That is, as if I had also defined #define NAME_STR "name". Is there a neater way than the following?
#define QUOT(str) #str
#define QUOT_ARG(str) QUOT(str)
#define NAME_STR QUOT_ARG(NAME)

Not really, due to the fact that macro arguments are not expanded when used in stringification. From the GNU C PreProcessor manual:
Unlike normal parameter replacement,
the argument is not macro-expanded
first. This is called stringification.
From the same source:
If you want to stringify the result of
expansion of a macro argument, you
have to use two levels of macros.
...which continues with an example:
#define xstr(s) str(s)
#define str(s) #s
#define foo 4
str (foo)
==> "foo"
xstr (foo)
==> xstr (4)
==> str (4)
==> "4"

Related

Julia: Macros, Expressions and Meta.parse

All these following lines of code are Julia expressions:
x = 10
1 + 1
println("hi")
if you want to pass an expression to a macro, it works like this. Macro foo just returns the given expression, which will be executed:
macro foo(ex)
return ex
end
#foo println("yes") # prints yes
x = #foo 1+1
println(x) # prints 2
If you want to convert a string into an expression, you can use Meta.parse():
string = "1+1"
expr = Meta.parse(string)
x = #foo expr
println(x) # prints 1 + 1
But, obviously, the macro treats expr as a symbol. What am i getting wrong here?
Thanks in advance!
Macro hygiene is important "macros must ensure that the variables they introduce in their returned expressions do not accidentally clash with existing variables in the surrounding code they expand into." There is a section in the docs. It is easiest just to show a simple case:
macro foo(x)
return :($x)
end
When you enter an ordinary expression in the REPL, it is evaluated immediately. To suppress that evaluation, surround the expression with :( ).
julia> 1 + 1
2
julia> :(1 + 1)
:(1 + 1)
# note this is the same result as you get using Meta.parse
julia> Meta.parse("1 + 1")
:(1 + 1)
So, Meta.parse will convert an appropriate string to an expression. And if you eval the result, the expression will be evaluated. Note that printing a simple expression removes the outer :( )
julia> expr = Meta.parse("1 + 1")
:(1 + 1)
julia> print(expr)
1 + 1
julia> result = eval(expr)
2
Usually, macros are used to manipulate things before the usual evaluation of expressions; they are syntax transformations, mostly. Macros are performed before other source code is compiled/evaluated/executed.
Rather than seeking a macro that evaluates a string as if it were typed directly into the REPL (without quotes), use this function instead.
evalstr(x::AbstractString) = eval(Meta.parse(x))
While I do not recommend this next macro, it is good to know the technique.
A macro named <name>_str is used like this <name>"<string contents>" :
julia> macro eval_str(x)
:(eval(Meta.parse($x)))
end
julia> eval"1 + 1"
2
(p.s. do not reuse Base function names as variable names, use str not string)
Please let me know if there is something I have not addressed.

Macro with arguments with default values, where default value is previous argument

I have a macro defined like this:
`define some_macro(ARG0, ARG1 = ARG0) \
...
I'd like the expansion some_macro(2) to expand to some_macro(2, 2). It expands to some_macro(2, ARG0), because in the default value specification for ARG1 the text ARG0 is used and not the value of the ARG0 argument.
Is it possible to specify the default of the second argument to be the value of ARG0?
Here's a good summary of what you can do with SV macros.
You could mostly achieve this with two macros, like
`define M(A1) \
`M2(A1, A1)
`define M2(A1, A2) \
"A1 A2"
module m();
initial begin
$display("joined string %s", `M(bye));
$finish;
end
endmodule
The difference is that this would require using either M or M2 depending on the number of arguments, not just one macro for both cases.

Quote-unquote idiom in Julia & concatenating Expr objects

I'd like to write a simple macro that shows the names & values of variables. In Common Lisp it would be
(defmacro dprint (&rest vars)
`(progn
,#(loop for v in vars
collect `(format t "~a: ~a~%" ',v ,v))))
In Julia I had two problems writing this:
How can I collect the generated Expr objects into a block? (In Lisp, this is done by splicing the list with ,# into progn.) The best I could come up with is to create an Expr(:block), and set its args to the list, but this is far from elegant.
I need to use both the name and the value of the variable. Interpolation inside strings and quoted expressions both use $, which complicates the issue, but even if I use string for concatenation, I can 't print the variable's name - at least :($v) does not do the same as ',v in CL...
My current macro looks like this:
macro dprint(vars...)
ex = Expr(:block)
ex.args = [:(println(string(:($v), " = ", $v))) for v in vars]
ex
end
Looking at a macroexpansion shows the problem:
julia> macroexpand(:(#dprint x y))
quote
println(string(v," = ",x))
println(string(v," = ",y))
end
I would like to get
quote
println(string(:x," = ",x))
println(string(:y," = ",y))
end
Any hints?
EDIT: Combining the answers, the solution seems to be the following:
macro dprint(vars...)
quote
$([:(println(string($(Meta.quot(v)), " = ", $v))) for v in vars]...)
end
end
... i.e., using $(Meta.quot(v)) to the effect of ',v, and $(expr...) for ,#expr. Thank you again!
the #show macro already exists for this. It is helpful to be able to implement it yourself, so later you can do other likes like make one that will show the size of an Array..
For your particular variant:
Answer is Meta.quot,
macro dprint(vars...)
ex = Expr(:block)
ex.args = [:(println($(Meta.quot(v)), " = ", $v)) for v in vars]
ex
end
See with:
julia> a=2; b=3;
julia> #dprint a
a = 2
julia> #dprint a b
a = 2
b = 3
oxinabox's answer is good, but I should mention the equivalent to ,#x is $(x...) (this is the other part of your question).
For instance, consider the macro
macro _begin(); esc(:begin); end
macro #_begin()(args...)
quote
$(args...)
end |> esc
end
and invocation
#begin x=1 y=2 x*y
which (though dubiously readable) produces the expected result 2. (The #_begin macro is not part of the example; it is required however because begin is a reserved word, so one needs a macro to access the symbol directly.)
Note
julia> macroexpand(:(#begin 1 2 3))
quote # REPL[1], line 5:
1
2
3
end
I consider this more readable, personally, than pushing to the .args array.

C language preprocessor behavior

There are different kind of macros in the C language, nested macro is one of them.
Considering a program with the following macro
#define HYPE(x,y) (SQUR(x)+SQUR(y))
#define SQUR(x) (x*x)
Using this we can successfully compile to get the result.
As we all know the C preprocessor replaces all the occurrence of the identifiers with the replacement-string. Considering the above example I would like to know how many times the C preprocessor traverses the program to replace the macro with the replacement values. I assume it cannot be done in one go.
the replacement takes place, when "HYPE" is actually used. it is not expanded when the #define statement occurs.
eg:
1 #define FOO 1
2
3 void foo() {
4 printf("%d\n", FOO);
5 }
so the replacement takes place in line 5, and not in line 1. hence the answer to your question is: once.
A #define'd macro invocation is expanded until there are no more terms to expand, except it doesn't recurse. For example:
#define TIMES *
#define factorial(n) ((n) == 0 ? 1 : (n) TIMES factorial((n)-1))
// Doesn't actually work, don't use.
Suppose you say factorial(2). It will expand to ((2) == 0 ? 1 : (2) * factorial((2)-1)). Note that factorial is expanded, then TIMES is also expanded, but factorial isn't expanded again afterwards, as that would be recursion.
However, note that nesting (arguably a different type of "recursion") is in fact expanded multiple times in the same expression:
#define ADD(a,b) ((a)+(b))
....
ADD(ADD(1,2),ADD(3,4)) // expands to ((((1)+(2)))+(((3)+(4))))

Variadic recursive preprocessor macros - is it possible?

I've run into a little theoretical problem. In a piece of code I'm maintaining there's a set of macros like
#define MAX_OF_2(a, b) (a) > (b) ? (a) : (b)
#define MAX_OF_3(a, b, c) MAX_OF_2(MAX_OF_2(a, b), c)
#define MAX_OF_4(a, b, c, d) MAX_OF_2(MAX_OF_3(a, b, c), d)
...etc up to MAX_OF_8
What I'd like to do is replace them with something like this:
/* Base case #1, single input */
#define MAX_OF_N(x) (x)
/* Base case #2, two inputs */
#define MAX_OF_N(x, y) (x) > (y) ? (x) : (y)
/* Recursive definition, arbitrary number of inputs */
#define MAX_OF_N(x, ...) MAX_OF_N(x, MAX_OF_N(__VA_ARGS__))
...which, of course, is not valid preprocessor code.
Ignoring that this particular case should probably be solved using a function rather than a preprocessor macro, is it possible to define a variadic MAX_OF_N() macro?
Just for clarity, the end result should be a single macro that takes an arbitrary number of parameters and evaluates to the largest of them. I've got an odd feeling that this should be possible, but I'm not seeing how.
It's possible to write a macro that evaluates to the number of arguments it's called with. (I couldn't find a link to the place where I first saw it.) So you could write MAX_OF_N() that would work as you'd like, but you'd still need all the numbered macros up until some limit:
#define MAX_OF_1(a) (a)
#define MAX_OF_2(a,b) max(a, b)
#define MAX_OF_3(a,...) MAX_OF_2(a,MAX_OF_2(__VA_ARGS__))
#define MAX_OF_4(a,...) MAX_OF_2(a,MAX_OF_3(__VA_ARGS__))
#define MAX_OF_5(a,...) MAX_OF_2(a,MAX_OF_4(__VA_ARGS__))
...
#define MAX_OF_64(a,...) MAX_OF_2(a,MAX_OF_63(__VA_ARGS__))
// NUM_ARGS(...) evaluates to the literal number of the passed-in arguments.
#define _NUM_ARGS2(X,X64,X63,X62,X61,X60,X59,X58,X57,X56,X55,X54,X53,X52,X51,X50,X49,X48,X47,X46,X45,X44,X43,X42,X41,X40,X39,X38,X37,X36,X35,X34,X33,X32,X31,X30,X29,X28,X27,X26,X25,X24,X23,X22,X21,X20,X19,X18,X17,X16,X15,X14,X13,X12,X11,X10,X9,X8,X7,X6,X5,X4,X3,X2,X1,N,...) N
#define NUM_ARGS(...) _NUM_ARGS2(0, __VA_ARGS__ ,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
#define _MAX_OF_N3(N, ...) MAX_OF_ ## N(__VA_ARGS__)
#define _MAX_OF_N2(N, ...) _MAX_OF_N3(N, __VA_ARGS__)
#define MAX_OF_N(...) _MAX_OF_N2(NUM_ARGS(__VA_ARGS__), __VA_ARGS__)
Now MAX_OF_N(a,b,c,d,e) will evaluate to max(a, max(b, max(c, max(d, e)))). (I've tested on gcc 4.2.1.)
Note that it's critical that the base case (MAX_OF_2) doesn't repeat its arguments more than once in the expansion (which is why I put max in this example). Otherwise, you'd be doubling the length of the expansion for every level, so you can imagine what will happen with 64 arguments :)
You might consider this cheating, since it is not recursive and it doesn't do the work in the preprocessor. And it uses a GCC extension. And it only works for one type. It is, however, a variadic MAX_OF_N macro:
#include <iostream>
#include <algorithm>
#define MAX_OF_N(...) ({\
int ra[] = { __VA_ARGS__ }; \
*std::max_element(&ra[0], &ra[sizeof(ra) / sizeof(int)]); \
})
int main() {
int i = 12;
std::cout << MAX_OF_N(1, 3, i, 6);
}
Oh yes, and because of the potential variable expression in the initializer list, I don't think that an equivalent of this (using its own function to avoid std::max_element) would work in C89. But I'm not sure variadic macros are in C89 either.
Here's something that I think gets around the "only one type" restriction. It's getting a bit hairy, though:
#include <iostream>
#include <algorithm>
#define MAX_OF_N(x, ...) ({\
typeof(x) ra[] = { (x), __VA_ARGS__ }; \
*std::max_element(&ra[0], &ra[sizeof(ra)/sizeof(ra[0])]); \
})
int main() {
int i = 12;
std::cout << MAX_OF_N(i + 1, 1, 3, 6, i);
}
No, because the preprocessor only takes one "swipe" at the file. There's no way to get it to recursively define macros.
The only code that I've seen do something like this was not variadic, but used default values the user had to pass:
x = MAX_OF_8 (a, b, -1, -1, -1, -1, -1, -1)
assuming all values were non-negative.
Inline functions should give you the same for C++ at least. As you state, it's probably better left to a function with variable arguments similar to printf().
I think that, even if you could expand macros recursively, there would be one little problem with your approach in terms of efficiency... when the macros are expanded, if the MAX_OF_[N-1] is greater, then you have to evaluate it again from scratch.
Here is a silly and stupid answer that probably no one will like xD
file "source.c"
#include "my_macros.h"
...
file "Makefile"
myprogram: source.c my_macros.h
gcc source.c -o myprogram
my_macros.h: make_macros.py
python make_macros.py > my_macros.h
file "make_macros.py"
def split(l):
n = len(l)
return l[:n/2], l[n/2:]
def gen_param_seq(n):
return [chr(i + ord("A")) for i in range(n)]
def make_max(a, b):
if len(a) == 1:
parta = "("+a[0]+")"
else:
parta = make_max(*split(a))
if len(b) == 1:
partb = "("+b[0]+")"
else:
partb = make_max(*split(b))
return "("+parta +">"+partb+"?"+parta+":"+partb+")"
for i in range(2, 9):
p = gen_param_seq(i)
print "#define MAX_"+str(i)+"("+", ".join(p)+") "+make_max(*split(p))
then you'll have those pretty macros defined:
#define MAX_2(A, B) ((A)>(B)?(A):(B))
#define MAX_3(A, B, C) ((A)>((B)>(C)?(B):(C))?(A):((B)>(C)?(B):(C)))
#define MAX_4(A, B, C, D) (((A)>(B)?(A):(B))>((C)>(D)?(C):(D))?((A)>(B)?(A):(B)):((C)>(D)?(C):(D)))
#define MAX_5(A, B, C, D, E) (((A)>(B)?(A):(B))>((C)>((D)>(E)?(D):(E))?(C):((D)>(E)?(D):(E)))?((A)>(B)?(A):(B)):((C)>((D)>(E)?(D):(E))?(C):((D)>(E)?(D):(E))))
#define MAX_6(A, B, C, D, E, F) (((A)>((B)>(C)?(B):(C))?(A):((B)>(C)?(B):(C)))>((D)>((E)>(F)?(E):(F))?(D):((E)>(F)?(E):(F)))?((A)>((B)>(C)?(B):(C))?(A):((B)>(C)?(B):(C))):((D)>((E)>(F)?(E):(F))?(D):((E)>(F)?(E):(F))))
#define MAX_7(A, B, C, D, E, F, G) (((A)>((B)>(C)?(B):(C))?(A):((B)>(C)?(B):(C)))>(((D)>(E)?(D):(E))>((F)>(G)?(F):(G))?((D)>(E)?(D):(E)):((F)>(G)?(F):(G)))?((A)>((B)>(C)?(B):(C))?(A):((B)>(C)?(B):(C))):(((D)>(E)?(D):(E))>((F)>(G)?(F):(G))?((D)>(E)?(D):(E)):((F)>(G)?(F):(G))))
#define MAX_8(A, B, C, D, E, F, G, H) ((((A)>(B)?(A):(B))>((C)>(D)?(C):(D))?((A)>(B)?(A):(B)):((C)>(D)?(C):(D)))>(((E)>(F)?(E):(F))>((G)>(H)?(G):(H))?((E)>(F)?(E):(F)):((G)>(H)?(G):(H)))?(((A)>(B)?(A):(B))>((C)>(D)?(C):(D))?((A)>(B)?(A):(B)):((C)>(D)?(C):(D))):(((E)>(F)?(E):(F))>((G)>(H)?(G):(H))?((E)>(F)?(E):(F)):((G)>(H)?(G):(H))))
and the best thing about it is that... it works ^_^
If you're going down this road in C++, take a look at template metaprogramming. It's not pretty, and it may not solve your exact problem, but it will handle recursion.
First, macros don't expand recusrsively. Although, macros can have reentrance by creating a macro for each recursion level and then deducing the recursion level. However, all this repetition and deducing recursion, is taken care of by the Boost.Preprocessor library. You can therefore use the higher order fold macro to calculate the max:
#define MAX_EACH(s, x, y) BOOST_PP_IF(BOOST_PP_GREATER_EQUAL(x, y), x, y)
#define MAX(...) BOOST_PP_SEQ_FOLD_LEFT(MAX_EACH, 0, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
MAX(3, 6, 8) //Outputs 8
MAX(4, 5, 9, 2) //Outputs 9
Now, this will understand literal numbers between 0-256. It wont work on C++ variables or expression, because the C preprocessor doesn't understand C++. Its just pure text replacement. But C++ provides a feature called a "function" that will work on C++ expressions, and you can use it to calculate the max value.
template<class T>
T max(T x, T y)
{
return x > y ? x : y;
}
template<class X, class... T>
auto max(X x, T ... args) -> decltype(max(x, max(args...)))
{
return max(x, max(args...));
}
Now, the code above does require a C++11 compiler. If you are using C++03, you can create multiple overloads of the function in order to simulate variadic parameters. Furthermore, we can use the preprocessor to generate this repetitive code for us(thats what it is there for). So in C++03, you can write this:
template<class T>
T max(T x, T y)
{
return x > y ? x : y;
}
#define MAX_FUNCTION(z, n, data) \
template<class T> \
T max(T x, BOOST_PP_ENUM_PARAMS(n, T x)) \
{ \
return max(x, max(BOOST_PP_ENUM_PARAMS(n, x)));\
}
BOOST_PP_REPEAT_FROM_TO(2, 64, MAX_FUNCTION, ~)
There's a nice recursion example here
The "hack" is to have a mid-step in the preprocessor to make it think that the define is not replaced by anything else at a given step.