﻿# Первый взгляд на RPG: оказывается, это не только ролевые игры

Многие из вас слышали об одном из старейших языков программирования COBOL, а также о том, что как сильно сейчас нужны COBOL\-программисты для поддержки старого кода\. Существует еще один "старожил", о котором знают немногие, который используется сейчас и будет использоваться еще достаточно долгое время для написания программ в различных сферах человеческой деятельности \(финансовой, банковской и др\.\)\. Имя этому языку \- IBM RPG\.

![0548_IBM_RPG_ru/image1.png](https://import.viva64.com/docx/blog/0548_IBM_RPG_ru/image1.png)

## Once upon a time\.\.\.

**RPG** \- проприетарный язык программирования высокого уровня, являющийся собственностью корпорации IBM, для создания бизнес\-приложений\. Последние версии языка доступны только для операционной системы IBM i \(и ее прошлых версий под старым названием OS/400\)\.

У RPG более чем полувековая история\. К концу 50\-х IBM выпустила огромное количество электромеханических машин, называемых табуляторами\. Последним серийным табулятором стала модель IBM 407 Accounting Machine:

![0548_IBM_RPG_ru/image2.png](https://import.viva64.com/docx/blog/0548_IBM_RPG_ru/image2.png)

Рисунок 1\. IBM 407 в Арсенале армии США в 1961 году\.

К слову, аренда такого табулятора в зависимости от модели стоила от $800 до $920 в месяц \(в перерасчете на современный доллар \- от $8100 до $9300\), а прекращена их продажа была 17 декабря 1976 года\.

Как известно, технический прогресс не стоял на месте, и к концу 50\-ых годов стали появляться транзисторные компьютеры\. Первым таким компьютером для IBM стал IBM 1401, вышедший в 1959 году:

![0548_IBM_RPG_ru/image3.png](https://import.viva64.com/docx/blog/0548_IBM_RPG_ru/image3.png)

Рисунок 2\. IBM 1401 в Центре истории и наследия Эндикотта\.

В Музее компьютерной истории находится вполне рабочий экземпляр, я думаю, вам будет интересно посмотреть, как все это работало \(особенно "доставляют" слова "_We need a little bit of cooling_" на [4:41](https://youtu.be/PwftXqJu8hs?t=4m41s)\):

<https://www.youtube.com/watch?v=PwftXqJu8hs>

Для упрощения перехода своих клиентов на новые транзисторные компьютеры в 1959 году также были придуманы сразу два инструмента, имитирующие процесс обработки перфокарт на компьютере \- FARGO \(Fourteen\-o\-one Automatic Report Generation Operation\) и RPG \(Report Program Generator\)\. Синтаксис обоих языков был схож с командным языком электромеханических табуляторов\. Кроме этого, FARGO и RPG повторяли важную особенность табуляторов: они эмулировали их циклический режим работы \(программный цикл\), во время которого табуляторы считывали данные с перфокарт, суммировали их и печатали результаты\. IBM и на сегодняшний момент обеспечивает обратную совместимость с программным циклом даже в последнем диалекте RPG IV\.

Хоть RPG и создавался под влиянием FARGO, уже через несколько лет RPG вытеснил своего предшественника как более перспективный вариант\. А следующей системой, куда "подвезли" RPG, был мейнфрейм IBM System/360 Model 20:

![0548_IBM_RPG_ru/image4.png](https://import.viva64.com/docx/blog/0548_IBM_RPG_ru/image4.png)

Рисунок 3\. IBM System/360 Model 20 в Немецком музее\.

А уже через пару лет \(конец 60\-ых\) IBM предоставляет следующий диалект языка \- RPG II \- для среднего компьютера System/3:

![0548_IBM_RPG_ru/image5.png](https://import.viva64.com/docx/blog/0548_IBM_RPG_ru/image5.png)

Рисунок 4\. Средний компьютер IBM System/3 Model 10 с оператором\.

С тех пор RPG развился в высокоуровневый аналог языков COBOL и PL/I\. Отличительной особенностью языка \(по сравнению с современными\) являлся "фиксированный формат" синтаксиса, затруднявшим чтение программ без специального отладочного шаблона\.

![0548_IBM_RPG_ru/image7.png](https://import.viva64.com/docx/blog/0548_IBM_RPG_ru/image7.png)

Рисунок 5\. Отладочный шаблон \(нажмите на картинку для увеличения\)\.

Программы начинались со _спецификаций файлов_ \(File Specifications\) \- списка всех файлов, подлежащих чтению, записи или обновлению\. За ними шли _спецификации определений данных_ \(Data Definition Specifications\) \- список элементов программы, таких как структуры данных или массивы\. Этот блок напоминает секцию рабочей памяти \(Working\-Storage\) в языке COBOL или команды с ключевым словом "var" в Паскале\. Для указания типа переменной в колонку 40 спецификации определений записывается соответствующий символ \(см\. таблицу ниже\)\. Если он опущен, т\.е\. вместо него стоит пробел, то типом по умолчанию будет _**A**_ при условии, что не заданы десятичные разряды\. В противном случае типом по умолчанию будет _**P**_\.

|Тип данных|Название|Длина|Описание|
|---|---|---|---|
|\\\*|Указатель на базированную переменную<br>Указатель на процедуру<br>Системный указатель|16 байт|Обращение к данным<br>Обращение к активированной процедуре<br>Обращение к объектному файлу|
|A|Буквенно\\\-цифровой символ|От 1 до 16 773 104 байт \\\(фиксированная длина\\\)<br>От 1 до 16 773 100 байт \\\(переменная длина\\\)|Буква или цифра|
|B|Двоичное число|1 байт \\\(8\\\-бит\\\)<br>2 байт \\\(16\\\-бит\\\)<br>4 байт \\\(32\\\-бит\\\)<br>8 байт \\\(64\\\-бит\\\)|Двоичное целое число со знаком|
|C|Символ в кодировке UCS\\\-2|От 1 до 8 386 552 символов \\\(фиксированная длина\\\)<br>От 1 до 8 386 550 символов \\\(переменная длина\\\)|16\\\-битный символ в кодировке UCS\\\-2 \\\(набор символов DBCS или EGCS\\\)|
|D|Дата|10 байт|Дата: год, месяц, день|
|F|Число с плавающей точкой|4 байт \\\(32\\\-бит\\\)<br>8 байт \\\(64\\\-бит\\\)|Двоичное вещественное число с плавающей точкой, со знаком|
|G|Графический символ|От 1 до 8 386 552 символов \\\(фиксированная длина\\\)<br>от 1 до 8 386 550 символов \\\(переменная длина\\\)|16\\\-битный графический символ \\\(набор символов DBCS или EGCS\\\)|
|I|Целое число|1 байт \\\(8\\\-бит\\\)<br>2 байт \\\(16\\\-бит\\\)<br>4 байт \\\(32\\\-бит\\\)<br>8 байт \\\(64\\\-бит\\\)|Двоичное целое число со знаком|
|N|Индикатор символа|1 байт|'1' \\\= TRUE<br>'0' \\\= FALSE|
|O|Объектный файл|Размер неизвестен|Ссылка на объектный файл|
|P|Упакованное десятичное число|От 1 до 63 цифр,<br>по 2 цифры на байт плюс знак|Десятичное число с фиксированной точкой, со знаком, с целой и дробной частями|
|S|Распакованное десятичное число|От 1 до 63 цифр,<br>по 1 цифре на байт|Десятичное число с фиксированной точкой, со знаком, с целой и дробной частями|
|T|Время|8 байт|Время: час, минута, секунда|
|U|Целое число|1 байт \\\(8\\\-бит\\\)<br>2 байт \\\(16\\\-бит\\\)<br>4 байт \\\(32\\\-бит\\\)<br>8 байт \\\(64\\\-бит\\\)|Целое число без знака|
|Z|Метка времени|26 байт|Дата и время: год, месяц, день, час, минута, секунда, микросекунды|

Далее указывались _спецификации вычислений_ \(Calculation Specifications\) \- список команд для исполнения\. Также могли добавляться _спецификации вывода_ \(Output Specifications\), определяющие вид выходных файлов или отчетов\. 

Приведу также дополнительную информацию о всех типах спецификаций:

* U \- спецификация автоотчета \(Auto Report\), требуется только для программ с автогенерируемым отчетом\.
* H \- спецификация заголовков \(Header\), служит началом программы и описывает такие опции компилятора, как максимальный размер объектного кода, листинг компиляции, а также флаг поддержки доступа с нескольких терминалов \(Multiple Requestor Terminal, MRT\)\. Имя объектной программы записывается в колонки 75\-80; если спецификация заголовков отсутствует, используется имя по умолчанию RPGOBJ\.
* F \- спецификации файлов \(File\)\. Здесь описываются файлы, используемые в программе\. Это могут быть как файлы на диске \(DISK\), так и устройства, такие как принтер \(PRINTER\), рабочая станция \(WORKSTN\), клавиатура \(KEYBORD\), неформатируемый дисплей \(CRT или DISPLAY\) либо пользовательское устройство \(SPECIAL\)\. Здесь же описывается размер записей и блоков, индикаторы переполнения и  внешние индикаторы\. Спецификации F могут отсутствовать\.
* E \- спецификации расширений \(Extension\), описывают массивы и таблицы, предварительно извлекаемые из файлов на диске \(таблицы ввода\) или констант в конце исходного кода между символами \*\* и /\* либо собираемые по итогам вычислений\.
* L \- спецификации счетчика строк \(Line Counter\)\. Если присутствуют, то описывают формат вывода на печать: количество строк на странице и границы начала и конца печати\.
* I \- спецификации ввода \(Input\): описывают области данных внутри файлов\. RPG II разрешает переопределять области данных, так что поле FLDA может занимать ту же область, что и массив AR, содержащий 8 односимвольных элементов\. Здесь же могут описываться области, не являющиеся записями, например, структуры данных\. Индикаторы могут использоваться в условиях, зависящих от значений входящей записи\.
* C \- спецификации вычислений \(Calculation\)\. Здесь описываются и наращиваются поля для итоговых результатов\. Над ними можно проводить сложные вычисления и операции со строками\. Индикаторы могут использоваться в условиях\.
* O \- спецификации вывода \(Output\), которые описывают поля и границы выходящей записи\.

А теперь небольшой пример для разминки ваших глаз \(опущены спецификации файлов и определений данных\):

```cpp
      * Звездочка (*) в колонке 7 определяет строку-комментарий

      * В колонке 6 пишется спецификация одним символом. Определяет,
      * что будет происходить в строке (например, раздел объявлений,
      * раздел вычислений, ...).
      * Спецификация "C" (calculation) - вычисление
     C        HOURS     IFLE 40
     C        HOURS     MULT RATE      PAY
     C                  ELSE
     C        RATE      MULT 40        PAY     72
     C        HOURS     SUB  40        OTIME   30
     C        RATE      MULT 1.5       OTRATE  94
     C        OTRATE    MULT OTIME     OTPAY   72
     C                  ADD  OTPAY     PAY
     C                  END
```

Код сложен для восприятия, не правда ли? А здесь всего лишь производится расчет налога на заработную плату для сотрудника с почасовой оплатой труда \(работники, переработавшие 40 часов, получают полуторную ставку\)\.

В 1978 году IBM представляет одновременно средний компьютер System/38 и новый диалект языка \- RPG III \- для него:

![0548_IBM_RPG_ru/image8.png](https://import.viva64.com/docx/blog/0548_IBM_RPG_ru/image8.png)

Рисунок 6\. Средний компьютер IBM System/38

С этого момента ограничения языка несколько ослабляются и разрешается писать спецификации вычислений в "свободном формате":

```cpp
      /free
        If Hours <= 40;                     
          Pay = Hours * Rate;                  
        Else;                          
          Pay = (40 * Rate) + ((Hours - 40) * (Rate * 1.5));         
        EndIf;
      /end-free
```

И, наконец, последняя версия диалекта \- RPG IV \(иначе RPGLE, ILE RPG\) \- вышла в 1994 году\. Тремя основными "фичами" можно назвать встроенные функции, процедуры и "свободный формат" программирования\. До ноября 2013 года свободный формат был доступен только для спецификаций вычислений\. В обновлении V7R1 TR7 команды "/free" и "/end\-free" были упразднены, а язык наконец\-то освободился от наследия эпохи перфокарт\.

Сам же язык широко используется сейчас под ОС IBM i на аппаратной платформе IBM Power i:

![0548_IBM_RPG_ru/image9.png](https://import.viva64.com/docx/blog/0548_IBM_RPG_ru/image9.png)

Рисунок 7\. Линейка серверов IBM Power i

В общей сложности, язык RPG успел побывать на таких компьютерах, как 1401, System/360, System/3, System/32, System/34, System/36, System/38, AS/400 и System i\. Имелись и реализации для платформ Digital VAX, Sperry Univac BC/7, Univac system 80, Siemens BS2000, Burroughs B700, B1700, Hewlett Packard HP3000, серии ICL 2900, Honeywell 6220 и 2020, серий Four\-Phase IV/70 и IV/90, Singer System 10 и WANG VS, а также разнообразные компиляторы и среды исполнения для Unix\-систем, например, Infinite36 \(бывшая Unibol 36\), и PC \(Baby/400, Lattice\-RPG\)\.

К настоящему времени язык RPG развился в сильный, жизнеспособный язык\. Программы можно по\-прежнему писать в обычном редакторе в черно\-зеленой гамме \(green\-screen\):

![0548_IBM_RPG_ru/image10.png](https://import.viva64.com/docx/blog/0548_IBM_RPG_ru/image10.png)

Рисунок 8\. Green\-screen\.

Однако появилось и множество других инструментов\. Среди них \- Visual Age для RPG, разработанные IBM и продвигаемые Джоном Пэрисом \(Jon Paris\) и другими\. Наиболее популярным редактором на данный момент является IBM Websphere Development Studio, позднее переименованный в RDi \(Rational Developer for i\), являющийся пользовательской реализацией Eclipse:

![0548_IBM_RPG_ru/image11.png](https://import.viva64.com/docx/blog/0548_IBM_RPG_ru/image11.png)

Рисунок 9\. Rational Developer for i\.

Также компилятор RPG реализован для платформы Microsoft \.NET\. Помимо базовой версии в него входят дополнительные расширения языка RPG IV, что позволяет Microsoft Windows и \.NET пользоваться окружением Native и System/36, а также портировать файлы DB/2 в базы данных Microsoft Access и Microsoft SQL Server через интерфейс ODBC\.

## Заключение

Хоть язык и представляет собой экзотику, мы понимаем, что на нем написано много кода для финансовой, банковской и других видов деятельности\. Он достаточно многообразен: существует 4 диалекта, фиксированная и свободная формы синтаксиса\. Необходимость в поддержке старого и написании нового кода вынуждает компании искать [RPG\-программистов](https://www.indeed.com/q-IBM-Rpg-Programmer-jobs.html), которые, по\-видимому, уже занесены в Красную книгу\. В таких условиях возникает потребность в использовании дополнительных инструментов по контролю качества кода, например, таких как статический анализатор\.

Возможно, читатель уже догадался, почему мы решили написать эту статью, и к чему мы клоним\. Да, мы [подумываем](https://pvs-studio.ru/ru/blog/posts/0547/) создать статический анализатор кода для языка RPG\. Думаю, такой анализатор станет отличным подспорьем тем, кто продолжает сопровождать и развивать программы на этом языке\. Однако, решение ещё не принято\. Думаю, вы понимаете, что это весьма специфическое направление\.

Поэтому, если вы хотите, чтобы анализатор [PVS\-Studio](https://pvs-studio.ru/ru/pvs-studio/) научился искать ошибки в RPG программах, то напишите нам\. Мы ищем Вас, уважаемых потенциальных клиентов PVS\-Studio RPG\. [Пишите](https://pvs-studio.ru/ru/about-feedback/) нам\!