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

Руководство по Фокалу


Автор:
Жанр:
Изобретательство
Опубликован:
22.04.2025 — 23.04.2025
Читателей:
1
Аннотация:
Нет описания
Предыдущая глава  
↓ Содержание ↓
↑ Свернуть ↑
  Следующая глава
 
 

поредактировать, и то что получилось сбрасываем в другой файл (когда придумаем

средство вывода). Ага, разбежались! При переключении канала ввода вот с того

самого файла на терминал, А2 автоматически очищается. Ну так надо чтобы не

очищался: добавим ко всяким RWABT в псевдониме открытого файла еще и буковку N.

А вот мы хотим, чтобы это было число, которое вот сейчас и вычислим...

Для этого переведём оператор Ask в особый режим, когда он работает в точности

как Type, но пишет не в канал вывода, а в А2. С помощью "спецформата" %% тоже

очищающего А2 и спецформата %%% — не очищающего (только урезающего по текущую

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

Действует этот особый режим работы оператора Ask до его конца или до ! как

раз и означающего конец строки.

Забегая вперёд: автор строит хищные планы не ограничивать режим вывода в А2 по спецформату %%% концом оператора Ask. Дабы приобщить к нему и всех остальных, кто способен писать в канал вывода. А то есть вот такая мелкая проблемка: исторически так сложилось, что функция FTMp, сообщающая текущие дату/время в виде единого числа, сама же и преобразует его в удобочитаемую форму. И этот текст выдаёт в канал вывода. В то время как все остальные функции с подобными побочными эффектами (FTEll например — имя очередног файла при их поиске в каталоге) пишут таки в А2. Вот так неединообразно получилось. Но возни, чтобы эту дату/время как то использовать... А тут всё стало бы единообразно.

Возникнув, эти самые спецформаты %%, %%% и даже %%%% принялись мигрировать,

в том числе обратно в операторы Type и Write.

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

такая штука — встроенный просмотрщик. (Аналог UNIX`овского more.) Всего лишь

подсчитывает переданные ему для вывода на экран строчки. И как вывел N штук,

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

пользователь. А он может нажать либо ввод, тогда просмотрщик выдаёт еще одну

строчку, либо пробел — тогда следующий экран, либо ЕСЦ — тогда вывод должен

быть прекращен.

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

Для оператора Write он тоже автоматически подключается. А вот для Type — нет.

Но подключается с помощью %%, а с помощью %%% еще и задействуется автотабуляция

чтобы выводимое выстраивалось в стройные колонки. (Прибамбас для вывода

значений переменных с помощью Write Set.) Для чего в недрах Фокала есть

таблица табулостопов (доступ к которой — как всегда с помощью функции FViz).

Например: For i=1,1e9; Type i; будет долго-долго вываливать на экран

числа от одного до миллиарда, при чем рассмотреть что либо не представляется

возможным. А вот: For i=1,1e9; Type %% i; — поэкранно. Но нажатие кнопки ESC

это процесс не прекратит: это надо проверить с помощью FTEll(0) и сделать

например так: For i=1,1e9; Type %% i; If(FTEll(0)),0,0; Set i=1e9

А если там написать: Type %%% "ой", "мама", "еще", "только", i

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

табулостопа.

Однако сейчас (5.1) у нас есть : (двоеточие) как раз и предписывающее

переход к следующему табулостопу — эффект тот же самый даже без привлечения

просмотрщика. Так что спецформат %%% в Type стал ненужен. И автор строит

хищные планы...

У этого самого просмотрщика есть счетчик выведенных им на экран строк. Ну

так обычно для каждого очередного оператора Help или Write счет ведётся с

нуля. Оператор Type его тоже сбрасывает — чисто на всякий случай. А вот со

спецформатом %%% — нет. Write %% тоже нет, а Write %%% N принудительно

устанавливает. (Уж не знаю зачем — авось пригодится...)

Спецформат вида %число в операторах ввода, а это Ask и Write с форматным

выражением, указывает "размер записи". Тоесть предписывает прочитать не

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

вот этим числом) размер.


* * *

(4.3) Миграция формата % в оператор Write.

Сброс содержимого А2 в канал вывода будет выглядеть так: Write % 1;

Правда при условии что А2 заведомо не пуст. Иначе потащит строку из канала

ввода. Или лучше: Write % ""; — тогда не потащит...

Однако придумано это для совершенно других целей: облегчения написания

скриптовых файлов. В том числе выдающих на экран длинные тексты, типа

всяких руководств и демонстрашек...

(Да что там греха таить: W % N "метка"; было придумано и реализовано

при попытке похвастаться красивостями (1.4) — написать демонстрационную

программку, рассказывающую о всяких FBip, FЦвет... объясняющую как их

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

С одной стороны тексты с объяснениями довольно длинные, а с другой — алгоритм

вовсе не тупо линейный... Там же выявилась необходимость хоть как-то управлять

просмотрщиком, который и выдаёт эти тексты на экран.)

"Командным" или "скриптовым" файлом называют программку, которая

выполняется прямо "с колёс" — по мере чтения из файла, где содержится.

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

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

какого другого носителя. Терминал "выделенный" — только в плане ошибок.

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

демонстрационно-обучающих программах тексты надо выдавать на экран в темпе

восприятия пользователя...

И, кстати, а как выдавать тексты? Элементарно, с помощью оператора Type.

То есть написать текст, а потом каждую строчку заключить в "скобочки": T" и "!

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

текст потом весьма неудобно. (Или надо их убрать, поредактировать и вставить

по-новой.) А нельзя ли без этого обойтись? Можно: поручим оператору Write

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

строки из канала ввода в канал вывода. С некоторым преобразованием — для

удобочтитаемости. Каковое традиционно укажем "форматом" вида: %Буковка, который

придумаем потом. А пока % как и в Type — по-умолчанию, то есть один в один.

Сначала — просто указанное количество строк (или до конца файла). Например:

Write % 5

если бы вот это был бы командный файл, выдал бы вот эту и следующие 4 строки

в канал вывода (на терминал, или куда он направлен). Потому как интерпретатор

тоже читает программу построчно: вот прочитал строчку с оператором Write % 5

и указатель ввода/вывода стоит на начале следующей после него строки. Дальше

он вот эти пять строк выведет, а потом в файле будет опять командная строка:

Coment вот в данном случае комментарий...

Но каждый раз строчки подсчитывать... Как минимум чревато ошибками. Поэтому

следующая мысль: копировать до "метки" — уникального текстового фрагмента,

который заведомо не встретится в выдаваемом тексте. Укажем его оператору Write

текстовой константой и поместим в первую после конца текста строку, типа:

=========================== метка_123 =================== (для заметности).

И пусть он ищет такой фрагмент в каждой очередной строке. Если найдено — стоп.

(А строку с меткой уже не выводит.)

Это, кстати, решает еще одну важную проблему: управление порядком действий

в командном файле.

Чтобы можно было писать полноценные программы, одной линейной

последовательности действий — недостаточно. Минимальные средства управления

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

(с запоминанием обратного адреса и последующим возвратом управления по нему).

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

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

еще пока не считанной строки) — не проблема: Set X=ftell(); (При условии,

что предшествующая операция ввода/вывода была именно с этим файлом. Если

что, для гарантии можно вставить фиктивную — типа: Oper () Псевдоним; )

Так что реализовать что возврат из подпрограммы, что цикл, который — переход

назад: Oper (X) A; или If(условие_повторения_цикла) 0,0; Oper (X) A;

(Наш командный файл скорее всего будет указан первым аргументом в командной

строке при запуске Фокала и следовательно открыт под псевдонимом А.)

Проблема — организовать переход вперёд: откуда бы нам знать смещение

интересующей нас строчки?! Единственная возможность — читать все строчки

подряд и искать в каждой из них вот эту самую "метку". Вот Write % "метка"

это и делает. (А без этого — побайтно читать файл функцией FCHr и с чем-то

сравнивать. Можно. Но сложно, громоздко, ненаглядно...) Единственное: оператор

Write %; не просто читает, а копирует. Но вот есть в операционной системе

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

информация... Откроем его заранее, например под псевдонимом Z: O "nul" ZW

и тогда преход к метке будет: O Z; W % "метка"; O T; или сначала: O (0) A

но это если эта самая "метка" — раньше (до текущего места). При чем заведомо

раньше, а то найдёт саму вот эту строку... Просто и универсально, увы, не

получается.

А начиная с (4.4), где появились форматные выражения, возиться с

устройством nul уже не обязательно: W %! "метка"; и всё.

Далее: а КАК Write % копирует строки?

Через А2.

Да, в результате этого возникают некоторые дополнительные проблемы, чем

если бы у Write был собственный буфер. Но за-то это одновременно и средство

вывода строки из аккумулятора. И не только...

В частности, при обнаружении метки, содержащая её строка так и остаётся в

А2. И перед следующей операцией приходится его очищать: Ask %; Но и это

можно применить для пользы дела. Например:

Если текст длинный — больше размера экрана, для его вывода подключается

встроенный просмотрщик. Дающий пользователю возможность в том числе прекратить

просмотр текста. (Нажав кнопку ЕСЦ.) В результате файл, откуда его читаем, не

будет перемотан до следующей командной строки. И с этим надо что-то делать.

Узнать, что пользователь нажал этот самый эскейп (ESC), мы можем проверив

содержание односимвольного буфера клавиатуры. (Получить его: ftell(0) при

условии что предыдущая операция ввода/вывода была с терминалом или

клавиатурой.) По-идее он должен быть пуст — содержать ноль. Но если в

просмотрщике был нажат ЕСЦ, то там будет -1, что впрочем тоже означает, что

он пуст. Так что:

Ask %; Write % "_метка_"; Oper () T; If(FTEll(0)),0,0; Write %! "_метка_";

Но ведь если первый оператор Write отработал полностью, то строка, содержащая

текст "_метка_" уже в аккумуляторе. Поэтому можно куда проще:

Write % "_метка_"; Write %! "_метка_";

(Второй оператор Write или найдёт эту самую метку сразу, или таки перемотает

до неё файл.)

Резюме (типа подведём итоги): С одной стороны к (4.3) Фокал стал куда

"более скриптовым". (Это мы еще не рассматривали, как организовать стэк для

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

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

чем с сохранением возможности автономного их выполнения. Впрочем, это

рассмотрено в разделе <<7>> файла справки (выдаваемой оператором Help),

непомерно в результате разросшимся...)

А с другой — обнаружились средства работы с текстовыми строками. Которых

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


* * *

пример ?


* * *

Но средства эти пока что непомерно хилые.


* * *

Прежде чем перейти к (4.4) и начать рассматривать более продвинутые

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

мы там, в том обширном списке пропустили?

(1.2) всякие удобства, включая оператор Help, уже упоминавшийся просмотрщик

к нему (всего лишь выдающий текст поэкранно) и редактор командной строки с

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

фрагмент строки — дабы вставить в другом месте. Потом возможность захватить в

этот карман (или сразу вставить в строку) кусок текста с любого места экрана.

(Слизано с ДосНавигатора.) Потом пул (мешок) ранее введенных строк. В том

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

самом файле _fpks.txt). Потом еще и "отладочное окно" — чтобы трассировочная

информация не затирала изображение на экране. Удобство, честно говоря,

сомнительное, а в графических режимах работает и вовсе безобразно. В то время

как использование для аналогичных целей файла протокола (того самого для

которого псевдоним Б) так и не вышло из стадии эксперимента.

Как всем этим пользоваться — см.<<1>>, для чего подать команду: Help 1

Или открыть файл foc.hlp (или какой он у текущей версии?) любым редактором

или просмотрщиком и найти там метку <<1>> (обязательно в начале строки).

Оператор Help просто выдаёт на экран разделы этого самого файла справки,

(который вполне себе текстовый), разделенные вот такими метками.

Соответственно: Help АБВГД ищет метку <>. Без аргумента Help выдаёт

краткую справку на один экран. (Самое начало файла.) А если метка не найдена,

то оглавление (список помеченных строк). Кроме <<#>> — эта часть текста в

файле справки — "закомментирована". В первом же из таких разделов — описание

организации самого файла справки.

(1.5) доработка операторов:

Что оператор If доработан для использования в "нулевой" строке, и

оператор Go с ним за компанию — см. выше. (Для Go нулевой номер строки велит

перейти к началу текущей, а для If — наоборот завершить текущую. А вот пропуск

номера строки или -1 — никуда не переходить, а передать управление следующему

после If оператору. И что из трёх выражений в операторе If вычисляется только

одно, а остальные — нет.)

Что шаг в операторе For, если он опущен, определяется автоматически, в

зависимости от того что больше — начальное или конечное значение (а не как

в (1.0) тупо устанавливается +1). Что цикл прекращается, когда значение

счетчика выйдет за конечное значение более чем на пол шага. Что опущен может

быть не только шаг, а вообще всё: For; — тогда тело цикла (остаток строки)

выполняется ровно один раз, но тоже как подпрограмма. Что тоже имеет смысл:

может служить границей распространения ситуации (см.(3)).

Что оператор Do, так же как FSBr, может иметь любое количество

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

1234567 ... 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)
Закрыть
Закрыть
Закрыть
↑ Вверх