Forth (язык программирования)

Forth (язык программирования)
Forth
Семантика:

императивный

Тип исполнения:

интерпретатор/компилятор

Появился в:

1971 г.

Автор(ы):

Чарльз Х. Мур

Основные реализации:

gForth, pForth, kForth, SP-Forth, win32forth ...

Диалекты:

FORTH-79, FORTH-83, ANSI FORTH 94 года.

Испытал влияние:

АПЛ, Лисп

Форт (Forth) — язык программирования, в котором программы записываются в постфиксной записи и в стековой нотации. Поддерживает механизмы метарасширения для изменения семантики и синтаксиса языка при настройке на предметную область. Синтаксис базового уровня в Форте необычайно прост и состоит из единственного правила: «все определения разделяются пробелами». Определения Форта могут иметь любое сочетание символов.

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

Содержание

История

В отличие от других языков программирования Форт не является плодом коллективного труда какого-либо комитета или коллектива учёных, он родился в голове одного человека — Чарльза X. Мура. В начале 1960-х годов Мура стало все больше не удовлетворять время и затраты труда, требовавшиеся для разработки программ на существовавших тогда ЭВМ. В течение нескольких лет он создал основы прототипа языка Форт, пользуясь для этого такими языками, как Алгол, Кобол, PL/I и ассемблер для IBM/360. Мур назвал свой язык Fourth, считая, что это будет язык для ЭВМ четвёртого (англ. fourth) поколения, однако ему приходилось работать на ЭВМ, которая допускала лишь пятибуквенные имена, составленные из прописных букв, поэтому название было преобразовано в FORTH, что символизировало его революционность (англ. forth — вперёд).

В 1971 году Мура пригласили на работу в Национальную Радиоастрономическую обсерваторию для разработки программ сбора и обработки данных, получаемых с радиотелескопа. В процессе этой работы и появилась первая реализация языка Форт (а вторым в мире программистом на этом языке стала сотрудница Мура Элизабет Ратер), который был принят в качестве основного языка программирования в Американском астрономическом обществе.

Базовый язык Форт общедоступен и бесплатно распространяется заинтересованной группой FORTH Interest Group (FIG). Существует множество реализаций разработанных как отдельными лицами, так и группами. Часть фирм поставляет различные по своим возможностям коммерческие версии языка, но ещё важнее то, что организована группа по стандартизации языка Форт для того, чтобы написанные на нём программы могли бы работать на различных компьютерах с минимальными затратами на их адаптацию.

В феврале 1978 в Утрехте (Голландия) был принят стандарт 1977 года (FORTH-77), адресованный прежде всего пользователям микроЭВМ.

В октябре 1979 встреча на острове Каталина закончилась разработкой стандарта FORTH-79, который распространяется на ЭВМ всех типов.

Осенью 1983 состоялась встреча по разработке стандарта 1983 года, утверждённого в 1984 году как FORTH-83. Стандарт Форт-83 отличается от стандарта Форт-79 некоторыми деталями, но не отличается от него по существу.

В 1994 году после продолжительных обсуждений многими фирмами был принят ANSI стандарт.[1]

Из первых успехов применения языка можно отметить использование его в программном обеспечении глубоководного спускаемого аппарата, при поисках «Титаника» в 1985 году. Существуют процессоры и контроллеры, поддерживающие вычислительную модель языка.

Диалект языка Форт используется в OpenProm — базовом программном обеспечении ЭВМ на базе процессоров PostScript[2], широко используемый для управления устройствами печати и послуживший основой для создания формата документов

Основные понятия классической Форт-системы

Основная часть Форт-системы — это связный список слов, или словарь, из которого слово вызывается по имени для выполнения специфических функций. Программирование на Форте состоит в определении новых слов на основе слов, определённых в словаре ранее. Как только новые слова скомпилированы в словарь, они не отличаются по форме от слов, которые в нём уже имелись. Описание слова в словаре называется статьёй.

Структура «типичной» статьи словаря Форта:

  • поле имени — содержит имя статьи (идентификатор слова) в виде строки со счётчиком, а также несколько флагов.
  • поле связи — указатель на предыдущую статью.
  • поле кода — указатель на код для интерпретации статьи.
  • поле параметров — семантика слова (в зависимости от поля кода).

