Як були зроблені перші компілятори?


70

Мені це завжди цікаво, і, можливо, мені потрібен гарний урок історії з мов програмування. Але оскільки в даний час більшість компіляторів створені на C, як були зроблені перші перші компілятори (AKA до C) або всі мови були просто інтерпретовані?

З урахуванням цього, я все ще не розумію, як було зроблено навіть мову першої збірки, я розумію, що таке мова збірки, але я не бачу, як вони спрацювали ДУЖЕ першу мову монтажу (наприклад, як вони зробили перший команди (як mov R21) або w / e встановлені у двійковий еквівалент?


9
Одного разу в моїй команді був комічно невмілий програміст, де все, що він робив, скаржився на C #. Ми колись жартували з вигаданої ним мови під назвою Crunk. Маловідомий факт про Crunk, це перша мова, де компілятор був ТАКОЖ написаний у Crunk. :)
maple_shaft

2
Чому хтось скаржиться на C #? він ніколи не використовував малу розмову чи Лісп? lol

2
можливий дублікат компілятора C і Dennis Ritchie
vartec

4
@maple_shaft: бути справедливим, GCC компілятор написаний на C . Це насправді не є проблемою, якщо у вас є хороший крос-компілятор для складання першої версії. Перший компілятор С, звичайно, повинен був бути написаний іншою мовою.
Скотт Вітлок

Відповіді:


89

Ха, я це зробив. У багатьох процесорах є прості інструкції з фіксованим розміром, довжиною всього пару байтів. Наприклад, для такого простого процесора, як Motorola 6800, ви можете вмістити всі його інструкції на одному аркуші паперу . Кожна інструкція матиме двобайтовий опкод, пов'язаний з нею, та аргументи. Ви можете скласти програму вручну, шукаючи код коду кожної інструкції. Потім ви пишете свою програму на папері , коментуючи кожну інструкцію відповідним кодом. Після того, як ви виписали свою програму, ви можете записати кожний опкод послідовно в EPROMякий би зберігав вашу програму. Підключіть EPROM до центрального процесора за допомогою правильних інструкцій за правильними адресами, і у вас є проста робоча програма. І щоб відповісти на ваше наступне питання, так. Було боляче (ми це робили в середній школі). Але я мушу сказати, що з'єднання кожного чіпа на 8-бітному комп’ютері та написання програми вручну дало мені глибину розуміння архітектури комп'ютера, чого я, певно, не міг досягти іншим способом.

Більш просунуті мікросхеми (наприклад, x86) набагато складніше в коді, оскільки вони часто мають інструкції змінної довжини. Процесори VLIW / EPIC на зразок Itanium близькі до неможливого ефективного кодування, оскільки вони діють в пакетах інструкцій, оптимізованих та зібраних передовими компіляторами. Для нових архітектур програми майже завжди записуються та збираються спочатку на іншому комп'ютері, а потім завантажуються в нову архітектуру. Насправді для таких фірм, як Intel, які фактично створюють процесори, вони можуть запускати фактичні програми на архітектурах, які ще не існують, запускаючи їх на тренажерах. Але я відволікаюсь ...

Що стосується компіляторів, то їх дуже просто, вони можуть бути трохи більше, ніж програми "вирізати та вставити". Ви можете написати дуже простий, неоптимізуючий, "мова високого рівня", який просто об'єднує прості інструкції з мовної збірки без особливих зусиль.

Якщо ви хочете історію компіляторів та мов програмування, пропоную вам GOTO історію FORTRAN .


27
. . . і не варто, щоб це було "... Я пропоную тобі JMP в історію ..."
Бінарний занепокоєння

2
Мені дуже дуже шкода. Але мені довелося. Я просто ... мав. до ...
Дейв Маркл

9
@Dave: Ви розумієте, що прирекли на смерть Велоцираптор ?
Бінарний страшник

7
Вони "знали", бо були буквально важко провіднані виконувати цю операцію, коли побачили сигнал 101010100 для даної інструкції. Насправді у них є чіп-блок, який відповідає за інструкції з декодування інструкцій: en.wikipedia.org/wiki/Decoder
Дейв Маркл

7
Варто додати: компілятор для нової мови, коли він написаний тією ж новою мовою, іноді компілюється з "протокомпілятором", написаним іншою мовою, який створює демонстраційно правильний, але жахливо неефективний код. Після того як це складено, він запускається на собі, щоб створити досить швидкий компілятор. Порівняйте машину Von Neumann. : D
BMDan

54

Саме про це йде завантажувальна програма компілятора (оскільки ніхто не згадав, як це називається =).

процес написання компілятора (або асемблера) на цільовій мові програмування, який він призначений для компіляції. Застосування цієї методики веде до самостійного розміщення компілятора.

Багато компіляторів для багатьох мов програмування завантажуються, включаючи компілятори для BASIC, ALGOL, C, Pascal, PL / I, Factor, Haskell, Modula-2, Oberon, OCaml, Common Lisp, Scheme, Java, Python, Scala та ін. .

Проблема з куркою та яйцями

Якщо потрібен компілятор для мови X, щоб отримати компілятор для мови X (який написаний мовою X), як записався перший компілятор? Можливі способи вирішення цієї проблеми з куркою чи яйцями включають:

  • Впроваджуючи інтерпретатора чи укладача мови X мовою, Й. Ніклаус Вірт повідомив, що він написав перший укладач Паскаля у Фортран.
  • Інший перекладач або компілятор для X вже написаний іншою мовою Y; ось як схему часто завантажують.
  • Раніші версії компілятора писалися в підмножині X, для якого існував ще якийсь компілятор; ось так завантажуються деякі набори Java, Haskell та початковий компілятор Free Pascal.
  • Компілятор для X перетинається з іншої архітектури, де існує компілятор для X; саме так компілятори для C зазвичай переносяться на інші платформи. Також це метод, який використовується для Free Pascal після початкового завантаження.
  • Написання компілятора в X; потім вручну компілюйте його з джерела (швидше за все, неоптимізованим способом) і запустіть його на код, щоб отримати оптимізований компілятор. Дональд Кнут використав це для своєї грамотної системи програмування WEB ...

Хороше посилання, яке також приведе вас до en.wikipedia.org/wiki/History_of_compiler_writing . Взагалі, я думаю, що оригінальні компілятори були написані мовою асамблеї ( en.wikipedia.org/wiki/Assembly_language ). Лише пізніше з’явилася ідея завантаження чи самохостингу.
Майкл Леві

1
+1 ОКОНЧО! Як не дивно, що це лише третя найбільш високо оцінена відповідь. Так, завантаження. Ось відповідь
Адам Ракіс

15

Зрештою, всі комп'ютери працюють на бінарних кодах, які подаються в процесор. Ці двійкові коди є абсолютно природними для процесора, але також абсолютно марні для людини. Одним із перших способів написання програми було пробивання дірок у картках. Положення отворів являло собою конкретне положення бітів всередині слова, а наявність або відсутність отвору інтерпретували як нуль або одиницю. Ці картки поміщають у потрібну послідовність у коробку, а потім подають у картридер, який фактично перетворює їх у двійковий код для центрального процесора (і ваше життя було фактично втрачено, якщо ви кинули коробку).

Очевидно, що перші програмісти один за одним опрацювали двійкові коди і мали машину для пробивання карт. Це по суті мовне мовлення програмування на ваших руках і колінах. Після цього ви можете створити з нього всі інші речі: простий текстовий редактор, компілятор мови складання (для перетворення висловлювань складання тексту у двійкові коди), посилання та завантажувач. А решта, як то кажуть, - це історія.


4
Перед картками у вас був набір комутаторів для адреси, набір для даних даних та комутатор для завантаження даних. Ви запрограмували кожну адресу пам’яті окремо, встановивши перемикачі адреси та даних за допомогою двійкового представлення та увімкнувши, а потім вимкніть перемикач навантаження. Це зайняло віки, але програма мала лише кілька слів - байти тоді не були винайдені.
uɐɪ

4
... А до цього вам довелося перемотувати його . Funfunfun!
Майкл К

Так, але коли вам довелося це зробити, ми не вважали насправді сучасним комп'ютером, як архітектура Фон Неймана ще не була придумана.
Дейв Маркл

7

Трохи гугл з'являється Початкові замовлення EDSAC з кінця 40-х. Оскільки це був перший асемблер, його, мабуть, закодували машинною мовою.

Пізніше з'явилися асемблери для інших машин, як SOAP I і II для IBM 650. SOAP I також був певно закодований машинною мовою, хоча остаточного твердження я не знайшов.

Трохи пізніше з'явився Fortran (перекладач формули) для IBM 704. Імовірно, це було написано в асемблері для 704. Ранній асемблер для 701 зараховується Натану Рочестеру .

Якщо ви хочете отримати уявлення про те, як програмувати комп’ютер машинною мовою, перегляньте один з моїх улюблених сайтів, ретрансляційний комп'ютер Гаррі Портера .


Святий дерьмо, домашній вбудований комп'ютер Гаррі Портер (майже сказав Гаррі Поттер лол) - ДУЖЕ. Я хотів би, щоб я зрозумів, як щось подібне будується :(.

1
@Sauron: Гаррі Портер не хотів би нічого кращого, ніж тобі сказати. На цій сторінці у нього прекрасно складений Powerpoint, що пояснює все це. Це передбачає деякі базові знання схеми, але це не так важко отримати.
Майк Данлаве

Я знаю, що я просто мессин ^ _ ^, незалежно від того, що це дуже вражаюча машина, і я впевнений, що багато годин майстра було вкладено в неї :).

