99 бутылок: AkRScript
В полку странных языков программирования, на которых я писал «песню о пиве», прибыло.
84. AkRScript — самодельный скриптовый язык программирования, написанный в середине десятых годов владельцем телеграм-канала «Notes from the Dark Side of the Moon», когда он ещё был школьником.
Он его оживил в эмуляторе и выложил несколько программ, написанных на AkRScript, что и позволило мне разобраться в том как этот язык устроен.
Синтаксис, как это часто бывает у самодельных языков, совершенно вырвиглазный. Зато есть все основные примитивные типы данных — строка, число, массив, хеш и даже лямбды. Программирование процедурное, функции возможны только в виде лямбд. У меня в коде тоже есть одна такая, её легко узнать — они всегда начинаются с тильды и заканчиваются обратным апострофом; параметры передаются подстановками $A1, $A2 и так далее.
Процедуры можно описывать двумя способами — через ключевое слово subp и при помощи subp opcode. Отличия существенные — обычную процедуру приходится вызывать через оператор csp, а опкод вызывается как оператор. Кроме того, в обычную процедуру параметры передаются через глобальные переменные, тогда как опкод может получать их через стек, снимая с него значения оператором pop.
Дополнено: автор написал, что процедуры, вызываемые через csp тоже, вроде бы, могут забирать параметры через pop. Звучит логично, но проверять это я уже не буду.
Параметры передаются через пробел, включая выражения, которые должны обрамляться обратными апострофами. Кое-где слова я не брал в кавычки, воспользовавшись тем, что вместо несуществующих переменных подставляется их имя.
С пробелами у языка сложные отношения — в параметрах они могут срезаться даже внутри строк, поэтому, чтобы не мучиться с ними, я завёл себе переменную sp, куда поместил неразрывный пробел и расставлял его везде, где сталкивался с трудностями.
-- "99 Bottles of Beer," written in AkrScript on August 9, 2025
-- by Evgeny Stepanishchev (https://bolknote.ru)
clrs
-- тут в скобках стоит неразрывный пробел (код 0xA0)
assign sp " "
subp opcode plural
assign _s s
assign _b `pop`
chk `cmp b 1` ~assign _s ""`
cno b ~assign _b No`
assign out `add _b sp bottle _s sp "of beer"`
mkill "_s"
mkill "_b"
ret
assign b 99
plural b
whi `gt b 0`
prnt out sp "on the wall, " out "!"
prnt "Take one down, pass it around,"
assign b `sub b 1`
plural b
prnt out sp "on the wall!"
prnt
ret
prnt "No more bottles of beer on the wall, no more bottles of beer."
prnt "Go to the store and buy some more, 99 bottles of beer on the wall."