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.
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.
Exactly how we did it too. We created the editor/assembler that peeked to see what was there and display it in Assembly, Hexadecimal, and ASCII.
You could edit whichever version you wanted and it would Poke it into RAM.
You could also save swaths to a file.
True, it was computer science.
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
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.