Ich glaube, ich muss das doch mal erklären: In dem Krankenhaus, in dem ich meinen Zivildienst abgeleistet habe, laufen die Anwendungen wie Abrechnung, Leistungserfassung und Buchhaltungen auf einer IBM eServer iSeries, vormals AS/400. Irgendwie fasziniert mich das Teil:

RPG

Damit man mal sehen kann, wie krank RPG wirklich ist, hier ein selbst geschriebenes Hello World, sogar in ILE RPG (das ist die neuere Generation ...):

     D MSG             S             52A
      *
     C                   Eval      MSG = 'Hello World!'
     C     MSG           Dsply
     C                   Seton                                        LR

Noch ein Hello World, diesmal sogar mit Ausdruck und in RPG III:

     H            D.J
      *
     FQSYSPRT O   F      78            PRINTER
      *
     C                     EXCPTHELLO
     C                     MOVE *ON       *INLR
      *
     OQSYSPRT E                HELLO
     O        H   10
     O                                 + 20 'Hello World!'

Programme, die aussehen wie Leitungsrauschen :) ! Erklärung gefällig? (oje, das wird lang)

In Spalte 6 steht das Verarbeitungskennzeichen, welches den Typ (und damit das Format) der Zeile bestimmt. Die erste Zeile (H wie Header) stellt ein einheimisches Datums- und Zahlenformat ein. Ein Stern in Spalte 7 bezeichnet einen Kommentar.

Zeile 3 definiert eine Datei (F = File). Diese heißt QSYSPRT, ist ein PRINTER-File (Drucker) und dient der Ausgabe (O). Das F in Spalte 19 bedeutet, dass die Datei programmbeschrieben ist, die Satzlänge beträgt 78 Zeichen. Dateien auf der AS/400 sind normalerweise extern beschrieben (externally described), d.h. die Beschreibung des Datensatz-Formats steht in der Datei selbst. In diesem Fall wird die externe Beschreibung aber nicht benutzt, um ein freies Druckformat zu erzeigen -- das ist in allen Fällen außer hier extrem schlechter Stil. Auf dieselbe Art wie ein "Printer-File" würde man auch eine Datei auf Platte (DISK in Spalte 40), auf Band (SEQ) oder eine Bildschirmmaske, ein so genanntes "Display File" (WORKSTN) einbinden. Display Files und Printer Files enthalten Informationen über Layout und Datenfelder (Längen/Typen) -- sie sind genau wie physische Dateien extern beschrieben.

Als nächstes die Output-Zeilen 8 bis 10: Hier wird das Ausgabeformat definiert. Zeile 8 definiert einen EXCPT-Satz (E in Spalte 15), den man mit dem EXCPT-Opcode ausgeben kann. Dieser bekommt den Namen HELLO zugewiesen. Zeile 9 gehört noch zum Header dieses Satzes (H in Spalte 15); sie besagt, dass vor dem Ausdruck ein Vorschub von 10 Zeilen erfolgen soll. In Zeile 10 steht eine Konstante ('Hello World!') die ausgegeben wird. Vor dem Text werden 19 Zeichen Platz gelassen. Ohne das Plus-Zeichen gäbe die Zahl die Position des letzten Zeichens an (rechtsbündige Ausgabe).

Zuletzt noch die Berechnungen (C = Calculation, Zeile 5 und 6): "Normale" RPG-Programme haben immer eine primäre Eingabedatei, die in den F-Zeilen z.B. so definiert wird:

     FNAME    IP  E                    DISK

Die C-Zeilen werden nun einmal für jeden Datensatz durchlaufen. Nach dem letzten Satz wird der LR-Indikator (Last Record) gesetzt. Die typische Anwendung ist z.B. die Berechnung einer Summe. In unserem Fall gibt es keine primäre Eingabedatei, also müssen wir den LR-Indikator selbst setzen -- ansonsten ergäbe sich eine Endlosschleife!

Indikatoren sind ähnlich wie BOOL-Variablen in C++, sie speichern einen Wahrheitswert. Neben LR gibt es noch die so genannten Bezugszahlen: Sie sind von 00 bis 99 nummeriert und können von Programmierer als Flags genutzt werden. Außerdem gibt es noch die Gruppenwechsel-Indikatoren L1 bis L9 -- diese kann die Laufzeitumgebung selbsttätig setzen, wenn sich z.B. ein Feldinhalt ändert.

Eine C-Zeile hat ungefähr folgendes Format:

     C01        Faktor1    OpcdeFaktor2   Ergebnis                HoNiGl

Direkt nach dem C kann eine Bezugszahl als Bedingung angegeben werden. Die obige Zeile wird z.B. nur ausgeführt, wenn die Bezugszahl 01 gesetzt ist. Jeder Befehl (Opcode) kann zwei Eingabe-Parameter (Faktor 1 und 2) und einen Ausgabe-Parameter (Ergebnis) annehmen. Hinten in der Zeile kann man maximal drei Bezugszahlen angeben, die bei einem bestimmten Ergebnis gesetzt werden (Hoch, Niedrig und Gleich); die Namen beziehen sich auf Zahlenvergleiche, jedoch bedeutet "Hoch" z.B. auch "Satz nicht gefunden". Ein Beispiel für deren Verwendung sieht man im ersten Beispielprogramm beim SETON-Opcode.

Jedenfalls ist MOVE der am meisten verwendete Opcode in RPG III; in ILE RPG gibt es ihn nicht mehr, was die Portierung von Programmen nicht leichter macht :) . Er ist ungefähr mit dem MOV aus i386-Assembler vergleichbar. Zeile 6 bedeutet also: "Setze Indikator LR auf An (*ON)". Der Stern steht für einen so genannten "Sonderwert" (also keinen regulären Bezeichner). Ja, und Zeile 5 gibt mit dem EXCPT-Opcode unseren weiter unten definierten Satz aus.

Alles in allem das wahrscheinlich komplizierteste "Hello World"-Programm, das man sich denken kann ;) .

BennySiegert/AS400 (zuletzt geändert am 2009-03-24 12:01:47 durch BennySiegert)