Условно, статьи Форта можно разделить на две категории: низкоуровневые статьи и форт-статьи. Статьи первого типа содержат в поле кода указатель на процедуру в кодах целевого процессора, непосредственно выполняющую семантику слова. В поле параметров таких статей располагаются передаваемые процедуре параметры, либо сам её код. Форт-статьи содержат в поле параметров указатели на другие статьи, а поле кода указывает на специальную процедуру, называемую интерпретатором ссылок. На практике, структура статьи зависит от реализации, но, как правило, похожа на рассмотренную выше. Принцип, используемый внутри форт-статьи, называется шитый код (англ. Threaded code), а интерпретатор ссылок — виртуальной Форт-машиной.

Грамматически текст, обрабатываемый транслятором Форта, представляет собой последовательность лексем (англ. token), разделённых пробелами и символами конца строки, обычно CR+LF. Транслятор входной строки выбирает очередной токен и производит его поиск в текущем словаре, причём поиск ведётся от более новых слов к старым. Если слово не найдено, предпринимается попытка интерпретировать токен в качестве записи числа, которое, в случае успеха, помещается на вершину стека. Если же токен соответствует слову Форта, анализируется текущее состояния флага compile Форт-системы. Если флаг сброшен, то слово исполняется — управление передаётся по указателю поля кода найденной статьи. Если флаг установлен, слово компилируется, то есть указатель на его поле кода дописывается в текущую создаваемую статью. Если было оттранслировано число, оно снимается со стека и компилируется в литеральный код, исполнение которого внутри словарной статьи помещает число на вершину стека. Кроме того, слова могут содержать флаг immediate (англ. немедленный), в этом случае они всегда исполняются.

Механизм передачи параметров между словами:

  • через стек данных;
  • через ячейки памяти;
  • через именованные локальные переменные (стандарт 1994 года).

Язык предоставляет способ работы с памятью системы, как с линейной областью.

Обязательным компонентом системы является также стек возвратов. Доступен программно для изменения потока управления программы.

Всё вышесказанное относится к понятию Форт только в первом приближении. Форт — это не совсем язык программирования; вернее, он перекрывает понятие языка программирования. Форт в большей степени является виртуальной машиной и операционной системой ForthOS.[3]

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

Создание на Форте нового набора слов (лексикона) очень привлекательно при изучении языка в школе и даже в ВУЗе. Весь базовый набор может быть переписан на русском. Точно так же, все последующие слова могут быть написаны на русском (польском, украинском, таджикском и т. д.). В таком виде созданные лексиконы могут быть использованы для систем управления бытовой техникой, оружием, роботами, станками на производстве и т. д.

Типы кода Форта

В качестве машинного представления скомпилированной форт-программы используется тот или иной вид шитого кода.

При использовании подпрограммного кода мы получаем машинный код, в котором, по сравнению с кодом, сгенерированном компилятором обычного языка программирования, где на единственный стек ложатся и переменные, и адреса возвратов из подпрограмм, отсутствуют операции по «перетаскиванию» параметров подпрограмм. В качестве стека возвратов используется основной стек процессора, стек данных организуется программно

При использовании шитого кода, отличающегося от подпрограммного, определения Форта, состоящие только из машинного кода, называются примитивы. В таком шитом коде часто стараются использовать основной стек процессора в качестве стека данных, а обращения к данным, лежащим на нём, в виде машинных команд pop и push.

Одно из не совсем очевидных преимуществ использования косвенного шитого кода в том, что весь машинный код, то есть примитивы, вызовы интерпретатора кода и переменных, могут размещаться в одном сегменте кода, который будет недоступен для изменения. Весь остальной код Форта размещается в сегменте данных. Этих сегментов может быть много, а работать с единственным номером сегмента легче, чем с двумя.

Форт системы могут так же использовать байт-код, как логическое завершение развития косвенного шитого кода и свёрнутого шитого кода с адресной таблицей. В этом случае код программы (Форта) представляет собой последовательность байтов, или код некоторого придуманного виртуального процессора. Для исполнения этого кода должна существовать таблица на 256 адресов (2-байтовых, 4- или 8-байтовых), по которым расположены примитивы Форта или сложные определения.

Этот вариант сильно отличается от других видов кода и заслуживает особого внимания.

  • Как и в косвенном шитом коде, примитивы Форта могут быть расположены в едином сегменте кода, защищённом от вмешательства, прошитом в ПЗУ. Примитивы зависят от конкретной платформы и могут быть выполнены в виде отдельного блока. Вся остальная часть Форта является платформонезависимой и переносимой на любую машину.
  • Вокруг таблицы на 256 определений группируется отдельный словарь, лексикон, предназначенный для конкретной задачи или группы задач. Эти 256 определений занимают места не более 64К, то есть таблица может содержать 2-байтовые адреса (смещения относительно начала словаря).
  • Байтовый код позволяет расширить количество определений за счет древовидной структуры словарей до любой величины, сохраняя минимальные размеры программы.
  • Байтовый код может быть стандартизован. Как и для

