sicp.io
5.5.2 · Компиляция выражений

Компиляция форм исходного кода в теги инструкций

Значения, переменные, цитирование, присваивание, определения, условные выражения, лямбды и применения компилируются в язык инструкций.

Вопрос для размышления

Какие решения исходного языка исчезают из цикла выполнения после компиляции?

  • Компиляция каждой базовой категории выражений в явные данные инструкций
  • Сохранение порядка вычисления оператора и операндов слева направо при вызовах
  • Представление скомпилированных замыканий через параметры, код и лексическое окружение
  • Изменение определений и присваиваний через явные операции над окружением
  • Выбор одной скомпилированной ветви без повторного обращения к синтаксису исходного кода
  • Выполнение скомпилированного кода на отдельной стековой машине

compile-expression выполняет всю классификацию исходного кода. Результат содержит только инструкции literal, load, closure, define, set, discard, branch и call. Форма lambda сохраняет уже скомпилированный код тела со своими параметрами. Форма begin вставляет discard между нефинальными формами, а применение помещает код оператора перед кодом операндов перед единственной инструкцией call.

run-code выполняет диспетчеризацию по тегам скомпилированных инструкций после того, как compile-expression классифицирует формы исходного кода. Скомпилированная процедура расширяет лексическое окружение, захваченное при создании замыкания, и выполняет код своего тела на чистом стеке операндов. Эта учебная VM выполняет глобальные определения, захваченные локальные присваивания, цитирование, ветвление, замыкания и применение примитивов с помощью указанного набора инструкций.

Код SICP10,895 из 1,048,576 байт UTF-8
Примеры
Результат
Вывод
Значение
Диагностика
Трасса выполнения0 / 0 событий
    Запуски происходят внутри браузера с отображением результата программы и трассы выполнения.
    Ожидаемый результат

    Первая скомпилированная программа возвращает ((18 large 15) (literal define discard closure define discard load literal call define discard load load literal call set discard load load literal call branch) 22). Замыкание с состоянием возвращает ((12 15 5 ok) (literal define discard closure define discard load literal call define discard load load literal call load literal call load literal call) 21).

    На что обратить внимание в трассе

    Сначала проверьте теги кода и убедитесь, что в них не осталось тегов форм исходного кода. Во время выполнения проследите создание замыкания до вызова make-adder или make-counter, новый кадр вызова для каждого скомпилированного применения, изменение захваченной записи start между вызовами counter и выбор ровно одного вложенного списка кода в branch.

    Попробуйте сами

    Измените программу и сравните результат.

    Добавьте рекурсивную скомпилированную процедуру или второе вложенное замыкание. Спрогнозируйте теги кода верхнего уровня, затем определите, в каком окружении процедуры каждая инструкция load и set должна выполнять поиск.

    Показать подсказку

    Определение помещает скомпилированное замыкание в общий глобальный кадр после того, как замыкание захватило этот объект кадра, поэтому последующий рекурсивный поиск сможет найти установленное имя.

    Завершить этот урок

    В этой главе пройдено 0 из 23 урока0%