On 2025-04-22, bart <
bc@freeuk.com> wrote:
BTW here is that macro definition from Lua:
>
#define op_arith(L,iop,fop) { \
TValue *v1 = vRB(i); \
TValue *v2 = vRC(i); \
op_arith_aux(L, v1, v2, iop, fop); }
I'm assuming that op_arith is called numerous times to define handling
for various VM opcodes.
It *reliably* writes a bunch of code that would otherwise require a lot
of error-prone copy and paste.
This is language extension; the LUA maintainers have written
themselves an op_arith language feature.
The generated codee is large and complex, but at least you can see it.
If that language feature were wired into the compiler, it would only
be harder to work with. All that morass of code would be hidden
inside, generated into some intermediate representation (that you
can perhaps intercept and get in some readable form, in a
language/notation you will have to learn).
It calls yet more macros, and those in turn call others; here are a few
for vRB:
>
#define vRB(i) s2v(RB(i))
#define s2v(o) (&(o)->val)
#define RB(i) (base+GETARG_B(i))
#define GETARG_A(i) getarg(i, POS_A, SIZE_A)
#define getarg(i,pos,size) (cast_int(((i)>>(pos)) & MASK1(size,0)))
#define cast_int(i) cast(int, (i))
#define MASK1(n,p) ((~((~(Instruction)0)<<(n)))<<(p))
#define cast(t, exp) ((t)(exp))
Some of these look like low value. For instance cast_int(x) saves no
characters over cast(int,x), and ony one character over cast(int, x),
and that is longer than just (int)(x), not to mention (int)x
situations where you can omit parentheses.
I've only defined cast macros for the purpose of switching between
C casts and C++ casts. If that's not going on here, it's just
gratuitous macrology.
The switching I'm talking about is this:
#ifdef __cplusplus
#define strip_qual(TYPE, EXPR) (const_cast<TYPE>(EXPR))
#define convert(TYPE, EXPR) (static_cast<TYPE>(EXPR))
#define coerce(TYPE, EXPR) (reinterpret_cast<TYPE>(EXPR))
#else
#define strip_qual(TYPE, EXPR) ((TYPE) (EXPR))
#define convert(TYPE, EXPR) ((TYPE) (EXPR))
#define coerce(TYPE, EXPR) ((TYPE) (EXPR))
#endif
The purpose is to gain access to the finer-grained C++ casts when
the code is compiled as C++, but fall back on the C casts when it
is compiled as C. These macros *do* something, so they are needed.
I don't want to have #ifdef __cplusplus all over the place and write
the same expressions twice with different casts.
So what language would say this program is written in?
Obviously C. C has preprocessing and so, the above is what C sometimes
looks like.
It's obviously not written in the C-without-preprocessing subset of C.
I would expect that Lua has more than one artithemetic
operation, so sharing code saves coding effort (actually, most
of tag mainipulations probably can be shared by all Lua instructions).
>
Any reason to uses *seven* levels of macro invocation? That is all in
one branch.
It allows the code to be built up in small chunks that are easy
to understand (when looking at the macro definitions).
If all else is equal, such as the sizes of the code mountains, one layer
of macro to generate the mountain of code is almost always going to be
objectively worse than a macro defined in several hierarchical levels
that offer some meaningful "chunking" to someone reading the code.
The definition will likely be more condensed, due to certain lower level
macros are used more than once in the higher level ones.
Do you think that's too many? Perhaps only 3 levels would have sufficed.
Low-value macros that only add levels of expansion without payoff should
be avoided. If there are 7 levels, but 4 of them are some low-value
syntactic sugar, a case can be made for reducing.
If we go by the chunking concept in cognitive psychology, that people
do well with an abstraction layer that has about 7 chunks of content,
in 7 layers of 7 chunks, we get a hierarchy with 800,000 items at the
leaf level, which is an improbable morass.
In 7 layers of macros, some of the layers are going to have low
branching factors, just providing some minor notations, sometimes
of little value.
Or would you automatically say it was reasonable no matter how many
levels there were, just to disagee with me and to side with a fellow C
programmer?
You're trying to say that C is a bad language because you can have
7 or more layers of macro expansion, but you're not considering how
bizarre and crippling restriction it would be to put a cap on it.
-- TXR Programming Language: http://nongnu.org/txrCygnal: Cygwin Native Application Library: http://kylheku.com/cygnalMastodon: @Kazinator@mstdn.ca