ar, as, b, bas, bcd, boot, cat, chdir, check, chmod, chown, cmp, cp, date, db, dbppt, dc, df, dsw, dtf, du, ed, find, for, form, hup, lbppt, ld, ln, ls, mail, mesg, mkdir, mkfs, mount, mv, nm, od, pr, rew, rkd, rkf, rkl, rm, rmdir, roff, sdate, sh, stat, strip, su, sum, tap, tm, tty, type, un, wc, who,
write.
3.2.1 Что такое QNX
Основным назначением любой операционной системы (ОС) является управление ресурсами компьютера. Все процессы в системе: планирование выполнения прикладных программ, запись файлов на диск, пересылка данных по сети и т. д., - должны выполняться как можно более единообразно и бесконфликтно.
Некоторые прикладные системы могут предъявлять повышенные требования к управлению ресурсами и планированию процессов. Например, работа приложений реального времени зависит от того, как операционная система управляет большим количеством событий, возникающих за конечные интервалы времени. Чем больше функций берет на себя ОС, тем более свободно "чувствуют" себя эти приложения при возникновении конфликтных ситуаций.
Для приложений, работающих в режиме реального времени, QNX является идеальной операционной системой. Она удовлетворяет всем основным требованиям, предъявляемым к системам реального времени: в ней реализован многозадачный режим, приоритетно-управляемое планирование и быстрое переключение контекста.
Кроме того, система QNX обладает большой гибкостью. Разработчики могут легко адаптировать ее под требования своих приложений. Настройка системы QNX может быть выполнена от минимальной (ядро и несколько небольших модулей) до полной сетевой конфигурации (обслуживание сотен пользователей), позволяя использовать в каждом конкретном случае только те ресурсы, которые необходимы.
Уникальная эффективность, модульность и простота системы QNX определяется:
- архитектурой ядра; взаимодействием между процессами посредством сообщений.
3.2.2 Архитектура ядра системы QNX
Система QNX состоит из небольшого ядра (микроядра) и набора взаимодействующих процессов. Как показано на рисунке 13, система не имеет иерархической структуры, ее организация скорее напоминает "спортивную команду", в которой игроки (процессы), имеющие равную значимость, взаимодействуют друг с другом и со своим "ведущим игроком" (ядром).
|
рис 13. - Микроядро системы QNX координирует работу системных администраторов |
3.2.3 Ядро системы QNX
Ядро является "сердцем" любой операционной системы. В некоторых системах на ядро возложено такое количество функций, что, по сути дела, оно само является полной операционной системой.
В системе QNX ядро является действительно ядром. Прежде всего, как и подобает ядру операционной системы реального времени, оно имеет небольшой размер_-_менее 8 Кбайт. На ядро системы QNX возложено выполнение только двух основных функций:
передача сообщений (ядро реализует передачу всех сообщений между всеми процессами во всей системе);
планирование (планировщик является частью ядра и подключается каждый раз, когда процесс меняет свое состояние в результате появления сообщения или прерывания).
В отличие от процессов само ядро никогда не планируется к выполнению. Управление передается ядру только в результате прямого вызова ядра либо из процесса, либо по аппаратному прерыванию.
3.2.4 Системные процессы
Все функции, выполняемые операционной системой QNX, за исключением функций ядра, реализуются стандартными процессами. В типичной конфигурации системы QNX имеются следующие системные процессы:
- Администратор процессов (Proc); Администратор файловой системы (Fsys); Администратор устройств (Dev); Сетевой администратор (Net).
3.2.5 Системные процессы и процессы пользователя
Системные процессы практически ничем не отличаются от любого процесса пользователя: у них нет специального или скрытого интерфейса, недоступного процессу пользователя.
Именно такая архитектура обеспечивает системе QNX неограниченную расширяемость. Поскольку большинство функций QNX выполняется стандартными системными процессами, то расширить операционную систему совсем не сложно: достаточно написать и включить в систему программу, реализующую новую функцию ОС.
Действительно, грань между операционной системой и прикладными программами весьма условна. Единственным принципиальным отличием системных процессов от прикладных является то, что системные процессы управляют ресурсами системы, предоставляя их прикладным процессам.
Сервер базы данных должен выполнять функции, аналогичные функциям Администратора файловой системы, который получает запросы (сообщения) на открытие файлов и чтение или запись данных. Несмотря на то, что запросы к серверу базы данных могут быть более сложными, и в том и в другом случае формируется набор примитивов (посредством сообщений), в результате чего обеспечивается доступ к системному ресурсу. В обоих случаях речь идет о процессах, которые могут быть написаны конечным пользователем и выполняться по необходимости. Таким образом, сервер базы данных можно рассматривать как системный процесс в одном случае и как прикладной в другом. Фактически нет никакой разницы. Важно отметить, что в системе QNX подобные процессы включаются без каких бы то ни было модификаций других компонентов операционной системы.
3.2.6 Драйверы устройств
Драйверы устройств - это процессы, которые избавляют операционную систему от необходимости иметь дело со всеми особенностями работы аппаратного обеспечения.
Поскольку драйверы выполняются как стандартные процессы, то добавление нового драйвера в систему QNX не влияет на работу других компонентов операционной системы. Единственное изменение, которое происходит в среде QNX - это запуск нового драйвера.
Драйвер может быть оформлен либо как дополнение к системному процессу, либо, для сохранения его "индивидуальности", в качестве стандартного процесса.
3.2.7 Связь между процессами
В типичной многозадачной среде, при одновременном выполнении нескольких процессов реального времени, операционная система должна обеспечивать возможность взаимодействия процессов друг с другом.
Связь между процессами (interprocess communication - IPC) является ключом к разработке приложений, представляющих собой набор взаимосвязанных процессов, в котором каждый процесс выполняетет одну строго определенную функцию.
В QNX реализован простой, но мощный набор IPC-возможностей, благодаря которому значительно упрощается разработка приложений, представляющих набор взаимодействующих процессов.
3.2.8 Операционная система с передачей сообщений
QNX стала первой коммерческой операционной системой данного класса, в которой IPC основан на принципе передачи сообщений. Именно благодаря глобальному использованию передачи сообщений во всей системе, ОС QNX обладает присущей ей мощностью, простотой и элегантностью.
В системе QNX под сообщением понимается пакет байтов, передаваемый от одного процесса к другому. QNX не предъявляет никаких требований к содержимому сообщения: данные в сообщении имеют значение только для его отправителя и получателя.
Посредством сообщений происходит не только передача данных между процессами, но также и синхронизация выполнения нескольких процессов. При передаче, получении и выдаче ответа на сообщения процессы изменяют свое состояние, что определяет время и продолжительность их выполнения. Располагая информацией о состоянии и приоритетах процессов, ядро может максимально эффективно планировать их выполнение, используя все доступные ресурсы центрального процессора. Этот метод передачи сообщений используется глобально во всей системе.
Для приложений реального времени требуется зависимая форма IPC, т. к. процессы, входящие в состав подобных приложений, сильно взаимосвязаны. Механизм передачи сообщений, реализованный в системе QNX, позволяет обеспечить высокую надежность работы приложений.
4 Языки программирования ВВС
Язык Оккам считается “языком ассемблера” для транспьютерных систем. Основой для языка Оккам является разработанный Т. Хоаром язык CSP.
Основным понятием языка является процесс: примитивный процесс, составной процесс, именованный процесс. Процессы могут выполняться последовательно и параллельно. Параллельные процессы взаимодействуют с помощью каналов.
Программа представляет простой процесс, использующий идентификаторы, точное значение которых зависит от конкретной машины. Процесс описывает действие, подлежащие выполнению. Процесс может быть примитивным или составным, содержащим определения и более простые составляющие процессы, объединенные «конструкторами» процессов. Структура составных задается посредствам фиксированного расположения текстов, в котором каждая компонента размещается на новой строке с небольшим отступом вправо от начала ключевого слова, вводящего определенную конструкцию.
4.1.1 Процессы
4.1.2 Процессы, не выполняющие действий
SKIP - простейший примитивный процесс, который не выполняет никаких действий.
STOP - процесс не выполняющий никаких действий, в отличие от процесса SKIP не завершается, но параллельно с остановленным процессом могут выполняться другие процессы.
4.1.3 Последовательные процессы
Выполнение последовательных программ заключается в присваивании переменным определенных значений, на основании которых в дальнейшем принимаются некоторые решения. Присваивание в языке Оккам имеет следующую форму.
переменная: = выражение
Каждое выражение имеет значение в виде комбинации битов, длина которой равна значению слова, используемого компьютером, каждая переменная способна сохранить битовую комбинацию размера слова.
SEQ – последовательный процесс конструируемый посредством записи последовательности его компонент, располагаемых одна за другой с небольшим отступом от ключевого слова SEQ. Последовательный процесс реализуется посредством выполнения каждой его компоненты в порядке записи.
IF - условный процесс с помощью которого производится выбор для выполнения одного из нескольких процессов, основанный на анализе значений переменных, Конструкция состоит из ключевого слова IF, ниже которого с небольшим отступом в право записываются компоненты. IF процессы выполняются путем просмотра сверху вниз списка компонент до тех пор пока не встретится условие со значением TRUE.
4.1.4 Параллельные процессы.
PAR – процесс, состоящий в выполнение каждой его компоненты до полного его завершения. Конструкция состоит из ключевого слова PAR, после которого с небольшим отступом вправо один под другим записываются процессы.
Связь между процессами осуществляется посредством ввода и вывода по каналам.
Процесс вывода
канал! Выражение - передает значение выражения по каналу.
Процесс ввода
канал? Переменная - принимает значение из канала и запоминает его как значение переменной.
Выбор процесса для выполнения в зависимости от других процессов ввода может производится с использованием ALT- процесса.
4.1.5 Процессы времени
В языке Оккам существует два примитивных процесса, с помощью которых программа получает доступ к текущему значению времени.
Процесс считывания показаний часов
TIME? Переменная - в результате переменной присваивается значение, равное текущему показанию часов.
Процесс временной задержки
TIME? AFTER выражение - может приостановить выполнение программы.
4.1.6 Описание данных
Имя в Оккам - программе, перед использованием, должно быть описано. Описание позволяет именовать значение констант, переменных и каналов.
Для записи констант используют ключевое слово DEF, за которым следуют определения вида
имя = константное выражение
Переменные описываются перечислением их имен после ключевого слова VAR выше процесса, в котором будут использоваться.
Каналы, описываются также, как переменные, но с ключевым словом CHAN.
С помощью ключевого слова PROC, можно давать имена процессам. Описание процесса вводится строкой вида:
PROC имя = текст именованного процесса
В языке существует один вид структурированных данных – одномерный массив. Можно использовать массивы констант, переменных и каналов. Описание массива состоит из имени массива, за которым в квадратных скобках записывается константное выражение.
имя [количество]
описывает ряд переменных, на которые можно ссылаться, индексируя имя массива выражениями, значение которых принадлежат диапазону от 0 до количество – 1.
Массив констант называется таблицей и обозначается следующим образом
TABLE [выражение. 0, выражение. 1, выражение. 2, …, выражение. n]
4.1.7 Циклы
В языке Оккам существует два вида циклов: неограниченные циклы WHILE и ограниченные индексируемы циклы FOR.
Выполнение WHILE заключается в проверке значений условий и затем, если это значение равно TRUE, выполнении тела цикла.
4.1.8 Приоритеты
Приоритеты в разменных операций не определены, поэтому в выражениях более чем с одной операцией, порядок действий обычно необходимо определять с помощью скобок. С помощью операций сравнения <, ≤, =, ≥, >, <> производится сравнение операндов.
Прием, который может заставить работать процесс, когда другой процесс занят какой – либо работой – это организовать передачу данных из одного канала в другой. Для этого надо неоднократно выполнять ввод из одного канала присваивания значения локальной переменной и последующую передачу значения переменной по другому каналу.
Структурные конфликты происходят тогда, когда программа должна выполнять операции над данными, различными на перекрывающиеся компоненты.
Естественный подход по нормированию подобных задач состоит в написании программ, структура которых отражает структуру документа.
Форт (Forth) — язык программирования, в котором программы записываются в постфиксной записи и в стековой нотации. Поддерживает механизмы метарасширения для изменения семантики и синтаксиса языка при настройке на предметную область. Синтаксис базового уровня в Форте прост и состоит из единственного правила: «все определения разделяются пробелами». Определения Форта могут иметь любое сочетание символов.
Ряд свойств, а именно интерактивность, гибкость и простота разработки делают Форт эффективным языком в прикладных исследованиях и при создании инструментальных средств. Очевидными областями применения этого языка являются встраиваемые системы управления. За счёт простоты транслятор, а зачастую и компилятор Форта легко реализуется для подавляющего числа микроконтроллеров. Также находит применение при программировании компьютеров под управлением различных операционных систем.
4.3.1 История
Язык Форт был создан Чарльзом X. Муром в конце 1960-х — начале 1970-х годов. Мур назвал свой язык Fourth, считая, что это будет язык для ЭВМ четвёртого (англ. fourth) поколения, однако ему приходилось работать на ЭВМ, которая допускала лишь пятибуквенные имена, составленные из прописных букв, поэтому название было преобразовано в FORTH, что символизировало его революционность (англ. forth — вперёд).
В 1971 году Мура пригласили на работу в Национальную Радиоастрономическую обсерваторию для разработки программ сбора и обработки данных, получаемых с радиотелескопа. В процессе этой работы и появилась первая реализация языка Форт (а вторым в мире программистом на этом языке стала сотрудница (E. Rather)), который был принят в качестве основного языка программирования в Американском астрономическом обществе.
Базовая реализация язык Форт общедоступен и бесплатно распространяется заинтересованной группой FORTH Interest Group (FIG). FIG также опубликовала первоначальный стандарт языка — FIG-FORTH.
Существует множество реализаций разработанных как отдельными лицами, так и группами. Часть фирм поставляет различные по своим возможностям коммерческие версии языка.
В составе ACM была организована группа SIGFORTH; была и соответствующая Российская группа ACM (председатель — проф. С. Н. Баранов (Санкт-Петербург, СПИИРАН)); сейчас — в составе более общей группы SIGPLAN.
В феврале 1978 года в Утрехте (Голландия) был принят стандарт 1977 года (FORTH-77), адресованный прежде всего пользователям микроЭВМ.
В октябре 1979 года встреча на острове Каталина закончилась разработкой стандарта FORTH-79, который распространяется на ЭВМ всех типов.
Осенью 1983 года состоялась встреча по разработке стандарта 1983 года, утверждённого в 1984 году как FORTH-83. Стандарт Форт-83 отличается от стандарта Форт-79 некоторыми деталями, но не отличается от него по существу.
В 1994 году после продолжительных обсуждений многими фирмами был принят ANSI стандарт.[3]
Одним из успехов применения языка можно отметить использование его в программном обеспечении глубоководного спускаемого аппарата, при поисках «Титаника» в 1985 году. Существуют процессоры и контроллеры, поддерживающие вычислительную модель языка.
Диалект языка Форт используется в OpenBoot — базовом программном обеспечении ЭВМ на базе процессоров SPARC, PowerPC.
На основе языка Форт Джоном Уорноком и Чаком Гешке из Adobe Systems в начале 1980-x годов был создан язык PostScript[4], широко используемый для управления устройствами печати и послуживший основой для создания формата документов PDF.
Ежегодно проводятся конференции ЕвроФорт (EuroForth), в том числе в Санкт-Петербурге (Россия), Англии, Австрии, Германии, Испании, Чехии (и Чехословакии)[5].
4.3.2 Основные понятия классической Форт-системы
Основная часть Форт-системы — это связный список слов, или словарь, из которого слово вызывается по имени для выполнения специфических функций. Программирование на Форте состоит в определении новых слов на основе слов, определённых в словаре ранее. Как только новые слова скомпилированы в словарь, они не отличаются по форме от слов, которые в нём уже имелись. Описание слова в словаре называется статьёй.
Структура «типичной» статьи словаря Форта:
- поле имени — содержит имя статьи (идентификатор слова) в виде строки со счётчиком, а также несколько флагов. поле связи — указатель на предыдущую статью. поле кода — указатель на код для интерпретации статьи. поле параметров — семантика слова (в зависимости от поля кода).
Условно статьи Форта можно разделить на две категории: низкоуровневые статьи и форт-статьи. Статьи первого типа содержат в поле кода указатель на процедуру в кодах целевого процессора, непосредственно выполняющую семантику слова. В поле параметров таких статей располагаются передаваемые процедуре параметры, либо сам её код. Форт-статьи содержат в поле параметров указатели на другие статьи, а поле кода указывает на специальную процедуру, называемую интерпретатором ссылок. На практике структура статьи зависит от реализации, но, как правило, похожа на рассмотренную выше. Принцип, используемый внутри форт-статьи, называется шитый код (англ. threaded code), а интерпретатор ссылок — виртуальной Форт-машиной.
Грамматически текст, обрабатываемый транслятором Форта, представляет собой последовательность лексем (англ. token), разделённых пробелами и символами конца строки. Транслятор входной строки выбирает очередной токен и производит его поиск в текущем словаре, причём поиск ведётся от более новых слов к старым. Если слово не найдено, предпринимается попытка интерпретировать токен в качестве записи числа, которое, в случае успеха, помещается на вершину стека. Если же токен соответствует слову Форта, анализируется текущее состояния флага compile Форт-системы. Если флаг сброшен, то слово исполняется — управление передаётся по указателю поля кода найденной статьи. Если флаг установлен, слово компилируется, то есть указатель на его поле кода дописывается в текущую создаваемую статью. Если было оттранслировано число, оно снимается со стека и компилируется в литеральный код, исполнение которого внутри словарной статьи помещает число на вершину стека. Кроме того, слова могут содержать флаг immediate («немедленный»), в этом случае они всегда исполняются.
Механизм передачи параметров между словами:
- через стек данных; через ячейки памяти; через именованные локальные переменные (стандарт 1994 года).
Язык предоставляет способ работы с памятью системы, как с линейной областью.
Обязательным компонентом системы является также стек возвратов. Доступен программно для изменения потока управления программы.
Всё вышесказанное относится к понятию Форт только в первом приближении. Форт — это не совсем язык программирования; вернее, он перекрывает понятие языка программирования. Форт в большей степени является виртуальной машиной и операционной системой ForthOS.[6]
Синтаксис и семантику Форта можно расширить до любого другого языка программирования прямо во время интерпретации (компиляции) форт-программы. Использовать Форт в качестве метаязыка удобно благодаря доступности средств Форта, поддерживающих те языки, которые уже есть в Форт-системе. Все ресурсы Форт-системы доступны пользователю и представлены в виде словарных статей. Как правило, словарные статьи, определённые пользователем, имеют точно такое же представление в Форт-системе, как и все остальные словарные статьи, из которых и состоит вся Форт-система.
4.3.3 Типы кода Форта
В качестве машинного представления скомпилированной форт-программы используется тот или иной вид шитого кода.
При использовании подпрограммного кода получается машинный код, в котором, по сравнению с кодом, сгенерированном компилятором обычного языка программирования, где на единственный стек ложатся и переменные, и адреса возвратов из подпрограмм, отсутствуют операции по «перетаскиванию» параметров подпрограмм. В качестве стека возвратов используется основной стек процессора, стек данных организуется программно.
При использовании шитого кода, отличающегося от подпрограммного, определения Форта, состоящие только из машинного кода, называются примитивы. В таком шитом коде часто стараются использовать основной стек процессора в качестве стека данных, а обращения к данным, лежащим на нём, в виде машинных команд pop и push.
Одно из не совсем очевидных преимуществ использования косвенного шитого кода в том, что весь машинный код, то есть примитивы, вызовы интерпретатора кода и переменных, могут размещаться в одном сегменте кода, который будет недоступен для изменения. Весь остальной код Форта размещается в сегменте данных. Этих сегментов может быть много, а работать с единственным номером сегмента легче, чем с двумя.
Форт системы могут так же использовать байт-код, как логическое завершение развития косвенного шитого кода и свёрнутого шитого кода с адресной таблицей. В этом случае код программы (Форта) представляет собой последовательность байтов, или код некоторого придуманного виртуального процессора. Для исполнения этого кода должна существовать таблица на 256 адресов (2-байтовых, 4- или 8-байтовых), по которым расположены примитивы Форта или сложные определения.
Этот вариант сильно отличается от других видов кода и заслуживает особого внимания.
- Как и в косвенном шитом коде, примитивы Форта могут быть расположены в едином сегменте кода, защищённом от вмешательства, прошитом в ПЗУ. Примитивы зависят от конкретной платформы и могут быть выполнены в виде отдельного блока. Вся остальная часть Форта является платформонезависимой и переносимой на любую машину. Вокруг таблицы на 256 определений группируется отдельный словарь, лексикон, предназначенный для конкретной задачи или группы задач. Эти 256 определений занимают места не более 64К, то есть таблица может содержать 2-байтовые адреса (смещения относительно начала словаря). Байтовый код позволяет расширить количество определений за счет древовидной структуры словарей до любой величины, сохраняя минимальные размеры программы. Байтовый код может быть стандартизован. Как и для Java, такой код может быстро пересылаться по сети и исполняться на машинах с любой платформой.
4.3.4 Примеры программ
." Привет Мир"
Пример определения слова SIGN, печатающего соответствующую фразу в зависимости от знака числа на вершине стека:
: SIGN ( n -- )
DUP 0> IF." ПОЛОЖИТЕЛЬНОЕ ЧИСЛО" DROP
ELSE 0=
IF." НОЛЬ"
ELSE." ОТРИЦАТЕЛЬНОЕ ЧИСЛО"
ENDIF
ENDIF ;
С учётом принятых в языке Форт норм оформления и написания, это должно быть, скорее, слово. SIGN и определяться так:
\ Напечатать знак числа
: .SIGN ( n -- )
?DUP 0= IF
." НОЛЬ"
ELSE
0> IF
." ПОЛОЖИТЕЛЬНОЕ ЧИСЛО" ELSE
." ОТРИЦАТЕЛЬНОЕ ЧИСЛО" ENDIF
ENDIF
;
Пример реального кода, создающего строчную константу в принятом в Форт виде (со счётчиком):
\ Создать "константу" из строки
: 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. ." байтам"
;
4.3.5 Место Forth среди других языков программирования
Одна из постоянных тем споров вокруг языка Форт — это место, которое он занимает среди «классических» императивных языков. Программы на Форте имеют крайне непривычный вид:
- Программа состоит из необычной последовательности слов, среди которых отсутствуют так называемые «ключевые» слова, которые распознаются и обрабатываются, в других языках программирования, специальным образом.
- Приведённый пример заодно указывает на уникальную особенность Форта: отсутствие списка параметров в скобках и возможность программировать на родном языке. Использование словарных конструкций родного языка позволяет сделать программу понятной, что повышает её надёжность. «Обратная польская запись» арифметических выражений и наличие нескольких стеков. Двойственная природа компилятора Форта. Нельзя утверждать однозначно, является ли Форт компилятором или интерпретатором. Практически всегда его можно использовать в двух режимах, за исключением редких случаев вроде «целевой компиляции» (трансляции в машинный код программы для системы с иной архитектурой). Отсутствие системы типов. Подобно многим «скриптовым» языкам, в Форте нет встроенной системы типов. Нет возможности узнать, что лежит на вершине стека — число со знаком, число без знака, указатель на строку, символ, или два числа, рассматриваемых как одно длинное число. Эта проблема разрешается двумя основными путями — использованием специальных наборов слов (например, запись и чтение ячеек памяти производят словами ! и @, а символов — словами C! и C@) и вынесением некоторых сущностей в специальные стеки (например, стек чисел с плавающей запятой, согласно стандарту ANSI FORTH 94; он может быть, а может и не быть, реализован с помощью основного стека).
Эти особенности и определяют преимущества и недостатки языка Форт:
- Простота идеи, заложенной в Форт, позволяют написать ядро Форт-системы за день. Свобода, предоставляемая программисту, требует сильного самоконтроля. Входной порог для программирования на Форте ниже, чем у языков типа C++, но требует привыкания и понимания не только возможностей и особенностей синтаксиса Форта, но, также, понимания философии, лежащей в его основе. Форт не поддерживает никакую парадигму программирования и поддерживает их все одновременно. Написать набор слов для организации ООП в программе на Форте (а их может быть одновременно несколько и они будут отлично уживаться вместе) гораздо проще, чем решить, какие возможности от этого набора слов требуются. Разбиение программы на множество мелких слов позволяет легко и быстро проверять их по отдельности, передавая им нужные наборы входных параметров и контролируя то, что остаётся на стеке. Фактически, это означает, что для тестирования какого-то компонента программы можно не загружать все зависимые компоненты целиком. Форт не скрывает ошибки. Этот факт установлен опытным путём. «Отложенные» ошибки в программе на Форте — большая редкость. Ошибки, которые, в обычных языках программирования, скрываются стандартным преобразованием типов (например, int в char в C++ (хотя большинство современных компиляторов выдаст, конечно, предупреждение) или строки в число в каком-нибудь скриптовом языке), практически мгновенно, при следующем же тестовом запуске, «обрушивают» программу. Форт позволяет сделать декомпиляцию программы. Полученный текст мало отличается от исходного. Форт позволяет реализовать любую возможность и технологию, которой овладели другие языки и системы. В то же время, он может сделать то, что не под силу другим системам. В нём допустимы приёмы, запрещённые в других языках (например — самомодификация кода). Грамотная методика использования и правильный лексикон могут устранить негативные последствия этих приёмов. В интерпретаторе легко реализовать все проверки на границы диапазона адресов, а это при создании ОС позволяет отказаться от защищенного режима процессора. Получается существенный выигрыш в скорости работы. Размер кода Форта для 16-разрядных систем, при грамотном написании программы, иногда в 10-20 раз меньше кода, скомпилированного из программы на Си. Для 32-разрядных систем этот разрыв еще больше. В операционных системах общий выигрыш может составлять уже сотни, а то и тысячи крат. Причина очень простая — готовая задача на Форте имеет размер несколько байт, все вспомогательные подпрограммы реализованы в виде определений, доступных всем. Система на Форте вместится в процессор, в который другие системы влезть в принципе не способны. Синхронизация процессов и потоков в многозадачных системах, переключение контекста, реализация доступа к ограниченным ресурсам — сложнейшие проблемы при написании ОС. Для поддержки этих возможностей даже создаются специальные команды в микропроцессорах. Для интерпретатора это вообще не проблема, поскольку он эмулирует любой процессор и любую необходимую команду.
Возможно, что на самом деле больше всего развитию Форта препятствует «тяжёлое наследство», пришедшее от машин с низкими возможностями, для которых он изначально создавался. В последнем стандарте (ANSI FORTH 94), существуют, например, следующие особенности:
- Переносимая программа должна предполагать, что стек чисел с плавающей запятой может быть реализован с использованием основного стека. К счастью, для большинства современных компиляторов это не так. Но сам факт наличия такого пункта в стандарте создаёт определённые неудобства. При программировании с активным использованием арифметики с плавающей точкой, эту норму стандарта традиционно игнорируют. Аналогичная норма существует относительно стека потока управления. Здесь всё не так просто, так как часто это именно так и есть — в процессе компиляции стек используется самим компилятором. В абсолютном большинстве случаев никакого влияния на программу это не оказывает, но про саму особенность надо помнить. Например, если вы хотите в процессе компиляции вычислить какое-то число, за пределами начала определения, а потом вставить его в слово как константу, то для этого придётся использовать какой-либо обходной путь. Определения многих слов в стандарте слишком низкоуровневые. Например, слово 2* производит не умножение на два, как следует из его названия, а «смещает число на один бит к старшему двоичному разряду, заполняя младший бит нулём». Конечно, на большинстве современных машин — это одно и то же, но сам факт использования особенностей конкретной архитектуры настораживает. (Существуют также более очевидные стандартные слова для сдвига битов — LSHIFT и RSHIFT.)
Многие из этих особенностей — следствие того, что на момент принятия стандарта существовало множество плохо совместимых Форт-систем, которые базировались на двух частично различающихся стандартах 79 и 83 года. В настоящий происходит обсуждение принятия европейского стандарта Форта. Перспективы этого начинания пока не ясны.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 |



