| Предыдущая глава |
↓ Содержание ↓
↑ Свернуть ↑
| Следующая глава |
Хотя здесь надо иметь в виду способ отображения всех этих символов на
экране. Если он графический — то как указано выше. Если же текстовый (то есть
выводится только код символа, а в знакогенераторе должно быть энное количество
картинок для каждого из таких кодов) — то таки придётся выделить пару страниц
под расширения латинского алфавита.
(Примечание: что-то не видно, чтобы ИСО, сооружая свой пресловутый
стандарт ИСО-8859 заботилось вот о таком отображении символов: нефига было
пихать всем дополнительные 32 никому не нужных управляющих кодов — глядишь,
для латиницы не 10 кодировок бы понадобилось а одна, ну максимум две.)
Упоминавшийся "курсив", он же "системный алфавит" (типа чтобы командовать
операционной системой — алфавит по-умолчанию) построенный по "типографскому"
принципу, так же как, например, уже упоминавшиеся УПК и ДКОИ: русские буквы и
плюс к ним не совпадающие с ними по написанию латинские. Русские буквы в первой
половине страницы — как "основные", а все остальные (начиная с буквы Ё) — во
второй как "дополнительные". Но по "фонетическому" принципу: В-V а не W!
Осталась масса свободных позиций, куда можно поместить буквы "с элементами":
эсперантские "со шляпами", немецкие "с умляутами" плюс "гросе-ЭС; некоторые
буквы из телеграфной азбуки: N E A-с_кружочком (уж коли они там удостоились
отдельных позиций, значит и в самом деле кому-то реально нужны).
А если сделать еще и маленькие курсивные буквы, то вместе с нулевой
страницей и псевдографикой получится вполне себе самодостаточная восьмибитная
кодировка. Но с проблемами. Во-первых дополнительные маленькие буквы не совсем
такие-же как заглавные:
v d ё z i j k l r s t f h q w
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я
V G Ё Z I J L N R S U F Q Y W
о гр. ^ ^ : ^ ^ ^ ~ ' : :
А Эс G J O H C S N E U A
А во-вторых с одной стороны всё равно остаются незанятые позиции (но занять-то
их придумаем чем — например некоторыми из букв греческого алфавита), при этом
на одну позицию претендуют сразу несколько символов. Позиция буквы Ж в
Эсперанто это J-со_шляпой, но Z-со_шляпой было бы логичнее. (Хотя вот как раз
это — вопрос шрифта а не кодировки!) И сюда же (вслед за телетайпетной МТК-2)
обычно относят букву V, а W — на место В-русской, что по-моему неправильно.
Вот только приткнуть эту самую лигатуру W получается реально некуда. И в
позицию буквы Д так и просится G-со_шляпой, обозначающая звук ДЖ, но тогда
некуда будет приткнуть букву Д-маленькая_латинская, таки отличающуся от
русской по написанию. По поводу Н-со_шляпой и мелкой латинской h — то же самое.
Так что придётся пойти на ряд компромисов: сделать написание Д-строчной
русской такое, чтобы её можно было принять и за Д-строчное латинское, а не как
рукописное, совпадающее с G-строчной латинской. Соответственно такую букву
поместить как парную к Г-маленькой. Парной к Д и большой и маленькой ДЖ в виде
G со шляпой. Эсперантскую h-со шляпой, обозначающую непридыхательную Х
совпадающую по звучанию с русскою, так и придётся перенести в позицию мягкого
знака. Выселив оттуда лигатуру W. Её так уж и быть сохраним — в основном чтобы
строчная изображала за одно и букву омега, но перенесём в позицию буквы Ц.
А в качестве эсперантского У-краткого придётся использовать У-с_умляутом.
(Впрочем, это тоже вопрос шрифта: двоеточие там или черточка.) И получается:
| v g | ё | z i j k l | r s t f h w | | q | | | | |
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я
| | V G | Ё | Z I J L N | R S U F W | | Q | Y | | | |
о гр. ^ ^ : ^ ^ ~ ^ ' : :
А эс G J O C S N H E U A
Итого остаётся 11 свободных позиций. Куда можно поместить буквы альфа,
(где Б-строчное), бета у нас уже есть, гамма (где К-заглавное), дельта, мю, ню
(где М и Н-строчное), пи, ро (где буква П), омега-большое (где Х-заглавное),
фи (на пару к букве У-строчное) и еще что ни будь (например сигма) на пару к Ы.
И еще у этого "курсива" — проблема с преобразованием в другие кодировки,
где русские и латинские буквы — раздельные. Впрочем, такая же в точности как
у ДКОИ и УПК. Ну да с ним нам не детей крестить... И вообще, это пока — так,
мысли вслух.
Конец лирического отступления.))
Однако, вернемся к нашим баранам: одной только базовой кодировки мало,
нужен еще и инструмент для её использования. Который бы что-то делал с
символами, рассматривая их как битовые наборы и/или беззнаковые целые.
Соответственно "что-то" это операции арифметические и побитовые. И разумеется
желательно, чтобы набор этих операций был функционально-полным.
Вот для этого и приспособили %r. Реверс — вещь не больно то нужная. Вот и
нечего фигнёй страдать — пусть займётся чем-то более полезным. И уж коли ему
таки положен аргумент — пусть это и будет операция. А он пусть выполняет её
последовательно над каждым байтом фрагмента под маркером... Ага-ага, а ничего,
что у большинства операций по два операнда? И что промежуточные результаты, в
том числе как символ уникода так и во внутренней кодировке, которую вот только
что обсуждали, будет размером более восьми бит? Это я к тому, что для %r нужно
место, для хранения вот этих вот операндов и промежуточных результатов.
По-моему тут идеально подойдёт примерно такой-же стэк, какой был у советского
программируемого микрокалькулятора Б3-34 (или МК-56). Всего четыре ячейки, но
хватало. И тут, думаю, хватит. Так что основная тактика — считать очередной
байт на стэк, что-то там с ним сделать и вернуть взад. Или, например, добавить
к содержимому регистра... Но это не одна, а несколько операций. А что нам
мешает передать %r несколько, заключив их в скобки или в кавычки?
Но у нас ведь куда конь с копытом, туда и рак с клешнёй: %R которому тоже
делать особо нечего, тоже пожелал во всём этом поучаствовать! Только возиться
с каждым из байтов, как %r, ему в лом (слишком вишь мелко, для такого
солидного!) — хочет чтобы со всем фрагментом одним махом, рассматривая его как
единое число или битовый набор. В результате получилась арифметика
неограниченной точности, правда пока только целочисленная. (Но, например,
чтобы поэкспериментировать с кодами Рида-Соломона — уже достаточно.)
Набор операций и для %r и для %R практически один и тот же: включает
арифметические и логические (вернее побитовые) операции и выполняется над
числами, снимаемыми с вершины собственного операционного стэка. И туда же
помещается результат. Но для %r его ячейки — это просто целые числа, в
данный момент 32-х разрядные, а для %R — аналог регистров форматного механизма,
содержащих многобайтные значения неопределенной длины.
Каждая операция тоже (как правило) обозначается одним символом:
, . ; -чтение, запись и обмен с фрагментом строки под маркером
[ ] : @ -дублирование, удаление, обмен пары и черырёх ячеек стэка
& | ^ ~ -побитовые операции И, ИЛИ, исключающее ИЛИ и инверсия.
+ — * / -арифметические операции. Деление даёт сразу и частное и остаток.
^ $ % -лентяйская арифметика — без переносов (якобы "с полиномами")
Но некоторые — таки двумя символами ( < > = # приходится уточнять):
N -циклический сдвиг на 0..9 разрядов (N — одна цифра);
<< >> -нециклический сдвиг на указанное первым аргументом число битов
< <= > >= = <> >< -"предикаты": сравнивают две верхние ячейки стэка
#N =N #X =X -(где N — цифра, X — буква) чтение/запись регистра и переменной
`А -ввод константы — кода указанного символа (кавычка — любая)
А так же и константы в виде числа:
NNN 0xNNN 0oNNN 0bNNN -в 10-ой, 16-й, 8-ой и двоичной системе счисления
Однако спецсимволов мало, пришлось пустить в ход и буковки. Уже известные:
б д в к и у -преобразовать операнд из указанной буквой кодировки в И-64
Б Д В К И У -преобразовать из И-64 обратно в указанную (Б — в текущую)
u U -прочитать и записать один символ уникода
(впрочем — всё это только и исключительно для %r)
Но так же и:
r R -сгенерировать и поместить на стэк псевдослучайное число
ч х (или 'h') -определить четность и вычислить код хеминга
л -получить размер ненулевой части операнда (в байтах)
m -создать "маску" из указанного операндом количества единичных битов
i -получить индекс (номер) текущего байта в обрабатываемом фрагменте
l -получить количество оставшихся байт (то и другое — только для %r)
i N -получить и установить "номинальный" размер операнда (только для %R)
l L -получить и установить размер операнда (в байтах) (только для %R)
А а -запись текущего значения в числовой аккумулятор А1 и чтение из него
F f -запись логического результата предыдущей операции в А1 как -1 0 +1
Дело в том, что предикаты, не изменяя операндов, вырабатывают некий
логический результат — "статус", как-то действующий на следующую операцию.
Впрочем, большинство операций его игнорирует, а сами вырабатывают
"нейтральный". Но вот следующие:
M S -константы ("младший" и "старший") дают отрицательный и положительный
p n c -операции ("позитив", "негатив" и "циклатив") — изменяют
? -выполняют или пропускают следующую за ними операцию, (или группу)
( ) -заключают в себе группу операций; для статуса "прозрачны" (не меняют)
{ } -цикл: { запоминает место; } переход к запомненному. Баланс, в отличии
от круглых скобок — не отслеживается: цикл может быть только один.
! -немедленно прекращает выполнение последовательности операций (для %r
только для очередного байта и провоцирует переход к следующему; чтобы — совсем,
надо совершить серьёзную ошибку, типа деления на ноль)
Как видим — имеются даже некоторые средства управления порядком действий.
Это не всё — но за кадром осталась еще буквально парочка операций.
Логические константы M S происходят от слов "младший" и "старший" потому
что влияют еще и на следующее непосредственно за ними обращение к регистру
=N и #N организуя "вагонку" — не замену или считывание целиком находящегося в
регистре значения, а аналог действий с железнодорожным составом, формируемым
путём добавления или удаления вагонов с обоих его концов.
Так, а мы еще не забыли за всеми этими разновсякими операциями — о чем
вообще шла речь?!
А вот о чем: есть у нас в Фокале оператор Write (от слова "врать", откуда
кстати и "врун" и "врач") — ну типа скажи-ка нам что ни будь такое-эдакое...
И правда специализирующийся на сообщении нам разной всякой полезной информации,
начиная с хранящихся в памяти программных строк. При чем в такой форме, чтобы
можно было всё это потом обратно ввести... И вот свалили на него еще и из
файла строчки выдавать... С некоторым их "на лету" преобразованием — якобы для
пущей удобочитаемости. И наобещали наделать для этого встроенных форматов,
каждый из которых будет обозначаться одной буковкой. (А то, например, развели
кодировок, отличных от ДОС`овской — поди прочитай...) Ага-ага: "обещанного три
года ждут"? Если бы только три... Но тем не менее в конце концов... А пока,
чтобы сильно не плакал, сделали для него парочку операций (коие и составляют
"форматное выражение") типа вставить/удалить кусочек строки. А перед этим
выделить... Ну или найти... И вот через некоторое время завелись у нас там
"шаблоны" (они же "регулярные выражения") чтобы указать что ищем — не только
константой "...", но и неким более общим образом. (Впринципе <...> это тоже
типа кавычки, только не "лапки" а "ёлочки"...) А потом, когда наконец
появились некоторые из давно обещанных "встроенных форматов", одному из них
(%r — "реверс") поручили дополнительную работу — выполнять над кодами
символов арифметические операции. А его старший братец %R — сам влез...
* * *
Ну и как же всё это использовать? А вот (уж коли всё это уже реализовано)
давайте в качестве примера нарисуем такие же картинки как выше — для нулевой
страницы И-64 и ASCII а так же для псевдографики. Включая рамочки символами
псевдографики. Проверим, а в самом ли деле оно вот так, как выше расписано?
Если только на экране, то рамочки можно нарисовать функцией FKурсор. Но
если потом надо в файл — придётся это с экрана как то считывать. (Ею же!)
Однако сперва нарисуем циферки сверху и слева, а в качестве "основного
содержимого" ну хотя бы числа — от 0 до 63 (из переменной #k):
4.1 f j=0,15; t %3.2 #k'' %; s #k=#k+1; C одна строка
3.6 s #k=0; f i=0,3; t " "i" "; d 4; t !; C все четыре
3.7 r
Второй % в операторе type восстанавливает нам формат по-умолчанию.
Верхнюю строчку можно-бы выдать сразу целиком — в готовом виде:
3.2 t !!" 0 1 2 3 4 5 6 7 8 9 A B C D E F"!!
Но мы не ищем лёгких путей!
3.2 t !!" "; f i=0,15; w %^__~$__*" "__1__*#{i%x}__. 0
3.3 t !! ; ц 1 2 3 4 5 6 7
Смотрим, что мы сделали. Для наглядности я вставил между отдельными
операция по два ничего не делающих _ (подчеркивания), играющего роль пробела.
И в следующей строке-комментарии пометил операции цифрами. Итак: 1 — поставили
маркер в начало А2 (так как неизвестно, где он был до этого); 2 — сделали,
чтобы всё, что сейчас есть в А2, стало "под маркером" — установили его размер
до конца строки (мало ли что там в А2 осталось с прошлого раза); 3 — заменили
всё это на два пробела; 4 — сдвинули маркер на одну позицию (в результате чего
его размер стал нулевой); 5 — вставили туда то, что нам выдала операция 6,
преобразующая значение переменной i в шестнадцатиричное число (по формату %x);
7 — выдали что получилось в канал вывода.
Теперь нам надо рамочку. Из символов псевдографики. Впринципе не проблема.
Можно в готовом виде:
3.3 t ! " ┌────────────────────────────────────────────────┐"!
3.6 s #k=0; f i=0,3; t % " "i" │"; d 4; t "│"!; C добавили две боковые "│"
3.7 t " └────────────────────────────────────────────────┘"!; r
Или мы опять не ищем лёгких путей?
3.9 f i=0,15; t "───"
| Предыдущая глава |
↓ Содержание ↓
↑ Свернуть ↑
| Следующая глава |