Страница произведения
Войти
Зарегистрироваться
Страница произведения

Еще одно такое-же типа дополнение к 4й главе


Автор:
Жанр:
Изобретательство
Опубликован:
17.03.2024 — 10.04.2024
Аннотация:
а на само деле результат очередной ревизии кода (самый конец до- и пере-писывается, а остальное - уже вряд ли)
 
↓ Содержание ↓
↑ Свернуть ↑
  Следующая глава
 
 

Краткое, но почти полное описание Фокала (можно сказать — "ликбез").

Сначала "базового", потом — текущая версия "вторая базовая".

(ред 1.07 от 1.4.24) (ревизия.3 от 9.4.24 )

А то книжка моя "Фокал снаружи и изнутри" это конечно хорошо, но уж слишком

много текста. Да и писана чтобы понять что и как нужно БУДЕТ сделать, и почему.

А надо — что уже сделано, типа руководство и справочник. Да, есть и такое:

результат ревизии. Но что-то мне не нравится. Как-то там всё не так...

Поэтому пишем заново.

================


* * *

===============

Итак: Фокал — интерпретируемый операторный язык еще первого поколения,

заточенный под режим диалога и ориентированный на экономию всех видов ресурсов

(как ЭВМ, так и человека), поэтому, в частности, максимально лаконичный.

(И, кстати, "строчно-ориентированный".)

(Все лишние рассуждения, например про поколения языков программирования и

"операторность" — удалил к коврюжьей матери! Но таки надо указать на

"калькуляторную" сущность данного языка, само название которого: КАЛькулятор

ФОрмул в пику ФорТРАНу, который — транслятор. И что Фокал обычно сравнивают с

Бейсиком: да, действительно во многом похожие языки, но Фокал компактнее,

лаконичнее, гораздо лучше продуман и вообще предназначен совсем для другого.)

"ДИАЛОГ" заключается в том, что человек сидит за терминалом (каковым может

быть даже телетайп середины прошлого века) и вводит командные строки: Фокал

выдаёт "приглашение", в качестве которого обычно символ * (звёздочка); человек

набирает командную строку и нажимает "ввод" (ВК, Enter); Фокал берёт эту

строку и либо сразу выполняет, либо, если в начале строки есть номер, помещает

её под этим номером в память, чтобы выполнить потом. В процессе выполнения

делает то, что предписывают составляющие эту командную строку "операторы".

После чего выдаёт следующее "приглашение"...

"ОПЕРАТОР" предписывает одно элементарное (для данного языка) законченное

действие. Чаще всего: вычислить выражение и как-то применить его результат.

Оператор Фокала обязательно начинается с ключевого слова, указывающего что

надо сделать, и может содержать что-то еще: второе ключевое слово, выражение,

или даже несколько, тогда они разделяются запятыми, или больше ничего. Сами

операторы, если в строке их несколько, разделяются символами ";". Ключевые

слова подобраны на разные буквы алфавита и могут сокращаться до одной первой

буквы. (Остальные всё равно игнорируются.)

Примеры операторов Фокала и для сравнения аналогичных операторов Бейсика:

Type (2+2)*2 — напечатать результат PRINT (2+2)*2

Set X=(2+2)*2 — сохранить в переменной X LET X=(2+2)*2

Ask X — ввести в X число с терминала INPUT X

Coment любой текст — комментарий до конца строки REM комментарий

Фокал, как и современный ему Бейсик, работал с одним единственным типом

данных — числами с плавающей запятой. Операций с ними — пять: + — * / ^.

(Последняя — возведение в степень.) Все скобки ([{<>}]) эквивалентны. Все

кавычки " ' ` — тоже. В кавычках — текстовые константы. Они используются в

операторах ввода и вывода Ask и Type для выдачи пояснений ко вводимым и

выводимым числам. Если там нужна кавычка — заключаем текст в кавычки другого

типа.

Обратим внимание: в операторах ввода/вывода Ask и Type допустим, не один, а

произвольное количество элементов списка ввода/вывода. Кроме текстовых констант

в виде символов в кавычках, а так же ! (восклицательного знака) предписывающего

переход на следующую строку, он включает для Ask — переменные, куда помещать

вводимые числа, а для Type — выражения, значения которых вывести. А так же

