RPG (プログラム言語)

RPG は、ビジネスソフトウェア向けの高水準言語に位置づけられるプログラム言語である。IBM独自の言語であり、IBM-iまたはOS/400のシステム上で動作する。

RPGというプログラム名はReport Program Generatorのアクロニムである。ILE (Integrated Language Environment) のオブジェクト指向機能を取り入れた RPG IVが現行である（ILE RPGとしても知られている）。最初期の第四世代言語 (4GL) とされる。

IBMによって1959年に開発された言語であり、高水準言語としてはFORTRAN、LISP、ALGOL58に次いで古い歴史を持つ。

 概観 
IBM System i（以前のAS/400）の主力プログラミング言語である。元はクエリー用ツールとして設計されたものだが、IBMが開発に注力したことで強力な言語になった。

典型的なRPGプログラムは File Specification から始まる。ここでは入出力用ファイルを全て列挙する。続いて Data Definition Specification である。これはデータ構造や配列を定義する部分で、COBOLの Working-Storage セクションやPascalの変数定義(var)セクションに大変よく似ている。次はプログラムの動作をコードする Calculation Specification である。出力するレポートのレイアウトを決定する Output Specification を加えてもいいし、外部でそれを決定してもいい。

初期のRPGの売り物はprogram cycleであった。これは、レコードをファイルから読み込む毎にいくつかのRPGプログラムが一つの暗黙のループの中で実行されるというものであり、別の見方をすれば、暗黙のうちに相互作用する一つのプログラムが作り上げられるということになる。現在では、プログラムフローを通常のループで制御しようとするプログラマが多いため、この機能は避けられる傾向にある。

 歴史 
RPGはパンチカード時代から現代まで常用され続けてきた数少ない言語の一つである。IBMがRPGを開発したのは1960年代のことであった。RPGは Report Program Generator のアクロニムで、この名前が目的を表している: データファイルを読み、小計や検算を含んだ会計報告を生成する。

RPGの前身はFARGO (Fourteen-o-one Automatic Report Generation Operation) である。FARGOとRPGはユニットレコード装置（以下PCS、タビュレーティングマシン参照）から当時新開発だったIBM 1401シリーズへの移行を容易ならしめることを目的としていた。PCS技術者は、プラグボード:en:plug-board上で配線することで入出力やカウンタ操作（四則演算）を行うことに慣れていた。PCSのプログラムは1マシンサイクル中にいくつかのパルスを発生することで実行されていたので、FARGOとRPGはprogram cycleの名でこれをエミュレートしたのである。RPGはFARGOより優れており、会計報告作成言語としてのFARGOを駆逐した。

当時、他に広く用いられていた言語にCOBOLとFORTRANがあった。COBOLは饒舌な（訳注: 自然言語に近づけるため、ソースコードの記述量が多くなった — 省略しても構わない部分も多いが）ビジネス向け言語で、FORTRANは科学計算向けであった。この時代の他の言語としては、PL/1、ALGOL、Autocoderがある。COBOLはメインフレーム/汎用機のビジネス応用ではより一般的であり、RPGはPCSから移行した店舗でより一般的だった（System/360モデル20）。

RPG IIはSystem/3と同時に導入され、後にはSystem/32、System/34、System/36上でも利用されたが、System/38向けには改良版のRPG IIIが作られた。同機の後継機AS/400（ミッドレンジ機で、現在ではSystem iに進化した）の登場に伴い、文法を洗練し、統合データベースといっそう緊密に統合された RPG/400 が作られた。RPG/400はAS/400上の主力開発言語となり、それぞれの specification （命令の種類）に応じたプロンプトが出るラインエディタが用いられた。

RPG IIIは元のRPGから格段に変化しており、IF-ENDIFブロック、DOループ、サブルーチンといった近代的な構造を持っている。

1994年に、RPG IV（あるいはRPGLE、RPG/ILE）がリリースされ、もはやRPGはReport Program Generatorのアクロニムではないことが公式に告げられた。RPG IVは新しい Extended Factor-2 Calculation Specification をサポートし、さらに広範な表現を可能としている。

