But this doesn’t really explain anything: ‘\010’ isn’t really any more primitive than ‘\x0a’: they’re just different representations of the same bit sequence
But it is more primitive than '\n', and can be rendered into binary without any further arbitrary conversion steps (arbitrary in that there's nothing in '\n' that says it should mean 10). It's just "transform the number after the backslash into the byte with that value".
Yeah, but what maps the characters 1 and 0 to the numerical value 10? I bet it’s the same chain of compilation, at some point leading to an assembly compiler, and that itself leading to some proto binary implementation, maybe even going into bios/hardware implementation?
The logic can be implemented entirely in a parser written in a high level language. For example,
//const int ZERO = '0';
const int ZERO = 0x30;
int convert(const char *s){
int ret = 0;
for (; *s; s++){
ret *= 10;
ret += *s - ZERO;
}
return ret;
}
After that you just dump the value to the output verbatim. Any high level language can handle this, it's just a change of representation like any other. There's no need to do any further delegation.
Replying to myself because I can't edit the comment anymore. I think I see what you mean now. The parser for the language that compiles your parser also needs to know that "10" means 10, and that "0x30" means 48. I guess that also is knowledge that is passed down through compiler generations. I wonder if you could write a simple parser that doesn't contain a single numerical constant.