]]> ]]>
Править | Обсудить | История

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.12

INTERCAL — один из тех языков, в которых даже вывод “Hello, World!” — пытка. C-INTERCAL использует метод вывода строк под названием лента Тьюринга. На вход команды READ OUT подается массив чисел (в данном случае ,1), который обрабатывается слева направо, по одному элементу за раз, следующим образом:

  1. 8 бит ASCII-кода предыдущего выведенного символа отображаются зеркально — rev(i). Если выводится первый символ, rev(i) принимается равным 0.
  2. array(i) — i-ый элемент массива.
  3. rev(i) = rev(i-1) -- array(i)
  4. Биты 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.-2

CLC-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

]]>

Работа программистам