99 бутылок: Parrot, OW-BASIC
33. OW-BASIC — наиболее популярный, среди пользователей PV-S450, диалектов языка BASIC. Ему присущи все основные черты небольших современных интерпретаторов этого языка — наличие процедур с локальными параметрами и параметрами по указателю, блочные конструкции, функции работы со строками и отсутствие необходимости нумеровать строки.
Конечно, в силу специфики железа, на котором этот интерпретатор работает есть и весьма специфические для этой платформы функции, например, проверка касания экрана, вывод встроенной графики и тому подобное. К сожалению, в интерпретаторе есть ряд весьма досадных багов, например, сбой при выходе за край экрана и местами довольно бедная диагностика ошибок.
Программа, выводящая песню о пиве (! beer)
! beer
! Beer song. Written by Evgeny Stepanischev
PROC beer i, VAR s$
IF i>0 THEN
s = STRING(i)
ELSE
s = "No"
ENDIF
s = s+" bottle"
IF i<>1 THEN
s = s+"s"
ENDIF
s = s+" of beer"
ENDP
FOR i=0 TO 98
beer 99-i, s$
? s;" on the wall, ";s;"."
? "Take one and pass around,"
beer 98-i, s
? s;" on the wall.":? ""
NEXT
? "": ? "No more bottles of beer..."
? "Go to the store and buy some more..."
? "99 bottles of beer."
32. Parrot. Очень молодой, его первый компилятор в байт-коды появился 10 сентября (дело происходило в 2001 году — более позднее примечание), язык виртуальной машины для интерпретируемых языков. Насколько я понимаю, разрабатывался специально для Perl6.
Язык по базовым конструкциям беднее ассемблера — нет ни одной конструкции цикла, все они заменяются условными переходами, ограниченное количество переменных (по 32 на каждый тип переменной), зато есть поддержка функций (параметры передаются через стек), операций с файлами, операторов ввода-вывода и так далее. Поскольку интерпретатору около месяца, диагностика ошибок еще весьма бедная, иногда единственное сообщение, которое получаешь на экран — «Segmentation fault». :)
Скрипт, выводящий песню о пиве (beer.pasm)
# Beer song. Written by Evgeny Stepanischev
set I1, 99
branch MAIN
beer: if I1, _NZERO
print "No"
branch _I1_EL
_NZERO: print I1
_I1_EL: print " bottle"
eq I1, 1, _NO_S
print "s"
_NO_S: ret
MAIN: bsr beer
print " of beer on the wall, "
bsr beer
print " of beer."
print "\nTake one and pass around,\n"
dec I1
bsr beer
print " on the wall.\n\n"
if I1, MAIN
print "No more bottles of beer...\n"
print "Go to the store and buy some more...\n"
print "99 bottles of beer.\n"
end