17. СПЕЦИАЛЬНЫЕ СИТУАЦИИ

В этом разделе мы рассмотрим некоторые специальные приемы программирования, реализованные в ACL. Как правило, описанные здесь команды не имеют прямых аналогов в других языках, хотя в несколько измененном виде они все же реализуются в интерпретируемых языках типа постскрипта. Первая специальная команда уже обсуждалась в самом начале, но с другим смыслом. Это очень короткая команда

 #%

Она делает особую метку в тексте программы. А именно, она записывает в переменную [%] номер байта (символа) в тексте программы, где она сама записана, а точнее номер символа [%] + 2. Это целое число может служить меткой текста программы сразу после этой команды. Эту метку можно использовать в различных целях. В частности, есть возможность перевести курсор сканирования текста программы на это место. Перенос позиции, с которой сканируется текст программы выполняет команда #goto, а короче

 #go N

Это команда безусловного перехода. В старых языках программирования она была очень популярна. Однако современные языки или не содержат ее совсем или имеют, но советуют не использовать. Аналогично в языке ACL. Нет никакой необходимости использовать эту команду, потому что все можно сделать без нее. И я сам ее не использую. Кроме того, чтобы сделать переход нужно иметь позицию куда следует переходить, а в языке ACL метки отсутствуют. Поэтому аргументом N команды является абсолютная позиция символа текста программы, отсчитываемая от ее начала. Это может быть целое число или буква с целым значением, включая [$],[%],[&].

Конечно, считать символы очень трудно. Но как раз команда #% показывает позицию сразу за собой в переменной [%], и это может быть использовано для создания меток. Разные позиции могут быть определены заранее и сохранены в элементах массивов, а затем использованы для перехода. Переход может быть сделан не только назад, но и вперед. В этом случае пользователь при отладке программы должен сначала напечатать позиции, а затем их использовать. Эта команда, в принципе, может быть использована в очень сложных интерактивных программах для реализации трудных ситуаций, в частности для обработки ошибок ввода в программах типа калькулятора. Эта программа будет рассмотрена в главе 23. Следующую команду

 #ini

