There’s actually good reasons for this design. It’s easy to write a Scheme interpreter, but it’s hard to write a C compiler that handles everything correctly. Much rather write it in higher level language if possible and Scheme lowers the bar to getting there.
Then you can write your C compiler in C and close the loop. For your final step, you use the C compiler to compile itself.
Assembly code is for writing C compilers, and C compilers are for writing Lisp interpreters.
Only the most very basic compilers. C compilers are in C mainly.
Not the first C compiler obviously. According to this Stack Overflow post, BCPL* begat B, which begat C. Language self-hosting is pretty fascinating.
*Perhaps BCPL was originally written in assembly; I’m not certain: https://github.com/SergeGris/BCPL-compiler
And that’s how you get the Thompson hack
Talking about bootstrap here?
Indeed
Back in High School in the 80’s me and a buddy wrote a Z-80 editor assembler in TRS-DOS BASIC.
It was not rocket science.
I never did get very far with the TRS-80 Editor Assembler, but that was my first exposure to such things.
I also remember the BASIC code for the Dancing Daemon which was replete with PEEKs and POKEs, such that much of it was written in machine code.
I saw a Scheme interpreter written in assembly running a C compiler written in Scheme.
There’s actually good reasons for this design. It’s easy to write a Scheme interpreter, but it’s hard to write a C compiler that handles everything correctly. Much rather write it in higher level language if possible and Scheme lowers the bar to getting there.
Then you can write your C compiler in C and close the loop. For your final step, you use the C compiler to compile itself.