6

Можна (якщо нудно) писати прямий машинний код. Можливо, ви записуєте програму в асемблері на аркуші паперу, а потім переводите її вручну в числові інструкції машинного коду, які ви вводите в пам'ять машини. Ви навіть можете пропустити крок асемблера на папері, якщо ви запам'ятали числові значення всіх інструкцій машинного коду - не рідкість у ті дні, вірите чи ні!

Найперші комп’ютери безпосередньо програмувались у двійковій формі шляхом перемикання фізичних комутаторів. Це було великим покращенням продуктивності, коли еволюціонувало обладнання, яке дозволяло програмісту (або помічнику введення даних) вводити код у шістнадцяткових цифрах за допомогою клавіатури!

Асемблер програмного забезпечення став актуальним лише тоді, коли стало доступно більше пам’яті (оскільки код асемблера займає більше місця, ніж сировинний код машини) та обладнання, що розвивалося, щоб дозволити буквено-цифровий ввід. Тож перші асемблери були написані безпосередньо людьми, які добре володіють машинним кодом.

Коли у вас є асемблер, ви можете написати компілятор для мови вищого рівня в асемблері.

Історія для C має кілька кроків. Перший компілятор C був написаний на B (попередник C), який, у свою чергу, був написаний у BCPL. BCPL є досить простою мовою (наприклад, вона взагалі не має типів), але все-таки є кроком від сировинного асемблера. Отже, ви бачите, як поступово складніші мови будуються на більш простих мовах аж до асемблера. А сам C - це досить мала і проста мова за сучасними мірками.

