bolk (bolk) wrote,
bolk
bolk

Особенность языка Postscript

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

Единственная конструкция, которая должна смущать, это место, где происходит печать числа:

% печать числа
//=string cvs print

Дело в том, что операторы show и print, принимают на вход только строку, поэтому число на входе надо преобразовать. Для этого используется оператор csv, на мой взгляд очень странный — он требует не один, как можно было бы ожидать, а два параметра — число, которое будет преобразовано и строку, которую оператор снимет со стека и положит вместо неё преобразованное в строку число. Причём по размеру строка должна быть не короче, чем строковое представление числа, которое мы надеемся преобразовать. Иначе мы получим ошибку «rangecheck». Видимо строковый параметр используется как какой-то буфер.

Чаще всего cvs используется так (правда это прямо запрещено
стилем кодирования Постскрипта, рекомендуется использовать не готовую строку, а формировать пустую строку оператором string, но всё равно широко встречается):

% печать числа 42
42 (  ) cvs print

Кладём на стек «42», потом строку из двух пробелов (скобки задают строку в Постскрипте), далее вызываем cvs, которая берёт со стека два значения, работает с ними и кладёт обратно строку, содержащую преобразованное число, print берёт значение со стека и выводит в консоль.

Но если места нужно много, нередко используют оператор =string, который кладёт на стек буфер в 128 байт, его хватит всем — таких больших числе в языке нет, любое гарантированно поместится:

% печать числа 10000000000, cvi нужно, чтобы преобразовать плавающее 1e+10 в целое
1e+10 cvi =string cvs print

Пока, надеюсь, всё просто и понятно. Далее надо знать такую вещь. Конструкция «{…}» кладёт на стек специальный тип — исполняемый блок, посмотрим как он выглядит на стеке:

% посмотрим как выглядит исполняемый блок на стеке:
{1e+10 cvi =string cvs print} ==
% выведет {1e+10 cvi =string cvs print}

Оператор «два равно» берёт значение со стека и выводит его на экран. Как видим блок попал на стек в неизменном виде. И вот тут можно сделать микрооптимизацию — если этот кусок кода кладётся не на стек, а в словарь (можно считать, что будет создана именованная функция) и мы рассчитываем вызвать его несколько раз, вызов =string можно сразу раскрыть в строку — это делается двумя слешами.

Два слеша — специальная конструкция, которая похожа на вызов анонимной функции по месту определения, в данном случае мы выполняем ровно один оператор и на стеке внутри блока кода мы увидим не вызов, а порождённую им строку:

{1e+10 cvi //=string cvs print} ==
% выведет {1e+10 cvi (x255Unicode\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000...) cvs print}


Ссылка на оригинал.
Subscribe

  • Тарелки на берегу

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

  • «Ночной пылесос»

    Дочка, как наверное вообще все дети, не очень-то любит убираться в своей комнате. И чтобы заставить её перед сном навести хотя бы косметический…

  • Ортопедические стельки

    В своих поисках того как можно облегчить состояние травмированной когда-то на спортивной гимнастике спине, забрёл к ортопеду. Я подозревал, что…

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments