| |||
![]()
|
![]() ![]() |
![]()
JOVIAL Jules' Own Version of IAL (IAL - International Algebraic Language - раннее название для Algol-58, послужившего отправной точкой для разработчиков языка). Пожалуй, один из первых языков программирования, позволяющий нормально работать с железом. Собственно и делался он для программирования SAC Communication and Control System (SACCS): напрограммировавшись при разработке SAGE (SemiAutomatic Ground Environment) на ассемблере, Jules Schwartz и компания в 1959 году решили придумать что-то получше. Характер задачи оказал решающее влияние на язык: поскольку он делался для программирования большой интерактивной и распределенной системы реального времени, то им пришлось во-первых принимать во внимание вопросы эффективности и низкоуровневого программирования, и, в отличие от тогдашнего mainstream'a (тогда языки были в основном специализированными - для коммерческих задач, для вычислительных etc) не замыкаться в отдельной области. Получилось в общем неплохо, а для того времени - очень хорошо. Когда я читал описание, я с тоской вспоминал те времена, когда приходилось программировать на Фортране - в смысле, насколько бы все было проще и лучше. Реализован язык был очень быстро - первые компиляторы появились в 1960 году, а в 1961 JOVIAL уже был реализован на себе самом (вероятно второй в истории компилятор, написанный методом раскрутки - первым был NELIAC). С практическим применением, несмотря на неотлаженность и медленность компилятора, тоже все оказалось довольно хорошо и с тех пор в USAF очень любят JOVIAL и до сих пор его используют. Забавно происхождение названия: в предварительных проработках язык фигурировал как OVIAL (Our Version of IAL). Когда дело подошло к более формальной разработке, граждане озадачились тем, что название вызывает нездоровые ассоциации, и что надо бы облагородить звучание. Облагораживать решили при помощи добавления буквы J в начало и оставалось только придумать, что бы это могло значить. В порядке хохмы была предложена вышеприведенная расшифровка, после чего, ничего не решив, публика разъехалась по домам. А спустя некоторое время Jules Shwartz обнаружил, что название уже вписано в разнообразные контракты и техзадания и менять уже себе дороже. Чем язык интересен:Он будучи "широко известен в узких кругах" оказал несомненное влияние на развитие языков программирования:"Официально" оно признано только в Coral66 и Ada, но imho несомненно еще в нескольких языках (что забавно - в Wiki очень много написано про его военную карьеру, но ни слова не сказано о том, чем он собственно говоря, замечателен):Во-первых - в Pascal - перечислимые типы, диапазоны и модификатор packed - прямое заимствование, записи с вариантами, думаю, тоже попытка адаптировать интересные, хотя и кривоватые записи JOVIAL. В PL/I влияние тоже очевидно - система типов до степени смешения напоминает JOVIAL-овскую, хотя enum-ы и диапазоны они выкинули, зато остальное цветет буйным цветом - в том числе "атрибутная" форма описания типов. Ну и несомненно и сильно влияние JOVIAL на Ada: что скорее всего связано с происхождение обоих языков: Довольно естественно, что DoD при формулировке требований не хотел расставаться с уже имеющимися вкусностями и более или менее все возможности JOVIAL переехали в техзадание на Ada. Теперь собственно про сам язык:Излагаю я по опубликованной в 1963 году в CACM спецификации языка (версия 1973 года уже куда более наворочена). Примеры в основном взяты оттуда же.Во-первых - обещанные enum'ыПример я уже показывал:
ITEM RUNWAY'CONDITION S V(OK) V(WET) V(ICY) V(SNOW) V(BLOCKED)$ ITEM - это ключевое слово, обозначающее объявление переменной, RUNWAY'CONDITION - имя переменной ("'" был просто буквой, которую можно было использовать для повышения удобочитаемости имен). S - тип переменной - перечисление (сокращение от Status). Далее идут значения. $ обозначает конец объявления. Использовать это можно было примерно так: IF RUNWAY'CONDITION EQ V(OK)$ ... ДиапазоныПри описании переменных можно было специфицировать диапазон их значений:ITEM CEILING U 0..511$Беззнаковое с диапазоном значений 0..511 (диапазон можно было специфицировать и для дробных чисел и с плавающей точкой тоже). Проверка не выполнялась, описание фигурировало как своего рода комментарий и hint компилятору. Другие типы данныхЦелых в языке строго говоря не было - были знаковые и беззнаковые числа с фиксированной двоичной точкой (привет от PL/I и Ada), еще был такой курьезнейший, но в условиях тех времен весьма практичный тип: "сдвоенные" (Dual) числа с фиксированной точкой. Характеризовались добавлением модификатора D. Смысл состоял в том, что в тогдашних машинах слова были весьма длинные - и в одной слово вполне можно было впихнуть два значения не слишком большой разрядности. Dual значения и содержали пару чисел, а арифметика etc выполнялась одновременно над соответствующими компонентами пар (в случае, например, сложения Dual значения с обычным обычное "раздваивалось"). Вещь кривоватая, но практичная. Недавно оно к нам вернулось в виде разнообразных MMX :)
Таблицы и layoutsКак известно, авторы большинства ранних языков при попытках придумать структуры изобретали нечто весьма экзотическое. JOVIAL не исключение. Его создатели почему-то решили, что структуры такая хорошая вещь, что их обязательно должно быть много и потому они обязательно должны образовывать массив. В результате получилось нечто странное под названием "таблицы" (tables).Таблица - это массив структур. Описывается довольно прямолинейно: TABLE AIRBASE'WEATHER R 85 S D$ ITEM REPORT'HOUR A 5 U 0..23$ ITEM REPORT'MINUTE A 6 U 0..59$ ... ITEM RUNWAY'CONDITION S V(OK) V(WET) V(ICY) V(SNOW) V(BLOCKED)$ ... ENDАтрибут A nnn задает количество бит в значении. Атрибут R 85 задает то, что таблица имеет фиксированный размер 85 элементов (есть еще V max-size - таблицы "переменного" размера: то есть резервируется все равно "по максимуму", но при таблице хранится счетчик элементов. Более забавны два других атрибута: Атрибут D задает способ упаковки: он может принимать три значения: Dense, Medium и No. N означает, что каждое поле в таблице занимает отдельное слово/группу слов, D означает, что поля упаковываются как можно плотнее, M - что поля упаковываются на границы "естественных" подполей слов (полуслова etc - в зависимости от архитектуры) - на современных архитектурах примерным аналогом M будет отказ от выравнивания полей на границы слов (атрибут можно задавать и индивидуально для полей). Аттрибут S - это атрибут, управляющий расположением таблицы. Значения у него два: Serial и Parallel. Пожалуй, единственный атрибут, оправдывающий превращение структуры в массив. Он определяет как располагать поля в памяти: S подразумевает привычный нам последовательное расположение "запись за записью". А вот P пожалуй не имеет аналогов: он означает, что сначала идет массив из всех первых полей структуры, потом - из всех вторых, и так далее (на самом деле даже хитрее - если несколько последовательных полей влезают в одно слово, они все-таки размещаются вместе, и очередной массив набирается уже из таких n-ок. Вещь странноватая, но в случае необходимости заниматься оптимизацией представления данных весьма полезная. Еще одна фишка состоит в возможности указывать точное расположение полей в записях: ITEM KEY A 6 U 3 12$Поле KEY (шириной 6 бит) располагается в 3-ем слове начиная с 12-го бита. Кажется мелочью, но все, кто программировал низкоуровневые железки, фичу заценят. Оператор DEFINEВ отличие от подавляющего большинства создателей языков тех времен, авторам JOVIAL'a таки пришла в голову идея, что выписывать по много раз одни и те же списки атрибутов неудобно и несопровождабельно и что с этим что-то надо делать. Идея для тех времен наверное отличалась новизной и оригинальностью: это был макрооператор DEFINE без параметров (в J73 он уже обзаведется параметрами):DEFINE RUNWAY'CONDITION'VALUES "V(OK) V(WET) V(ICY) V(SNOW) V(BLOCKED)"$В пояснениях, думаю, не нуждается. Оператор TESTВидимо, первое явлениеFOR I = 1,1,100$ BEGIN FOR J=I,1,100$ BEGIN IF I+J EQ 150$ TEST I$ END ENDСтранное ключевое слово, выбранное для этого оператора, объясняется тем, что имеется в виду "переход на проверку условия выполнения следующей итерации цикла" Мелочь, а приятно: оператор итерации по элементам таблицы (как бы массива):FOR I = ALL (BASES)$ ...Тут все понятно. Прикольный оператор ==Смешной довольно - выполняет exchange значений по обе стороны оператора:Работа с битовыми/байтовыми полямВещь, которой почему-то с тех пор практически нигде не было: с одной стороны, эмулируется она, конечно, несложно (хотя, когда битовое поле пересекает границы слова - не так уж и несложно), с другой - настолько обычна, что причины ее отсутствия непонятны, да и в смысле эффективности скорее всего встроенная конструкция может быть реализована лучше:Итак: есть конструкция BIT ($index-of-first-bit [, index-of-last-bit]$) Обозначает ровно то самое. Может быть и получателем в операторе присваивания. Если значение занимает несколько слов, диапазон может пересекать границу слова. Например: BIT($0,6$)(COLUMN) = BIT($0,6$)(COLUMN) + (I - 2) Теперь еще раз напомню, что дело происходит во времена, когда у машин слова длинные, а единицей адресации является слово. Термин "байт" уже в ходу - но в смысле, что скажем 37-разрядное слово содержит 6 6-битных байтов: байт - это стандартная для данной машины группа битов в слове, которая используется для хранения символа. В некоторых архитектурах работа с байтами поддерживалась аппаратно, в некоторых все делалось руками. Потому кроме BIT есть модификатор BYTE с аналогичной семантикой, только он манипулирует не битами, а байтами. Для комплекта отмечу еще модификаторы MANT и CHAR, которые "вырезают" из вещественного числа мантиссу и характеристику. Пример из спеки: преобразование плавающего числа в представление с фиксированной точкой: MANT (BETA) * 2 ** CHAR (BETA) Ассемблерные вставкиОпять же - сделано было довольно забавно: Был оператор DIRECT список-команд JOVIAL, внутри которого можно было вставлять набор команд ассемблера. Для доступа к переменным была псевдокоманда ASSIGN, которая позволяла пересылать данные между переменными программы и регистром-аккумулятором. Мелочь - но опять-же - очень нужная в реальной жизни даже сейчас.Дальнейшее развитиеКак уже говорилось - в 73 году вышел стандарт языка: там уже DEFINE обзавелся параметрами, завелась условная компиляция, появились указатели и динамическое управление памятью etc etc. Но это уже не очень интересно, поскольку к тому времени новизна этих фич уже подутратилась.Тем не менее - JOVIAL imho заслуживает всяческого внимания хотя бы уже за то, что именно он, а не C, является первым универсальным языком, на котором действительно можно писать программы не испытывая необходимости постоянно фиксить нештатные ситуации ассемблерными вставками или совсем уж низкоуровневым хакерством с битиками и адресами. |
||||||||||||||||
![]() |
![]() |