2001年、OS/400 V5R1 のリリースと共にRPG IVは Extended Factor-2 Calculation Specification すら超える自由を得た: 従来のコラム依存のコーディングの代わりに自由書式のソースコードを受け入れるようになったのである。"/FREE"計算を用いるとこれまでのように特定のコラムに命令コードを書く必要がなくなり、EVAL及びCALLP命令の命令コードがオプションになり、一般に行われる汎用言語によく似た構文になった。

今日、RPG IVはより堅固な言語になっている。昔と同様単純なエディタでプログラムを編集してもいいし、IBMのWebsphere Development Studioを通してPCで編集してもいい。IBMはRPGの機能拡張を続けており、内蔵された機能 (BIF) も増加している。Javaのオブジェクトとのリンク可能性、OS/400のAPIのコールなどである。IBMのCgidev2ツールキットやRPG xTools CGILIB 他の商用パッケージを用いれば、CGIを書くこともできる。これらの改良の一方ではこれまでとの互換性も考慮されており、35年前に書かれたRPGプログラムが現在でもほとんど修正なしで実行可能である。

データ型
RPGは以下のデータ型を使用することができる。

 データ型 名称 長さ 説明A英数字1 ～ 16,773,104 バイト (固定) 1 ～ 16,773,100 バイト(可変長)英数字Bバイナリ数値1 バイト (8ビット) 2 バイト (16ビット) 4 バイト (32ビット) 8 バイト (64ビット)符号付き2進整数CUCS-2（文字）1 ～ 8,386,552 文字 (固定) 1～8,386,550 文字 (可変)16ビット UCS-2(DBCS・EGCS)D日付10 バイト日付: 年, 月, 日F浮動小数点4 バイト (32ビット) 8 バイト (64ビット)符号付きバイナリ浮動小数点実数GGraphic character1～8,386,552 文字 (固定) 1～8,386,550 文字 (可変)16ビット graphic character (DBCS・EGCS)I整数値1 バイト (8ビット) 2 バイト (16ビット) 4 バイト (32ビット) 8 バイト (64ビット)符号付き2進整数Nブーリアン型1 バイト'1' = TRUE'0' = FALSEOオブジェクト不定オブジェクト（参照）Pパック10進数1～63 桁, 2 桁/バイト ＋ 符号整数と小数点付きの固定小数点10進数の符号付きS ゾーン10進数1～63 桁, 1 桁/バイト整数と小数点付きの固定小数点10進数の符号付きT時刻8 バイト時刻: 時, 分, 秒U整数値1 バイト (8ビット) 2 バイト (16ビット) 4 バイト (32ビット) 8 バイト (64ビット)符号なし2進整数Zタイムスタンプ26 バイト日時:   年, 月, 日, 時, 分, 秒, マイクロ秒*ポインタ16 バイトデータ・標識・オブジェクトへのアクセス

 コードの例 
