Коротка відповідь: ви маєте рацію в своїх підозрах, вам завжди потрібен або інший перекладач, написаний на X, або компілятор з Y на якусь іншу мову, для якої у вас уже є перекладач. Інтерпретатори виконують, компілятори перекладають лише з однієї мови на іншу, в якийсь момент у вашій системі повинен бути перекладач… навіть це лише CPU.
Незалежно від того, скільки нових перекладачів ви пишете мовою Y , вам завжди доведеться використовувати перший перекладач, написаний на X, для тлумачення наступних перекладачів. Це, здається, є проблемою просто через природу перекладачів.
Правильно. Що ви можете зробити, це написати компілятор від Y до X (або іншу мову , для якого у вас є перекладач), і ви навіть можете зробити це в Y . Тоді ви можете запустити ваш компілятор Y, написаний на Y, на Y- інтерпретаторі, написаному X (або на Y- інтерпретаторі, написаному на Y, на Y- інтерпретаторі, написаному на X , або на Y- інтерпретаторі, написаному на Y, на Y- інтерпретаторі, написаному на Y працює на Y інтерпретатора, написаний X , або… ad infinitum), щоб скласти свій Y- інтерпретатор, написаний від Y до X , щоб потім можна було виконати його на X- інтерпретаторі. Таким чином, ви позбулися свого інтерпретатора Y, написаного на X , але тепер вам потрібен перекладач X (ми знаємо, що у нас його вже є, хоча в іншому випадку ми не змогли запустити перекладача X, написаного Y ), і ви довелося спочатку написати Y- to- X- компілятор .
Однак , на зворотній стороні, стаття Вікіпедії про перекладачів насправді розповідає про перекладачів, що займаються власною організацією. Ось невеликий уривок, який є релевантним:
Самоперекладач - це перекладач мови програмування, написаний мовою програмування, який може інтерпретувати себе; приклад - перекладач BASIC, написаний на BASIC. Самоперекладачі пов’язані з самостійними організаторами хостингу.
Якщо немає компілятора для інтерпретації мови, для створення самоперекладача потрібна реалізація мови на мові хоста (яка може бути іншою мовою програмування або асемблером). Маючи першого перекладача, такого як цей, система завантажується і нові версії інтерпретатора можуть бути розроблені на самій мові
Мені все ще не зрозуміло, як саме це було б зроблено. Здається, що незалежно від цього, ви завжди будете змушені використовувати першу версію свого перекладача, написану мовою хосту.
Правильно. Зауважте, що у статті Вікіпедії прямо написано, що вам потрібна друга реалізація вашої мови, і вона не говорить про те, що ви можете позбутися першої.
Тепер згадана вище стаття посилається на іншу статтю, в якій Вікіпедія наводить кілька прикладів передбачуваних перекладачів, що розміщуються на власному хостингу. При більш детальному огляді, здається, що основна "інтерпретація" частини багатьох тих перекладачів, що займаються самоврядуванням (особливо деякі більш поширені, такі як PyPy або Rubinius), насправді написана іншими мовами, такими як C ++ або C.
Знову правильно. Це справді погані приклади. Візьмемо, наприклад, Рубіній. Так, це правда, що частина Rubyus у Rubinius розміщена самостійно, але це компілятор, а не інтерпретатор: він компілює у вихідний код Ruby до байт-коду Rubinius. Частина інтерпретатора OTOH не є власною організацією: вона інтерпретує байт-код Рубінія, але він написаний на C ++. Так, називаючи Rubinius «резидентних перекладач» є неправильним: резидентних частина не є перекладачем , а перекладач частина не резидентних .
PyPy схожий, але ще більш невірний: він навіть не написаний в Python в першу чергу, він написаний на RPython, що є іншою мовою. Він синтаксично схожий на Python, семантично "розширений підмножина", але він насправді є мовою статичного типу приблизно на тому ж рівні абстракції, що і Java, і його реалізація є компілятором з декількома зворотними пакетами, який компілює RPython у вихідний код C, ECMAScript вихідний код, байт-код CIL, байт-код JVM або вихідний код Python.
То чи можливо те, що я описую вище? Чи може самостійний перекладач-хост бути незалежним від свого початкового хоста? Якщо так, то як би це було зроблено?
Ні, не самостійно. Вам або потрібно буде зберегти оригінального перекладача або написати компілятор і скласти свій самоперекладач.
Там є деякі мета-кругової віртуальні машини, такі як Кляйн (написано в Самості ) і Максін (написаний на Java). Однак зауважте, що тут визначення "мета-кругової" все ж відрізняється: ці VM не написані мовою, яку вони виконують. Однак вихідний код Self / Java VM фактично компілюється в байт-код Self / JVM і потім виконується ВМ, тому до моменту його виконання він знаходиться на мові, яку він виконує. Phew.
Зауважте також, що це відрізняється від таких віртуальних машин, як SqueakVM та RVM Jikes . Jikes написаний на Java, а SqueakVM написаний на сленгу (статично набраний синтаксичний і семантичний підмножина Smalltalk приблизно на тому ж рівні абстракції, що і асемблер високого рівня), і обидва отримують статичний збір до нативного коду до їх запуску. Вони не бігають всередину себе. Однак ви можете запускати їх зверху (або поверх іншого Smalltalk VM / JVM). Але це не є "мета-круговим" у цьому сенсі.
Максін і Клейн, OTOH робитибігати всередину себе; вони виконують свій власний байт-код, використовуючи власну реалізацію. Це справді розум! Це дозволяє отримати декілька цікавих можливостей оптимізації, наприклад, оскільки VM виконує себе разом із користувацькою програмою, він може вбудовувати дзвінки з користувацької програми в VM і навпаки, наприклад, дзвінок до сміттєзбірника або розподільник пам'яті може бути вбудований у користувача код і відбивні зворотні дзвінки в коді користувача можуть бути вписані в VM. Крім того, усі розумні прийоми оптимізації, які роблять сучасні віртуальні машини, де вони переглядають програму, що виконує, та оптимізують її залежно від фактичного навантаження та даних, VM може застосувати ті самі хитрощі до себе під час виконання користувацької програми під час користувацької програми виконується конкретне навантаження. Іншими словами, VM вузькоспеціалізованих себе за щоконкретна програма, що працює на цьому робочому навантаженні.
Однак, зауважте, я обійшов вживання слова "перекладач" вище і завжди використовував "виконувати"? Ну, ці віртуальні віртуальні машини не побудовані навколо інтерпретаторів, вони побудовані навколо (JIT) компіляторів. Пізніше до Maxine був доданий перекладач, але вам завжди потрібен компілятор: вам потрібно запустити VM один раз над іншим VM (наприклад, Oracle HotSpot у випадку Maxine), щоб VM міг (JIT) компілювати себе. У випадку з Maxine він буде JIT компілювати власну фазу завантаження, потім серіалізувати цей скомпільований нативний код до зображення VM завантажувальної машини та наклеїти дуже простий завантажувач спереду (єдиний компонент VM, написаний на C, хоча це просто для зручності , це може бути і на Java). Тепер ви можете використовувати Maxine для виконання себе.