таинственную конструкцию "формат", указывающую как их выводить (см. далее).

ПЕРЕМЕННЫЕ — только глобальные. И тоже, как и в Бейсике, не требуют

предварительного объявления, а создаются по мере надобности — в момент

первого присваивания. То же самое относится и к элементам массивов, которые

на самом деле — переменные с индексами: каждая из них существует индивидуально.

(Тогда как в Бейсике массив таки надо предварительно объявить оператором DIM.)

Это несколько расточительно, зато удобно. И сама собой исчезает проблема

начального индекса: с единицы, как в Бейсике, нумеруются элементы массива, или

с нуля как в Си? Но в качестве побочного эффекта — возможность обратиться к

одной и той же переменной с разным количеством индексов, да еще и зависящая от

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

эквивалентно его отсутствию: и Х(0,0) и Х(0) это то же самое, что просто Х.

Надеюсь, уже не надо объяснять, что "переменная" это такая штучка, в которой

можно хранить одно число?...

ИМЕНА ПЕРЕМЕННЫХ распознаются по двум первым буквам. Для калькулятора

этого более чем достаточно. Остальные если есть — игнорируются. Как и в других

языках, имена могут состоять из букв и цифр и начинаться должны обязательно с

буквы. Но буквой в Фокале считается всё, что не цифра и не разделитель. Т.е.

это не только русские буквы, но и всякие значки типа @ # $ & | _.

В отличии от переменных, имена всех встроенных функций начинаются на букву

Ф (а переменные на букву Ф называть нельзя, увы) и распознаются по первым

уникальным буквам. При чём, чтобы не гадать как правильно: FRAnd или FRNd,

реализованы все альтернативные варианты. Но именованные функции — только

встроенные. Возможности назначить имена подпрограммам не предусматривается.

Однако, предусматривается возможность подгрузки недостающих библиотечных

функций: оператором Load (до сих пор не реализованная).

Набор встроенных функций, как и у Бейсика, включает математические (корень,

логарифм, экспонента, прямые и обратные тригонометрические), генератор

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

целой и дробной части. Но вместо SLEEP тупо приостанавливающей выполнение

программы — FCLk сообщающая длительность временного интервала от некоторого

момента, ею же в прошлый раз и установленного. В дополнение к работающим с

числами Ask и Type, функция FCHr для побайтного ввода/вывода. И функция FX для

управления оборудованием, в том числе нестандартным.

Особняком стоит функция FSUbr предназначенная для обращения к подпрограмме

как к функции — из середины выражения. С передачей параметра и возвратом

результата. (Можно даже сказать, что это функциональный аналог оператора Do.)

Параметр попадает в спецпеременную с именем &, а в качестве результата

возвращается значение последнего вычисленного в подпрограмме выражения. (Не

важно в каком операторе.)

В Бейсике, кстати, было сделано аналогично. Там это называлось "функция

определяемая пользователем". Но там она была одна единственная и требовала

предварительного объявления. (Что, кстати, вместе с операторами DATA/READ,

сохранившимися и поныне, указывает на то, что это сляпанное на скорую руку

подмножество всё того же Фортрана было таки изначально ориентировано на

компиляцию, причем с перфокарт.)

ПРОГРАММНЫЕ СТРОКИ в Фокале, как и в Бейсике — нумеруются. Номера строк

служат как метками для передачи управления, так и средством их упорядочивания:

хранятся и выполняются они в порядке нумерации, независимо от того, в каком

порядке введены. Новая строка с тем же самым номером замещает уже существующую.

Строка без номера называется "прямой" (или "нулевой") и выполняется сразу.

(А нумерованные — соответственно "косвенными".)

Но в отличии от Бейсика, номера строк не целые числа, а дробные.

В результате программа распадается на структурные единицы — "группы" строк.

Так, что целое число обозначает всю такую группу, а дробное — конкретную

строку в ней. А когда нужна вся программа (например в операторе Write, Modify,

или Eraze (см. далее)) — пишется ключевое слово Ales, что значит "всё".

Каждая такая группа это "естественная подпрограмма", где сам бог велел

разместить одно законченное сложное действие. При передаче управления такой