Примеры программ

." Привет Мир" 

Пример определения слова SIGN, печатающего соответствующую фразу в зависимости от знака числа на вершине стека:

: SIGN  ( n -- )
   DUP 0> IF ." ПОЛОЖИТЕЛЬНОЕ ЧИСЛО" DROP
          ELSE 0=
            IF ." НОЛЬ"
            ELSE ." ОТРИЦАТЕЛЬНОЕ ЧИСЛО"
            THEN
          THEN ;

С учётом принятых в языке Форт норм оформления и написания, это должно быть, скорее, слово .SIGN и определяться так:

\ Напечатать знак числа
: .SIGN ( n -- )
  ?DUP 0= IF
    ." НОЛЬ"
  ELSE
    0>                       IF
    ." ПОЛОЖИТЕЛЬНОЕ ЧИСЛО"  ELSE
    ." ОТРИЦАТЕЛЬНОЕ ЧИСЛО"  THEN
  THEN
;

Пример реального кода, создающего строчную константу в принятом в Форт виде (со счётчиком):

\ Создать "константу" из строки
: S-CONSTANT ( c-addr u "<spaces>name" -- )
  CREATE 
    DUP , 0 ?DO
      DUP C@ C, CHAR+
    LOOP DROP 0 C,
  DOES>
    DUP CELL+ SWAP @
;

В этом примере создаётся определение слова name с помощью слова CREATE. При исполнении слова name на стек будет ложиться адрес указателя области памяти, который был во время компиляции слова. Для того, чтобы его можно было как-то использовать, туда записывается («компилируется» строка). При выполнении слова выполняются слова, указанные после слова DOES>.

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

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

Примеры таких стандартных слов:

[ — Временное переключение в режим исполнения (фактически, часто просто записывает 0 в переменную STATE).

] — Переключиться обратно в режим компиляции.

LITERAL — Компилировать число, в данный момент лежащее на вершине стека, как константу. Также является словом немедленного исполнения.

Пример кода, где используются эти слова:

\ Некоторый размер данных в килобайтах
16 CONSTANT size

\ Напечатать отчёт о пересчёте килобайтов в байты
: report ( -- )
  size . ."  килобайт эквивалентны "
  [ size 1024 * ] LITERAL . ." байтам"
;

Место Forth среди других языков программирования

Одна из постоянных тем споров вокруг языка Форт — это место, которое он занимает среди «классических» императивных языков. Программы на Форте имеют крайне непривычный вид:

  • Программа состоит из необычной последовательности слов, среди которых отсутствуют так называемые «ключевые» слова, которые распознаются и обрабатываются, в других языках программирования, специальным образом.

С выходом сериала «Звёздные Войны» по этому поводу появилась шутка, ставшая ныне классической, которая хорошо иллюстрирует данную особенность Форта:

ЙОДЫ МАГИСТРА РЕЧИ ТАЙНА ОТКРЫТА
НА ФОРТЕ ПРОГРАММЕР ЕСТЬ СТАРЫЙ ОН ПРОСТО
  • Приведенный пример заодно указывает на уникальную особенность Форта: отсутствие списка параметров в скобках и возможность программировать на родном языке. Использование словарных конструкций родного языка позволяет сделать программу очень понятной, а это повышает её надёжность. К сожалению, даже профессионалы Форта часто игнорируют хороший стиль и их программы представляют собой малопонятную абракадабру из смеси слов всех языков мира, да ещё в перемешку со стандартными определениями Форта. Эти программы отпугивают не только новичков, но даже знатоков. «Чужая программа — потёмки».
  • «Польская запись» арифметических выражений и наличие нескольких стеков. Это одна из «страшилок», которыми пугают новичков книги о Форте. Как показывает практика, привыкнуть к этой особенности совершенно не сложно. Считается, что написание небольшого набора слов, реализующего привычный вид записи математических выражений — хорошая тренировка для начинающего Форт-программиста.
  • Двойственная природа компилятора Форта. Нельзя утверждать однозначно, является ли Форт компилятором или интерпретатором. Практически всегда его можно использовать в двух режимах, за исключением редких случаев вроде «целевой компиляции» (трансляции в машинный код программы для системы с иной архитектурой).
  • Отсутствие системы типов. Подобно многим «скриптовым» языкам, в Форте нет встроенной системы типов. Нет возможности узнать, что лежит на вершине стека — число со знаком, число без знака, указатель на строку, символ, или два числа, рассматриваемого как одно большое число. Эта проблема разрешается двумя основными путями — использованием специальных наборов слов (например, запись и чтение ячеек памяти производят словами ! и @, а символов — словами C! и C@) и вынесением некоторых сущностей в специальные стеки (например, стек чисел с плавающей запятой, согласно стандарту ANS FORTH 94; он может быть, а может и не быть, реализован с помощью основного стека).

