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

Фокал - часть 3 (пишется)


Автор:
Опубликован:
24.05.2026 — 24.05.2026
Читателей:
1
Аннотация:
Типа продолжение к "Фокал снаружи и внутри"
Предыдущая глава  
↓ Содержание ↓
↑ Свернуть ↑
  Следующая глава
 
 

три: чтение, запись и побитовое-И — например на предмет проверки признака

готовности), без первого аргумента: FX( , А, Б) не лезет ни в какие

регистры, а всего лишь выполняет побитовое-И между А и Б, рассматривая их как

длинные целые: бывает, что надо и в других местах выделять отдельные биты.

(Или, используя не вполне корректные фокусы-покусы со знаками А и Б — другие

побитовые операции...) Или например так же самая FSBr() без аргументов не

вызывая никаких подпрограмм, сразу возвращает содержимое аккумулятора. (Куда

иногда могут "зелететь" и такие вещи, как например количество строк, реально

выданных на экран просмотрщиком, что больше ну никак...)

— парочка-троечка функций с побочными эффектами: FColoro (она же FЦвет) для

указания цвета выводимых на экран символов (включая коррекцию палитры);

FKурсор (она же FCS) для перемещения по экрану курсора (включая считывание

считывание уже выведенных на экран буковок, изменение их цвета, а так же

рисование на нём линий и рамочек символами псевдографики); FBIp для издания

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

морзе); FMuso (она же FMышь) для работы с мышкой; FMIn и FMAx (без побочных

эффектов) призванные (вместе со сменой знака в роли инверсии) служить

логическими операциями И и ИЛИ — в том числе для троичной или нечеткой логики.

FTMp для получения текущей даты/времени (в виде количества суток от начала

тысячелетия, где время это дробная часть суток) а так же для других действий с

датой/временем, включая преобразование в удобочитаемый вид и обратно. (Вот эта

вот функция была первой и получилась несколько нестандартной...)

— оператор Vizual и парная к нему функция FViz на предмет "управления

визуализацией". А на самом деле получения параметров экрана (например высоты и

ширины), а так же режима работы дисплея. Включая их переключение, в том числе в

один из графических режимов и отрисовку там графичесских примитивов.

Однако, эти примитивы оказались слишком примитивными (и пока что этот

оператор отправлен на реконструкцию, а функции сией функции — урезаны): Фокал

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

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

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