структурной единице оператором обращения к подпрограмме Do или функцией FSBr,

возврат автоматически происходит по достижении её конца. При чем даже в том

случае, если там нет оператора возврата Ret.

Каждая отдельная строка — это тоже естественная подпрограмма! Что удобно

например для отладки: можно запускать строки по одной и смотреть что

получается... Но запустить подпрограмму с "дополнительной точки входа" (т.е.

не с начала группы) — невозможно.

Как правило может быть до 99 групп и до 99 строк в каждой группе. Но на

самом деле — на сколько памяти хватит. Однако, обратим внимание: номер группы

и строки в ней это не два целых числа, а одно дробное. Так что строка с

номером 1.1 это то же самое, что 1.10, а вовсе не 1.01!

Операторы УПРАВЛЕНИЯ порядком действий:

Go N_строки — безусловный переход к строке с указанным номером

Do N_строки — переход к подпрограмме

Ret — возврат из подпрограммы

If (Усл) N1,N2,N3 — условный переход

For i=Нач,Кон,Шаг; ... — цикл со счетчиком

Quit — стоп (и в "прямой" строке — выход из Фокала)

Условный оператор сравнивает значение "Усл" с нулём — поэтому в нём три

адреса: для случаев когда оно меньше нуля, равно и больше. Последние из них,

впрочем, могут быть опущены и тогда в соответствующих случаях выполняется

остаток строки. Обратим внимание: условие обязательно в скобках.

В операторе For циклически выполняется остаток строки после оператора. И он

тоже — "естественная подпрограмма": куда бы мы оттуда ни передали управление,

оно всё равно вернется заголовку цикла. Но досрочно выйти из цикла (как в

других языках — просто передачей управления за его пределы) — невозможно. Для

этого придётся установить значение параметра цикла больше конечного.

(Разумеется, в качестве параметра цикла можно использовать любую переменную,

включая элементы массива.) Выражения в заголовке цикла вычисляются только один

раз — перед первой итерацией. И последние из них, так же как и в операторе If,

могут быть опущены. Тогда шаг будет +1. А без конечного значения оператор

эквивалентен присваиванию.

Обратим внимание: оператор цикла (в отличии от аналогичного оператора

Бейсика) можно использовать и в ненумерованной, "прямой" строке.

Необходимо отметить, что в Фокале выражение произвольного вида может быть

везде, где по смыслу требуется число. В том числе и в качестве адреса в

операторах перехода — будет "вычисляемый переход", аналог оператора switch

языка Си. И даже когда ввода ожидает оператор Ask. (Который фактически левая

часть оператора присваивания. А правую вводит сидящий за терминалом...)

Константа — только в конструкции "ФОРМАТ" оператора Type: два целых числа

через точку после символа % (процент) — указывающих сколько всего позиций под

число и какова точность. (Одиночный % восстанавливает формат "по-умолчанию".)

Например: известно, что facos(-1) это число Пи. С разными форматами:

номера позиций: 123456789_123456789_123456

T %5.5 facos(-1),-2 -> 3.1416 -2

T %10.5 facos(-1),-2 -> 3.1416 -2

T %5.10 facos(-1),-2 -> 3.141592654 -2

T %1.10 facos(-1),-2 -> 3.141592654 -2

T %1.40 facos(-1),-2 -> 3.14159265358979312 -2

T % facos(-1),-2 -> 3.14159 -2

Таким образом, рассматриваемая версия (использующая плавающее число

"двойной точности") даёт максимум 18 значащих цифр и действительно выделяет

под число поле указанной ширины. Но если число занимает больше позиций — без

зазрения совести вылезает за пределы этого поля. Да еще и добавляет после числа

пробел (чтобы идущие подряд числа не сливались), от которого решительно

невозможно (было) избавиться! Но сейчас — можно: он подавляется при наличии

текстовой константы. В том числе и пустой:

T facos(-1),-2 -> 3.14159 -2

T facos(-1),"",-2 -> 3.14159-2

И наконец по желанию па-ачтеннейшей публики... (Ну да, забыл я про это.)

T %010.5 facos(-1),-1 -> 00003.1416 -000000001

"ОБСЛУЖИВАНИЕ" ПРОГРАММЫ, в отличии от Бейсика, производится тоже

