Предыдущая глава |
↓ Содержание ↓
↑ Свернуть ↑
| Следующая глава |
Но выглядеть это должно: Write %_%Xy; потому что спецформаты %% и %%%
успели и в оператор Write мигрировать! Да и Write %Число тоже что-то такое
значит, по-этому лучше бы: Write %_Число или Write %+Число...
Отвлечемся на секундочку:
— мы же говорили, что везде, где по смыслу требуется число, в Фокале допустимо
выражение. Даже когда ввода ожидает оператор Ask... А вот тут что — не число
разве? Константа!
— ну так это и есть "таинственная конструкция формат", однако.
— да, но всё-же... Вот если это самое число (что бы оно там ни значило) мы
получим только в процессе вычислений?
— да, нехорошо получается... Однако вот как раз для этого и есть такая вещь,
как "самомодификация" — хорошо, что мы наконец о ней вспомнили...
В общем получается, что параметр "определяемым пользователем" аналогам
подпрограмм %N и %{:NNN} достался чисто "за компанию" — исключительно ради
соблюдения принципа, что если что-то можно кому-то то можно и всем. Далее,
заметим, что префиксы + и — на % не действуют. (Чисто потому, что я так и не
придумал, как передать в подпрограмму факт наличия перед ней такого префикса.
Параметр-то этот, и то со скрипом...) Поэтому встроенное преобразование Х в
форме -Х и +Х можно примерить к тому что и до и после маркера, а %Х — нет.
А к перекодировкам мы еще вернёмся...
Конструкции #{...} и ={...} — форматные преобразования.
— еще более форматные, чем те форматные выражения, коие щас рассматриваем?
— ага!
Преобразуют число, вычисленное заключенным в {...} выражением в его
текстовое представление и обратно. Когда обратно — помещает в указанную в
={...} переменную. Там же вслед за ней должен (может) быть формат, указывающий
как это сделать. (Если нету — используется тот, что и в операторе Type.)
Организованный на Си-шный манер — как в ейных функциях printf() и scanf():
% ширина_поля буковка. (Без пробелов, естественно; "буковка" — одна буква, а
"ширина_поля" — числовая константа, состоящая из циферок. Буковка: d i o u x
для целых чисел, e f g — для плавающих, c s — пока ровно один байт: ширину
игнорирует. (А зря-а-а!)
Вообще-то у нас такими вещами оператора Ask и Type занимаются. Но что
делает например Ask? Берёт (да — тоже отсюда) ВЫРАЖЕНИЕ и вычисляет его!
Причем выражение это должно быть грамматически правильное. А все константы в нём
исключительно десятичные... (Ну калькулятор-же!) Ага. А в его аналоге ={...}
выражение нельзя, но за-то можно и восьмеричное число и шестнадцатиричное...
Подробнее — грамматику см. <<Ш>>
Сейчас надо наконец закончить с форматными выражениями. И тогда можно будет
вернуться и к перекодировкам (т.е. к встроенным преобразомваниям) и к
упоминавшейся "самомодификации"...
Там и осталось-то: . и !
— потому что все остальные символы уже использовали?
Ну в самом деле: пробел, запятая и точка с запятой — табу! Кавычки и
цифры — для изображения констант. Буквы — под будущие "встроенные"
преобразования. Плюс и минус — префиксы, * и / основные операции; ^ и $
перемещение в начало и в конец строки; = и # установить и применить; круглая
"Абезьяна" (она же "сАбака") — @ префикс повторения, & ? постфиксы (провека
условия). Подчеркивание _ аналог пробела, надчеркивание ~ (она же "тильда") -
установка размера маркера; процент % известный своей склонностью устраивать
заговоры, тайные общества и прочие форматы — и тут чем-то подобным занимается
(вот сейчас только обсуждали); скобки... А вот скобки, в отличии от кавычек,
все используются по-разному: круглые () для группировки операций в одну
составную; фигурные {} для заключения в них фокаловских выражений, квадратные
[]... Вот квадратные пока что зарезервированы на будущее. (На них обширные
планы, хотя пока что весьма и весьма туманные...) И наконец угловые <> которые
по сути своей и не скобки вовсе, а скорее кавычки-"ёлочки" (остальные -
"лапки")... Вот как раз в таком качестве (4.6) к делу и пристроены...
Ну так что осталось? Да, всего четыре символа . : ! | (если не считать
некий "забой", ввести который — затруднительно, а использовать — стрёмно).
Восклицательный знак: "прекратить немедленно!". Завершить выполнение форматного
выражения (а с префиксами — и всего оператора), при чем вывод вот этой строки
отменяется. Точка — всё наоборот: вывести текущую строку и продолжить дальше.
Символ | планируется использовать для возврата конца строки — на случай если
вдруг ввели слишком много: вот есть у винды такое уже упоминавшееся неприятное
свойство — делать сверхдлинные строки с целый абзац размером... А символ :
(двоеточие ) — так же как и в операторах ввода/вывода для перехода к другому
полю... Но пока что оба — резерв главного командования.
Ну-с, с форматными выражениями практически всё — всё готово к пришествию
встроенных преобразований и шаблонов.
* * *
А в это время в замке у шефа...
В смысле в самом Фокале...
В самом Фокале вдруг осознали, что кроме "..." оказывается есть еще две
конструкции, которые в операторах ввода/вывода Ask и Type тоже считаются
строчными константами: ! обозначающий конец строки и тихой сапой пролезшее туда
двоеточие, предписывающее переход к следующему полю... Вернее табулостопу,
каковые вдруг завелись, чтобы оператор Write со вторым ключевым словом Set мог
выдавать значения переменных в несколько колонок. (А то по одной штуке в
строке, да еще когда их много — типа массивы какие ни будь...)
Вернее осознали не само их наличие (тоже мне новость!) а что таки есть куда
их запрячь: обозначать аккумулятор А2 и регистры форматного механизма :цифра.
(Как мы видели, в самом форматном механизме всё наоборот: :NNN это одна из
строк программы, правда только в {...}, а регистры: #N и =N. Но там-то они
как раз доступны непосредственно...
Вспомним, что нынче текстовые константы могут быть не только в Ask и Type,
но и еще в некоторых других операторах. (Начиная с Operate.) А так же могут
передаваться как параметры некоторым функциям — тем, которые "знают" что с этим
делать. Ну так теперь всем им можно не только "..." передать, но и содержимое
А2 или регистра.
И за одно, чтобы служба мёдом не казалась, добавили оператору Write
ключевое слово Reg — чтобы сообщал: а что это у нас сейчас в этих регистрах
находится? (А то делать что либо вслепую... Неправильно это!)
За одно, ему-же, и оператору Eraze — тоже аргумент в виде текстовой
констаны ("..." ! :N) чтобы сообщали/удаляли не все переменные разом, а токмо
вот этой вот якобы константой указанные.
(4.5)
А оператору Modify (который теперь можно смело называть "Move") сделали
форму "с присваиванием": чтобы он мог перемещать программные строчки из одной
группы в другую. А за одно между регистрами и аккамулятором А2, или например
записать в любое из них текстовую константу (буде она справа от знака =).
Потому как вдруг обнаружили, что программные строчки от любых других строк
ровно ничем не отличаются. И их грамматика проверяется только и исключительно в
процессе выполнения. А в остальное время там можно хранить абсолютно всё что
вздумается. Хотя вот пока только и исключительно "печатное". А то попадётся
байт с кодом ноль — и привет: все будут думать, что строка на нём кончается.
(Так что и в этом смысле пресловутый уникод — вещь предельно похабная: любой
пробел включает байт с кодом ноль.)
Кстати, ему (оператору Modify, а не уникоду) и без присваивания разрешили
использовать аргумент в виде текстовой константы — так же как и операторам
Eraze и Write. Но если для Eraze и Write таким образом указываются имена
переменных — чтобы не все скопом удаляли / выводили на печать, а только
указанные, то оператору Modify, занимающемуся вообще-то говоря редактированием
строк программы... И чтобы вдруг текстовая константа (которая нынче и не
константа вовсе) — дело пахнет керосином! Заговором! Самомодификацией!
Впрочем, предлог был совершенно невинный — всё дело, мол, в отладчике.
Встроенного отладчика в Фокале небыло никогда — за ненадобностью. Каждая
строчка и без того "естественная подпрограмма". Запускай их поштучно
оператором Do и смотри, что они сделают. А чтобы посмотреть, куда оператор If
передаст управление — есть "трассировка". Включается (и выключается)
оператором ? (вопросительный знак).
Гладко было на бумаге...
Вернее вот как раз на бумаге (когда терминалом была пишущая машинка) весь
этот неудобочитаемый результат трассировки, можно было, оторвав этот листок
(длинною метра полтора) и разложив на столе, анализировать со всеми удобствами.
В том числе писать на нём всё что вздумается, стрелки например на выведенном
туда же тексте программы, как на карте рисовать: "айнэ колоннэ марширт рейхс,
цвайте колоннэ марширт линкс!...", или например выделять интересные места
цветными маркерами...
Твёрдая копия — великая вещь! Но бумаги не напасёшся. И шумно.
Но с пришествием дисплеев стало с этим делом как-то совсем кисло. На экране
маненький кусочек бумажного листа помещается. (Ну что такое — 24 строчки?!)
И не напишешь ничего, и даже руками не потрогаешь — только глядеть... И, глядь,
всё интересное, не успеешь оглянуться, уже уползло за край экрана!
(Надо бы конешно сваливать трассировочную информацию в файл — вот второй
в командной строке как раз для этого: под протокол. Но вот как-то до сих пор
не.)
Выход — вот этот вот "пошаговый режим" (включается — ??) — та же самая
трассировка, но на выполнение следующего оператора Фокал ждёт разрешения от
пользователя. Впрочем я сделал, что он сначала выводит текст оператора, потом
ждёт и только дождавшись — выполняет. (Мне так показалось логичней.) А еще я
сделал возможность ввести и выполнить командную строку. "Прямую". Чтобы
например посмотреть значение переменной. Распечатать кусочек кода. Или даже в
хелп заглянуть... (И включаемое оттуда же "отладочное окно" — чтобы этим
изображение на основной части экрана не портить...)
Но в отличии от диалоговой части интерпретатора, нумерованных строчек там
вводить нельзя. Не понимает оно такого авангардизма. Поправить уже
существующие строчки и с помощью Modify можно. При этом можно даже номер
строки изменить. Но добавить новую — увы. Вот и пришлось сделать из оператора
Modify полный аналог диалоговой части интерпретатора...
Но теперь с помощью этой фичи программа может править сама себя!
Смертельный номер! Русский самоубийца! Только у нас! Только один раз!
(Или что там еще кричат цирковые зазывалы в подобных случаях?) Но и в самом
деле самомодифицирующийся код это эффектно, эффективно, смертельно опасно.
При том, что возможность для самомодификации программ была в Фокале всегда.
Изначально. Но при отсутствии перезаписываемых и перематываемых внешних
носителей (а это хотя бы магнитная лента) ограничивалась тем, чтобы подгрузить
заранее написанный код. Для этого надо переключить канал ввода на содержащий
его носитель и остановить программу. Управление получит диалоговая часть
интерпретатора и всё это сама собой подгрузит. Но там в конце должна быть
прямая команда чтобы запустить программу по-новой.
А при наличии файловой системы уже на уровне (1.1) даже при отсутствии
позиционирования, можно было окрыть файл на запись, записать туда нужные
команды, добавить прямую строку для повторного запуска, закрыть и открыть на
чтение. После чего тоже переключить на него канал ввода и остановить программу.
А вот теперь даже внешний носитель без надобности.
Зачем нужен этот цирковой фокус? А вот для тех самых (уже немногих)
оставшихся случаев, когда (увы-увы) в программе должна быть именно константа.
Например завершить работу интерпретатора находящаяся в памяти программа
никак не может: для этого надо выполнить Quit из прямой строки, а у неё — все
косвенные. А вот теперь — пожалуйста: 10.7 Modify "Quit"
Чуть более сложный случай: установить формат для оператора Type — %N.M где
N и M не константы, а числа, находящиеся в переменных с такими вот именами:
Ask %% "Type %", N, ".", M; Write %^ 0; Modify !
Здесь мы воспользовались спецрежимом оператора Ask, предназначенных для
формирования "начального значения" для предъявления пользователю. В котором он
работает в точности как Type, но весь вывод попадает не в канал вывода а в А2.
Однако, маркер при этом всё время в конце, все символы в А2 — как бы "уже
использованные", а сам он — выглядит пустым. Поэтому мы сначала сдвигаем
маркер хотя бы на одну позицию назад (а в данном случае ставим в начало А2) и
только потом используем как текстовый аргумент в операторе Modify, который это
и выполнит.
Обратим внимание на нелепость пресловутой "опоры на естественный язык". Нет,
для самых-самых начинающих это еще имеет смысл — при условии что это их родной
язык, а не хрен знает чей. Далее оно только мешает. А в данном примере
целенаправленно вводит в заблуждение: оператор "Ask" здесь ни у кого ничего не
спрашивает, "Write" никому и ничего не сообщает, "Type" ничего не печатает, а
"Modify" соответственно ничего не модифицирует. Гораздо понятнее в данном
случае будет, если написать: A %% "T %"N'.'M; W %^ 0; M !
Наблюдая этот цирк, мы проглядели самое интересное: теперь у нас,
оказывается, есть переменные не только для чисел но и для строк. Правда
напрямую из форматного механизма записать туда ничего нельзя (ибо нефиг!),
только с помощью оператора Modify (он же Move). Но ничто нам не мешает с
помощью FSBr... (См. выше.)
* * *
О кодировках символов и встроенных преобразованиях для оных
Буковки, циферки и прочие знаки препинания для машины — просто числа
(коротенькие целые), а картинки — изображения буковок, которые мы и видим на
экране или на бумаге, просто этими числами пронумерованы. Способов, которыми
нумеруются буковки — превеликое множество. Для каждого языка выдумана свой
собственный. И часто не один. Для русского — штук пять или шесть. Вот они то и
называются "кодировками".
(Не путать кодировки со шрифтами! Разные шрифты это разные картинки для
одной и той же буквы, а разные кодировки — разные числа для её обозначения.)
Та, которую использует Фокал это 866-я или "ДОС`овская" кодировка.
(Далеко не лучшая, но зато в ней есть все символы псевдографики.) Еще
постоянно приходится буквально запинаться об "виндовую" — 1251, и так
называемый "уникод", которого к тому же еще и несколько разновидностей.
Предыдущая глава |
↓ Содержание ↓
↑ Свернуть ↑
| Следующая глава |