Первые версии компилятора Си для «больших машин» писались в машинных кодах. Почитай историю.
Страуструп вроде бы это описывает в «Эволюции языка Си++» (есть перевод на русский).
Как в последнем сезоне Lexx: «Я научу вас строить большие машины, которые будут строить машины поменьше, которые будут строить маленькие машины, которые будут строить совсем крошечные машины, а уж они будут собирать космический корабль.»
А вот как работают интерпретаторы? Вот есть Python, его интерпретатор написан, допустим, на Java, её интерпретатор (допустим!!! я не говорю, что оно так на самом деле!) - на C, а интерпретатор C? На ассемблере?
На асме/в кодах пишется минимальное нечто, позволяющее компилить хоть что-то. На нём уже пишется недокомпилятор, но уже менее недо. Через несколько итераций получаем нормальный.
Реально на асме писать смысла немного, можно начальный недокомпилер на любой платформе и любом ЯП написать.
встречал упоминания и краткие описания нескольких С-интерпретаторов
Я больше скажу - я в генте поддерживаю один такой пакетик :-) app-shells/ccsh, если кому интересно. Версия 0.0.4 кагбе намекает на его допиленность :-)