Искусство программирования для Unix
Шрифт:
Исторически PostScript-интерпретация на основе стеков имеет сходство с языком FORTH, который первоначально предназначался для управления приводами телескопов в реальном времени и имел кратковременную популярность в 80-х годах прошлого века. Языки обработки стеков отличаются превосходной поддержкой чрезвычайно плотного, экономичного кода и печально известны тем, что их трудно читать. Для PostScript характерны обе эти особенности.
PostScript часто реализуется в виде встроенного в принтер программного обеспечения. Ghostscript, реализация PostScript с открытым исходным кодом транслирует PostScript в различные графические форматы и (более слабые) языки управления принтерами. Большая часть
PostScript (в оригинальном или упрощенном варианте EPSF с объявленным вокруг него обрамлением, позволяющим встраивать его в другие графические форматы) является очень хорошо спроектированным примером специализированного языка управления и, как модель, заслуживает внимательного изучения. Он является компонентом других стандартов, например, PDF (Portable Document Format — формат для переносимых документов).
8.2.10. Учебный пример: утилиты bc и dc
Впервые утилиты bс(1) и dc(1) рассматривались в главе 7 как учебный пример вызова с созданием подоболочки. Они также являются примерами узкоспециальных мини-языков императивного типа.
dc — старейший язык в Unix. Он был создан на компьютере PDP-7 и перенесен на PDP-11 еще до того, как была перенесена (сама) Unix.
Кен Томпсон
Предметной областью данных языков являются арифметические вычисления неограниченной точности. Другие программы могут использовать их для выполнения таких вычислений, "не заботясь" о необходимых для этого специальных методиках.
Фактически первоначальная мотивация для создания dc не была связана с разработкой универсального интерактивного калькулятора, для которого было бы достаточно простой программы, поддерживающей вычисления с плавающей точкой. Мотивирующим фактором была давняя заинтересованность Bell Labs в численном анализе: точному вычислению констант для численных алгоритмов весьма способствует возможность работать с более высокой точностью, чем та, которую использует сам алгоритм. Отсюда и арифметика с неограниченной точностью в dc.
Генри Спенсер.
Как и в случае SNG- и Glade-разметки одним из преимуществ обоих языков является их простота. Однажды узнав о том, что dc(1)— калькулятор с обратной польской записью, а Ьс(1) — калькулятор с алгебраической записью, пользователь найдет новыми очень немногие сведения об интерактивном использовании любого из двух языков. Важность правила наименьшей неожиданности в интерфейсах повторно рассматривается в главе 11.
В обоих мини-языках имеются условные операции и циклы; они являются языками Тьюринга, но имеют очень ограниченную онтологию типов, включающую только целые числа неограниченной точности и строки, что ставит их между интерпретируемыми мини-языками и полными языками сценариев. Функции программирования реализованы так, чтобы не нарушать обычное использование программы в качестве калькулятора; в действительности, большинство пользователей dc/bc, вероятно, не подозревают о существовании этих функций.
Обычно программы dc/bc используются в диалоговом режиме, но их способность поддерживать
Поскольку интерфейс программ dc/bc прост (передается строка, содержащая выражение, в ответ на которую возвращается строка, содержащая значение), другие программы и сценарии могут легко получит доступ ко всем этим возможностям, вызывая dc/bc как подчиненные процессы. Ниже приводится один известный пример (см. пример 8.6), реализация шифра с открытым ключом Ривеста-Шамира-Адельмана (Rivest-Shamir-Adelman) на Perl, которая широко публиковалась в подписях почтовых сообщений и на футболках как протест против введенного в США в 1995 году ограничения на экспорт криптографических средств. Данный сценарий для выполнения необходимых арифметических расчетов с неограниченной точностью вызывает dc с созданием подоболочки.
Пример 8.6. RSA-реализация с помощью утилиты dc
print pack"C*",split/\D+/,"echo "16iII*o\U®{$/=$z;[(pop,pop,unpack "H*", o) ] }\EsMsKsN0 [lN*llK[d2%Sa2/d0<X+d*lMLa A *lN%0]dsXx++\ lMlN/dsMO<J]dsJxp"|dc'
8.2.11. Учебный пример: Emacs Lisp
Вместо того чтобы просто запускать интерпретируемый язык специального назначения в качестве подчиненного процесса для решения специфических задач, его можно использовать как основу для всей структуры. Преимущества и недостатки данного подхода рассматриваются в главе 13. Запросы troff были его ранним примером. Одним из самых известных и наиболее мощных современных примеров является редактор Emacs. Он создан на основе диалекта языка Lisp с примитивами как для описания действий в буферах редактирования, так и управления подчиненными процессами.
Тот факт, что Emacs построен вокруг мощного языка для описания редактирующих действий или клиентской части для других программ, означает, что он, кроме обычного редактирования, может применяться для многих других целей. Применение развитой, специализированной логики Emacs для повседневной разработки программ (компиляции, отладки, контроля версий) рассматривается в главе 15. "Режимы" Emacs представляют собой пользовательские библиотеки, т.е. программы, написанные на Emacs Lisp, которые приспосабливают редактор для решения специфической задачи, обычно (но не обязательно) связанной с редактированием.
Таким образом, существуют специализированные режимы, которые распознают синтаксис большого числа языков программирования и разметки, таких как SGML, XML и HTML. Однако многие пользователи также используют Emacs-режимы для отправки и получения электронной почты (в таких режимах в качестве подчиненных процессов используются почтовые утилиты Unix) или новостей Usenet. Emacs может служить в качестве Web-браузера или клиентской части для различных программ интерактивного общения. Существует также пакет для составления расписаний, собственная программа-калькулятор для Emacs и даже весьма широкий выбор игр, написанных как режимы Emacs Lisp.