VKACL — туториал и справочник

Одна страница со всей книгой · собрано 2026-09-29

О проекте

VKACL — язык программирования, который Виктор Германович Кон (доктор физико-математических наук, Курчатовский институт) придумал в 1991 году, ещё работая на Фортране, и развивает до сих пор. Главной целью с самого начала была быстрая работа с графикой; вычисления, файлы, окна, PDF и всё остальное выросли вокруг неё. Долгое время язык назывался просто ACL, но это сокращение занято многим другим, и теперь автор называет его по имени сайта — vkacl. (Название «МЛЯП» — «мой личный язык программирования» — относится к сообществу во ВКонтакте, а не к языку.)

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

С чего начинать

Автор советует новичкам не начинать с программирования. Сначала скачать интерпретатор и пользоваться готовыми программами — многим этого достаточно. Если что-то в готовой программе не устраивает, её текст открыт, и её можно поправить. Так постепенно и приходит язык.

Поэтому у этой книги три входа:

Если вы хотите… Начните с
пользоваться готовыми программами Начало работы и Готовые программы
писать свои программы Что такое VKACL и дальше по туториалу
найти, как работает конкретная команда Справочник команд

Откуда взяты сведения

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

Что нужно знать сразу

Ожидание Реальность
< и > — сравнения Это минимум и максимум, и они связывают сильнее + и *
Любой текст вне команд — комментарий Только если в нём нет символа #
После команды можно сразу писать пояснение После #c, #d, #v, #e сначала нужен ! — он закрывает их аргументы
Имя команды пишется целиком Значимы первые 1–3 буквы: #pr, #pri, #print — одно и то же

Где взять интерпретатор

Дистрибутив — на странице vkacl: архив vkacl.zip и переносная Java 8 (JRE), которую не нужно устанавливать — достаточно распаковать папку. Подробно — в главе Начало работы.

В этом проекте есть и собственная реализация ядра языка — она запускает примеры прямо на страницах книги (см. Песочница и Реализация на Rust). Графики, окон и готовых программ в ней нет: для настоящей работы нужен интерпретатор автора.

Правовая заметка

Язык VKACL, его интерпретатор, описания и готовые программы принадлежат Виктору Кону. Эта книга — независимое изложение, написанное заново.

Начало работы

Название VKACL составлено из первых букв слов Victor Kohn Advanced Command Language. Устроена система как Линукс: небольшое ядро — интерпретатор языка, написанный на Java, — и неограниченная периферия — программы на самом VKACL. Автор называет их а-программами.

Эта глава — о том, как поставить настоящий интерпретатор и запустить первую готовую программу. Писать код для этого не нужно.

Что скачать

Всё лежит на странице vkacl:

Файл Что это Размер
vkacl.zip интерпретатор и все готовые программы около 10 МБ
переносная JRE 1.8.0_91 Java для Windows, ссылка на странице около 64 МБ
vkacld.zip демонстрационные файлы (по желанию) около 9 МБ

Java нужна любая 64-битная, но удобнее всего переносная версия со страницы автора: её не нужно устанавливать.

Как поставить

  1. Распакуйте JRE так, чтобы получилась папка C:\jre1.8.0_91.
  2. Распакуйте vkacl.zip в любое место — например, C:\vkacl.
  3. Всё. Ничего не регистрируется в системе.

Папку с JRE и папку с программой можно целиком записать на флешку и запускать на любом компьютере. Тогда в bat-файлах нужно поменять букву диска C: на букву флешки.

В папке программы:

Что Зачем
aclp.jar сам интерпретатор
_runp.bat запуск в режиме проигрывателя — для готовых программ
_rund.bat запуск в режиме среды разработки — для своих программ
_runp.sh, _rund.sh то же для Линукса
program.acl программа-меню, которую показывает проигрыватель
pro/ основная рабочая папка; сюда программы кладут результаты
proc/, s/ библиотеки и программы из хранилища
help.txt справка, её показывает кнопка Help

Если Java стоит в другом месте, поправьте первую строку bat-файла:

set path=C:/jre1.8.0_91/bin;%path%
java -jar aclp.jar 2

Число после aclp.jar выбирает режим: 2 — проигрыватель, 0 — среда разработки.

Два режима

Проигрыватель (_runp.bat). Окна среды нет — сразу появляется меню из кнопок:

Кнопка Что делает
Help справка по работе с программой
File выбрать и выполнить любой файл с кодом VKACL
Index таблица номеров готовых программ — выбираете номер, программа запускается
Demo демонстрация
SciPro научные программы
Exit выход

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

Среда разработки (_rund.bat). Окно с меню и редактором: здесь пишут и запускают свои программы. Проигрыватель из неё вызывается клавишами Alt+B.

При запуске открывается чёрное окно

Это окно терминала Java, в которое она пишет свои сообщения. Закрывать его не нужно — но если программа зациклилась и не отвечает, закрытие этого окна надёжно её останавливает.

Что дальше

Готовые программы

Вместе с интерпретатором VKACL поставляется набор из восьмидесяти готовых программ, написанных автором языка Виктором Коном. У каждой есть номер, и каждая делает одну практическую работу: собирает PDF из картинок, рисует график по файлу чисел, делает сайт из текста, режет картинки, ищет слово в файлах и так далее.

Чтобы пользоваться ими, программировать не нужно. Программа открывает текстовый файл с примером входных данных — одной-двумя строками чисел и имён файлов. Вы исправляете пример под свою задачу, закрываете редактор — и программа выполняется.

Автор советует новичкам именно такой порядок: сначала скачать интерпретатор и поработать с готовыми программами, и только потом, когда станет понятно, что они умеют, заглядывать в их код и менять его. Этот раздел — для первого шага.

Описания составлены по сайту автора (aclp-info), по текстам внутри файлов входных данных и по самому коду программ из архива vkacl.zip от 23.05.2026. Там, где источники расходятся, указано, как ведёт себя код.

Установка

Всё скачивается со страницы ACLnews.

Что Зачем Обязательно?
vkacl.zip (≈ 9,7 МБ, версия 23.05.2026) интерпретатор и все готовые программы да
архив JRE 1.8.0_91 для Windows (≈ 64 МБ, ссылка на Яндекс-диск там же) Java, без которой интерпретатор не работает если Java не установлена
vkacld.zip (≈ 9 МБ) файлы для примеров и для кнопки Demo очень желательно
vktot.zip словарь для проверки опечаток в большом редакторе (программа №25) нет

По шагам:

  1. Распакуйте vkacl.zip в любое место, например в C:\vkacl. Установки нет — это и есть вся программа.
  2. Распакуйте архив JRE в корень диска C:, чтобы получилась папка C:\jre1.8.0_91. Именно этот путь записан в bat-файлах. Если Java у вас уже установлена (любая 64-битная), этот шаг можно пропустить.
  3. Из vkacld.zip возьмите две папки: папку 0 положите внутрь папки pro (получится C:\vkacl\pro\0), папку zip — в главную папку программы (получится C:\vkacl\zip). Почти все примеры входных данных ссылаются на файлы из pro/0/, поэтому без этого архива примеры не сработают. (Автор пишет, что можно просто положить сам архив в главную папку — кнопка Demo распакует его сама; надёжнее разложить папки вручную.)

Папку программы вместе с папкой JRE можно записать на флешку и запускать на чужом компьютере. Тогда в первой строке bat-файлов поменяйте букву диска:

set path=C:/jre1.8.0_91/bin;%path%
java -jar aclp.jar 2

Два режима запуска

Файл Режим Для кого
_runp.bat (Линукс: _runp.sh) проигрыватель — окна нет, сразу появляется меню из кнопок для тех, кто пользуется готовыми программами
_rund.bat (Линукс: _rund.sh) среда разработки — окно с меню и редактором кода для тех, кто пишет свои программы

Из среды разработки проигрыватель тоже вызывается — клавишами Alt+B.

При запуске через bat-файл открывается чёрное окно терминала: туда Java пишет свои сообщения. Не закрывайте его. Но если программа «зависла» и не реагирует, закрытие этого окна надёжно её останавливает.

Меню проигрывателя

Кнопка Что делает
Help показывает справку help.txt
File выбрать любой файл на компьютере и «исполнить» его по расширению: файл .acl выполняется как программа VKACL, картинки, сайты, музыка и видео открываются системой, .dat рисуется графиком, .mid проигрывается, остальное открывается в редакторе
Index таблица из 99 номеров — главная кнопка для запуска готовых программ
Demo та же таблица, но программы запускаются с демонстрационными данными
SciPro научные программы автора; каждую нужно отдельно скачать со страницы Depository в папку s
Exit выход

Как запустить программу по номеру

  1. Запустите _runp.bat. Появится меню.
  2. Нажмите Index. Откроется таблица из 99 кнопок. Сейчас работают номера 1–79 и 99; на остальные программа ответит, что они ещё не готовы.
  3. Выберите номер. Откроется редактор с файлом входных данных этой программы. В верхних строках — готовые варианты входных данных, ниже — инструкция автора (она местами устарела; актуальное описание — на сайте и на страницах этого раздела).
  4. Исправьте нужную строку или допишите свою. Поставьте курсор в самое начало той строки, которую хотите выполнить.
  5. Нажмите Esc (или выйдите через меню редактора). Файл сохранится, и программа выполнится с данными из выбранной строки. Если передумали — закройте окно редактора крестиком: программа не запустится, изменения не сохранятся.
  6. Посмотрите результат. Программы пишут файлы в папки, указанные во входных данных, а многие ещё и показывают результат: картинку в окне, PDF или сайт — в программе, которая открывает такие файлы в системе.
  7. Ответьте на вопросы проигрывателя:
    • Wait / Go — «файл готов». Wait — открыть его сейчас, Go — не открывать и идти дальше;
    • Job is done! Continue? — Yes запускает ту же программу ещё раз (удобно подбирать параметры), No — выход из неё;
    • Would you like to run other program? — Yes снова показывает таблицу номеров, No возвращает в главное меню.

Исправленные входные данные запоминаются: в следующий раз программа откроет их в том же виде. Хранятся они в файле idc00.txt в главной папке — строка с номером N относится к программе N.

Как записывать входные данные

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

Одна строка — один вариант. Строк с вариантами может быть сколько угодно; выполняется та, в начале которой стоит курсор. В самой первой строке курсор может стоять и во второй позиции — так он оказывается сразу после открытия файла. Если курсор стоит в другом месте, программа сообщит об ошибке и предложит исправить.

Поля разделяются пробелами. Внутри поля пробелов быть не должно. Там, где нужен текст с пробелами (подпись над графиком, заголовок), пишут символ _ вместо пробела — программа сама превратит его в пробел.

Пути к файлам и папкам. Можно писать путь относительно главной папки программы (pro/1/) или полный путь с буквой диска (C:/photo/, букву — заглавной). Годятся оба разделителя, / и \. Надёжнее относительные пути: в некоторых программах длина пути ограничена (около 40 символов), да и в строке данных короткий путь удобнее. Пробелов в путях быть не должно. Нужен ли разделитель в конце имени папки — зависит от программы, это указано в таблицах.

Пробел в конце строки. После последнего поля должен стоять пробел. Поскольку его не видно, автор в примерах часто пишет после пробела лишнюю букву E: программа её не читает, но видно, что пробел есть. Осторожно: там, где важно число полей, лишняя буква меняет смысл строки. Не ставьте её в программах №2 (обычный режим), 6, 12, 17, 27, 46, 53, 56, 62, 75, 76, а также в многострочных данных №1, 8, 39, 66, где строка целиком — это текст, имя файла или адрес. Подробности — в описании каждой программы.

Многострочные данные. Некоторые программы берут не строку под курсором, а первые строки файла: №1, 8, 10, 11, 12, 13, 14, 28, 39, 49, 50, 57, 66, 78. У них позиция курсора не важна, выполняется только верхний вариант. Запасные варианты держите ниже и при необходимости переносите наверх.

Числовые файлы .dat

Многие программы работают с матрицами чисел в двоичном виде. Такой файл — это просто подряд записанные числа по 4 байта (формат float языка Java, старшие байты впереди), без заголовка. Размер матрицы в файле не хранится: его надо знать и указывать во входных данных. Проверка простая — размер файла в байтах равен 4 × ширина × высота.

Матрица записывается по строкам. Для программ, которые рисуют карты, первая строка файла — нижняя строка картинки.

Перевести текстовую таблицу чисел в такой файл умеет программа №16, обратно — №43. Подробный пример — в разборе №21.

Папки и файлы

Где Что там
главная папка aclp.jar (интерпретатор), bat-файлы, program.acl (меню проигрывателя), help.txt
pro00.txt код всех программ, по одной на строку (строка N — программа N; символ ~ заменяет перевод строки)
idc00.txt ваши входные данные — тоже по строке на программу
idcd00.txt входные данные для кнопки Demo
pri00.txt старая копия кода программ; меню проигрывателя её не использует
runsys.bat вспомогательный файл, через который программы открывают готовые PDF и сайты; если что-то не открылось само, кликните его
jsc1.txt, jsc2.txt команды операционной системы для программы №76
pro/ главная рабочая папка; сюда многие программы пишут результаты
pro/0.par, pro/0.acl временные копии входных данных и кода запущенной программы
pro/0/ файлы для примеров из vkacld.zip
pro/1/, pro/2/ папки-черновики, которые используются в примерах
pro/b/ служебные файлы: шаблоны сайтов, фоновые картинки, таблица Менделеева
pro/pdf/ рабочая папка программы №61
pro/sites/ проекты сайтов программы №44
zip/ архив презентации для программы №27
s/ научные программы (кнопка SciPro)
vkNP/ настройки большого редактора; в 17-й строке vkNP/par.txt надо указать путь к своему браузеру

Внимание. Кнопка Demo перед некоторыми демонстрациями очищает папки pro/1/ и pro/2/, чтобы подготовить исходные файлы. Не храните там ничего ценного — для своих файлов заведите отдельные папки.

Если что-то пошло не так

Каталог

Программы сгруппированы по назначению. Номер — ссылка на подробное описание.

Картинки — pictures.md

№ Название Для чего
06 PICs on MAT собрать одну картинку из таблицы одинаковых картинок
07 PICs to ICONs уменьшенные копии (иконки) всех картинок папки
08 SLIDE MAKER слайд или заставка из картинок и надписей (разбор)
34 INDEX копии картинок папки с именами вида «шапка + номер»
35 PNG to JPG перевести все PNG папки в JPG
40 PIC to FRAG вырезать фрагмент картинки мышью или по числам
45 PICs to CUT2 разрезать каждую картинку папки пополам
47 PIC to RSFrag фрагмент картинки после поворота и масштабирования
51 SCR to PIC снимки экрана по нажатию клавиши (например, с видео)
54 IMG VIEW просмотр картинок, несколько штук на экране, увеличение
58 PIC MOD яркость, контраст, гамма и другие операции над пикселями
59 PICs SUP сложить несколько картинок с весами
60 PICs PRO перемножить или поделить картинки
68 PNG to EPS перевести все PNG папки в EPS
73 IMG MOD 2 массово изменить высоту картинок или вписать их в рамку

PDF — pdf.md

№ Название Для чего
09 PDF PRESENT PDF-презентация из картинок папки
10 PDF to PART новый PDF из выбранных страниц другого PDF
11 PDFs to PDF объединить несколько PDF в один
12 PDF PAGEs узнать размеры страниц PDF
13 PIC on PDF положить картинки поверх страницы PDF
14 TXT on PDF написать текст поверх страницы PDF
39 PDF to PRINT лист A4 с картинками для печати
61 SWP4rus PDF из TeX-файла редактора SWP с русским текстом

Числовые массивы и матрицы — arrays.md

№ Название Для чего
16 TXT to DAT текстовая таблица чисел → двоичный файл .dat
17 MAT to FRAG вырезать прямоугольный фрагмент матрицы
18 MAT to Smooth сгладить матрицу гауссианом (серия ширин)
19 MAT RESIZE изменить размер матрицы интерполяцией
32 TIFF to TAGs параметры TIFF-файла (размер, разрядность, сжатие)
33 TIFFs to DATs матрицы из всех TIFF-файлов папки
37 ADGF подобрать функцию Гаусса к кривой
43 DAT to TXT двоичный файл .dat → текст
46 PIC to DAT пиксели картинок → числовые матрицы
48 PIC to XYProf средние профили картинки по X и по Y
53 MAT to LINE значения матрицы вдоль отрезка
55 DAT MOD 2 арифметика над всеми файлами папки
65 DAT MOD 1 арифметика и преобразования одного массива
71 DAT to TIFF 1 матрица → 16-битный TIFF
77 DAT MOD 1 транспонирование, обрезка, сглаживание, отражение матрицы
79 MAT PROP анализ 16-битных матриц детектора
80 — вычислить функции по формулам «как в Excel» (в архиве 23.05.2026 ещё нет)

Графики — graphs.md

№ Название Для чего
03 DAT to PNG 2 картинки из матриц всех файлов папки
20 1D PIC 1 график одной или нескольких кривых
21 2D MAP карта матрицы в оттенках серого или в цвете (разбор)
22 2D as SET 1D квазитрёхмерный график — семейство сдвинутых кривых
23 2D as AXON аксонометрия поверхности z(x, y)
24 2D as ANIM анимация: сечения матрицы сменяют друг друга
49 EPS 1D график кривых в EPS и PDF
50 EPS 2D карта матрицы в EPS и PDF
67 1D PIC 2 графики для всех файлов папки
70 DAT to PNG 1 картинка из фрагмента одной матрицы

Тексты и файлы — text.md

№ Название Для чего
02 SYMBOL сколько раз символ встречается в файле
05 FIND WORD найти слово во всех файлах папки
15 CIPHER редактор зашифрованных текстов
25 EDITOR большой редактор текстов
26 LINE EDIT править одну строку файла по номеру
36 COPY FILEs склеить несколько файлов в один
64 TXT to FB2 электронная книга FB2 из текста
72 DAT MOD 2 замены текста во всех файлах папки, перекодировка, сортировка строк
75 Exe FILE выбрать файл и открыть его по расширению

Сайты — sites.md

№ Название Для чего
01 FOTO SITE заготовка сайта фотографий с комментариями
04 SLIDE SHOW сайт — слайд-шоу по картинкам папки
38 SIMP SITE простой сайт из текстового файла
44 COMP SITE сложный сайт по простой разметке
52 FOTO SHOW сайт фото-шоу под музыку
66 WEB SITE копия статьи из интернета: текст и картинки отдельно
74 CH LANG сайт из текста с кнопкой перевода на другие языки

Звук, анимация, игры — media.md

№ Название Для чего
27 LECTURE показ презентации доклада или картинок папки
41 GAME PIC игра-мозаика: собрать перемешанную картинку
42 GAME MOV анимация движения упругих шаров
63 FM-PLAYER проигрыватель mp3-файлов папки в браузере
69 vkSS слайд-шоу под музыку с эффектными переходами
99 DEMO рекламная анимация языка VKACL

Автоматизация и система — system.md

№ Название Для чего
28 RUNNER панель из 176 кнопок для часто нужных файлов
29 PLAYER написать и сразу выполнить небольшую программу на VKACL
56 CHAIN 1 выполнить несколько программ подряд
57 CHAIN 2 цепочка программ, данные прямо в протоколе
76 SYSTEM выполнить команды операционной системы по номерам
78 CHAIN 3 цепочка программ для каждого файла папки

Разное — other.md

№ Название Для чего
30 UNICODES посмотреть, какие символы есть в шрифте
31 PTOE таблица Менделеева — справочник и записная книжка
62 CALCUL калькулятор выражений на 8 переменных (разбор)

Подробные разборы

Три программы разобраны по шагам, от пустой папки до готового результата:

Где ещё почитать

Картинки

Программы этой группы собирают, режут, пересчитывают и переименовывают файлы картинок (JPG, PNG, иногда GIF). Общие правила записи входных данных — в разделе Как записывать входные данные; примеры используют файлы из архива vkacld.zip (папка pro/0/).

№ Название Для чего
06 PICs on MAT одна картинка из таблицы картинок
07 PICs to ICONs уменьшенные копии всех картинок папки
08 SLIDE MAKER слайд из картинок и надписей
34 INDEX копии картинок с номерами в именах
35 PNG to JPG все PNG папки → JPG
40 PIC to FRAG вырезать фрагмент
45 PICs to CUT2 разрезать картинки пополам
47 PIC to RSFrag фрагмент после поворота и масштаба
51 SCR to PIC снимки экрана по клавише
54 IMG VIEW просмотр картинок
58 PIC MOD яркость, контраст, гамма
59 PICs SUP сумма картинок с весами
60 PICs PRO произведение или частное картинок
68 PNG to EPS все PNG папки → EPS
73 IMG MOD 2 массово поменять высоту или вписать в рамку

№06. PICs on MAT — картинка из таблицы картинок

Что делает. Раскладывает несколько картинок одинакового размера таблицей (столько-то в строке, столько-то строк) с промежутками заданного цвета и сохраняет результат как одну картинку. Удобно для отчётов и каталогов. Готовая картинка сразу показывается в левом верхнем углу экрана; закрыть её — кликом по картинке или крестиком.

Что нужно заранее. Все картинки лежат в одной папке, имеют формат PNG или JPG и один и тот же размер (размер берётся по первой).

Входные данные — одна строка:

Поле Что писать Пример
1 папка с картинками, с разделителем / в конце pro/0/
2 … k+1 имена k картинок без расширения, в порядке заполнения таблицы; одно имя можно повторять jad jad jad jad
k+2 имя нового файла без расширения all
k+3 сколько картинок в строке таблицы 2
k+4 сколько строк 2
k+5 промежуток между картинками по горизонтали, px 3
k+6 промежуток по вертикали, px 3
k+7 номер цвета промежутков, от 1 до 256 250

Результат. Файл <папка>/<имя>.jpg или .png — того же типа, что исходные картинки. Размер: ширина = столбцы × ширина картинки + промежутки.

Пример. Четыре копии портрета jad.jpg (220×250) таблицей 2×2:

pro/0/ jad jad jad jad all 2 2 3 3 250 

Получится pro/0/all.jpg размером 443×503.

Тонкости.

№07. PICs to ICONs — уменьшенные копии картинок

Что делает. Для каждой картинки исходной папки делает копию заданной ширины (высота — пропорционально) и кладёт её в другую папку под тем же именем. Обычно так делают иконки для каталогов и сайтов.

Что нужно заранее. В исходной папке — только картинки JPG или PNG (размеры могут быть разными). Папка для копий должна существовать.

Входные данные — одна строка:

Поле Что писать Пример
1 исходная папка, с разделителем в конце pro/1/
2 папка для копий, с разделителем в конце pro/2/
3 ширина копий, px 200

Результат. В папке копий — файлы с теми же именами, но всегда в формате JPG (m91.png → m91.jpg). В конце программа сообщает, куда записаны копии.

Пример. Скопируйте m91.jpg … m95.jpg из pro/0/ в pro/1/, затем:

pro/1/ pro/2/ 200 

Тонкости.

№08. SLIDE MAKER — слайд из картинок и надписей

Пошаговый разбор с примером — на странице Разбор: №08 SLIDE MAKER.

Что делает. Собирает картинку заданного размера — слайд презентации, объявление, заставку для видео — методом «вырезать и наклеить»: на основу кладёт картинки (со сдвигом, поворотом, наклоном и масштабом), а поверх пишет строки текста любым шрифтом, установленным на компьютере.

Что нужно заранее. Все используемые картинки лежат в папке pro/1/. Туда же программа запишет результат.

Входные данные — несколько первых строк файла:

Строка Что писать Пример
1 W H N1 N2, |, имя результата 512 512 1 3|slide
2 … N1+1 X Y A Sx Sy Mx My, |, файл картинки 256 256 0 0 0 9 9|000000.png
ещё N2 строк X Y M K S R G B, |шрифт|текст 256 100 5 1 30 0 255 0 |Arial|Привет

Смысл чисел:

Параметр Значение
W, H размер основы в пикселях
N1, N2 сколько будет картинок и сколько надписей (столько строк и должно идти следом)
имя результата без расширения; получатся файлы .png и .jpg
файл картинки имя файла в папке pro/1/ с расширением
X, Y для картинки — положение её центра, для надписи — точка привязки; отсчёт в пикселях от левого верхнего угла основы, Y растёт вниз
A угол поворота картинки в градусах
Sx, Sy сдвиговая (скашивающая) деформация; 0 0 — без неё
Mx, My масштаб по осям; 1 1 — исходный размер
M способ привязки надписи к точке X, Y (от 1 до 9, см. ниже)
K начертание: 0 обычное, 1 жирное, 2 курсив, 3 жирный курсив
S размер шрифта, px
R, G, B цвет текста, каждая составляющая от 0 до 255

Привязка M: по горизонтали 1, 4, 7 — левым краем, 2, 5, 8 — серединой, 3, 6, 9 — правым краем; по вертикали 1–3 — низом, 4–6 — серединой высоты, 7–9 — верхом. Самая удобная — 5: текст центрируется в точке.

Результат. Два файла: pro/1/<имя>.png и pro/1/<имя>.jpg. Слайд показывается на экране, затем программа спрашивает, не поменять ли параметры. Yes снова открывает входные данные — можно подправить и посмотреть ещё раз.

Пример (автора). Для него скопируйте 000000.png из pro/0/ в pro/1/.

512 512 1 3|slide
 256 256 0 0 0 9 9|000000.png
 256 100 5 1 30  0 255 0 |Arial|на полотно любого размера
 256 200 5 1 30 255 0 0  |Arial|можно ставить картинки
 256 300 5 1 30 255 255 255 |Arial|и тексты любых фасонов

Чёрная картинка 256×192, увеличенная в 9 раз, закрывает всю основу 512×512, а поверх идут три строки: зелёная, красная и белая.

Тонкости.

№34. INDEX — копии картинок с номерами

Что делает. Копирует все файлы .jpg и .png из одной папки в другую, давая им новые имена: «шапка» + трёхзначный номер + прежнее расширение (abc001.jpg, abc002.png, …). Номера идут подряд в порядке файлов в каталоге. Исходные файлы остаются на месте.

Что нужно заранее. Обе папки существуют.

Входные данные — одна строка:

Поле Что писать Пример
1 исходная папка pro/0/
2 папка для копий pro/2/
3 шапка — любые символы без пробелов, хотя бы один abc

Результат. В папке копий: abc001.jpg, abc002.jpg, …

Пример.

pro/0/  pro/2/  abc E

Тонкости.

№35. PNG to JPG — перевод PNG в JPG

Что делает. Переводит все файлы .png исходной папки в формат JPG и записывает их в другую папку с тем же именем. Остальные файлы не трогает.

Что нужно заранее. Обе папки существуют.

Входные данные — одна строка:

Поле Что писать Пример
1 исходная папка pro/0/
2 папка для JPG pro/2/

Результат. pro/2/<имя>.jpg для каждого <имя>.png.

Пример.

pro/0/  pro/2/ E

Тонкости. Расширение png должно быть написано строчными буквами. Если папка пуста, программа так и скажет.

№40. PIC to FRAG — вырезать фрагмент картинки

Что делает. Вырезает прямоугольный фрагмент из картинки JPG или PNG и сохраняет его в новый файл. Два режима: с одной картинкой (фрагмент можно выделить мышью) и пакетный — одинаковый фрагмент из серии пронумерованных файлов.

Входные данные — одна строка:

Поле Что писать Пример
1 рабочая папка, с разделителем в конце pro/0/
2 исходная картинка m91.jpg
3 файл фрагмента; расширение .jpg или .png задаёт формат frag.jpg
4, 5 X, Y — левый нижний угол фрагмента, px 0 0
6, 7 W, H — ширина и высота фрагмента, px 500 500
8 N: 1 — одна картинка; больше 1 — пакетный режим на N файлов 1

Режим N = 1. Картинка показывается на экране (слишком большая — уменьшенной), подсказка — в строке над панелью задач. Дальше одно из двух:

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

Режим N > 1. Имена обеих картинок должны кончаться трёхзначным номером перед точкой, а перед номером — хотя бы одна буква: vk001.jpg, f001.jpg. Программа молча вырезает фрагмент X Y W H из первого файла, увеличивает номера в обоих именах на 1 и повторяет, всего N раз.

Результат. <папка>/<файл фрагмента> (в пакетном режиме — серия файлов).

Пример.

pro/0/  m91.jpg  frag.jpg  0 0 500 500 1 

Тонкости.

№45. PICs to CUT2 — разрезать картинки пополам

Что делает. Каждую картинку исходной папки разрезает по вертикали на две половинки, как развороты книги на две страницы. Нужно для слайд-шоу в виде книги, но годится и для других целей.

Что нужно заранее. В исходной папке — только картинки JPG, PNG или GIF. Папка для результатов существует (может быть не пустой).

Входные данные — одна строка:

Поле Что писать Пример
1 исходная папка, с разделителем в конце pro/1/
2 папка для половинок, с разделителем в конце pro/2/

Результат. Для m91.jpg — файлы pro/2/m91-1.jpg и pro/2/m91-2.jpg, всегда в формате JPG.

Пример.

pro/1/  pro/2/ 

Тонкости. По коду программы -1 — правая половина, -2 — левая; проверьте на своей картинке, прежде чем готовить книгу.

№47. PIC to RSFrag — фрагмент после поворота и масштаба

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

Что нужно заранее. Рабочая папка находится внутри папки программы (пока это обязательно).

Входные данные — одна строка:

Поле Что писать Пример
1 рабочая папка pro/0
2 исходная картинка jad.jpg
3 новая картинка; расширение .jpg или .png задаёт формат frag.jpg
4, 5 ширина и высота новой картинки, px 100 100
6 угол поворота, градусы 90
7 коэффициент масштабирования 1.3

Результат. <папка>/<новая картинка>; она же показывается на экране.

Пример.

pro/0  jad.jpg  frag.jpg  100 100 90 1.3 

Тонкости.

№51. SCR to PIC — снимки экрана по клавише

Что делает. Сохраняет снимки всего экрана в JPG по нажатию клавиши — не показывая себя и не мешая видео или видеоконференции, с которых снимают кадры. О том, что программа работает, говорит только маленький красный прямоугольник в правом верхнем углу экрана.

Входные данные — одна строка, лучше первая:

Поле Что писать Пример
1 папка для снимков, короткий путь (не длиннее 30 символов) pro/2/
2 номер, с которого продолжать нумерацию 0

Как работать.

  1. Запустите программу, затем откройте видео. Окно видео не должно закрывать красный прямоугольник.
  2. Кликните по красному прямоугольнику — программа получит фокус.
  3. Enter — снимок; прямоугольник на миг мигнёт.
  4. Если переключались на другие окна, перед следующим снимком снова кликните по прямоугольнику.
  5. Пробел — выход.

Результат. Файлы <папка>/vk001.jpg, vk002.jpg, … Номер увеличивается перед каждым снимком. При выходе программа сама записывает в первую строку входных данных папку и последний номер — следующий сеанс продолжит нумерацию, не затирая старые снимки.

Пример.

pro/2/ 0 

Тонкости. Работает в режиме проигрывателя. Папку лучше брать внутри папки программы — путь короче; не пишите в имя папки пробелы и длинные русские фразы.

№54. IMG VIEW — просмотр картинок

Что делает. Показывает картинки PNG, JPG и GIF, в том числе несколько сразу, и позволяет увеличивать и уменьшать их.

Входные данные. Нет. Поставьте курсор в начало текста и нажмите Esc.

Как работать. Откроется окно выбора файла (начиная с папки программы). Один клик по файлу показывает эскиз, кнопка Select или двойной клик — картинку в натуральную величину (большая — с полосами прокрутки). Дальше:

Действие Что происходит
клик по картинке картинка закрывается, снова окно выбора
→ картинка остаётся, можно выбрать ещё одну — так на экране собирается несколько картинок; двигать их за рамку окна
↑ / ↓ таблица из 99 чисел: картинка увеличится / уменьшится на выбранное число процентов (50 — в полтора раза)
Cancel в окне выбора конец работы

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

№58. PIC MOD — яркость, контраст, гамма

Что делает. Пересчитывает цвета всех пикселей картинки по одной из восьми формул: делает светлее или темнее, контрастнее или мягче. Размер не меняется.

Входные данные — одна строка:

Поле Что писать Пример
1 рабочая папка (разделитель в конце можно не ставить) pro/0
2 исходная картинка JPG, PNG или GIF, с расширением s9.jpg
3 имя новой картинки без расширения s9n
4 номер операции, 1–8 1
5, 6 параметры p1 и p2 (если операции нужен один, второй всё равно пишется) 50 0

Операции (x — значение цвета от 0 до 255):

№ Что делает
1 прибавляет p1 ко всем цветам
2 умножает все цвета на p1/1000
3 растягивает диапазон: p1 → 0, p2 → 255
4 сжимает диапазон: 0 → p1, 255 → p2
5 умножает контраст на p1/1000, среднее сохраняется
6 гамма: 255·(x/255)^(p1/1000)
7 логарифмическая кривая с параметрами p1, p2 (формула — на сайте автора)
8 S-образная кривая 255/(1+exp((a2−x)/a1)), где a1=(p2−p1)/2, a2=(p2+p1)/2

Результат. <папка>/<новое имя>.jpg, всегда JPG; показывается на экране.

Пример. Сделать картинку светлее на 50 единиц:

pro/0 s9.jpg s9n 1 50 0 

Тонкости. Если нет папки или файла, программа скажет об этом по-русски. Эффект операций проще всего понять пробой.

№59. PICs SUP — сумма картинок с весами

Что делает. Складывает несколько картинок, каждую со своим весом (веса могут быть отрицательными — это вычитание), и нормирует результат в диапазон 0–255. Полезно, например, для суммирования серии снимков одного объекта.

Входные данные — одна строка из пяти полей:

Поле Что писать Пример
1 рабочая папка pro/0
2 список картинок через запятую, с расширениями m91.jpg,m92.jpg
3 имя результата без расширения; первая буква c — цветной, b — чёрно-белый cnew
4 веса через запятую (важны только отношения) 50,50
5 нормировка: 1 — отрицательное обнуляется, максимум → 255; 2 — весь диапазон от минимума до максимума → 0–255 2

Результат. <папка>/<имя>.jpg размером с первую картинку.

Пример.

pro/0 m91.jpg,m92.jpg cnew 50,50 2 

Тонкости.

№60. PICs PRO — произведение или частное картинок

Что делает. Перемножает картинки (например, чтобы вырезать область по маске) или делит одну на другую; результат линейно приводится к диапазону 0–255.

Входные данные — одна строка из четырёх полей:

Поле Что писать Пример
1 рабочая папка pro/0
2 список картинок через запятую, с расширениями m91.jpg,m92.jpg
3 имя результата без расширения; первая буква c — цветной, b — чёрно-белый cnew
4 1 — умножение, 2 — деление 1

Результат. <папка>/<имя>.jpg размером с первую картинку.

Пример.

pro/0 m91.jpg,m92.jpg cnew 1 

Тонкости. При делении используются только две первые картинки; нули делителя заменяются единицами. Про размеры — то же, что у №59.

№68. PNG to EPS — перевод PNG в EPS

Что делает. Переводит все PNG-файлы папки в формат EPS — для вставки в статьи и в рисунки на PostScript.

Входные данные — одна строка:

Поле Что писать Пример
1 вариант: 1 — готовый к просмотру EPS; 2 — только код картинки для вставки в другой EPS 1
2 папка с PNG, с разделителем в конце pro/1/
3 папка для результатов (должна существовать), с разделителем в конце pro/2/

Результат. pro/2/<имя>.eps (вариант 1) или pro/2/<имя>EPS.txt (вариант 2) для каждого файла.

Пример.

1 pro/1/ pro/2/ 

Тонкости. В исходной папке не должно быть ничего, кроме PNG. Символ _ в путях к папкам программа заменяет на пробел, поэтому папки с _ в имени не подойдут.

№73. IMG MOD 2 — высота и рамка для всех картинок папки

Что делает. Меняет сами файлы всех картинок папки. Вариант 1 — задаёт всем одну высоту, сохраняя пропорции. Вариант 2 — помещает каждую картинку в центр пустого кадра заданного размера (удобно после варианта 1, чтобы все кадры стали одинаковыми).

Входные данные — одна строка:

Поле Что писать Пример
1 вариант, 1 или 2 2
2 папка, с разделителем в конце pro/1/
3 h — новая высота (в варианте 2 не используется, но пишется) 720
4, 5 W, H — размер кадра (только для варианта 2) 1280 720

Результат. Вариант 1: файлы перезаписываются (JPG остаётся JPG, PNG — PNG). Вариант 2: результат пишется в JPG с тем же именем (для PNG рядом появляется .jpg).

Пример.

1 pro/1/ 720 E
2 pro/1/ 720 1280 720 E

Тонкости.

PDF

Программы этой группы собирают PDF из картинок, склеивают и перекраивают готовые PDF, кладут поверх страницы картинки и надписи. Размеры в PDF задаются в пунктах (pt): лист A4 — это 596 × 843 pt (у автора встречается и 596 × 842).

Общие правила записи входных данных — в разделе Как записывать входные данные. Программы №10–14 и 39 читают несколько первых строк файла и выполняют только верхний вариант.

№ Название Для чего
09 PDF PRESENT PDF-презентация из картинок папки
10 PDF to PART новый PDF из выбранных страниц
11 PDFs to PDF объединить несколько PDF
12 PDF PAGEs размеры страниц PDF
13 PIC on PDF картинки поверх страницы PDF
14 TXT on PDF текст поверх страницы PDF
39 PDF to PRINT лист с картинками для печати
61 SWP4rus PDF из TeX-файла редактора SWP

Запускайте эти программы через _runp.bat. Если источник — повреждённый или вообще не PDF, Java не сможет его прочитать, выведет ошибку в чёрное окно терминала и остановит интерпретатор. Проверить это из программы на VKACL нельзя, поэтому перед работой просто откройте исходный PDF обычной программой просмотра.

Готовый PDF программы пытаются открыть сами (кнопка Wait). Если он не открылся — найдите файл в папке или кликните runsys.bat.

№09. PDF PRESENT — PDF-презентация из картинок

Что делает. Собирает PDF-файл, в котором каждая страница — одна картинка из папки. Так готовят файл доклада из слайдов-картинок. Есть режим для постерных докладов: слайды поворачиваются на 90° и вписываются в лист A4, чтобы их можно было распечатать и приколоть на стенд.

Что нужно заранее. В папке — только картинки JPG или PNG. Порядок страниц — алфавитный порядок имён файлов.

Входные данные — одна строка:

Поле Что писать Пример
1 папка с картинками, с разделителем в конце pro/1/
2 имя PDF без расширения present
3 режим: 0 — как есть, 1 — поворот на 90° и лист A4 0

Результат. Файл pro/<имя>.pdf — всегда в папке pro.

Пример. Скопируйте m91.jpg … m95.jpg из pro/0/ в pro/1/, затем:

pro/1/  present  0  E

Получится пятистраничный pro/present.pdf. Не удаляйте его — он понадобится как источник в примерах программ №10–12.

Тонкости. В режиме 0 размер страницы берётся по первой картинке, и все картинки ставятся в натуральную величину. Поэтому слайды должны быть одного размера.

№10. PDF to PART — новый PDF из выбранных страниц

Что делает. Берёт из готового PDF нужные страницы и собирает из них новый файл. Каждую страницу можно сдвинуть, растянуть и повернуть. Можно ставить по две страницы источника на одну страницу результата.

Входные данные — первые строки файла:

Строка Что писать Пример
1 W H N, затем путь к новому PDF и путь к PDF-источнику, оба без расширения 640 480 2 pro/1/new pro/present
2 … |N|+1 по строке на страницу: n X Y Sx Sy A 1 0 0 0.5 0.5 0

Смысл чисел:

Параметр Значение
W, H размер страницы нового файла, pt
N сколько страниц взять. N > 0 — по одной странице источника на страницу; N < 0 — по две (их нужно уменьшить и развести сдвигом, чтобы не перекрывались)
n номер страницы источника
X, Y сдвиг страницы источника на новой странице, pt
Sx, Sy масштаб по осям; 1 1 — без изменений
A угол поворота, градусы

Результат. Файл по первому пути (pro/1/new.pdf).

Пример (источник — pro/present.pdf из примера №9):

640 480 2 pro/1/new pro/present  E
 1 0 0 0.5 0.5 0 E
 2 0 0 0.5 0.5 0 E

Тонкости.

№11. PDFs to PDF — объединение нескольких PDF

Что делает. Склеивает несколько PDF в один. Страницы можно сдвинуть, растянуть и повернуть. Удобно, например, чтобы собрать одностраничные PDF с картинками в один многостраничный.

Входные данные — первые строки файла:

Строка Что писать Пример
1 W H N, затем путь к новому PDF без расширения 640 480 2 pro/1/new2
2 … |N|+1 по строке на файл: X Y Sx Sy A, затем путь к PDF без расширения 0 0 1 1 0 pro/1/new

W, H — размер страницы результата в pt; N — сколько файлов объединить (N < 0 — по две старые страницы на новую); X, Y, Sx, Sy, A — как у №10.

Результат. pro/1/new2.pdf.

Пример — дважды вставить файл из примера №10:

 640 480 2 pro/1/new2 E
 0 0 1 1 0 pro/1/new E
 0 0 1 1 0 pro/1/new E

Тонкости.

№12. PDF PAGEs — размеры страниц

Что делает. Показывает размеры всех страниц выбранного PDF. Нужно, чтобы правильно задать сдвиги и масштабы в программах №10, 11, 13 и 14.

Входные данные — первая строка файла:

Строка Что писать Пример
1 папка, с которой начать выбор файла pro/

Как работать. Откроется окно выбора файла, показывающее только PDF. Выберите файл.

Результат. Файл pro/page-sizes.txt: по строке на страницу — номер, ширина и высота в pt. Он сразу открывается в редакторе. Папку выбранного файла программа записывает в первую строку входных данных — в следующий раз выбор начнётся с неё.

Пример.

pro/

Тонкости. Используется только первая строка; лишних символов после пути не ставьте.

№13. PIC on PDF — картинки поверх страницы PDF

Что делает. Делает новый одностраничный PDF: копию первой страницы старого PDF, поверх которой положены картинки — в любом месте, с масштабом и поворотом. Удобно, чтобы добавить в документ подпись, печать или пометку.

Входные данные — первые строки файла:

Строка Что писать Пример
1 N, путь к старому PDF, путь к новому PDF (оба без расширения) 1 pro/0/QR-vgkohn pro/1/1
2 … N+1 по строке на картинку: X Y P S A, затем путь к картинке с расширением 0 0 0 220 0 pro/0/jad.jpg
Параметр Значение
X, Y левый нижний угол картинки, pt
P всегда 0 (не используется)
S ширина картинки на странице, pt; высота — пропорционально
A угол поворота, градусы

Результат. pro/1/1.pdf.

Пример.

 1  pro/0/QR-vgkohn  pro/1/1  E
 0 0 0 220 0 pro/0/jad.jpg 

Тонкости.

№14. TXT on PDF — текст поверх страницы PDF

Что делает. Как №13, но вместо картинок кладёт на страницу строки текста встроенными шрифтами PDF.

Входные данные — первые строки файла:

Строка Что писать Пример
1 N, путь к старому PDF, путь к новому PDF (оба без расширения) 1 pro/0/QR-vgkohn pro/1/1
2 … N+1 по строке на надпись: S X Y A F P R G B, затем сам текст и пробел 16 60 160 0 10 0 0 0 0 Privet_Mir_!
Параметр Значение
S размер шрифта, pt
X, Y точка привязки текста, pt
A угол поворота, градусы
F номер шрифта, см. ниже
P привязка к точке: 0 — левым краем, 1 — серединой, 2 — правым краем
R, G, B цвет, каждая составляющая от 0 до 255 (0 0 0 — чёрный)

Шрифты: 1 Courier, 2 Courier-Bold, 3 Courier-Oblique, 4 Courier-BoldOblique, 5 Helvetica, 6 Helvetica-Bold, 7 Helvetica-Oblique, 8 Helvetica-BoldOblique, 9 Times, 10 Times-Bold, 11 Times-Italic, 12 Times-BoldItalic, 13 Times-Roman, 14 Symbol, 15 ZapfDingbats.

Результат. pro/1/1.pdf.

Пример.

 1 pro/0/QR-vgkohn pro/1/1  E
 16 60 160 0 10 0 0 0 0 Privet_Mir_! E

Тонкости.

№39. PDF to PRINT — лист с картинками для печати

Что делает. Делает одностраничный PDF, на который можно положить сколько угодно картинок. Главное применение — разложить картинки на лист A4 и напечатать.

Входные данные — первые строки файла. Все пути считаются от папки pro:

Строка Что писать Пример
1 W H N, затем | и имя PDF без расширения 596 842 2|pri
2 … N+1 по строке на картинку: M X Y P S A, затем | и файл картинки с расширением 11 100 150 0 220 0|0/jad.jpg
Параметр Значение
M двузначное число KL. K: 1 — по координатам (рекомендуется), 0 — «потоком» друг за другом. L: 0 — масштаб в процентах, 1 — ширина в pt, 2 — высота в pt
X, Y при K = 1 — левый нижний угол картинки, pt; при K = 0 — отступ после предыдущего объекта
P при K = 0 — положение в строке: 0 слева, 1 по центру, 2 справа
S масштаб: проценты, ширина или высота — в зависимости от L
A угол поворота, градусы

Результат. pro/pri.pdf.

Пример — два портрета шириной 220 pt на листе A4:

 596 842 2|pri
 11 100 150 0 220 0|0/jad.jpg
 11 150 500 0 220 0|0/jad.jpg

Тонкости.

№61. SWP4rus — PDF из TeX-файла редактора SWP

Что делает. Помогает сделать PDF из TeX-файла, записанного редактором Scientific WorkPlace 4 и новее, если в нём есть русский текст. SWP кодирует русские буквы так, что ни сам SWP, ни MiKTeX не могут сделать PDF. Программа перекодирует их в windows-1251 и готовит запуск MiKTeX.

Что нужно заранее.

Входные данные. Нет. Поставьте курсор в начало первой строки и нажмите Esc.

Как работать.

  1. В окне выбора (оно открывается в pro/pdf/) выберите TeX-файл.
  2. Программа создаст pro/pdf/runsys.bat и попросит запустить его. Сначала кликните этот файл в менеджере файлов, дождитесь конца его работы и только потом нажмите OK.
  3. PDF появится рядом с TeX-файлом, с тем же именем.

Тонкости. Только Windows. Файл runsys.bat создаёт сама программа — его не правят; править нужно swp4rus.dat, один раз. Подробности у автора: latex-info.

Числовые массивы и матрицы

Эти программы работают с массивами чисел: переводят их из текста в двоичный вид и обратно, вырезают, сглаживают, интерполируют, вычисляют. Большинство работает с файлами .dat — числами по 4 байта без заголовка (подробнее — в разделе Числовые файлы .dat). Размеры матрицы в таком файле не хранятся, поэтому их всегда указывают во входных данных.

Нарисовать массив помогут программы группы Графики.

№ Название Для чего
16 TXT to DAT текст → .dat
17 MAT to FRAG вырезать фрагмент матрицы
18 MAT to Smooth сглаживание гауссианом
19 MAT RESIZE новый размер интерполяцией
32 TIFF to TAGs параметры TIFF-файла
33 TIFFs to DATs матрицы из TIFF-файлов папки
37 ADGF подгонка функцией Гаусса
43 DAT to TXT .dat → текст
46 PIC to DAT пиксели картинок → числа
48 PIC to XYProf профили картинки по X и Y
53 MAT to LINE значения вдоль отрезка
55 DAT MOD 2 операции над всеми файлами папки
65 DAT MOD 1 операции над одним массивом
71 DAT to TIFF 1 матрица → 16-битный TIFF
77 DAT MOD 1 транспонирование, обрезка, сглаживание, отражение
79 MAT PROP анализ 16-битных матриц детектора
80 — функции по формулам «как в Excel»

№16. TXT to DAT — текстовая таблица в двоичный файл

Пошаговый пример — в разборе №21.

Что делает. Читает матрицу (или вектор) чисел из текстового файла и записывает те же числа в двоичный файл .dat, с которым работают другие программы.

Что нужно заранее. Текстовый файл с расширением .txt. В режиме матрицы каждая строка матрицы записана на отдельной строке файла.

Входные данные — одна строка:

Поле Что писать Пример
1 сколько чисел в строке матрицы (для вектора — сколько всего чисел) 441
2 сколько строк в матрице; 1 — особый случай «вектор» 1
3 сколько строк в начале файла пропустить (например, текстовый заголовок) 0
4 путь к файлу без .txt pro/0/matrix

Результат. Файл с тем же именем и расширением .dat в той же папке.

Пример. Файл pro/0/matrix.txt — 21 строка по 21 числу. Его можно прочитать как вектор из 441 числа или как матрицу 21×21 — результат одинаков:

441  1 0 pro/0/matrix  E
21 21 0 pro/0/matrix  E

Тонкости.

№17. MAT to FRAG — фрагмент матрицы

Что делает. Вырезает из матрицы прямоугольный фрагмент и записывает его в новый файл — как вырезают кусок картинки. Есть и обратный режим: вставить фрагмент из второго файла на место в первом.

Входные данные — одна строка:

Поле Что писать Пример
1, 2 ширина и высота исходной матрицы 400 100
3, 4 сдвиг начала фрагмента по горизонтали и вертикали 0 0
5, 6 ширина и высота фрагмента 100 50
7 исходный файл с расширением pro/0/m001.dat
8 файл фрагмента с расширением pro/1/m001f.dat

Результат. Второй файл — ширина × высота фрагмента чисел.

Пример.

400 100 0 0 100 50 pro/0/m001.dat pro/1/m001f.dat 

Тонкости.

№18. MAT to Smooth — сглаживание гауссианом

Что делает. Сглаживает матрицу (свёртка с функцией Гаусса) сразу для серии ширин гауссиана и записывает все результаты в один файл. Умеет и обратную операцию — развёртку.

Входные данные — одна строка:

Поле Что писать Пример
1, 2 nx, ny — ширина и высота матрицы (ny может быть 1) 64 1
3 ep: 0 — свёртка, больше 0 — развёртка 0
4 mo: 1 — вдоль первого индекса, 2 — вдоль второго, 3 — по обоим (матрица квадратная) 1
5 d — шаг сетки 1
6 dr — начальная полная ширина гауссиана на полувысоте 5
7 dd — шаг изменения ширины 5
8 nd — сколько ширин перебрать 3
9 исходный файл pro/0/in999.dat
10 файл результата pro/1/in999.dat

Результат. Файл из nd матриц подряд (nx × ny × nd чисел), по одной на каждую ширину dr, dr+dd, dr+2·dd, …

Пример.

64 1 0 1 1 5 5 3 pro/0/in999.dat  pro/1/in999.dat  E

Тонкости.

№19. MAT RESIZE — новый размер матрицы

Что делает. Пересчитывает матрицу на другое число точек линейной интерполяцией. Область значений аргументов при этом сохраняется.

Входные данные — одна строка:

Поле Что писать Пример
1, 2 ширина и высота исходной матрицы 400 100
3, 4 ширина и высота результата 512 512
5 исходный файл pro/0/m001.dat
6 файл результата pro/1/m001n.dat

Результат. Файл с матрицей нового размера.

Пример.

400 100 512 512 pro/0/m001.dat pro/1/m001n.dat  E

№32. TIFF to TAGs — параметры TIFF-файла

Что делает. Читает служебные записи (теги) TIFF-файла и показывает главное: ширину и высоту картинки, число бит на пиксель, сжатие, порядок байтов, где лежат данные. Нужна, чтобы убедиться, что файл — 16-битная чёрно-белая картинка (значения 0–65535), пригодная для научных данных.

Входные данные — одна строка:

Поле Что писать Пример
1 папка, с которой начать выбор файла pro/0

Как работать. В окне выбора укажите TIFF-файл.

Результат. Файл tif-inf.txt в папке TIFF-файла; он сразу открывается в редакторе.

Пример (в pro/0/ есть s001.tif):

pro/0 E

Тонкости. Если выбранный файл — не TIFF, программа сообщит об этом и прервёт работу проигрывателя (в её коде на этот случай стоит команда #stop); просто запустите _runp.bat снова.

№33. TIFFs to DATs — матрицы из TIFF-файлов

Что делает. Просматривает все файлы папки, находит среди них подходящие TIFF (8 или 16 бит на пиксель) и записывает их пиксели как числа в файлы .dat в другую папку.

Входные данные — одна строка:

Поле Что писать Пример
1 папка с TIFF-файлами pro/0/
2 папка для .dat pro/2/
3 1 — сообщать о каждом неподошедшем файле, 0 — молча пропускать 1

Результат. pro/2/<имя>.dat для каждого подходящего <имя>.tif.

Пример.

pro/0/  pro/2/  1  E

Тонкости. Расширение исходных файлов — .tif из трёх букв: программа отрезает три последних символа имени и дописывает dat. Разделители \ превращаются в / автоматически.

№37. ADGF — подгонка функцией Гаусса

Что делает. Ищет функцию Гаусса, которая лучше всего описывает кривую из файла: подбирает положение центра и ширину, минимизируя сумму квадратов отклонений. Поиск идёт с графическим сопровождением, в конце рисуется график кривой и найденного гауссиана.

Что нужно заранее. Кривая — двоичный файл .dat из N чисел, записанных с постоянным шагом d = X/N. Координата точки j (от 0 до N−1) — x(j) = d·(j + (1−N)/2), то есть кривая центрирована на нуле.

Входные данные — одна строка:

Поле Что писать Пример
1 Nm — сколько раз вычислять гауссиан при поиске 200
2 N — число точек кривой 301
3 X — длина области аргумента 0.12
4 x — начальное положение центра 0.002
5 w — начальная ширина на полувысоте 0.032
6 dx — шаг поиска по центру 0.0002
7 dw — шаг поиска по ширине 0.0002
8 m: 1 — записывать протокол поиска 1
9 файл с кривой pro/0/ep01.dat

Результат. В папке pro: график adgf.png (над ним — найденные x, w и высота M) и, если m = 1, файл adgf.txt со строкой «x w M сумма квадратов» на каждое вычисление.

Пример.

200  301 0.12 0.002 0.032 0.0002 0.0002 1   pro/0/ep01.dat 

№43. DAT to TXT — двоичный файл в текст

Что делает. Переписывает числа из .dat в текстовый файл — для программ, которые понимают только текст.

Входные данные — одна строка:

Поле Что писать Пример
1 файл .dat без расширения pro/0/in999
2 новый файл без расширения (будет .txt) pro/1/in999
3 n — сколько чисел в строке 1
4 M — формат: 1 — с плавающей точкой, 2 — целые 1
5 N: при M = 1 — ширина числа (10 → 3 знака после точки, 11 → 4 и т. д.); при M = 2 — множитель 11
6 C: при M = 2 — вычитаемая константа (при M = 1 не важна) 0

Результат. pro/1/in999.txt.

Пример.

pro/0/in999 pro/1/in999  1  1  11  0 

Тонкости. При M = 2 каждое число умножается на N, из него вычитается C, и результат пишется целым числом шириной 5 позиций — значит, не больше четырёх цифр. Вычитание убирает неизменный «фон», умножение делает числа целыми; подходящие N и C подберите по графику исходных данных.

№46. PIC to DAT — пиксели картинок в числа

Что делает. Для каждой картинки папки (JPG, PNG, GIF) записывает значения её пикселей как вещественные числа в файл .dat — для дальнейшей математической обработки.

Входные данные — одна строка:

Поле Что писать Пример
1 папка с картинками, с разделителем в конце pro/1/
2 папка для .dat, с разделителем в конце pro/2/
3–5 необязательно: веса R G B для перевода в оттенки серого 1 1 1

Результат. pro/2/<имя>.dat для каждой картинки. Без весов каждый пиксель даёт три числа (красный, зелёный, синий) — всего 3·W·H чисел. С весами — одно число g = (R·r + G·g + B·b)/255 на пиксель, файл втрое меньше.

Пример.

pro/1/  pro/2/ 

Тонкости.

№48. PIC to XYProf — профили картинки

Что делает. Складывает цвета каждого пикселя картинки (JPG или PNG), усредняет полученную матрицу по столбцам и по строкам и получает две кривые — профиль по X и профиль по Y. Записывает их и рисует графики.

Входные данные — одна строка:

Поле Что писать Пример
1 путь к картинке с расширением pro/0/m91.jpg
2, 3 начало и конец оси X на графике 0 1
4, 5 начало и конец оси Y на графике 0 1

Результат. Рядом с картинкой: m91X.dat и m91Y.dat — столбцы чисел, m91X.png и m91Y.png — графики.

Пример.

pro/0/m91.jpg  0 1 0 1 

Тонкости. Несмотря на расширение, файлы X.dat и Y.dat — текстовые (число в строке), а не двоичные.

№53. MAT to LINE — значения вдоль отрезка

Что делает. Берёт из матрицы значения вдоль прямого отрезка между двумя точками (с интерполяцией), записывает их и рисует график.

Входные данные — одна строка, ровно девять полей:

Поле Что писать Пример
1 файл матрицы без .dat pro/0/m001
2 файл результата без расширения pro/1/new
3, 4 nx, ny — размеры матрицы 400 100
5, 6 x1, y1 — начало отрезка 0 0
7, 8 x2, y2 — конец отрезка 399 99
9 n — сколько точек взять на отрезке 100

Координаты — номера точек, считая с нуля: x от 0 до nx−1, y от 0 до ny−1. Они могут быть дробными.

Результат. pro/1/new.dat (n чисел) и график pro/1/new.png: кривая нормирована на интервал 0–1, над графиком — координаты концов, минимум и максимум.

Пример.

pro/0/m001  pro/1/new  400 100 0 0 399 99 100 

Тонкости. Полей должно быть ровно девять. Лишняя буква E в конце вызовет сообщение Input data are incomplete!.

№55. DAT MOD 2 — операции над всеми файлами папки

Что делает. Выполняет одну математическую операцию над каждым числовым файлом папки.

Входные данные — одна строка:

Поле Что писать Пример
1 номер операции, 1–10 3
2 параметр C 100
3 папка с исходными файлами, с разделителем в конце pro/1/
4 вторая папка (нужна операциям 1 и 2, но пишется всегда), с разделителем в конце pro/2/
№ Операция (a — массив из первой папки, b — из второй)
1 a / b; значения b меньше C заменяются на C (C > 0)
2 a · b
3 a + C
4 a · C
5 a + линейная функция от C в начале до −C в конце (поправка фона)
6 exp(C·a)
7 ln(a); значения меньше C заменяются на C
8 sin(C·a)
9 cos(C·a)
10 a в степени C

Результат. Файлы 0001.dat, 0002.dat, … — в первой папке.

Пример.

3 100 pro/1/ pro/2/ 

Тонкости.

№65. DAT MOD 1 — операции над одним массивом

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

Входные данные — одна строка:

Поле Что писать Пример
1 номер операции, 1–14 3
2 параметр C 100
3 исходный файл pro/0/in999.dat
4 второй файл (нужен операциям 1 и 2; иначе пишется любой путь) pro/1/in999.dat
5 файл результата pro/1/in998.dat

Операции 1–10 — те же, что у №55. Дополнительно:

№ Операция
11 для каждой строки матрицы (длина строки nx — степень двойки) — свёртка с гауссианом ширины w и ширина самого высокого пика; результат — кривая длиной ny. C = nx·1000 + w, например 1024020 (w в шагах сетки)
12 транспонирование матрицы; C = nx
13 среднее по строкам (результат — вектор); C = nx
14 среднее по столбцам; C = nx

Результат. Третий файл.

Пример.

3 100 pro/0/in999.dat pro/1/in999.dat pro/1/in998.dat   E

Тонкости. Для операций 1 и 2 массивы должны быть одного размера. Матрица в файле хранится по строкам: сначала первая строка, потом вторая.

№71. DAT to TIFF 1 — матрица в 16-битный TIFF

Что делает. Записывает матрицу из .dat в TIFF-файл: 16 бит на пиксель, без сжатия.

Входные данные — одна строка:

Поле Что писать Пример
1, 2 ширина и высота матрицы 100 165
3 порядок байтов: 0 — Юникс, 1 — Windows (автор советует 1) 1
4 путь к .dat от папки pro, без расширения 0/001

Результат. TIFF с тем же именем: pro/0/001.tif.

Пример. Буква E в конце не читается — она только показывает, что после последнего поля есть пробел:

100 165 1 0/001 E

Тонкости.

№77. DAT MOD 1 — преобразования матрицы в файле

Что делает. Пять операций над одним файлом: транспонирование, ограничение значений, удаление выбросов и сглаживание шума, отражение, график минимумов и максимумов строк.

Входные данные — одна строка; первые четыре поля общие:

Поле Что писать Пример
1 номер операции, 1–5 1
2 папка с разделителем в конце — или *, если пути файлов пишутся полностью от главной папки pro/0/
3 исходный файл m001.dat
4 файл результата m001t.dat
5 … числа операции, см. ниже 400 100
№ Числа Что делает
1 W H транспонирует матрицу W×H (строки становятся столбцами)
2 Mi Ma всё, что меньше Mi, делает равным Mi; больше Ma — равным Ma
3 W H N S заменяет точки, отличающиеся от соседей больше чем на S, средним по N соседям (N нечётное, не меньше 3); при S ≤ 0 сглаживает все точки
4 ±W ±H отражает матрицу; знак минус перед размером указывает, какой индекс переворачивать (один или оба)
5 W H рисует график минимума и максимума каждой строки; результат — картинка, её имя пишется без расширения

Результат. Файл результата в той же папке (для операции 5 — .png).

Пример — транспонировать матрицу 400×100 из демонстрационных файлов:

1 pro/0/ m001.dat m001t.dat 400 100 E

Тонкости. Программа проверяет, что размер файла соответствует W×H, и при несоответствии сообщает об ошибке. В операции 5 длиной строки можно считать сумму нескольких строк: вместо 2304×1500 указать 11520×300.

№79. MAT PROP — анализ 16-битных матриц

Что делает. Специальная программа для квадратных матриц из целых чисел 0–65535 — таких, какие записывают 16-битные TIFF-файлы координатных детекторов синхротронного излучения (матрицы получают программой №33). Три операции; номер операции — первое число строки.

Операция 1 — сводка по серии файлов. Поля: 1, рабочая папка (от главной папки), имя отчёта без расширения, общее начало имён файлов, число файлов nA (1–10), число максимумов nB, размер матрицы nC. Файлы должны называться «начало + цифра 0…9» с расширением .dat. В отчёт .txt по строке на файл: минимум, максимум, среднее и координаты nB наибольших значений (координаты считаются сверху вниз).

Операция 2 — увеличенный фрагмент. Поля: 2, папка, начало имени, номер файла nA (0–9), размер матрицы nB, размер фрагмента nC, координаты x и y центра фрагмента. Рисует логарифм фрагмента в оттенках серого с обращённым контрастом (максимум — чёрный) и записывает картинку в файл.

Операция 3 — деление двух матриц и сглаживание. Поля: 3, папка, первый файл, второй файл, имя результата (все без .dat), размер матрицы nB и управляющее число Q. Цифры Q считаются справа налево: p1 — делить заново (1) или взять готовое частное (0); p2 — рисовать картинки исходных файлов; p3 — палитра 0–3; p4 и p5 — размер окна сглаживания N = p4 + 10·p5 (нечётный); p6 — 1 убирает оси; p7 — вариант палитры 3; p8 — 1 рисует логарифм. Результаты: <имя>a.dat / <имя>a.png (частное) и <имя>b.dat / <имя>b.png (сглаженное частное).

Пример (автора; папки task/… есть только на его компьютере):

  1  task/o46/5/d  info  d  1 10 2304 E
  2  task/o46/7/o4g1nc  d  4  2304 100 366 738 E
  3  task/o46/4/d  56  bg19  56b19  2304 0009311 E

Тонкости. Демонстрационных данных у программы нет. Матрицы рисуются перевёрнутыми по вертикали, чтобы выглядеть так же, как в других программах просмотра TIFF.

№80. Векторные вычисления «как в Excel»

В архиве vkacl.zip от 23.05.2026 этой программы ещё нет: строка 80 файла pro00.txt пуста, и меню Index номер 80 не принимает. Описание ниже составлено по сайту автора.

Что делает. Вычисляет несколько функций по формулам на сетке значений аргумента (или по столбцам аргументов из файла), записывает таблицу результатов и рисует график.

Вариант 1 — аргумент на равномерной сетке. Строка начинается с 0:

Поле Что писать Пример
1 0 0
2 nf — двузначное число: единицы — сколько функций (до 9), десятки — 0 нормировать графики, 1 не нормировать 2
3, 4 A1, A2 — начальное и конечное значения аргумента A 0 9
5 nA — число значений аргумента 10
6 имя результата без расширения pro/test
7 … формулы функций от A, по одной на поле A A*A

Результат: pro/test.png (график; над ним — минимум и максимум первых трёх функций) и pro/test.txt (столбцы чисел).

Вариант 2 — аргументы из файла. Строка начинается с числа аргументов na (1–4): na nf nA файл_аргументов файл_результата f1 f2 …. Файл аргументов (.txt, без расширения во входных данных) содержит na столбцов по nA строк; аргументы называются A, B, C, D. Результат — только функции в <файл_результата>.txt и график .png.

Пример (с сайта автора):

0  2  0  9  10  pro/test  A   A*A  E

Тонкости. Формулы пишутся без пробелов, по правилам выражений VKACL (см. Выражения и функции).

Графики

Программы этой группы рисуют числовые данные: кривые, карты матриц, квазитрёхмерные и аксонометрические графики, анимацию сечений. Данные берутся из текстовых файлов или из двоичных .dat (см. Числовые файлы .dat); картинки сохраняются в PNG, а №49 и 50 — в EPS и PDF.

Общие правила записи входных данных — в разделе Как записывать входные данные. Подписи над графиками пишутся без пробелов: вместо пробела ставьте _.

№ Название Для чего
03 DAT to PNG 2 картинки из матриц всех файлов папки
20 1D PIC 1 график кривых
21 2D MAP карта матрицы
22 2D as SET 1D семейство сдвинутых кривых
23 2D as AXON аксонометрия поверхности
24 2D as ANIM анимация сечений
49 EPS 1D кривые в EPS/PDF
50 EPS 2D карта в EPS/PDF
67 1D PIC 2 графики для всех файлов папки
70 DAT to PNG 1 картинка из фрагмента матрицы

Текстовые файлы с числами. Программы №20, 21 и 22 перед чтением заменяют в копии файла табуляции на пробелы, а запятые — на точки. Значит, десятичная запятая допустима, но разделять числа запятыми нельзя — только пробелами, табуляциями или переводами строк.

№03. DAT to PNG 2 — картинки из матриц всех файлов папки

Что делает. Для каждого числового файла папки рисует картинку прямоугольного фрагмента матрицы (или всей матрицы) — без осей и подписей — и записывает её в PNG. Удобно для серий однотипных файлов.

Что нужно заранее. В исходной папке — только двоичные файлы .dat одинакового размера. Папка для картинок существует.

Входные данные — одна строка:

Поле Что писать Пример
1 папка с матрицами pro/1/
2 папка для картинок pro/2/
3, 4 ширина и высота матрицы 640 169
5, 6 сдвиг начала фрагмента по горизонтали и по вертикали (от левого нижнего угла) 0 0
7, 8 ширина и высота фрагмента 640 169
9 отражение: 0 — нет, 1 — по высоте, 2 — по ширине, 3 — по обеим осям 0
10 палитра: 0 — оттенки серого, 1–4 — цветные (лучшие — 3 и 4) 0

Результат. pro/2/<имя>.png для каждого <имя>.dat. Сама программа картинки не показывает — в конце она сообщает папку, а смотреть их удобно программой №54.

Пример. Скопируйте m003.dat из pro/0/ в pro/1/, затем:

pro/1/ pro/2/ 640 169 0 0 640 169 0 0 E

Тонкости. Имена файлов упорядочиваются по алфавиту; у картинки то же имя, что у файла, с расширением .png. Для одного файла удобнее программа №70.

№20. 1D PIC 1 — график кривых

Что делает. Рисует в рамке с осями график одной или нескольких функций из файла. Большинство оформления задано заранее, во входных данных — только главное.

Входные данные — одна строка: девять чисел, подпись, файл.

Поле Что писать Пример
1 nf — число функций 1
2 np — число точек каждой функции 77
3 nb — номер первой точки, которая попадёт на график 1
4 ng — сколько точек рисовать 77
5, 6 x1, x2 — аргумент в первой и последней точке файла 0 76
7 s — масштаб графика (1 — обычный); отрицательный — не показывать, только записать файл 1
8 t — формат файла, см. ниже 3
9 ni — сколько строк (t = 1, 2) или чисел (t = 3) пропустить в начале 0
10 подпись над графиком, _ вместо пробелов рис._1
11 файл с данными pro/0/in999.dat

Форматы: t = 1 — текст столбцами, первый столбец — аргумент, остальные — функции; t = 2 — текст столбцами, только функции; t = 3 — двоичный .dat, сначала все точки первой функции, потом второй и так далее.

Результат. PNG с тем же именем рядом с файлом данных: pro/0/in999.png. График показывается на экране (если s > 0).

Пример.

1 77 1 77 0 76 1 3 0  рис._1 pro/0/in999.dat  E

Тонкости. Отрицательный масштаб удобен в цепочках программ (№57), когда окна с графиками не нужны. Для серии файлов с одинаковой структурой есть №67.

№21. 2D MAP — карта матрицы

Подробный разбор с примером — Разбор: №21 2D MAP.

Что делает. Рисует матрицу как карту: каждая точка — прямоугольник, окрашенный по значению (оттенки серого или цвет). Оси размечаются по заданным пределам аргументов, сбоку — шкала цветов, над картой — подпись, минимум и максимум.

Входные данные — одна строка: nx ny x1 x2 y1 y2 p1 p2 tf sf td Подпись Файл.

Поле Что писать Пример
1, 2 nx, ny — число точек по горизонтали и вертикали 21 21
3, 4 x1, x2 — пределы горизонтальной оси -5 5
5, 6 y1, y2 — пределы вертикальной оси -4 4
7, 8 p1, p2 — ширина и высота прямоугольника точки, px (1–9) 9 9
9 tf — вид графика (1–6) 2
10 sf — множитель размера (1 — обычный) 1
11 td — формат данных и режимы (до трёх цифр) 1
12 подпись, _ вместо пробелов; если не нужна — один _ Матрица_чисел
13 файл с матрицей pro/0/matrix.txt

tf: 1 — полный график, серый; 2 и 3 — полный, цветной (две разные палитры); 4, 5, 6 — то же, но только сама картинка без осей и шкалы (размер ровно nx·p1 × ny·p2).

td: последняя цифра — формат (1 — текст, 2 — двоичный .dat); вторая с конца, если 1, — не показывать график на экране; третья с конца, если 1, — обратить палитру (максимум и минимум меняются местами). Например, 1, 11, 111, 2, 12.

Результат. PNG рядом с файлом данных: pro/0/matrix.png.

Пример.

21 21 -5 5 -4 4 9 9  2 1 1  Матрица_чисел  pro/0/matrix.txt 

Тонкости. Числа идут так: сначала нижняя строка карты слева направо, потом строка над ней и так далее. В текстовом файле разбиение по строкам не важно.

№22. 2D as SET 1D — семейство сдвинутых кривых

Что делает. Рисует функцию двух переменных как серию кривых-сечений, сдвинутых друг относительно друга, с удалением невидимых линий — получается квазитрёхмерный график без искажений в сечениях.

Входные данные — одна строка: двенадцать чисел и файл.

Поле Что писать Пример
1, 2 nx — точек в каждой кривой, ny — число кривых 141 41
3, 4 x1, x2 — пределы аргумента по горизонтали -1 1
5, 6 y1, y2 — значения параметра для первой и последней кривой (подписываются на наклонной оси) 1 100
7 sa — сдвиг левой вертикальной оси, px (к стандартным 90) 1
8 sc — горизонтальный сдвиг кривых: 0 — на один шаг сетки, 1 — на два и т. д. 1
9 sv — вертикальный сдвиг кривых в единицах 0,001 от максимума функции 15
10 dt — формат: 1 — текст, 2 — двоичный .dat 2
11 st — размер чисел на осях, px 20
12 wa — добавка к ширине рисунка, px (к стандартным 900) 20
13 файл с данными pro/0/fxy2.dat

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

Результат. Два графика рядом с файлом: fxy2a.png и fxy2b.png.

Пример.

141 41  -1 1   1 100   1  1   15  2   20 20  pro/0/fxy2.dat 

Тонкости. Лучше всего выходит, когда кривых хотя бы вдвое меньше, чем точек в каждой (ny < nx/2): иначе график сильно вытягивается вправо. Это поправляют параметрами sa и wa.

№23. 2D as AXON — аксонометрия поверхности

Что делает. Рисует поверхность z(x, y), заданную матрицей, в аксонометрической проекции — с осями, подписями и сечениями.

Входные данные — одна строка: двадцать чисел, подпись, файл.

Поле Параметр Что значит Пример
1, 2 nx, ny число точек матрицы по x и y 400 100
3, 4 x1, x2 пределы аргумента x -6 6
5, 6 y1, y2 пределы аргумента y 197 256
7, 8 z1, z2 пределы оси z 0 55.6
9 sm четыре цифры: первая 1 — показать график на экране, остальные три — масштаб в процентах 1100
10 sa две цифры: первая — сечения (1 XZ, 2 YZ, 3 оба), вторая — вертикальные оси (0 обе, 1 правая, 2 левая) 30
11–13 vx, vy, vz направление на точку зрения (важны отношения) 12 18 10
14 dv удалённость точки зрения (автор: десятичный логарифм расстояния) 200
15, 16 sx, sy множители осей x и y относительно оси z 5. 1
17, 18 tx, ty положение подписи, px 9 9
19, 20 kx, ky число точек на графике; если не равны nx, ny, матрица интерполируется 100 100
21 подпись _ вместо пробелов Axon_pro
22 файл двоичный .dat pro/0/m001.dat

Результат. PNG рядом с файлом данных: pro/0/m001.png.

Пример.

400 100 -6 6 197 256 0 55.6 1100 30 12 18 10 200 5. 1 9 9 100 100 Axon_pro pro/0/m001.dat 

Тонкости.

№24. 2D as ANIM — анимация сечений

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

Входные данные — одна строка: пять чисел, подпись, файл.

Поле Что писать Пример
1 nx — точек в каждой кривой 400
2 ny — число кривых (кадров) 100
3, 4 x1, x2 — аргумент в первой и последней точке -20.48 20.48
5 tp — пауза между кадрами, в десятых долях секунды 4
6 подпись, _ вместо пробелов Intensity
7 двоичный файл .dat pro/0/m001.dat

Управление.

Клавиша Действие
Enter запустить анимацию
Пробел остановить
→ / ← остановить; следующий Enter запустит вдвое быстрее / медленнее
↑ остановить и спросить номер кривой (пока не нажмёте Cancel)
↓ пошаговый режим: 0, затем снова ↓ — следующая кривая
Esc выход

Пример.

400 100 -20.48 20.48 4 Intensity pro/0/m001.dat  E

Тонкости. nx·ny не может быть больше, чем размер файла в байтах, делённый на 4.

№49. EPS 1D — график кривых в EPS и PDF

Что делает. Строит график кривых в векторном формате EPS и переводит его в PDF — для статей. Входные данные — смесь чисел и команд PostScript из книги автора (учебник по PostScript); если вы не знаете PostScript, меняйте в примере только числа.

Что нужно заранее.

Входные данные — первые строки файла (рабочая папка — pro):

Строка Что писать
1 ширина и высота рисунка в pt, число кривых, номер результата (3 → файлы f003.eps и f003.pdf)
2 подписи: размер шрифта перед def, координаты подписей перед m, тексты в скобках с кодами шрифтов (I — курсив, L — прямой, ib — нижний индекс, dsN/isN — уменьшить/вернуть размер); последние два числа — сдвиг начала координат
3 оси: перед par — длины осей, размеры рисок, размер чисел, пределы горизонтальной и вертикальной осей; перед parx и parf — первая длинная риска, шаг между длинными, число коротких; axx, axf — нарисовать оси с числами (варианты axx0, axx1, axx2 — без чисел, верхняя без чисел, верхняя с числами)
4 и далее по строке на кривую: номер файла in…dat, множитель, делающий числа целыми (не больше 4 цифр), толщина линии, цвет r g b, начало и конец аргумента, число точек, множитель для приведения к вертикальной оси
последняя путь к папке bin MiKTeX на вашем компьютере

Результат. pro/f003.eps; после ответа Yes на вопрос программы — ещё и pro/f003.pdf, который сразу открывается.

Пример (автора; путь к MiKTeX замените своим):

700 450 1  3
 /FS 26 def  13 412 m (I)I( / )L(I)I()L(0)ib   500 20 m (\()L(D)G(E)I( / )L(E)I(\))L( x 10)L(4)it  gs 77 92 tr
  600 300 6 12 26 -2.4 2.4 0 90 par -2 1 0 parx axx  0 20 0 parf axf
 999  1  1.5 slw  0 0 0  srgb  -2.28  2.28  77  0.1 figl
C:\_vk\Miktex\miktex\bin

Тонкости. Число точек в строке кривой может быть меньше числа значений в файле, но не больше. Перевод в PDF идёт через runsys.bat и работает только в Windows.

№50. EPS 2D — карта матрицы в EPS и PDF

Что делает. Вторая часть «EPS-набора»: рисует матрицу картой контраста в EPS и переводит в PDF.

Что нужно заранее. MiKTeX (как у №49); матрица — двоичный файл pro/m<np>.dat (для примера скопируйте m998.dat из pro/0/ в pro/).

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

Параметр Значение
np номер файла: 998 → pro/m998.dat
nx точек по первому аргументу (вторая размерность вычисляется по размеру файла)
Sc масштаб в процентах (100 — пиксель равен pt)
Sx сдвиг нижней подписи от середины, pt
x1, x2 пределы первого аргумента
y1, y2 пределы второго аргумента
f1, f2 пределы значений функции
m контраст: 1 — цветной, максимум белый; 2 — серый, максимум чёрный; 3 — цветной, максимум чёрный; 4 — серый, максимум белый
pp две цифры — сколько пикселей на точку по x и по y

После #pr в той же строке — подписи осей на PostScript (xti, yti). Вторая строка — путь к папке bin MiKTeX.

Результат. В папке pro: p998.png (голая картинка), p998.eps, p998EPS.txt (картинка в коде EPS, для продвинутых) и, после ответа Yes, p998.pdf.

Пример (автора):

# np=998; nx=400; Sc=100; Sx=-35; x1=-3; x2=4; y1=105; y2=125; f1=0; f2=61.7; m=1; pp=11; #pr /xti{(x)I(, )H ds2 (MKM)H is2}bd  /yti{(z)I(, )H ds2(CM)H is2 40 0 rm (I)I( / I)I()H(0)ib}bd\E
C:\_vk\Miktex\miktex\bin

Тонкости. На сайте автора сказано, что файл берётся из папки data, а результаты пишутся в папку eps; в коде программы и то и другое — папка pro. Русские буквы в подписях PostScript не используются.

№67. 1D PIC 2 — графики для всех файлов папки

Что делает. Для каждого двоичного файла папки рисует график (как №20 с форматом t = 3) и записывает его в PNG, не показывая. Удобно, когда файлов много и они одинаково устроены — например, одна зависимость при разных внешних параметрах.

Входные данные — одна строка из одиннадцати полей:

Поле Что писать Пример
1 nf — число функций 1
2 np — точек на функцию 77
3 nb — первая точка на графике 1
4 ng — сколько точек рисовать 77
5, 6 x1, x2 — начальное и конечное значение аргумента -1 1
7 s — масштаб (меньше 10; 1 — обычный) 1
8 ni — сколько чисел пропустить в начале файла (при ni = np·i пропускаются i первых функций) 0
9 подпись, _ вместо пробелов рис._1
10 папка с файлами pro/1/
11 папка для графиков (можно ту же) pro/1/

Результат. <папка графиков>/<имя>.png для каждого файла.

Пример. Скопируйте in999.dat из pro/0/ в pro/1/ (можно ещё одну копию под другим именем), затем:

1 77 1 77  -1 1  1 0  рис._1 pro/1/  pro/1/ 

Тонкости. Лучше брать папки внутри папки программы и писать относительный путь. Символ _ программа заменяет на пробел не только в подписи, но и в путях к папкам — папки с _ в имени не подойдут.

№70. DAT to PNG 1 — картинка из фрагмента матрицы

Что делает. Как №03, но для одного файла: рисует прямоугольный фрагмент матрицы (или всю матрицу) без осей и записывает в PNG с заданным именем.

Входные данные — одна строка:

Поле Что писать Пример
1 файл матрицы без .dat pro/0/m003
2 файл картинки без .png pro/2/m003
3, 4 ширина и высота матрицы 640 169
5, 6 сдвиг фрагмента по горизонтали и вертикали (от левого нижнего угла) 0 0
7, 8 ширина и высота фрагмента 640 169
9 отражение: 0 — нет, 1 — по высоте, 2 — по ширине, 3 — по обеим 0
10 число из трёх цифр I S P: P — палитра (0 — серая, 1–4 — цветные), S = 1 — не показывать на экране, I = 1 — обратить палитру (минимум белый); ведущие нули можно не писать 4

Результат. pro/2/m003.png; показывается на экране, если S = 0.

Пример.

pro/0/m003 pro/2/m003 640 169 0 0 640 169 0 4 

Тонкости. Если полей меньше десяти, программа сообщит, что чего-то не хватает.

Тексты и файлы

Программы для работы с текстовыми файлами и с файлами вообще: поиск, подсчёт, замена, шифрование, склейка, редактирование, электронные книги.

Общие правила записи входных данных — в разделе Как записывать входные данные.

№ Название Для чего
02 SYMBOL сколько раз символ встречается в файле
05 FIND WORD найти слово во всех файлах папки
15 CIPHER редактор зашифрованных текстов
25 EDITOR большой редактор текстов
26 LINE EDIT править одну строку файла
36 COPY FILEs склеить файлы в один
64 TXT to FB2 электронная книга FB2
72 DAT MOD 2 замены текста во всех файлах папки
75 Exe FILE открыть файл по расширению

№02. SYMBOL — сколько раз символ встречается в файле

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

Входные данные — одна строка, в одном из двух видов:

Вид Что писать Пример
обычный сам символ и сразу, без пробела, путь к файлу @pro/note.txt
по коду знак ^, сразу путь к файлу, пробел, номер символа в Юникоде, пробел ^pro/0/figure.pro 10 E

Результат. Окно с текстом File has this symbol N times.

Пример — сколько строк (символов с кодом 10) в файле:

^pro/0/figure.pro 10 E

Тонкости.

№05. FIND WORD — поиск слова во всех файлах папки

Что делает. Ищет слово во всех файлах с заданным расширением в одной папке, показывает список найденных мест и предлагает посмотреть или отредактировать эти файлы.

Входные данные — одна строка:

Поле Что писать Пример
1 слово (любое, хоть одна буква; без пробелов) @
2 расширение файлов, без точки acl
3 папка без разделителя в конце pro

Результат. Файл pro/word_in_files.txt: по строке на файл — имя и номера байтов, где найдено слово. Он показывается в редакторе, затем программа предлагает выбор:

Кнопка Что будет
See по очереди открываются найденные файлы; курсор стоит на первой букве найденного слова
Edit то же, но файлы можно править; при выходе по Esc файл перезаписывается
Exit конец работы

При просмотре Esc переходит к следующему месту, а крестик окна прекращает работу.

Пример — найти символ @ во всех файлах .acl папки pro:

@  acl  pro E

Тонкости.

№15. CIPHER — редактор зашифрованных текстов

Что делает. Позволяет хранить текстовый файл на диске только в зашифрованном виде и при этом редактировать его как обычный текст. Ключ — число от 1 до 255.

Что нужно заранее. Текстовый файл с латиницей (коды 0–127) и русскими буквами в кодировке windows-1251.

Входные данные — одна строка:

Поле Что писать Пример
1 режим: 1 — отредактировать обычный текст и зашифровать; 2 — расшифровать, отредактировать и снова зашифровать; 3 — только расшифровать и записать 2
2 ключ, от 1 до 255 123
3 путь к файлу pro/0/Эти-глаза-напротив.txt

Результат. Тот же файл, перезаписанный (зашифрованным или расшифрованным — по режиму).

Пример.

2 123 pro/0/Эти-глаза-напротив.txt  E

Тонкости.

№25. EDITOR — большой редактор текстов

Что делает. Открывает указанный файл в большом редакторе — с множеством функций обработки текста и использования его для других операций. Описание редактора — на сайте автора: vkNotepad.

Входные данные — одна строка:

Поле Что писать Пример
1 путь к файлу pro/note.txt

Пример.

pro/note.txt 

Тонкости.

№26. LINE EDIT — правка одной строки файла

Что делает. Показывает в редакторе одну строку файла с заданным номером, предварительно заменив в ней символы ~ на переводы строк; после правки делает обратную замену и записывает строку на место. Удобно для файлов-«баз», где каждая строка — отдельная запись: код программы, подпись к фотографии и т. п. Так, например, устроены pro00.txt и idc00.txt.

Входные данные — одна строка:

Поле Что писать Пример
1 номер строки 63
2 путь к файлу pro00.txt

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

Пример (автора — строка 63 файла с кодом программ):

63  pro00.txt 

Тонкости. pro00.txt — это код готовых программ, а idc00.txt — ваши входные данные. Правьте их, только понимая, что делаете; для пробы возьмите копию файла.

№36. COPY FILEs — склеить файлы в один

Что делает. Складывает несколько файлов побайтно, один за другим, и записывает результат в новый файл. Годится и для текстов, и для музыки.

Входные данные — одна строка:

Поле Что писать Пример
1 папка — только относительно папки программы, без разделителя в конце pro/0
2 имена файлов этой папки через +, без пробелов matrix.txt+matrix.txt+matrix.txt
3 имя нового файла new.txt

Результат. pro/0/new.txt.

Пример.

pro/0  matrix.txt+matrix.txt+matrix.txt  new.txt E

№64. TXT to FB2 — электронная книга

Что делает. Делает электронную книгу формата FB2 из текстового файла с простой специальной разметкой.

Что нужно заранее.

Входные данные — одна строка:

Поле Что писать Пример
1 путь к текстовому файлу с расширением pro/0/mylife.txt

Результат. pro/0/mylife.fb2. Программа предлагает сразу открыть его.

Пример.

pro/0/mylife.txt 

№72. DAT MOD 2 — замены текста во всех файлах папки

В списке автора эта программа носит то же имя, что и №55, но работает с текстом.

Что делает. Меняет текст во всех файлах папки сразу — любого типа. Файлы переписываются на месте, исходного вида не останется.

Входные данные — одна строка: номер операции, папка, тексты.

Поле Что писать Пример
1 номер операции, 1–6 2
2 папка, с разделителем в конце pro/1/
3 … тексты, нужные операции, через пробел старое новое
№ Что делает Тексты
1 переводит русские буквы из windows-1251 в UTF-8 и заменяет в тексте указание windows-1251 на utf-8 —
2 заменяет текст 1 на текст 2 2
3 попеременно: текст 1 → текст 2, затем текст 3 → текст 4, снова текст 1 … — так меняют пары скобок, (…) на […] 4
4 заменяет всё от текста 1 до текста 2 включительно на текст 3: например, все (123) на точку 3
5 сортирует строки по алфавиту —
6 перенумеровывает строки: после каждого перевода строки, пропустив один символ, три следующих заменяет номером 001, 002, … (для списков ссылок) —

Результат. Изменённые файлы в той же папке. Программа ничего не показывает — смотрите результат сами.

Пример.

1 pro/1/  E
2 pro/1/ старое новое E
3 pro/1/ ( [ ) ] E
4 pro/1/ ( ) . E

Тонкости.

№75. Exe FILE — открыть файл по расширению

Что делает. Менеджер файлов особого вида: вы выбираете файл, а программа «исполняет» его в зависимости от расширения.

Расширение Что будет
pdf, htm, jpg, png, gif, mp3, wma, mp4, wmv, avi, flv, mkv, mov открывается программой, которую для этого назначила система (в Линуксе — браузером)
dat рисуется график чисел (формат float, 4 байта); картинка графика записывается рядом, <имя>.png
acl выполняется как программа на VKACL
mid проигрывается музыка
остальные открываются в большом редакторе

После этого программа спрашивает, повторить ли.

Входные данные — одна строка: путь к любому файлу в той папке, с которой начать выбор.

Поле Что писать Пример
1 путь к файлу pro/note.txt

Пример.

pro/note.txt

Тонкости. Вся строка считается именем файла: пишите его с первой позиции, без пробелов (замените их на - или _) и без лишних символов в конце.

Сайты

Эти программы готовят веб-страницы: сайт с фотографиями, слайд-шоу, статью из текста, сложный сайт по разметке, копию чужой статьи, страницу для перевода. Результат — файл .htm, который можно открыть в браузере на своём компьютере или выложить в интернет.

Готовую страницу программа обычно предлагает открыть (кнопки Wait / Go). Если браузер не открылся, найдите файл в папке или кликните runsys.bat в главной папке программы. Общие правила записи входных данных — в разделе Как записывать входные данные.

№ Название Для чего
01 FOTO SITE сайт фотографий с комментариями
04 SLIDE SHOW слайд-шоу по картинкам папки
38 SIMP SITE простой сайт из текста
44 COMP SITE сложный сайт по разметке
52 FOTO SHOW фото-шоу под музыку
66 WEB SITE копия статьи из интернета
74 CH LANG страница с кнопкой перевода

№01. FOTO SITE — сайт фотографий с комментариями

Что делает. Делает заготовку сайта: таблицу иконок фотографий по пять в ряд. Клик по иконке показывает большую фотографию, клик по фотографии возвращает к таблице. Иконки шириной 240 px программа делает сама. Комментарии к фотографиям вы потом дописываете в готовый файл вручную (можно и не дописывать — сайт готов сразу).

Что нужно заранее. Папка с большими фотографиями (разметка страницы рассчитана на ширину около 1280 px), их число кратно пяти. Папка для сайта существует.

Входные данные — семь первых строк файла:

Строка Что писать Пример
1 название сайта для вкладки браузера и соцсетей (на странице не видно) Круиз 25. 12-я часть…
2 заголовок на странице Фотографии с круиза…
3 автор, дата, адреса — что угодно Кон В. Г. . . . 26-06-2025
4 адрес папки с фотографиями на сервере (для будущей публикации) http://kohnvict.narod.ru/s/2506/C/
5 папка с фотографиями на компьютере, с / в конце pro/1/
6 папка для иконок и сайта, с / в конце pro/2/
7 любой HTML-код в самом конце страницы (реклама, ссылки); если не нужен — точка или пробел <iframe … src="icons.htm"></iframe>

Результат. В папке из строки 6: иконки s<имя>.jpg (к имени фотографии спереди добавлена буква s) и страница m9s.htm. Иконки и страница должны лежать в одной папке; m9s.htm можно переименовать.

Пример (автора). Скопируйте m91.jpg … m95.jpg из pro/0/ в pro/1/ и icons.htm из pro/0/ в pro/2/:

Круиз 25. 12-я часть. Фотографии с круиза на теплоходе Александр Пушкин. Виктор Кон. Victor Kohn.
Фотографии с круиза на теплоходе Александр Пушкин в 2025-м году. 12-я часть.
Кон В. Г. . . . 26-06-2025 . . . http://kohnvict.narod.ru
http://kohnvict.narod.ru/s/2506/C/
pro/1/
pro/2/
<iframe frameborder=0 width=860 height=80 src="icons.htm"></iframe>

Тонкости.

№04. SLIDE SHOW — слайд-шоу по картинкам папки

Что делает. Делает страницу слайд-шоу по всем картинкам папки: каталог иконок, удобная навигация, смена кадров. Интернет не нужен — картинки показываются прямо с компьютера.

Что нужно заранее. Папка с картинками в формате, который понимает браузер (PNG, JPG, GIF). Лучше одного размера — иначе они будут приведены к одному.

Входные данные — одна строка:

Поле Что писать Пример
1 папка с картинками — относительно папки программы или полный путь pro/1/
2, 3 числитель и знаменатель отношения высоты картинок к ширине 3 4

Результат. Страница pro/show.htm; программа предлагает её открыть.

Пример — картинки 1280×960 (отношение 3 : 4) в pro/1/:

pro/1/ 3 4 E

Тонкости.

№38. SIMP SITE — простой сайт из текста

Что делает. Превращает обычный текстовый файл в веб-страницу по шаблону автора. Разметка почти не нужна.

Что нужно заранее. Текстовый файл .txt: в первой строке — заголовок статьи, во второй — автор и что-нибудь о нём (всё в одну строку), с третьей — сам текст; абзацы разделяются пустой строкой.

Входные данные — одна строка:

Поле Что писать Пример
1 путь к текстовому файлу без .txt pro/0/exam0

Как работает. Сначала текст открывается в редакторе — его можно подправить. После выхода по Esc рядом создаётся страница.

Результат. pro/0/exam0.htm.

Пример.

pro/0/exam0  E

Тонкости. Файл exam0.txt — одновременно образец и инструкция по подготовке текста. Не правьте его, а скопируйте под другим именем. Если нужна страница посложнее — №44, если для перевода — №74.

№44. COMP SITE — сложный сайт по разметке

Что делает. Делает сайт на HTML, CSS и JavaScript, но писать на этих языках не нужно: текст размечается простыми трёхсимвольными командами. Описание разметки — на сайтах автора txthtmh и txt-htm-ex.

Как устроены проекты. Рабочая папка — pro/sites/. Каждый сайт — проект с номером от 01 до 99: текст проекта 2 лежит в pro/sites/pro02.txt, готовый сайт — pro/sites/pro02.htm, дополнительные файлы (объекты txthtmo.txt, внешние тексты txthtmt.txt, картинки, музыка) — в папке pro/sites/02/. Проект 01 уже есть: он показывает все возможности разметки. Новый проект создаётся сам — копированием проекта 01, когда вы впервые укажете его номер.

Входные данные — одна строка из двух чисел: номер проекта и номер операции.

Операция Что делает
1 открыть текст проекта в большом редакторе
2 собрать сайт
3 править объекты — по одному; номер объекта выбирается в таблице из 99 кнопок (работают 9), кнопка 99 — выход
4 править внешние тексты — повторяющиеся фрагменты, по одному на строку
5 открыть в браузере описание разметки (pro/sites/txthtmh.htm)

Результат. pro/sites/proNN.htm.

Пример — удобно сразу записать пять строк и выбирать операцию курсором:

2 1
2 2
2 3
2 4
2 5

Тонкости.

№52. FOTO SHOW — фото-шоу под музыку

Что делает. Делает страницу фото-шоу: фотографии сменяются автоматически под музыку, есть панель управления и правила (скрыты, открываются кнопкой).

Что нужно заранее. Файл данных .txt (путь считается от папки pro):

Строка файла данных Что писать
1 название сайта (для вкладки и соцсетей)
2 комментарий к показу — любой длины, он прокручивается
3 адрес mp3: в интернете (http://…) или на компьютере (file:///…)
4 и далее адреса фотографий, по одному на строку, тоже http:// или file:///

Последняя строка тоже должна кончаться переводом строки.

Входные данные — одна строка:

Поле Что писать Пример
1 файл данных — от папки pro, без .txt 0/in
2 имя страницы — от папки pro, без .htm out

Как работает. Файл данных сначала открывается в редакторе; после выхода по Esc программа собирает страницу.

Результат. pro/out.htm.

Пример (файл данных pro/0/in.txt есть в vkacld.zip):

0/in out 

Тонкости. Полный путь с буквой диска для файла данных задавать нельзя. Оформление и скрипт страница загружает с сайта автора, поэтому смотреть её нужно при подключённом интернете. Автор оптимизировал показ под Google Chrome.

№66. WEB SITE — копия статьи из интернета

Что делает. Помогает переложить интересную статью из интернета в свой аккуратный формат: текст отдельно, картинки отдельно — таблицей иконок, которые открываются по клику. Работа полуавтоматическая: часть шагов вы делаете вручную, строго по порядку.

Входные данные — восемь первых строк файла:

Строка Что писать
1 путь к будущему файлу страницы (полный или от папки программы)
2 название сайта для вкладки браузера и соцсетей
3 ссылка на источник
4 файл со списком таких статей (относительно будущей страницы)
5 заголовок, который увидит читатель
6 фоновая картинка (относительно будущей страницы)
7 любой HTML-код в самом верху страницы; если не нужен — один пробел
8 параметры картинок: менять только значения после =

Параметры восьмой строки: n — число картинок (0 — без картинок, остальное тогда не важно); w, h — их ширина и высота; af — общее начало адресов картинок; ef — окончание (расширение). Картинки нумеруются двумя цифрами: af + 01 + ef, af + 02 + ef, …

Как работать.

  1. Выйдите из редактора по Esc. Программа запишет страницу и откроет её в большом редакторе.
  2. Выделите текст статьи на сайте-источнике, скопируйте (Ctrl+C) и вставьте в место с подсказкой (Ctrl+V).
  3. Проверьте, что абзацы разделены ровно одной пустой строкой. Строку-заголовок можно выделить знаком $ в начале и в конце.
  4. В меню редактора выберите кодировку UB (Unicode Big Endian) и концы строк как в Windows. Выйдите по Esc.
  5. Программа сделает замены и снова откроет текст. Ничего не меняйте, только выберите кодировку UTF-8 General marker и выйдите по Esc.

Результат. Файл из строки 1. Сам он не открывается — найдите и откройте его в браузере.

Пример (адреса условные):

pro/1/article.htm
Название для вкладки браузера
https://example.ru/source-article
readme.htm
Заголовок статьи
../0/bgim2.gif
 
n=0; w=900; h=675; af="http://example.ru/pics/"; ef=".jpg";

Тонкости. Пример автора во входных данных ссылается на его папки и работает только на его компьютере — подготовьте свои данные. Ссылку на источник и автора статьи оставляйте обязательно.

№74. CH LANG — страница с кнопкой перевода

Что делает. Превращает текстовый файл в веб-страницу с кнопкой выбора языка: Google переводит её с русского на любой из 54 языков. Переведённый текст можно скопировать.

Что нужно заранее. Текстовый файл .txt:

Входные данные — одна строка:

Поле Что писать Пример
1 путь к текстовому файлу без .txt pro/0/MFL1s

Результат. Текст копируется в pro/b/textforsite.js, а в браузере открывается страница pro/b/ini-fr01.htm.

Пример.

pro/0/MFL1s E

Как перевести. Нужен интернет. Выберите язык кнопкой на странице и пролистайте весь текст — Google переводит то, что появилось на экране. Затем Ctrl+A, Ctrl+C и вставьте текст в любой редактор.

Тонкости.

Звук, анимация, игры

Презентации, слайд-шоу под музыку, проигрыватель mp3, игры и демонстрационные анимации. Общие правила записи входных данных — в разделе Как записывать входные данные.

№ Название Для чего
27 LECTURE показ презентации или картинок папки
41 GAME PIC игра-мозаика
42 GAME MOV движение упругих шаров
63 FM-PLAYER проигрыватель mp3 в браузере
69 vkSS слайд-шоу под музыку с переходами
99 DEMO рекламная анимация VKACL

№27. LECTURE — показ презентации и картинок

Что делает. Три связанных применения:

  1. Показ доклада из zip-архива со слайдами-картинками — во весь экран, с быстрым переходом к любому слайду через таблицу иконок.
  2. Просмотр всех JPG и PNG в любой папке — и заодно подготовка архива для первого режима.
  3. Запуск программ на VKACL прямо из презентации: анимаций, расчётов, дополнительных материалов к слайдам.

Входные данные — одна строка:

Поле Что писать Пример
1 zip-архив презентации (режим 1) или папка с картинками, с разделителем в конце (режим 2); лучше относительно папки программы zip/240725.zip
2 необязательно: сколько пикселей снизу оставить свободными (чтобы видеть панель задач); по умолчанию 25 0

Управление.

Действие Клавиша Или клик мышью
следующий слайд → в правой верхней четверти
предыдущий слайд ← в левой верхней четверти
таблица иконок всех слайдов (клик по иконке — к слайду) ↑ в правой нижней четверти
выход ↓ (автор называет и Esc) в левой нижней четверти
запустить программу VKACL для текущего слайда Enter —
записать архив lect.zip (только в режиме 2, когда показан слайд) Z —

Как устроен архив презентации.

Как подготовить архив. Откройте в режиме 2 папку со слайдами (имена любые), нажмите Z — в главной папке программы появится lect.zip с папкой lect. Папку anim и программы добавьте в архив вручную, затем переименуйте архив как угодно (расширение .zip).

Результат. Показ на экране. В режиме 2, если таблицы иконок s999 ещё нет, программа строит её (это небыстро) и сохраняет в папку, чтобы в следующий раз не строить заново.

Пример — демонстрационная презентация из vkacld.zip:

zip/240725.zip 0

Тонкости.

№41. GAME PIC — игра-мозаика

Что делает. Тренажёр зрительной памяти. Вы рассматриваете картинку, затем она режется на 48 квадратов 100×100, которые перемешиваются. Нужно собрать картинку обратно, меняя квадраты местами попарно.

Входные данные. Нет — программа сразу открывает окно выбора картинки в папке pro/0/.

Как играть.

  1. Выберите картинку размером 800×600 — например, game.jpg из vkacld.zip.
  2. Рассмотрите и запомните её, затем нажмите Enter.
  3. Наведите мышь на квадрат и нажмите Пробел (или кликните) — он отметится крестиком. Наведите на квадрат, с которым надо поменяться, и снова Пробел или клик.
  4. Повторяйте, пока картинка не соберётся. Надоело — закройте окно крестиком.
  5. Программа спросит, сыграть ли ещё.

Тонкости. Если выбранная картинка не 800×600, программа уменьшит или увеличит её, запишет как pro/0/tmp.jpg и попросит запустить игру снова и выбрать этот файл.

№42. GAME MOV — движение упругих шаров

Что делает. Демонстрация законов механики: пронумерованные твёрдые шары летают в замкнутой области, отскакивая от стенок, препятствий и друг от друга без потери энергии. Четыре сюжета; параметры можно менять и наблюдать.

Входные данные — одна строка: номер сюжета и его параметры.

Сюжет Что писать после номера
1 — прямоугольная область W H Nh Nv E Ns R — ширина и высота области (px), шаров по горизонтали и по вертикали, полная энергия, сколько шаров сначала движется, радиус шара
2 — круглая область со столбиками Dr Dp Dw Np Nw RDp RDw SS Nb — диаметры области, шара и столбика (px), число шаров и столбиков, диаметры кругов расстановки шаров и столбиков (% от области), начальная скорость (px), число неподвижных шаров между подвижными
3 — две области, соединённые щелью как в сюжете 1, плюс ширина щели Ws
4 — сложная область, всё задано скорость шаров V (подберите под свой компьютер)

Управление. Enter — движение, Пробел — остановка, Esc — выход.

Пример — значения автора, оптимальные для каждого сюжета:

1  500 500 13 13 900 1 10
2  400 40 20 6 12 90 60 20 10
3  600 400 6 8 200 12 10 22
4  6

Тонкости.

№63. FM-PLAYER — проигрыватель mp3 в браузере

Что делает. Делает страницу-проигрыватель для всех mp3-файлов папки с удобной навигацией и открывает её в браузере. Интернет не нужен.

Входные данные — одна строка:

Поле Что писать Пример
1 папка с mp3 — полный путь или от папки программы pro/1/1/
2 вид проигрывателя, 1 или 2 2

Результат. Страница pro/b/mp.htm; программа предлагает открыть её.

Пример.

pro/1/1/  2  E

Тонкости.

№69. vkSS — слайд-шоу под музыку

Что делает. Показывает слайд-шоу по заранее написанному протоколу: картинки сменяются под фоновую музыку с эффектными переходами, могут увеличиваться и плыть по экрану, на них появляются надписи.

Входные данные — одна строка:

Поле Что писать Пример
1 путь к файлу протокола pro/0/sky0.vks

Протокол — текстовый файл:

Адреса — в виде URL: http://… или для своего компьютера File:C:/папка/файл. Музыка — только MIDI (.mid).

Переходы: 0 — мгновенно; 1 — старая картинка схлопывается к центру; 2, 3, 4 — новая вырастает из центра, из левого верхнего, из левого нижнего угла; 5 — падает сверху; 6 — наползает слева; 7 — плавное смешивание; 8 — затухание и проявление; 9–12 — новая выталкивает старую слева, справа, сверху, снизу.

Управление.

Клавиша Действие
Esc выход
Enter пауза; повторно — музыка сначала и следующий кадр
↑ / ← / Backspace / PgUp назад на 1 / 2 / 3 / 4 кадра
PgDn вперёд на 5 кадров
Home / End в начало / в конец
C / O выключить / включить музыку
любая другая вперёд на 1 кадр

Пример — протокол pro/0/sky0.vks; первые его строки:

File:C:/0/sky/Julio-Iglesias-Je-Nai-Pas-Change.mid|1 840 640 -1 -1
#File:C:/0/sky/sky.png|400 0 0 0
#File:C:/0/sky/s000.jpg|400 1 0 0
#File:C:/0/sky/s001.jpg|400 2 0 0

Картинки и музыки к нему в архивах нет: их нужно скачать с Яндекс-диска автора (ссылка — во входных данных программы) и положить в C:\0\sky\.

Тонкости.

№99. DEMO — рекламная анимация VKACL

Что делает. Показывает анимации, рекламирующие язык VKACL: картинку, которая растёт, и текст, который появляется строка за строкой, под музыку.

Входные данные. Нет. Поставьте курсор в начало файла и нажмите Esc.

Как работать. В меню выберите Picture size, Text size или All together; Exit — выход. Остановить анимацию — крестиком в правом верхнем углу окна.

Автоматизация и система

Программы, которые запускают другие программы, файлы и команды: панель кнопок, «проигрыватель в проигрывателе» для своего кода, цепочки готовых программ, команды операционной системы. Общие правила записи входных данных — в разделе Как записывать входные данные.

№ Название Для чего
28 RUNNER панель из 176 кнопок
29 PLAYER свой код на VKACL: написать и выполнить
56 CHAIN 1 несколько программ подряд
57 CHAIN 2 цепочка с данными прямо в протоколе
76 SYSTEM команды операционной системы
78 CHAIN 3 цепочка для каждого файла папки

№28. RUNNER — панель кнопок

Что делает. Показывает таблицу из 176 кнопок (11 × 16). Каждую кнопку вы настраиваете сами: открыть файл в редакторе, запустить его средствами системы, выполнить как программу VKACL, открыть папку. Так под рукой оказываются самые нужные файлы, документы и программы.

Входные данные. При запуске файл входных данных не показывается — сразу появляется таблица. Первая строка файла — пояснение (не читается), со второй строки идут кнопки: строка 2 — кнопка 1, строка 3 — кнопка 2 и так далее. Формат строки:

Название кнопки| действие путь
Действие Что делает с файлом
1 открывает в большом редакторе
2 открывает программой, назначенной в системе для этого типа файлов (только Windows)
3 выполняет как программу на VKACL
4 открывает в малом редакторе — он умеет показывать сайты с адресом https
5 открывает папку в проводнике Windows

Путь — полный или от папки программы.

Как работать. Кликните кнопку — действие выполнится, и таблица появится снова (после действия 5 программа, судя по коду, заканчивает работу). Выход — крестик окна таблицы. В заготовке автора первая кнопка Edit ID открывает сам файл кнопок (pro/0.par) — так их и настраивают; изменения сохранятся.

Пример — начало файла кнопок:

Пояснения: первая строка программой не читается
Edit ID| 1 pro/0.par
Справка| 4 help.txt
Заметки| 1 pro/note.txt
О программе| 2 pro/hdata/about.htm
Папка pro| 5 pro

Тонкости.

№29. PLAYER — свой код на VKACL

Что делает. Проигрыватель программ на VKACL, написанный на самом VKACL. Позволяет быстро написать и выполнить небольшую программу — расчёт, график, обработку файла — не выходя из режима проигрывателя. Для серьёзной работы автор советует среду разработки (_rund.bat).

Что нужно заранее. Файл с расширением .pro с кодом. Проигрыватель сам файлы не создаёт — сделайте файл средствами системы, лучше в папке pro/0/. Образец — pro/0/figure.pro из vkacld.zip (рисует функции Бесселя).

Входные данные. Нет — роль инструкции играет сам файл входных данных.

Как работать.

  1. Появится окно с кнопками Help, Start, Exit. Help открывает инструкцию — прочитайте её.
  2. Start открывает выбор файла .pro в папке pro/0/.
  3. Код появляется в редакторе. Поправьте его и выйдите по Esc: файл сохранится и выполнится. Если закрыть редактор крестиком, ничего не сохранится и не выполнится.
  4. При ошибке в коде появится сообщение, и код откроется снова для правки.
  5. После выполнения выберите: Current — снова этот файл, New — другой, Nothing — выход.

Пример — файл pro/0/test.pro из двух строк:

# a=2^10; b=sqr(2); c=4*art(1);
#m [op=win;] 2^10 = \G a;\n корень из 2 = \G b;\n пи = \G c;\E

Тонкости. В коде нельзя использовать команды #stop и #exit, переменные на букву U и последние элементы текстового массива t() (с индексами больше KY−10000): их занимает сам проигрыватель. Как писать на VKACL — начиная с главы Начало работы.

№56. CHAIN 1 — несколько программ подряд

Что делает. Сама ничего не делает — запускает другие готовые программы одну за другой, каждую со своими заранее подготовленными входными данными.

Что нужно заранее. Входные данные запускаемых программ должны быть уже записаны без ошибок — исправить их по ходу не получится. Проще всего один раз запустить каждую программу из меню Index и довести её данные до ума (или отредактировать нужную строку idc00.txt программой №26).

Входные данные — одна строка из пар чисел:

Поле Что писать Пример
1, 2 номер программы и номер строки в её входных данных 31 1
3, 4 следующая пара 54 1
… и так далее

Пример — запустить №31 и №54, каждую с первой строкой её данных:

31 1 54 1 

Тонкости.

№57. CHAIN 2 — цепочка с данными в протоколе

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

Входные данные — первые строки файла (позиция курсора не важна, выполняется верхний протокол):

Пример (автора) — нарисовать график №20 и карту №21:

20  1 77 1 77 0 76 1 3 0  рис._1 pro/0/in999.dat  E
21  21 21 -5 5 -4 4 9 9  2 1 1 Матрица_чисел  pro/0/matrix.txt E
@

Тонкости.

№76. SYSTEM — команды операционной системы

Что делает. Заменяет командные файлы: выполняет команды операционной системы, записанные по одной на строку в jsc1.txt (Windows) или jsc2.txt (Линукс) в главной папке. Систему программа определяет сама.

Что нужно заранее. Свои команды в jsc1.txt. Сейчас там команды автора (пути к его программам) — замените их. Команда — имя программы с аргументами; папки в путях Windows разделяйте знаком /; лишних пробелов не ставьте. Например:

notepad.exe C:/vkacl/pro/note.txt
explorer.exe C:/vkacl/pro

Входные данные — одна строка: номера строк файла команд через пробел.

Поле Что писать Пример
1 … номера команд, которые выполнить 1 2

Пример.

1 2 

Тонкости.

№78. CHAIN 3 — цепочка для каждого файла папки

Что делает. Как №57, но в пакетном режиме: выполняет протокол по очереди для каждого файла указанной папки. Годится для программ, которые обрабатывают один файл.

Входные данные — первые строки файла:

Строка Что писать
1 папка с файлами, относительно папки программы
2 и далее протокол, как у №57: номер программы в двух позициях, пробел, её входные данные; конец — строка @

В данных вместо имени файла пишут \T$1 $2\u32; — это полный путь к очередному файлу и пробел после него. Номер файла (1, 2, …) доступен как \I1 $0; и годится для составления новых имён: например, 2\I1 $0;f превратится в 21f, 22f, …

Пример (автора) — дважды убрать выбросы и транспонировать каждую матрицу 2304×2304 из pro/5/ программой №77:

pro/5/ E
77 3 *  \T$1 $2\u32;  \T$1 $2\u32;   2304  2304  25  0 E
77 1 *  \T$1 $2\u32;  \T$1 $2\u32;   2304  2304  E
77 3 *  \T$1 $2\u32;  \T$1 $2\u32;   2304  2304  25  0 E
77 1 *  \T$1 $2\u32;  \T$1 $2\u32;   2304  2304  E
@

Тонкости. В этом примере результат каждой операции записывается поверх исходного файла — работайте с копиями. Демонстрационных данных у программы нет.

Разное

Справочники и калькулятор. Общие правила записи входных данных — в разделе Как записывать входные данные.

№ Название Для чего
30 UNICODES какие символы есть в шрифте
31 PTOE таблица Менделеева — справочник и записная книжка
62 CALCUL калькулятор на 8 переменных

№30. UNICODES — символы шрифтов

Что делает. Показывает таблицами все символы выбранного шрифта с их номерами в Юникоде. Нужна, чтобы узнать, какие символы (буквы, греческие, математические знаки) можно использовать в надписях программ, например №08.

Входные данные. Нет — программа сразу показывает список шрифтов.

Как работать.

  1. Выберите шрифт из списка (Arial, Times New Roman, Verdana и др.) или нажмите New и введите имя своего шрифта. Exit — выход.
  2. На странице — 340 символов: 17 строк по 20. Слева — номер первого символа строки, сверху — номера столбцов 0–19; номер символа = номер строки + номер столбца.
  3. Любая клавиша или клик — следующая страница; PgUp или ↑ — предыдущая; Esc — назад к списку шрифтов.

Тонкости. Если шрифта на компьютере нет, Java подставит свой шрифт по умолчанию — таблица будет, но не того шрифта.

№31. PTOE — таблица Менделеева

Что делает. Интерактивная таблица Менделеева и одновременно записная книжка: клик по элементу открывает текст о нём, который можно дополнять и исправлять — программа всё запомнит. В текстах есть ссылки на ресурсы интернета, в том числе на статьи из книги автора.

Входные данные. Нет. Поставьте курсор в начало первой строки и нажмите Esc.

Как работать.

  1. Кликните по клетке элемента — его текст откроется в большом редакторе.
  2. Правьте и выходите по Esc: изменения сохранятся в pro/b/ptoe.dbn.
  3. Чтобы открыть ссылку из текста, поставьте на неё курсор и нажмите F4.
  4. Чтобы закончить, кликните по картинке вне клеток элементов — например, по портрету Менделеева.

Тонкости. Первая ссылка ведёт на статью автора и точно работает; другие со временем могут исчезнуть — заменяйте их новыми.

№62. CALCUL — калькулятор

Подробный разбор с примерами — Разбор: №62 CALCUL.

Что делает. Вычисляет выражения и показывает в окне значения восьми переменных a b c d e f g h. В одной строке можно записать целую цепочку вычислений — использовать уже посчитанные переменные в следующих формулах.

Входные данные — одна строка присваиваний вида переменная=выражение;:

Что Правило
присваивание имя=выражение; — точка с запятой в конце обязательна
операции + - * / ^ (степень); < — меньшее из двух, > — большее из двух
функции abs sqr log exp sin cos tan ars arc art int sgn sfi cfi bj0 bj1, аргумент в скобках
числа 2.5, 2,5, 4.4e1
результат то, что присвоено переменным a–h

Результат. Окно со значениями a…h в формате вида 1.9635+01 (то есть 1,9635·10¹).

Пример (автора):

x=-4.4e1; h=abs(x); a=sqr(h); b=log(h); c=exp(x); d=sin(x); e=ars(d); f=cos(x); g=arc(d); 

Тонкости. Строк можно держать сколько угодно, выполняется та, в начале которой курсор. Лишнюю букву E в конце не ставьте — она будет понята как часть выражения. Подробности и ловушки — в разборе.

Разбор: №08 SLIDE MAKER

Программа №08 собирает картинку-слайд: на основу заданного размера кладёт другие картинки и пишет поверх них текст. Так делают титульный слайд доклада, объявление, заставку к видео, кнопку для сайта. Краткое описание — в каталоге: №08 SLIDE MAKER.

В этом разборе мы сначала запустим пример автора, а потом соберём свой титульный слайд 1280×720 из трёх картинок и двух надписей.

Что понадобится

Файл Что это Размер
000000.png чёрный прямоугольник 256×192
m91.jpg фотография 1280×960
jad.jpg портрет 220×250

Шаг 1. Открываем программу

  1. Запустите _runp.bat.
  2. Нажмите Index, затем кнопку 8.
  3. Откроется редактор. Наверху — пример входных данных, ниже — варианты автора и его инструкция.

Программа №08 читает первые строки файла и выполняет только верхний вариант. Позиция курсора ей не важна.

Шаг 2. Пример автора

Наверху файла стоит (или впишите сами) такой вариант:

512 512 1 3|slide
 256 256 0 0 0 9 9|000000.png
 256 100 5 1 30  0 255 0 |Arial|на полотно любого размера
 256 200 5 1 30 255 0 0  |Arial|можно ставить картинки
 256 300 5 1 30 255 255 255 |Arial|и тексты любых фасонов

Разберём его построчно.

Строка 1 — 512 512 1 3|slide:

Число Смысл
512 512 основа шириной 512 и высотой 512 пикселей
1 N1 — на основу кладётся одна картинка
3 N2 — будет три надписи
slide имя результата: получатся slide.png и slide.jpg

Строка 2 — картинка: 256 256 0 0 0 9 9|000000.png:

Число Смысл
256 256 центр картинки — в центре основы
0 поворота нет
0 0 скашивания нет
9 9 увеличить в 9 раз по ширине и по высоте
000000.png файл в pro/1/

Чёрный прямоугольник 256×192, увеличенный в 9 раз, становится 2304×1728 и закрывает всю основу — получается чёрный фон.

Строки 3–5 — надписи, например 256 100 5 1 30 0 255 0 |Arial|на полотно любого размера:

Число Смысл
256 100 точка привязки: x = 256 (середина), y = 100 пикселей от верхнего края
5 способ привязки: текст центрируется в точке и по ширине, и по высоте
1 жирный шрифт
30 размер шрифта 30 пикселей
0 255 0 цвет — зелёный
Arial шрифт
на полотно… сам текст, до конца строки

Нажмите Esc. Слайд появится в окне в левом верхнем углу экрана: на чёрном фоне три строки — зелёная, красная и белая, одна под другой. В папке pro/1/ появятся slide.png и slide.jpg.

Затем программа спросит Do you like to change parameters? Ответ Yes снова откроет входные данные — так удобно подгонять слайд понемногу. No закончит работу.

Шаг 3. Как устроены координаты

Для надписи X, Y — точка привязки, а число M (от 1 до 9) говорит, какой частью текст к ней прикладывается:

M слева по центру справа
низом 1 2 3
серединой высоты 4 5 6
верхом 7 8 9

Например, M = 1 — левый нижний угол текста в точке X, Y; M = 5 — центр текста в точке; M = 9 — правый верхний угол в точке.

Шаг 4. Свой слайд

Сделаем титульный слайд 1280×720: фотография во весь слайд, тёмные полосы сверху и снизу для текста, повёрнутый портрет слева, заголовок и подпись. Вставьте в самое начало файла, над примером автора, семь строк:

1280 720 4 2|title
 640 360 0 0 0 1 1|m91.jpg
 640 70 0 0 0 5 0.7|000000.png
 640 650 0 0 0 5 0.7|000000.png
 200 360 5 0 0 1.2 1.2|jad.jpg
 640 70 5 1 64 255 255 255 |Arial|Готовые программы VKACL
 640 650 5 2 40 255 220 0 |Arial|слайд собран программой №08

Что здесь происходит:

Строка Что делает
1280 720 4 2|title основа 1280×720, четыре картинки, две надписи, результат title
640 360 … 1 1|m91.jpg фотография 1280×960 в центре, без изменений: по ширине она точно по слайду, лишнее сверху и снизу обрежется
640 70 … 5 0.7|000000.png чёрный прямоугольник, растянутый в 5 раз по ширине (1280) и сжатый до 0,7 по высоте (≈134): полоса вдоль верхнего края
640 650 … 5 0.7|000000.png такая же полоса внизу — один файл можно класть сколько угодно раз
200 360 5 0 0 1.2 1.2|jad.jpg портрет слева, увеличенный в 1,2 раза и наклонённый на 5°
640 70 5 1 64 … заголовок: по центру верхней полосы, жирный, 64 px, белый
640 650 5 2 40 255 220 0 … подпись: по центру нижней полосы, курсив, 40 px, жёлтый

Нажмите Esc и посмотрите на результат. Если наклон портрета получился не в ту сторону, поменяйте знак угла (-5). Ответьте Yes, поправьте числа, снова Esc — и так, пока слайд не понравится.

Шаг 5. Результат

В папке pro/1/ лежат title.png и title.jpg размером 1280×720. Входные данные сохранились — в следующий раз программа откроет их в том же виде.

Что дальше:

Если что-то не так

Что видно Почему Что делать
File: … is absent!, на месте картинки светлый квадратик файла нет в pro/1/ или опечатка в имени скопируйте файл в pro/1/, проверьте имя и расширение
Font or Text is absent! в строке надписи нет второй черты | или текст пустой формат: числа |шрифт|текст
надпись не там, где ждали y отсчитывается сверху; не тот способ привязки M начните с M = 5 — текст центрируется в точке
картинка пропала её закрыла картинка, записанная ниже поменяйте строки местами
надпись взялась из текста инструкции N2 больше, чем строк надписей N1 и N2 должны точно совпадать с числом строк
последняя надпись не появилась N2 меньше, чем строк надписей увеличьте N2
файл результата назван странно после имени в первой строке стоят пробелы или буква E после | — только имя, до конца строки
шрифт выглядит «не тем» такого шрифта нет на компьютере, Java подставила свой выберите шрифт из списка программы №30

Разбор: №21 2D MAP

Программа №21 рисует матрицу чисел как карту: каждая точка — цветной или серый прямоугольник, по краям — оси с подписями, сбоку — шкала цветов. Так смотрят результаты расчётов, распределения интенсивности, рельеф — любую функцию двух переменных, заданную таблицей. Краткое описание — в каталоге: №21 2D MAP.

В разборе мы нарисуем карту по текстовой таблице, попробуем разные виды графика, затем переведём таблицу в двоичный файл программой №16 TXT to DAT и нарисуем карту уже по нему.

Что понадобится

Установленная программа и архив vkacld.zip, разложенный по папкам (см. Установка). Нужен файл pro/0/matrix.txt из этого архива.

Шаг 1. Смотрим на данные

pro/0/matrix.txt — 21 строка по 21 целому числу от 0 до 99, всего 441 число. Это «холм»: по краям нули, к центру значения растут до 99. Первые строки файла:

  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  0  0  0  0  0  0 17 31 38 42 43 42 38 31 17  0  0  0  0  0  0
  0  0  0  0  0 32 44 51 56 58 59 58 56 51 44 32  0  0  0  0  0

Как программа №21 читает такие данные:

Шаг 2. Первая карта

  1. Запустите _runp.bat, нажмите Index, затем 21.

  2. В редакторе первая строка — как раз наш случай:

    21 21 -5 5 -4 4 9 9  2 1 1  Матрица_чисел  pro/0/matrix.txt 
  3. Курсор уже стоит в начале первой строки (подойдёт и вторая позиция). Нажмите Esc.

Разберём строку поле за полем:

Поле Значение Смысл
nx 21 в каждой строке матрицы 21 точка
ny 21 строк 21
x1, x2 -5 5 горизонтальная ось размечается от −5 до 5
y1, y2 -4 4 вертикальная ось — от −4 до 4
p1, p2 9 9 каждая точка — квадрат 9×9 пикселей, карта будет 189×189
tf 2 полный график: карта, оси, шкала, подпись; цветная палитра 1
sf 1 обычный размер
td 1 данные — текст; показать график на экране; палитра обычная
подпись Матрица_чисел над картой будет «Матрица чисел» — _ стал пробелом
файл pro/0/matrix.txt где лежат числа

Результат. На экране — цветная карта холма с осями и шкалой цветов. Над ней подпись и пара чисел — настоящие минимум и максимум матрицы (0 и 99); шкала цветов показывает значения, нормированные на интервал 0–1. Картинка записана в pro/0/matrix.png — рядом с файлом данных, с тем же именем.

Программа спросит Job is done! Continue? Ответьте Yes, чтобы вернуться к входным данным и попробовать варианты.

Шаг 3. Варианты

Не правьте удачную строку — скопируйте её ниже и меняйте копию; нужный вариант выбирается курсором. Попробуйте по одной правке:

Что поменять Строка Что получится
tf = 1 21 21 -5 5 -4 4 9 9 1 1 1 Матрица_чисел pro/0/matrix.txt оттенки серого
tf = 3 21 21 -5 5 -4 4 9 9 3 1 1 Матрица_чисел pro/0/matrix.txt вторая цветная палитра
tf = 5 21 21 -5 5 -4 4 9 9 5 1 1 _ pro/0/matrix.txt только картинка 189×189, без осей и шкалы (подпись не нужна, но _ писать обязательно)
td = 101 21 21 -5 5 -4 4 9 9 2 1 101 Матрица_чисел pro/0/matrix.txt палитра обращена: максимум и минимум поменялись цветами
td = 11 21 21 -5 5 -4 4 9 9 2 1 11 Матрица_чисел pro/0/matrix.txt график не показывается, только записывается в файл
p1 p2 = 4 4 21 21 -5 5 -4 4 4 4 2 1 1 Матрица_чисел pro/0/matrix.txt карта меньше: 84×84
sf = 2 21 21 -5 5 -4 4 9 9 2 2 1 Матрица_чисел pro/0/matrix.txt весь график вдвое крупнее

Все варианты пишут в один и тот же файл pro/0/matrix.png — каждый следующий заменяет предыдущий.

Как читать td: это число до трёх цифр. Последняя цифра — формат данных (1 текст, 2 двоичный файл). Средняя — 1, если график не показывать. Первая — 1, если обратить палитру. Нули впереди не пишут: 1, 11, 101, 111, 2, 12…

Шаг 4. Переводим таблицу в двоичный файл (№16)

Текст удобен человеку, но большие матрицы программы VKACL хранят в двоичных файлах .dat: по 4 байта на число, без заголовка (см. Числовые файлы .dat). Перевести таблицу умеет программа №16.

  1. В проигрывателе: Index → 16.

  2. Выберите или впишите строку:

    441 1 0 pro/0/matrix E

    Это значит: прочитать 441 число, как вектор (1 во втором поле), ничего не пропуская в начале файла (0), из pro/0/matrix.txt — расширение .txt не пишется. Буква E в конце не читается, она лишь показывает, что после пути есть пробел.

    То же самое можно записать как матрицу — 21 число в строке, 21 строка: 21 21 0 pro/0/matrix E. В режиме матрицы каждая строка матрицы должна стоять на отдельной строке файла.

  3. Нажмите Esc. Появится файл pro/0/matrix.dat.

Проверка: размер файла должен быть 441 × 4 = 1764 байта.

Заметьте: программа №16 заменяет табуляции на пробелы прямо в исходном текстовом файле.

Шаг 5. Карта по двоичному файлу

Вернитесь к программе №21 и добавьте строку, где последняя цифра td — 2, а файл — .dat:

21 21 -5 5 -4 4 9 9 2 1 2 Из_двоичного_файла pro/0/matrix.dat 

Получится та же карта с новой подписью. Картинка снова запишется в pro/0/matrix.png: имя берётся из имени файла данных без расширения. Если хотите сохранить обе картинки, скопируйте matrix.dat под другим именем (например, matrix2.dat) и рисуйте по копии.

Шаг 6. Свои данные

  1. Подготовьте текстовый файл: nx чисел в строке, ny строк; первой записывайте нижнюю строку карты. Таблица из Excel, сохранённая как «текст с разделителями табуляции», подойдёт, но в Excel верхняя строка идёт первой — карта выйдет перевёрнутой по вертикали. Тогда просто переставьте строки в обратном порядке.
  2. Положите файл в папку внутри папки программы, например pro/1/data.txt.
  3. Впишите в №21 строку со своими nx, ny, пределами осей и путём.
  4. Если данных много, сначала переведите их в .dat программой №16 — чтение двоичного файла быстрее.

Если что-то не так

Что видно Почему Что делать
сообщение об ошибке, курсор не в начале строки строка выбирается по курсору поставьте курсор в первую позицию нужной строки
карта «полосатая», картинка сдвинута nx или ny не совпадают с данными проверьте: nx × ny = числу чисел в файле (для .dat — размеру файла, делённому на 4)
числа прочитаны неверно в файле запятые между числами разделяйте числа пробелами
подпись обрезана по первому слову в подписи пробел вместо пробелов _
программа не видит файл опечатка в пути или пробел в нём путь без пробелов, лучше относительный
карта вверх ногами в файле первой идёт верхняя строка переставьте строки
окна нет, а файл есть вторая цифра td равна 1 уберите её: td = 1 или 2

Разбор: №62 CALCUL

Программа №62 — калькулятор выражений. В строке пишут цепочку присваиваний вроде r=2.5; a=r*r;, а программа показывает в окне значения восьми переменных a, b, c, d, e, f, g, h. Строк можно накопить сколько угодно — получается записная книжка формул, которая сохраняется между запусками. Краткое описание — в каталоге: №62 CALCUL.

На самом деле строка калькулятора — это команда присваивания языка VKACL. Поэтому всё, что здесь сказано о выражениях, верно и для программ на VKACL.

Шаг 1. Открываем калькулятор

  1. Запустите _runp.bat, нажмите Index, затем 62.

  2. В редакторе — три строки-примера автора и под ними инструкция:

    X=121; M=0.15/(366-X); a=0.85+(323-X)*M; b=0.85+(97-X)*M;
    x=-4.4e1; h=abs(x); a=sqr(h); b=log(h); c=exp(x); d=sin(x); e=ars(d); f=cos(x); g=arc(d);
    x=4.4e1; a=int(x); b=sgn(x); c=sfi(x); d=cfi(x); e=bj0(x); f=bj1(x); g=x^2; h=2*(x+4)/5;

Шаг 2. Первый расчёт

Поставьте курсор в самое начало второй строки и нажмите Esc. Программа выполнит строку:

Присваивание Что вычисляется Значение
x=-4.4e1; x = −4,4·10¹ −44
h=abs(x); модуль 44
a=sqr(h); квадратный корень 6,6332
b=log(h); натуральный логарифм 3,7842
c=exp(x); экспонента 7,7811·10⁻²⁰
d=sin(x); синус (аргумент в радианах) −0,017702
e=ars(d); арксинус −0,017703
f=cos(x); косинус 0,99984
g=arc(d); арккосинус 1,5885

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

a=  6.6332+00,  b=  3.7842+00,  c=  7.7811-20,  d= -1.7702-02
e= -1.7703-02,  f=  9.9984-01,  g=  1.5885+00,  h=  4.4000+01

Это экспоненциальная запись без буквы E: четыре знака после точки, затем знак и двузначный порядок. 6.6332+00 — это 6,6332·10⁰ = 6,6332; -1.7702-02 — это −1,7702·10⁻² = −0,017702; 4.4000+01 — это 44.

Закройте окно. Программа спросит Job is done! Continue? — ответ Yes вернёт в редактор, No закончит работу.

Шаг 3. Свой расчёт

Допишите в начало файла новую строку — площадь и длину окружности радиуса 2,5, гипотенузу треугольника 3–4–5 и ещё несколько величин:

r=2.5; p=4*art(1); a=p*r^2; b=2*p*r; c=sqr(3^2+4^2); d=art(1)*180/p; e=exp(1); f=log(10); g=10<3; h=10>3;
Переменная Формула Результат В окне
p 4·arctg 1 = π (своей константы π в языке нет) 3,14159 не показывается
a π·r² — площадь круга 19,635 1.9635+01
b 2·π·r — длина окружности 15,708 1.5708+01
c √(3² + 4²) — гипотенуза 5 5.0000+00
d arctg 1 в градусах 45 4.5000+01
e число e 2,7183 2.7183+00
f ln 10 2,3026 2.3026+00
g меньшее из 10 и 3 3 3.0000+00
h большее из 10 и 3 10 1.0000+01

Поставьте курсор в начало этой строки и нажмите Esc. Вспомогательные переменные r и p в окне не видны — показываются только a–h. Поэтому всё, что хотите увидеть, присваивайте им.

Правила записи

Присваивание: имя=выражение;. Точка с запятой нужна после каждого присваивания, включая последнее. Пробелы вокруг = и между элементами допустимы.

Числа: 42, 3.14, 3,14 (запятая тоже годится), 1.5e3, 2.5E-4.

Операции — от более сильной к более слабой:

Уровень Операции Смысл
1 < > меньшее из двух, большее из двух
2 ^ степень
3 * / умножение, деление
4 + - сложение, вычитание

Скобки ( ) — как обычно.

Функции — имя из трёх букв и аргумент в скобках:

Функция Что считает
abs(x) модуль
sqr(x) квадратный корень, x ≥ 0
log(x) натуральный логарифм, x > 0
exp(x) экспонента, x < 500
sin(x), cos(x), tan(x) синус, косинус, тангенс; x в радианах
ars(x), arc(x) арксинус, арккосинус; |x| ≤ 1
art(x) арктангенс
int(x) целая часть: дробь просто отбрасывается, int(-2.7) = −2
sgn(x) знак: −1, 0 или 1
sfi(x), cfi(x) интегралы Френеля S(x) и C(x)
bj0(x), bj1(x) функции Бесселя J₀(x) и J₁(x)
rnd(0) случайное число от 0 до 1 (в списке автора для калькулятора её нет, но язык её знает)

Имена переменных: одна буква (x, R; большие и маленькие буквы — разные переменные), буква с цифрой (a1), две буквы (dx). Надёжнее всего брать маленькие буквы. Не используйте имена, которые занимает сам проигрыватель: начинающиеся с U, двухбуквенные с последней буквой X, Y или Z (в том числе AY … KY).

Комментарий. После восклицательного знака ! строку можно продолжить любым текстом — он не выполняется. Только знака # в таком тексте быть не должно.

r=2.5; a=4*art(1)*r^2; ! площадь круга радиуса 2,5

Ловушки

Ловушка Пример Как правильно
минимум и максимум связывают сильнее всего 1<5+10 даёт 11, а не 1 ставьте скобки: 1<(5+10)
степень считается слева направо 2^3^2 = (2³)² = 64 2^(3^2) = 512
минус сразу после знака операции — ошибка 2*-3 2*(0-3) или -3*2
логарифм натуральный log(100) = 4,605 десятичный: log(100)/log(10) = 2
углы — в радианах sin(30) ≠ 0,5 sin(30*4*art(1)/180) = 0,5
забыли ; в конце a=1; b=2 a=1; b=2;
буква E в конце для «видимого пробела» a=1; E здесь она будет понята как выражение — не ставьте её
переменная из a–h не задана в строке нет h= в окне будет старое значение, оставшееся от предыдущих вычислений

Ошибка в выражении (деление на ноль, корень из отрицательного числа, неизвестная функция) вызывает сообщение интерпретатора, и расчёт прерывается. Если после этого проигрыватель закрылся, запустите его заново — строки входных данных сохранятся, кроме последней правки.

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

Что дальше

Что такое VKACL

VKACL не похож на языки, к которым вы привыкли. Прежде чем писать первую программу, стоит принять четыре его исходные идеи — иначе всё остальное будет казаться странным.

Идея первая: программа — это поток команд в тексте

В большинстве языков файл состоит из инструкций, а комментарии помечаются особым знаком. В VKACL наоборот: файл состоит из текста, а команды помечаются знаком #.

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

#pr Привет!\E

И снова текст, который никто не исполняет.

Интерпретатор ищет ближайший #, выполняет то, что за ним, снова ищет # — и так до конца файла. Всё между командами он просто пропускает.

Отсюда сразу следует ограничение, о котором стоит помнить с самого начала: в поясняющем тексте не должно быть символа #. Строка

Здесь мы используем команду #d для заполнения массива.

не комментарий: интерпретатор найдёт #d и попытается его выполнить.

Идея вторая: вся память общая

В VKACL нет объявлений переменных, нет областей видимости, нет локальных переменных у процедур. Есть фиксированный набор ячеек, существующий всегда:

Процедура — это просто именованный кусок кода; данные она получает и возвращает через те же общие ячейки.

У такого устройства есть причина. Автор начинал на Фортране, где массив объявлялся в каждой процедуре с фиксированным размером, «на всякий случай» по максимуму. Он с самого начала сделал иначе, как в ассемблере: одна большая область памяти, а «массив» — это просто номер первого элемента и длина. Тогда массивы укладываются плотно, а вектор можно на ходу считать матрицей, матрицу одной формы — матрицей другой формы, и наоборот, ничего не копируя. Индексы считать несложно, и этому быстро учишься.

Идея третья: команда — это имя, параметры и аргументы

Любая команда выглядит одинаково:

#имя [параметр=значение; параметр=значение;] аргументы

Поле в квадратных скобках необязательно. Важная особенность: параметры запоминаются. Если вы один раз написали [mo=1;], этот mo останется равным единице для всех последующих команд, пока его не переопределят. Это удобно и это же — источник самых неприятных ошибок.

Чего в языке нет

Стоит сказать прямо, чтобы не искать:

Взамен язык даёт очень короткую запись для того, что автор делает постоянно: рисовать графики, показывать окна, обрабатывать файлы и картинки, запускать готовые программы.

Идея четвёртая: язык — диспетчер, а не вычислитель

VKACL задуман в первую очередь как язык управления: графика, окна ввода и выбора, работа с файлами и PDF, запуск готовых программ и подпрограмм на Java. Для этого он очень удобен.

Для больших расчётов — тройных циклов по тысяче повторов — интерпретируемый язык не годится, и VKACL здесь не исключение. Способ, которым такие задачи решаются в Matlab и в numpy, есть и здесь: операции над массивом целиком. Их выполняет команда #ma — сложить, умножить, транспонировать, отсортировать, взять преобразование Фурье, построить сплайн — одной командой, без цикла. А то, что и так не получается, автор пишет на Java и вызывает из VKACL как процедуру.

Две реализации

Интерпретатор автора Этот проект
Что aclp.jar, Java acl-core, Rust
Команд 40 и 54 суперкоманды ядро языка, #ma, файлы (см. Реализация)
Графика, окна, звук, PDF да нет; окна выбора и ввода заменены вопросами в консоли
Готовые программы 80 нет
Где взять страница vkacl песочница

Для реальной работы нужен интерпретатор автора. Реализация из этого проекта существует, чтобы примеры туториала запускались прямо на странице и чтобы поведение языка было проверено тестами.

Дальше — первая программа.

Первая программа

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

Вывод в две ступени

#pr Привет, мир!\n\E
#m [op=txt;] \Tp\E

Разберём построчно.

#pr Привет, мир!\n\E — команда формирует текст и кладёт его в текстовый массив t(). Она ничего не показывает на экране. \n — перевод строки, \E — обязательный признак конца текста.

#m [op=txt;] \Tp\E — команда показывает текст в окне терминала. \Tp означает «взять последний фрагмент, записанный #pr».

Конца программы специально отмечать не нужно: интерпретатор просто доходит до конца текста.

Имя команды можно писать длиннее: значимы только первые три буквы, так что #pr, #pri и #print — одна и та же команда. В программах автора чаще всего встречается короткая форма #pr. А вот #p — это другая команда: она только задаёт параметры.

Такое разделение выглядит громоздким, но у него есть смысл: текст в t() можно накопить, потом отредактировать, записать в файл, показать на экране или отправить в PDF — источник один.

Почему \E и почему \n

Аргумент #pr — это форматированный текст (в документации автора — FT). Он не заканчивается на конце строки: интерпретатор читает его, пока не встретит \E. Поэтому текст можно свободно разносить по строкам.

Внутри работают escape-коды: \n — перевод строки, \t — табуляция, \# — сам знак #, \\ — обратная косая черта.

Ловушка с пробелами

Перед каждым фрагментом текста интерпретатор пропускает пробелы и переводы строк. Это значит, что так пробел не получить:

#pr A B\E

даст A B (внутренние пробелы сохраняются), а вот так:

#pr A \E

даст A — хвостовой пробел исчезнет, потому что после A идёт \, и пробел перед ним съеден. Явный пробел записывают кодом символа:

#pr A\u32;\E

\u32; — символ с кодом 32, то есть пробел. Точка с запятой обязательна.

Считаем и печатаем

# a=2; b=3;
# c=a*b+1;
#pr a*b+1 = \G c;\n\E
#m [op=txt;] \Tp\E

Здесь два новых элемента.

# a=2; b=3; — команда вычислений. Она начинается с #, за которым сразу идёт пробел — это краткая форма команды #c. Каждое присваивание заканчивается точкой с запятой.

\G c; — вставить значение переменной c в формате «мантисса и порядок». Результат будет выглядеть так:

a*b+1 =   7.0000+00

Формат \G — фиксированной ширины 11 символов, четыре знака после точки, двузначный порядок без буквы E. Для целых чисел удобнее \I:

#pr a*b+1 = \I4 c;\n\E

даст a*b+1 = 7 — число выровнено по ширине 4.

Где кончается команда

Программа выполняется сверху вниз. У большинства команд аргументы имеют понятный конец: у #pr это \E, у #rep — одно число. Но у некоторых команд аргументов может быть сколько угодно: у вычислений #c — любое число присваиваний, у #d и #v — любое число значений, у #e — имя процедуры. Такая команда читает аргументы, пока не встретит один из трёх знаков:

Знак Смысл
# началась следующая команда
@ кончилась процедура
! аргументы кончились — дальше обычный текст

Поэтому после таких команд перед поясняющим текстом ставят !:

# a=2; b=3; !
Здесь пояснение: без восклицательного знака слово «Здесь»
было бы принято за начало ещё одного присваивания.
#pr \G a b;\E

То же нужно, если такая команда стоит последней в программе: без ! интерпретатор продолжит читать аргументы за концом текста и остановится с ошибкой. Для #e в файле, который вызывается из другой программы, это проявляется сообщением, что такой процедуры нет.

Отсюда привычка, которую легко перенять у автора: заканчивать вычисления знаком !, если дальше не идёт сразу другая команда:

# a=2; b=3; c=a*b; !

Что попробовать

Откройте песочницу и запустите:

# n=5; f=1; i=1;
#rep 5
  # f=f*i; i=i+1;
#end
#pr 5! = \I6 f;\n\E
#m [op=txt;] \Tp\E

Это факториал пятёрки. #rep 5 … #end — цикл на пять повторений; про него подробно в главе Ветвления и циклы.

Дальше — вычисления и переменные.

Вычисления и переменные

Команда вычислений — самая частая в любой программе на VKACL. У неё две записи, полностью равнозначные:

#c a=1; b=2;
# a=1; b=2; !

Вторая — просто # и пробел. В реальном коде почти всегда пишут её.

Переменные

Отдельно объявлять ничего не нужно, все ячейки существуют с самого начала и равны нулю.

# a=1; z=2; A=3; Z=4; $=5; %=6; &=7;
# a1=10; b2=20; zz=30; AB=40; !

Доступны:

Все они хранят вещественные числа.

Три имени имеют особый смысл по традиции: & — условие для #case (см. Ветвления), $ и % часто используют как временные.

Операции

# a=2+3; b=7-2; c=2*3; d=7/2; e=2^10; !
Операция Что делает
+ - сложение, вычитание
* / умножение, деление
^ возведение в степень
< минимум двух значений
> максимум двух значений

Да, < и > — не сравнения. a<b — это меньшее из двух чисел.

Приоритеты: главная неожиданность

Порядок связывания в VKACL такой (сверху — сильнее):

  1. < > — минимум и максимум
  2. ^ — степень
  3. * /
  4. + -

Минимум и максимум связывают сильнее всего. Поэтому:

# m=1<5+10; !

это min(1,5) + 10 = 11, а вовсе не min(1, 15). И

# n=2*3<4; !

это 2 * min(3,4) = 6.

Степень вычисляется слева направо: 2^3^2 равно (2^3)^2 = 64, а не 2^9.

Когда сомневаетесь — ставьте скобки. Они работают обычным образом.

Функции

Имя функции — ровно три буквы, сразу за ним открывающая скобка:

# a=sqr(16); b=log(10); c=exp(1);
# d=sin(1); e=cos(1); f=tan(1);
# g=ars(0.5); h=arc(0.5); k=art(1);
# m=abs(0-7); n=int(3.7); p=sgn(0-2); q=rnd(0); !
Функция Смысл Примечание
sqr квадратный корень ошибка при отрицательном аргументе
log натуральный логарифм ошибка при аргументе ≤ 0
exp экспонента при аргументе < −500 даёт 0
sin cos tan тригонометрия аргумент в радианах
ars arc art арксинус, арккосинус, арктангенс
abs модуль
int целая часть отбрасывание к нулю: int(-3.7) = -3
sgn знак: −1, 0 или 1
rnd случайное число из [0,1) аргумент игнорируется
sfi cfi интегралы Френеля
bj0 bj1 функции Бесселя первого рода

Наличие Френеля и Бесселя прямо в языке многое говорит о задачах, ради которых он создавался: Виктор Кон занимается рентгеновской оптикой.

Унарный минус

Минус в начале выражения работает:

# a=-5; b=-sgn(x); !

А вот сразу после другой операции — нет. Запись 2*-3 даёт ошибку. Пишите так:

# a=2*(0-3); !

Идиома 0-x вместо -x в середине выражения встречается в авторском коде повсеместно.

Числа

# a=42; b=3.14; c=3,14; d=1.5e3; e=2.5e-4; !

Разделителем дробной части может быть и точка, и запятая. Экспонента пишется через e или E.

Как построить условие

Раз сравнений нет, условия строят арифметикой. Самый частый приём — sgn:

Единица, если q меньше трёх, иначе ноль или минус единица
# &=-sgn(q-3); !

sgn(q-3) равен −1 при q<3, нулю при q=3 и +1 при q>3; минус переводит это в 1 / 0 / −1. Полученное значение затем разбирает #case.

Другой приём — «зажать» значение через минимум и максимум:

Ограничить x диапазоном от 0 до 100
# x=0>x<100; !

Читается справа налево по приоритетам: сначала x<100 (не больше 100), потом 0>… (не меньше 0).

Дальше — массивы и память.

Массивы и память

Кроме скалярных переменных в VKACL есть четыре массива. Они существуют всегда, общие для всей программы, и индексируются с единицы.

Запись Что хранит Размер
i(n) целые числа 249 999
r(n) вещественные числа 25 999 999
t(n) символы текста 1 999 999
s(n) служебные ячейки 112

Обращение к элементу — обычное:

# i(1)=10; i(2)=20;
# r(100)=3.14;
# a=i(1)+i(2); !

Индексы считаются упрощённо

Внутри скобок работает урезанный вычислитель. Допустимы только числа, скалярные переменные и операции + - * / ^:

# k=5;
# a=i(k); !      это работает
# b=i(k+1); !    и это
# c=i(k*2-1); !  и это

А вот так — нельзя:

# d=i(int(k/2)); ! ошибка: функции в индексах не работают
# e=i(j(1)); !     ошибка: вложенные массивы тоже

Обходной путь один — посчитать индекс заранее в переменную:

# k=7; m=int(k/2); d=i(m); !

Заполнение массива: #d

Перечислять элементы по одному утомительно, поэтому есть команда #d:

#d 6 i(1) 7 0 0 0 9 11 !

Читается так: «шесть значений, начиная с i(1), вот они». Повторы записываются короче — через звёздочку:

#d 6 i(1) 7 0*3 9 11 !

0*3 означает «ноль три раза». Результат тот же.

За один раз можно задать не больше 500 значений. Команда продолжает читать группы количество приёмник значения…, пока не встретит следующую команду:

#d 3 i(1) 1 2 3  3 r(1) 1.5 2.5 3.5 !

Копирование: #pas

#pas 4 r(1) i(10)

«Переслать четыре элемента из r(1)…r(4) в i(10)…i(13)». Типы приводятся автоматически: вещественные округляются при записи в целый массив.

Команда корректно работает при наложении областей — если приёмник правее источника, копирование идёт с конца.

Текстовый массив t()

t() хранит символы. Записать в него можно двумя способами: числовым кодом

# t(200)=65; t(201)=66; t(202)=67; !

или, что гораздо чаще, командой #pr, которая пишет туда форматированный текст.

Прочитать фрагмент обратно в текст — escape-код \T:

#pr \T200 3\E

«Взять три символа начиная с t(200)» — получится ABC.

У \T два аргумента: начало и длина. Оба — простые числа или переменные, выражения там не работают:

# n=3;
#pr \T200 n\E      так можно
#pr \T200 n-1\E    так нельзя: напечатается ABC-1

Служебный массив s()

s() — это одновременно и параметры команд, и их результаты. Когда вы пишете

#f [op=size; file=data.txt;]

значение параметра n попадает в s(7), mo — в s(11) и так далее, а размер файла команда вернёт в s(1).

Ячейки, которые нужны чаще всего:

Ячейка Смысл
s(1) результат: размер файла и т. п.
s(3) текущая позиция записи в t()
s(4), s(5) начало и длина последнего фрагмента от #pr
s(6) максимальная занятая позиция в t()

s(3) — самая важная. Именно её сбрасывают в единицу, чтобы начать формировать текст заново:

# s(3)=1;
#pr первая строка\n\E
#pr вторая строка\n\E

Без сброса каждый новый #pr дописывает текст к предыдущему — иногда это именно то, что нужно.

Как вывести весь накопленный текст

Типичная концовка программы:

# n9=s(3)-1;
#m [op=txt;] \T1 n9\E

Длину пришлось положить в переменную, потому что \T не понимает выражений. И точки с запятой после аргументов нет: \T читает ровно два значения и на этом останавливается — всё, что написано дальше, попадёт в вывод как текст.

Это настолько частая идиома, что её стоит запомнить целиком.

Дальше — текст и вывод.

Текст и вывод

Форматированный текст (в документации автора — FT) — это язык внутри языка. Его понимают #pr, #m и текстовые параметры команд.

Правило одно: текст читается до \E. Всё остальное — детали.

Скелет

# s(3)=1;
#pr Результат: \G x;\n\E
#m [op=txt;] \Tp\E

Пробелы съедаются

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

#pr Первая строка\n
     Вторая строка\n
     Третья строка\n\E

Отступы в исходнике на результат не влияют. Но и нужный пробел так не поставить — для него есть \u32;:

#pr Итого:\u32;\G x;\n\E

Другой способ — перенести строку исходника кодом \-, который не даёт ничего:

#pr Очень длинная строка, которую хочется \-
     разбить в исходнике\n\E

Escape-коды: символы

Код Даёт
\n \r \t \b перевод строки, возврат каретки, табуляция, забой
\\ \" \' сами символы
\# \@ \[ \] сами символы
\- ничего (перенос строки в исходнике)
\u коды; символы по кодам: \u32;, \u65 66 67;, \u65*4;
\D текущие дата и время
\E конец текста

Коды \# и \@ нужны потому, что # и @ иначе оборвали бы команду.

Escape-коды: числа

Здесь начинается специфика. Каждый код читает список значений до ;:

#pr \G a b c;\n\E

выведет подряд три числа.

Код Формат Пример для 3.14159
\G ширина 11, 4 знака, порядок без E 3.1416+00
\B ш зн то же с буквой E \B 12 4 → 3.1416E+00
\I ш целое, выравнивание пробелами \I5 → 3
\I-ш целое, выравнивание нулями \I-5 → 00003
\N ш зн с фиксированной точкой \N 10 3 → 3.142
\S короткая запись числа 3.14159
\O полная запись плюс два пробела 3.14159

\G — рабочая лошадка для вещественных чисел, \I — для целых.

Обратите внимание на порядок: у \B и \N сначала идёт ширина поля и число знаков, потом сам список значений.

#pr \B 14 6 x;\n\E

Вставка из массива

Код Что делает
\T нач длина фрагмент массива t()
\Tp последний фрагмент от #pr (по s(4), s(5))
\P n; значение текстового параметра n

Аргументы \T — только числа или переменные, не выражения.

Комментарий внутри текста

Прямо в форматированном тексте можно оставить заметку — она не попадёт в результат:

#pr Итого:\u32;![ тут будет сумма ]!\G s;\n\E

Открывается ![, закрывается ]!. Распознаётся такой комментарий только в самом начале текста или сразу после escape-кода — там, где интерпретатор пропускает пробелы. В середине обычного текста ![ … ]! будет напечатан как есть; поэтому в примере перед ним стоит \u32;.

Накопление текста

Поскольку #pr дописывает в t(), отчёт удобно собирать по частям:

# s(3)=1;
#pr Отчёт\n\E
#pr ------\n\E
# i=1;
#rep 5
  #pr строка \I2 i;\n\E
  # i=i+1;
#end
# n9=s(3)-1;
#m [op=txt;] \T1 n9\E

Каждый #pr внутри цикла дописывает строку, а в конце всё показывается разом.

Куда ещё уходит текст

Собранный в t() текст — универсальный источник:

Именно поэтому вывод сделан двухступенчатым.

Дальше — ветвления и циклы.

Ветвления и циклы

В VKACL всего две управляющие конструкции — #rep и #case — и обе закрываются одним и тем же #end. Из них собирается всё остальное.

Цикл с известным числом повторений

# s=0; i=1;
#rep 10
  # s=s+i; i=i+1;
#end

#rep N повторяет тело N раз. N — число или переменная, но не выражение: считать его нужно заранее:

# n=5; m=n*2; !
#rep m
  ...
#end

Циклы вкладываются, глубина — до 45 уровней:

# c=0;
#rep 3
  #rep 4
    # c=c+1;
  #end
#end

После этого c равно 12.

Если N окажется нулём или отрицательным — это ошибка, а не пустой цикл. Проверяйте счётчик заранее.

Ветвление

Условие в VKACL — это значение переменной &, а #case сравнивает его со своей меткой:

# &=2;
#case 1  # z=10;  #end |
#case 2  # z=20;  #end |
#case 3  # z=40;  #end |

Выполнится только вторая ветка: & равно 2. Остальные пропускаются целиком, вместе со всем, что внутри.

Вертикальная черта после #end — не украшение. Она означает «сбросить условие»: после #end | переменная & получает служебное значение 12345, которое не совпадает ни с одной меткой. Без неё произойдёт кое-что интересное.

#case как цикл «пока»

Если после #end не написать |, то по достижении #end интерпретатор снова сравнит & с меткой ветки, и при совпадении вернётся к её началу. Это и есть цикл с условием:

# &=1; q=0;
#case 1
  # q=q+1;
  # &=-sgn(q-4);
#end
#pr q = \I3 q;\n\E

Пока q меньше 4, выражение -sgn(q-4) даёт 1, & остаётся равным метке, и блок повторяется. Когда q достигнет 4, sgn(0) даст 0, & станет нулём, и цикл закончится.

То же можно записать через #end (x) — эта форма задаёт новое значение условия прямо в закрывающей команде. В скобках допускается только число или переменная, не выражение, поэтому условие считают заранее:

# &=1; q=0; !
#case 1
  # q=q+1; w=-sgn(q-4); !
#end (w)

Как строят условия

Раз сравнений нет, всё сводится к тому, чтобы получить в & нужное целое.

Проверка на равенство — вычесть и взять модуль знака:

Единица, если a равно b
# &=1-abs(sgn(a-b)); !

Проверка «больше» — знак разности:

Единица, если a больше b, иначе 0 или -1
# &=sgn(a-b);
#case 1   ... a больше ...   #end |
#case 0   ... равны ...      #end |
#case -1  ... a меньше ...   #end |

Метка может быть отрицательной — это удобно и используется постоянно.

Флаг — просто 0 или 1:

# &=0;
#case 1   ... не выполнится ...   #end |

Ранний выход из цикла

Прямого break нет, и у #rep число повторов задано заранее — изменить его изнутри нельзя. Когда цикл должен закончиться по условию, его пишут через #case, где условие продолжения вы вычисляете сами:

# k=0; &=1; !
#case 1
  # k=k+1; &=sgn(50-k*k)>0; !
#end
#pr первое k, у которого k*k больше 50: \I3 k;\n\E
#m [op=txt;] \Tp\E

Пока k*k меньше 50, sgn(50-k*k) равен 1, и ветка повторяется. Как только квадрат превысит 50, sgn даст −1, а >0 (максимум с нулём) превратит его в 0 — ветка больше не совпадает с &, и цикл заканчивается на k = 8.

Что важно помнить

Дальше — процедуры.

Процедуры

Процедура в VKACL — именованный кусок кода. Без параметров, без возвращаемого значения, без локальных переменных. Всё общение — через общую память.

Определение и вызов

#pro summ
  # s=a+b;
@

# a=2; b=3;
#e _summ
#pr сумма = \G s;\n\E

#pro имя открывает процедуру, @ закрывает. Вызов — #e _имя с подчёркиванием перед именем.

Определения обычно собирают в начале файла, а основной код идёт после них. Интерпретатор регистрирует процедуру, когда доходит до #pro, поэтому определение должно встретиться раньше вызова.

Значимы первые четыре буквы имени

Это не опечатка: имя процедуры усекается до четырёх символов.

#pro calculate  ...  @
#pro calcform   ...  @

Обе процедуры получат имя calc — и вторая затрёт первую. Имена длиннее четырёх букв читаются нормально, но различаться должны в первых четырёх:

#pro calc-total  ...  @
#pro calc-part   ...  @

Здесь тоже конфликт: calc и calc. Безопаснее давать имена ровно из четырёх символов.

Подчёркивание в вызове

#e _summ !

Подчёркивание означает «вызвать безусловно». Без него вызов становится условным: процедура выполнится, только если параметр c совпадает с &.

#e [c=3;] summ !

выполнит summ, только когда & равно 3. Приём экзотический; в авторском коде почти везде стоит подчёркивание.

Данные передают через переменные

Раз параметров нет, договариваться приходится на уровне соглашения:

Возводит x в квадрат, результат кладёт в y
#pro sqre
  # y=x*x;
@

# x=5;
#e _sqre
#pr \G y;\n\E

Это работает, но требует дисциплины: любая процедура может испортить любую переменную. Распространённая практика — закрепить за процедурами свои буквы или диапазоны массивов.

Рекурсии нет

Вызов процедуры из неё самой — ошибка 14. Вложенные вызовы разных процедур разрешены, глубина — до 45:

#pro inne
  # c=c+1;
@

#pro oute
  #e _inne
  #e _inne
@

# c=0;
#e _oute !

После этого c равно 2.

Выполнение текста как программы

Есть особая форма вызова — #e _text. Она выполняет как программу тот текст, который лежит в массиве t():

# s(3)=1;
#pr \#\u32;q=6*7;!\E
# b=s(4); l=s(5);
#e [b=b; le=l;] _text !
#pr q = \G q;\n\E
#m [op=txt;] \Tp\E

Здесь программа сначала формирует строку # q=6*7;!, а потом исполняет её. Обратите внимание на три детали:

Приём выглядит экзотикой, но именно на нём построены калькуляторы автора: формулу, введённую в окне ввода, программа превращает в команду #c и исполняет. В песочнице есть пример «Мини-калькулятор».

Процедуры из файлов

Код можно держать в отдельном файле и выполнять его из программы:

#e [file=lib.acl;] _file !

Файл читается и выполняется так, как если бы его текст стоял на месте вызова. Если #e — последняя команда в таком файле, после неё обязателен !.

Две тонкости, обе проверены на интерпретаторе автора:

Краткая старая форма — ##имя: она выполняет файл proc/имя.acl. Автор ею больше не пользуется, потому что файл читается с диска при каждом вызове.

Суперкоманды

Вместо россыпи файлов в новой версии есть номерные суперкоманды: ##1, ##2, … Это готовые программы на VKACL из библиотеки автора — графики, карты, окна, интерполяция, преобразование Фурье. Каждая хранится в одной строке общего файла-библиотеки; при первом вызове читается и остаётся в памяти, в конце массива t(), так что повторные вызовы в цикле ничего не стоят.

Входные данные суперкоманде передают через переменные и массивы, а тексты — через #pr, разделяя части вертикальной чертой:

#pr Да|Нет|Продолжить вычисления?\E ##33

показывает сообщение с кнопками «Да» и «Нет»; номер нажатой кнопки попадает в &. Все 54 суперкоманды описаны в разделе Суперкоманды.

У этого устройства есть два следствия для любой программы:

Дальше — файлы.

Файлы

За работу с файлами отвечают две команды: #io читает и пишет файл целиком, #f выполняет операции над файлами и папками.

Запись текста в файл

# s(3)=1;
#pr Привет из VKACL\n\E
#pr Вторая строка\n\E
# n9=s(3)-1;
#io [op=wt; fir=t(1); n=n9; file=out.txt;]

Разберём параметры:

Параметр Смысл
op=wt операция: write text
fir=t(1) откуда брать: начало области
n=n9 сколько элементов
file=out.txt имя файла

fir — это не число, а ссылка на ячейку: t(1), i(5), r(100). Для текстовых операций она обязана указывать на t().

Чтение текста из файла

#io [op=rt; fir=t(1); n=100000; file=in.txt;]
# m=s(5); !
#pr прочитано\I7 m;\u32;символов\n\E

n здесь — верхняя граница, сколько максимум прочитать. Где оказался прочитанный текст, команда сообщает так же, как #pr: начало — в s(4), длина — в s(5). Поэтому его сразу можно вывести через \Tp. Позицию записи s(3) чтение не сдвигает.

Восемь операций #io

op Что делает
rt / wt читать / писать текст (только с t())
rb / wb читать / писать байты
rd / wd читать / писать вещественные числа
rf / wf читать / писать файл как массив

Двоичные формы работают с i() и r() и позволяют сохранять численные данные без потери точности.

Операции с файлами: #f

#f [op=size; file=data.txt;]
# sz=s(1); !
op Что делает
fold сменить рабочую папку
size размер файла в s(1)
copy скопировать
dele удалить
line прочитать или записать строку с номером n
find repl поиск и замена в файле
list список файлов папки

Полный список — в справочнике команды #f.

Смена папки — почти обязательный первый шаг в авторских программах:

#f [op=fold; file=pro;]

После этого все относительные имена отсчитываются от папки pro.

Имя файла из переменных

Имя файла — текстовый параметр, а значит, его можно собрать escape-кодами:

# n=7;
#f [op=size; file=\-данные-\I-3 n;.txt\E]

Если значение параметра начинается с \, оно читается как форматированный текст. Код \- в начале ничего не выводит и нужен только для того, чтобы значение начиналось с обратной косой черты. Получится данные-007.txt.

Похожий приём — специальное имя arg, при котором имя файла берётся из следующего форматированного текста:

#io [op=rt; fir=t(1); n=10000; file=arg;] отчёт-\I-2 k;.txt\E

Что поддерживает реализация из этого проекта

Порт на Rust умеет все восемь операций #io, почти все операции #f и #te, кроме связанных с картинками, окнами и сетью, — о таких он сообщает, называя операцию. В песочнице без подключённой папки файлы живут в памяти: записанное показывается под выводом. С подключённой папкой (кнопка «Подключить папку») программа работает с настоящими файлами.

Дальше — ловушки языка.

Ловушки языка

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

Символ # в поясняющем тексте

Заполняем массив командой #d — так делать нельзя.
#d 3 i(1) 1 2 3 !

Интерпретатор найдёт #d в «комментарии» и попытается его выполнить: прочитает слово — как число элементов, получит ноль и остановится с ошибкой 33.

Правило: в тексте между командами не должно быть #. Если очень нужно — пишите «команда d» словами.

Текст сразу после #c, #d, #v, #e

# a=1;
Дальше идёт пояснение.
#pr ...\E

Команда вычислений читает присваивания, пока не встретит #, @ или !. Слово Дальше она примет за имя переменной и остановится с ошибкой. То же с #d, #v и #e: у всех них число аргументов не фиксировано.

Правило: после таких команд, если дальше идёт текст, ставьте !:

# a=1; !
Дальше идёт пояснение.

Пробел после \#

Когда программа собирает команду в текстовом массиве, чтобы потом выполнить её (#e _text), легко написать так:

#pr \# a=1;\E

Получится #a=1;: пробел перед a съеден по общему правилу форматированного текста, и это уже не команда вычислений. Нужен явный пробел: \#\u32;a=1;\E.

Чужие переменные

Двухбуквенные переменные с Y на конце (AY…KY и другие) заняты диспетчером суперкоманд, а за t(KY) лежит его код. Программа, которая их трогает, работает до первой суперкоманды, а потом ломается непредсказуемо.

Правило: двухбуквенные имена на X, Y, Z не использовать; в t() не заходить дальше KY.

< и > — это не сравнения

# &=a<b; !

Это не «a меньше b», а минимум из двух. И связывает он сильнее умножения:

# n=2*3<4; !   это 2*min(3,4) = 6
# m=1<5+10; !  это min(1,5)+10 = 11

Правило: для условий используйте sgn, а если нужен минимум в середине формулы — ставьте скобки.

Степень слева направо

# e=2^3^2; !

Даёт 64, то есть (2^3)^2. В математике принято наоборот.

Унарный минус только в начале

# a=2*-3; !    ошибка 11
# a=2*(0-3); ! правильно
# b=-5; !      правильно, минус в начале

Аргумент #rep — не выражение

#rep 2+1  … #end      выполнится 20 раз, а не 3
#rep n+1  … #end      выполнится n раз, «+1» молча пропадёт

Счётчик #rep, метка #case, значения #d, числа в \G и \I читаются особым образом: это одно число или одна переменная, а не выражение. Причём в числе буква порядка E необязательна — 2+1 читается как 2·10¹. Так сделано, чтобы можно было прочитать собственный формат вывода 2.0000+01.

Правило: всё, что нужно посчитать, считайте заранее в переменную:

# m=n+1; !
#rep m … #end

Параметры не сбрасываются

#f [op=size; file=a.txt; n=5;]
#f [op=size; file=b.txt;]

Во второй команде n всё ещё равно 5. Параметры глобальны и живут до переопределения. Это чаще всего проявляется в параметрах mo, n и b, которые используют почти все команды.

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

Значимы первые буквы имён — и ищутся подстрокой

Команды сопоставляются по первым трём буквам, процедуры — по первым четырём. Причём имя команды ищется в общей таблице как подстрока, и находится первое совпадение:

Пишут Думают Получают
#p #pr #p — только установка параметров
#in #inp #w — «IN» есть внутри «WIN»
#ro #rob #pro
#ex #exit #e

С параметрами то же: xs — это xsh (сдвиг), а не позиция xpo; wi — это twi, he — the (см. Поле параметров).

#pro calculate ... @
#pro calcform  ... @    имя то же самое: calc

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

Хвостовые пробелы исчезают

#pr Итого: \G x;\E

Пробел перед \G съеден: перед каждым фрагментом текста пропускаются пробелы. Нужен пробел — пишите \u32;.

Индексы массивов считаются упрощённо

# a=i(k+1); !      работает
# b=i(int(k/2)); ! ошибка

В индексах доступны только числа, скалярные переменные и + - * / ^. То же ограничение — у аргументов \T.

Кодировка исходников

Интерпретатор автора читает файлы как windows-1251. Файл, сохранённый в UTF-8, даст кракозябры в русском тексте. Реализация из этого проекта определяет кодировку сама и понимает оба варианта, но программы для интерпретатора автора стоит сохранять в windows-1251.

Ошибка молча прекращает программу

По умолчанию (err=0) любая ошибка показывает окно и завершает выполнение. Чтобы обработать ошибку самому, нужны две вещи: параметр err не равен нулю и точка возврата, отмеченная командой #%. После ошибки исполнение продолжается с этой точки, а & получает значение 10101.

# ok=1; !
#p [err=1;]
#%
#case 10101 # ok=0; #end |
# &=ok; !
#case 1 #io [op=rt; fir=t(1); n=10000; file=может-не-быть.txt;] #end |
# &=ok; !
#case 0 #pr файл прочитать не удалось\n\E #end |
#p [err=0;]

Разберём, как это работает. #% запоминает место, куда вернуться после ошибки. При первом проходе & не равно 10101, и ветка #case 10101 пропускается. Если чтение файла сорвалось, исполнение возвращается сразу за #%, а & становится 10101 — теперь ветка выполняется и сбрасывает флаг ok. Флаг нужен, чтобы опасная команда не выполнилась повторно: иначе программа снова наткнётся на ту же ошибку и снова вернётся к #%.

Это единственный в языке механизм обработки ошибок.

Массивы целиком: #ma

Интерпретируемый язык медленен в циклах. Тройной цикл по тысяче повторов для VKACL — непосильная задача, как и для любого интерпретатора. Matlab и numpy решают это одинаково: операция применяется к массиву целиком, одной командой, а цикл выполняется внутри, на скорости Java или C. В VKACL это команда #ma, и она была в языке с самого начала, ещё во времена Фортрана.

Автор формулирует жёстко: без #ma язык не годится ни для научных расчётов, ни для обработки картинок. Поэтому эта глава обязательна для всех, кто будет считать.

Массив — это начало и длина

Вспомним, как устроена память: r() — одна большая область. «Массив» в программе — это просто номер первого элемента и число элементов. Поэтому у команд #ma почти всегда есть параметры:

Параметр Смысл
b номер первого элемента в r()
le число элементов (для векторов)
nx, ny размеры матрицы: nx элементов в строке, ny строк
trx сдвиг до второго массива: он начинается с r(b+trx)

Матрица хранится по строкам: элемент строки y, столбца x лежит в r(b + y·nx + x) (счёт с нуля). Ничто не мешает считать те же 12 чисел то матрицей 3×4, то 4×3, то вектором длины 12 — это просто разные значения nx, ny и le.

Константы, нужные операциям, берутся из переменных — чаще всего C и D. А результат, если он одно число, иногда тоже кладётся в переменную.

Сумма квадратов без цикла

# s(3)=1; C=1; D=1; !
#ma [op=via; b=1; le=100;]
#ma [op=vvm; b=1; le=100; trx=0;]
#ma [op=mss; b=1; nx=100; ny=1; em=0;]
#pr sum=\B 16 8 r(101);\n\E
sum=  3.38350000E+05

Три строки — три операции над массивом из ста чисел:

  1. via заполняет r(b+i) = C + D·i — получаем 1, 2, …, 100;
  2. vvm умножает каждый элемент на элемент, отстоящий на trx; при trx=0 это возведение в квадрат;
  3. mss суммирует; для вектора (ny=1) сумма кладётся сразу за ним, в r(b+nx).

Матрицы

# s(3)=1; !
#d 6 r(1) 1 2 3 4 5 6 !
#ma [op=mtr; b=1; nx=3; ny=2;]
#pr \G r(1) r(2) r(3) r(4) r(5) r(6);\n\E
  1.0000+00  4.0000+00  2.0000+00  5.0000+00  3.0000+00  6.0000+00

Матрица 2×3 (две строки: 1 2 3 и 4 5 6) после mtr стала матрицей 3×2 — теперь её строки 1 4, 2 5, 3 6. Транспонирование делается на месте.

mss для матрицы кладёт после неё сначала суммы по столбцам, потом по строкам, потом общую сумму. Для той же исходной матрицы получится 5 7 9 | 6 15 | 21.

Скалярное произведение и ограничение диапазона

# s(3)=1; !
#d 4 r(1) 1 2 3 4 !
#d 4 r(5) 2 2 2 2 !
#ma [op=vvs; b=1; le=4; trx=4;]
#pr dot=\G C;\n\E
#d 5 r(1) 0.5 2.7 -1.3 4.2 3.1 !
# V0=0; V1=3; !
#ma [op=var; b=1; le=5;]
#pr \G r(1) r(2) r(3) r(4) r(5);\n\E
dot=  2.0000+01
  5.0000-01  2.7000+00         0.  3.0000+00  3.0000+00

vvs записывает результат в переменную C — будьте внимательны, если C использовалась для другого. var зажимает значения в диапазон от V0 до V1.

Сортировка

# s(3)=1; !
#d 5 r(1) 3.5 1.25 4.75 2.5 0.5 !
#ma [op=vor; b=1; le=5; mo=1;]
#pr \G r(1) r(2) r(3) r(4) r(5);\n\E
#pr \I3 i(1) i(2) i(3) i(4) i(5);\n\E
  5.0000-01  1.2500+00  2.5000+00  3.5000+00  4.7500+00
  5  2  4  1  3

mo=1 — по возрастанию, mo=2 — по убыванию. Заодно в i(1)…i(le) записываются прежние номера элементов: видно, что наименьший был пятым.

Какие операции есть

Полное описание — в справочнике #ma. По группам:

Группа Операции
заполнить vic константой, via прогрессией, vig гауссианой
поэлементно с константой vac прибавить C, vmc умножить на C, vpo степень C
функция от каждого элемента vex exp, vlo ln, vsi sin, vco cos, vin целая часть, vba поправка байтов
два массива vva сложить, vvm перемножить, vvs скалярное произведение
ограничить, отсортировать var, vor
матрицы mtr транспонировать, mii отразить, mss суммы, fno нормировать строки, mip, mds, mmr поворот
комплексные массивы mcc, dcc, ccm, ccd умножение и деление, cne, cen модуль и фаза
спектр и свёртка fft, mcg свёртка с гауссианой
интерполяция mmi, ffi, fis кубический сплайн
производные и интегралы fdf, sdf, fsd, ffd
прочее gis гистограмма, cwm пик и его ширина, bsm bsi bsr система шаров

Как думать в стиле #ma

Вместо «для каждого i сделать…» — «какой операцией над целым массивом это выражается». Цикл остаётся там, где он действительно нужен: по строкам файла, по кадрам анимации, по вариантам расчёта. А внутри каждого шага — одна или несколько команд #ma.

Тем, кто пришёл из Matlab или numpy, это знакомо; тем, кто пришёл из C или Паскаля, придётся привыкнуть. Автор научился такому стилю ещё на Фортране и считает его самым естественным для научных расчётов.

Графика

Ради графики язык и появился в 1991 году: автору нужно было быстро строить научные графики, не переписывая каждый раз программу на Фортране. Графика есть только в интерпретаторе автора — в песочнице этой книги её нет. Оба рисунка ниже получены запуском приведённых программ в настоящем интерпретаторе.

Команд рисования три, и у каждой своя роль:

Команда Для чего
#w научные графики «в одну команду»: кривые с осями, карты матриц, квази-трёхмерные графики; показ и преобразование картинок
#g рисование по элементам: текст, линии, области, прямоугольники, овалы, оси, картинки
#eg то же с вещественными координатами и преобразованиями — для сложных рисунков

А для самых частых случаев есть готовые суперкоманды: ##1 — график функций, ##2 — цветная карта матрицы, ##3 — аксонометрия. Им достаточно передать данные, оси и подписи они размечают сами (см. Суперкоманды).

График функций одной командой

Две кривые, синус и косинус на отрезке от 0 до 2 пи.
# s(3)=1; n=201; C=0; D=2*3.14159265/(n-1); !
#ma [op=via; b=1; le=n;]
#ma [op=vsi; b=1; le=n;]
#ma [op=via; b=202; le=n;]
#ma [op=vco; b=202; le=n;]
#w [op=pf; file=here; b=1; le=0; mo=0; nx=n; ny=2; n=0; uni=0; col=247; msi=0;
    twi=640; the=400; wid=520; hei=300; xsh=80; ysh=50; bot=5; top=10;
    tsi=14; tfo=1; tki=1; sty=0; c=0; sav=1;] 0 6.2832
#f [op=topng; n=1; form=sinus;]

Синус и косинус

Что здесь происходит:

  1. #ma [op=via;] заполняет массив арифметической прогрессией C + D·i, а #ma [op=vsi;] берёт синус от каждого элемента — две команды вместо цикла. Так же готовится косинус, начиная с r(202).
  2. #w [op=pf;] (plain figure) рисует график. file=here говорит, что числа лежат в массиве r() начиная с b=1, а не в файле. nx — точек в кривой, ny — число кривых, при mo=0 все столбцы — значения функций, а аргумент меняется равномерно от первого до второго числа после скобок (0 6.2832). uni=0 — разметку осей выбрать автоматически.
  3. Размеры: twi×the — вся картинка, wid×hei — прямоугольник осей, xsh, ysh — его сдвиг от левого нижнего угла, bot и top — длины рисок, tsi — размер шрифта чисел на осях (его обязательно задать: при нуле числа не видны).
  4. col=247 — цвет первой кривой; следующая берёт следующий цвет палитры.
  5. sav=1 — не показывать картинку, а сохранить её в память под номером 1. #f [op=topng; n=1; form=sinus;] записывает её в файл sinus.png.

Куда девается картинка

Параметр sav у всех рисующих команд работает одинаково:

sav Результат
больше 0 картинка сохраняется в памяти под этим номером (до 100) и не показывается
0 показывается в отдельном окне; при c=1 программа ждёт, пока окно закроют
−1 показывается и одновременно записывается в файл form.jpg
−2 только записывается в файл form.jpg, без окна

Из памяти картинку можно записать в PNG (#f [op=topng;]), дорисовать командой #g [op=cont;], показать, собрать из нескольких одну.

Рисунок по элементам

Белый холст, синяя рамка, красный круг и подпись.
Координаты отсчитываются от левого нижнего угла, прямоугольники
и овалы ставятся по центру. Номера цветов считаются с единицы.
# s(3)=1;
#g [op=open; twi=400; the=300; col=246;]
#g [op=rect; nx=200; ny=150; wid=360; hei=260; col=249; mo=1;]
#g [op=oval; nx=200; ny=130; wid=140; hei=140; col=248; mo=0;]
#g [op=text; nx=200; ny=240; col=247; tfo=1; tki=1; tsi=24; sty=2;] VKACL\E
#g [op=close; c=0; sav=2;] \E
#f [op=topng; n=2; form=drawing;]

Рисунок по элементам

Порядок всегда один: op=open задаёт размер холста и цвет фона, дальше рисуются элементы, op=close закрывает рисунок и распоряжается им по sav.

Несколько деталей, которые проще увидеть на картинке, чем вычитать:

Сдвиг и масштаб всего рисунка

Параметры trx, try сдвигают, а sca масштабирует всё, что рисуется после них, — не трогая координат в самих командах. Так один и тот же код рисует фрагмент в разных местах и разного размера. При sca, заданном со знаком минус, меняются только размеры фигур, а их расположение остаётся прежним.

Что дальше

Модель исполнения

Буфер и указатель

Интерпретатор держит весь текст программы в одном символьном буфере (на программу отводится до миллиона символов) и один указатель — текущую позицию разбора. Управляющие конструкции работают именно с ним: цикл — это возврат указателя назад, переход — присваивание указателю нового значения.

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

Главный цикл

  1. Найти вперёд ближайший #; всё до него — комментарий.
  2. Поставить указатель сразу за #.
  3. Разобрать и выполнить команду.
  4. Повторять.

Цикл заканчивается, когда указатель выходит за границу текущей области исполнения и стек вызовов пуст, либо когда встретилась команда #stop / #exit.

Что может стоять после #

Запись Смысл
# (пробел) команда вычислений, синоним #c
##N (число) номерная суперкоманда из библиотеки автора, см. Суперкоманды
##имя старая форма: выполнить файл proc/имя.acl (каждый раз читается с диска)
#имя обычная команда

Сопоставление имени команды

Имя читается до пробела или перевода строки, приводится к верхнему регистру, берутся первые не более трёх символов, и результат ищется как подстрока в таблице из 4-символьных слотов:

PAR DAT CAL EXE IOP PRI PAS REP END CAS %   STO PRO MES FIL WIN
COL INP EXI REA SEL MAT TEX SYS ZIP GRA GOT ROB EGR PAT AGR INI
SOU PSG BIM PDO FRA PFO CHO VRA

Номер команды — позиция / 4 + 1.

Следствия:

Завершение аргументов

У команд с аргументами переменной длины — #c (и # ), #d, #v, #e и некоторых других — аргументы кончаются на одном из трёх знаков:

Знак Смысл
# начало следующей команды
@ конец процедуры
! конец аргументов; дальше обычный текст

! обязателен, если за такой командой идёт поясняющий текст, и если #e — последняя команда в файле, который выполняется из другой программы. У команд с аргументами фиксированной формы (#pr … \E, #rep N) он не нужен.

Сам конец программы ничем не отмечается: исполнение заканчивается, когда текст кончился, или по командам #stop и #exit.

Области исполнения

Текущая граница исполнения хранится в s(110). Вызов процедуры сохраняет позицию возврата и старую границу, устанавливает новые и продолжает разбор. Когда указатель доходит до границы, происходит возврат.

Глубина вложенности вызовов — до 45, так же и для циклов и ветвей (в версиях до 2025 года было 25). Рекурсия запрещена: повторный вход в процедуру с тем же именем даёт ошибку 14, и сообщение показывает всю цепочку вызовов.

Кодировка

Исходники читаются побайтово как windows-1251:

Диапазон байта Преобразование
0x00…0x7F без изменений (ASCII)
0x80…0xBF символ с тем же кодом (Latin-1); Ё и ё так не читаются
0xC0…0xFF кириллица А…я (U+0410…U+044F)

Одиночный CR без LF превращается в LF.

Обработка ошибок

Поведение задаёт параметр err (ячейка s(26)):

err Что происходит при ошибке
0 (по умолчанию) окно с сообщением, выполнение прекращается
не 0 без окна; если командой #% отмечена точка возврата, исполнение продолжается с неё, а & получает значение 10101

Ветка #case 10101 сразу за #% — стандартный способ поймать ошибку; полный образец — в разделе Коды ошибок.

Память и переменные

Вся память статическая и глобальная. Ничего не объявляется, всё существует с начала программы и обнулено.

Классы хранилищ

Запись Что хранит Максимальный индекс
a…z, A…Z, $, %, & вещественное 55 ячеек
буква+цифра: a0…Z9 вещественное 550
буква+буква: aa…ZZ вещественное 3 025
i(n) целое 249 999
r(n) вещественное 25 999 999
t(n) символ 1 999 999
s(n) целое, служебное 112

Индексация везде с единицы. Обращение к нулевому или слишком большому индексу — ошибка 7.

Алфавит имён

Порядок символов, задающий нумерацию скалярных ячеек:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$%&

Регистр значим: a и A — разные переменные.

Двухсимвольные имена индексируются по формулам: буква+цифра даёт позиция + 55 × цифра, буква+буква — позиция₁ + 55 × (позиция₂ − 1). Практического значения это не имеет, но объясняет, почему пространств имён именно столько.

Преобразование типов

Скалярные переменные и r() хранят вещественные числа. При записи в i() и s() значение округляется. При записи в t() число трактуется как код символа; отрицательные значения интерпретируются как кириллица cp1251.

Чтение из t() даёт код символа.

Индексы

Внутри скобок работает урезанный вычислитель: только числа, скалярные переменные и операции + - * / ^. Ни функций, ни вложенных обращений к массивам, ни скобок.

# a=i(k); !      да
# b=i(k*2+1); !  да
# c=i(int(k)); ! нет — ошибка

Перед именем допустим унарный минус: -r(5) читается как значение со знаком.

Служебный массив s()

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

Ячейки, имеющие постоянное значение:

Ячейка Смысл
s(1) результат: размер файла, число прочитанных элементов
s(3) текущая позиция записи в t()
s(4) начало последнего фрагмента, записанного #pr
s(5) длина последнего фрагмента
s(6) максимальная занятая позиция в t()
s(26) режим обработки ошибок (err)
s(45) операционная система: 1 — Windows, 2 — Linux (задаёт start.acl)
s(106), s(107) ширина и высота экрана
s(108) аргумент командной строки (режим запуска)
s(109) верхняя граница массива r()
s(110) граница текущей области исполнения

Начальные значения после запуска: s(3)=1, s(6)=1, s(29)=1, s(36)=100.

Переменная &

Формально это обычная скалярная ячейка, но по ней работает #case: команда сравнивает свою метку именно с &. Значение 12345 считается «условие сброшено» и не совпадает ни с одной меткой; значение 10101 означает «произошла ошибка».

Занятые переменные и граница t()

При запуске интерпретатор выполняет свой начальный код (start.acl), который кладёт в конец массива t() диспетчер номерных суперкоманд и кэш уже прочитанных суперкоманд. Отсюда правила для любой программы:

Правило Почему
пользоваться только t(1)…t(KY) выше KY лежат диспетчер и кэш суперкоманд
не трогать двухбуквенные переменные на Y: AY…KY и другие их использует диспетчер
по возможности не брать двухбуквенные имена на X и Z часть из них тоже задана заранее (ZZ — размер r(), AZ, BZ… — входы суперкоманд)

Готовые программы автора дополнительно не пользуются последними 10 000 элементами до KY и переменными с буквой U: там хранится код самой выполняемой программы.

Копирование между ячейками: #v

#v — обратная команда к #d: переписывает подряд идущие элементы массива в перечисленные переменные.

#d 3 r(11) 1.5 2.5 3.5 !
#v 3 r(11) a b c !

После этого a = 1.5, b = 2.5, c = 3.5. Как и у #d, групп «количество, начало, приёмники» может быть несколько; конец — #, @ или !.

#init

Команда #init (значимы первые буквы #ini) останавливает звук, запущенный командой #so. Память она не сбрасывает.

Выражения и функции

В языке два вычислителя. Полный работает в #c и в числовых параметрах; урезанный — только в индексах массивов.

Полный вычислитель

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

Операции и приоритеты

Сверху — то, что связывает сильнее:

Уровень Операции Смысл
1 < > минимум, максимум
2 ^ возведение в степень
3 * / умножение, деление
4 + - сложение, вычитание

Всё левоассоциативно, включая ^: выражение 2^3^2 равно (2^3)^2 = 64.

То, что минимум и максимум связывают сильнее арифметики, — самая контринтуитивная черта языка:

Запись Значение
1<5+10 min(1,5)+10 = 11
2*3<4 2*min(3,4) = 6
0>x<100 зажать x в диапазон 0…100

Унарный минус

Допустим в начале выражения и сразу после открывающей скобки или имени функции. После бинарной операции — синтаксическая ошибка:

# a=-5; !        да
# b=sqr(-x+9); ! да
# c=2*-3; !      ошибка 11
# d=2*(0-3); !   обходной путь

Деление на ноль

Ошибка 24, а не бесконечность.

Урезанный вычислитель

Работает внутри i( ), r( ), s( ), t( ). Отличия:

Функции

Имя ровно из трёх букв, сразу за ним (. Регистр не важен.

Имя Смысл Ограничения
sqr квадратный корень аргумент ≥ 0, иначе ошибка 10
log натуральный логарифм аргумент > 0
exp экспонента аргумент < 500; при < −500 результат 0
sin синус радианы
cos косинус радианы
tan тангенс радианы
ars арксинус |аргумент| ≤ 1
arc арккосинус |аргумент| ≤ 1
art арктангенс
abs модуль
int целая часть отбрасывание к нулю
sgn знак: −1, 0, 1
rnd случайное из [0,1) аргумент игнорируется
sfi интеграл Френеля S
cfi интеграл Френеля C
bj0 функция Бесселя J₀
bj1 функция Бесселя J₁

Числовые литералы

42      целое
3.14    точка как разделитель
3,14    запятая тоже
1.5e3   экспонента
2.5E-4  знак у экспоненты

Команда #c

#c имя=выражение; имя=выражение; ...
# имя=выражение; ...

Команда читает пары «приёмник = выражение», пока не встретит #, ! или @. Приёмником может быть скалярная переменная или элемент любого массива:

# a=1; i(5)=a*2; r(100)=sqr(2); t(1)=65; s(3)=1; !

Обратите внимание: если за командой вычислений идёт поясняющий текст или конец программы, её нужно закрыть знаком ! — иначе текст будет разобран как продолжение списка присваиваний.

Поле параметров

Сразу за именем команды может стоять поле в квадратных скобках:

#f [op=fold; file=pro;]
#sel [nx=6; ny=9; mo=0; wid=60; hei=30;]

Внутри — пары имя=значение;. Имя сопоставляется по первым трём буквам, как и имена команд.

Параметры глобальны

Значения сохраняются до явного переопределения и видны всем последующим командам. Это главный источник трудноуловимых ошибок: команда может сработать не так из-за параметра, заданного двадцатью строками выше.

#f [op=size; file=a.txt; n=5;]
#f [op=size; file=b.txt;]      здесь n всё ещё 5

Короткие имена и ловушки

Имя параметра, как и имя команды, ищется подстрокой по первым трём буквам в общей таблице имён — и находится первое совпадение. Поэтому короткое имя может означать совсем не то, что кажется:

Пишут Кажется На самом деле
xs, ys xpo, ypo (позиция) xsh, ysh — s(16), s(17) (сдвиг)
wi wid twi — s(12)
he hei the — s(13)
si siz tsi — s(24)
co col c (cod) — s(8)
or ord form
mi msi / mki такого нет — ошибка 2

Для позиции окна пишут xp и yp. Надёжнее всего писать имена полностью или первыми тремя буквами.

Текстовые параметры

Четыре штуки, у каждого своя предельная длина:

Имя Длина Назначение
fir 8 ссылка на ячейку: t(1), i(5), r(100)
op 4 код операции
file 42 имя файла или папки
form 42 формат, вспомогательная строка

Значение читается до пробела или ;. Если раньше встретится ] — ошибка 27.

Значение, начинающееся с \, разбирается как форматированный текст — так собирают имена файлов из переменных:

#f [op=size; file=\-отчёт-\I-3 n;.txt\E]

Числовые параметры

Все остальные вычисляются полным вычислителем и округляются в ячейку s() с соответствующим номером.

Имя s() Обычное назначение
n 7 количество
c 8 код, условие вызова
b 9 начало
le 10 длина
mo 11 режим
twi 12 ширина изображения
the 13 высота изображения
wid 14 ширина
hei 15 высота
xsh (или xs) 16 сдвиг по X
ysh (или ys) 17 сдвиг по Y
sty 18 стиль
bot 19 нижняя граница
top 20 верхняя граница
nx 21 число элементов по X
ny 22 число элементов по Y
sav 23 сохранение
tsi 24 размер шрифта текста на рисунке
uni 25 код символа
err 26 режим обработки ошибок
fk 27 вид шрифта текстовых окон (1…5)
fs 28 размер шрифта текстовых окон
col 29 цвет
tfo 30 шрифт текста
tki 31 вид текста
msi 32 размер маркера
mki 33 вид маркера
trx 34 сдвиг по X (в #g — смещение рисунка, в #ma — расстояние до второго массива)
try 35 сдвиг по Y
sca 36 масштаб
rat 37 отношение
siz 38 размер
ord 39 порядок
dir 40 направление
em 41 пустое поле
xp 42 позиция по X (полное имя xpo)
yp 43 позиция по Y (полное имя ypo)
pal 44 палитра

Поскольку параметр — это просто ячейка s(), его можно задать и напрямую:

#p [n=5;]
# s(7)=5; !

Обе записи эквивалентны. Первая читается лучше.

Команда #p

Команда #p не делает ничего, кроме установки параметров. Её используют, чтобы задать значения заранее:

#p [err=1; mo=0;]

Форматированный текст

Форматированный текст (FT) — аргумент команд #pr, #m, #read и текстовых параметров. Читается до \E.

Правило пробелов

Перед каждым фрагментом пропускаются пробелы, табуляции и переводы строк. Поэтому отступы в исходнике безопасны, но и нужный пробел приходится записывать явно: \u32;.

Символы

Код Результат
\E конец текста (обязателен)
\- ничего — перенос строки в исходнике
\n перевод строки
\r возврат каретки
\t табуляция
\b забой
\\ обратная косая черта
\" \' кавычки
\# \@ \[ \] сами символы
\D текущие дата и время

Числа

Каждый код читает список выражений и заканчивается точкой с запятой.

Код Синтаксис Формат Пример для 3.14159
\G \G знач; ширина 11, 4 знака, порядок без E 3.1416+00
\B \B ш зн знач; то же с буквой E 3.1416E+00
\I \Iш знач; целое, дополнение пробелами 3
\I \I-ш знач; целое, дополнение нулями 00003
\N \N ш зн знач; фиксированная точка 3.142
\S \S знач; короткая запись 3.14159
\O \O знач; полная запись плюс два пробела 3.14159

Ширина у \I пишется слитно с кодом, у \B и \N — через пробел.

Если числу не хватает заданной ширины, \G и \B печатают одиночную звёздочку. Ноль печатается как 0. с выравниванием по правому краю.

Данные

Код Синтаксис Что делает
\T \T нач длина фрагмент массива t()
\Tp \Tp последний фрагмент от #pr (по s(4), s(5))
\P \P n; текстовый параметр n (1 — fir, 4 — op, 5 — file, 6 — form)
\u \u коды; символы по числовым кодам
\U \U выражения; то же, но коды вычисляются

Аргументы \T — только числа или скалярные переменные, выражения не работают. Точка с запятой в конце не нужна: \T читает ровно два значения. Если её поставить, она попадёт в вывод как обычный символ — этим пользуются, когда собирают в t() текст команды для последующего #e _text.

В \u и \U действует повтор через звёздочку:

#pr \u45*40;\n\E      сорок минусов
#pr \u32 65 32;\E     пробел, A, пробел

Комментарий внутри текста

#pr Итого:\u32;![ здесь будет сумма ]!\G s;\n\E

Открывается ![, закрывается ]!, в результат не попадает. Распознаётся только в начале текста или сразу после escape-кода; внутри обычного текста печатается как есть.

Пути и служебные значения

Код Даёт
\F имя файла интерпретатора
\H рабочая папка
\M текущая папка процесса
\L имя последней запущенной внешней программы

В реализации из этого проекта эти коды разворачиваются в пустую строку.

Команда #pr

#pr дописывает построенный текст в массив t() начиная с позиции s(3), после чего:

Сама по себе команда ничего не показывает: для вывода нужен #m [op=txt;].

Коды ошибок

Номера совпадают с оригинальным интерпретатором, поэтому сообщения обеих реализаций сопоставимы напрямую.

№ Причина Частая настоящая причина
1 неизвестное имя команды символ # в поясняющем тексте
2 неизвестное имя параметра опечатка в поле [...]
3 указатель вышел за границу буфера незакрытый текст или потерянный \E
4 процедура не закрыта символом @
5 недопустимый индекс массива функция или выражение в индексе
6 слишком большое значение параметра
7 неверный тип массива или выход за границу индекс 0 или больше максимума
8 процедура отсутствует несовпадение первых четырёх букв имени
9 недопустимая операция в #f
10 недопустимый аргумент функции sqr от отрицательного, log от нуля
11 синтаксическая ошибка в выражении текст сразу после #c; 2*-3
12 больше 45 вложенных циклов незакрытый #end
13 файл данных отсутствует
14 рекурсивный вызов процедуры
15 больше 45 вложенных процедур
16 переполнение массива забыт сброс s(3)
17 неверная пара параметр=значение пропущен ]
18 недопустимое значение ожидались число, буква или i(..)/r(..)
19 файл отсутствует
20 недопустимая операция #io не из набора rf wf rb wb rd wd rt wt
21 комментарий программы не закрыт знаком =
22 текстовый комментарий не закрыт знаками ]!
23 нет файла в #f [op=line;]
24 деление на ноль
25 переполнена база процедур (более 200)
26 недопустимая операция #f
27 текстовый параметр не закрыт пробелом или ;
28 #rep с неположительным счётчиком счётчик оказался нулём
31 нет файла в #e [file=;]
33 число элементов в #d вне 1…500 символ # в тексте перед командой
34 цикл не закрыт к концу процедуры
35 недопустимый формат в #io
36 недопустимая операция #te
37 недопустимая операция #m
38 #io с rt/wt не с массивом t()
40 форматированный текст не завершён забыт \E
41 неизвестный код в форматированном тексте опечатка после \
42 слишком большое целое
900 команда не поддержана этой реализацией графика, GUI, звук
1000 программа остановлена #stop или #exit — не ошибка

Как поймать ошибку

По умолчанию ошибка прекращает выполнение. Чтобы обработать её самому, нужны две вещи: параметр err не равен нулю и отмеченная командой #% точка возврата. После ошибки исполнение продолжается с этой точки, а & получает значение 10101.

# ok=1; !
#p [err=1;]
#%
#case 10101 # ok=0; #end |
# &=ok; !
#case 1 #io [op=rt; fir=t(1); n=10000; file=может-не-быть.txt;] #end |
# &=ok; !
#case 0 #pr файл прочитать не удалось\n\E #end |
#p [err=0;]

Разберём, как это работает. #% запоминает место, куда вернуться после ошибки. При первом проходе & не равно 10101, и ветка #case 10101 пропускается. Если чтение файла сорвалось, исполнение возвращается сразу за #%, а & становится 10101 — теперь ветка выполняется и сбрасывает флаг ok. Флаг нужен, чтобы опасная команда не выполнилась повторно: иначе программа снова наткнётся на ту же ошибку и снова вернётся к #%.

Код 900 в этот механизм не входит: он означает, что команда в принципе не реализована в порте, и требует запуска на оригинальном интерпретаторе.

Команды VKACL: обзор

В этом разделе описана каждая команда VKACL и каждая её операция. Порядок групп повторяет справочник автора: сначала многооперационные команды общего назначения, затем специализированные (анимация, PDF, PostScript, картинки как байты), затем команды с одной операцией и, наконец, номерные суперкоманды из библиотеки автора.

Где описание автора расходится с поведением интерпретатора, страницы следуют интерпретатору (декомпилированный aclp.jar, проверки на нём же) и отмечают расхождение в разделе «Тонкости».

Многооперационные команды

Команда Кратко Что делает Страница
#f #f операции с файлами и папками: рабочая папка, размер, копирование, поиск и замена байтов, строки текста, редактор, конвертация картинок #f
#io #i чтение и запись массива в файл целиком: текст, байты, двоичные числа, числа по формату #io
#fr #fr показать картинку из памяти поверх всего и убрать её программно #fr
#g #g простая растровая графика: линии, фигуры, текст, оси, функции, аксонометрия #g
#m #m сообщения: терминал, окна с кнопками #m
#ma #ma математика над массивами: векторы, матрицы, комплексные числа, БПФ, свёртка, интерполяция #ma
#pf #pf окно-индикатор хода длительной работы #pf
#sys #sy секундомер и запуск внешних программ #sys
#te #te операции над текстовым массивом t(): поиск, замена, разбиение на слова, редактор, почта #te
#w #w окна с картинками и научные графики: карты, графики функций, квази-3D #w
#z #z zip-архивы: каталог, упаковка, распаковка #z

Специализированные команды

Команда Кратко Что делает Страница
#ag #ag окно анимации, фоновая музыка, опрос клавиш и мыши, слайд-шоу #ag
#bi #bi попиксельная обработка «сырых» байтовых картинок в файлах #bi
#eg #eg универсальная векторная графика (Java 2D): контуры, заливки, аффинные преобразования #eg
#pat #pat построение контуров (path) для #eg #pat
#pd #pd создание PDF-документов, вставка страниц из других PDF #pd
#ps #ps векторная графика в EPS-файл #ps

Команды с одной операцией

Команда Кратко Что делает Страница
# / #c # вычисления и присваивания ядро
#case #cas выполнить блок, если & равно метке; цикл «пока» ядро
#ch #ch показать картинку и ждать клика или клавиши #ch
#col #co задать цвета в таблице цветов #col
#d #d заполнить массив или переменные списком значений ядро
#e #e выполнить процедуры, файл или текст из t() ядро
#end #en конец блока #rep или #case ядро
#exit #exi закрыть интерпретатор ядро
#go #go перейти на позицию в тексте программы ядро
#init #ini снять блокировку циклов после анимации, выключить звук ядро
#inp #inp панель с окнами ввода #inp
#p #p только задать параметры ядро
#pas #pas переслать значения между массивами ядро
#pr #pr напечатать форматированный текст в t() ядро
#pro #pro определить процедуру ядро
#rea #rea прочитать числа из текста в t() ядро
#rep #re повторить блок N раз ядро
#rob #rob пауза, снимок экрана, цвет пикселя #rob
#sel #se таблица кнопок для выбора варианта #sel
#so #so проигрывание и запись звука #so
#stop #st закончить текущую программу ядро
#v #v разложить элементы массива по переменным ядро
#% #% запомнить позицию для #go и для возврата после ошибки ядро
##N — номерная суперкоманда из библиотеки автора суперкоманды

Столбец «Кратко» — самая короткая запись, которая ещё попадает в нужную команду. Имя команды ищется в таблице подстрокой по первым трём буквам (см. Модель исполнения), поэтому некоторые сокращения коварны:

Запись На самом деле Нужно писать
#in #w (подстрока слова WIN) #inp или #ini
#ro #pro #rob
#pa #p #pas или #pat
#ex #e #exi
#ca #c #cas
#i #io —
#s #pas #se, #so, #st, #sy
#a, #r #p #ag, #rea, #rep, #rob

Общие соглашения

Операции

Многооперационные команды выбирают операцию по параметру op. Сколько букв значимо, у каждой команды своё:

Команда Значимо букв op Неизвестная операция
#ag, #fr, #pf 1 ошибка 55, 78, 84
#io, #sys, #w, #ps 2 ошибка 20, 49, 29, 65
#g, #eg, #pat, #ma, #z, #bi, #so 3 ошибка 52, 53, 54, 48, 51, 66, 56
#m 3, сравнение точное ошибка 37
#f, #te, #pd 4 ошибка 9, 36, 74

Лишние буквы игнорируются: op=close и op=clo в #g одно и то же. Но у #f значимы четыре буквы, поэтому op=top там не сработает, а нужно op=topn.

Параметры и их короткие имена

Числовые параметры — это ячейки s(7)…s(44) (таблица в разделе Поле параметров). Имя параметра ищется подстрокой по первым трём буквам в таблице FIR · · OPE FIL FOR NUM COD BEG LEN MOD TWI THE WID HEI XSH YSH STY BOT TOP NXF NYF SAV TSI UNI ERR FKI FSI COL TFO TKI MSI MKI TRX TRY SCA RAT SIZ ORD DIR EMP XPO YPO PAL. Автор часто пишет сокращения; в этом справочнике параметры названы полными именами, а соответствие такое:

Автор пишет Это параметр Ячейка
tw, th twi, the s(12), s(13)
xs, ys xsh, ysh s(16), s(17)
st, bo, to sty, bot, top s(18), s(19), s(20)
sa sav s(23)
ts, un tsi, uni s(24), s(25)
tf, tk tfo, tki s(30), s(31)
ms, mk msi, mki s(32), s(33)
sc, ra sca, rat s(36), s(37)
di dir s(40)
em, emp em s(41)
xp, yp xpo, ypo s(42), s(43)
pa pal s(44)

Опасные сокращения, которые попадают не туда: wi — это twi, he — the, si — tsi (а не siz), co — c (а не col), or — form, f и fi — fir (для имени файла нужно минимум fil), mi — ошибка 2. Пишите wid, hei, siz, col, ord, file полностью.

Куда команды кладут результаты

Где Что обычно там оказывается
s(1), s(2) размер файла, число найденных совпадений, код модификатора клика и код клавиши
s(3) позиция следующей записи в t(); её сдвигают все команды, которые печатают в t()
s(4), s(5) начало и длина последнего фрагмента, записанного в t()
s(6) наибольшая занятая позиция t()
s(12), s(13) ширина и высота прочитанной картинки
s(102)…s(105) координаты мыши x1 y1 x2 y2 после клика или протяжки
s(106), s(107) размеры экрана
& номер нажатой кнопки, признак «ОК/Отмена», найден ли шрифт
A B C D E, V0 V1, $ входные и выходные скаляры команд #ma и #sys
i(), r() списки позиций, таблицы координат, результаты #ma

Файлы и папки

Картинки и контуры в памяти

Графические команды сохраняют готовые картинки в память под номерами 1…100 (параметр sav), а берут их оттуда параметром n. Контуры #pat хранятся отдельно, тоже под номерами 1…100. Номер вне диапазона при записи молча игнорируется, при чтении даёт ошибку 63 (картинка) или 62 (контур).

Команды ядра

Здесь собраны команды, из которых складывается любая программа: вычисления, заполнение и пересылка массивов, печать в текстовый массив, ветвления, циклы, процедуры и переходы. Подробное введение — в туториале (вычисления, массивы, текст, ветвления и циклы, процедуры); эта страница — справка.

Общее правило для команд со списком аргументов переменной длины (# , #d, #v, #e): список кончается на # (следующая команда), @ (конец процедуры) или !. Если после такой команды идёт поясняющий текст, перед ним обязателен !.

# и #c — вычисления

# приёмник=выражение; приёмник=выражение; ...
#c приёмник=выражение; ...

Решётка с пробелом — краткая форма команды #c. Приёмник — скалярная переменная или элемент любого массива: a, x1, ab, i(k), r(k+1), s(3), t(5). Выражение вычисляется полным вычислителем (см. Выражения и функции) и обязательно заканчивается ;.

Куда пишем Что происходит со значением
скаляр, r() хранится как есть (вещественное)
i(), s() округляется до ближайшего целого
t() трактуется как код символа; отрицательные от −64 до −1 превращаются в кириллицу А…я

Внутри списка можно оставить комментарий: он начинается с ; и кончается знаком =, например # a=1; ;здесь начальное значение= b=2;. Проще, однако, закончить команду ! и писать пояснение обычным текстом.

# s(3)=1; a=2; b=a^3+1; i(1)=b/2; !
Здесь уже можно писать пояснения.
#pr a=\I3 a; b=\I3 b; i(1)=\I3 i(1);\n\E

Тонкости. Знаки < и > — минимум и максимум, а не сравнения, и связывают они сильнее умножения. Унарный минус допустим только в начале выражения и после (. Индексы массивов вычисляются урезанным вычислителем: без функций и скобок.

#d — заполнить массив

#d N приёмник значение значение ... [N приёмник значения ...] [!]

Записывает N значений подряд, начиная с элемента приёмник. Групп «число — приёмник — значения» в одной команде может быть сколько угодно.

Элемент Что допускается
N от 1 до 500, иначе ошибка 33
приёмник элемент любого массива (r(11), i(1), s(9), t(1)) или скалярная переменная
значение число, переменная или элемент массива; выражения не вычисляются
значение*k повторить значение k раз

Если приёмник — скаляр, заполняются следующие по порядку переменные того же вида: #d 3 A 1 2 3 задаёт A, B, C; #d 2 AZ 5 6 — AZ и BZ. Так задают входные данные суперкоманд. Приёмником может быть и s(): тогда #d задаёт сразу несколько параметров команды.

# s(3)=1; k=7; !
#d 6 r(1) 1.5 2,5 k 0*3 !
#d 3 A 10 20 30 !
#pr \G r(1) r(2) r(3) r(4);\n\I4 A B C;\n\E

Тонкости.

#v — разложить массив по переменным

#v N источник приёмник1 приёмник2 ... приёмникN [N источник ...] [!]

Обратная к #d команда: берёт N элементов подряд, начиная с источник, и присваивает их перечисленным приёмникам (переменным или элементам массивов). N должно быть не меньше 1; верхней границы нет.

# s(3)=1; !
#d 3 r(11) 1.5 2.5 3.5 !
#v 3 r(11) a b c !
#pr \G a b c;\n\E

#pas — переслать массив

#pas N источник приёмник

Копирует N элементов (N ≥ 1, иначе ошибка 86) с приведением типа: в i() и s() значения округляются, в t() попадают как коды символов, из t() читаются коды. Перекрывающиеся области одного массива обрабатываются правильно — #pas 4 r(1) r(2) сдвигает четыре числа на одну позицию вправо. Группа в команде одна; для следующей пересылки нужна новая команда.

# s(3)=1; !
#pr (([[\E
#pas 4 t(1) i(11)
#pr коды \I4 i(11) i(12) i(13) i(14);\n\E

Тонкость. Имя нужно писать минимум из трёх букв: #pa — это #p.

#pr — печать в текстовый массив

#pr форматированный-текст\E

#pr (оно же #pri, #print) разбирает форматированный текст и записывает результат в t(), начиная с позиции s(3). После команды:

Ячейка Значение
s(4) начало записанного фрагмента
s(5) его длина
s(3) сдвинута за конец фрагмента
s(6) наибольшая занятая позиция t()

Сам текст на экране не появляется — для этого есть #m [op=txt;]. Код \Tp в следующем форматированном тексте вставляет последний фрагмент, \TpN — его же без N последних символов (\Tp4 превратит data.txt в data).

#pr — главный способ передать текст другим командам: имена файлов (file=\Tp\E), заголовки окон, списки кнопок через |, входные тексты суперкоманд.

# s(3)=1; !
#pr filename.dat\E
#pr \Tp4.png\E
#m [op=txt;] \Tp\n\E

Тонкости. Перед формированием нового текста обычно сбрасывают # s(3)=1;, иначе t() постепенно заполняется до ошибки 16. Писать дальше позиции KY нельзя: конец t() занят библиотекой суперкоманд (см. Суперкоманды).

#rea — прочитать числа из текста

#rea [fir=приёмник; n=; b=; le=;]

Обратная к #pr операция: сканирует le символов t() начиная с t(b) и записывает не более n чисел в массив, начиная с fir.

Параметр Смысл
fir первый элемент приёмника: r(1), i(10), скаляр
n сколько чисел прочитать самое большее
b, le начало и длина текста в t() (часто b=s(4); le=s(5);)
Результат Значение
s(1) сколько символов реально просмотрено
s(2) число прочитанных чисел плюс один
# s(3)=1; !
#pr 1 2,5 3\E
#rea [fir=r(1); n=10; b=s(4); le=s(5);]
# k=s(2)-1; !
#pr прочитано \I2 k; чисел: \G r(1) r(2) r(3);\n\E

Тонкости.

#p — только параметры

#p [параметр=значение; ...]

Ничего не делает, кроме установки параметров. Удобна, чтобы задать параметры один раз перед циклом или включить обработку ошибок: #p [err=1;]. Пустая команда #p [] иногда служит «заглушкой» в конце текста, который выполняют через #e _text.

#rep, #case, #end — циклы и ветвления

#rep N ... #end
#case N ... #end
#case N ... #end |
#case N ... #end (x)
Команда Что делает
#rep N выполнить блок N раз; N ≤ 0 — ошибка 28
#case N выполнить блок, если & в точности равно N; иначе пропустить его целиком вместе с вложенными блоками
#end закрыть блок; для #case — повторить блок, если целые части & и N совпадают
#end | сначала &=12345 (значение, не совпадающее ни с какой меткой), потом проверка — то есть блок не повторяется
#end (x) сначала &=x, потом проверка

N в #rep и #case и x в #end (x) — число, переменная или элемент массива. Выражения здесь не вычисляются. Вложенность блоков — до 45 уровней (ошибка 12 при превышении, 85 при #end без пары, 34 если блок не закрыт к концу процедуры).

# s(3)=1; q=0; &=1; !
#case 1
  # q=q+1; w=-sgn(q-4); !
#end (w)
#pr q=\I2 q;\n\E

Блок выполнится четыре раза: пока q меньше 4, w равно 1.

Тонкости.

#pro и #e — процедуры

#pro ИМЯ тело-процедуры @
#e [c=; file=; b=; le=;] имя1 имя2 ... [!]
#e _имя
#e [file=путь;] _file
#e [b=; le=;] _text

#pro запоминает процедуру, не выполняя её. Значимы ровно четыре первых символа имени (более длинное обрезается, остаток становится частью тела; имя короче четырёх букв не найдётся). Тело кончается первым символом @. Процедура регистрируется, когда интерпретатор доходит до #pro, поэтому определение должно стоять раньше вызова. Всего процедур — не больше 200 (ошибка 25).

#e выполняет процедуры по списку имён.

Параметр Смысл
c код условия: без _ список выполняется, только если & в точности равно c
file путь к файлу для _file, от папки интерпретатора; file=arg — путь из аргумента
b, le начало и длина текста в t() для _text
Имя в списке Что выполняется
_имя процедура, безусловно (подчёркивание ставят перед первым именем)
имя процедура, если & равно c
_file / file весь файл как программа
_text / text le символов t() начиная с t(b) как программа
_\NN встроенная Java-программа автора номер NN (\00…\10)
#pro sqre # y=x*x; @
# s(3)=1; x=5; !
#e _sqre !
#pr y=\I4 y;\n\E

Тонкости.

#go и #% — переходы и возврат после ошибки

#%
#go n

#% записывает в переменную % позицию в тексте программы сразу за собой. #go n переносит разбор на позицию n (число или скалярная переменная, без выражений и элементов массивов); выполнение продолжается со следующего # после этой позиции.

Вторая роль #% — точка возврата при ошибке. Если err (s(26)) не равен нулю, ошибка не прерывает программу: управление переходит на позицию %, а & получает значение 10101 (подробнее — в Кодах ошибок).

# s(3)=1; q=0; !
#%
# q=q+1; &=sgn(3-q); !
#case 1 #go % #end |
#pr q=\I2 q;\n\E

Тонкость. Переход изнутри блока #rep или #case наружу не закрывает блок. Пример выше выходит так дважды, и это безопасно, но каждый такой выход оставляет незакрытый уровень вложенности: после 45 выходов будет ошибка 12, а внутри процедуры — ошибка 34 при возврате. Для длинных повторов используйте цикл #case … #end.

#stop, #exit, #init

Команда Что делает
#stop заканчивает текущую программу; остальной текст файла не выполняется
#exit закрывает интерпретатор целиком (все окна, среда разработки)
#init возвращает нормальную работу циклов, заблокированных закрытием окна анимации #ag, и выключает звук (#ag, #so)

Тонкость. #init не восстанавливает служебные ячейки s() и параметры — он касается только циклов и звука. Имена сокращаются до #st, #exi, #ini; #ex — это уже #e.

Суперкоманды

Суперкоманда — готовая программа на VKACL, которую вызывают одной короткой записью, как команду: ##33, ##2. Суперкоманды автора — это научные графики и карты, анимации, меню, окна подсказок, интерполяция, преобразование Фурье, служебные операции с файлами. Их код не встроен в интерпретатор, а лежит в библиотеке, которая входит в дистрибутив.

Как устроен вызов ##N

Когда после ## стоит число, интерпретатор делает всего две вещи:

  1. записывает номер в s(7) — то есть в параметр n;
  2. выполняет как программу 670 символов текстового массива, начиная с t(1 899 331).

В этом месте t() лежит диспетчер — небольшая программа на VKACL, которую кладёт туда стартовая программа автора (start.acl) при запуске интерпретатора. Диспетчер ищет суперкоманду номер n в файле-библиотеке (по одной суперкоманде в строке), при первом вызове читает её и запоминает в конце t(), а при следующих вызовах запускает уже из памяти. Поэтому номерные суперкоманды работают быстро, в том числе в циклах, и не нагружают диск. Кэш живёт, пока открыт интерпретатор; автор держит его открытым постоянно, а при странном поведении советует просто перезапустить.

Из этого устройства вытекают правила для любой программы:

Правило Почему
не писать в t() дальше позиции KY; чтобы положить m символов в конец доступной части, начинайте с KY−m конец t() занят диспетчером и кэшем; KY задаёт стартовая программа
не использовать двухбуквенные переменные, оканчивающиеся на Y (AY…KY и другие) их использует диспетчер
по возможности не использовать и двухбуквенные на X и Z часть из них предопределена стартовой программой, другие (AZ, BZ, ZZ, ZY, …) служат входами и выходами суперкоманд
помнить, что после ##N параметр n равен N так диспетчер узнаёт номер
не рассчитывать на ##N без стартовой программы автора без неё по адресу диспетчера пусто

Суперкоманда исполняется как код из файла, поэтому процедуру, внутри которой есть вызов суперкоманды, не ставьте в цепочку #e _a b c — вызывайте её отдельной командой.

Как передавать данные

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

Что Как Пример
числа в переменные, чаще всего одной командой #d: #d 7 A … заполняет A, B, …, G #d 7 A 1 101 1 -1 1 247 1100 !
числа (новый стиль) в конец r(): сначала # ZZ=s(109); !, потом #d k r(ZZ−m) … #d 3 r(ZZ-10) 100 100 2 !
числа (старый стиль) в начало r(): r(1), r(2), … #d 7 r(1) J x1 x2 n X1 X2 m !
тексты последний напечатанный фрагмент #pr; части разделяются | #pr имя-файла|Заголовок\E
параметры общие параметры (pal, em, xpo, ypo, fk, fs…) действуют как обычно #p [pal=1; em=0;]

Результаты возвращаются в & (номер кнопки), в переменные (AZ, BZ, DZ, TZ, I1, S1, …), в r(), в файлы и окна — у каждой суперкоманды по-своему. Суперкоманды работают в общей памяти и могут портить переменные и массивы; у многих в описании перечислено, что именно они используют.

#pr 1D|2D|Какой график построить?\E ##33
#case 1 #m [op=txt;] Выбран одномерный\n\E #end |
#case 2 #m [op=txt;] Выбран двумерный\n\E #end |

Старая форма ##имя

Если после ## стоит не цифра, а имя, выполняется файл proc/имя.acl из папки интерпретатора — точно так же, как #e [file=proc/имя.acl;] _file, но короче. Файл читается с диска при каждом вызове, поэтому в циклах такая форма медленная. Данные передаются теми же способами. Своих суперкоманд этого вида пользователь может написать сколько угодно; автор советует описывать их назначение, входы и выходы комментарием прямо в файле.

Каталог номерных суперкоманд

Описание по справочнику автора (acls-info). Номера 47–50 в каталоге отсутствуют. «Текст» — то, что нужно напечатать #pr перед вызовом.

№ Что делает Входные данные Результат
1 график 1D нескольких функций из r() на равномерной сетке A — начало данных, B — число точек (отрицательное — ширина по числу точек, с прокруткой), C — число функций, D, E — пределы аргумента, F — цвет первой кривой (отрицательный — узкий график 550 px), G — четыре разряда: тысячи 0 — сохранить без показа, 1 — показать и сохранить, 2 — только показать, 3 — ни то ни другое, три младших — масштаб в %; обычно 1100. Текст: файл|заголовок окно, файл файл.png (980×500 при 100 %), при режиме 3 — картинка памяти 2
2 карта матрицы с осями и размером пикселя, линейная шкала A — начало, B, C — точки по горизонтали и вертикали, D — шесть разрядов (добавка к размеру текста 20, обращение контраста, показ, масштаб %; отрицательное — голая картинка без осей), E — пикселей экрана на точку по x (десятки) и y (единицы); E>0 — числа нормируются на 0…1, E<0 — настоящие значения; F — начало 15 чисел разметки трёх осей (по 5: начало, конец, первая длинная риска, шаг, число коротких). Текст: файл|заголовок. Параметры pal, em, xpo, ypo окно, файл.png; портит последние 100 элементов r() и 5 элементов i()
3 аксонометрия поверхности z(x, y) с разметкой осей A — начало, B, C — точки по x и y, D — показ и масштаб (как у 1), E — десятки: 1 x-z, 2 y-z, 3 оба сечения; единицы: 0 — две вертикальные оси, 1 — правая, 2 — левая; F — начало 15 чисел разметки; G, H, I — направление взгляда; J — lg расстояния; K, L — масштабы x, y; M, N — место заголовка. Текст: файл|заголовок окно, файл.png
4 квази-трёхмерный график 2D функции A — начало, B, C — точки по x и y, D, E — пределы x, F, G — пределы y, H — добавочный сдвиг вправо, I — добавка к сдвигу сечений в шагах, J — вертикальный сдвиг сечений в 0,001 максимума (10…50), K — размер текста, L, M — добавки к ширине 900 и высоте 600. Текст: имя файла окно, файл картинки
5 разметка одной числовой оси r(1), r(2) — начало и конец оси r(3) — первая длинная риска, r(4) — шаг, r(5) — число коротких рисок
6 стандартные параметры внешнего редактора #f [op=edit;] — ; дальше пишут #f [file=имя;] параметры установлены
7 стандартные параметры меню ##14 — параметры установлены
8 квадрат модуля комплексной функции AZ — начало, BZ — число комплексных чисел BZ вещественных чисел с AZ
9 интерполяция функции одной переменной r(1) — начало данных, r(2)…r(4) — первый, последний аргумент и число точек исходной сетки, r(5)…r(7) — то же для новой новая функция на месте старой
10 интерполяция функции двух переменных на квадрате r(1) — начало, r(2)…r(4) — сетка (одинаковая по обеим осям), r(5) — начало результата, r(6)…r(8) — новая сетка новая матрица
11 стандартные параметры встроенного редактора #f [op=edtf;] — ; дальше #f [file=имя;] параметры установлены
12 прибавить к комплексному массиву вещественное число AZ — начало, BZ — длина, CZ — число на месте
13 комплексное сопряжение массива AZ, BZ на месте
14 вертикальное фасонное меню без рамки X, Y — угол окна, W, H — размер кнопки, K — начертание 0…3; цвета 1–5: фон, заголовок, надписи, два цвета градиента кнопок. Текст: заголовок|кнопка1|…|кнопкаN|шрифт| & — номер выбранной кнопки (мышью или клавишами 1…9, 0, A…Z)
15 предложение прочитать справку $ — 0 для файла на компьютере, 1 для адреса в интернете. Текст: путь от папки интерпретатора или адрес по OK файл открывается программой просмотра
16 таблица из 99 кнопок для выбора варианта обычно ничего; нестандартно — &Z=99 и цвета цифр и фона в r(1)…r(6) & — номер кнопки
17 подсказка в строке над панелью задач текст подсказки; ZY — положение (0 — стандарт, 0…1 — сдвиг) окно; закрыть — #fr [op=c; mo=1;]
18 графики действительной и мнимой частей комплексной функции четыре числа в r(ZZ−21)…: начало, число точек, полуширина области аргумента, номер вызова 1…9 (отрицательный — без показа). Текст: подпапка для картинок файлы scarReM.png, scarImM.png
19 анимация по нумерованным картинкам с масштабированием Текст через пробелы: папка файл музыка N1 N2 W H T — папка, образец имени (номер из трёх цифр перед точкой), MIDI или nomusic, первый и последний номера, размер кадра, пауза в мс окно: пробел — шаг, Enter — автоматически, Esc — выход; портит %0
20 анимация сечений двумерного массива 17 чисел в r(1)…r(17): Nx Ny x1 x2, пределы и разметка осей x и y, номер первой кривой, индекс данных в r() (0 — из файла), пауза в 0,1 с. Текст: файл|заголовок окно; Enter, пробел, Backspace, стрелки управляют показом
21 картинка-матрица из других картинок Текст: имя файла параметров в рабочей папке; в нём первая строка — подпапка, имена картинок и имя результата, вторая — картинок в строке и строк файл png
22 разложить девять разрядов Q по переменным Q &1…&9 — разряды слева направо
23 картинка с текстом подсказки (новая версия 25) текст или имя файла; r(ZZ−20)…: W H X Y M N N1 N2 — размер, угол, режим (0 — текст из печати, 1 — строки N1…N1+N−1 файла), номер картинки окно; закрыть — #fr [op=c; mo=1;]
24 старая универсальная форма ввода данных L — ширина рамки; ZZ=s(109); процедура genp; текст: папка|файл-подписей|файл-параметров|файл-описания|файл-заметок| запускает genp с введёнными данными
25 картинка с текстом подсказки (первая версия) переменные W H X Y M N N1 N2; текст окно; портит f1 f2 H J M N N1 N2 W X y Y
26 график части r() для отладки r(ZZ−10)…: начало, число элементов, номер вызова 0…9 (отрицательное число — сохранить в smN.jpg, оба отрицательные — только сохранить). Текст: подпапка окно или файл
27 кнопка OK для паузы r(ZZ−10)…: координаты левого нижнего угла и масштаб ждёт нажатия
28 анимация сечений трёхмерного массива 19 чисел в r(1)…: размеры, разметка осей, номер первого кадра, индекс данных, пауза, палитра, нормировка, масштаб. Текст: файл|заголовок окно, управление как у 20
29 поиск минимума функции двух переменных с графикой r(ZZ−70)…: a1 a2 s1 s2 n — начальная точка, шаги, число вычислений; процедура pcmf вычисляет C по B1, B2 AZ, BZ — точка минимума; использует r() с 997001
30 шифрование текстового файла Текст: полный-путь ключ вариант — ключ 1…255; вариант 1 — только зашифровать, 2 — расшифровать для правки и снова зашифровать, 3 — только расшифровать файл
31 разметка трёх осей для карты F — куда писать 15 чисел; r(ZZ−30)…: x1 x2 y1 y2 z1 z2 15 чисел с r(F) (вход для 2)
32 фасонное меню в два столбца как у 14, число кнопок чётное &
33 сообщение с кнопками в один ряд Текст: кнопка1|…|кнопкаK|сообщение (без кнопок — только OK) & — номер кнопки, −1 — окно закрыто
34 дата и время изменения файла Текст: полный путь (при #f [op=fold; file=null;]) DZ — ГГММДД, TZ — ччммсс; портит r(1)…r(30)
35 ввод входных данных из файла Текст: имя файла; A — строк с двумя числами, B — строк с текстовыми параметрами, C — куда в t() писать тексты числа в r(1)…, за ними длины текстов, тексты в t() с C
36 контейнер программы: выбор строки входных данных и запуск имя файла, напечатанное с KY−500−N; режим в t(KY−1); процедура pr36 (или prex при &z=1) запускает процедуру со строкой \TI1 S1; &0=1 — начать заново
37 файл с последней датой изменения в папке Текст: папка имя файла (\Tp); портит начало третьей сотни i() и часть конца t()
38 копирование картинок jpg и png в другую папку с нумерацией Текст: папка-источник папка-результат шапка & — число скопированных, 0 — нечего
39 число картинок jpg и png в папке Текст: папка &
40 график строки матрицы из r() с интегралом r(1)…r(6): начало строки, размеры n1 n2, шаг, режим U, порог e. Текст: имя окно и файлы .png, .dat; S — интеграл
41 прямое и обратное двумерное БПФ r(ZZ−200)…: начало, N1 n1 d1 и N2 n2 d2 (размер — степень 2, кратность расширения 1, 2, 4, шаг), k — −1 прямое, 1 обратное на месте
42 сменить палитру pal=3 NP — номер файла pro/hdata/cmNP.txt копия в colmap.txt
43 выбрать строку файла в редакторе Текст: имя файла I1, S1 — начало и длина строки; &0 — 1 при нормальном выходе, 0 при ошибке
44 номер строки после правки файла Текст: имя файла j — номер строки; a, b — имя файла в t(); &0
45 модуль и фаза комплексной волновой функции с записью Текст: имя без расширения; 13 чисел в r(1)… файлы имяa.png, имяb.png, имяa.dat, имяb.dat
46 свёртка с гауссианой на произвольной сетке r(1)…r(4): начало, число точек, полуширина в шагах сетки, начало рабочего массива на месте
51 справочная карточка: коды форматированного текста — —
52 справочная карточка: таблица цветов — —
53 справочная карточка: параметры по именам и номерам — —
54 справочная карточка: массивы и их размеры — —

Тонкость. Карточки 53 и 54 местами расходятся с интерпретатором: длины текстовых параметров file и form там названы 22 и 62 символа (на деле по 42), сокращение mi для msi не работает (ошибка 2), а размер i() указан 149 999 (на деле 249 999). Точные значения — в Поле параметров и Памяти.

#f — файлы и папки

#f [op=xxxx; file=имя; другие параметры] [аргументы]

Команда выполняет операции над файлами и папками: задаёт рабочую папку, сообщает размер и дату файла, копирует, режет и удаляет, ищет и заменяет последовательности байтов, читает и пишет строки текста, открывает редактор и браузер, конвертирует картинки. Операцию выбирают первые четыре буквы op (неизвестная — ошибка 9). Чтение и запись массивов целиком делает соседняя команда #io.

Все операции

op Что делает Группа
fold задать рабочую папку, проверить существование папки папки
fcat список файлов папки в t() папки
choo диалог выбора файла папки
size размер файла в s(1) сведения
modi время последнего изменения сведения
dele удалить файл копирование
copy склеить несколько файлов в один копирование
divi вырезать из файла регулярную «подматрицу» байтов копирование
find сосчитать вхождения последовательности байтов байты
repl заменить последовательность байтов байты
rep2 заменить пары «открывающая — закрывающая» байты
rep3 заменить фрагменты «начало … конец» байты
line прочитать, записать или удалить строку текст
list собрать строку из чередующихся кусков файла текст
alph упорядочить строки файла по алфавиту текст
ruco перекодировать файл из windows-1251 в UTF-8 текст
edit внешний текстовый редактор редакторы
edtf внутренний текстовый редактор редакторы
html простой браузер HTML редакторы
tobm картинка → байтовая карта серого картинки
tocm картинка → байтовая карта RGB картинки
tops картинка → EPS картинки
topn картинка из памяти → PNG картинки
w2jc перевернуть порядок байтов в 4-байтовых числах двоичные
cdpj файл .npy (Python) → числа double для VKACL двоичные
mb64 кодирование в MIME Base64 и обратно двоичные

Общие правила

Параметр Смысл
op код операции, значимы 4 буквы
file имя файла или папки, до 42 символов; file=arg — имя из первого аргумента
form второе имя (результат), до 42 символов

Папки

fold — рабочая папка

#f [op=fold; file=папка; em=;]
Параметр Смысл
file путь от папки интерпретатора, вложенность через /; null — работать без рабочей папки; oldf — вернуть предыдущую
em 0 — несуществующую папку создать (один уровень); не 0 — не создавать

Рабочая папка действует до следующего fold — и после конца программы, пока открыт интерпретатор. При em≠0 проверка существования возвращается через сам параметр: если папки нет, em (s(41)) становится 0.

Проверить, есть ли папка pro/data, не создавая её.
#f [op=fold; file=pro/data; em=1;]
# ok=s(41); !
#f [op=fold; file=oldf; em=0;]

Тонкости. Папки с именами null и oldf задать невозможно. Даже когда проверка показала, что папки нет, она всё равно становится рабочей — верните прежнюю через file=oldf, как в примере. Если папка есть, em остаётся ненулевым; его читают и другие команды (например, line при em≠0 удаляет строку), поэтому сразу верните em=0. После задания рабочей папки абсолютные пути C:/… в других командах перестают работать; для них нужно file=null.

fcat — каталог папки

#f [op=fcat; file=папка;]

Записывает в t() имена всех файлов и подпапок, после каждого имени — символ |. Путь отсчитывается от папки интерпретатора (рабочая не используется), абсолютный допустим. Если file — не папка, s(5)=0.

choo — выбор файла

#f [op=choo; mo=; file=;] [расширения\E]
Параметр Смысл
file папка (или файл в ней), с которой начинается просмотр; от папки интерпретатора
mo 0 — все файлы; 1 — только картинки gif, jpg, png с предпросмотром; 2 — фильтр по расширениям из аргумента, например txt|bat|mp3\E
Результат Значение
& 1 — файл выбран, 2 — отказ или окно закрыто, −1 — ошибка диалога
t() с s(3) путь к файлу: от папки интерпретатора, если файл внутри неё, иначе полный; разделители /
s(4), s(5) начало и длина пути; при отказе s(5)=0

Тонкость. Перед работой с выбранным файлом проверьте и &, и s(5), и наличие файла через size. Режим mo=2, по словам автора, в новых версиях Java может не работать.

Сведения о файле

size — размер

#f [op=size; file=имя;]

В s(1) — размер в байтах; 0 означает, что файла нет (или он пуст).

modi — время изменения

#f [op=modi; file=имя;]

Время последнего изменения в миллисекундах от 1970 года не помещается в целое, поэтому оно разбито на два числа: s(2) — число полных десятидневок (864 000 000 мс), s(1) — остаток в миллисекундах. Время равно s(2)·864000000 + s(1). Для отсутствующего файла s(1)=0.

Удаление, копирование, разрезание

dele — удалить

#f [op=dele; file=имя;]

Удаляет файл без подтверждения. Если файла нет, ничего не происходит.

copy — склеить файлы

#f [op=copy; n=; file=результат;] имя1\E имя2\E ...

Создаёт файл file, в котором подряд записано содержимое n файлов, перечисленных аргументами. Отсутствующие файлы пропускаются молча; если нет ни одного, получится пустой файл. Аргументов может быть больше n (лишние останутся текстом), но не меньше.

divi — вырезать регулярные куски

#f [op=divi; file=; b=; le=; xsh=; n=;]

Файл рассматривается как матрица байтов: пропустить b байтов, взять le, затем n−1 раз пропустить xsh и взять le. Получается ровно le·n байтов — например, прямоугольный фрагмент «сырой» картинки.

Тонкость. Автор пишет, что результат записывается в файл form. В действительности результат записывается поверх исходного файла file, а form не используется. Сделайте копию заранее (copy с n=1).

Поиск и замена байтов

Все три операции берут последовательности байтов из целого массива i(): элементы i(b), i(b+1), … Коды символов ASCII совпадают с байтами; байты windows-1251 от 128 до 255 можно задавать как есть или как отрицательные от −128 до −1. Изменённый файл записывается на старое место.

find — сосчитать вхождения

#f [op=find; b=; le=; file=;]

Ищет последовательность i(b)…i(b+le−1); число вхождений — в s(2). Нет файла — ошибка 19.

#d 2 i(11) 13 10 !
#f [op=find; b=11; le=2; file=text.txt;]
# nl=s(2); !

Так считают строки файла, записанного в Windows (пара байтов 13, 10).

repl — заменить

#f [op=repl; b=; le=; mo=; file=;]

Первые mo байтов из i(b)… — что искать, остальные le−mo — на что заменить (может быть и 0 байтов, тогда найденное удаляется).

#d 2 i(11) 44 46 !
#f [op=repl; b=11; le=2; mo=1; file=some.txt;]

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

rep2 — заменить пары

#f [op=rep2; b=; le=; mo=; twi=; the=; file=;]

После каждого вхождения первой последовательности ищется вторая, и обе заменяются. Раскладка в i(b)…:

Байты Смысл
первые mo первая искомая последовательность
следующие le−mo замена для неё
следующие the вторая искомая последовательность
следующие twi−the замена для неё

Всего le+twi байтов. Пример автора — двойные круглые скобки на двойные квадратные:

# s(3)=1; !
#pr (([[))]]\E
#pas 8 t(1) i(1)
#f [op=rep2; b=1; le=4; mo=2; twi=4; the=2; file=some.txt;]

Поскольку b, le, mo, twi, the — это s(9)…s(13), их можно задать одной командой #d 5 s(9) 1 4 2 4 2.

rep3 — заменить фрагменты по началу и концу

#f [op=rep3; b=; le=; mo=; twi=; file=;]

Находит каждый фрагмент, который начинается одной последовательностью и кончается другой (середина любая), и заменяет весь фрагмент третьей.

Байты в i(b)… Смысл
первые mo начало фрагмента
следующие twi конец фрагмента
остальные le−mo−twi замена (может быть пустой)
# s(3)=1; !
#pr \\U{}.\E
#pas 5 t(1) i(1)
#f [op=rep3; b=1; le=5; mo=3; twi=1; file=some.txt;]

Все коды вида \U{…} заменятся точкой.

Текстовые файлы

line — строка файла

#f [op=line; file=; n=; b=; le=; em=;]
n Действие
−N прочитать строку N в t() с позиции s(3); s(4), s(5) — начало и длина; строки нет — s(5)=0
N, em=0 записать строку N из t(b)…t(b+le−1); если строк меньше, файл дополняется пустыми строками
N, em≠0 удалить строку N

Файл должен существовать (иначе ошибка 23). После удаления строки верните em=0: этот параметр читают и другие команды.

# s(3)=1; !
#pr первая\nвторая\nтретья\n\E
# n9=s(3)-1; !
#io [op=wt; fir=t(1); n=n9; file=list.txt;]
#f [op=line; file=list.txt; n=-2;]
#m [op=txt;] \Tp\n\E

list — чередующиеся куски

#f [op=list; file=; c=; b=; em=;]

c и b — коды байтов. При em=0 операция берёт символы от начала файла по символ с кодом c включительно, затем пропускает всё до символа с кодом b включительно, снова берёт до c и так далее. При em≠0 порядок обратный: сначала пропуск, потом взятие. Результат — одна строка в t() с s(3); в s(2) — число взятых кусков. Так из файла записей «имя — тело» быстро получают список имён. Байты windows-1251 переводятся в кириллицу.

alph — сортировка строк

#f [op=alph;] исходный-файл\E результат\E

Читает текстовый файл, упорядочивает строки по алфавиту и пишет результат во второй файл. Пути отсчитываются от папки интерпретатора (или полные); для файлов рядом с программой их удобно собрать кодами \M\H. Если строки начинаются с номеров, сортировка получается по номерам.

ruco — windows-1251 → UTF-8

#f [op=ruco; file=;]

Перекодирует файл на месте. В начало записывается метка порядка байтов UTF-8 (EF BB BF). Содержимое не проверяется: применённая к файлу не в windows-1251 или повторно, операция его испортит.

Тонкость. Правильно переводятся только ASCII и буквы А…я. Остальные символы верхней половины windows-1251 — Ё, ё, №, кавычки «ёлочки» — превращаются в посторонние символы.

Редакторы и просмотр

edit — внешний редактор

#f [op=edit; file=; mo=; c=; em=; xsh=; ysh=; nx=; ny=;]
#f [op=edit; file=here; b=; le=; mo=; c=;] заголовок\E
Параметр Смысл
file редактируемый файл (создаётся, если его нет) или here — часть t()
mo для файла: 1 — сохранить при выходе через меню, 0 — только просмотр; для here: −1 — только просмотр, −2 — вернуть текст в t()
b, le для here — начало и длина текста в t()
c 0 — не ждать закрытия окна; иначе ждать
em единицы: 0 — окно по центру, 1 — левый верхний угол в (xsh, ysh) от угла экрана, 2 — от угла главного окна; десятки: 1 — размер (700+nx)×(высота экрана − 100 + ny)
fk, fs шрифт редактора (вид 1…5 и размер); запоминаются в start.acl
s(1) до вызова — начальная позиция курсора (с нуля)
Результат Значение
s(1) позиция курсора при выходе
& 1 — выход через меню или Esc, 2 — крестиком
t() с s(3) для file=here — текст из редактора; s(4), s(5) — начало и длина
fk, fs шрифт, выбранный пользователем

Для file=here аргумент-заголовок обязателен. Меню редактора умеет искать, менять шрифт и перенос строк, перекодировать неверную раскладку, показывать HTML и картинки и запускать выделенное имя файла. Та же работа для части t() короче записывается командой #te.

Тонкость. Если выйти крестиком при mo=1, изменения в файл не записываются.

edtf — внутренний редактор

#f [op=edtf; file=; mo=; em=; xsh=; ysh=;] [заголовок\E]

То же, что edit, но окно открывается внутри главного окна интерпретатора (em: 0 — в углу, 1 — в точке (xsh, ysh)).

Тонкость. Окно немодальное: программа сразу идёт дальше, и в текущем интерпретаторе ни позиция курсора, ни &, ни текст для file=here в программу не возвращаются. Если результат нужен, используйте edit.

html — простой браузер

#f [op=html; file=путь;]
#f [op=html; file=*N;] путь\E

Показывает HTML-файл встроенным браузером из ранних версий Java (без JavaScript, только простая разметка). Окна модальные; ссылка открывается в новом окне поверх прежнего. Путь — от папки интерпретатора или полный.

file Откуда путь
имя из самого параметра
*1 из аргумента: файл на компьютере
*2 из аргумента: адрес в интернете без http://
*3 из аргумента: файл в папке resources внутри jar-файла

edee — большой редактор

Операция описана автором, но в интерпретаторе её нет (op=edee даёт ошибку 9). Тот же редактор вызывается как встроенная программа:

# &=0; s(3)=1; !
#pr pro/notes.txt\E
#e [n=1; em=1; c=1;] _\09

При c=1 программа ждёт закрытия редактора; &=1, если выход был по Esc.

Картинки

Операции tobm, tocm, tops принимают файл gif, jpg или png (проверяется расширение, иначе ошибка 58) или file=here — тогда берётся картинка из памяти под номером n. Результат пишется в файл form в рабочей папке. После операции s(12) и s(13) — ширина и высота картинки.

tobm — байтовая карта серого

#f [op=tobm; file=; form=; dir=; n=; col=;]

Каждый пиксель превращается в один байт (r·R + g·G + b·B)/255, где R G B — компоненты цвета номер col из таблицы цветов; результат ограничивается сверху 255. dir=1 — строки сверху вниз, иначе снизу вверх (как в расчётных картах). Размер файла равен числу пикселей.

Тонкость. По умолчанию col=1, а цвет 1 — чёрный: получится файл из нулей. Для обычного среднего по трём каналам возьмите цвет 245 (85 85 85); цветной фильтр — любой другой цвет.

tocm — байтовая карта RGB

#f [op=tocm; file=; form=; dir=; n=;]

Три байта (красный, зелёный, синий) на пиксель, dir как у tobm.

tops — EPS из картинки

#f [op=tops; file=; form=; mo=; uni=; n=;]
mo Результат
0 полный EPS, оттенки серого
1 полный EPS, цветной
2 фрагмент PostScript-кода (серый) для вставки через #ps [op=ps;]
3 фрагмент, цветной
4 полный EPS другим, более надёжным кодом; если цветов меньше 256 — с палитрой
5 фрагмент тем же кодом

Другие значения — ошибка 59. uni для mo 0 и 1 — масштаб в единицах 0,0001 (отношение пикселя экрана к точке PostScript; у автора было 6255). form — полное имя с расширением. Коды 0–3 автор писал сам, и файл показывается правильно, только если картинка стоит в PostScript-коде последней; коды 4 и 5 от этого свободны.

topn — PNG из памяти

#f [op=topng; n=; form=;]

Записывает картинку номер n в файл form.png (расширение добавляется само). Нет картинки — ошибка 63. Полезно для линейной графики: JPEG, который пишут сами графические команды, размывает линии.

Двоичные форматы

w2jc — порядок байтов

#f [op=w2jc; file=;]

Переставляет байты в каждой четвёрке в обратном порядке и пишет файл на место. VKACL, как и Java, хранит числа старшим байтом вперёд, программы Windows — младшим; операция переводит 4-байтовые числа из одного порядка в другой. Повторное применение возвращает исходное.

cdpj — массив NumPy

#f [op=cdpj; file=исходный.npy; form=результат;]

Отрезает 128-байтовую шапку файла .npy и переворачивает порядок байтов в каждом 8-байтовом числе. Результат читается через #io [op=rd; mo=3;].

mb64 — Base64

#f [op=mb64; mo=; file=; form=;]

mo=1 — закодировать файл (обычно картинку) в текст Base64, mo=2 — раскодировать обратно. Имя результата получается из имени исходного файла заменой последних символов на form: при file=pic.jpg и form=b64 будет pic.b64.

Тонкость. Операция использует класс sun.misc.BASE64Encoder, которого нет в Java 9 и новее: на современной Java интерпретатор падает с исключением.

#io — массив в файл и обратно

#io [op=xx; fir=элемент; n=; file=имя; form=; mo=; le=; ord=;]

Команда переносит подряд идущие элементы массива в файл или из файла целиком, одной операцией. Операцию задают две буквы: первая — направление (r читать, w писать), вторая — вид данных. Неизвестная пара — ошибка 20. Операции над файлами как объектами (размер, копирование, строки) — в #f.

op Данные Массив Вспомогательные параметры
rt / wt текст только t() —
rb / wb байты любой le — пропуск при чтении
rd / wd числа в двоичном коде любой mo — формат числа, le — пропуск, ord
rf / wf числа текстом только i() и r() form — формат

Параметры

Параметр Смысл
fir первый элемент массива: t(1), i(10), r(k) (до 8 символов: r(9999999) уже не поместится, пишите r(k))
n число элементов; для rt — сколько символов прочитать самое большее
file имя файла от рабочей папки; file=arg — имя из аргумента
form формат для rf/wf
mo формат двоичного числа для rd/wd
le сколько байтов пропустить в начале файла при чтении (rb, rd)
ord порядок байтов для mo=5: 0 — старший первым, иначе младший первым

Читающие операции требуют, чтобы файл существовал (ошибка 19). Запись всегда создаёт файл заново.

rt, wt — текст

#io [op=rt; fir=t(k); n=; file=;]
#io [op=wt; fir=t(k); n=; file=;]

rt читает файл как текст и копирует в t() не больше n символов, начиная с элемента fir (а не с s(3)). После чтения s(4) — начало, s(5) — сколько символов прочитано; s(3) не меняется.

wt записывает n символов t() начиная с fir. Символ с кодом 10 в файле становится переводом строки системы (в Windows — парой 13, 10). Готовить содержимое удобно командой #pr.

# s(3)=1; !
#pr строка один\nстрока два\n\E
# n9=s(3)-1; !
#io [op=wt; fir=t(1); n=n9; file=out.txt;]
#io [op=rt; fir=t(1000); n=100000; file=out.txt;]
# ln=s(5); !

Тонкости. Реально прочитанное количество — в s(5), не в s(1). Имя с & впереди (file=&help.txt) читает файл из папки resources внутри jar-файла интерпретатора, но только когда рабочая папка не задана.

rb, wb — байты

#io [op=rb; fir=; n=; le=; file=;]
#io [op=wb; fir=; n=; file=;]

rb пропускает le байтов и читает n байтов как целые от −128 до 127. При чтении в t() байты кириллицы windows-1251 (А…я, коды 192…255) превращаются в буквы Юникода; байты 128…191 — в символы с кодами 128…191 (буквы Ё, ё так не читаются).

wb пишет значения как байты: из t() буквы А…я — в кодировке windows-1251, из i() числа 128…255 — как соответствующие байты.

#io [op=rb; fir=i(1); n=4; le=0; file=pic.raw;]

Язык интерпретируемый, поэтому побайтовая обработка больших файлов медленна; для картинок есть #bi и #f.

rd, wd — двоичные числа

#io [op=rd; fir=; n=; mo=; le=; ord=; file=;]
#io [op=wd; fir=; n=; mo=; ord=; file=;]
mo Формат Байтов на число
1 вещественное float 4
2 целое int со знаком 4
3 вещественное double 8
4 целое short со знаком 2
5 целое без знака; порядок байтов задаёт ord 2

Другие mo — ошибка 73. Для mo 1–4 порядок байтов как в Java: старший первым. Файлы программ Windows переворачивают операцией #f [op=w2jc;]. При wd с mo=5 значение больше 65535 — ошибка 86.

При чтении le — число пропускаемых байтов (не чисел), а в s(1) возвращается, сколько байтов реально пропущено.

# s(3)=1; !
#d 3 r(1) 1.5 2.5 3.5 !
#io [op=wd; fir=r(1); n=3; mo=1; file=f.dat;]
#io [op=rd; fir=r(11); n=2; mo=1; le=4; file=f.dat;]
#pr \G r(11) r(12);\n\E

Второе чтение пропускает первое число и даёт 2.5 и 3.5.

Тонкость. Если заказать больше чисел, чем есть в файле, ошибка не фиксируется: сообщение об исключении Java попадает только в терминал.

rf, wf — числа текстом

#io [op=rf; fir=; n=; form=*K; file=;]
#io [op=wf; fir=; n=; form=*N; file=;]
#io [op=wf; fir=; n=; form=EN.M.L; file=;]

Работают только с i() и r() (другой массив — ошибка 7). Числа из других массивов сначала пересылают командой #pas.

rf читает n чисел подряд в любом виде, который понимает #d: через пробелы и переводы строк, с точкой или запятой, с порядком E. Формат здесь означает другое: form=*K — пропустить K строк в начале файла (K — число или переменная).

wf пишет числа по формату:

form Вид строки
*N по N чисел в строке, каждое — пробел и поле из 10 символов, как у \G
EN.M.L по N чисел в строке, поле из M символов, L знаков после точки, порядок с буквой E; нужно M ≥ L+7, иначе ошибка 35

Например, 6 чисел с form=E3.10.3 дают две строки вида 1.000E+00 2.000E+00 3.000E+00. Строки кончаются переводом строки системы. Более сложный вид файла собирают в t() командой #pr и пишут через wt.

# s(3)=1; !
#d 4 r(1) 1 2 3 4 !
#io [op=wf; fir=r(1); n=4; form=*2; file=nums.txt;]
#io [op=rf; fir=r(11); n=4; form=*0; file=nums.txt;]
#pr \G r(11) r(12) r(13) r(14);\n\E

Тонкости.

#te — операции с текстовым массивом

#te [op=xxxx; b=; le=; другие параметры] [аргумент\E]

Команда работает с куском массива t() от t(b) длиной le символов: ищет символы и подстроки, заменяет символы, режет текст на слова, отсекает хвостовые пробелы, показывает кусок в редакторе. Значимы четыре буквы op; неизвестная операция — ошибка 36. Понятия «строка» в языке нет: строка — это пара чисел «начало, длина», и #te выдаёт именно такие пары.

op Что делает Результат
find найти все позиции символа i(n)…, s(1)
fitt найти все вхождения подстроки i(n)…, s(1)
repl заменить символ на другой сам текст
trim разбить на слова по пробелам пары в i(n)…, s(1)
tail отсечь хвостовые пробелы и переводы строк новое le
show показать кусок в редакторе без правки s(1), &
edit отредактировать кусок и получить результат t() с s(3), s(1), &
emls отправить письмо по электронной почте t() с s(3)

Коды символов — коды Юникода: для латиницы и цифр они совпадают с ASCII, русские буквы А…я имеют коды 1040…1103.

find — позиции символа

#te [op=find; b=; le=; c=код; n=;]

Записывает в i(n), i(n+1), … индексы t() всех символов с кодом c; их число — в s(1).

fitt — позиции подстроки

#te [op=fitt; b=; le=; c=начало; twi=длина; n=;]

Образец лежит в самом t(): twi символов начиная с t(c) (здесь c — индекс, а не код). Индексы начала каждого вхождения — в i(n)…, их число — в s(1). После найденного вхождения поиск продолжается за его концом, так что перекрывающиеся вхождения не считаются.

repl — замена символа

#te [op=repl; b=; le=; c=старый-код; mo=новый-код;]

Заменяет каждый символ с кодом c на символ с кодом mo.

trim — слова

#te [op=trim; b=; le=; n=;]

Находит куски текста, разделённые пробелами, и записывает для каждого пару «начало, длина»: i(n), i(n+1) — первый кусок, i(n+2), i(n+3) — второй и так далее. Число кусков — в s(1). Пары прямо подходят как b и le для #rea и других команд.

# s(3)=1; !
#pr x= 12 y= 3,5\u32;\E
#te [op=trim; b=s(4); le=s(5); n=1;]
# k=s(1); !
#rea [fir=r(1); n=1; b=i(3); le=i(4)+1;]
#rea [fir=r(2); n=1; b=i(7); le=i(8)+1;]
#pr кусков \I2 k; x=\G r(1); y=\G r(2);\n\E

Здесь четыре куска: x=, 12, y=, 3,5; второй и четвёртый читаются как числа 12 и 3.5. Длина для #rea взята на единицу больше, чтобы в диапазон попал пробел после числа (почему это нужно — см. тонкости #rea).

Тонкости.

tail — хвост

#te [op=tail; b=; le=;]

Уменьшает le (s(10)) так, чтобы кусок не кончался пробелами, символами перевода строки или возврата каретки. Удобно после чтения строк из файлов и окон ввода.

show — просмотр

#te [op=show; b=; le=;] заголовок\E

То же, что #f [op=edit; file=here; mo=-1; c=1;]: кусок t() показывается в редакторе без возможности сохранить правку. s(1) до вызова — начальная позиция курсора (с нуля), после — позиция при выходе; & — 1 при выходе через меню или Esc, 2 — крестиком. Положение и размер окна, шрифт задаются параметрами em, xsh, ysh, nx, ny, fk, fs, как у #f [op=edit;].

edit — правка

#te [op=edit; b=; le=;] заголовок\E

То же, что #f [op=edit; file=here; mo=-2; c=1;]: после закрытия редактора текст записывается в t() с позиции s(3); s(4), s(5) — начало и длина, s(3) сдвигается. s(1) и & — как у show.

# s(3)=1; !
#pr Отредактируйте этот текст\E
#te [op=edit; b=s(4); le=s(5);] Правка\E
#m [op=txt;] \Tp\n\E

emls — электронная почта

#te [op=emls;] поле1|поле2|...|поле9|текст письма\E

Отправляет письмо через почтовый сервер (нужен интернет). Аргумент состоит из десяти полей через |: девять служебных (сервер, адреса и прочее) и текст письма. Назначение служебных полей автор не описывает, а отсылает к примеру pro/emls1.acl из дистрибутива. Если программа отправки что-то вернула, этот текст записывается в t() с позиции s(3); иначе s(5)=0.

#ma — математика над массивами

#ma [op=xxx; b=; le=; nx=; ny=; trx=; ...] [аргументы]

Команда выполняет над частями массива r() операции, которые на самом VKACL писать долго и считать медленно: заполнение и поэлементные функции векторов, действия с матрицами, комплексная арифметика, быстрое преобразование Фурье, свёртка, интерполяция, поиск пиков. Код операций написан на Java и работает на порядки быстрее цикла на VKACL. Значимы три буквы op; неизвестная операция — ошибка 48.

Соглашения

Понятие Как лежит в памяти
вектор le чисел r(b), r(b+1), …, r(b+le−1)
второй вектор такой же длины, начиная с r(b+trx); trx может быть отрицательным
матрица nx × ny по строкам: строка k (с нуля) занимает r(b+k·nx) … r(b+k·nx+nx−1); nx — длина строки (первый индекс), ny — число строк
комплексный массив пары «действительная, мнимая часть»: r(b), r(b+1) — первое число, r(b+2), r(b+3) — второе

Почти все операции пишут результат на место исходных данных или сразу за ними; куда именно — сказано в описании каждой. Кроме параметров, часть операций берёт числа из скалярных переменных и возвращает результат в них:

Переменная Где используется
A, B vig (начало и шаг аргумента), mmr (угол), результаты cwm
C константа для vic, via, vac, vmc, vpo, mmi; результат vvs, cwm; период для mip
D шаг для via, ширина для vig, множитель для fft, период для mip, диаметр шара в bsi, bsr; результат cwm
E малая добавка против деления на ноль в ccd, dcc
V0, V1 границы для var
N, K, N1 число шаров, начало и число отрезков стенки в bsm, bsi, bsr

Операции, читающие файлы (mcg, mmi, smh, rfh), ищут их в рабочей папке.

Все операции

Группа Операции
заполнение вектора vic, via, vig
поэлементные функции vac, vmc, vpo, vex, vlo, vsi, vco, vin, vba, var
два вектора vva, vvm, vvs
сортировка и пики vor, cwm
производные и первообразные fdf, sdf, ffd, fsd
матрицы mtr, mii, fno, mss, mds, mip, mmr, tom, gis
интерполяция fis, ffi, mmi
комплексные массивы com, ccm, ccd, mcc, dcc, cen, cne
Фурье и свёртка fft, mcg
специальные вычисления vsm vsm в семи режимах
изображения детекторов smh, rfh
разметка осей box
система шаров bsm, bsi, bsr

Имя vlm есть в таблице операций, но ничего не делает.

Заполнение вектора

op Что записывает в r(b+i), i = 0 … le−1
vic C
via C + D·i — арифметическая прогрессия
vig exp(−a·(A + B·i − C)²), где a = 4·ln 2 / D² — гауссиана с центром C и полной шириной на половине высоты D; аргумент начинается с A и растёт с шагом B
# s(3)=1; A=-1; B=0.5; C=0; D=1; !
#ma [op=vig; b=1; le=5;]
#pr \G r(1) r(2) r(3) r(4) r(5);\n\E

Получится 0.0625 0.5 1 0.5 0.0625: на расстоянии половины ширины от центра значение ровно 1/2.

Поэлементные функции

Параметры b, le; результат на месте вектора.

op x превращается в Замечание
vac x + C
vmc x · C
vpo x^C проверки допустимости нет
vex exp(x)
vlo ln(x) для x ≤ 0 получится не число, ошибки нет
vsi sin(x)
vco cos(x)
vin ⌊x⌋ — целая часть снизу пересылка в i() округляет, а не отбрасывает
vba x + 256, если x < 0 байты −128…127 → коды 0…255
var x, ограниченное снизу V0 и сверху V1

Тонкость. В справочнике автора имена vac и vmc набраны с русской буквой «с». Скопированные оттуда, они дают ошибку 48 — набирайте латиницей.

Два вектора

Первый вектор — r(b)…, второй — r(b+trx)…, оба длины le. Векторы не должны перекрываться (кроме trx=0).

op Результат
vva первый вектор заменяется суммой; для вычитания второй сначала умножают на −1 (vmc)
vvm первый вектор заменяется поэлементным произведением; при trx=0 — квадратами
vvs скалярное произведение — в переменную C
# s(3)=1; !
#d 4 r(1) 1 2 3 4 !
#d 4 r(5) 2 2 2 2 !
#ma [op=vvs; b=1; le=4; trx=4;]
#pr скалярное произведение = \G C;\n\E

Сортировка и параметры пика

vor — упорядочить

#ma [op=vor; b=; le=; mo=;]

mo=1 — по возрастанию, mo=2 — по убыванию. В i(1)…i(le) записываются прежние номера элементов (с единицы, относительно b) в новом порядке: по ним тем же образом переставляют другие векторы.

# s(3)=1; !
#d 5 r(1) 3.5 1.25 4.75 2.5 0.5 !
#ma [op=vor; b=1; le=5; mo=1;]
#pr \G r(1) r(2) r(3) r(4) r(5);\n\I3 i(1) i(2) i(3) i(4) i(5);\n\E

Результат: 0.5 1.25 2.5 3.5 4.75 и номера 5 2 4 1 3.

Тонкости. Автор пишет, что mo=0 сортирует по убыванию; на деле при mo=0 порядок не меняется (массив i() всё равно заполняется числами 1…le). Номера всегда пишутся с i(1), затирая то, что там было.

cwm — максимум и его ширина

#ma [op=cwm; b=; le=; mo=;]
Результат Значение
A наименьшее значение вектора
B наибольшее значение, уточнённое параболой по соседним точкам (не меньше любого элемента)
C положение максимума, дробный номер элемента с единицы
D ширина области, где значения выше уровня: B/2 при mo=0, (A+B)/2 при mo=1; 0, если уровень не пересечён с обеих сторон

Ширина получается в шагах сетки; для физических единиц её умножают на шаг.

Производные и первообразные

Функция задана на равномерной сетке с шагом 1; при другом шаге результат делят на шаг (для второй производной — на его квадрат) или умножают на шаг. Исходный вектор F лежит в r(b+trx)…, результат f — в r(b)…, длина le = N.

op Формула Края
fdf f[k] = (F[k+1] − F[k−1])/2 — первая производная f[1]=f[2], f[N]=f[N−1]
sdf f[k] = F[k+1] + F[k−1] − 2F[k] — вторая производная так же
ffd f[k+1] = f[k] + (F[k] + F[k+1])/2 — функция по производной (трапеции) f[1] задают заранее
fsd f[k+1] = F[k] + 2f[k] − f[k−1] вперёд и f[k−1] = F[k] + 2f[k] − f[k+1] назад — функция по второй производной две точки f[n], f[n+1] задают заранее

У fsd параметр n — номер (с единицы, внутри вектора) первой из двух известных точек. При n=1 расчёт идёт слева направо; при n>1 сначала вычисляются точки правее, потом левее. Это нужно, когда вторая производная у края определена плохо и движение от края портит весь результат.

Матрицы

mtr — транспонирование

#ma [op=mtr; b=; nx=; ny=;]

Матрица из ny строк длины nx заменяется транспонированной: nx строк длины ny. Удобно после чтения таблицы из файла по строкам: столбцы (отдельные функции) становятся непрерывными кусками.

mii — обращение порядка индексов

#ma [op=mii; b=; nx=; ny=; mo=;]
mo Что меняется
0 обратный порядок и элементов в строках, и самих строк (поворот на 180°)
1 обратный порядок элементов в каждой строке (отражение слева направо)
2 обратный порядок строк (отражение сверху вниз)

fno — минимум, максимум, среднее, нормировка

#ma [op=fno; b=; nx=; ny=; mo=;]

Для каждой из ny строк находит минимум, максимум и среднее и пишет их сразу за матрицей: с r(b+nx·ny) — ny минимумов, затем ny максимумов, затем ny средних. При mo=0 каждая строка вдобавок нормируется на отрезок [0, 1]: (v − min)/(max − min); при других mo матрица не меняется.

mss — суммы по строкам и столбцам

#ma [op=mss; b=; nx=; ny=; em=;]

Результаты пишутся подряд сразу за матрицей, с r(b+nx·ny):

Случай Что записывается
ny>1, em=0 nx сумм по столбцам (для каждого первого индекса — сумма по строкам), затем ny сумм по строкам, затем общая сумма
ny>1, em=1 только nx сумм по столбцам и общая сумма
ny>1, em=2 только ny сумм по строкам и общая сумма
ny=1 только сумма всего вектора

Для матрицы 1 2 3 / 4 5 6 (nx=3, ny=2) при em=0 за ней появится 5 7 9 6 15 21. Это численное интегрирование функции двух переменных по одной, по другой и по обеим.

mds — диагональное сечение

#ma [op=mds; b=; nx=; ny=; xpo=; ypo=; dir=; n=; sav=;]

Вектор длины n с r(sav) обнуляется, в его середину записывается элемент матрицы в столбце xpo и строке ypo (с единицы), а затем вектор заполняется элементами диагонали через эту точку, пока она не выйдет за матрицу: вперёд и назад от середины. dir=1 — диагональ вправо-вверх, dir=−1 — влево-вверх. Часть элементов может остаться нулями. Используется для интегрирования локальной функции вдоль диагонали.

mip — размножение периода

# C=p1; D=p2; !
#ma [op=mip; b=; nx=; ny=;]

В центре матрицы выделяется прямоугольник p1 × p2 (периоды в шагах сетки, могут быть дробными), а все элементы вне его пересчитываются из условия периодичности с линейной интерполяцией: сначала по вертикали, потом по горизонтали. Так заполняют большую матрицу копиями одного периода или восстанавливают периодичность, испорченную у краёв. Чтобы не было скачков, значения на границах периода должны совпадать. Одномерный случай: ny=1, D=1.

mmr — поворот квадратной матрицы

# A=угол; !
#ma [op=mmr; b=; le=;]

Матрица le × le поворачивается вокруг центра на угол A в радианах, как чёрно-белая картинка; значения берутся билинейной интерполяцией, точки, пришедшие из-за края, равны нулю. Результат пишется сразу за исходной матрицей, с r(b+le²).

tom — томографическая обратная проекция

#ma [op=tom; n=; le=; siz=; b=;]

Исходные данные с r(n): siz проекций по le значений, каждая проекция — непрерывный кусок. Проекция номер m соответствует углу π·m/siz. Результат — квадратная матрица le × le с r(b): для каждой её точки суммируются интерполированные значения всех проекций. Области не должны перекрываться. Во время расчёта показывается окно хода работы.

gis — гистограмма

#ma [op=gis; b=; le=; n=; sav=;]

Для каждого из le чисел r(b)… берётся целая часть снизу (прижатая к отрезку 0…n−1), и соответствующий элемент гистограммы увеличивается на 1. Гистограмма из n чисел пишется с r(sav); перед подсчётом она обнуляется.

Интерполяция

fis — кубический сплайн

#ma [op=fis; b=; nx=; ny=; siz=;]

Строки матрицы — функции, заданные на общей сетке с переменным шагом. Сетка из nx значений аргумента лежит прямо перед матрицей, с r(b−nx); матрица — ny строк длины nx с r(b). Каждая строка интерполируется кубическим сплайном на равномерную сетку из siz точек от первого до последнего значения аргумента. Новая матрица (ny строк длины siz) пишется сразу за старой, с r(b+nx·ny). nx или siz меньше 2 — ошибка 60.

ffi — линейная интерполяция строк

#ma [op=ffi; b=; nx=; ny=; c=; wid=; n=;]

Раскладка исходных данных та же, что у fis. Новая сетка — wid точек (хоть одна) от r(c) до r(c+1); результат, ny строк длины wid, пишется с r(n). Точка вне исходного интервала получает граничное значение.

# s(3)=1; !
#d 3 r(1) 0 1 3 !
#d 3 r(4) 0 10 30 !
#d 2 r(21) 0 3 !
#ma [op=ffi; b=4; nx=3; ny=1; c=21; wid=4; n=31;]
#pr \G r(31) r(32) r(33) r(34);\n\E

Функция 0, 10, 30 на сетке 0, 1, 3 переносится на сетку 0, 1, 2, 3: получится 0 10 20 30.

mmi — матрица в матрицу

#ma [op=mmi; n=; b=; nx=; ny=; sav=; wid=; hei=; file=; form=; em=;]

Исходная матрица nx × ny описывает прямоугольник [xi1, xi2] × [yi1, yi2], новая wid × hei — прямоугольник [xo1, xo2] × [yo1, yo2]. Восемь чисел xi1 xi2 yi1 yi2 xo1 xo2 yo1 yo2 лежат с r(n). Шаг сетки (x2 − x1)/(nx − 1), интерполяция линейная.

Параметр Смысл
file файл с исходной матрицей (числа float, 4 байта); here — матрица в r(b)…
form файл для результата (float); here — результат в r(sav)…
em точки вне исходного прямоугольника: при em=1 получают значение C, иначе — среднее исходной матрицы

Операция оптимизирована под одномерный случай: сначала интерполируются строки, потом столбцы. Поэтому при большом ny и одной выходной точке (wid=hei=1) она работает непропорционально долго — ограничьте ny двумя нужными строками.

Комплексные массивы

ccm, ccd — умножение и деление

#ma [op=ccm; b=; le=; trx=;]
#ma [op=ccd; b=; le=; trx=;]

Первый массив из le комплексных чисел — с r(b), второй — с r(b+trx). Результат заменяет первый массив. ccd делит по формуле c1·conj(c2)/(|c2|² + E²), поэтому переменная E должна быть задана малым числом.

mcc и dcc — старые варианты тех же операций: размер задаётся в nx, а второй массив лежит сразу за первым (r(b+2·nx)). Их оставили для старых программ.

cen, cne — модуль и фаза

#ma [op=cen; b=; n=; trx=;]
#ma [op=cne; b=; n=; trx=; nx=; ny=;]
op Откуда Куда
cen n модулей с r(b) и сразу за ними n фаз n комплексных чисел с r(b+trx)
cne n комплексных чисел с r(b) n модулей с r(b+trx) и сразу за ними n фаз

Области не должны перекрываться (|trx| > 2n); это не проверяется. cne «выпрямляет» фазу — убирает скачки на 2π, двигаясь от точки номер nx в обе стороны (выберите её там, где фаза меняется медленнее всего; при nx вне 1…n берётся n/2). Для двумерных массивов выпрямление отключают, задав ny=10101.

com — программа комплексной арифметики

#ma [op=com; em=0;] K A B C  K A B C ... !
#ma [op=com; em=1; b=;] Xabc Xabc ... !
#ma [op=com; em=2; b=;]

Операция выполняет последовательность действий над комплексными числами в r(): над первыми двумя операндами, с результатом в третьем.

Код K (em=0) Символ (em=1) Действие
1 + C = A + B
2 - C = A − B
3 * C = A · B
4 / C = A / B
5 E C = exp(A)
6 C C = cos(A)
7 S C = sin(A)
8 T C = tan(A)
9 P C = A^Re(B) — только действительная степень
10 L C = ln(A)
11 0 C = J0(A) — функция Бесселя
12 1 C = J1(A)

При em=0 каждая команда — четыре числа: код и индексы в r() действительных частей трёх чисел (мнимые лежат следом). Для функций второй операнд не нужен, на его месте можно писать 0.

При em=1 комплексные числа называются буквами a…z: a — это r(b), b — r(b+2), c — r(b+4) и так далее. Команда — символ действия и три буквы; писать их можно слитно (*abc) или через пробелы (* a b c).

Список команд кончается на #, @ или !; если дальше идёт текст, ! обязателен.

# s(3)=1; !
#d 4 r(1) 1 2 3 4 !
#ma [op=com; em=1; b=1;] *abc !
#pr (1+2i)(3+4i) = \G r(5) r(6);\n\E

Получится −5 + 10i. То же при em=0: #ma [op=com; em=0;] 3 1 3 5 !.

При em=2 операция умножает комплексные матрицы. Шесть целых чисел лежат с i(b): i1 i2 i3 n1 n2 n3 — начало первой матрицы, второй и результата в r(), число строк первой матрицы, число её столбцов (оно же число строк второй) и число столбцов второй. Области не должны пересекаться. При размерностях n 1 1 получается умножение вектора на число, при n 1 m — матрица из двух векторов.

Тонкость. Автор честно предупреждает: ошибки в такой записи искать трудно. Отлаживайте программу com на числах, результат которых знаете.

Фурье и свёртка

fft — быстрое преобразование Фурье

# D=множитель; !
#ma [op=fft; b=; nx=k; em=;]

Комплексный массив из N = 2^|k| чисел с r(b) заменяется своим Фурье-образом. |k| не больше 22 (ошибка 57). Знак k задаёт знак в показателе экспоненты: при k>0 вычисляется fq[n] = Σ exp(+2πi·nm/N)·fx[m], при k<0 — с минусом. Результат умножается на переменную D.

em Что вычисляется
0 интеграл Фурье: сумма с фазовыми множителями, так что функция и образ заданы на симметричных сетках d·(n + (1−N)/2); старый код через комплексные объекты
1 только сумма, как в numpy.fft: образ сдвинут на полпериода, знаки чередуются, но обратное преобразование точно восстанавливает функцию
2 то же, что 0, без комплексных объектов, немного быстрее
3 то же, что 1, без комплексных объектов, примерно вдвое быстрее

Для интеграла Фурье автор рекомендует задавать в D множитель d/2π, где d — шаг сетки.

# s(3)=1; !
#d 8 r(1) 1 0 2 0 3 0 4 0 !
# D=1; !
#ma [op=fft; b=1; nx=2; em=1;]
# D=0.25; !
#ma [op=fft; b=1; nx=-2; em=1;]
#pr \G r(1) r(3) r(5) r(7);\n\E

Прямое и обратное преобразования с множителем 1/N возвращают 1 2 3 4.

mcg — свёртка с гауссианой

#ma [op=mcg; n=; b=; nx=; ny=; file=; form=; sav=;]

Матрица nx × ny (обе размерности — степени двойки; ny=1 — одномерный случай) сворачивается с гауссианой методом двойного БПФ. Три числа с r(n): σx, σy (в шагах сетки) и ε.

ε Что делается с Фурье-образом каждой строки/столбца
0 умножается на G(q) = exp(−(σq)²/2) — свёртка (размытие)
> 0 умножается на 1/√(G² + ε²) — развёртка с регуляризацией

Если σx или σy равно нулю, по этому направлению ничего не делается. Источник: file — файл чисел float (4 байта) или here — r(b)…; результат: form — файл float или here — r(sav)…. Перед преобразованием из каждой строки вычитается среднее её крайних значений, а потом прибавляется обратно — это уменьшает краевые эффекты.

vsm — специальные вычисления

#ma [op=vsm; mo=; b=; le=; nx=; ny=; top=; n=;]

Набор независимых процедур для больших массивов, выбираемых параметром mo.

mo Что делает Данные Результат
1 убирает шум около среднего 1: значения, отличающиеся от 1 меньше чем на E = top·10⁻⁹, становятся ровно 1, к остальным прибавляется константа, чтобы среднее снова было 1 вектор b, le на месте
2 убирает «плохие» пиксели и шум детектора (см. ниже) матрица b, nx, ny; le, top на месте
3 три наибольших значения вектор b, le r(1)…r(6): пары «смещение от начала, значение», третий по величине первым
4 n наибольших значений вектор b, le; n r(1)…r(2n): пары «смещение, значение», наибольшее первым
5 сглаживание по трём точкам: x → x/2 + (левый + правый)/4 в каждой строке; линейная функция не меняется матрица b, nx, ny на месте; крайние точки строки копируют соседние
6 пять сечений квадратной матрицы: горизонталь и вертикаль через середину, две диагонали и окружность диаметром N/2 матрица N × N с r(b), N = le 5 строк по N чисел с r(n)
7 x → arctg(x) вектор b, le на месте

Режим 2 обрабатывает строки матрицы по очереди. При top>0 сравниваются соседние числа: если разность больше top, аномальное число заменяется полусуммой соседей. При top<0 в окне из le точек (не меньше трёх) ищется максимум, и если он превышает среднее остальных больше чем на |top|, заменяется средним. При top=0 все числа заменяются скользящими средними по le точкам, то есть шум сглаживается. Крайние числа строк остаются прежними.

Тонкости. Режимы 3 и 4 всегда пишут результат в начало r(), а смещения в них отсчитываются с нуля. В справочнике автора для mo=6 перепутаны роли параметров: на деле матрица берётся с r(b), а сечения пишутся с r(n).

Изображения детекторов

Обе операции читают 16-битовое изображение из файла: file — имя, le — размер заголовка в байтах, twi, the — ширина и высота в пикселях, ord — порядок байтов (0 — старший первым, иначе младший первым).

smh — поиск фокуса

#ma [op=smh; file=; le=; twi=; the=; ord=; b=; bot=; em=; top=;]

Из каждого пикселя вычитается фон bot (отрицательное становится нулём). Максимум ищется по сумме квадрата 3×3, без полосы в 5 пикселей у краёв.

Результат Значение
r(b), r(b+1) координаты максимума, номера пикселей с нуля
r(b+2) значение в максимуме
r(b+3), r(b+4) полная ширина на половине высоты по x и по y
r(b+5), r(b+6) левая и нижняя границы этих полуширин
с r(b+7) при em=1 или 3 — профиль по x через максимум: сначала число точек, затем значения; при em=2 или 3 — следом профиль по y

При top>0 профили усредняются по полосе шириной 2·top+1 пикселей. Автор описывает только первые пять чисел; остальное видно из кода.

rfh — фрагмент изображения

#ma [op=rfh; file=; le=; twi=; the=; ord=; b=; wid=; hei=; xsh=; ysh=;]

Вырезает прямоугольник wid × hei, левый нижний угол которого — пиксель (xsh, ysh) (считая с единицы; изображение трактуется как записанное снизу вверх), и пишет его в r(b)… по строкам. Фрагмент шириной или высотой 1 — кусок строки или столбца.

box — разметка осей

#ma [op=box; wid=; hei=; sty=; bot=; top=; uni=; b=;]

Вычисляет всё, что нужно, чтобы нарисовать прямоугольник осей научного графика средствами #eg — так же, как это делают #w [op=pf;] и #g [op=axes;], но с возможностью дальше рисовать самому.

Входные данные: размер области осей wid, hei; вид осей и длины рисок sty, bot, top (как в #w); с r(b) — четыре числа xmi xma fmi fma при uni=0 (автоматическая разметка) или одиннадцать чисел ручной разметки при uni≠0.

Результат Значение
i(1) N — число точек ломаных линий осей и рисок
i(2) M — число подписей-чисел
r(1)…r(2N) координаты точек x1 y1 x2 y2 …
i(3)…i(N+1) видимость отрезков: 1 — соединить точку с следующей, 0 — нет
с r(2N+1) по четыре числа на подпись: координаты, само число, ось (0 — левая, 1 — нижняя, 2 — правая, 3 — верхняя)
с r(2N+4M+1) xbeg cx ybeg cy — начала осей и масштабы для пересчёта функции в координаты рисунка

Тонкость. Результат всегда пишется в начало r() и i(), затирая то, что там было. Входные данные берите подальше. Пример использования — суперкоманда ##pfFCH автора.

Система шаров

Три операции без описания в справочнике автора; их смысл восстановлен по коду. Они моделируют движение N одинаковых шаров на плоскости — основу простых анимаций и игр. Каждый шар — четыре числа x y vx vy, шары лежат подряд с r(1); число шаров — в переменной N.

op Что делает
bsm шаг движения: x += vx, y += vy для каждого шара
bsi столкновения: шары, центры которых ближе диаметра D, раздвигаются вдоль линии центров на расстояние D+1 и обмениваются составляющими скоростей вдоль этой линии (упругий удар равных масс)
bsr отражение от стенки-ломаной: точки (x, y) лежат с r(K), отрезков N1; шар радиуса D/2, оказавшийся ближе к отрезку, выталкивается на расстояние D/2, а его скорость отражается от отрезка

Стенки односторонние: шар удерживается с той стороны отрезка, куда смотрит нормаль (dy, −dx) к направлению (dx, dy) от первой точки ко второй. Например, отрезок от (20, 0) до (0, 0) держит шары в области y > 0, а отрезок от (0, 0) до (20, 0) — в области y < 0; шар, оказавшийся не с той стороны ближе D, будет перенесён сквозь стенку. Для каждого шара учитывается только первый задевший его отрезок.

Два шара летят навстречу друг другу и отскакивают.
# s(3)=1; N=2; D=10; !
#d 8 r(1) 0 0 1 0 15 0 -1 0 !
#rep 5 #ma [op=bsm;] #ma [op=bsi;] #end
#pr x1=\G r(1); vx1=\G r(3); x2=\G r(5); vx2=\G r(7);\n\E

После пяти шагов первый шар в точке 1 летит влево (vx1=−1), второй в точке 16 — вправо.

#z — zip-архивы

#z [op=xxx; file=архив; n=; mo=;] имя1\E имя2\E ...

Команда показывает содержимое zip-архива, упаковывает в архив папки или отдельные файлы и распаковывает их. Значимы три буквы op; неизвестная операция — ошибка 51.

op Что делает Аргументы
cat каталог архива в t() нет
sfo упаковать папки n имён папок
gfo распаковать папки n имён папок
sfi упаковать файлы n имён файлов
gfi распаковать файлы n имён файлов
Параметр Смысл
file имя архива от папки интерпретатора (рабочая папка не используется), с расширением; расширение может быть любым
n число аргументов-имён
mo режим распаковки для gfo, gfi

Имена папок и файлов в аргументах тоже отсчитываются от папки интерпретатора; внутри архива они хранятся в виде папка/файл. Для cat, gfo, gfi архив должен существовать (ошибка 69).

mo Режим распаковки
0 распаковать, заменив существующие файлы; недостающую папку создать
1 распаковать временно: файлы и созданные папки удаляются при закрытии интерпретатора
2 распаковать, только если папки (для gfi — файла) ещё нет; удобно для первого запуска дистрибутива

cat — каталог

#z [op=cat; file=архив;]

Записывает в t() с позиции s(3) имена всех элементов архива через |; s(4), s(5) — начало и длина. Файлы в папках выглядят как папка/файл, сами папки — как папка/.

Тонкость. Для архива без единого элемента интерпретатор падает с исключением Java.

sfo — упаковать папки

#z [op=sfo; file=архив; n=;] папка1\E папка2\E ...

Создаёт архив из всех файлов перечисленных папок. Вложенные папки не обрабатываются: по коду интерпретатора попытка прочитать подпапку как файл обрывает упаковку. Папки с подпапками упаковывайте через sfi, перечислив файлы.

gfo — распаковать папки

#z [op=gfo; file=архив; n=; mo=;] папка1\E папка2\E ...

Извлекает файлы, лежащие непосредственно в каждой из названных папок архива. Вложенную папку one/two можно извлечь, только когда внешняя one уже существует: сначала извлеките one, затем отдельной командой one/two. Имя null означает файлы из корня архива.

sfi — упаковать файлы

#z [op=sfi; file=архив; n=;] имя1\E имя2\E ...

Создаёт архив из перечисленных файлов. Имя вида папка/файл создаёт папку внутри архива. Отсутствующие файлы пропускаются. Удобно и для сжатия одного большого файла.

gfi — распаковать файлы

#z [op=gfi; file=архив; n=; mo=;] папка/файл1\E ...

Извлекает перечисленные элементы архива на те же относительные пути. Если нет последней папки пути, она создаётся; внешние папки должны существовать.

#z [op=sfi; file=pro/backup.zip; n=2;] pro/a.acl\E pro/b.acl\E
# s(3)=1; !
#z [op=cat; file=pro/backup.zip;]
#m [op=txt;] \Tp\n\E

#sys — секундомер и внешние программы

#sys [op=xx; file=;] [командная строка\E]

Команда для системно-зависимых действий. Значимы две буквы op; неизвестная операция — ошибка 49.

op Что делает Результат
st запомнить время («включить секундомер») —
gt время, прошедшее после st $ в секундах
rp запустить внешнюю программу или командный файл —

st — старт секундомера

#sys [op=st;]

Запоминает текущее время системных часов.

gt — показание секундомера

#sys [op=gt;]

Записывает в переменную $ время в секундах, прошедшее после последнего st, с точностью до миллисекунды. Можно вызывать несколько раз подряд.

# s(3)=1; !
#sys [op=st;]
#rep 100000 # a=sin(1); #end
#sys [op=gt;]
#pr цикл занял \N 8 3 $; с\n\E

Так оценивают время большого расчёта по одному прогону.

rp — запуск программы

#sys [op=rp; file=имя;]
#sys [op=rp; file=arg;] командная строка\E
file Что запускается
имя исполняемый файл или командный файл .bat от папки интерпретатора; файл должен существовать (ошибка 50)
arg командная строка из аргумента — любая программа с аргументами; наличие файла не проверяется

Программа запускается в отдельном процессе, и VKACL-программа сразу идёт дальше, не дожидаясь её конца. Если дальше нужны результаты внешней программы, программу останавливают: окном #m [op=win;], которое ждёт нажатия, или паузой #rob [mo=1;].

# s(3)=1; !
#pr C:\ncd "Program Files"\\Tetcolor\nTetColor.exe\n\E
# n9=s(3)-1; !
#io [op=wt; fir=t(1); n=n9; file=runpro.bat;]
#sys [op=rp; file=runpro.bat;]

Командный файл, собранный прямо из программы, обходит требование держать запускаемую программу в папке интерпретатора. В Linux файлу нужно дать атрибут исполняемого.

#m — сообщения и окна с кнопками

#m [op=xxx;] текст\E [ещё аргументы\E]

Команда показывает текст пользователю: в окне терминала или в диалоговом окне с кнопками. Первый аргумент — форматированный текст — читается всегда, при любой операции. Операцию задают три буквы op, причём они должны точно совпасть с одной из перечисленных (op=text — это ошибка 37, нужно op=txt).

op Что показывает Ждёт пользователя Результат
txt текст в окне терминала нет —
rtt стирает символы в конце терминала нет —
win окно с кнопкой OK да —
yno окно с кнопками Yes, No да &
oce окно с кнопками OK, Cancel, Edit да &
uni окно со своим заголовком и кнопками да &
gen окно с кнопками в несколько рядов и настраиваемой раскладкой да &

В окнах yno, oce и uni, закрытых крестиком, & становится равным 0.

txt — терминал

#m [op=txt;] текст\E

Дописывает текст в окно «Терминал», сопровождающее программу. Окно появляется при первой записи и закрывается после конца программы; чтобы оно осталось на экране, перед концом программы выполните #rob [mo=2;]. Обычная связка — собрать текст в t() и показать его кодом \Tp или \T:

# s(3)=1; x=3.14159; !
#pr x = \G x;\n\E
#m [op=txt;] \Tp\E

rtt — стереть конец терминала

#m [op=rtt; n=;] \E

Удаляет n последних символов терминала. Аргумент не используется, но должен присутствовать хотя бы как пустой \E. Так делают обратный отсчёт: печатают строку символов и стирают по одному по мере работы цикла.

win — сообщение

#m [op=win;] текст\E

Показывает текст в окне с кнопкой OK и ждёт, пока пользователь её нажмёт. Годится и как простая пауза «продолжить».

yno — да или нет

#m [op=yno;] вопрос\E

Кнопки Yes и No; & — 1 или 2.

#m [op=yno;] Сохранить результат?\E
#case 1
  #io [op=wd; fir=r(1); n=100; mo=3; file=result.dat;]
#end |

oce — OK, Cancel, Edit

#m [op=oce;] текст\E

Кнопки OK, Cancel, Edit; & — 1, 2 или 3.

uni — свои кнопки

#m [op=uni;] текст\E заголовок|кнопка1|кнопка2|...\E

Второй аргумент задаёт через | заголовок окна и надписи кнопок; кнопок столько, сколько надписей. Все кнопки в один ряд; & — номер нажатой, с единицы.

#m [op=uni;] Что построить?\E Выбор|График|Карта|Выход\E

gen — окно общего вида

#m [op=gen; b=; n=; nx=; ny=; siz=;] заголовок\E текст\E кнопка1|кнопка2|...\E

Кнопки размещаются в n рядов. Строки текста разделяются \n; пустую строку задают как \u32;\n, потому что совсем пустые строки не допускаются. Раскладку задают целые числа в i(b), i(b+1), …:

Числа по порядку Сколько Смысл
первые по одному на строку текста ширина пустого места после строки (строки центрируются; удлиняя короткие строки справа, их выравнивают влево); можно нули
следующие n сколько кнопок в каждом ряду; в сумме — все кнопки
последние n ширина полей слева и справа в каждом ряду кнопок
Параметр Смысл
nx, ny левый верхний угол окна от угла экрана; если хоть один отрицателен — окно по центру
siz поля по краям окна, куда не заходят ни текст, ни кнопки

& — номер нажатой кнопки. Упрощённый вариант с одним рядом кнопок — суперкоманда ##33.

#sel — таблица кнопок

#sel [nx=; ny=; mo=; wid=; hei=; tfo=; tki=; tsi=; col=; em=; xsh=; ysh=;] заголовок\E кнопка1|кнопка2|...\E

Команда показывает панель с прямоугольной таблицей кнопок и ждёт, пока пользователь нажмёт одну из них. Номер нажатой кнопки попадает в &, и обычно за командой следует серия #case … #end |. Одна из самых употребительных команд диалога.

Параметр Смысл
nx кнопок в ряду
ny рядов
mo вид кнопок: 0 — текст на цветном прямоугольнике; 1 — картинки jpg; 2 — картинки png; 3 — картинки png внутри интерпретатора (для проигрывателя)
wid, hei размер текстовой кнопки в пикселях
tsi размер шрифта (не меньше 8)
tfo шрифт 1…5: Monospaced, Serif, SansSerif, Dialog, DialogInput
tki начертание: 0 обычное, 1 жирное, 2 наклонное, 3 жирное наклонное
col для mo=0: номер цвета текста в таблице цветов; следующий номер — цвет фона
em 0 — панель по центру экрана; 1 — левый верхний угол в (xsh, ysh) от угла экрана; 2 — от угла главного окна программы

Кнопки заполняют таблицу по рядам: сначала первый ряд, потом второй. Для mo=1 и mo=2 надписи — это имена файлов картинок без расширения в рабочей папке (можно папка/файл); для mo=3 — имена внутри папки com.vk jar-файла.

Результат Значение
& номер нажатой кнопки с единицы; −1, если панель закрыта крестиком
#sel [nx=3; ny=1; mo=0; wid=120; hei=40; tsi=16; tfo=3; tki=1; col=255; em=0;] Что делать?\E График|Таблица|Выход\E
#case 1 #m [op=txt;] Выбран график\n\E #end |
#case 2 #m [op=txt;] Выбрана таблица\n\E #end |

Тонкости.

#inp — окна ввода

#inp [n=; le=; mo=; em=; xsh=; ysh=;] заголовок\E подписи-и-тексты...

Команда открывает панель с n однострочными окнами ввода, у каждого своя подпись и начальный текст, и кнопками OK и Cancel. После OK тексты всех окон записываются в t().

Аргументы

Первый аргумент — заголовок панели. Дальше — в зависимости от чётности mo:

mo Аргументы после заголовка
чётное (0, 2, …) n пар: подпись\E текст\E подпись\E текст\E …
нечётное (1, 3, …) два аргумента: все подписи через | и все начальные тексты через |; если частей меньше n — ошибка 61

При n=0 панель вводит пароль: одно окно без подписи, вместо символов показываются звёздочки, аргумент только один — заголовок.

Параметры

Параметр Смысл
n число окон ввода; 0 — ввод пароля
le ширина пустого места по бокам от кнопок; этим задаётся ширина всей панели (обычно около 50)
mo раскладка, см. ниже
em единицы: 0 — панель по центру, 1 — угол в (xsh, ysh) от угла экрана, 2 — от угла главного окна; десятки: 1 — добавить ряд кнопок Help, Notes, Save Var, Choose Var
mo Раскладка
0, 1 подпись над окном, все в один столбец; кнопки по центру
2, 3 подпись и окно в одной строке, один столбец; кнопки слева
4, 5 то же, кнопки справа
6, 7 два столбца (n чётное)
8, 9 три столбца (n делится на 3)
больше 9 по 4, 5 … пары в строке, без выравнивания столбцов

Результат

Где Значение
& 1 — OK, 2 — Cancel, 3…6 — кнопки Help, Notes, Save Var, Choose Var
t() с s(3) тексты всех окон, после каждого символ с кодом 10 (не пишется при Cancel)
s(4), s(5) начало записи и её длина вместе с символами 10

Для одного окна или пароля сам текст занимает s(5)−1 символов. Кнопки дополнительного ряда только сообщают о намерении пользователя через & — справку, заметки и сохранение вариантов программа делает сама.

# s(3)=1; !
#inp [n=2; le=50; mo=3; em=0;] Размер картинки\E Ширина|Высота\E 640|480\E
#case 1
  #rea [fir=r(1); n=2; b=s(4); le=s(5);]
#end |

Числа из окон ввода превращаются в значения командой #rea: символ 10 между ними служит разделителем.

Тонкости. Имя команды пишется минимум тремя буквами: #in попадает в #w. После em≠0 верните em=0. Автор сам теперь предпочитает вводить данные через текстовый редактор (#f [op=edit;]) — такой ввод проще сохранять и править.

#ch — выбор кликом по картинке

#ch [n=; xsh=; ysh=;]

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

Параметр Смысл
n номер картинки в памяти, 1…100 (нет картинки — ошибка 63)
xsh, ysh левый верхний угол картинки от левого верхнего угла экрана
Результат Значение
s(102), s(103) координаты курсора в момент клика, от левого нижнего угла картинки
s(1) модификатор клика: 16 — простой клик, 17 — с Shift, 18 — с Ctrl и т. д.
s(2) код нажатой клавиши

Таблицы модификаторов и кодов клавиш — в описании #w [op=im;].

Команда даёт выбор общего вида: на картинке может быть инструкция «нажмите клавишу», карта, по которой кликают, или таблица кнопок любой формы (например, таблица Менделеева). Анализ координат программа делает сама; готовую таблицу прямоугольных кнопок проще получить командой #sel.

#g [op=open; twi=300; the=100; col=256;]
#g [op=text; nx=150; ny=45; col=255; tfo=3; tki=1; tsi=18; sty=2;] Нажмите Y или N\E
#g [op=close; sav=9;]
#ch [n=9; xsh=200; ysh=200;]
# kc=s(2); !

Клавиши букв дают коды заглавных латинских букв: Y — 89, N — 78.

#fr — картинка поверх экрана

#fr [op=o; n=; mo=; xsh=; ysh=;] [заголовок\E]
#fr [op=c; mo=;] [заголовок\E]

Команда выставляет на экран картинку, заранее сохранённую в памяти (номер 1…100; сохраняют её #w, #g, #eg), не останавливая программу, и убирает её программно, без участия пользователя. Так показывают комментарии рядом с окнами диалога, строку состояния, сообщения о ходе расчёта. Операцию задаёт одна буква: o — открыть, c — закрыть; другая — ошибка 78.

Параметр Смысл
n номер картинки в памяти (нет картинки — ошибка 63)
mo 0 — внутреннее окно с рамкой и заголовком внутри главного окна интерпретатора; 1…10 — окно без рамки номер mo
xsh, ysh левый верхний угол от левого верхнего угла экрана (для mo=0 — главного окна)

o — показать

При mo=0 аргумент — заголовок внутреннего окна; такое окно живёт внутри главного окна интерпретатора и вместе с ним сворачивается. В проигрывателе (версии без главного окна) этот вариант не работает. При mo от 1 до 10 картинка показывается анонимно, без рамки и заголовка; аргумент не нужен. Одновременно можно держать до 10 таких картинок, в том числе одну поверх другой.

c — убрать

При mo=0 аргумент — заголовок: закрываются внутренние окна с этим заголовком. При mo>0 убирается анонимная картинка номер mo.

Нарисовать строку состояния и показать её внизу экрана.
# s(3)=1; y=s(107)-60; !
#g [op=open; twi=400; the=30; col=256;]
#g [op=text; nx=10; ny=8; col=255; tfo=3; tki=0; tsi=16; sty=1;] Идёт расчёт...\E
#g [op=close; sav=7;]
#fr [op=o; n=7; mo=1; xsh=20; ysh=y;]
#rep 100000 # a=sin(1); #end
#fr [op=c; mo=1;]

Тонкости. Размер экрана — в s(106) и s(107). Анонимная картинка не должна перекрывать окна анимации или диалога: кликнув по ней, пользователь уводит фокус, и программа может потерять управление. Готовая подсказка в строке состояния — суперкоманда ##17.

#pf — индикатор хода работы

#pf [op=o; le=;]
#pf [op=m; siz=;]
#pf [op=c;]

Команда открывает окно «Progress» с полосой, которая постепенно закрашивается, и процентом выполнения посередине. Долгий расчёт без такого окна выглядит как зависание. Операцию задаёт одна буква; другая — ошибка 84.

op Что делает Параметр
o открыть окно (всегда в центре экрана) le — значение, соответствующее 100 %
m закрасить полосу до значения siz и показать siz/le·100 % siz — от 0 до le; выходящее за пределы прижимается к границе
c закрыть окно —
# k=0; !
#pf [op=o; le=999;]
#rep 1000
  # r(k+1)=exp(-0.001*k); k=k+1; !
  #pf [op=m; siz=k;]
#end
#pf [op=c;]

#pf [op=o;] ставят перед циклом, #pf [op=m;] — внутри, #pf [op=c;] — после.

#rob — пауза, снимок экрана, цвет пикселя

#rob [mo=; le=; n=; xsh=; ysh=; wid=; hei=;]

Когда-то команда имитировала действия пользователя (нажатия клавиш, движение мыши). Эти функции автор убрал, оставив имя ради совместимости и несколько полезных действий. Операцию выбирает не op, а mo.

mo Что делает Параметры Результат
1 пауза le — длительность в миллисекундах —
2 не закрывать окно терминала после конца программы — —
3 снимок части экрана в память n — номер картинки, xsh, ysh — левый верхний угол, wid, hei — размер картинка n
4 цвет пикселя экрана xsh, ysh — координаты s(1), s(2), s(3) — красный, зелёный, синий

Другие значения mo ничего не делают.

#m [op=txt;] Подождите две секунды...\n\E
#rob [mo=1; le=2000;]
#rob [mo=2;]

Пауза нужна при анимации из заранее сохранённых кадров, после запуска внешней программы через #sys и в слайд-шоу. Снимок экрана (mo=3) затем можно показать, дорисовать или сохранить в файл командами #w, #g, #f [op=topng;].

Тонкость. mo=4 записывает синюю компоненту в s(3) — позицию печати в t(). Сразу сохраните цвет и восстановите s(3):

#rob [mo=4; xsh=100; ysh=100;]
# cr=s(1); cg=s(2); cb=s(3); s(3)=1; !

#col — таблица цветов

#col [b=; le=; fir=;]

Графические команды задают цвет не тремя компонентами, а номером в таблице из 256 цветов. Команда #col переопределяет le цветов подряд, начиная с номера b; компоненты — 3·le чисел (красный, зелёный, синий) подряд, начиная с элемента fir.

Параметр Смысл
b номер первого переопределяемого цвета, от 1 (меньше — ошибка 17)
le сколько цветов
fir первый элемент с компонентами: i(1), r(1) или скалярная переменная

Компоненты отбрасывают дробную часть и прижимаются к диапазону 0…255. Таблицу можно менять в любой момент.

#d 6 i(1) 255 0 0 122 122 122 !
#col [b=2; le=2; fir=i(1);]

Теперь цвет 2 — красный, цвет 3 — серый.

Таблица при запуске

Номер RGB Цвет
1…243 0 0 0 чёрный
244 128 0 0 тёмно-красный
245 85 85 85 тёмно-серый
246 255 255 255 белый
247 0 0 0 чёрный
248 255 0 0 красный
249 0 0 255 синий
250 0 195 0 зелёный
251 122 122 122 серый
252 152 128 0 коричневый
253 152 0 152 фиолетовый
254 0 255 255 голубой
255 0 0 128 тёмно-синий
256 220 200 180 светло-коричневый

Где используется

Параметр col в команде Что красит
#g, #eg фон при открытии графика, линии, фигуры, текст
#w [op=pf;] первую кривую; следующие кривые — следующими номерами
#sel текст кнопок (col) и их фон (col+1)
#f [op=tobm;] веса каналов при переводе картинки в серый
#pd, #ps текст и линии в PDF и EPS

Цветные карты числовых матриц красятся не этой таблицей, а палитрой pal (см. #w [op=im;]).

Тонкость. В справочнике автора цвет 251 назван как 128 128 128; в интерпретаторе он 122 122 122.

#w — картинки и научные графики

#w [op=xx; file=; form=; sav=; c=; ...] [аргументы]

Команда показывает готовые картинки (gif, jpg, png), превращает числовые матрицы в серые и цветные карты и строит научные графики: кривые в осях, квази-трёхмерные графики, карты в осях, составные картинки. Результат показывается в окне, сохраняется в память под номером или записывается в файл jpg. Операцию задают две буквы op; неизвестная — ошибка 29.

op Что строит
im картинку из файла, памяти или интернета; карту числовой матрицы
pf график функций в осях с подписями
mp квази-трёхмерный график: строки матрицы — кривые, сдвинутые друг за другом
mm картинку (обычно карту) в прямоугольнике осей с подписями
ff составную картинку из нескольких картинок памяти

Более гибкое рисование — в #g и #eg, векторные графики — в #ps.

Общие правила

Файл. Параметр file проверяется до выполнения любой операции: файл должен существовать в рабочей папке, либо имя должно быть here, либо начинаться с & (файл внутри jar-файла). Иначе — ошибка 13. Поэтому для картинок из памяти, из интернета и для ff пишите file=here. Если file=arg или form=arg, имена берутся из аргументов (сначала для file, потом для form) до остальных аргументов операции.

Куда девается картинка — одинаково для #w, #g, #eg:

sav Что происходит
1…100 картинка сохраняется в память под этим номером, на экран не выводится
0 показывается в окне
−1 показывается и записывается в файл form.jpg в рабочей папке
−2 только записывается в файл form.jpg

form — имя без расширения. Заголовок окна у im, pf, mp, mm — имя файла из file, у ff — аргумент.

Параметр окна Смысл
c 0 — показать и сразу идти дальше; иначе ждать, пока пользователь кликнет по картинке или нажмёт клавишу
em 0 — окно по центру экрана; 1 — левый верхний угол окна в точке (xpo, ypo) от угла экрана

Что возвращает окно при c≠0:

Ячейка Значение
s(1) модификатор клика
s(2) код клавиши, если окно закрыто клавиатурой
s(102)…s(105) x1 y1 x2 y2 — точки нажатия и отпускания кнопки мыши, если по картинке протянули мышь (так выделяют область)
Модификатор Клик
16 простой
17 с Shift
18 с Ctrl
19 с Shift и Ctrl
24 с Alt
25 с Alt и Shift
26 с Alt и Ctrl
27 с Alt, Ctrl и Shift
Клавиша Код
цифры 0…9 48…57
буквы A…Z (любой регистр) 65…90
, - . / 44, 45, 46, 47
; = [ \ ] 59, 61, 91, 92, 93
', ` 222, 192
Backspace, Enter, CapsLock, Esc, пробел 8, 10, 20, 27, 32
PgUp, PgDn, End, Home 33, 34, 35, 36
стрелки влево, вверх, вправо, вниз 37, 38, 39, 40
F1…F12 112…123
Insert, Delete 155, 127

Tab, Shift, Ctrl и Alt сами по себе окно не закрывают. Коды клавиш удобны для слайд-шоу: следующая картинка — по пробелу, выход — по Esc.

im — картинка или карта

#w [op=im; file=; mo=; n=; twi=; the=; wid=; hei=; xsh=; ysh=; sca=; sav=; form=; c=; em=;]

Источник картинки выбирает mo:

mo Источник Что делается
0 файл gif, jpg, png показывается как есть; s(12), s(13) — ширина и высота
1 такой же файл масштабирование к twi × the и/или вырезание части
2 картинка памяти n масштабирование
3 картинка памяти n вырезание части
−1 адрес в интернете из аргумента показывается как есть
8, 16, 24, 32, 100, 125 числовые данные карта, см. ниже

Масштабирование (mo 1, 2) выполняется, если хотя бы одно из twi, the положительно; отрицательное вычисляется так, чтобы сохранить пропорции. Способ задаёт sca: 1 — по умолчанию, 2 — быстрый, 4 — сглаживающий, 8 — повтор пикселей, 16 — усреднение по площади. После операции s(12), s(13) — новый размер.

Вырезание (mo 1, 3) выполняется, если wid, hei положительны, а xsh, ysh неотрицательны: показывается часть wid × hei, левый нижний угол которой отстоит на (xsh, ysh) от левого нижнего угла картинки. Часть, вылезающая за край, обрезается.

Тонкость. sca — это ещё и масштаб в процентах у #g, по умолчанию он равен 100, а у #w допустимы только 1, 2, 4, 8, 16. Масштабирование с sca=100 — ошибка 71: задавайте sca явно.

#w [op=im; file=photo.jpg; mo=1; twi=400; the=-1; sca=4; sav=0; c=1; em=0;]
# kc=s(2); !

Карты числовых данных

mo Данные в файле Значение пикселя
8 байт на точку сам байт — уровень серого 0…255
16 два байта на точку, без знака; порядок задаёт ord (0 — старший первым) масштабирование в серый
24 три байта на точку: красный, зелёный, синий цвет как есть
32 число float (4 байта) на точку; при file=here — числа из r(le)… масштабирование в серый
100 данные не читаются, а вычисляются: линейная шкала от r(b) до r(b+1) (нужно file=here) масштабирование в серый
125 один бит на точку, 8 точек в байте (сканы страниц) чёрный или белый
Параметр Смысл
le размер заголовка файла в байтах (при mo=32, file=here — первый индекс r())
twi полная ширина данных в точках
the полная высота
wid, hei размер показываемой части; у mo=100 один из них должен быть 1 (ошибка 46)
xsh, ysh сдвиг показываемой части от начала данных
dir 1 — строки записаны сверху вниз, иначе снизу вверх (как в расчётах)
nx, ny сколько пикселей экрана по горизонтали и вертикали отводить на точку данных
sty, bot, top, b масштабирование в серый, см. ниже
sca только для mo=125: масштаб в процентах (обычно уменьшение)
pal палитра, см. ниже

Масштабирование в серый (mo 16, 32, 100). Пусть Fmin, Fmax — наименьшее и наибольшее значения. Для mo=100 они всегда берутся из r(b), r(b+1); для 16 и 32 — оттуда же, если |sty| > 10, а иначе вычисляются по данным и записываются в r(b), r(b+1). Показывается окно значений

Fmi = Fmin + (Fmax − Fmin)·bot/100000
Fma = Fmin + (Fmax − Fmin)·top/100000

а вид шкалы задаёт последняя цифра |sty|:

Цифра Шкала
1 линейная: 255·(f − Fmi)/(Fma − Fmi)
2 логарифмическая: 255·ln(f/Fmi)/ln(Fma/Fmi); нужно Fmi > 0, иначе ошибка 30
3 корень: 255·√((f − Fmi)/(Fma − Fmi))

Отрицательный sty обращает контраст: минимум белый, максимум чёрный.

Палитра pal (параметр 44) превращает уровень 0…255 в цвет:

pal Цвета от минимума к максимуму
0 и больше 3 от чёрного к белому
1 синий → красный → белый
2 чёрный → синий → зелёный → красный → белый
3 из файла colmap.txt в папке интерпретатора: 768 целых чисел текстом — 256 красных, 256 зелёных, 256 синих; файл читается в момент рисования, поэтому палитру можно менять по ходу программы

Пример автора — показать кусок 16-битного изображения детектора в формате edf (параметры с c по sav — это s(8)…s(23), их удобно задать одной командой #d):

#d 16 s(8) 1 1 3072 16 2048 2048 128 128 1408 968 -2 1 999 4 4 0 !
#w [op=im; file=any.edf;]

Здесь заголовок 3072 байта, данные 2048×2048, показывается часть 128×128 со сдвигом (1408, 968), шкала логарифмическая обращённая, каждая точка — квадрат 4×4 пикселя.

Тонкости.

pf — график функций

#w [op=pf; file=; b=; le=; mo=; nx=; ny=; col=; msi=; mki=; оси...; n=; sav=; form=; c=;] [Xmin Xmax] подписи...

Данные. Числа float из файла (после le байтов заголовка) или, при file=here, из r(b)…. Данные идут столбцами по nx точек, столбцов ny:

mo Смысл столбцов Кривых
0 все столбцы — функции; аргумент равномерный от Xmin до Xmax, это первые два аргумента команды ny
1 первый столбец — аргумент, остальные — функции ny−1
2 пары «аргумент, функция» ny/2

Кривые. Первая рисуется цветом col, следующие — следующими номерами таблицы цветов. При msi=0 все кривые — линии толщиной 1. При msi>0 это размер маркеров в пикселях, а mki — пятизначное число, цифры которого (слева направо) задают вид первых пяти кривых, дальше по кругу:

Цифра mki Вид
0 линия
1 пустой квадрат
2 залитый квадрат
3 пустой круг
4 залитый круг

Например, mki=1234 (то есть 01234) — линия, пустой квадрат, залитый квадрат, пустой круг, залитый круг.

Подписи. Их число — n; каждая задаётся аргументами x y rts текст\E: левый нижний угол текста от левого нижнего угла картинки и добавка rts к размеру шрифта tsi.

Фон графика белый, оси чёрные. Ошибки: 44 — nx·ny ≤ 0, 32 — файл меньше, чем нужно, 68 — нулевой размер картинки, 43 — неверная ручная разметка осей.

Две гауссианы на одном графике, данные в r().
# x=-2; k=1; !
#rep 101
  # r(k)=x; r(k+101)=100*exp(0-x*x); r(k+202)=80*exp(0-(x-0.5)*(x-0.5)); x=x+0.04; k=k+1; !
#end
#d 3 i(1) 255 0 0 !
#col [b=2; le=1; fir=i(1);]
#w [op=pf; file=here; b=1; le=0; mo=1; nx=101; ny=3; col=2; msi=0; twi=600; the=400; wid=480; hei=300; xsh=80; ysh=60; sty=1; bot=4; top=8; tsi=14; tfo=3; tki=0; uni=0; n=2; sav=0; c=1; em=0;] 300 15 2 x\E 20 375 2 Две гауссианы\E

Оси и подписи чисел

Этот способ описания осей общий для #w [op=pf;], #w [op=mm;], #g [op=axes;], #ps [op=pf;] и #ma [op=box;].

Параметр Смысл
twi, the полный размер картинки в пикселях
wid, hei размер прямоугольника осей
xsh, ysh левый нижний угол прямоугольника осей от левого нижнего угла картинки
bot, top длина коротких и длинных рисок
tsi, tfo, tki размер, шрифт (1…5) и начертание (0…2) чисел на осях; tki=3 здесь сбрасывается в 0, хотя в #g оно означает жирный наклонный
sty вид осей, пятизначное число lbrtm
uni 0 — разметка автоматически; иначе номер j элемента r() с ручной разметкой

Цифры sty = lbrtm относятся к левой (l), нижней (b), правой (r) и верхней (t) осям:

Цифра оси Ось
0 есть; числа у левой и нижней, у правой и верхней — нет
1 оси нет
2 есть; числа у правой и верхней, у левой и нижней — нет

Последняя цифра m: 0 — риски внутрь, 1 — наружу. Так, sty=1 — все четыре оси, числа слева и снизу, риски наружу; sty=11211 — только правая ось с числами. Если риски внутрь, а длинные риски длиной в половину большей стороны, получается сетка.

Ручная разметка (uni=j) — одиннадцать чисел с r(j):

Элемент Смысл
r(j) единица функции: график показывает f/r(j)
r(j+1), r(j+2) начало и конец оси x
r(j+3) значение у первой длинной риски на x
r(j+4) шаг между длинными рисками на x
r(j+5) число коротких рисок между длинными на x
r(j+6)…r(j+10) то же для оси y

mp — квази-трёхмерный график

#w [op=mp; file=; le=; b=; nx=; ny=; twi=; the=; wid=; hei=; xsh=; ysh=; bot=; top=; trx=; try=; tsi=; tfo=; tki=; sav=; form=; c=;] xmi xma ymi yma

Матрица f(x, y) — ny строк по nx чисел float из файла (после le байтов) или из r(b)… при file=here — рисуется как набор кривых: каждая следующая строка сдвинута вправо и вверх и заслоняет невидимые части предыдущих. Аргументы — пределы осей: xmi xma для первого аргумента (сетка равномерная), ymi yma — для второго, он размечается на наклонной третьей оси справа.

Параметр Смысл
trx сдвиг следующей кривой вправо, в шагах сетки по x (обычно 1); при 0 рисуется замкнутый прямоугольник без третьей оси
try сдвиг следующей кривой вверх, в тысячных долях максимума функции
wid, hei, xsh, ysh размер и положение прямоугольника осей

Числа на осях ставятся автоматически; подписей нет — их добавляют, сохранив картинку в память и дорисовав командой #g. nx меньше 2 — ошибка 24.

mm — картинка в осях

#w [op=mm; file=; mo=; b=; uni=; twi=; the=; wid=; hei=; xsh=; ysh=; sty=; bot=; top=; tsi=; tfo=; tki=; n=; sav=; form=; c=;] подписи...

Ставит картинку (настоящую, а не числовую матрицу — матрицу сначала превращают в картинку операцией im с сохранением в память) в центр прямоугольника осей и размечает оси. Картинка берётся из файла или, при file=here, из памяти под номером mo. При uni=0 пределы осей берутся из r(b)…r(b+3): xmi xma fmi fma. Подписи — как у pf.

Тонкость. При ручной разметке первое из одиннадцати чисел (единица функции) здесь не используется, но место под него нужно: если ваши десять чисел разметки начинаются с r(j), задайте uni=j−1.

ff — составная картинка

#w [op=ff; file=here; n=; b=; sav=; form=; c=;] заголовок\E

Картинка памяти номер 1 — основа; на неё накладываются картинки 2…n. Картинка номер k сдвигается на (i(b+2k−4), i(b+2k−3)) пикселей: по горизонтали от левого края основы, по вертикали от нижнего края. Типичное применение — карта и шкала серого к ней, полная картина и её сечения. Ту же работу гибче делают #g и #eg.

Карта 200x200 в памяти 1, шкала 20x200 в памяти 2 справа от неё.
#d 2 i(1) 210 0 !
#w [op=ff; file=here; n=2; b=1; sav=0; c=1;] Карта со шкалой\E

#g — простая графика

#g [op=open; twi=; the=; col=;]
#g [op=фигура; ...] [текст\E]
#g [op=close; sav=; form=; c=;] [заголовок\E]

Команда рисует растровую картинку по шагам: открыть холст, нанести линии, фигуры, тексты, готовые картинки, оси и графики функций, закрыть — показать, сохранить в память или в файл. Координаты — целые пиксели от левого нижнего угла холста (ось y вверх). Значимы три буквы op; неизвестная операция — ошибка 52, рисование без открытого холста — ошибка 80, повторное открытие без закрытия — ошибка 82. Не смешивайте открытые холсты #g и #eg: интерпретатор хранит рисуемую картинку в одном месте, и открытие второго холста подменяет первый.

op Что делает
open новый холст
cont продолжить рисование на картинке из памяти
close закончить и показать или сохранить
text строка текста
line ломаная
area многоугольник
rect прямоугольник
oval эллипс
arc дуга или сектор эллипса
image готовая картинка
axes прямоугольник осей с числами и подписями
rfun прочитать функции для графика
dfun нарисовать функции в осях
axon аксонометрия поверхности z(x, y)

Сдвиг и масштаб всего рисунка

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

Параметр Смысл
trx, try вектор, прибавляемый ко всем координатам
sca масштаб в процентах (100 — без изменения); положительный масштабирует и размеры, и положения; отрицательный — только размеры объектов по модулю, положения не трогает

Готовые картинки (image) и размеры осей не масштабируются.

Тонкость. sca использует и #w [op=im;], где он означает способ масштабирования (1…16). После такого #w рисунок #g окажется уменьшенным до нескольких процентов — задавайте #p [trx=0; try=0; sca=100;] перед началом рисования.

open, cont, close

#g [op=open; twi=; the=; col=;]

Открывает холст twi × the пикселей, залитый цветом col из таблицы цветов. Размеры читаются и при закрытии, и операциями axes, dfun, поэтому до close менять twi и the нельзя. Команды, которые их меняют (например, #w [op=im;] для загрузки картинки в память), выполняйте до open.

#g [op=cont; n=;]

Открывает для рисования картинку памяти номер n (нет — ошибка 63).

#g [op=close; sav=; form=; c=; em=; xpo=; ypo=;] заголовок\E

Закрывает холст; судьба картинки — по правилам sav: номер памяти, показ, файл form.jpg. Аргумент-заголовок окна читается только при sav=0 и sav=−1; в остальных случаях текст после команды — просто комментарий. При показе с c≠0 программа ждёт клика или клавиши и получает модификатор и код клавиши в s(1), s(2). em=1 ставит окно в точку (xpo, ypo) от угла экрана.

text — текст

#g [op=text; nx=; ny=; sty=; col=; tfo=; tki=; tsi=;] текст\E
Параметр Смысл
nx, ny точка привязки
sty 1 — текст начинается в точке, 2 — точка в середине строки, 3 — строка кончается в точке; по вертикали точка всегда на базовой линии
col цвет
tfo шрифт: 1 Monospaced, 2 Serif, 3 SansSerif, 4 Dialog, 5 DialogInput (другое — SansSerif)
tki 0 обычный, 1 жирный, 2 наклонный, 3 жирный наклонный
tsi размер в пикселях (разумно 12…16)

Греческие буквы вставляют кодами Юникода: \U945; — α, \U946; — β, \U947; — γ, \U948; — δ, \U916; — Δ, \U952; — θ, \U955; — λ, \U956; — μ, \U960; — π, \U963; — σ, \U969; — ω. Русские буквы пишутся обычным текстом.

line, area — ломаная и многоугольник

#g [op=line; nx=; ny=; n=; b=; col=;]
#g [op=area; nx=; ny=; n=; b=; col=; mo=;]

Начальная точка — (nx, ny); n отрезков заданы приращениями в целом массиве: i(b), i(b+1) — вектор первого отрезка, i(b+2), i(b+3) — второго и так далее.

area дополнительно замыкает ломаную в многоугольник: при mo=0 он заливается цветом col, при mo=1 рисуется только контур.

rect, oval, arc — фигуры

#g [op=rect; nx=; ny=; wid=; hei=; col=; mo=;]
#g [op=oval; nx=; ny=; wid=; hei=; col=; mo=;]
#g [op=arc; nx=; ny=; wid=; hei=; col=; mo=; b=; le=;]

Прямоугольник wid × hei с центром в (nx, ny), эллипс, вписанный в такой прямоугольник, или часть эллипса. mo=0 — залить, mo=1 — только контур.

У arc b — начальный угол, le — угловая ширина, в градусах; углы отсчитываются от направления «на три часа» против часовой стрелки. С mo=0 получается залитый сектор.

image — готовая картинка

#g [op=image; nx=; ny=; n=; file=;]

При n>0 картинка берётся из памяти, иначе из файла file в рабочей папке (нет файла — ошибка 13). Центр картинки ставится в (nx, ny); сама картинка не масштабируется.

axes, rfun, dfun — график функций

Эти три операции делают то же, что #w [op=pf;], но позволяют рисовать разные функции разными цветами, поверх других элементов, и ставить область функций не там, где оси.

#g [op=rfun; file=; b=; le=; mo=; nx=; ny=; n=;] [Xmin Xmax]
#g [op=axes; b=; wid=; hei=; xsh=; ysh=; col=; sty=; bot=; top=; tsi=; tfo=; tki=; uni=; n=;] подписи...
#g [op=dfun; b=; col=; mo=; nx=; ny=; msi=; mki=;]

rfun читает функции так же, как #w [op=pf;]: из файла в рабочей папке (числа float после le байтов) или из r(b)… при file=here; mo, nx, ny и аргументы Xmin Xmax — оттуда же. Пределы xmi xma fmi fma записываются в r(n)…r(n+3).

axes рисует прямоугольник осей wid × hei с центром в (xsh, ysh) и подписи (их n, каждая — x y rts текст\E от левого нижнего угла холста). Пределы для автоматической разметки берутся из r(b)…r(b+3). Остальное — как в описании осей.

dfun рисует функции, прочитанные последним rfun, в масштабе осей, нарисованных последним axes. Пределы берутся из r(b)…r(b+3) и должны совпадать с теми, что вернул rfun.

Тонкость. rfun возвращает пределы в r(n), а axes и dfun берут их из r(b): при rfun параметр b занят под адрес данных. Задавайте b для axes и dfun равным n из rfun. the при этом должен оставаться равным высоте холста.

axon — аксонометрия поверхности

#g [op=axon; b=; n=; c=; wid=; hei=; xsh=; ysh=; col=; tsi=; tfo=; tki=;]

Рисует однозначную поверхность z(x, y) линиями x-z и y-z сечений с удалением невидимых линий, в трёхмерных осях. Значения функции — матрица nx × ny без аргументов с r(b). Картинка занимает прямоугольник wid × hei с левым нижним углом (xsh, ysh). Шрифт чисел — tfo, tki (0…2), tsi.

Восемнадцать вещественных параметров с r(n):

Элементы Смысл
xmi xma xfm xdm пределы оси x, значение у первой короткой риски, шаг коротких рисок
ymi yma yfm ydm то же для y
zmi zma zfm zdm то же для z
vp1 vp2 vp3 направление на точку зрения (нормируется; алгоритм рассчитан на направления около 1 1 1)
vpm десятичный логарифм расстояния до точки зрения: 3 — это 1000
hx hy масштабы аргументов x и y (обычно 1); подбираются так, чтобы Δx·hx и Δy·hy были близки к Δz, когда величины в разных единицах

Двенадцать целых параметров с i(c):

Элементы Смысл
nx ny число точек по x и по y (произведение не больше 65536, иначе ошибка 87)
ngv 1 — x-z сечения, 2 — y-z сечения, 3 — оба
bot top длина коротких и длинных рисок в тысячных долях диагонали
nxfm nxsm номер первой короткой риски, которая становится длинной с числом, и число коротких рисок между длинными по x
nyfm nysm, nzfm nzsm то же для y и z
nax 0 — обе вертикальные оси, средняя ось и уровни; 1 — только правая вертикальная ось у оси x; 2 — только левая у оси y

Векторный вариант того же графика — #ps [op=ax;], готовая программа с разметкой осей — суперкоманда ##3.

Пример

#p [trx=0; try=0; sca=100;]
#g [op=open; twi=300; the=200; col=246;]
#g [op=rect; nx=150; ny=100; wid=200; hei=120; col=249; mo=1;]
#g [op=oval; nx=150; ny=100; wid=80; hei=80; col=248; mo=0;]
#g [op=arc; nx=150; ny=100; wid=120; hei=120; col=250; mo=1; b=0; le=90;]
#d 4 i(1) 100 0 0 50 !
#g [op=line; nx=20; ny=20; n=2; b=1; col=250;]
#g [op=text; nx=150; ny=175; col=255; tfo=3; tki=1; tsi=16; sty=2;] Фигуры\E
#g [op=close; sav=-1; form=shapes; c=1;] Пример графики\E

Синяя рамка, красный круг в центре, зелёная четверть окружности справа вверху, ломаная «вправо на 100, вверх на 50» из точки (20, 20) и заголовок; картинка показывается и записывается в shapes.jpg.

#eg — универсальная графика

#eg [op=open; twi=; the=; col=;]
#eg [op=xxx; ...] [аргументы]
#eg [op=close; sav=; form=; c=;] [заголовок\E]

Команда рисует на основе пакета Java 2D, устроенного по идеям PostScript: любой объект — это контур (path), который можно обвести линией заданной толщины и рисунка или залить сплошным цветом, градиентом или текстурой; ко всем последующим объектам можно применять сдвиг, поворот, масштаб и скос. Контуры строит отдельная команда #pat, а #eg использует их по номеру. Качество выше, чем у #g, но и программировать сложнее.

Значимы три буквы op; неизвестная операция — ошибка 53, рисование без открытого холста — ошибка 39, повторное открытие — ошибка 82. Сглаживание включено всегда.

Координаты

op Что делает Числа в r(b)…
open новый холст twi × the, фон col —
cont продолжить картинку памяти n —
close закончить, показать или сохранить —
trans сдвиг последующих объектов x y
rotate поворот вокруг текущего начала координат угол в радианах
scale масштаб sx sy
shear скос x y
clip обрезать последующее по контуру n —
paint способ закраски для градиента x1 y1 x2 y2
fill залить контур n —
draw обвести контур n толщина, предел острия, пунктир, фаза
text строка текста x y
mtxt несколько строк текста — (всё в аргументах)
image картинка из памяти x y угол shx shy sx sy
chfont проверить наличие шрифта —

open, cont, close

open открывает холст twi × the, залитый цветом col из таблицы цветов. cont вместо нового холста открывает картинку памяти номер n (нет — ошибка 63). close работает так же, как у #g: правила sav, файл form.jpg, заголовок-аргумент только при sav 0 и −1, ожидание клика при c≠0, положение окна em=1, xpo, ypo.

Картинки из файлов загружайте в память (например, #w [op=im; sav=…;]) до открытия холста.

trans, rotate, scale, shear — преобразования

#eg [op=trans; b=;]    сдвиг на (r(b), r(b+1))
#eg [op=rotate; b=;]   поворот на r(b) радиан
#eg [op=scale; b=;]    масштаб r(b) по x, r(b+1) по y
#eg [op=shear; b=;]    скос: r(b) по x, r(b+1) по y

Преобразования накапливаются и действуют на все последующие объекты, в том числе текст и картинки. Поворот идёт вокруг начала координат, поэтому, чтобы повернуть объект вокруг его центра, сначала сдвигают начало в центр.

clip — обрезка

#eg [op=clip; n=;]

Всё, что рисуется дальше, видно только внутри замкнутого контура номер n.

paint — способ закраски

#eg [op=paint; mo=; col=; b=; sty=; c=;]
mo Закраска
1 сплошной цвет col
2 градиент от цвета col в точке (r(b), r(b+1)) к цвету col+1 в точке (r(b+2), r(b+3)); sty=0 — за пределами отрезка цвет постоянный, sty=1 — переход повторяется периодически
3 текстура: копии картинки памяти номер c (не n!)

Закраска действует на fill, draw и текст.

fill — залить контур

#eg [op=fill; n=;]

Заливает контур номер n текущей закраской с учётом всех преобразований. Незаданный контур — ошибка 62.

draw — обвести контур

#eg [op=draw; n=; b=; le=; mo=; sty=;]
Элемент Смысл
r(b) толщина линии
r(b+1) предел длины острого угла для соединения «острие» (не меньше 1)
r(b+2) … r(b+1+le) пунктир: длина штриха, длина пропуска, штрих, … — повторяется вдоль линии
r(b+2+le) фаза пунктира — длина первого отрезка
mo концы линии: 0 — обрезаны точно по концу, 1 — скруглены, 2 — квадратные, выступающие на полтолщины
sty соединения отрезков: 0 — острие, 1 — скругление, 2 — срез

Значения mo и sty вне 0…2 заменяются на 1.

Тонкость. Пунктир обязателен: при le=0 Java отвергает пустой пунктир, и интерпретатор падает с исключением. Сплошная линия получается пунктиром из штриха и нулевого пропуска: le=2, r(b+2)=1, r(b+3)=0.

text — строка текста

#eg [op=text; b=; sty=; tki=; tsi=; form=; em=;] текст\E
Параметр Смысл
r(b), r(b+1) точка привязки
sty 1…9: по горизонтали 1, 4, 7 — начало строки, 2, 5, 8 — середина, 3, 6, 9 — конец; по вертикали 1…3 — низ, 4…6 — середина высоты, 7…9 — верх
tki 0 обычный, 1 жирный, 2 наклонный, 3 жирный наклонный
tsi размер
form имя семейства шрифтов — любого установленного в системе
em больше 0 — y отсчитывается от нижнего края холста (только без scale)

Имя шрифта с пробелами прямо в параметр не записать (пробел оканчивает значение) — его печатают в t() и подставляют ссылкой:

#pr Times New Roman\E
#p [form=\Tp\E]

Греческие буквы — кодами Юникода (\U945; и т. д., см. #g). После em>0 верните em=0.

mtxt — несколько строк

#eg [op=mtxt; n=; tki=; tsi=; form=; em=;] st x y ts текст\E st x y ts текст\E ...

n строк, каждая описана пятью аргументами: st — привязка (1 — начало, 2 — середина, 3 — конец строки; знак минус — координаты абсолютные, иначе отсчитываются от точки предыдущей строки, начиная с (0, 0)), x y, добавка ts к базовому размеру tsi, сам текст. Шрифт — form, начертание — tki. При em>0 абсолютные y отсчитываются от нижнего края.

image — картинка

#eg [op=image; n=; b=; em=;]

Ставит картинку памяти номер n с собственным преобразованием, которое выполняется до общего:

Элемент Смысл
r(b), r(b+1) центр картинки (от верхнего левого угла; при em>0 y от нижнего края)
r(b+2) поворот вокруг центра, радианы
r(b+3), r(b+4) скос
r(b+5), r(b+6) масштаб по x и по y — обязательно задайте, при нуле картинка не видна

chfont — есть ли шрифт

#eg [op=chfont; form=имя;]

&=1, если семейство шрифтов установлено, иначе &=0. Работает и без открытого холста. Нужна для переносимости: отсутствующий шрифт Java молча заменяет своим, и текст перестаёт помещаться.

PDF

Если перед этим открыт документ #pd и выполнено #pd [op=opeg;], все операции #eg, кроме open и close, рисуют прямо в PDF.

Пример

#d 4 r(1) 20 20 160 80 !
#pat [op=rect; b=1; n=1;]
#eg [op=open; twi=200; the=120; col=246;]
#d 4 r(11) 20 0 180 0 !
#eg [op=paint; mo=2; col=249; b=11; sty=0;]
#eg [op=fill; n=1;]
#d 5 r(21) 3 1 8 4 0 !
#eg [op=paint; mo=1; col=247;]
#eg [op=draw; n=1; b=21; le=2; mo=0; sty=0;]
#d 2 r(31) 100 60 !
#eg [op=paint; mo=1; col=246;]
#eg [op=text; b=31; sty=5; tki=1; tsi=18; form=Serif;] Градиент\E
#eg [op=close; sav=0; c=1;] Пример универсальной графики\E

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

#pat — контуры для #eg

#pat [op=open; b=;]
#pat [op=line; b=;] ...
#pat [op=close; n=; mo=;]
#pat [op=rect; b=; n=;]

Команда строит контуры (path) — сложные линии из отрезков прямых и кривых Безье, эллипсов и дуг — и хранит их под номерами 1…100. Команда #eg потом заливает, обводит их или обрезает по ним рисунок. Один и тот же контур можно использовать много раз. Значимы три буквы op; неизвестная операция — ошибка 54.

Координаты, как и в #eg, вещественные, от левого верхнего угла, ось y вниз; они берутся из r() начиная с r(b).

op Что делает Числа в r(b)…
open начать новый текущий контур, поставить перо в точку x y
cont сделать текущим сохранённый контур n и продолжать его —
line отрезок из текущей точки x y — конец
quad квадратичная кривая: касательные в концах проходят через управляющую точку x1 y1 — управляющая точка, x2 y2 — конец
cub кубическая кривая: касательная в начале направлена к первой управляющей точке, в конце — от второй x1 y1 x2 y2 — управляющие точки, x3 y3 — конец
app присоединить сохранённый контур n к текущему; mo=1 — соединив отрезком —
close сохранить текущий контур под номером n; mo=1 — замкнуть отрезком в начальную точку —
rect сразу сохранить под номером n прямоугольник x y w h — левый верхний угол, ширина, высота
ell сразу сохранить под номером n эллипс, вписанный в прямоугольник x y w h
arc сразу сохранить под номером n часть такого эллипса x y w h, начальный угол, угловая ширина

У arc параметр mo задаёт вид: 0 — открытая дуга, 1 — дуга с хордой, 2 — сектор («кусок пирога»).

Треугольник как контур 3, залитый красным.
#d 6 r(1) 100 10 180 150 20 150 !
#pat [op=open; b=1;]
#pat [op=line; b=3;]
#pat [op=line; b=5;]
#pat [op=close; n=3; mo=1;]
#eg [op=open; twi=200; the=170; col=246;]
#eg [op=paint; mo=1; col=248;]
#eg [op=fill; n=3;]
#eg [op=close; sav=0; c=1;] Треугольник\E

Тонкости.

#ps — векторная графика в EPS

#ps [op=of; twi=; the=; form=;]
#ps [op=ps | pf | ax; ...]
#ps [op=cf;]

Команда пишет рисунок на языке PostScript в файл encapsulated PostScript (.eps). Такая графика векторная: печатается без потери качества, вставляется в статьи LaTeX, показывается программой Ghostview (GSview) или после перевода в PDF. Сам интерпретатор EPS не показывает. Рисунок собирается из готовых фрагментов, каждый — одной операцией. Значимы две буквы op; короче двух — ошибка 45, неизвестная — ошибка 65, рисование без открытого файла — ошибка 81.

op Что делает
of открыть файл, записать заголовок и пролог
ps вставить готовый PostScript-код из файла или из t()
pf нарисовать одну функцию в осях, как #w [op=pf;]
ax аксонометрия поверхности, как #g [op=axon;]
cf закончить и закрыть файл

Единицы и общий сдвиг

Размеры рисунка — в точках PostScript (1/72 дюйма; лист A4 — 596×843 точки). Операции ps, pf, ax оборачивают свой фрагмент в преобразование:

Параметр Смысл
trx, try сдвиг фрагмента в десятых долях точки
sca масштаб в сотых долях: 100 — натуральный размер
rat только у ps: поворот в десятых долях градуса

Поэтому один и тот же фрагмент можно ставить в разные места, в разном масштабе и много раз. Параметр rat обычно равен 0; оставшееся от другой команды значение повернёт вставленный фрагмент.

of — открыть файл

#ps [op=of; twi=; the=; form=имя;]

Создаёт в рабочей папке файл имя.eps с рамкой twi × the точек и пишет пролог — набор коротких команд-сокращений (m — перейти, l — линия, ls — отрезок, srgb — цвет, slw — толщина, r — поворот, s, sc, se — текст с привязкой слева, по центру, справа, L, G, H — текст 14 пт шрифтами Palatino, Symbol, Helvetica и другие). Ими удобно пользоваться во фрагментах для ps; пролог можно прочитать в любом созданном файле. Эта операция должна быть первой.

ps — готовый код

#ps [op=ps; file=; b=; le=; trx=; try=; sca=; rat=;]

Вставляет PostScript-код из файла file в рабочей папке (нет файла — ошибка 13) или, при file=here, le символов из t() начиная с t(b). Так вставляют растровые картинки, превращённые во фрагменты операцией #f [op=tops; mo=2 или 3;], подписи и любые собственные рисунки. Например, подпись в точке (100, 50), повёрнутая на 90°:

#ps [op=of; twi=200; the=200; form=label;]
# s(3)=1; !
#pr 100 50 m 90 r (Intensity)L -90 r\E
#ps [op=ps; file=here; b=s(4); le=s(5); trx=0; try=0; sca=100; rat=0;]
#ps [op=cf;]

Буква L печатает латиницей, G — греческими буквами. Русский текст автор выводит собственным шрифтом; это отдельная техника, описанная в его книге о PostScript.

pf — функция в осях

#ps [op=pf; file=; b=; le=; mo=; nx=; col=; msi=; mki=; siz=; оси...; trx=; try=; sca=;] [X1 X2]

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

Параметр Смысл
file файл чисел float в рабочей папке (после le байтов заголовка) или here — r(b)…
nx число точек
mo 0 — в данных только значения, аргумент равномерный от X1 до X2 (аргументы команды); 1 — сначала nx аргументов, затем nx значений
col цвет кривой (оси всегда чёрные)
mki 0 — сплошная линия толщиной msi (по словам автора — в сотых долях точки); 1 — белый квадрат, 2 — цветной квадрат, 3 — белый круг, 4 — цветной круг размером msi; больше 4 — ошибка 64
siz толщина линий осей — 0,5·siz точки
wid, hei, xsh, ysh, sty, bot, top, uni оси, как в #w; sty=11111 — без осей
tsi размер чисел на осях в точках (шрифт Helvetica)

ax — аксонометрия

#ps [op=ax; b=; n=; c=; wid=; hei=; col=; tsi=; trx=; try=; sca=;]

Всё как у #g [op=axon;]: функция z(x, y) с r(b), восемнадцать вещественных параметров с r(n), двенадцать целых с i(c). Отличия: wid, hei — размер прямоугольника, в котором лежат линии (числа на осях могут выходить за него); xsh, ysh не используются — положение задают trx, try (они должны быть положительными, иначе числа уйдут за рамку); шрифт чисел фиксирован, tsi — его размер в точках.

cf — закрыть

#ps [op=cf;]

Дописывает окончание и закрывает файл. Без неё файл неполон.

Пример

Гауссова поверхность 91 на 91 точку в EPS.
# y=-9; d=0.2; j=21; !
#rep 91
  # x=-9; !
  #rep 91 # r(j)=exp(-0.03*(x*x+y*y)); j=j+1; x=x+d; #end
  # y=y+d; !
#end
#ps [op=of; twi=450; the=320; form=axexam;]
#d 12 i(1) 91 91 3 10 20 2 3 2 3 1 1 0 !
#d 18 r(1) -0,9 0,9 -0,9 0,1 -0,9 0,9 -0,9 0,1 0 1 0 0,1 1 1 0.5 3 1 1 !
#p [tsi=14; col=247;]
#ps [op=ax; trx=750; try=500; sca=100; n=1; c=1; b=21; wid=300; hei=250;]
#ps [op=cf;]

Тонкость. В похожем примере автора стоят trx=75; try=50; sca=1;. По коду интерпретатора сдвиг задаётся в десятых долях точки, а масштаб — в сотых, так что с такими значениями рисунок получится в сто раз меньше натурального. Для натурального размера нужно sca=100.

#pd — PDF-документы

#pd [op=open; file=имя.pdf; twi=; the=; wid=; hei=; xsh=; ysh=; mo=;] [аргументы]
#pd [op=para | text | imag | page | ...; ...]
#pd [op=clos;]

Команда создаёт документ PDF: абзацы текста, надписи в заданных точках, картинки, векторная графика #eg, страницы из других PDF-файлов, колонтитулы, пароли. В основе — библиотека iText 1.3 (Bruno Lowagie). Все размеры — в точках (pt, 1/72 дюйма; лист A4 — 596×843 pt). Значимы четыре буквы op; неизвестная операция — ошибка 74, неверное расширение файла — ошибка 75, операция без открытого документа — ошибка 76.

op Что делает
open начать документ
clos закончить и записать файл
para абзац текста в потоке
text строка текста в заданной точке, с поворотом
imag картинка в потоке или в заданной точке
page перейти на новую страницу
smar поля следующей страницы
smmi зеркальные поля
spgn номер страницы
rpdf прочитать внешний PDF
wpdf вставить страницу прочитанного PDF
opeg начать векторную графику #eg прямо в PDF
cleg поставить эту графику на страницу

Тонкость. Встроенные шрифты PDF не содержат русских букв. Русский текст рисуют командой #eg в картинку и вставляют операцией imag.

open — начать документ

Параметр Смысл
file имя файла с расширением .pdf в рабочей папке; file=arg — из аргумента
twi, the размер листа
wid, hei размер области текста
xsh, ysh левое и нижнее поля (правое и верхнее — остаток)
mo четырёхзначное KLMN из нулей и единиц: N — нижний колонтитул, M — верхний, L — метаданные, K — пароль

Для каждой единицы в mo читается аргумент, в порядке: нижний колонтитул, верхний колонтитул, метаданные, пароль.

Аргумент Вид Дополнительно
колонтитул текст|номер|рамка\E: номер > 0 — нумеровать страницы начиная с него; рамка — сумма 1 (верх), 2 (низ), 4 (лево), 8 (право) выравнивание: bot для нижнего, top для верхнего — 0 слева, 1 по центру, 2 справа
метаданные заголовок|тема|ключевые слова|создатель|автор\E в документе не видны
пароль пароль пользователя и пароль владельца подряд, \E le — длина пароля пользователя; sty=1 — слабое шифрование (иначе сильное); sav — сумма разрешений
Разрешение Число
печать 2052
печать низкого качества 4
изменение содержимого 8
копирование 16
изменение примечаний 32
заполнение форм 256
программы чтения с экрана 512
сборка документа 1024

Разрешить печать и копирование — sav=2068. Остальные действия потребуют пароля.

clos — закончить

Закрывает документ и дописывает файл. Без неё PDF неполон.

para — абзац

#pd [op=para; b=; tfo=; tki=; tsi=; col=;] текст\E
Параметр Смысл
tfo семейство: 0 Courier, 1 Helvetica, 2 Times-Roman, 3 Symbol, 4 ZapfDingbats
tki начертание: 0 обычное, 1 жирное, 2 курсив, 3 жирный курсив, 4 подчёркнутое, 8 зачёркнутое
tsi размер в pt
col цвет из таблицы цветов
r(b)…r(b+5) отступ перед абзацем, отступ после, выравнивание (0 слева, 1 по центру, 2 справа), отступ первой строки, поле слева, поле справа

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

text — надпись в точке

#pd [op=text; b=; tfo=; col=; sty=;] текст\E
Параметр Смысл
tfo шрифт 1…15: Courier (1–4: обычный, жирный, наклонный, жирный наклонный), Helvetica (5–8, так же), Times (9–12: обычный, жирный, курсив, жирный курсив), 13 Times-Roman, 14 Symbol, 15 ZapfDingbats
r(b)…r(b+3) размер в pt, координаты x, y на странице, угол поворота
sty привязка к точке: 0 — левым краем, 1 — серединой, 2 — правым краем

Тонкость. Автор пишет, что угол задаётся в радианах; библиотека iText принимает его в градусах.

imag — картинка

#pd [op=imag; file=; mo=; b=;]

Картинка из файла jpg, gif, png, bmp, tif, wmf или eps (файл с другим расширением молча пропускается). mo — двузначное KM:

Разряд Значения
K 0 — в потоке текста после предыдущего; 1 — по абсолютным координатам левого нижнего угла
M масштаб: 0 — в процентах, 1 — до заданной ширины, 2 — до заданной высоты (пропорции сохраняются)
Элемент Смысл
r(b), r(b+1) при K=1 — координаты; при K=0 — отступы до и после картинки
r(b+2) при K=0 — положение в строке: 0 слева, 1 по центру, 2 справа
r(b+3) проценты, ширина или высота в pt — по M
r(b+4) поворот в градусах

Прозрачности нет: картинки, поставленные позже, закрывают ранние. Поэтому картинки по абсолютным координатам ставят после потоковых.

page — новая страница

Принудительно переводит вывод на следующую страницу.

smar, smmi, spgn — поля и нумерация

Операция Что делает
#pd [op=smar; b=;] поля следующей страницы из r(b)…r(b+3): левое, правое, верхнее, нижнее
#pd [op=smmi; mo=;] mo=1 — зеркальные поля на чётных и нечётных страницах, иначе нет
#pd [op=spgn; n=;] номер текущей страницы (и включение нумерации)

rpdf, wpdf — страницы другого PDF

#pd [op=rpdf; file=другой.pdf; b=;]
#pd [op=wpdf; n=; b=;]

rpdf читает внешний файл (открытый документ не нужен): число страниц — в s(1), размеры страниц — в r(b)… парами «ширина, высота». wpdf ставит страницу номер n прочитанного файла на текущую страницу документа с преобразованием из r(b)…r(b+4): сдвиг по x и y от левого нижнего угла (pt), масштаб по x и y (1 — без изменений), поворот в градусах. Так собирают несколько страниц на одном листе, поворачивают и переупорядочивают страницы.

opeg, cleg — векторная графика в PDF

#pd [op=opeg; wid=; hei=; col=;]
#eg [...] ...
#pd [op=cleg; xsh=; ysh=;]

opeg открывает область графики wid × hei, залитую цветом col; после неё любые операции #eg, кроме open и close, рисуют прямо в PDF (векторно). cleg ставит нарисованное на страницу с левым и нижним полями xsh, ysh. Открытый холст #eg при opeg — ошибка 82, cleg без opeg — ошибка 39.

Пример

#pd [op=open; file=report.pdf; twi=596; the=843; wid=480; hei=700; xsh=58; ysh=70; mo=1;] VKACL report|1|1\E
#d 6 r(1) 0 12 1 0 0 0 !
#pd [op=para; b=1; tfo=2; tki=1; tsi=18; col=247;] Measurement report\E
#d 6 r(1) 0 6 0 20 0 0 !
#pd [op=para; b=1; tfo=2; tki=0; tsi=12; col=247;] The picture below was made by the program.\E
#d 5 r(11) 10 10 1 300 0 !
#pd [op=imag; file=pic.png; mo=1; b=11;]
#pd [op=clos;]

Документ A4 с нижним колонтитулом «VKACL report», номерами страниц с первой и линией над колонтитулом; заголовок по центру, абзац с красной строкой и картинка шириной 300 pt по центру.

#bi — обработка байтовых картинок

#bi [op=xxx; file=; form=; rat=; bot=; top=; mo=; b=;] [список файлов\E]

Команда обрабатывает «сырые» картинки — файлы, где каждый байт означает уровень серого точки (такие делает, например, #f [op=tobm;]). Байт трактуется как целое 0…255; после преобразования отрицательные значения становятся 0, большие 255 — 255. Исходный файл file не меняется, результат пишется в файл form; оба имени — в рабочей папке. Значимы три буквы op; неизвестная операция — ошибка 66, недопустимые параметры — ошибка 67, нет файла — ошибка 19.

Преобразования одной картинки

op Новое значение f из исходного b Параметры
add b + rat — ярче или темнее rat любого знака
mul b·rat/1000; при rat ≤ 0 — 255 + b·rat/1000, то есть обращение контраста rat (1000 — без изменений)
inc отрезок [bot, top] растягивается на [0, 255] — контраст выше 0 < bot < top < 255
dec [0, 255] сжимается в [bot, top] — контраст ниже 0 < bot < top < 255
cha m + (b − m)·rat/1000, где m — среднее по картинке rat (1000 — без изменений)
pow 255·(b/255)^(rat/1000) — неравномерный градиент при тех же пределах rat (1000 — без изменений)
log (ln(b + p1) − ln(255 + p2 − b) + f1)·f2, где f1 = ln(255 + p2) − ln p1, f2 = 255/(ln(255 + p1) − ln p2 + f1); сглаженный аналог dec — градиент в середине меньше p1 = bot > 0, p2 = top > 0
exp 255/(1 + exp((p2 − b)/p1)), где p2 = (bot+top)/2, p1 = p2 − bot; сглаженный аналог inc — градиент в середине больше 0 < bot < top < 255, top − bot чётное
#bi [op=inc; bot=40; top=200; file=scan.raw; form=scan2.raw;]

Несколько картинок

sup, pro, div работают со списком файлов, который задают двумя способами:

file Аргумент
list имена через |: 1.rif|2.rif|3.rif\E
order базовое имя с номером перед расширением из трёх букв, например my00.rif\E; номера от bot до top подставляются вместо последних цифр: my01.rif, my02.rif, …

Результат имеет размер первого файла. Файлы меньшего размера используются целиком, большего — только их начало. Отсутствующий файл пропускается с сообщением в терминале.

op Что вычисляется
sup взвешенная сумма Σ b_k·i(b+k−1) с целыми весами из i(b)… (отрицательные — вычитание); затем mo=0 — отрицательные обнуляются, а максимум приводится к 255; mo=1 — весь диапазон от минимума до максимума переводится в 0…255
pro произведение всех картинок, максимум приводится к 255
div первая картинка, делённая на вторую (нулевые байты делителя заменяются на 1), максимум приводится к 255; остальные файлы списка не используются
#d 3 i(1) 1 2 3 !
#bi [op=sup; mo=0; file=list; form=sum.rif; b=1;] 1.rif|2.rif|3.rif\E
#bi [op=sup; mo=0; file=order; form=sum2.rif; b=1; bot=1; top=3;] my00.rif\E

Первая команда складывает три картинки с весами 1, 2, 3; вторая делает то же для my01.rif…my03.rif. Сложение удобно, когда детектор не выдерживает длинной экспозиции и один кадр снимают много раз; умножение на маску из нулей и единиц вырезает часть картинки.

Тонкость. Картинки разной ширины складываются «вслепую», байт за байтом: меньшая картинка размазывается по большей. Для таких случаев сначала вырежьте из большой картинки фрагмент нужного размера (#f [op=divi;]).

#ag — анимация

#ag [op=o; wid=; hei=; xsh=; ysh=; file=;] заголовок\E
#ag [op=m; n=; xsh=; ysh=; file=;] заголовок\E
#ag [op=p;]   #ag [op=i;]   #ag [op=c;]
#ag [op=s;] адрес-протокола\E

Команда открывает окно анимации, показывает в нём по очереди картинки из памяти (их заранее рисуют #g, #eg или загружают #w), играет фоновую музыку и сообщает программе о нажатиях клавиш и действиях мышью — этого хватает для презентаций и простых интерактивных игр. Операцию задаёт одна буква; другая — ошибка 55.

op Что делает
o открыть окно анимации, включить фоновую музыку
m показать кадр, сменить заголовок, получить действия пользователя
p только получить действия пользователя
i обнулить сведения о действиях
c закрыть окно, выключить музыку
s запустить готовую программу слайд-шоу

o — открыть окно

Параметр Смысл
wid, hei полный размер окна в пикселях
xsh, ysh левый верхний угол окна от угла экрана
file фоновая музыка, повторяется бесконечно: файл .wav, .au, .aif или .mid в рабочей папке; &имя — файл внутри jar-файла; nomusic — без музыки; arg — имя из первого аргумента (заголовок тогда — второй аргумент)

Аргумент — заголовок окна. Отсутствующий файл музыки ошибкой не считается. Для фона разумнее всего MIDI: файлы маленькие.

Тонкость. В новых версиях Java окно поначалу прозрачное и показывает то, что было под ним. Сразу после o выставьте первый кадр операцией m.

m — кадр

Параметр Смысл
n номер картинки в памяти
xsh, ysh сдвиг центра картинки от центра окна
file звуковой файл, проигрываемый один раз; nomusic — без звука

Аргумент заменяет заголовок окна. Окно имеет полосу заголовка высотой около 26 пикселей: чтобы картинка W × H поместилась целиком, задайте окну высоту H+26 и сдвиг ysh=−13.

После показа кадра программа получает сведения о действиях пользователя с момента последнего обнуления:

Ячейка Значение
s(1) модификатор клика (см. таблицу #w)
s(2) код нажатой клавиши
s(102), s(103) текущее положение мыши в окне
s(104), s(105) точка отпускания кнопки после протяжки
s(108) кратность клика: 1 — одинарный, 2 — двойной, …

Если музыка не нужна, всё равно пишите file=nomusic: проверка несуществующего файла отнимает время в каждом кадре. Одновременное проигрывание звука и подготовка кадра ухудшают звук — автор советует готовить кадр в тишине, а звук давать, пока кадр стоит на экране.

p и i — опрос действий

p только возвращает те же сведения, что и m, без показа кадра — так пишут цикл ожидания клавиши. Сведения сохраняются, пока их не обнулит i; без обнуления одно нажатие будет «видно» вечно. Клавиатура опрашивается надёжно, клики мыши — по словам автора, пока нестабильно. Окно анимации не всегда активно, поэтому клавишу иногда приходится подержать.

Ждать нажатия любой клавиши.
#ag [op=i;]
# &=1; !
#case 1
  #rob [mo=1; le=50;]
  #ag [op=p;]
  # &=1-sgn(s(2)); !
#end

c — закрыть

Закрывает окно и выключает музыку. Если пользователь закрыл окно крестиком во время показа, интерпретатор блокирует циклы: тело любого #rep и #case-цикла выполняется только один раз, чтобы бесконечная анимация кончилась. Нормальную работу циклов возвращает #init, поэтому после анимации всегда пишут #ag [op=c;] и #init.

Кадры 1…10 заранее сохранены в память.
#ag [op=o; wid=320; hei=266; xsh=100; ysh=100; file=nomusic;] Анимация\E
# k=1; !
#rep 10
  #ag [op=m; n=k; xsh=0; ysh=-13; file=nomusic;] Кадр\E
  #rob [mo=1; le=100;]
  # k=k+1; !
#end
#ag [op=c;]
#init

Для быстрой анимации кадры лучше приготовить заранее и сохранить в память, а темп задавать паузой #rob [mo=1;]: рисование кадра прямо в цикле иногда даёт случайные задержки.

s — слайд-шоу

#ag [op=s;] адрес\E

Запускает готовую программу слайд-шоу с переходами между картинками — локальными или из интернета. Ей управляет файл-протокол, адрес которого — в аргументе: File:C:/папка/show.vks для локального файла или обычный адрес http://…. Путь к файлу рядом с программой удобно собрать кодами \M\H. Правила записи протокола автор описывает отдельно на своём сайте (kohnvict.ucoz.ru/acl/vkss.htm).

#so — звук

#so [op=psf; n=; c=; siz=; sty=; mo=; le=;] файл1\E файл2\E ...
#so [op=rsf; xsh=; ysh=; rat=; siz=; mo=; sty=; b=; le=;]
#so [op=mid; file=;]

Команда проигрывает звуковые файлы и записывает звук с микрофона. Значимы три буквы op; неизвестная операция — ошибка 56. Команда писалась под Java 1.4.2; автор предупреждает, что в новых версиях Java её работу нужно проверять.

psf — проиграть файлы

Параметр Смысл
n число файлов; их имена — аргументы, по одному в каждом, в рабочей папке
c канал 1…10; проигрыватели в разных каналах звучат одновременно
siz громкость в процентах: 100 — как в файле; MIDI не бывает громче 100, WAVE, AU, AIFF — бывают
sty панорама от −100 до 100 (распределение между динамиками), обычно 0
mo 0 — проиграть один раз; иначе повторять по кругу
le параметр звукового процесса, обычно 100 (или 99); другие значения дают эффекты, подбираемые на слух

Файлы проигрываются по очереди, другие форматы не поддерживаются. Бесконечное проигрывание (mo≠0) останавливает только #init. Автор советует сочетать звук с окном анимации #ag: держать программу в цикле, а после цикла поставить #init — закрытие окна анимации завершит цикл и остановит звук. Нормальный звук получается, когда открыто мало окон и программа не занята тяжёлым расчётом.

#so [op=psf; n=2; c=1; siz=100; sty=0; mo=0; le=100;] intro.wav\E theme.mid\E

rsf — записать звук

Открывает диалог записи: пользователь вводит имя файла (без расширения) и записывает сколько угодно клипов, например комментарии к слайдам. Файлы сохраняются в рабочую папку, кодировка — PCM.

Параметр Смысл
xsh, ysh положение окна диалога от угла экрана (размер фиксирован)
rat частота выборки: 8000, 11025, 16000, 22050 или 44100 (качество CD)
siz разрядность: 8 или 16 бит
mo 1 — моно, 2 — стерео
sty тип файла: 1 — WAVE (.wav), 2 — AU (.au), 3 — AIFF (.aif)
b, le текст в t(), который показывает кнопка Help диалога

mid — фоновая музыка

Операция не описана в справочнике автора; по коду она берёт файл file из рабочей папки (или &имя из jar-файла) и проигрывает его по кругу — так же, как фоновая музыка окна анимации. Останавливает её #init или #ag [op=c;].

Песочница

Программы выполняются прямо в браузере: интерпретатор ядра VKACL собран в WebAssembly и встроен в страницу, поэтому всё работает даже без интернета и при открытии книги прямо с диска. Выберите пример из списка или пишите своё; запуск — кнопкой или Ctrl+Enter.

Песочница работает только на сайте книги.

Что здесь работает

Ядро языка: вычисления, память, ветвления, циклы, процедуры, форматированный текст, #d, #v, #pas, #pr, #m, операции над массивами #ma, файловые команды #io, #f, #te.

Окна выбора и ввода (#sel, #inp, #m [op=gen;], суперкоманда ##33) заменены вопросами: ответы берутся по одному из поля «Ответы на вопросы программы» под редактором — номер кнопки или значение поля.

Файлы. Без подключённой папки файлы живут в памяти только на время одного запуска: то, что программа записала, показывается под выводом, а каждый файл можно скачать по ссылке. Кнопка «Подключить папку» (есть в Chrome, Edge, Opera, Яндекс Браузере) даёт программе настоящую папку на диске: перед запуском её файлы читаются, после — изменённые и новые записываются обратно. Браузер спросит разрешение один раз. В Firefox и Safari такой возможности нет, и на месте кнопки стоит подсказка.

Графики, окна с картинками, звука, PDF здесь нет — такая команда честно сообщит, что не поддерживается. Для них нужен интерпретатор автора.

Шпаргалка

# a=1; b=a*2; !          вычисления; ! — конец списка присваиваний
#pr текст \G b;\n\E      сформировать текст
#m [op=txt;] \Tp\E       показать последний фрагмент
#rep 5 ... #end          цикл
#case 1 ... #end |       ветка
#pro имя ... @           процедура
#e _имя !                вызов
#ma [op=vic; b=1; le=5;] операция над массивом целиком

Три правила, о которых легко забыть:

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

Реализация на Rust

В проекте есть независимая реализация ядра VKACL — acl-core. Она нужна для двух вещей: чтобы примеры в этой книге запускались в браузере и в терминале, и чтобы поведение языка было зафиксировано проверяемыми тестами, а не только описанием. Заменой интерпретатору автора она не является и не задумывалась.

Что есть

Область Состояние
Разбор потока команд, комментарии, !, @ есть
Вычисления #c, все операции и функции есть
Память: скаляры, двухсимвольные переменные, i(), r(), t(), s() есть
#d, #v, #pas, #p есть
#case, #rep, #end, #go, #%, обработка ошибок есть
#pro, #e, #e _text, #e _file, ##имя есть
Форматированный текст целиком, включая \TpN есть
#pr, #read, #m есть
#ma — операции над массивами есть все, кроме tom (окно прогресса), box (разметка осей графики), smh и rfh (файлы детекторов) и mmi/mcg с записью в файл
#io, #f, #te файловые и текстовые операции есть; графические и сетевые — нет
#sel, #inp, #m, #f [op=edit;], редактор #e _\09 вместо окон — вопросы в консоли
#pf (индикатор хода) пропускается: программе он ничего не возвращает
Номерные суперкоманды ##N из библиотеки автора proc00.txt, если она лежит рядом с программой; без неё — только ##33
Графика #w, #g, #eg, анимация, звук, PDF, архивы нет

Неподдержанная команда не игнорируется: программа останавливается с кодом 900 и названием того, чего не хватает.

Окна становятся вопросами

Команды, открывающие окна выбора и ввода, в терминале задают вопросы:

── Что посчитать? ──
[1] Факториал 7  [2] Сумма 1..100  [3] Выход
> 2

Ответ ложится туда же, куда его кладёт окно в оригинале: номер кнопки — в &, введённые значения — в t() с позиции s(3). Поэтому программы, написанные для окон, работают без изменений. В песочнице ответы берутся из поля под редактором.

Редактор текста (#f [op=edit;]) показывает файл с номерами строк и ждёт одного ответа: Enter — выйти, номер — поставить курсор в начало этой строки и выйти, любой другой текст — дописать его новой строкой. Позиция курсора попадает в s(1), как в оригинале, а изменённый файл при mo=1 сохраняется.

Готовые программы автора в консоли

Суперкоманды автора — обычный код на VKACL в файле proc00.txt. Если программа лежит в папке vkacl из дистрибутива автора, суперкоманды берутся оттуда так же, как их берёт диспетчер оригинала. На этом построен проигрыватель.acl из архива этой книги: скопируйте его в папку vkacl и перетащите на запуск.bat (или наберите в этой папке путь-к-acl.exe проигрыватель.acl). В другом месте он объяснит, что делать, и закончит работу.

Проигрыватель спрашивает номер программы, записывает её код и данные в pro/0.acl и pro/0.par, как это делает кнопка Index в меню автора, и запускает её. Так работает, например, калькулятор №62: редактор показывает строки файла данных, вы выбираете строку с формулами или вводите новую, и программа печатает значения a…h.

Из 79 программ дистрибутива (№80 в нём нет) без ошибок до конца доходят 26, остальные останавливаются на графике, PDF или окнах (ошибка 900). 20 программ сверены с оригиналом, запущенным в пакетном режиме с теми же данными: созданные файлы совпадают байт в байт, а где оригинал останавливается с ошибкой, порт останавливается с той же.

Как проверялась точность

Эталоном служит сам интерпретатор автора. Небольшая обвязка на Java вызывает его напрямую, без окон (сообщения об ошибках она закрывает сама и записывает их текст). Набор программ из corpus/tests/ прогоняется через оригинал, его вывод сохраняется как эталон, и с ним посимвольно сравнивается вывод этой реализации. Совпадает всё: арифметика и приоритеты, все форматы чисел, циклы и ветвления, процедуры, работа с массивами и файлами, операции #ma, функции Бесселя и интегралы Френеля — их приближения перенесены коэффициент в коэффициент.

Где реализация сознательно отличается

При проверке нашлись места, где интерпретатор автора, по-видимому, ошибается — например, печатает 1000 как 1.0000+02 или теряет знак у bj1 от отрицательного аргумента. Каждый такой случай подтверждён запуском. Здесь эти места работают правильно, а подробный список с примерами и предлагаемыми исправлениями передан автору. Для остальных программ разница незаметна.

Запуск из терминала

Готовая программа acl.exe (Windows 10/11, около 600 КБ, без установки):

acl.exe программа.acl

Проще всего — перетащить файл .acl на запуск.bat: окно останется открытым с результатом. Кодировка файла — windows-1251 или UTF-8, определяется сама.

При первом запуске скачанного .exe Windows может показать «Система Windows защитила ваш компьютер»: программа не подписана. Нажмите «Подробнее» → «Выполнить в любом случае».

Сборка из исходников

cargo build --release -p acl-cli
cargo test
cargo build -p acl-wasm --target wasm32-unknown-unknown --release

Модуль WebAssembly обходится без wasm-bindgen и встраивается прямо в страницу песочницы, поэтому она работает и при открытии книги с диска.

↑