]]> ]]>

C-INTERCAL

Реализация языка программирования INTERCAL

C-INTERCAL — поддерживаемая версия INTERCAL, написанная на C и распространяемая под лицензией GNU GPLv2.

Компилятор C-INTERCAL называется ick и запускается из командной строки. По умолчанию он компилирует заданный файл в исполняемый того же названия. Опции вызова позволяют использовать синтаксис других популярных реализаций, исключить некоторые ошибки компиляции, использовать многопоточность и вычисления с откатами, настраивать отладку и т.д.

C-INTERCAL добавляет альтернативный метод ввода-вывода под названием ленты Тьюринга. Он использует в качестве аргумента массив, а не скалярную переменную, и основан на бинарных кодах символов и их разностях.

Примеры:

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

Комментарии

]]>

blog comments powered by Disqus

]]>

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