Диспетчер компилятора и его специализированные процедуры создают записи последовательностей с явными needs, modifications, statements и targets.
Вопрос для размышления
Какие решения компилятора зависят от синтаксиса исходного кода, а какие определяются запрошенным регистром target и соглашением linkage?
Классификация каждой поддерживаемой формы исходного кода перед компиляцией
Передача регистра target и linkage специализированным компиляторам
Представление последовательностей инструкций через needs, modifies и statements
Компоновка последовательностей с сохранением консервативных контрактов регистров
Генерация меток для управления ветвлением
Компиляция тела lambda в сохраненный код процедуры вместо сохранения исходного текста тела
compile отвечает только за диспетчеризацию по синтаксису. Специализированные компиляторы определяют, как самовычисляемое значение, переменная, цитирование, условное выражение, lambda, последовательность или применение попадают в target. Затем end-with-linkage добавляет отсутствие передачи управления, возврат через continue или прямой переход goto по метке. Это отделяет смысл выражения от того, куда должно попасть его значение и что должно произойти дальше.
Последовательности инструкций содержат statements вместе с консервативными наборами needs и modifies. Процедура append-sequences объединяет эти контракты с сохранением порядка. Пример с условным выражением демонстрирует метки и linkage вокруг рекурсивно скомпилированного предиката и ветвей. Компилятор lambda рекурсивно компилирует свое тело и сохраняет полученные данные инструкций в представленной скомпилированной процедуре. Этот учебный набор инструкций моделирует показанную структуру компилятора SICP с универсальной операцией apply-procedure.
Программа диспетчеризации возвращает (self variable quote if lambda begin application). Компилятор условных выражений возвращает ((env continue) (val proc argl continue) 15 (assign test branch assign assign assign assign assign assign assign goto label assign label goto) 2).
На что обратить внимание в трассе
Во второй программе отделите компиляцию предиката от сгенерированных test и branch. Затем проследите компиляцию оператора в proc, компиляцию операндов в val и argl, метку alternative, метку after-if и финальный возврат через continue. Наборы needs и modifies задают консервативные контракты обращения к регистрам.
Попробуйте сами
Измените программу и сравните результат.
Скомпилируйте форму lambda, содержащую begin и if, с регистром target proc и именованным linkage. Изучите сохраненные инструкции тела отдельно от внешней последовательности создания замыкания.
Показать подсказку
Тело lambda всегда компилируется с расчетом на val и с linkage return. Внешние target и linkage описывают выражение, создающее скомпилированную процедуру.