"полигон" и закраска оного, а оси координат (вместе с началом координат,

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

и уже только после этого точки графика (возможно объединённые в "коллекции"),

положения которых на экране автоматически пересчитываютя в соотвтествии с

масштабом осей. Эта часть графики — "векторная". А "растровую" предполагается

поручить двум функциям FТочка и FЛиния, как это было в Фокале на БК-0010,

организованным по аналогии с FKурсор...

— некоторая модернизация некоторых операторов:

* Вычисление возвращаемого значения прямо в операторе Ret, делающее его

аналогом Xecut. (Чисто на будущее: чтобы если и когда будут параллельные

процессы, запускаемые оператором Job — чтобы между вычислением возвращаемого

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

всю малину.)

* Передача оператором Do параметров в подпрограмму по аналогии с FSBr

* Дополнительные ключевые слова в операторе Write чтобы сообщал дополнительные

сведения (в форме пригодной для последующего ввода), в том числе о результатах

деятельности операторов Set Oper Do Break... Аналогично и для Eraze — буде

там найдётся что очистить.

* Несколько выражений в операторе Xecut и несколько присваиваний в операторе

Set — выпендрёж чистой воды. (Ибо экономия получается — копеечная.) А вот

избавляться от ключевого слова Set (как в Бейсике первое что сделали — сделали

чтобы можно было не писать LET) — это фиг: нарушение принципов! Да и экономия

в два символа, включая пробел...

* Меры по повышению "скриптовости" операторов передачи управления If и Go.

Это когда программа не как обычно — сперва грузится в память и только потом

запускается на выполнение, а сразу выполняется по мере чтения из файла. Который

называют "командным" (а нынче — "скриптовым"). Особенность тут в том, что

все строчки командного файла — "прямые". А операторам передачи управления

подавай номер строки!. Чтобы от них здесь был какой-то толк, надо бы номера

строк как ни будь того... Равняясь на оператор For, у которого тело цикла это

остаток строки, вспомним, что и у If есть то же самое — когда последние адреса

перехода отсутствуют. Ну так разрешим, чтобы любые, а не только последние -

при условии сохранения разделяющих их запятых. И плюс к этому пусть нулевой и

отрицательный номер строки тоже что-то значат: нулевой — ничего не делать

(перейти к следующей строке), а отрицательный — к следующему оператору, как и

пропуск. (А то вызовем FSBr, а она...) И тогда можно например так:

If (X) 0, ,0; Type " икс равен нулю "!

If (X) ,0 ; Type " икс не равен нулю"!

Дополнительно: из трёх выражений в операторе If теперь вычисляется только одно,

а остальные — пропускаются. Потому что эти выражения вполне могут давать

побочный эффект. И/или в выборе одного из них — смысл всего этого оператора...

По аналогии с If — оператор Go 0; передаёт управление на начало текущей

строки и таким образом позволяет сделать цикл в одной строчке. Например:

Set c=FCHr(-1); type c; If(c-27),0; Go 0; Coment 27 — код нопки ESC

Эта програмка в одну строку будет выдавать коды нажатых кнопок, пока

пользователь не нажмёт кнопку ESC, она же "эскейп".

* Модернизация оператора For на предмет борьбы с плавающей арифметикой:

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

конечное значение более чем на пол шага. (Но после завершения цикла остаётся

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

шага, если он опущен: еще и -1 если конечное значение меньше начального. А

опустить можно не только шаг, или даже конечное значение (получится аналог

оператора присваивания), но и вообще всё. Остаток строки выполнится ровно один

раз, но как подпрограмма — что нам тоже понадобится... (Чуть ниже.)

— Реакция на "события" и "ситуации" (в т.ч. ошибки). Она устанавливается:

Break С = реакция; "Реакция" здесь это номер строки или группы, которую

надо запустить, когда произойдёт оное событие или случится ошибка/ситуация.

Хотя это может быть и остаток строки: Break С = ; остаток строки...

Если С < 0 то это ВНЕШНЕЕ "событие", ловушка на него — глобальная.

(Удалить — только явно, указав нулевую реакцию.) Для ДОС`а первые 256 из них

реальные прерывания (а под UNIX`ом это будут сигналы); с номерами больше 1000

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

заказанного функцией FCLk, и.т.п. К сожалению количество таких ловушек очень

ограничено — средство это таки экспериментальное. Интерпретатор Фокала -

медленный; реакция на событие "вклинивается" между выполнением операторов и

выглядит так, как будто между ними вставили оператор Do, но когда это еще

будет... Поэтому внешние события только "фиксируются" — наращивается значение

связанного с ловушкой счетчика. При реакции оно передаётся первым аргументом,

а счетчик — сбрасывается. Принудительно обнулить все эти счетчики: Eraze Break;

Если С >= 0 то это ВНУТРЕННЯЯ "ситуация", в том числе ошибка; ловушка

на неё — локальная. (Автоматически удаляется при возврате из поставившей её

подпрограмы вместе с локальными переменными.) По аналогии с программными

строками, события объединяются в группы (ошибки: группы событий 0 — 5), ловушку

можно поставить как на всю группу, так и индивидуально. Возникнув, ситуация

начинает "распространятся" — последовательно прекращая выполнение вложенных

вызовов подпрограмм. И дораспространявшись до интерпретатора, вызывает с его

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

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

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

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

Искусственно порождать ситуации поручено оператору Quit (а события — Kill).

Например так можно досрочно выскочить из цикла или даже нескольких вложенных:

Brek 7; For i=1,N; For j=-M,M; For k=0,L; If(FSBr(ххх, i,j,k))0; Quit 7,""

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

переданные ей i j k её вполне устраивают, так и. Это и есть "структурный

переход". Ситуация 7 выбрана "от балды" (лишь бы не совпадала с уже имеющимися:

теми, которые ошибки). Дололнительные числовые аргументы в Quit передаются

подпрограмме реакции, но она в этом примере — "нулевая". А вот текстовый -

интерпретатору, чтобы он, если что, знал что сказать. А в нулевой строке (как

в данном случае) указывает — что мол еще поработаем, что это не команда на

завершение работы интерпретатора.

Если вышеприведённый пример в одну строку, таки строка подпрограммы, то

следующие после неё строки не будут выполнены: ведь тут же случилась СИТУАЦИЯ,

но реакция на оную (хотя и нулевая) героически устранила последствия. После

чего подпрограмма НОРМАЛЬНО завершается, а не... (Типа: не устрани она — ой что

было бы!) Ага-ага. Но если нам надо чтобы выполнились и следующие строки, надо

засунуть всё это в персональную подпрограмму, сделав телом оператора For из

одного только этого ключевого слова. Вот пусть это она "нормально завершается".

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

одной стороны отладочное окошко (правда весьма ограниченной полезности, так как

пристойно работает только в текстовых режимах) — чтобы трассировочная

