INTERCAL
- Дата создания:
- 1972
- Повлиял на:
- Парадигма:
- Типизация:
- Принятые расширения файлов:
- .i
- Реализации и версии (свернуть все | развернуть все):
INTERCAL (полное название — Compiler Language With No Pronounceable Acronym) — один из старейших эзотерических языков программирования.
Он был создан в 1972 году как пародия на языки, существующие в то время, и целенаправленно усложнялся как только возможно; чего стоит один вывод чисел в римской записи! Одна из черт, известных даже людям, которые не программировали на INTERCAL — модификатор PLEASE
, не несущий никакой смысловой нагрузки и призванный исключительно вынудить программиста быть вежливым, но не слишком.
Язык стандартизован в основном его первой реализацией, INTERCAL-72, на совместимость с которой ориентируются последующие реализации. Большинство реализаций привносят в язык что-то свое, будь это альтернативный формат ввода-вывода или элементы квантовых вычислений. Особенности оригинальной реализации (например, случайные ошибки или стилистику сообщений об ошибках) тщательно сохраняются и переносятся в новые реализации.
Элементы синтаксиса:
Комментарий до конца строки | NOTE: ... (игнорируется некоторыми реализациями из-за NOT) |
---|---|
Присваивание значения переменной | DO <variable> <- <value> |
Бесконечный цикл | (1) DO FORGET #1 ... DO (1) NEXT |
Ссылки:
Примеры:
Hello, World!:
Пример для версий C-INTERCAL 28.0, J-INTERCAL 0.11, J-INTERCAL 0.12INTERCAL — один из тех языков, в которых даже вывод “Hello, World!” — пытка. C-INTERCAL использует метод вывода строк под названием лента Тьюринга. На вход команды READ OUT
подается массив чисел (в данном случае ,1
), который обрабатывается слева направо, по одному элементу за раз, следующим образом:
-
8 бит ASCII-кода предыдущего выведенного символа отображаются зеркально —
rev(i)
. Если выводится первый символ,rev(i)
принимается равным 0. -
array(i)
— i-ый элемент массива. -
rev(i) = rev(i-1) -- array(i)
-
Биты
rev(i)
снова отображаются зеркально, и получаем ASCII-код следующего символа для вывода.
Также следует отметить использование модификатора PLEASE
: в этой программе он должен встретиться 4 или 5 раз, в произвольных местах. 3 и меньше вызовут ошибку “ICL079I PROGRAMMER IS INSUFFICIENTLY POLITE”, 6 и больше — “ICL099I PROGRAMMER IS OVERLY POLITE”.
Остальные команды и выражения сравнительно обычны: # — префикс константы, <- — присвоение, SUB — индекс массива. Первая строка примера создает массив 16-битных целых из 13 элементов.
DO ,1 <- #13
PLEASE DO ,1 SUB #1 <- #238
DO ,1 SUB #2 <- #108
DO ,1 SUB #3 <- #112
DO ,1 SUB #4 <- #0
DO ,1 SUB #5 <- #64
DO ,1 SUB #6 <- #194
PLEASE DO ,1 SUB #7 <- #48
DO ,1 SUB #8 <- #26
DO ,1 SUB #9 <- #244
PLEASE DO ,1 SUB #10 <- #168
DO ,1 SUB #11 <- #24
DO ,1 SUB #12 <- #16
DO ,1 SUB #13 <- #162
PLEASE READ OUT ,1
PLEASE GIVE UP
Числа Фибоначчи:
Пример для версий C-INTERCAL 28.0, J-INTERCAL 0.11, J-INTERCAL 0.12Используется итеративное определение чисел Фибоначчи. В переменных .11 и .12 хранятся предыдущее и текущее числа, в .9 — количество остающихся итераций.
Тело цикла довольно простое — напечатать число .11, скопировать .10 и .11 в .1 и .2, сложить их ((1009) NEXT
вызывает сложение из стандартной библиотеки и записывает сумму в .3) и обновить значения. Самая сложная часть программы — код, обеспечивающий циклическое поведение. Вот что он делает:
(3) NEXT
и (4) NEXT
обеспечивают переход на метку (4). Здесь счетчик цикла .9 уменьшается на 1 (вызов (1010)
). После этого .1 вычисляется побитовыми операциями и становится 1, если .9 содержит ненулевое значение, и 0 в противном случае, и затем увеличивается на 1. Наконец, RESUME .1
возвращает выполнение программы к одному из более ранних NEXT
. Если .1 равно 2, программа возвращается на два NEXT
назад и продолжает выполняться с DO (1) NEXT
, возвращаясь к началу тела цикла. Если же .1 равно 1, программа возвращается на один NEXT
назад, продолжает выполняться с PLEASE GIVE UP
и останавливается.
Вывод программы выглядит следующим образом:
I
I
II
III
V
VIII
XIII
XXI
XXXIV
LV
LXXXIX
CXLIV
CCXXXIII
CCCLXXVII
DCX
CMLXXXVII
DO .9 <- #16
DO .10 <- #0
DO .11 <- #1
(1) PLEASE READ OUT .11
DO .1 <- .10
DO .2 <- .11
PLEASE (1009) NEXT
DO .10 <- .11
DO .11 <- .3
DO (3) NEXT
DO (1) NEXT
(3) DO (4) NEXT
PLEASE GIVE UP
(4) DO .1 <- .9
DO .2 <- #1
PLEASE (1010) NEXT
DO .9 <- .3
DO .1 <- '.9~.9'~#1
PLEASE (1020) NEXT
DO RESUME .1
Факториал:
Пример для версий C-INTERCAL 28.0, J-INTERCAL 0.11, J-INTERCAL 0.12Используется итеративное определение факториала. Циклическая часть практически идентична примеру числами Фибоначчи, тело отличается, но незначительно. Отметим использование для переменных факториала и числа префикса :
вместо .
— первый означает 32-битные переменные, второй — 16-битные. Вывод выглядит следующим образом (числа идут парами, n и n!, и каждое число занимает две строки):
_
I
I
I
II
II
III
VI
IV
XXIV
V
CXX
VI
DCCXX
VII
_
VXL
VIII
__
XLCCCXX
IX
_____
CCCLXMMDCCCLXXX
X
___________
MMMDCXXVIIIDCCC
XI
_____
xxxixCMXVIDCCC
XII
cdlxxixMDC
XIII
___
mcmxxxMMLMMMDIV
XIV
_____
mcclxxviiiCMXLVCCLXXX
XV
____
mmivCCCXXVI
XVI
_______
mmivCLXXXIXCLXXXIV
C-INTERCAL использует для вывода римскую запись чисел, черта над знаком умножает его значение на 1000, а запись в нижнем регистре — на 1000000.
DO .9 <- #17
DO :10 <- #0
DO :11 <- #1
DO :2 <- :10
(1) PLEASE READ OUT :10
PLEASE READ OUT :11
DO :1 <- #1
PLEASE (1509) NEXT
DO :10 <- :3
DO :2 <- :10
DO :1 <- :11
PLEASE (1549) NEXT
DO :11 <- :3
DO (3) NEXT
DO (1) NEXT
(3) DO (4) NEXT
PLEASE GIVE UP
(4) DO .1 <- .9
DO .2 <- #1
PLEASE (1010) NEXT
DO .9 <- .3
DO .1 <- '.9~.9'~#1
PLEASE (1020) NEXT
DO RESUME .1
Hello, World!:
Пример для версий CLC-INTERCAL 1.-94.-2CLC-INTERCAL использует механизм текстового ввода-вывода, основанный на кодах Бадо. Это 5-битная кодировка, в которой код каждого символа состоит из двух частей — сдвиг и собственно код. Сдвиг может принимать значения от 1 до 4, переключения между сдвигами делается специальными кодами 31 (из 1|2 в 2 или 3|4 в 1) и 27 (из 1|2 в 3 или из 3|4 в 4). Таким образом, выводящийся массив интерпретируется как последовательность кодов символов и переключателей сдвига. Массив обычно длиннее, чем сообщение, из-за переключателей сдвига.
В этом примере, сообщение начинается с H, код Бадо “1 0x14”. Изначально сдвиг равен 1, его менять не нужно, поэтому первый элемент массива — код символа 20. Следующий символ — e, код Бадо “2 0x01”, приходится переключаться на сдвиг 2 (код 31) и только потом печатать символ (код 1), и т.д.
Следует отметить, что CLC-INTERCAL не слишком беспокоится о вежливости программиста: этот пример работает с гораздо меньшим количеством PLEASE
, чем потребовал бы C-INTERCAL.
DO ,1 <- #18
DO ,1 SUB #1 <- #20
DO ,1 SUB #2 <- #31
DO ,1 SUB #3 <- #1
DO ,1 SUB #4 <- #19
DO ,1 SUB #5 <- #19
DO ,1 SUB #6 <- #24
DO ,1 SUB #7 <- #27
DO ,1 SUB #8 <- #12
DO ,1 SUB #9 <- #4
DO ,1 SUB #10 <- #31
DO ,1 SUB #11 <- #18
DO ,1 SUB #12 <- #31
DO ,1 SUB #13 <- #24
DO ,1 SUB #14 <- #10
DO ,1 SUB #15 <- #19
DO ,1 SUB #16 <- #9
DO ,1 SUB #17 <- #27
DO ,1 SUB #18 <- #13
PLEASE READ OUT ,1
PLEASE GIVE UP
Комментарии
]]>blog comments powered by Disqus
]]>