Эти особенности и определяют преимущества и недостатки языка Форт, благодаря которым он остался вне основных направлений развития прикладного программирования и, одновременно, обрёл своеобразное «бессмертие», благодаря которому у него всегда будут свои почитатели:

  • Простота и красота идеи, заложенной в Форт, позволяют написать ядро Форт-системы за день.
  • Свобода, предоставляемая программисту, требует сильного самоконтроля. Входной порог для программирования на Форте ниже, чем у языков типа C++, но требует привыкания и понимания не только возможностей и особенностей синтаксиса Форта, но, также, понимания философии, лежащей в его основе. Как следствие, нельзя использовать «дешёвых» программистов, как при использовании C# или Java.
  • Форт не поддерживает никакую парадигму программирования и поддерживает их все одновременно. Написать набор слов для организации ООП в программе на Форте (а их может быть одновременно несколько и они будут отлично уживаться вместе) гораздо проще, чем решить, какие возможности от этого набора слов требуются.
  • Разбиение программы на множество мелких слов позволяет легко и быстро проверять их по отдельности, передавая им нужные наборы входных параметров и контролируя то, что остаётся на стеке. Фактически, это означает, что для тестирования какого-то компонента программы можно не загружать все зависимые компоненты целиком.
  • Форт не скрывает ошибки. Этот факт установлен опытным путём. «Отложенные» ошибки в программе на Форте — большая редкость. Ошибки, которые, в обычных языках программирования, скрываются стандартным преобразованием типов (например, int в char в C++ (хотя большинство современных компиляторов выдаст, конечно, предупреждение) или строки в число в каком-нибудь скриптовом языке), практически мгновенно, при следующем же тестовом запуске, «обрушивают» программу.
  • Форт позволяет сделать декомпиляцию программы. Полученный текст мало отличается от исходного.
  • Форт позволяет реализовать любой «выкрутас» и технологию, которой овладели другие языки и системы. В то же время, он может сделать то, что не под силу другим системам. В нём допустимы приёмы, запрещённые в других языках (например — самомодификация кода). Грамотная методика использования и правильный лексикон могут устранить негативные последствия этих приёмов.
  • В интерпретаторе легко реализовать все проверки на границы диапазона адресов, а это при создании ОС позволяет отказаться от защищенного режима процессора. Получается существенный выигрыш в скорости работы.
  • Размер кода Форта для 16-разрядных систем, при грамотном написании программы, иногда в 10-20 раз меньше кода, скомпилированного из программы на С. Для 32-разрядных систем этот разрыв еще больше. В операционных системах общий выигрыш может составлять уже сотни, а то и тысячи крат. Причина очень простая — готовая задача на Форте имеет размер несколько байт, все вспомогательные подпрограммы реализованы в виде определений, доступных всем. Система на Форте вместится в процессор, в который другие системы влезть в принципе не способны.
  • Синхронизация процессов и потоков в многозадачных системах, переключение контекста, реализация доступа к ограниченным ресурсам — это сложнейшие проблемы при написании ОС-м. Для поддержки этих возможностей даже создаются специальные команды в микропроцессорах. Для интерпретатора это вообще не проблема, поскольку он эмулирует любой процессор и любую необходимую команду.