информация попадала туда и не на основной экран и не портила изображение;

а с другой — микро-хелп в отладочном режиме (подсказка по его командам) и

возможность ввести и выполнить командную строку — чтобы например посмотреть

значения переменных или заглянуть в основной хелп...

А вот перенаправление трассировочной информации в отдельный файл — тот,

который указывается в командной строке вторым и открывается под псевдонимом Б,

так и не сделано: уж больно как-то оно всё неизящно получается...

— Табулостопы и спецкомментарий из одних двоеточий, типа: : : : !

где двоеточиями отмечаются их позиции. Спецкомментарий становится "спец" только

если завершается ! (восклицательным знаком) или ; (точкой с запятой),

указывающими на конец строки или же её продолжение. Иначе, как и любой

комментарий, игнорируется. (Раньше двоеточие тоже числилось буковкой на ряду со

всякими # @ $ | ~ но поручив ему табуляцию, пришлось назначить

его разделителем.)

Вобще-то табулостопы понадобились оператору Write со вторым ключевым

словом Set, сообщающему результат деятельности оператора присваивания — список

переменных, имеющихся на настоящий момент в памяти. Вместе с их значениями,

разумеется. Этих переменных может быть как две-три, так и десятки, сотни и

даже тысячи, особенно когда мы имеем дело с массивами. И выдавай оператор Write

каждую из них в отдельной строке — просматривать всё это было бы муторно.

Надо чтобы в виде таблички, желательно стройными рядами и колоннами... Ну так

на то и табуляция!

Секретарши испокон веку печатали на пишущих машинках всяческие таблички.

И у них там эти самые "табулостопы" — такие выдвигающиеся железочки,

отмечающие начало очередной колонки. А клавиша ТАБ передвигала каретку к

следующему. Но в эпоху алфавитно-цифровых дисплеев их тупо расставили в каждую

восьмую позицию... А я сперва сделал чтобы можно было устанавливать какой хочу

шаг табуляции, а потом и оные табулостопы индивидуально. И свалил всё это на

FVIz. Получилось универсально, но таки сложновато и ненаглядно. А наглядно — в

виде вот такого спецкомментария. Он же выдаётся по Write Tab; а Eraze Tab;

приводит систему с состояние по-умолчанию.

И теперь вот думаю: а ведь запись в базе данных, ну например типа .dbf,

она ведь вот так же выглядит? Правда, там у полей есть имена, и их границы

пересекать не полагается... А что мешает и мне так сделать? И можно будет

заполнять поля оной записи в произвольном порядке, типа: Type :имя, значение;

Правда, для этого понадобится еще и буферизация вывода...


* * *

Подсистема ввода/вывода Фокала (ну наконец-то мы до неё добрались!)

устроена очень просто: есть один канал ввода и один канал вывода. Канал вывода

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

переключен оператором Operate куда-то еще. А канал ввода соответственно

по-умолчанию подключен к клавиатуре.

Из канала ввода читает функция FCHr — побайтно, оператор Ask — построчно,

и интерфейсная часть интерпретатора (тоже построчно), когда ей нужна

очередная командная строка.

Обратим внимание: интерфейсная часть интерпретатора читает командные

строки из канала ввода, не интересуясь — к чему именно он подключен. Что и

даёт возможность как загрузить ранее сохранённую программу (просто переключив

на неё канал ввода — будет вводиться сама собою, пока не кончится...), так и

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

только тем, что тут все строки — "прямые", а там — косвенные. То есть ничем:

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

её сразу же и запустит, так и командному файлу по мере необходимости

подгружать (а потом — удалять) куски программ. (Сильно сомневаюсь, чтобы

Бейсику было доступно хоть что-то подобное.)

Кстати, при запуске интерпретатора, первый аргумент в командной строке

это имя файла, который сразу же открывается (под псевдонимом "А") и на него

переключается канал ввода...

В канал вывода пишут все, кому не лень: и та же самая функция FCHr — тоже

побайтно; и операторы Type, Write, Help; и сам интерпретатор — сообщения об

ошибках; и даже функция FTMp. (Прямо не канал, а проходной двор!)

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

"на посмотреть" пользователю, и для сохранения её где-то на внешнем носителе

используются разные команды — LIST и SAVE, каждая со своим собственным

заковыристым и неочевидным синтаксисом, то в Фокале всё это делает один и тот

же оператор Write, синтаксис которого предельно прост. Но конечно для

123456 ... 121314
Предыдущая глава  
↓ Содержание ↓
↑ Свернуть ↑
  Следующая глава



Иные расы и виды существ 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)
Закрыть
Закрыть
Закрыть
↑ Вверх