3.3 Обзор языка программирования FORTH
==46
3.3.1 Язык FORTH, как основа мироздания
В связи с тем, что большинство современных стековых машин берут своё начало в языке программирования FORTH, далее следует введение в основы языка.
Язык программирования FORTH был придуман Чарльзом Муром ( Charles Moore ) для управления телескопом с помощью мини-компьютера ( Moore 1980 ). По этим причинам FORTH делает акцент на производительности, лаконичности, универсальности и эффективности в части программно-аппаратного взаимодействия. В то же время он обладает достаточной мощностью, позволяющей использовать его для решения весьма широкого круга программных задач: работа с базами данных, бухгалтерские программы, издательские, графические и экспертные системы, а также научные вычисления. В Приложении _B приведён словарь примитивных операций языка FORTH.
Дополнительными преимуществами программирования на языке FORTH является простота модификации и отладки программ, невероятная гибкость и очень быстрый цикл редактирование-компиляция-тестирование, высокая степень переносимости на разнообразные вычислительные архитектуры, краткость исходных текстов и компактность исполняемого кода ( Jonak 1986 ). Kogge ( 1982 ) описывает многопоточную программную среду с упором на низкоуровневые механизмы работы языка.
3.3.2 Виртуальная FORTH-машина
В соответствии с изначальной задачей управления телескопом языку FORTH требовались некоторые важные свойства. Он должен был быть пригоден для управления в реальном времени, обладать высокой степенью интерактивности для облегчения использования непрограммистами и удовлетворять жёстким ограничениям на объём занимаемой памяти.
Рассмотрение с этих позиций обнаруживает у языка два основных достоинства: использование поточного кода и 0-операндные стековые инструкции. В процессе объяснения работы языка в качестве вычислительной модели используется виртуальная FORTH-машина. В такой машине есть два стека: стек данных и стек адресов возврата. Приложения, написанные на FORTH, фактически эмулируют на целевом процессоре архитектуру MS0 . Они состоят из большого числа очень компактных процедур, которые вызывают другие процедуры и выполняют простейшие действия над стеком. Программы получаются похожими на деревья, где каждый вызов подпрограммы ведёт к небольшой коллекции низлежащих подпрограмм.
==47
Легко заметить, что FORTH является естественным языком для стековой машины с 0-операндной адресацией, подобной представленной «Классической Стековой Машине».
Следует отметить, что даже если процессор проектировался под FORTH, он может исполнять программы на любом другом языке программирования. Это происходит потому, что примитивы, характерные для языка FORTH, определены на очень низком уровне и соответствуют операциям в машинных кодах, которые имеются в любой стековой машине. Таким образом, любой процессор, рекламируемый, как «FORTH-машина», обычно пригоден и для работы с другими языками. [* Если компилятор для таких языков строит промежуточный код в соответствии с архитектурой абстрактной стековой машины. К таким компиляторам относятся PASCAL, MODULA, JAVA, C ] .
3.3.2.1 Стековая архитектура / Обратная польская запись ( RPN )
Примитивы языка FORTH, включая все инструкции «Классической Стековой Машины», приведены в табл. 3.1 . Все операции, не обрамлённые «[...]», точно соответствуют именам функций FORTH.
Имена в квадратных скобках «[IF]», «[CALL]», «[EXIT]» и «[LIT]» относятся к внутренним функциям языка, которые компилируются автоматически. Например, «[IF]» будет транслирован для выполнения условного перехода, когда в исходном тексте встречается конструкция «IF ... THEN». «[CALL]» вставляется всякий раз, когда встречается ссылка на слово FORTH, не являющееся машинной операцией. «[EXIT]» формируется оператором «;» ( точка с запятой ) в конце определения нового слова FORTH или словом «EXIT». И, наконец, «[LIT]» используется всякий раз, когда в программе встречается константа, например, «1234».
Некоторые конструкции языка FORTH, например, «LOOP» или переменные и константы, «Классической Стековой Машиной» напрямую не поддерживаются, но могут быть собраны из простых операций. Понятно, что эффективный FORTH-компьютер должен прямо поддерживать все часто используемые конструкции языка.
3.3.2.2 Частые вызовы коротких процедур
Основной особенностью языка FORTH, отличающей его от большинства остальных языков, является частый вызов подпрограмм. Хороший стиль программирования на FORTH поощряет поэтапную разработку и тестирование через вызовы маленьких функций, состоящих часто всего из 5 или 10 инструкций. Ситуация, при которой половину машинных кодов исполняемого файла составляет инструкция вызова подпрограмм, считается нормальной.
Такая организация работы позволяет создавать программы очень быстро и без ошибок. Она особенно эффективна для систем с ограниченным объёмом памяти и рассчитана на использование процессоров, поддерживающих быстрые вызовы процедур.
3.3.3 Акцент на интерактивности и универсальности
==48
Серьёзным преимуществом языка FORTH является высокий уровень интерактивности, предоставляемый средой разработки. В набор инструментов для разработки входит пошаговый транслятор и редактор, которые позволяют модифицировать и проверять отдельные процедуры в диалоговом режиме. Поощрение к написанию небольших процедур и модульного кода позволяет лёгко и быстро тестировать программу прямо в процессе написания, что существенно уменьшает необходимость последующего исправления однажды написанных слов. По общему мнению программистов, использующих FORTH, этот язык позволяет сократить время разработки в 10 раз в очень широком диапазоне приложений, по сравнению с другими языками.
Программы на нём делают основной упор на универсальности решений. Из-за того, что FORTH - расширяемый язык, новые структуры данных и управления могут добавляться к языку для вычислительной поддержки каких-либо специфических задач. Подобная универсальность позволяет одному-двум программистам решать проблемы, требующие усилий больших команд при использовании других языков, уменьшая накладные расходы на управление и увеличивая, тем самым, производительность. FORTH мало использовался в особо масштабных программных проектах, поэтому его эффективность в больших приложениях пока неизвестна . [* Выделено мной. Взаимоисключающие параграфы] .
==48