операторами языка:

Write n — вывести на терминал строку или группу строк номер n

Eraze n — стереть -//-

Modify n — редактировать строку n (а не вводить целиком заново)

Write — вывести всю программу

Write Ales — -//— плюс заголовок-комментарий

Eraze Ales — стереть всё — привести интерпретатор в исходное состояние

Eraze — стереть только переменные (программу — нет)

Запустить выполнение находящихся в памяти строк — любым оператором передачи

управления: Go, Do и даже If. Но если с самого начала и всю программу — то Go

или Do с ключевым словом Ales, или вообще без аргументов.

Распечатать на бумаге или сохранить программу на внешнем носителе — тоже

оператором Write. Но для этого сначала надо переключить (оператором Operate)

канал вывода на одно из подключенных к машине устройств (например на принтер:

O L), а потом обратно на терминал: O L; W A; O T.

Загрузить ранее сохраненную программу еще проще: достаточно переключить на

неё канал ввода, и интерпретатор прочитает её оттуда сам. Но когда она там

кончится, произойдёт ошибка "конец носителя". А по любой ошибке каналы ввода

и вывода автоматически устанавливаются обратно на терминал и его клавиатуру.

(Но вполне можно было добавить в конце какую ни будь прямую команду: хоть

переключающую канал ввода обратно на клавиатуру принудительно, хоть сразу же

запускающую только что загруженную программу: O P;W A;T "O K"!;O T)

В оные времена внешних устройств у машины было немного и они указывались в

операторе Operate вторым ключевым словом: Lpt — принтер, Prf — перфоратор,

Rd — перфосчитыватель, Tty — терминал, Kbd — его клавиатура. А сейчас второе

ключевое слово превратилось в "псевдоним" открытого файла. Впрочем L всё так

же обозначает превентивно открытый в ДОС`е файл стандартного принтера, а T и K

терминал и клавиатуру.

ЗА КАДРОМ ОСТАЛСЯ оператор Xecut (надо бы execut — "выполнить", да буква Е

уже занята), просто вычисляющий выражение и игнорирующий его результат. Он

нужен для вызовов функций с "побочным эффектом" (например FCHr(x) выдающую

байт с кодом х в канал вывода) когда нужен этот эффект, а возвращаемое

функцией значение — нет. Оператор Kill сбрасывающий все внешние устройства в

исходное состояние. (Сейчас после этого пришлось бы перезагружать компьютер.)

И оператор "?" (вопросительный знак), который будучи поставлен перед любым

другим оператором, включает (или выключает) режим "трассировки" — когда текст

123 ... 567
 
↓ Содержание ↓
↑ Свернуть ↑
  Следующая глава



Иные расы и виды существ 11 списков
Ангелы (Произведений: 91)
Оборотни (Произведений: 181)
Орки, гоблины, гномы, назгулы, тролли (Произведений: 41)
Эльфы, эльфы-полукровки, дроу (Произведений: 230)
Привидения, призраки, полтергейсты, духи (Произведений: 74)
Боги, полубоги, божественные сущности (Произведений: 165)
Вампиры (Произведений: 241)
Демоны (Произведений: 265)
Драконы (Произведений: 164)
Особенная раса, вид (созданные автором) (Произведений: 122)
Редкие расы (но не авторские) (Произведений: 107)
Профессии, занятия, стили жизни 8 списков
Внутренний мир человека. Мысли и жизнь 4 списка
Миры фэнтези и фантастики: каноны, апокрифы, смешение жанров 7 списков
О взаимоотношениях 7 списков
Герои 13 списков
Земля 6 списков
Альтернативная история (Произведений: 213)
Аномальные зоны (Произведений: 73)
Городские истории (Произведений: 306)
Исторические фантазии (Произведений: 98)
Постапокалиптика (Произведений: 104)
Стилизации и этнические мотивы (Произведений: 130)
Попадалово 5 списков
Противостояние 9 списков
О чувствах 3 списка
Следующее поколение 4 списка
Детское фэнтези (Произведений: 39)
Для самых маленьких (Произведений: 34)
О животных (Произведений: 48)
Поучительные сказки, притчи (Произведений: 82)
Закрыть
Закрыть
Закрыть
↑ Вверх