Go, Rust, Zig?
I'm curious, what language do you know of with a more complex macro system than the whole C preprocessor?
EDIT: To be clear to prospective downvoters, I'm not just throwing these languages out because they're hype or whatever. They all have a grammar that's much simpler to parse. Notably, you can construct a parse tree without a semantic analyser which is capable of running in lockstep with the parser to provide semantic information to the parser. You can just write a parser which makes a parse tree.
I've never written a parser for any of those languages but my intuition is that Go is easier to parse than C. The others are debatable. Rust macros are definitely not simpler than C macros. I'm not sure what could be simpler than text substition. Zig doesn't have macros and comptime is implemented as a language VM that runs as a compilation step(last I knew), so that's definitely not simpler. I don't use go often, but I don't think it has macros at all so that's definitely simpler.
When people say that C is a simple language, my interpretation is that they mean it is easy to interpret what a C program does at a low level, not that it is simple to write.
The other languages can be written by a parser. A parser for C needs a semantic analyzer working in tandem.
The C preprocessor is not text substitution.
It is not easy to describe what C does at a low level. There are simple, easy to describe and wrong models of what C does "at a low level". C's semantics are defined by a very difficult to understand standards document, and if you use one of those simple and enticing mental models, you will end up with incorrect C code which works until you try a different compiler or enable optimisations.
A parser for C does not need a semantic analyzer. What C does it allows semantic analysis to be integrated into the parser.
The preprocessor has some weird behavior, it it is also not very complicated.
And I would argue that the abstract machine model of C is still relatively simple. There are are certainly simpler languages in this regard, but they give up one of the key powers of C, i.e. that you can manipulate the representation of objects on a byte level.
By that argument the other languages mentioned are impossible to understand since they don't have a spec, except for Go again.
No. The other languages have documented semantics too. Just happens that C's are in the shape of a standards document.