Benutzer:Arbol01/REXX
Einleitung
[Bearbeiten]Die Programmiersprache REXX kennt keine Typendeklaration.
Wenn eine Variable noch keinen Wert zugewiesen bekommen hat, also uninitialisiert ist, verhält sie sich wie ein in Großbuchstaben geschriebener String:
say hallo => HALLO
Erst mit der Initialisierung ändert sich das:
hallo = 25 say hallo => 25 hallo = "say 5 + 3" say hallo => say 5 + 3
Durch die Anweisung drop wird eine Variable deinitialisiert und vergessen.
hallo = "Guten Morgen" say hallo => Guten Morgen drop hallo say hallo => HALLO
Werden in REXX Variablen mit Zahlen initialisiert, läßt sich mit ihnen rechnen:
a = 25 b = 17 say a + b => 42 say a - b => 8 say a * b => 425
Stems
[Bearbeiten]Stems haben in vielerlei Hinsicht Ähnlichkeiten mit Arrays:
do i = 1 to 10 zahl.i = 10 - i end zahl.0 = i - 1 /* => 10; per Konvention */ do i = 1 to zahl.0 say i')' zahl.i end i
Danach existieren folgende Variablen mit folgender Zuordnung: zahl.1 = 9, zahl.2 = 8, zahl.3 = 7 ... Per Konvention wird unter dem Index 0 die Anzahl der gespeicherten Elemente abgelegt. Mit drop zahl. können dann alle elf Variablen der Form zahl.i mit einem Schlag entfernt werden.
Andererseits haben Stems auch Ähnlichkeiten mit Zeigern (Pointern):
a = 2 Do 5 b = 2*a-1 p.a = b a = b End
Nach dem Ablauf existieren folgende Variablen mit folgender Zuordnung: p.2 = 3, p.3 = 5, p.5 = 9, p.9 = 17, p.17 = 33. Wie bei Zeigern läßt sich, ohne explizit die Existenz der Variablen (mit Ausnahme der ersten Variable p.2) zu kennen, auf die verketteten Variablen zugreifen.
Diese Art der Variablen wird als Stem-Variablen bezeichnet; der erste Teil einschließlich des ersten Punkts wird als Stem bezeichnet, der Rest als Tail. Der Tail kann auch aus mehreren Symbolen bestehen, die durch Punkte voneinander getrennt werden; auf diese Weise können auch mehrdimensionale Arrays realisiert werden. Die Werte der verwendeten Symbole können beliebig sein; sie sind durchaus nicht auf Zahlen beschränkt.
Ausgabe
[Bearbeiten]- Ausgabe über den Bildschirm
Wenn man in REXX etwas über den Bildschirm ausgeben will, macht man das über die Anweisung say:
say ausdruck
- Ausgabe als Datei
lineout(dateiname,ausdruck)
Eingabe
[Bearbeiten]- Eingabe über die Tastatur
Die Eingabe über die Tastatur erfolgt über die Anweisung pull:
pull variable
- Eingabe aus einer Datei
variable=linein(dateiname)
Wenn man sicher gehen will, dass im Eingabestrom noch Zeilen vorhanden sind, kann man die Funktion lines() verwenden:
variable = lines(dateiname)
Der zurückgelieferte Wert gibt an, wieviele vollständige Zeilen sich noch im Eingabestrom befinden.
Für den Fall, dass man einzelne Zeichen lesen will, gibt es die zu linein() und lines() analogen Funktionen charin() und chars()
charin(dateiname) variable = chars(dateiname)
- Übergabe bei Start eines REXX-Programms
Wie bei den meisten Programmiersprachen, lassen sich beim Start eines Programms Parameter übergeben. Das Programm kann diese Parameter über die Funktion arg(1) abrufen und dann wie einen String auswerten.
/* Ein REXX-Program */ console = arg(1) say anzahl = words(console) do index = 1 to anzahl by 1 say word(console,index) end
Der Aufruf von arg() liefert zurück, ob Parameter angegeben wurden (arg() == 1) oder ob keine Parameter angegeben wurden (arg() == 0).
Mathematische Grundoperationen
[Bearbeiten]- Addieren:
a = 2+3 ==> a == 5
- Multiplizieren:
a = 2*3 ==> a == 6
- Subtrahieren:
a = 2-3 ==> a == -1
- Division:
a = 2 / 3 ==> a == 0.66667
- Potenzieren:
Um bn zu berechnen benutzt man b**n
a = 2**3 ==> a == 8
Modulo
[Bearbeiten]Man kann nicht alles so teilen, das gebrochene Zahlen herauskommen. Wenn man zum Beispiel 33 Eier auf 4 Personen aufteilen will, ohne die Eier zu zerteilen, so bleiben Eier übrig. Die Aufteilung ist in diesem Fall 7 Eier pro Person, und 5 Eier, die man nicht aufteilen kann. Die Operationen heißen Div und Mod, und werden in REXX durch die Symbole % und // repräsentiert.
- Div
a = 33 % 4 ==> a == 7
- Mod
a = 33 // 4 ==> a == 5
Die Modulo-Operation spielt in der Zahlentheorie eine besondere Bedeutung. Der kleine fermatsche Satz besagt nämlich, das wenn die natürliche Zahl eine Primzahl ist, dann gilt für jede Basis , das durch teilbar ist. Daraus abgeleitet gilt für jede Primzahl : .
In einem Programm in REXX wird man diesen Satz so verwenden:
n = (a**(p-1))//p ==> wenn n == 1 ist, dann ist p mit einer gewissen Wahrscheinlichkeit eine Primzahl.
in der Praxis benötigt man die Modulo-Operation sehr oft für Datumsberechnungen. z.B. 26.01.2006 war Mitwoch. der 27.04.2006 ist genau 90 Tage später. 90 % 7 = 6 (90:7=84 Rest 6) Daraus folgt, Mittwoch + 6 Tage = Dienstag
logische Funktionen
[Bearbeiten]Die folgenden drei Funktionen vergleichen die Zeichen bitweise. Ein Bit kann dabei den Zustand 0 oder 1 haben. Jeweils 8 Bit zusammengefasst ergeben ein Zeichen. Das Zeichen "A" hat zum Beispiel den entsprechenden binären Code 01000001.
- bitand(a,b)
Beispiel: 01011010 und 01101101 ergeben 01001000
a = bitand("Z","m") ==> a == "H"
- bitor(a,b)
Beispiel: 01011010 und 01101101 ergeben 01111111
a = bitor("Z","m") ==>
- bitxor(a,b)
Beispiel: 01011010 und 01101101 ergeben 00110111
a = bitor("Z","m") ==> "7"
Um diese Operationen mit dezimalen Zahlen benuzten zu können, muß man sie vorher und nachher konvertieren:
a = D2C(5) b = D2C(9) x = C2D(bitand(a,b)) ==> x == 1 y = C2D(bitor(a,b)) ==> y == 13 z = C2D(bitxor(a,b)) ==> z == 12
Einleitung
[Bearbeiten]Der eigentliche Typ einer Variable in REXX ist ja String. Demzufolge gibt es eine Menge Anweisungen und Funktionen zur Bearbeitung von Strings.
Konkatenation
[Bearbeiten]Es kommt vor, das man zwei Strings (oder mehr) zu einem String zusammenführen, oder einen String verlängern möchte. So eine Zusammenführung ermöglicht der Operator ||:
gesamtstring = string1||string2
Länge eines Strings
[Bearbeiten]Mit der Funktion length() bekommt man heraus, aus wie vielen Zeichen ein String besteht:
variable = length(string)
Teilstrings
[Bearbeiten]Manchmal will man nur einen Teil eines Strings verwenden. Dafür kann man die Funktion substr() verwenden:
teilstring = substr(string,startposition,länge)
Beispiel: a = substr("Grottenolm",2,5) => a == "rotte"
Wörterzerlegung
[Bearbeiten]Angenommen, man will die Wörter eines als String eingegebenen Satzes analysieren. Dafür gibt es eine Anzahl von Funktionen. Die Funktion words() gibt die Anzahl der Wörter zurück, aus denen der String zusammengesetzt ist:
variable = words(string)
Beispiel: a = words("Dieser Satz hat fünf Wörter") => a == 5
Mit der Funktion word() kann man dann auf die einzelnen Wörter dieses Strings zugreifen:
variable = word(string,wert)
Beispiel: a = word("Die Katze tritt die Treppe krum",2) => a == "Katze"
Sonstiges
[Bearbeiten]Beispiel: a = lower("HaLlO") => a == "hallo"
Beispiel: a = upper("HaLlO") => a == "HALLO"
Einleitung
[Bearbeiten]Alle Anweisungen und Funktionen, die nicht schon in den anderen Kapiteln besprochen wurden oder noch besprochen werden, werden hier behandelt.
Anweisungen
[Bearbeiten]- clear
Die Anweisung clear löscht den Bildschim.
- drop
Mit drop variable kann man einzelne Variablen löschen, oder auch einen ganzen Stem.
- exit
Die Anweisung exit veranlaßt ein Programm sich zu beenden.
- leave
leave bewirkt das Verlassen einer Schleife. Das ist besonders sinnvoll, wenn es sich bei der Schleife um eine Endlosschleife handelt.
- nop
Die Anweisung nop steht für no operation. Es ist eine Leeranweisung, die nichts macht.
- random(u,o,s)
Um Zufallszahlen zu bekommen, kann man Die Funktion random() verwenden. random kennt die drei Parameter u (für Untergrenze), o (für Obergrenze und s. Alle drei Parameter sind optional, können also auch entfallen.
- C2D()
C2D() wandelt Zeichen in ASCII-Code (dezimal) um.
a = C2D("A") ==> a == 65
- C2X
C2X() wandelt Zeichen in ASCII-Code (hexadezimal) um
a = C2D("A") ==> a == 41
- D2C
D2C() wandelt Dezimalzahlen in Zeichen um
a = D2C(33) ==> a == "!"
- D2X
D2X() wandelt Dezimalzahlen in Hexadezimalzahlen um
a = D2X(255) ==> a == "FF"
Einleitung
[Bearbeiten]Im Gegensatz zu anderen Programmiersprachen beginnen bei REXX alle Schleifen mit do. Die Gestaltung dieser do-Schleife kann sehr vielfältig sein.
Ein Block von Anweisungen
[Bearbeiten]Wenn man eine feste Folge von Anweisungen braucht, dann lassen sie sich mit einer do-end Kombination gliedern:
Folge von Anweisungen:
do Anweisung1 Anweisung2 Anweisung3 . . . AnweisungN end
begrenzte Anzahl von Wiederholungen
[Bearbeiten]Soll eine Schleife eine fest vorgegebene Anzahl durchlaufen werden, dann kann man hinter dem do einen Ausdruck angeben, der die Anzahl der Wiederholungen bestimmt (Beispiel):
do 5 say "Hallo" end
Es wird fünfmal "Hallo" ausgegeben
Zähl-Schleife
[Bearbeiten]do index=start to ende by schrittweite Anweisung1 Anweisung2 Anweisung3 . . . AnweisungN end
While-Schleife
[Bearbeiten]do while Bedingung Anweisung1 Anweisung2 Anweisung3 . . . AnweisungN end
Endlos Schleife (mit optionaler Abbruchbedingung)
[Bearbeiten]do forever Anweisung1 Anweisung2 Anweisung3 . . . AnweisungN if Abbruchbedingung then leave end
Einleitung
[Bearbeiten]Wie in den meisten Programmiersprachen kann man auch in REXX eigene Funktionen schreiben. Es lassen sich auch externe Bibliotheken erstellen. Egal ob es sich um eine eigene Funktion innerhalb des Programms handelt, oder um eine externe Bilbliothek, der Aufruf ist immer:
call funktionsname parameter
eigene Funktionen innerhalb des Programms
[Bearbeiten]Als Beispiel ein Programm zur Ausgabe der Fakultät. Die eigentliche Berechnung der Fakultät findet in der selbst geschriebenen Funktion statt.
/* Ein Rexx-Programm */ do forever say "Bitte gib eine Zahl >= 0 ein" pull n call fakultaet n say "die Fakultaet zu" n "ist" result end /* */ FAKULTAET: procedure arg n if n = 0 then n = n + 1 if n = 1 then n = n * 1 if n > 1 then do call fakultaet (n - 1) n = n * result end return n
Als Rückgabeparameter fungiert result.
Externe Bibliothek
[Bearbeiten]Eine externe Bibliothek muß erst in das Programm dazu geladen werden. Das bewirkt die Anweisung:
call load 'datei'
/* Ein REXX-Programm */ call load 'convert.r' do forever pull zahl pull base call d2n zahl,base say zahl'='result end
Die externe Bibliothek ist nicht ablauffähig. Um auf diesen Umstand hinzuweisen, kann man der Bibliothek zwei Zeilen an den Anfang stellen:
say 'Only a Library!' exit 1
Diese zwei Zeilen bewirken, das beim Starten der Bibliothek eine Meldung ausgegeben wird, das es sich bei der ausgeführten Datei um eine Bibliothek handelt. Das exit 1 beendet dann die Datei. Beim Aufruf mit call load aus einem REXX-Programm haben diese beiden Zeilen keine Auswirkungen.
/* REXX-Programm */ say 'Only a Library!' exit 1 /* */ /* */ D2N: procedure arg n,b /* initialisierung */ z='0123456789ABCDEFGHIJKLMNOPQRSTUVW' conv = nstart = n DO WHILE n > 0 p = n // b conv = substr(z,(p+1),1)||conv n = n % b END /* Ausgabe der Konversion in der Form: 23 = (10111)2 */ return conv
Sieb des Erathostenes
[Bearbeiten]/* Ein Rexx-Programm */ /* Initialisierung */ do index = 2 to 10000 zahl.index = 1 /* Alle Zahlen sind Primzahlen */ end /* Primzahlen sieben */ do index = 2 to 100 if (zahl.index = 1) then do index2 = (index*index) to 10000 by index zahl.index2 = 0 end end /* Ausgabe der Primzahlen */ do index = 2 to 10000 if (zahl.index = 1) then say index end
Primzahltest naiver Ansatz
[Bearbeiten]/* Ein REXX-Programm */ initial=1 obergrenze = 10000 anzahl_primzahlen = 1 primzahl_zeiger.1=2 say 2 do index = 3 to obergrenze primzahl_wahr = 1 laeufer = initial do anzahl_primzahlen laeufer = primzahl_zeiger.laeufer if (index // laeufer = 0) then primzahl_wahr = 0 end if (primzahl_wahr = 1) then do primzahl_zeiger.laeufer = index anzahl_primzahlen = anzahl_primzahlen + 1 say index end end
Übersicht der REXX-Anweisungen (unvollständig)
[Bearbeiten]REXX-Anweisungen | ||
---|---|---|
address umgebung ausdruck | zum Ausführen von Anweisungen außerhalb der REXX-Umgebung | address DOS 'DIR *.*' |
call prozedur | Aufruf einer prozedur | call binkoeff n k |
call load 'bibliothek' | Eine externe Bibliothek laden | call load 'mathe.r' |
clear | löscht den Bildschirm | |
delete datei | Löscht die Datei datei | |
do | Alle möglichen Arten von Schleifen | |
drop variable | variable löschen | drop a |
exit | veranlasst das Programm sich zu beenden | |
if bedingung then anweisung | Selektionsbefehl | if a > 0 then a = a + 1 |
interpret ausdruck | ausdruck wird wie eine REXX-Anweisung behandelt | interpret "a=5*(4+b)" |
iterate | Leerdurchlauf einer Schleife ohne Ausführung der hier kodierten Befehle | |
leave | Verlassen einer Schleife | |
nop | Leeranweisung, die nichts macht | |
parse | Analyse von Eingaben und Variablen (Vorlaufinformation) | |
pull variable | liest eine Zeichenkette von der Tastatur ein | pull eingabe |
say ausdruck | ausdruck wird auf dem Bildschirm ausgegeben | say "Hallo Welt!" |
signal label | Äquivalent zu goto label |
Übersicht der REXX-Funktionen (unvollständig)
[Bearbeiten]REXX-Funktionen | ||
---|---|---|
address() | gibt die Umgebung zurück | z.B: address() == 'DOS' |
arg(1) | Enthält die Eingabe aus der Kommandozeile | console = arg(1) |
charin("dateiname") | holt ein Zeichen aus dem Eingabestrom | zeichen = charin("semmel.txt") |
charout() | schreibt ein Zeichen in den Ausgabestrom | |
chars() | gibt die Anzahl der noch verfügbaren Zeichen im Eingabestrom aus | |
date() | Funktion Datum gibt je nach Option Tages bzw. Datumsangaben zurück. | |
linein("dateiname") | Liest eine ganze Zeile aus einer Datei ein | zeile = linein("semmel.txt") |
lineout("dateiname",ausdruck) | ausdruck wird in Datei geschrieben | lineout("semmel.txt",eumel) |
lines() | gibt die Anzahl der noch vollständigen Zeilen im Eingabestrom aus | |
Stringfunktionen | ||
length(string) | liefert die Länge eines Strings zurück | |
lower(string) | wandelt alle Buchstaben eines Strings in Kleinbuchstaben um | |
substr(string,position,zeichenzahl) | Ein Teilstring aus string | |
upper(string) | wandelt alle Buchstaben eines Strings in Großbuchstaben um | |
word(string,wort) | gibt das n.te Wort des String aus | a = word("polyglotte Katze",2) |
words(string) | gibt die Anzahl der Wörter des Strings aus | a = words("Hallo Leute") |
mathematische Funktionen | ||
abs(zahl) | liefert den vorzeichenlosen Teil einer Zahl zurück | |
bitand() | Bitweises UND | |
bitor() | Bitweises ODER | |
bitxor() | Bitweises XOR | |
random(u,o,s) | liefert eine zufällige Zahl in den Grenzen von u und o zurück. u,o und s sind optional | |
C2D() | Wandelt Zeichen in ASCII-Code (dezimal) um | |
C2X() | Wandelt Zeichen in ASCII-Code (hexadezimal) um | |
D2C() | Wandelt Dezimalzahlen in Zeichen um | |
D2X() | Wandelt Dezimalzahlen in Hexadezimalzahlen um |
Übersicht der REXX-Operatoren (unvollständig)
[Bearbeiten]Vergleichsoperatoren
[Bearbeiten]Rexx verfügt über zwei Klassen von Vergleichsoperatoren, die exakt (z. B. ==
) oder
numerisch (=
) vergleichen. Im zweiten Fall werden zunächst etwaige Rand-Blanks entfernt, weil diese für die Interpretation als Zahl nicht von Bedeutung sind.
Rexx unterstützt eine große Zahl von Varianten, wobei allerdings „nicht“ nicht, wie in manchen Sprachen üblich, durch das Ausrufungszeichen, sondern durch das mathematische Zeichen für „nicht“ (¬
), ersatzweise den Backslash ausgedrückt wird (das Ausrufungszeichen gehört zum Zeichenvorrat für Bezeichner!)
Vergleichs-Operatoren | Beispiel | Ergebnis | |
---|---|---|---|
exakt gleich | == |
"1" == 1 |
0 |
numerisch gleich | = |
"1" = 1 |
1 |
nicht exakt gleich | ¬== \==
| ||
numerisch ungleich | <> ¬= \=
| ||
exakt größer | >> |
30 >> "4 " |
0 |
numerisch größer | > |
30 > "4 " |
1 |
exakt größer oder gleich | >== ¬<< \<<
| ||
numerisch größer oder gleich | >= ¬< \<
| ||
exakt kleiner | << |
30 << "4 " |
1 |
numerisch kleiner | < |
30 < "4 " |
0 |
exakt kleiner oder gleich | <== ¬>> \>>
| ||
numerisch kleiner oder gleich | <= ¬> \>
|
sonstige Operatoren
[Bearbeiten]Die Operatoren +, -, * und / werden nicht extra aufgeführt.
REXX-Operatoren | ||
---|---|---|
** | Potenz | 4**3 == 64 |
% | ganzzahlige Division | 11%3 == 3 |
// | Rest-Operator (Modulo) | 11//3 == 2 |
& | logisches UND | a & b => wahr, wenn a und b wahr sind |
| | logisches ODER | a | b => wahr wenn a oder b wahr ist |
&& | logisches XOR | a && b => wahr, wenn entweder a oder b wahr ist, aber nicht beide gleichzeitig |
|| | Stringverkettung (Konkatenation) | "bär"||"tiger" = "bärtiger" |
REXX-Versionen
[Bearbeiten]- BREXX - Vasilis Vlachoudis (DOS, Linux, Amiga, ...)
- Regina (Linux, Windows, ...)
- ARexx (Amiga)
Literatur
[Bearbeiten]- Michael Cowlishaw, The Rexx Language: A Practical Approach to Programming, ISBN 0137806515
- Michael Metz et al., ARexx. Eine Einführung und mehr, ISBN 3930733005
- Karlheinz Wittemann, REXX unter MVS-TSO/E, ISBN 3446179569
- Howard Fosdick, Rexx Programmer's Reference (Wiley/Wrox: 2005), ISBN 0764579967