мы уже обсуждали в разделе про анимацию. Ее назначение -- восстановить нормальную работу циклов и выключить аудио-плейеры. Нарушить нормальную работу циклов, то есть блокировать возврат курсора в циклах можно разными способами. Во-первых, это происходит при закрытии окна анимации. Во-вторых, то же самое происходит при выборе в меню отладчика раздела (Exec // Stop execution). Этот полезно, если в программе нечаянно образовался бесконечный цикл. В новых версиях программы могут появиться и другие способы.

.

Следующая команда #robot или короче #rob. Первоначально эта команда была задумана для того, чтобы позволить программисту имитировать действия пользователя в тех случаях, когда нормальная работа программы ждет реакции от пользователя. Она использовала Java class Robot и была способна нажимать клавиши клавиатуры, двигать мышь и кликать кнопки. Однако для успешной работы этой программы Java VМ должна быть установлена с расширением XTEST. Как оказалось, в тех случаях, когда это расширение не установлено, программа вообще не может работать, даже если и не пользоваться данной командой. Расширение XTEST обычно не ставят в многопользовательских системах, типа UNIX.

Так как мне не удалось преодолеть эту проблему, я ликвидировал эти способности в программе интерпретатора, поскольку по большому счету они не нужны. Но для совместимости с уже написанным ACL кодом, я оставил название команды и те функции, которые могут быть сделаны другим способом, то есть без использования XTEST. На момент написания этого текста команда имеет 4 функции, различающиеся параметром [mo], а не параметром [op]. Первая использует дополнительный параметр

 #rob [mo=1; le=N;]

Эта функция реализует принудительную остановку работы программы на N миллисекунд. Вместо N может быть любая переменная, число, элемент массива или их комбинация вместе с знаками математических операций. Параметр mo=1 указывает на операцию. Вторая без дополнительных параметров

 #rob [mo=2;]

Эта функция блокирует закрытие окна терминала после окончания работы программы. Стандартно при выполнении ACL программы открывается окно терминала, при первой печати в это окно, в котором печатаются временные сообщения о работе программы. После окончания ACL программы окно терминала автоматически закрывается. Однако, если в ACL программе выполняется данная команда, то окно терминала остается открытым и его надо закрывать вручную. Третья функция использует много дополнительных параметров

 #rob [mo=3; n=; xs=; ys=; wid=; hei=;]

Эта функция спасает часть экрана во внутренюю картинку с заданным номером. Часть экрана имеет заданную ширину, высоту и смешение. Наконец, четвертая функция выдает цвет пиксела на экране с заданными координатами. Цвет выдается в параметры с номерами 1, 2, 3, которые не имеют имен, а вызов такой

 #rob [mo=4; xs=; ys=;]

Две последние функции существенно расширяют возможности языка по анализу картинок, которые показываются на экране.

Следующая специальная команда называется #system или короче #sys. Она позволяет программисту выполнить некоторые системно-зависящие операции. Работу этой команды следует проверить в каждой операционной системе отдельно. При успехе эта команда позволяет программисту существенно усилить возможности ACL-программирования. В данной интерпретатора имеется три операции этой команды. Первые две операции используют показания компьютерных (системных) часов. Допустим вам необходимо узнать сколько времени будет работать ваша очень сложная программа, обрабатывающая 555 картинок. Операцией

.

 #sys [op=st;]

вы запускаете системные часы на компьютере (st = set time). Реально программа считывает время с компьютерных часов и запоминает. Затем вы делаете обработку одной картинки и после этого запускаете вторую операцию

.

 #sys [op=gt;]

в момент выполнения которой показания часов считываются еще раз и разность времен между выполнением первой и второй операций вам записывается в переменную [$] в секундах, но точность часов миллисекунды, то есть можно смотреть число с тремя десятичными знаками (gt = get time) . Все работает так, как будто вы дали отмашку бегуну и включили секундомер, а в момент финиша выключили. И смотрите время, которое секундомер показывает в переменной [$]. Вам остается просто прочитать это число и умножить его на 555. Таким образом вы узнаете сколько часов будет работать ваша программа еще до того, как она начнет работать. Эту пару команд также можно использовать для остановки программы на определенное время, аналогично команде #rob. Можно найти и другие применения.

.

Третья операция более сложная. Она позволяет выполнить другую исполняемую программу прямо из ACL программы. То есть речь идет о программе, написанной на другом языке программирования, например, Java или Fortran или любом другом из сотен разных языков. Допустим у вас на компьютере есть другие программы, которые вы скачали из интернета. Вот я скачал программу TetColor.exe - это такая игра. И допустим я ее хочу запустить прямо из ACL-программы, то есть сделать на ACL менеджер файлов типа того, что есть в любой операционной системе. Операция op=rp (run program) как раз и запускает внешнюю программу.

Но я сделал команду с ограничением. А именно, внешняя программа запускается только в том случае, если она находится в главной папке, то есть в той же папке, что и интерпретатор. Более того, делается проверка на наличие файла, и если файла нет, то выдается ошибка. Это формально ограничивает возможности команды. Допустим, моя программа TetСolor.exe у меня установлена в отдельной папке по такому пути

 C:\Program Files\Tetcolor\TetColor.exe

а интерпретатор вообще на диске D. Как быть? Решение все таки есть. Одно из решений проблемы в ОС Windows такое. В главной папке записать файл с названием "runpro.bat" и с таким содержанием

 C:
 cd "Program Files"\Tetcolor
 TetColor.exe

а в ACL программе записать такую команду

 #sys [op=rp; file=runpro.bat;]

Все файлы с расширением ".bat" операционная система Windows рассматривает как командные файлы, то есть исполняемые как и программы. И операция rp команды #sys их тоже выполняет команду за командой. Что касается системы UNIX, то в ней надо этому файлу присвоить атрибут исполняемого файла. Команды операционной системы необходимо выучить в другом месте. Это выходит за рамки данного курса. Я могу порекомендовать собственную статью . В нашем bat-файле (так они называются) используется переход на диск C командой C:, затем тривиальная команда cd (change directory) просто меняет папку на более внутреннюю по отношению к головной папке. Если в названии есть пробел, его надо ставить в кавычки. А название программы (exe файла) на следующей строке просто запускает файл. Обратите внимание, что папки в Windows разделяются символом "\", а в Java - символом "/", так как язык Java был продуктом фирмы Sun Microsystems, а она делала как в UNIX. В ACL как в Java. В таком виде программа прекрасно запускается. Файл "runpro.bat" можно записать заранее (вручную). Можно даже записать много таких файлов. А можно формировать этот файл в процессе выполнения самой ACL программы перед его использованием данной командой. Это позволяет обойти указанное выше ограничение и запускать любую программу на компьютере и с аргументом. Можно делать и намного более сложные bat-файлы.

Но все так хорошо, когда после этой команды стоит, например, команда #stop. Если же команда #stop не стоит, а дальше есть еще ACL код, то ситуация сложнее. Еще сложнее если последующий ACL код нуждается в результатах расчета по внешней программе. Тогда ACL-программа должна ждать, когда закончит работу внешняя программа и только после этого продолжать работу. То есть надо как-то остановить ACL программу. Есть два способа. Либо вызвать команду диалога, которая сама ждет реакции пользователя, типа

 #m [op=win;] Подождите минуту\E

Тогда ACL программа будет ждать пока вы не нажмете [OK]. Это не всегда быстро, если внешняя программа работает быстро. Второй способ -- сделать паузу на время. Можно делать много пауз, тут есть разные варианты. Паузу делает команда #rob как было показано в разделе про анимацию. Хотя на ACL можно вычислить все на свете, но есть две причины, по которым разумно сделать программу на другом языке программирования, а в ACL только использовать ее результаты. Первая причина -- у вас уже была написана программа и она хорошо работает. Зачем вам все переписывать на ACL. Вторая причина -- вам нужно очень сложный расчет сделать быстро. Тогда ACL не годится, так как он не очень быстрый, ведь команды интерпретируются. Для этой цели надо программировать на языках C, Fortran или на Java, если все аккуратно написать. Сюда же относятся программы показа кино, прослушивания музыки и так далее.

Режим работы с bat-файлом не имеет ограничений. Можно запускать программу с аргументом и даже цепочку программ одну за другой. Но записывать bat-файлы заранее не всегда интересно, а записывать динамический bat-файл -- не всегда так быстро, как хочется. В современной версии языка есть другой вариант. Если [file=arg;] то запускаемый файл записывается аргументом команды, а не через параметр [file]. При этом проверка на наличие файла не проводится, то есть реально вместо файла может быть командная строка в виде программы с аргументами, она вообще может иметь любую структуру. Такой вариант работает быстрее и устойчивее. На его основе можно написать менеджер файлов для работы со всей файловой системой компьютера. Однако сказанное выше об остановке работы ACL программы на некоторое время после этой команды остается в силе. Запуск внешней программы делается в другом потоке и чтобы он запустился надо остановить основной поток.

Есть не только специальные команды, но и специальные параметры. Таким параметром является параметр

 [err]

эквивалентный s(26). Этот параметр регулирует режим работы интерпретатора по обработке ошибок в коде программы. Изначально s(26)=0 и можно всегда работать не меняя его значения. В этом случае ошибки в тексте программы будут приводить к появлению сообщения об ошибке и остановке программы. Программист обязан исправить ошибку и запустить программу снова. Но так не всегда удобно. Если программой пользуется человек, не знающий языка ACL, то он не сможет исправить ошибку. Кроме того, могут быть элементарные опечатки при вводе текста в окна ввода. То есть желательно иметь режим, в котором сама ACL программа обрабатывает возможные ошибки своего кода. Такой режим возникает, если параметр s(26) переопределен, например, s(26)=1. В этом случае при возникновении ошибки продолжение будет другим. Сообщение об ошибке не появится, переменной [&] будет присвоено значение 10101 и программа сделает безусловный переход на позицию (то есть номер символа текста программы), которая задается переменной [%]. Эта переменная может быть определена предварительно командой #% и просто математической операцией.