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

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


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

даже целыми текстами таким макаром сделать можно. (Буковки это фактически и

есть короткие целые числа, а строки — массивы таких чисел.) Но уж больно это

громоздко, сложно и расточительно: средство зело низкоуровневое...

Более продвинутые средства: строчный аккумулятор (который А2) и возможность

не только хранить там одну текстовую строку, а так же вводить её и выводить на

внешние устройства (в файлы), или формировать (с помощью Ask %%), но и

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

написав ! вместо "...". Везде, кроме операторов ввода/вывода Ask и Type, где !

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

(Ну Ask — так точно: А2 это же его входной буфер!) Но такая строка всего одна.

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

не лучше.

И наконец возможность хранения любого числа текстовых строк — под видом

строк программы. (Грамматику которых оказывается никто никогда не проверяет.

Только во время выполнения.) И обработка с помощью форматного механизма

оператора Write %. Плюс регистры этого самого форматного механизма...

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

образовалось СРЕДСТВО РАБОТЫ СО СТРОКАМИ. Но совсем не такое, как

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

средств работы со структурами данных.)

Как такое получилось? Как набор побочных эффектов при доработке операторов

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

разных всяких нужд... В частности:

Ask Х, Y... — (штатное использование оператора Ask — ввод чисел)

Ask % — делает А2 пустым

Ask — вводит строку в А2 из канала ввода (но не использует)

Write N_стр — (штатное использование оператора Write — вывод программы)

Write % 1 — выдаёт строку из А2 в канал вывода

Write %YYY 0 — преобразует строку в А2 в соответствии с выражением YYY

! — подставляет строку из А2 туда где допустима "..."

Mod N_стр — (штатное использование оператора Modify — редактирование)

Mod N_стр = N2 — (в форме "с присваиванием" — перемещение строк программы)

Mod N_стр = ! — копирует А2 в память программных строк

Mod ! = N_стр — копирует программную строку в А2

Mod ! = "...." — запись константы в А2

Mod N = "...." — запись константы в указанную программную строку

Mod "ком_стр" — выполнить командную_строку (или поместить в память)

Mod ! — -//— но взятую из А2

FCHr(-1) — (штатное использование функции FCHr — ввод )