Возможно, что на самом деле больше всего развитию Форта препятствует «тяжёлое наследство», пришедшее от машин с низкими возможностями, для которых он изначально создавался. В последнем стандарте (ANSI FORTH 94), существуют, например, следующие особенности:

  • Переносимая программа должна предполагать, что стек чисел с плавающей запятой может быть реализован с использованием основного стека. К счастью, для большинства современных компиляторов это не так. Но сам факт наличия такого пункта в стандарте создаёт определённые неудобства. При программировании с активным использованием арифметики с плавающей точкой, эту норму стандарта традиционно игнорируют.
  • Аналогичная норма существует относительно стека потока управления. Здесь всё не так просто, так как часто это именно так и есть — в процессе компиляции стек используется самим компилятором. В абсолютном большинстве случаев никакого влияния на программу это не оказывает, но про саму особенность надо помнить. Например, если вы хотите в процессе компиляции вычислить какое-то число, за пределами начала определения, а потом вставить его в слово как константу, то для этого придётся использовать какой-либо обходной путь.
  • Определения многих слов в стандарте слишком низкоуровневые. Например, слово 2* производит не умножение на два, как следует из его названия, а «смещает число на один бит к старшему двоичному разряду, заполняя младший бит нулём». Конечно, на большинстве современных машин — это одно и то же, но сам факт использования особенностей конкретной архитектуры настораживает. (Существуют также более очевидные стандартные слова для сдвига битов — LSHIFT и RSHIFT.)

Многие из этих особенностей — следствие того, что на момент принятия стандарта существовало множество плохо совместимых Форт-систем, которые базировались на двух частично различающихся стандартах 79 и 83 года. В настоящий момент происходит обсуждение принятия европейского стандарта Форта. Перспективы этого начинания пока не ясны.

Примечания

См. также

Диалекты и курьёзы
Известные российские программы, написанные на Форте (SPF)
  • Eserv (почтовый и прокси-сервер, www, ftp, nntp сервер)
  • nnCron (планировщик)

Ссылки

Литература


Wikimedia Foundation. 2010.

Игры ⚽ Нужен реферат?

Полезное


Смотреть что такое "Forth (язык программирования)" в других словарях:

  • Язык программирования Си — Си Семантика: процедурный Тип исполнения: компилируемый Появился в: 1969 73 г. Автор(ы): Кен Томпсон, Денис Ритчи Типизация данных: статическая Основные реализации …   Википедия

  • Язык программирования C — Си Семантика: процедурный Тип исполнения: компилируемый Появился в: 1969 73 г. Автор(ы): Кен Томпсон, Денис Ритчи Типизация данных: статическая Основные реализации …   Википедия

  • Язык программирования Рубин — Ruby Семантика: мультипарадигмальный Тип исполнения: интерпретатор Появился в: 1995 г. Автор(ы): Юкихиро Мацумото Последняя версия: 1.9.1 …   Википедия

  • Язык программирования Java — Java Класс языка: объектно ориентированный, структурный, императивный Появился в: 1995 г. Автор(ы): Sun Microsystems Последняя версия: Java Standard Edition 6 (1.6.14) Т …   Википедия

  • Язык программирования Dylan — Dylan  динамический объектно ориентированный язык программирования, нацеленный на быструю разработку программ, разработанный, прежде всего, усилиями множественное наследование, полиморфизм и многие другие функции. Язык общего назначения,… …   Википедия

  • Occam (язык программирования) — Язык программирования Оккам (англ. Occam) это процедурный язык параллельного программирования высокого уровня, разработанный в начале 80 х годов группой учёных из Оксфорда под руководством Дэвида Мэя (англ. David May) по заданию английской… …   Википедия

  • Форт (язык программирования) — У этого термина существуют и другие значения, см. Форт (значения). Forth Семантика: императивный Тип исполнения: интерпретатор/компилятор Появился в: 1971 Автор(ы): Чарльз Х. Мур Основные реализации …   Википедия

  • ФОРТ (язык программирования) — Форт (Forth) процедурный язык программирования (см. ЯЗЫКИ ПРОГРАММИРОВАНИЯ) высокого уровня, а также программная среда (виртуальная машина) для него; разработан для обработки данных с радиотелескопов, но популярность приобрел с появлением… …   Энциклопедический словарь

  • Конкатенативный язык программирования — Конкатенативные или стековые языки программирования основаны на том, что конкатенация двух фрагментов кода выражает их композицию. Эти языки используют стек для хранения аргументов и возвращаемых значений операций. Самый распространённый… …   Википедия

  • AWL (язык программирования) — AWL (Alternative Web Language) Класс языка: мультипарадигмальный: функциональный, процедурный, объектно ориентированный Тип исполнения: интерпретируемый Появился в: 2005 г. Типизация данных: динамическая …   Википедия


Поделиться ссылкой на выделенное

Прямая ссылка:
Нажмите правой клавишей мыши и выберите «Копировать ссылку»