Машина SECD - SECD machine

В Машина SECD очень влиятельный (Видеть: # Вклад Ландина ) виртуальная машина и абстрактная машина предназначен как цель для функциональный язык программирования компиляторы. Буквы означают Sприхватка Eокружающая среда Control, Dump - внутренние регистры машины. Регистры Stack, Control и Dump указывают на (некоторые реализации) стеки, а Environment указывает на (некоторую реализацию) ассоциативный массив.

Машина была первой, специально разработанной для оценки лямбда-исчисление выражения. Первоначально он был описан Питер Дж. Ландин в "Механической оценке выражений"[1] в 1964 году. Описание, опубликованное Ландином, было довольно абстрактным и оставляло множество вариантов реализации открытыми (например, операционная семантика ). Следовательно, машина SECD часто представлена ​​в более подробной форме, например Питер Хендерсон с Лиспкит Лисп компилятор, который распространяется с 1980 года. С тех пор он использовался в качестве мишени для нескольких других экспериментальных компиляторов.

В 1989 г. исследователи Университет Калгари работал над аппаратной реализацией машины.[2]

Вклад Ландина

Д. А. Тернер (2012) [3] указывает, что Пересмотренный отчет по Алгол 60 (Naur 1963) определяет вызов процедуры с помощью правила копирования, которое позволяет избежать захвата переменных с систематическим изменением идентификаторов. Этот метод работает в реализации Algol 60, но в функциональном языке программирования, где функции являются первоклассными гражданами, свободная переменная в стеке вызовов может быть разыменована по ошибке.

Тернер отмечает, что Ландин решил эту проблему с помощью своей машины SECD, в которой функция представлена закрытие вместо этого в куче.[3]

Неформальное описание

Когда начинается оценка выражения, выражение загружается как единственный элемент управления. C. Окружающая среда E, куча S и сбросить D начать пусто.

Во время оценки C он преобразован в обратная польская запись (РПН) с ap (за подать заявление ), будучи единственным оператором. Например, выражение F (G X) (один элемент списка) заменяется списком X: G: ap: F: ap.

Оценка C действует аналогично другим выражениям RPN. Если первый элемент в C это значение, оно помещается в стек S. Точнее, если элемент является идентификатором, значение, помещенное в стек, будет привязкой для этого идентификатора в текущей среде. E. Если элемент является абстракцией, закрытие построен так, чтобы сохранить привязки своих свободных переменных (которые находятся в E), и именно это закрытие помещается в стек.

Если товар ap, два значения извлекаются из стека и приложение готово (первое применяется ко второму). Если результатом приложения является значение, оно помещается в стек.

Однако, если приложение представляет собой абстракцию для значения, это приведет к выражению лямбда-исчисления, которое само может быть приложением (а не значением), и поэтому его нельзя поместить в стек. В этом случае текущее содержимое S, E, и C сброшены на свалку D (который представляет собой стопку этих троек), S повторно инициализируется пустым, а C повторно инициализируется для результата приложения с помощью E содержащий среду для свободных переменных этого выражения, дополненную привязкой, полученной из приложения. Затем оценка продолжается, как указано выше.

Завершенная оценка обозначается значком C быть пустым, и в этом случае результат будет в стеке S. Последнее сохраненное состояние оценки на D затем выталкивается, и результат завершенной оценки помещается в содержимое стека, восстановленное из D. Затем оценка восстановленного состояния продолжается, как указано выше.

Если C и D оба пусты, общая оценка завершена, результат находится в стеке S.

Регистры и память

Машина SECD на основе стека. Функции берут свои аргументы из стека. Аргументы встроенных инструкций кодируются сразу после них в потоке инструкций.

Как и все внутренние структуры данных, стек представляет собой список с S регистр, указывающий на список голова или начало. Благодаря структуре списка стек не обязательно должен быть непрерывным блоком памяти, поэтому пространство стека доступно до тех пор, пока есть одна свободная ячейка памяти. Даже когда все ячейки были использованы, вывоз мусора может дать дополнительную свободную память. Очевидно, что определенные реализации структуры SECD могут реализовать стек как каноническую структуру стека, таким образом повышая общую эффективность виртуальной машины, при условии, что размер стека будет строго ограничен.

В C точки регистрации в начале списка кода или инструкций, которые будут оцениваться. Как только инструкция там была выполнена, C указывает на следующую инструкцию в списке - она ​​похожа на указатель инструкции (или же счетчик команд ) на обычных машинах, за исключением того, что последующие инструкции всегда указываются во время выполнения и по умолчанию не содержатся в последующих ячейках памяти, как в случае с обычными машинами.

Текущее окружение переменных управляется E register, который указывает на список списков. Каждый отдельный список представляет один уровень среды: параметры текущей функции находятся в заголовке списка, переменные, которые свободны в текущей функции, но связаны с окружающей функцией, находятся в других элементах E.

Свалка, во главе которой D точки регистров используются как временное хранилище для значений других регистров, например, во время вызовов функций. Его можно сравнить со стеком возврата других машин.

Организация памяти машины SECD аналогична модели, используемой в большинстве функциональных языков. переводчики: количество ячеек памяти, каждая из которых может содержать атом (простое значение, например 13) или представляют собой пустой или непустой список. В последнем случае ячейка содержит два указателя на другие ячейки, одна из которых представляет первый элемент, а другая представляет список, за исключением первого элемента. Два указателя традиционно называются машина и CDR соответственно, но более современные термины голова и хвост вместо этого часто используются. Различные типы значений, которые может содержать ячейка, различаются тег. Часто также различают разные типы атомов (целые числа, строки и т. Д.).

Итак, список с числами 1, 2, и 3, обычно пишется как (1 2 3), можно представить в следующем виде:

Содержимое адресного тега (значение для целых чисел, автомобиль и cdr для списков) 9 [целое | 2] 8 [целое | 3] 7 [список | 8 | 0] 6 [список | 9 | 7] ... 2 [список | 1 | 6] 1 [целое | 1] 0 [ноль]

Ячейки памяти с 3 по 5 не входят в наш список, ячейки которых могут быть распределены по памяти случайным образом. Ячейка 2 является заголовком списка, она указывает на ячейку 1, которая содержит значение первого элемента, и список, содержащий только 2 и 3 (начиная с ячейки 6). Ячейка 6 указывает на ячейку, содержащую 2, и на ячейку 7, которая представляет собой список, содержащий только 3. Он делает это, указывая на ячейку 8, содержащую значение 3, и указав на пустой список (ноль) как cdr. В машине SECD ячейка 0 всегда неявно представляет пустой список, поэтому не требуется специального значения тега, чтобы сигнализировать о пустом списке (все, что нужно, может просто указывать на ячейку 0).

Принцип, согласно которому cdr в ячейке списка должен указывать на другой список, является просто соглашением. Если и car, и cdr указывают на атомы, получается пара, обычно записываемая как (1 . 2)

инструкции

  • ноль помещает нулевой указатель в стек
  • ldc помещает постоянный аргумент в стек
  • ld помещает значение переменной в стек. Переменная обозначается аргументом, парой. Автомобиль пары указывает уровень, cdr - позицию. Так (1 . 3) дает третий параметр текущей функции (уровень 1).
  • сел ожидает два аргумента списка и извлекает значение из стека. Первый список выполняется, если извлеченное значение было отличным от нуля, в противном случае - второй список. Прежде чем один из этих указателей списка будет создан, новый C, указатель на инструкцию, следующую за сохраняется на свалке.
  • присоединиться выдает ссылку на список из дампа и делает его новым значением C. Эта инструкция появляется в конце обоих вариантов сел.
  • ldf принимает один аргумент списка, представляющий функцию. Он создает замыкание (пару, содержащую функцию и текущую среду) и помещает ее в стек.
  • ap выскакивает закрытие и список значений параметров из стека. Замыкание применяется к параметрам, устанавливая его среду как текущую, помещая перед ней список параметров, очищая стек и устанавливая C на указатель функции закрытия. Предыдущие значения S, E, а следующее значение C сохраняются на свалке.
  • Ret извлекает одно возвращаемое значение из стека, восстанавливает S, E, и C из дампа и помещает возвращаемое значение в текущий стек.
  • дурак помещает «пустышку», пустой список, перед списком окружения.
  • рэп работает как , только то, что он заменяет вхождение фиктивного окружения текущим, что делает возможными рекурсивные функции

Существует ряд дополнительных инструкций для основных функций, таких как car, cdr, построение списка, сложение целых чисел, ввод-вывод и т. Д. Все они берут из стека необходимые параметры.

Смотрите также

Рекомендации

  1. ^ Ландин, П. Дж. (Январь 1964 г.). «Механическая оценка выражений». Comput. Дж. 6 (4): 308–320. Дои:10.1093 / comjnl / 6.4.308.
  2. ^ Бумага о дизайне, SECD: ПРОБЛЕМЫ ДИЗАЙНА доступен.
  3. ^ а б Д. А. Тернер «Немного истории языков функционального программирования» в приглашенной лекции. TFP12, Университет Сент-Эндрюс, 12 июня 2012 г. См. Раздел об Алголе 60.

дальнейшее чтение

внешняя ссылка