Сьогодні перший компілятор для нової мови часто пишеться на С, але коли мова досягає певної зрілості, вона часто переписується "сама по собі". Перший компілятор Java був написаний на C, але пізніше переписаний на Java. Перший компілятор C # був написаний на C ++, але останнім часом він був переписаний на C #. Компілятор / інтерпретатор Python написаний на C, але проект PyPy - це спроба переписати його в Python.

Не завжди можливо скласти компілятор / перекладач для мови на самій мові. Інтерпретатор JavaScript, написаний на JavaScript, існує, але компілятори / інтерпретатори в поточних браузерах все ще записуються на C або C ++ з міркувань продуктивності. JavaScript, написаний на JavaScript, занадто повільний.

Але вам не потрібно використовувати C як "початкову мову" для компілятора. Перший компілятор F # був написаний в OCaml, що є іншою мовою, найбільш тісно пов'язаною з F #. Коли компілятор завершився, він був переписаний у F #. Перший компілятор для Perl 6 був написаний на Haskell (чиста функціональна мова, сильно відрізняється від Perl), але зараз компілятор написаний на C.

Цікавий випадок «Руст», де перший компілятор був написаний в OCaml (зараз він переписаний у «Rust»). Це помітно, оскільки OCaml, як правило, вважається вищим рівнем, ніж Rust, що є мовою систем, наближених до металу. Тож це не завжди мови вищого рівня, реалізовані в мовах нижчого рівня, це може бути і навпаки.


3

Якщо припустити, що ви починаєте з чистого набору інструкцій і нічого іншого, ви почнете, створивши мінімальний , ледве функціональний асемблер або компілятор, який може завантажувати файл, аналізувати мінімальний підмножина цільової мови та генерувати виконуваний файл файл як вихід, написавши сировинний код за допомогою шестигранного редактора або подібного.

Потім ви використовуєте цей ледве функціональний компілятор або асемблер, щоб реалізувати трохи більш здатний компілятор або асемблер, який може розпізнати більшу підмножину цільової мови. Помийте, промийте, повторіть, поки не будете мати готовий продукт.


2

Це не так складно, як здається. У дитинстві;) Я зробив на увазі кілька розбирань x86.

Вам навіть цього особливо не потрібно вчити. Це просто відбувається, коли ви можете програмувати в ASM, а потім намагаєтеся виправити сторонні двійкові файли за допомогою інтерактивних розбиральників. Або при написанні власного захисту із шифруванням коду.

Тобто іноді ти не дивно переходиш навіть з мови на коди.


1

Перші компілятори були реалізовані за допомогою мови складання. І перші асемблери були реалізовані програмами кодування у двійковій ...


Адже НЕ ТАКЕ давно програмування у бінарному творі все ще було вмінням, яким користувалися люди.

Коли я був студентом, я пам'ятаю, як робив вправу програмування, яке тягнуло за собою написання крихітної програми в машинному коді PDP-8 (я думаю), введення її через перемикачі на передній панелі та запуск її. Через пару років я придбав собі набір для розробки системи 6502, який мав шістнадцяткову клавіатуру для введення програм ... і 4 К байт оперативної пам'яті.


-3

ДУЖЕ ПРОСТИЙ ВІДПОВІДЬ Припустімо, що ми пишемо програму з жорсткої провідності і зберігаємо її в ПЗУ. Його можна розглядати як компілятор. Тому я просто хочу сказати, що перший компілятор був провідним. У міру вдосконалення технології ці прості компілятори потім використовувались для написання компіляторів високого рівня.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.