次のプログラムは入力として顧客番号を受け取って名前と住所を出力する。
コメントの訳は次の通り。
「自由書式が許される環境もあるが、歴史的にRPGはコラムに従って記述する。第7コラムの星印(*)はコメント行を意味する。行の目的は第6コラムの文字で決まる。」
「'F'はファイルその他の入出力装置の仕様を示す。」
「'D'は変数定義である。」
「'C'は実行すべき文を示す。パラメタは plist 及び parm 命令で定義される。」
「'chain' コマンドは（検索用）キーのあるファイルのランダムアクセスを行う。」
「RPGはスイッチを利用する。その一つ'LR'＜最終レコード＞の意味で、プログラムの実行を停止する。」

 RPG3 
 F* F仕様書はI/Oファイルなどを定義する
 FARMSTF1UF E DISK
 F ARMST KRENAMERARMST
 C* パラメータの定義
 C *ENTRY PLIST 
 C PARM PCUSNO 60
 C PARM PNAME 30
 C PARM PADDR1 30
 C PARM PADDR2 30
 C PARM PCITY 25
 C PARM PSTATE 2
 C PARM PZIP 10
 C*
 C* "CHAIN"命令を使用してキーファイルをランダムアクセスする
 C* ファイルに存在しないときは、標識90がオンになる。
 C PCUSNO CHAINARMSTF1 90
 C*
 C* レコードが存在する場合はその値をパラメータにセットする
 C *IN90 IFEQ *OFF
 C Z-ADDARNM01 PNAME
 C MOVELARAD01 PADDR1
 C MOVELARAD02 PADDR2
 C MOVELARCY01 PCITY
 C MOVELARST01 PSTATE
 C MOVELARZP15 PZIP
 C ENDIF
 C* RPGのプログラム終了時には標識LRをオンにする。
 C MOVE '1' *INLR

 RPG4（ILE） 
 * Historically RPG is columnar in nature, though free-formatting
 * is allowed under particular circumstances. 
 * The purpose of various lines code are determined by a 
 * letter code in column 6.
 * An asterisk (*) in column 7 denotes a comment line

 * "F" (file) specs define files and other i/o devices
 FARMstF1 UF E Disk Rename(ARMST:RARMST)

 * "D" specs are used to define variables
 D pCusNo S 6p 0
 D pName S 30a
 D pAddr1 S 30a
 D pAddr2 S 30a
 D pCity S 25a
 D pState S 2a
 D pZip S 10a

 * "C" (calculation) specs are used for executable statements
 * Parameters are defined using plist and parm opcodes 
 C *entry plist
 C parm pCusNo
 C parm pName
 C parm pAddr1
 C parm pAddr2
 C parm pCity
 C parm pState
 C parm pZip

 * The "chain" command is used for random access of a keyed file
 C pCusNo chain ARMstF1

 * If a record is found, move fields from the file into parameters
 C if %found
 C eval pName = ARNm01
 C eval pAddr1 = ARAd01
 C eval pAddr2 = ARAd02
 C eval pCity = ARCy01
 C eval pState = ARSt01
 C eval pZip = ARZp15
 C endif
 
 * RPG makes use of switches. One switch "LR" stands for 
 * "last record". This ends program execution.
 C eval *InLR = *On
 

 RPG4（フリーフォーマット） 
 * "F" (file) specs define files and other i/o devices
 FARMstF1 UF E Disk Rename(ARMST:RARMST)

 * "D" specs are used to define variables and parameters
 * The "prototype" for the program is in a separate file
 * allowing other programs to call it
 /copy cust_pr
 * The "procedure interface" describes the *ENTRY parameters
 D getCustInf PI
 D pCusNo 6p 0 const
 D pName 30a
 D pAddr1 30a
 D pAddr2 30a
 D pCity 25a
 D pState 2a
 D pZip 10a
 /free
 // The "chain" command is used for random access of a keyed file
 chain pCusNo ARMstF1;

 // If a record is found, move fields from the file into parameters
 if %found;
 pName = ARNm01;
 pAddr1 = ARAd01;
 pAddr2 = ARAd02;
 pCity = ARCy01;
 pState = ARSt01;
 pZip = ARZp15;
 endif;
 
 // RPG makes use of switches. One switch "LR" stands for 
 // "last record". This ends program execution.
 *InLR = *On;
 /end-free

 プラットホーム 
前述のように、RPGはもともとIBMによって 1401, System/360, /3, /32, /34, /36, /38, AS/400, 及び System i システム用に導入された。だが、IBMの計算機の他にも、Digital VAX, Sperry Univac BC/7, Univac system 80, Siemens BS2000, Burroughs B1700, Hewlett Packard HP3000, ICL 2900 series, 及び WANG VS に移植され、UNIXベースのシステム (Unibol) 及び PC (Baby/400, Lattice-RPG) にもコンパイラが存在した。RPG IIは今でもサードパーティ製のコンパイラがあり（Migration RPG 参照）、HP OpenVMS operating system on VAX, Alpha, 及びIntegrity processorをサポートしている。