FCHr(c,d,...) — ( -//— и вывод )

FCHr() — вернуть назад 1 байт и сообщить сколько осталось

FCHr(,N) — -//— N байт (передвинуть маркер в любую сторону)

FCHr(,) — сообщить сколько байт уже использовано (т.е. до маркера)

FCHr("А") — выдаёт код буквы "А"

FCHr("АБ",c,d, ) — -//-, остальное — в аккумулятор

Указатель текущего символа в А2 (он же "маркер") фактически делит его на ту

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

FCHr(-1) читает байты непосредственно из канала ввода только если А2 пуст.

Иначе — из него, сдвигая маркер. Но может подвинуть и в другую сторону.

И вообще переставить куда угодно и/или определить местоположение. И может не

только читать символы из А2 но и записывать...

Читает строку в А2 оператор Аск (т.к. это его входной буфер), но сам же и

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

А2 — пуст. (Однако это — не проблема: A %) Выдаёт наружу оператор Write

"с форматом", а сохраняет в памяти программных строк и загружает оттуда

обратно в А2 — оператор Modify "с присваиванием"...

Которые все исходно были предназначены для чего-то совершенно другого...

Например A %; чистит А2 чтобы ввод следующего числа был точно со следующей

строки...


* * *

Миграция формата из Type в другие операторы ввода/вывода. А так же его

мутация в "спецформат" %% и %%% — ради специфических нужд, в основном

связанных терминалом. Вернее с редактором командной строки и просмотрщиком.

Ask %NN — (где NN — цифры) — ограничение ширины поля ввода — чтобы

совместно с ф-ей FКурсор, перемещающей курсор по экрану, вписывать что либо в

поля некоторой нарисованной на экране таблицы так, чтобы вводимый текст не

вылезал за пределы этого поля. (Примечание: аналогично ограничить поле вывода

для Type — с помощью "окна вывода", задаваемого функцией FViz.)

Ask % — сделать А2 пустым, чтобы следующее вводимое число было заведомо

с новой строки

Ask %% — -//— плюс режим формирования в А2 "начального значения"

Ask %%% — то же, но добавление к содержимому А2

"Начальное значение" — чтобы сидящий за терминалом человек мог не набирать

это целиком, а либо просто согласиться, либо малость отредактировать. (Нет,

стереть, нажав ESC, и набрать с нуля он конечно тоже может...)

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

точности как оператор Type (до конца оператора или до !), но сформированный

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

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

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

буфер. А упомянутый указатель всё время остаётся в его конце. А то Ask

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

ему больше не удаётся найти в А2 ничего, похожего на выражение. В том числе

если он пуст. А если нет — чистит. А тут — "не догадывается": он же уже

ВЫГЛЯДИТ пустым... Спецформат %% как и % очищает А2, а %%% — нет (только

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

помещено в А2 ранее.

Планируется распространить действие %%% за пределы оператора (и отменять его

только принудительно), а то исторически так сложилось, что некоторые функции

(например FTELL) свой текстовый "побочный эффект" (в данном случае — имя

найденного файла) помещают, как и полагается, в А2, а некоторые (FTMP) — сразу

в канал вывода... И ломать это — нецелесообразно...

Спецформат %% в операторе Type предписывает подключить (при выводе на

терминал) встроенный просмотрщик (см. далее). А спецформат %%% еще и

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

табулостопа. Но сейчас устарел и отменен: нынче это делается по-другому.

(См. табулостопы.) И теперь планируется задействовать безработный спецформат

(по аналогии с таким же в Ask) для включения буферизации вывода. (Еще не

реализованного.) Это когда выводимые символы сначала накапливаются в отдельном

буфере, а выводятся все разом по Type !. Что даёт, в частности, возможность

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

дальнейшем присвоения этим полям не только номера но имени и типа — как у полей

записи реляционной базы данных...

Write % копирует строки из канала ввода в канал вывода (см. далее). В том

числе, если с терминала, то Write %NN как и для Ask, тоже ограничивает ширину

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

Но каждый следующий оператор Write обнуляет его счетчик выведенных на терминал

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

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

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

принудительно: W %%% N;.


* * *

"СКРИПТОВОСТЬ" И САМОМОДИФИКАЦИЯ

Возможность выполнять программу не заранее загруженную (некоторым образом)

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

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

была у Фокала всегда. Изначально. Достаточно переключить на этот носитель

канал ввода: Фокалу без разницы откуда поступают командные строки. (Терминал и

клавиатура "выделенные" только в плане ошибок.) С появлением средств

позиционирования файла (см. выше), появилась и возможность управления порядком

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

переходов к ним — условного и безусловного. А также "к подпрограмме" — с

сохранением адреса возврата.

Эти фокусы-покусы с файлом, программа из которого в данный момент и

выполняется, возможны, и при том совершенно безопасны, из за упомянутой в самом

начале "строчно-ориентированности" Фокала. Заключающейся в том, что за раз он

всегда читает командную строку целиком. И хранит в некотором входном буфере.

А использует (выполняет) — по-операторно. Так что пока эта строка не кончилась

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

откуда она была прочитана) что угодно.

Но поиск в командном файле метки — только путём прямого его просмотра

(чтения всех строк подряд, пока не встретится) и представляет собой проблему.

Которая, впрочем, элементарно решается с введением формата % в оператор Write.

(См. далее.)

Подгрузка частей программы по мере необходимости (и удаление уже ненужных)

тоже были в Фокале изначально. А вот возможность "самомодификации" -

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

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

возможность перемотки в начало. (Впрочем, это могла быть и магнитная лента.)

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

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

чего снова перематывает его на начало; переключает на него канал ввода и

останавливает программу оператором Quit. В результате управление получает

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

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

по-новой запускающая программу с нужного места.

Этот приём, хотя и имеет ряд недостатков, продолжает оставаться вполне

действенным. Однако, уже не единственно возможным (см. Modify "...").

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

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

обучающих и демонстрационных программах...

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

вещи (как тот же формат в операторе Type) где допускаются только константы, а

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

программы...


* * *

Оператору Write дополнительно поручено копировать строки из канала ввода

в канал вывода. (Через А2.) Вот как раз чтобы из командного (скриптового) файла

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

снабжая собственным оператором Type. (А то больно уж набирать такое муторно.)

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

его преобразованием. (Например — в другой кодировке...)

Write %формат

или даже Write %формат, N, "метка"

"Формат" может быть и пустой (состоящий из одного символа %) тогда строчки

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

копированию строк, а если отсутствует — до конца файла. Текстовый аргумент

указывает "метку": если он есть, эта метка ищется в каждой очередной строке.

И если найдена — работа оператора завершается. (А строка так и остаётся в А2.)

Этот механизм вполне пригоден так же и для передачи управления к метке в

пределах командного файла. Метка должна быть в строке, предшествующей той,

которой надо передать управление. (И оформить её можно как комментарий.)

А копирование ведётся на имеющееся в операционной системе устройство nul, где

бесследно исчезает любая информация:

O "nul" zw; C открыть устройство nul в самом начале командного файла

........

O zw; O ar; O (0) a; W % "==м1=="; O t; C аналог оператора Goto ==м1==

Здесь предполагается, что командный файл открыт под псевдонимом А, и что

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

перематывается в начало.

Если спешить особо некуда — всё это вполне приемлемо. Но для ускорения дела

лучше один раз в самом начале найти все метки, запомнить их положение в

переменных, а потом сразу позиционировать файл к нужному месту.

Можно обойтись и без устройства null, написав: W %! "метка";.

Копирование строк идёт через А2 (входной буфер оператора Ask). Если он не

пуст, то W % 1; просто выдаст его содержимое в канал вывода, а W %ф_выраж 0;

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

к текущему содержимому А2 (даже в том случае когда А2 пуст).

Так как W % "метка"; оставляет строку с меткой в А2, то перед следующей

аналогичной операцией надо не забыть очистить его: Ask %.


* * *

ВСТРОЕННЫЙ ПРОСМОТРЩИК — аналог UNIX`овского more, вообще-то

принадлежность оператора Help. Но автоматически подключается и при выводе на

терминал текстов оператором Write, включая и W %;. (А вот для оператора Type

для этого надо использовать спецформат %%.)

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

вывод, нажав ESC. И работа оператора завершится. Обнаружить сей факт можно,

посмотрев (с помощью FTEll(1)) — что в буфере клавиатуры? Когда он пуст — там

ноль. Но после нажатия ESC в просмотрщике там будет -1 (что, впрочем, тоже

означает что он пуст).

Если вывод текста идёт прямо из командного файла:

W % "метка2" ; C очередная командная строка

.....текст...................................

..............текст..........................

...................всё еще текст.............

метка2


* * *


* * *


* * *


* * *

; C следующая командная строка

то до следующей командной строки он в результате "не дотянет". Надо написать:

W % "метка2"; If(FTEll(1)),0,0; W %! "метка2";

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

Но строка то с меткой застряла таки в А2? Значит проще можно:

W % "метка2"; W %! "метка2";


* * *

Оператору Modify дополнительно поручено... Ну, то есть кроме формы:

Modify N_стр — с числовым аргументом, ввели форму:

Modify текст — с текстовым, где может быть и "..." и ! и :N

Modify N_стр = N_стр2 — а так же форму с присваиванием

Modify N_стр = текст — или даже:

Modify N_стр = N_стр2, текст2 ,... — чтобы дополнить строку

Modify ! = ..... — чтобы поместить это в А2

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



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