Как язык может быть интерпретирован отдельно (как Rubinius)?

Я программировал в Ruby некоторое время теперь только с стандартной реализацией МРТ Ruby, но мне всегда было любопытно на предмет других реализаций, о которых я слышу так много.

Я читал о Rubinius на днях, интерпретатор Ruby, записанный в Ruby. Я пытался искать его в различных местах, но мне было нелегко выяснять точно, как что-то вроде этого работает. У меня никогда не было большого опыта в компиляторах или записи языка, но мне действительно интересно понимать это.

Как точно язык может быть интерпретирован отдельно? Существует ли основной шаг в компиляции этого, я не понимаю, где это имеет смысл? Может кто-то объяснять это мне как, я - идиот (потому что это не было бы слишком далекой основой так или иначе),

5
задан joeellis 30 May 2010 в 06:01
поделиться

5 ответов

Это проще, чем вы думаете.

Rubinius не на 100% написан на Ruby, а только в основном.

От http://rubini.us/

Важным аспектом популярных языков, таких как C и Java, является то, что большая часть функциональности, доступной программисту, написана в самом языке. Цель Rubinius - добавить Ruby в этот список. Рубинисты могли бы легче добавлять функции в язык, исправлять ошибки и изучать, как работает язык. Там, где это возможно, Rubinius написан на Ruby. Там, где это невозможно (пока), это C++.

8
ответ дан 18 December 2019 в 11:54
поделиться

В случае Rubinius, VM написана на C++ и занимается всеми низкоуровневыми (связанными с операционной системой) вещами и базовыми операциями. ВМ имеет свой собственный формат байткода (как и JVM имеет свой собственный формат), и при запуске Rubinius запускается ВМ, которая исполняет байткод. Большая часть стандартной библиотеки Rubinius (которая является частью языка Ruby) реализована в Ruby, однако, по сравнению с C (MRI) или Java (JRuby). Кроме того, компилятор байткода Rubinius также написан на Ruby. Так что да, в какой-то момент в самом начале им пришлось использовать стандартный интерпретатор Ruby (MRI) для загрузки Rubinius. Но теперь этого не должно быть (хотя я не уверен, что он все еще может вам понадобиться, поскольку его build-система использует rake).

2
ответ дан 18 December 2019 в 11:54
поделиться

Предположим, что язык, с которым вы работаете, - это некоторый язык, скажем, Lisp, хотя это не имеет значения. (Это может быть C++, Java, Ruby, что угодно.)

Итак, у вас есть реализация Lisp. Назовем эту реализацию Imp (просто придуманное название, сокращенное от IMPlementation). Поскольку Imp - это программа сама по себе, ваш компьютер может ее запустить. Теперь вы пишете свою собственную реализацию для Lisp, написанную на Lisp, и называете ее Circ. Circ - это просто программа, скомпилированная (или интерпретированная, если хотите) из кода Лиспа. Ваш код написан так, что он читает файл, разбирает его (обрабатывает в осмысленные данные) и что-то делает с этими данными. Что это за действие? В случае с Circ, он выполняет данные.

Но как он это делает?

Для простоты предположим, что код, который считывает и разбирает Circ, представляет собой нечто простое, например, выполнение математических операций и вывод результата. Circ обрабатывает код в простые для использования данные (ну, для такого языка, как Lisp, они просты для начала, но это не суть важно) и сохраняет их. В Lisp вы можете написать код для обработки чисел, так что код, написанный для Circ, тоже может это делать, потому что он написан на Lisp. Итак, обработанные данные вставляются в код обработки сложения... и вуаля! У вас есть числовой результат! Затем ваша программа Circ выводит результат.

То же самое можно сделать и с более сложными вещами, чем простая математика. На самом деле вы можете компилировать/интерпретировать другие аспекты языка. Если написать достаточное количество таких "других аспектов" и склеить их вместе, то получится компилятор для Лиспа, написанный на Лиспе.

Поскольку компилятор скомпилирован Imp, он может быть запущен вашей машиной, и престо! Все готово.

1
ответ дан 18 December 2019 в 11:54
поделиться

Эта техника обычно называется метациркулярным оценщиком и впервые была представлена несколько десятилетий назад в контексте Lisp.

Хорошее описание этой техники можно найти в Структура и интерпретация компьютерных программ, глава 4.

0
ответ дан 18 December 2019 в 11:54
поделиться

Вам нужна концепция начальной загрузки компилятора .

В основном самонастройка означает написание компилятора (или интерпретатора) для языка x на языке x . Это делается либо путем написания базового компилятора на более низком уровне вручную (т.е. написания компилятора C на ассемблере), либо с использованием другого языка высокого уровня.

Подробнее о начальной загрузке читайте в википедии . Также настоятельно рекомендуется ответить Грега относительно мета-циркулярных оценщиков, включая соответствующую главу в SICP.

4
ответ дан 18 December 2019 в 11:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: