Comal
Dieser Artikel behandelt die Programmiersprache COMAL in Sicht der Commodore Computersysteme.
Allgemeines[Bearbeiten | Quelltext bearbeiten]
COMAL ist eine 1973 in Dänemark von Benedict Löfstedt (Benedict Løfstedt) und Börge Christensen (Børge Christensen) entwickelte höhere Programmiersprache für Programmieranfänger. Der Name wurde als Akronym aus Common Algorithmic Language gebildet.
Bei der Ausgestaltung dieser Sprache standen leichte Erlernbarkeit, Lesbarkeit und Bedienung im Vordergrund, da sie nicht nur von ausgebildeten Programmierern angewendet werden sollte. In COMAL wurden Elemente bzw. Befehle von BASIC (Einfachheit, Befehle) und Pascal (strukturiertes Programmieren), teilweise stark erweitert, zusammengeführt. Später kam noch weitere Erweiterungen u. a. auch Teile der Programmiersprache LOGO (Turtle-Grafik) hinzu und bei den C64-Versionen Unterstützungen zur Grafik-, Sprite- und Sound-Programmierung.
Ein COMAL-System verhält sich sowohl wie ein Interpreter als auch wie ein Compiler (3-Pass-Interpreter).
- Im Direktmodus wird jede Anweisung (z. B.
PRINT 5*2
) sofort nach der Eingabe ausgeführt. - Anweisungen können als Programm im Speicher abgelegt werden. Vor der eigentlichen Ausführung findet dann eine Prüfung der Programmstruktur statt. Dabei werden auch Sprungadressen vorberechnet, was eine Beschleunigung des anschließenden Programmlaufes bewirkt (auf dem C64 etwa um Faktor 3).
- Im Direktmodus wird jede Anweisung (z. B.
Versionen[Bearbeiten | Quelltext bearbeiten]
Folgende COMAL-Versionen sind für Commodore-Computersysteme für CP/M, PET-/CBM-4000-Serie, C64/128 und Amiga bis etwa 2000 erschienen (Auflistung nach der Reihenfolge des Erscheinens):[1]
- 0.11: Original-COMAL Version 0.11 erschienen für 32K CBM und PET mit ROM-Version 4.0. Im Jahr 1979 durch europäische Universitäten standardisiert als COMAL-80.
- 0.12: Verbesserungen des COMAL-KERNALs für CBM und PET. CBM-COMAL-80 erstellt durch Mogens Kjaer, Lars Laursen, Jens Erik Jensen, and Helge Lassen.
- 0.14: (erstellt durch UNICOMAL) Ergänzung eines LOGO-kompatibelen Grafiksystem bei der C64-Version, plus neue Befehle KEY$ und PRINT USING (siehe Commodore 64 Comal-80 rev. 00.14).
- 1.02: Version für den Commodore CBM-8096, Zeichenketten-Befehle und weitere Ergänzungen
- 2.00: (erstellt durch UNICOMAL) Update für die Version 1.02 für einen 96K CBM-8096 oder C64-Steckmodul mit Erweiterungen und Unterstützung für Grafik, Sprites und Sound (siehe Commodore-64 Comal 80 rev 2.01). Weiterhin Zahlenvariablen können nun auch Hexadezimale Zahlen ($F5) und Binärzahlen (%11001001) verarbeiten. Die Version 2.02 ist für den C128 entwickelt worden.
- 1.40: (erstellt durch UNICOMAL) COMAL-Version für den Amiga mit vielen neuen Befehlen und Erweiterungen im Jahr 1989.
- 2.10: (erstellt durch UNICOMAL) COMAL-Version für den Amiga namens AMIGA-COMAL mit vielen neuen Befehlen und Erweiterungen. [2]
- 3.40: (erstellt durch UNICOMAL) COMAL-Version für den Amiga im Jahr 1996.
Hinweise[Bearbeiten | Quelltext bearbeiten]
- Eingabezeile des Interpreters ist max. 80 Zeichen lang.
- Überlange COMAL-Zeilen führen zu Bearbeitungsprobleme, wegen der 4-stelligen Zeilennummer plus ein Leerzeichen!
- Gültige Zeilennummernangaben sind von 0001 bis maximal 9999.
- Variablennamen dürfen ein Länge von bis 78 Zeichen haben, beginnend mit einem Buchstaben, sinnvoll sind aber kürzere Variabelnamen bis etwa 40 Zeichen.
- Variable$ - Zeichenketten, die innerhalb von Anführungszeichen stehen müssen; Bsp.:
NAME$:="C64-WIKI"
- Variable# - Integer-Variable (Ganzzahlen-Variable; gültiger Zahlenbereich: -32768 bis + 32767); Bsp.:
WERTE#:=2022
- Variable - Fließkomma-Variable (Signifikate Anzeige von bis zu 8 Stellen nach dem Dezimalpunkt; gültiger Zahlenbereich: ±9.99999999·10−89 bis ±9.99999999·1037); Bsp.:
WERT:=-3.145
- Variable$ - Zeichenketten, die innerhalb von Anführungszeichen stehen müssen; Bsp.:
- Labels können mit
LABELNAME:
definiert werden. - Mehrteilige Befehle wie FOR-NEXT-Schleife, IF-THEN-Befehle, usw. dürfen strukturiert in mehreren Zeilen geschrieben werden.
- Wichtig: Abtrennung von verschiedenen Befehlen durch ein Leerzeichen:
PRINT CHR$(147)
löscht beim C64 den Bildschirm. - Mathematische Ausführreihenfolge (von oben nach unten):
↑ (Potenzierung) * / DIV MOD + - < <= = >= > <> IN NOT AND OR
Der Sprachkern[Bearbeiten | Quelltext bearbeiten]
Die Sprache hat einen standardisierten Sprachkern (COMAL-80 Kernel : Syntax & Semantics) der keine Zeilennummern und keine Kommandos zum bearbeiten vom Programm beinhaltet. Die Implementierungen zum Standard verwenden allerdings alle Zeilennummern und einen gemeinsamen Satz von Kommandos um Programme zu laden, speichern, auflisten, und bearbeiten.
Einzelne Zeilen können bei der Eingabe schon auf syntaktische Fehler geprüft werden. Mehrzeilige Syntaxkonstrukte aber erst nach der Eingabe aller dafür benötigten Zeilen.
Kommentare[Bearbeiten | Quelltext bearbeiten]
Kommentare werden mit //
eingeleitet und gehen bis zum Zeilenende. Sie können am Ende von jeder Zeile stehen. Inklusive ansonsten leerer Zeilen.
// Zeile die nur einen Kommmentar enthält. PRINT 42 // Gibt die Antwort auf alle Fragen aus.
Literale Werte[Bearbeiten | Quelltext bearbeiten]
Numerisch[Bearbeiten | Quelltext bearbeiten]
Literal | Beschreibung |
---|---|
42
|
ganze Zahl in Dezimalschreibweise |
-23
|
vorangestelltes Minus für negative Zahlen |
47.11
|
Dezimalbrüche werden mit einem Dezimalpunkt geschrieben |
.5
|
Eine führende 0 vor dem Komma kann weg gelassen werden |
1E6
|
10er-Potenzen können mit einem E und der Potenz angegeben werden (1000000) |
2.5E-2
|
Negative 10er-Potenzen sind möglich (0.025) |
Der Wertebereich ist implementierungsabhängig. Er entspricht bei den COMAL-Implementierungen für den C64 dem Wertebereich für Gleitkommazahlen in BASIC.
Zeichenketten[Bearbeiten | Quelltext bearbeiten]
"Hallo, Welt!"
Zeichenkettenliterale werden in doppelte Anführungszeichen eingefasst. Welche Zeichen zwischen den Anführungszeichen erlaubt sind, ist implementierungsabhängig.
Variablen[Bearbeiten | Quelltext bearbeiten]
Variablennamen müssen mit einem Buchstaben anfangen und können mit Buchstaben, Ziffern und Zeichen weitergehen. Welche Zeichen konkret erlaubt sind, ist implementierungsabhängig. Bei den COMAL-Implementierungen für Commodore-Rechner sind neben Buchstaben und Ziffern die Zeichen '
, [
, ]
, und ←
in Namen erlaubt. Namen dürfen bis zu 78 Zeichen lang sein.
Namen von Zeichenkettenvariablen werden mit einem angehängen $
gekennzeichnet. Namen für Variablen in denen Gleitkommazahlen gespeichert werden, haben keine Kennzeichnung. Ganzzahlvariablen werden mit #
gekennzeichnet. Auf diese Weise wird auch der Rückgabetyp von Funktionen über den Namen festgelegt.
Zeichenketten können zwar laut Standard mit dynamischer Länge implementiert werden, aber die Implementierungen für Commodore-8-Bit-Rechner verwenden alle statische Zeichenketten, das heisst Zeichenkettenvariablen haben eine maximale Länge. Bei Operationen, die diese Länge überschreiten, wird der Rest einfach abgeschnitten.
Arrays müssen vor ihrer Verwendung mit der DIM
-Anweisung dimensioniert werden. Zeichenkettenvariablen müssen das nicht, allerdings ist die Länge dann auf maximal 40 Zeichen beschränkt.
Anders als in BASIC, wo a
, a%
, a$
, a()
, a%()
, und a$()
alles Namen für verschiedene Variablen sind, die gleichzeitig existieren können, kann es in COMAL jeden Namen nur einmal geben, unabhängig davon ob er für einen numerischen Wert, eine Zeichenkettenvariable, oder auch einer Funktion oder Prozedur verwendet wird.
Operatoren[Bearbeiten | Quelltext bearbeiten]
Es gibt in COMAL numerische Ausdrücke, logische Ausdrücke, und Ausdrücke die Zeichenketten als Ergebnis haben.
Logische Ausdrücke sind ein Sonderfall von numerischen Ausdrücken, wobei 0 als „unwahr“ und jede andere Zahl als „wahr“ gilt. Die logischen Operatoren AND
, OR
, und NOT
haben immer 0 und 1 als Ergebnis und lassen sich nicht wie in BASIC als bitweise Verknüpfungsoperatoren verwenden!
Arrayzugriffe[Bearbeiten | Quelltext bearbeiten]
name(n[,...])
Auf Arrayelemente wird über die Indexwerte in Klammern hinter dem Variablennamen zugegriffen.
Funktionsaufrufe[Bearbeiten | Quelltext bearbeiten]
name[(parameterliste)]
Funktionen werden durch ihren Namen aufgerufen. Falls die Funktion Parameter erwartet, werden diese in Klammern und durch Kommas getrennt übergeben.
Grundrechenarten[Bearbeiten | Quelltext bearbeiten]
a + b a - b a * b a / b a ↑ b
Die bekannten Grundrechenarten Addition, Subtraktion, Multiplikation, Division, und Potenz für numerische Ausdrücke.
+
kann auch zum verbinden von Zeichenketten verwendet werden.
Relationale Operatoren[Bearbeiten | Quelltext bearbeiten]
a < b a <= b a = b a >= b a > b a <> b
Logische Vergleichsoperatoren die auf zwei Zahlen oder zwei Zeichenketten operieren und 1 liefern, falls die Beziehung stimmt, und 0 sonst.
Zeichenketten werden auf Basis der Zahlwerte zu den Zeichencode verglichen. Siehe auch die ORD
-Funktion.
Operator | Bedeutung |
---|---|
<
|
kleiner |
<=
|
kleiner oder gleich |
=
|
gleich |
>=
|
grösser oder gleich |
>
|
grösser |
<>
|
ungleich |
Teilzeichenketten[Bearbeiten | Quelltext bearbeiten]
zeichenkette(start:ende)
Mit dieser Syntax kann man auf Teilzeichenketten zugreifen. Das Ergebnis des Ausdrucks ist eine Zeichenkette mit allen Zeichen von start
bis einschliesslich ende
. Das erste Zeichen hat die Position 1.
AND[Bearbeiten | Quelltext bearbeiten]
ausdruck_a AND ausdruck_b
Ist genau dann 1, wenn sowohl ausdruck_a
als auch ausdruck_b
wahr ist.
a
|
b
|
a AND b
|
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
DIV[Bearbeiten | Quelltext bearbeiten]
a DIV b
Diese Operation liefert den ganzzahligen Teil einer Division.
Siehe auch MOD
.
FALSE[Bearbeiten | Quelltext bearbeiten]
Alias für den numerischen Wert 0.
MOD[Bearbeiten | Quelltext bearbeiten]
a MOD b
Der Modulo-Operator liefert den Rest einer ganzzahligen Division. a MOD b
ist äquivalent zu (a - (a DIV b) * b)
. Das zweite Argument muss positiv sein.
Siehe auch DIV
.
IN[Bearbeiten | Quelltext bearbeiten]
zeichenketten_ausdruck_a IN zeichenketten_ausdruck_b
Dieser Operator liefert die Startposition von der Zeichenkette vor dem Operator in der Zeichenkette nach dem Operator. Sollte es keine Fundstelle geben, liefert die Operation den Wert 0. Damit kann dieser Operator in logischen Ausdrücken auch als Test auf enthalten sein verwendet werden.
Eine leere Zeichenkette ist in keiner anderen Zeichenkette enthalten.
NOT[Bearbeiten | Quelltext bearbeiten]
NOT ausdruck
Negiert den Wert vom Ausdruck, also 1 falls der Ausdruck 0 ergibt, 0 sonst.
OR[Bearbeiten | Quelltext bearbeiten]
ausdruck_a OR ausdruck_b
Ist genau dann 1, wenn mindestens einer der beiden Ausdrücke wahr ist.
a
|
b
|
a OR b
|
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
TRUE[Bearbeiten | Quelltext bearbeiten]
Alias für den numerischen Wert 1.
Anweisungen[Bearbeiten | Quelltext bearbeiten]
Zuweisung[Bearbeiten | Quelltext bearbeiten]
name:=ausdruck [; ...]
Mehrere Zuweisungen können durch Semikolon getrennt in der gleichen Zeile stehen.
Marke (:
)[Bearbeiten | Quelltext bearbeiten]
name:
Benannte Marke als Ziel für GOTO
oder RESTORE
.
APPEND[Bearbeiten | Quelltext bearbeiten]
Siehe OPEN
.
CASE[Bearbeiten | Quelltext bearbeiten]
CASE ausdruck OF WHEN werteliste zeilen [WHEN werteliste zeilen] [OTHERWISE zeilen] ENDCASE
Der Ausdruck wird ausgewertet und dann wird das Ergebnis mit den durch Komma getrennten Werten der WHEN
-Anweisungen verglichen. Beim ersten WHEN
wo ein Treffer vorhanden ist, werden die dazugehörigen Zeilen ausgeführt und danach läuft das Programm nach dem ENDCASE
weiter. Man kann beliebig viele WHEN
-Anweisungen verwenden. Optional lässt sich mit OTHERWISE
noch angeben was gemacht werden soll, falls kein WHEN
einen passenden Wert hatte.
BASIC's ON ausdruck GOTO|GOSUB zeilennummern
lassen sich in COMAL als CASE
-Anweisungen ausdrücken. CASE
ist etwas flexibler, weil pro WHEN
mehr als ein Vergleichswert verwendet werden kann und nicht nur zusammenhängende Zahlenreihen auf Code abgebildet werden können, sondern auch Zeichenketten.
CLOSE[Bearbeiten | Quelltext bearbeiten]
CLOSE [FILE kanalnummer]
Schliesst die Datei zu der angegebenen Kanalnummer. Ohne Kanalnummer werden alle offenen Dateien geschlossen.
Siehe auch OPEN
.
CLOSED[Bearbeiten | Quelltext bearbeiten]
Deklariert eine Prozedur oder Funktion als geschlossen. Siehe PROC
.
DATA[Bearbeiten | Quelltext bearbeiten]
DATA werteliste
Legt Werte im Programm ab, die mit READ
nacheinander in Variablen gelesen werden können. Mit der RESTORE
-Anweisung kann man festlegen, dass das nächste READ
wieder vom ersten Datenlement oder von einem bestimmten, durch eine benannte Marke gekennzeichnetes Element an. Mit der EOD
-Funktion kann man prüfen ob noch ungelesene Daten vorhanden sind.
Jede DATA
-Anweisung erweitert die globale Werteliste, auch <DATA>
-Anweisungen in geschlossenen Prozeduren und Funktionen!
Der Standard empfielt als gute Programmierpraxis DATA
-Zeilen am Programmende und am Ende von Prozeduren und Funktionen zu platzieren.
Siehe auch READ
, die EOD
-Funktion, und RESTORE
.
DELETE[Bearbeiten | Quelltext bearbeiten]
DELETE dateiname
Löscht die Datei mit dem angegebenen Namen.
DIM[Bearbeiten | Quelltext bearbeiten]
DIM name(dimensionen)|name$[(dimensionen)] [OF laenge][, ...]
Dimensioniert Arrays und Zeichenketten. Arrays können beliebig viele Dimensionen haben. Mehrere Dimensionen werden durch Kommas getrennt. Jede Dimension wird als [untergrenze:]obergrenze
angegeben. Wenn die optionale Untergrenze weg gelassen wird, dann wird 1 angenommen. Die Grenzen können auch negativ sein, solange die Untergrenze kleiner als die Obergrenze ist.
Beispiele:
DIM a(0,10),feld(-1:1,-1:1),k$ OF 1,filenames$(144) OF 16,buffer$ OF 1000
Hier werden folgende Variablen dimensioniert:
- ein numerisches Array
a
mit 11 Elementen, - ein zweidimensionales numerisches Array
feld
mit 3×3=9 Elementen, bei dem der Index 0,0 für das mittlere Feld steht, - eine Zeichenkette
k
mit der maximalen Länge 1. - ein Zeichenkettenarray
filenames$
mit 144 Elementen, wobei jedes Element die maximale Länge 16 hat. - eine Zeichenkette
buffer$
mit einer maximalen Länge von 1000.
Zeichenketten die verwendet werden ohne vorher DIM
ensioniert zu werden, haben eine maximale Länge von 40.
Arrays und Zeichenketten können wie in BASIC nur einmal mit DIM
dimensioniert werden. Ein weiterer Versuch endet in einem Programmabbruch und einer Laufzeitfehlermeldung. Es gibt kein REDIM
wie in einigen BASIC-Dialekten. Allerdings existieren lokale Variablen in geschlossenen Prozeduren und Funktionen nur solange die Prozedur oder Funktion läuft. Bei jedem Aufruf kann also die lokale Variable erneut dimensioniert werden. Während bei
LOOP INPUT "Anzahl Elemente: ": n DIM x(n) // Etwas mit n Elementen machen. ENDLOOP
beim zweiten Schleifendurchlauf eine Fehlermeldung bei dem Versuch x
erneut zu dimensionieren kommt, ist folgendes kein Problem, weil das lokale Array x
bei jedem Aufruf erneut angelegt wird:
LOOP INPUT "Anzahl Elemente: ": n verarbeitung(n) ENDLOOP PROC verarbeitung(n) CLOSED DIM x(n) // Etwas mit n Elementen machen. ENDPROC verarbeitung
Programmierer die von BASIC kommen, müssen darauf achten, dass ein DIM(n)
in BASIC eine feste Untergrenze von 0 hat, die man in COMAL explizit angeben muss, also das Gegenstück ein DIM(0:n)
ist. Und während Zeichenketten in COMAL zwar länger als 255 Zeichen sein dürfen, muss man alles was über 40 Zeichen hinausgehen soll, vorher entsprechend dimensionieren.
DO[Bearbeiten | Quelltext bearbeiten]
Siehe FOR
und WHILE
.
DOWNTO[Bearbeiten | Quelltext bearbeiten]
Negiert die Schrittweite einer FOR
-Schleife. Siehe FOR
.
ELIF[Bearbeiten | Quelltext bearbeiten]
Kombiniert ELSE
und IF
um eine zusätzliche Verschachtelungsebene zu vermeiden. Siehe IF
.
ELSE[Bearbeiten | Quelltext bearbeiten]
Siehe IF
.
ENDCASE[Bearbeiten | Quelltext bearbeiten]
Siehe CASE
.
ENDFOR[Bearbeiten | Quelltext bearbeiten]
Ende einer FOR
-Schleife. Siehe FOR
.
ENDFUNC[Bearbeiten | Quelltext bearbeiten]
Siehe FUNC
.
ENDIF[Bearbeiten | Quelltext bearbeiten]
Siehe IF
.
ENDPROC[Bearbeiten | Quelltext bearbeiten]
Ende einer Prozedur. Siehe PROC
.
ENDWHILE[Bearbeiten | Quelltext bearbeiten]
Ende einer WHILE
-Schleife. Siehe WHILE
.
EXEC[Bearbeiten | Quelltext bearbeiten]
[EXEC] prozedurname[(parameterliste)]
Aufruf einer Prozedur. EXEC
ist optional. Die Parameter, sofern vorhanden, werden durch Kommas getrennt.
Siehe auch PROC
.
FILE[Bearbeiten | Quelltext bearbeiten]
Siehe INPUT
, OPEN
, READ
, WRITE
, PRINT
, und CLOSE
.
FOR[Bearbeiten | Quelltext bearbeiten]
FOR variable:=ausdruck [DOWN]TO ausdruck [STEP ausdruck] DO einfache anweisung
FOR variable:=startwert [DOWN]TO endwert [STEP schrittweite] DO zeilen ENDFOR [variable]
For Ausführung der Schleife wird die Steuervariable auf den Startwert gesetzt, der Endwert einmal ausgerechnet, und die Schrittweite festgelegt. Ohne STEP
-Angabe ist die Schrittweite 1.
Ein DOWNTO
statt eines TO
negiert die Schrittweite. FOR n:=10 TO 1 STEP -1 DO …
entspricht also FOR n:=10 DOWNTO 1 DO …
.
Im Gegensatz zu BASIC findet die Prüfung der Abbruchbedingung vor jedem Eintritt in den Schleifenkörper statt. Das heisst man braucht in COMAL kein zusätzliches IF
um zu verhindern, dass eine FOR
-Schleife in jedem Fall mindestens einmal ausgeführt wird.
Ob die Steuervariable lokal zum Schleifenkörper ist oder nicht, hängt von der Implementierung ab.
FUNC[Bearbeiten | Quelltext bearbeiten]
Definiert eine Funktion. Funktionen entsprechen vom Aufbau her Prozeduren mit FUNC
und ENDFUNC
statt PROC
und ENDPROC
.
Funktionen werden Aufgerufen in dem man sie wie eingebaute Funktionen innerhalb eines Ausdrucks verwendet.
Sie müssen mit einem RETURN
enden bei dem der Rückgabewert der Funktion als Ausdruck angegeben wird. Solle das Programm bis zum ENDFUNC
laufen ohne vorher auf ein RETURN
getroffen zu sein, bricht das Programm mit einer Laufzeitfehlermeldung ab.
DEF FNname(x)=ausdruck
aus BASIC entspricht in COMAL einer offenen Funktion mit einem Argument, die nur aus einem RETURN
und dem entsprechenden Ausdruck besteht:
FUNC name(x) RETURN ausdruck ENDFUNC name
Siehe auch PROC
.
GOTO[Bearbeiten | Quelltext bearbeiten]
GOTO marke
Der Programmfluss wird ab der Zeile mit der benannten Marke fortgeführt.
Man kann mit GOTO
nicht in Strukturen oder Prozeduren und Funktionen hinein springen und auch nicht aus Prozeduren und Funktionen heraus. Allerdings kann man damit Schleifen und Entscheidungsstrukturen verlassen. Auch über mehrere Ebenen hinweg.
Siehe auch :
.
IF[Bearbeiten | Quelltext bearbeiten]
IF bedingung THEN einfache anweisung
IF bedingung THEN zeilen [ELIF bedingung zeilen] [ELSE zeilen] ENDIF
In der Kurzform wird eine Anweisung ausgeführt falls die Bedingung zutrifft.
In der Langform kann man nicht nur mehrere Anweisungen ausführen, sondern optional mit ELIF
auch weitere Bedingungen prüfen, falls die vorherige(n) Prüfung(en) nicht zutrafen. Der ELIF
-Teil kann beliebig oft wiederholt werden.
Falls keine der Bedingungen zutraf, kann man mit einem optionalen ELSE
-Zweig noch festlegen was diesem Fall passieren soll.
IMPORT[Bearbeiten | Quelltext bearbeiten]
Importiert Namen in eine geschlossene Funktion oder Prozedur. Siehe PROC
.
INPUT[Bearbeiten | Quelltext bearbeiten]
INPUT [zeichenkette:] variable [,|;] INPUT FILE kanalnummer[,datensatznummer]: variablenliste
In der ersten Variante werden Informationen vom Benutzer erfragt. Die optionale Zeichenkette wird statt eines Standard-Prompt ausgegeben, "?"
in den UniComal-Implementierungen, und der Benutzer kann dann einen passenden Wert eingeben, der der Variable zugewiesen wird. Sollte die Eingabe nicht zum Typ der Variable passen, wird eine Fehlermeldung ausgegeben und die Aufforderung wiederholt.
Das optionale Komma oder Semikolon am Ende hat die gleiche Bedeuting wie bei PRINT
.
In der zweiten Variante werden die Daten aus einer Datei gelesen und es können mehrere Variablen angegeben werden. Eine Datensatznummer darf nur für Dateien angegeben werden, die im RANDOM
-Modus geöffnet wurde.
Siehe auch PRINT
, OPEN
, READ
, WRITE
, und CLOSE
.
OF[Bearbeiten | Quelltext bearbeiten]
Siehe CASE
und DIM
.
OTHERWISE[Bearbeiten | Quelltext bearbeiten]
Siehe CASE
.
OPEN[Bearbeiten | Quelltext bearbeiten]
OPEN FILE kanalnummer,dateiname,[READ|WRITE|APPEND|RANDOM länge [READONLY|WRITEONLY]]
Öffnet die Datei mit dem gegebenen Dateinamen zum Lesen, Schreiben, Anhängen, oder als Binärdatei mit einer festen Datensatzlänge und weist die Datei der angegebenen Kanalnummer zu. Über die Kanalnummer wird die Datei bei anderen dateirelevanten Anweisungen und Funktionen identifiziert.
Der RANDOM
OUTPUT[Bearbeiten | Quelltext bearbeiten]
Siehe SELECT
.
PRINT[Bearbeiten | Quelltext bearbeiten]
PRINT [FILE kanalnummer[,datensatznummer]] ausgabeliste [,|;] PRINT [FILE kanalnummer[,datensatznummer]] USING format: werteliste [,|;]
Textausgabe auf den Bildschirm oder in eine Datei mit der angegebenen Kanalnummer. Eine Datensatznummer ist nur bei Dateien erlaubt, die im Modus RANDOM
geöffnet wurden.
Die Ausgabeliste besteht aus Ausdrücken die durch ,
oder ;
getrennt sind. Ein ;
wird als Leerzeichen ausgegeben, während ein ,
so viele Leerzeichen ausgibt, dass der nächste Wert am Anfang der nächsten Aushabezone ausgegeben wird. Die Voreinstellung der Zonenbreite ist 0, das heisst es wird gar kein Leerzeichen zwischen den Werten ausgegeben.
Ein ,
oder ;
am Ende der Anweisung hat die eben beschriebene Bedeutung und unterbindet, dass die nächste Ausgabe am Anfang der nächsten Ausgabezeile beginnt.
Die Bedeutung von ,
und ;
bei der BASIC-PRINT
-Anweisung fallen in COMAL beide auf das ,
mit einem unterschiedlichen Wert für die Zonenbreite. Das ,
aus BASIC entspricht der Zonenbreite 10 und ;
aus BASIC entspricht der Zonenbreite 0.
Die USING
-Variante formatiert numerische Werte in eine Zeichenkette die Platzhalter für Zahlen enthält. Und zwar ein #
-Zeichen pro Ziffer. Ein einzelner .
steht für den Dezimalpunkt an dem der Dezimalpunkt der Zahl ausgerichtet wird. Nach dem Doppelpunkt folgt eine durch Kommas getrennte Liste von numerischen Ausdrücken. Einer pro Platzhalter für eine Zahl. Falls die Zahl mehr Ziffern hat als Platzhalter für einzelne Ziffern vorsieht, werden *
-Zeichen statt Ziffern ausgegeben.
Siehe auch OPEN
, und ZONE
.
PROC[Bearbeiten | Quelltext bearbeiten]
PROC name [(parameterliste)] [CLOSED] [IMPORT namensliste] zeilen ENDPROC name
Definiert eine Prozedur die über ihren Namen aufgerufen werden kann.
Es können optional formale Parameter angegeben werden, die man dann beim Aufruf angeben muss. Die Namen dieser Parameter sind lokal zur Prozedur gültig, das heisst sie haben keinen Einfluss auf Variablen mit gleichen Namen ausserhalb der Prozedur oder Funktion.
Mit dem Schlüsselwort REF
können Parameter als Referenzparameter deklariert werden, das heisst der Name ist nur ein Alias für den beim Aufruf übergebenen Parameter und Änderungen wirken sich auf die Ursprungsvariable aus. Arrays müssen als Referenzparameter übergeben werden!
Prozeduren und Funktionen können offen und geschlossen sein. Offene Prozeduren und Funktionen können auf alle Variablen in ihrer Umgebung zugreifen und sie verändern. Geschlossene Prozeduren und Funktionen werden mit dem Zusatz CLOSED
deklariert, und können das nicht.
Um auf Variablen oder andere Prozeduren und Funktionen die ausserhalb von geschlossenen Prozeduren und Funktionen zugreifen zu können, müssen diese mit IMPORT
bekannt gemacht werden.
Die Ausführung einer Prozedur wird durch das Ereichen von ENDPROC
oder einer RETURN
-Anweisung beendet. Das Programm fährt dann mit den Anweisungen nach dem Aufruf fort.
Prozeduren und Funktionen können auch verschachtelt werden, also innerhalb von anderen Prozeduren und Funktionen definiert werden.
Da die Argumente nur lokal gültig sind, können Prozeduren und Funktionen rekursiv aufgerufen werden.
Offene Prozeduren ohne Parameter entsprechen in etwa Unterprogrammen mit GOSUB
und RETURN
in BASIC.
Siehe auch EXEC
für den Aufruf einer Prozedur und FUNC
für benutzerdefinierte Funktionen.
RANDOM[Bearbeiten | Quelltext bearbeiten]
Siehe OPEN
.
RANDOMIZE[Bearbeiten | Quelltext bearbeiten]
RANDOMIZE [ausdruck]
Setzt den Zustand des Zufallszahlengenerators auf den angegebenen Wert, oder einen zufälligen Wert wenn kein Wert angegeben wird. Letzteres braucht man eigentlich nicht, weil das vor der Ausführung von einem Programm automatisch passiert.
Einen Wert zu setzen macht beispielsweise Sinn, wenn man wiederholt die gleiche Folge von Zufallszahlen benötigt, beispielsweise um eine Simulation mit Zufallszahlen zu dem gleichen Ergebnis kommen zu lassen.
READ[Bearbeiten | Quelltext bearbeiten]
READ variablenliste READ FILE kanalnummer[,datensatznummer]: variablenliste
Die erste Form liest Daten aus DATA
-Zeilen in die angegebenen Variablen.
In der zweiten Form werden die Daten als Binärdaten aus der angegebenen Datei und der optionalen Datensatznummer in die angegebenen Variablen gelesen.
Die Angabe einer Datensatznummer ist nur bei Dateien erlaubt, die im RANDOM
-Modus geöffnet wurden.
Das Format der Binärdaten ist implementierungsabhängig. Bei den Commodore-8-Bit-Rechner werden Gleitkommazahlen im gleichen Format gespeichert wie BASIC sie im Speicher ablegt. Ganze Zahlen werden als zwei Bytes gespeichert. Bei Zeichenketten wird die Länge als Ganzzahl gespeichert, gefolgt von der Anzahl der Zeichen.
Siehe auch OPEN
, WRITE
, und CLOSE
.
READONLY[Bearbeiten | Quelltext bearbeiten]
Siehe OPEN
.
REPEAT[Bearbeiten | Quelltext bearbeiten]
REPEAT zeilen UNTIL bedingung
Die Zeilen werden solange wiederholt ausgeführt bis die Bedingung eintrifft. Die Bedingung wird am Ende von jedem Schleifendurchlauf geprüft.
RESTORE[Bearbeiten | Quelltext bearbeiten]
RESTORE [marke]
Setzt den Zeiger für die per DATA
im Programm eingebetteten Werte auf den ersten Wert im Quelltext, oder auf den ersten Wert der auf die benannte Marke folgt.
Siehe auch DATA
, :
und die EOD
-Funktion.
RETURN[Bearbeiten | Quelltext bearbeiten]
RETURN [ausdruck]
Beendet eine Prozedur oder Funktion. Die Variante mit einem Ausdruck ist nur in Funktionen erlaubt. Siehe auch PROC
und FUNC
.
SELECT[Bearbeiten | Quelltext bearbeiten]
SELECT OUTPUT dateiname
Wählt die Ausgabedatei für normale Ausgaben. Neben normalen Textdateien gibt es noch die Gerätedateien "LP:" für den Drucker und "DS:" für den Bildschirm.
Man kann damit die kompletten Ausgaben auf dem Bildschirm in eine Datei oder auf einen Drucker umleiten.
Das enpricht in etwa dem CMD
-Befehl aus BASIC.
STEP[Bearbeiten | Quelltext bearbeiten]
Gibt die Schrittweite einer FOR
-Schleife an. Siehe FOR
.
STOP[Bearbeiten | Quelltext bearbeiten]
STOP [zeichenkette]
Unterbricht das Programm an dieser Stelle und gibt die Zeichenkette aus. Das Programm kann mit CON
nach der STOP
-Anweisung fortgesetzt werden.
Siehe auch CON
.
THEN[Bearbeiten | Quelltext bearbeiten]
Siehe IF
.
TO[Bearbeiten | Quelltext bearbeiten]
Siehe FOR
.
UNTIL[Bearbeiten | Quelltext bearbeiten]
Siehe REPEAT
.
USING[Bearbeiten | Quelltext bearbeiten]
Siehe PRINT
.
WHEN[Bearbeiten | Quelltext bearbeiten]
Siehe CASE
.
WHILE[Bearbeiten | Quelltext bearbeiten]
WHILE bedingung DO einfache anweisung
WHILE begdingung DO zeilen ENDWHILE
Schleife deren DO
-Teil solange wiederholt wird, wie die Bedingung wahr ist. Die Bedingung wird vor jedem Schleifendurchlauf getestet.
WRITE[Bearbeiten | Quelltext bearbeiten]
WRITE FILE kanalnummer[,datensatznummer]: variablenliste
Die Werte der angegebenen Variablen werden als Binärdaten in die Datei geschrieben. Falls eine Datensatznummer angegeben ist, was nur bei RANDOM
-Dateien erlaubt ist, wird vor dem Schreiben der entsprechende Datensatz angewählt.
Siehe auch OPEN
, READ
, und CLOSE
.
WRITEONLY[Bearbeiten | Quelltext bearbeiten]
Siehe OPEN
.
ZONE[Bearbeiten | Quelltext bearbeiten]
ZONE ausdruck
Legt die Breite der Ausgabezonen fest. Die Ausgabezeile wird in Zonen gleicher Breite eingeteilt. Siehe die Verwendung des ,
bei PRINT
.
Siehe auch PRINT
und INPUT
.
Eingebaute Funktionen[Bearbeiten | Quelltext bearbeiten]
Trigonomische Funktionen[Bearbeiten | Quelltext bearbeiten]
COS(n) SIN(n) TAN(n) ATN(n)
Berechnet den Cosinus, Sinus, Tangens, oder Arcustangens vom in Radiant angegeben Wert.
ABS[Bearbeiten | Quelltext bearbeiten]
ABS(n)
Ermittelt den Betrag des angegeben Wertes.
CHR$[Bearbeiten | Quelltext bearbeiten]
CHR$(n)
Erstellt eine Zeichenkette der Länge 1 aus dem numerischen Zeichenwert. Das Gegenstück ist die ORD
-Funktion.
EOD[Bearbeiten | Quelltext bearbeiten]
EOD
Steht für „end of data“ und prüft ob es noch Werte aus DATA
-Zeilen zum lesen gibt.
Siehe auch DATA
und READ
.
EOF[Bearbeiten | Quelltext bearbeiten]
EOF(kanalnummer)
Steht für „end of file“ und prüft ob es noch Daten in der Datei mit der gegeben Kanalnummer zum lesen gibt.
Siehe auch OPEN
, INPUT
, und READ
.
EXP[Bearbeiten | Quelltext bearbeiten]
EXP(n)
Berechnet den natürlichen Exponenten des angegeben Wertes.
INT[Bearbeiten | Quelltext bearbeiten]
INT(n)
Liefert den zum Argument nächstkleineren ganzzahligen Wert.
LEN[Bearbeiten | Quelltext bearbeiten]
LEN(zeichenkette)
Liefert die Länge der Zeichenkette.
LOG[Bearbeiten | Quelltext bearbeiten]
LOG(n)
Berechnet den natürlichen Logarithmus des angegebenen Wertes.
ORD[Bearbeiten | Quelltext bearbeiten]
ORD(zeichenkette)
Liefert den Zahlwert des ersten Zeichens in der gegebenen Zeichenkette. Das Gegenstück ist die CHR$
-Funktion.
Diese Funktion entspricht der ASC
-Funktion aus BASIC.
RND[Bearbeiten | Quelltext bearbeiten]
RND RND(a,b)
Liefert in der ersten Variante eine Zahl grösser oder gleich 0 und kleiner als 1.
In der zweiten Variante wird eine ganze Zahl aus dem Intervall von a bis b geliefert. Das entspricht INT(RND*(b-a))+a
.
SGN[Bearbeiten | Quelltext bearbeiten]
SGN(n)
Liefert -1 für negative Zahlen, 0 für eine 0, und 1 für positive Zahlen.
SQR[Bearbeiten | Quelltext bearbeiten]
SQR(n)
Berechnet die Quadratwurzel des angegebenen Wertes.
STR$[Bearbeiten | Quelltext bearbeiten]
STR$(n)
Der übergebene numerische Wert wird in eine Zeichenkette umgewandelt.
VAL[Bearbeiten | Quelltext bearbeiten]
VAL(zeichenkette)
Wandelt die Zeichenkette in eine Zahl um. Die Zeichenkette kann die gleiche Form haben in der man Zahlen auch im Quelltext schreiben kann.
Kommandos[Bearbeiten | Quelltext bearbeiten]
Kommandos können nich innerhalb des Programms verwendet werden, sondern nur im Direktmodus. Die meisten dienen der Bearbeitung von Programmen.
AUTO[Bearbeiten | Quelltext bearbeiten]
AUTO [start][,schrittweite]
Gibt automatisch Zeilennummern beginnend mit dem Startwert in der Schrittweite vor. Voreinstellung für beide Werte ist 10.
CAT[Bearbeiten | Quelltext bearbeiten]
CAT
Listet das Inhaltsverzeichnis direkt von der Diskette auf den Bildschirm auf. Ein Programm im Speicher bleibt dabei erhalten.
CON[Bearbeiten | Quelltext bearbeiten]
CON
Kurz für „continue“, setzt ein mit der STOP
-Anweisung unterbrochenes Programm fort, sofern das Programm zwischenzeitlich nicht verändert wurde. Variableninhalte dürfen dagegen verändert werden.
DEL[Bearbeiten | Quelltext bearbeiten]
DEL zeile | [startzeile]-[endzeile] | name
Löscht eine angegebene Zeile oder einen Bereich von Zeilen aus dem Programm. Man kann bei der Bereichsangabe entweder den Startwert oder den Endwert weg lassen, dann werden alle Zeilen vom Programmanfang bis zum Endwert oder alles vom Startwert bis zum Programmende gelöscht.
Der Bereich kann auch als Prozedur- oder Funktionsname angegeben werden.
DISPLAY[Bearbeiten | Quelltext bearbeiten]
DISPLAY [[start]-[ende]|name][,dateiname] DISPLAY dateiname
Listet das Programm oder einen Bereich ohne Zeilennummern auf. Der Bereich kann als Start- und Endzeile angegeben werden, oder als Prozedur- oder Funktionsname.
Wenn ein Dateiname angegeben wird, dann wird die Auflistung als Textdatei erstellt.
Siehe auch LIST
.
ENTER[Bearbeiten | Quelltext bearbeiten]
ENTER dateiname
Gibt eine Textdatei als Programm ein. Das Programm im Speicher wird ersetzt.
Eine Quelltextdatei kann mit LIST
erstellt werden, aber auch mit einem Texteditor.
Mit DISPLAY
erstellte Textdateien lassen sich nicht mit ENTER
einlesen, da dort keine Zeilennummern vorhanden sind.
Siehe auch NEW
und LIST
.
LIST[Bearbeiten | Quelltext bearbeiten]
LIST [[start]-[ende]|name][,dateiname] LIST dateiname
Listet das Programm oder einen Bereich mit Zeilennummern auf. Der Bereich kann als Start- und Endzeile angegeben werden, oder als Prozedur- oder Funktionsname.
Wenn ein Dateiname angegeben wird, dann wird die Auflistung als Textdatei erstellt.
Siehe auch DISPLAY
und ENTER
.
LOAD[Bearbeiten | Quelltext bearbeiten]
LOAD dateiname
Lädt ein Programm im Binärformat. Das Programm im Speicher wird ersetzt.
Siehe auch SAVE
, NEW
, und RUN
.
NEW[Bearbeiten | Quelltext bearbeiten]
NEW
Löscht ein im Speicher befindliches Programm.
RENUMBER[Bearbeiten | Quelltext bearbeiten]
RENUM[BER] [startzeile[,schrittweite]]
Nummeriert die Programmzeilen neu durch. Voreinstellung für Startzeile und Schrittweite ist 10.
RUN[Bearbeiten | Quelltext bearbeiten]
RUN [dateiname]
Startet das im Speicher befindliche Programm oder lädt und startet das Programm mit dem angegebenen Dateinamen.
Siehe auch LOAD
und SAVE
.
SAVE[Bearbeiten | Quelltext bearbeiten]
SAVE dateiname
Sichert das im Speicher befindliche Programm im Binärformat unter dem angegebenen Dateinamen.
Siehe auch LOAD
und RUN
.
SIZE[Bearbeiten | Quelltext bearbeiten]
SIZE
Zeigt den belegten Programm- und Datenspeicher und die noch verbleibenden freien Bytes an.
Beispiel[Bearbeiten | Quelltext bearbeiten]
Beispiel für ein strukturiertes Programm in Comal mit aussagekräftigen Namen für Unterprozeduren und Variablen. Die Zeilennummern dienen in Comal nur noch als Angabe der Reihenfolge der Quelltextzeilen, nicht mehr als Sprungziele wie in BASIC.
Die dargestellte Formatierung des Quelltextes wird von Comal automatisch beim Auflisten vorgenommen, die interne Darstellung ist kompakter.
Alle Beispiele können ab COMAL-Version 2.01 auf einem C64 ausgeführt werden:
- Version 1
0010 PROC set'cursor(x#,y#) CLOSED 0020 POKE 211,x# 0030 POKE 214,y# 0040 SYS 58640 0050 ENDPROC set'cursor 0060 0070 PROC set'color(color#) CLOSED 0080 POKE $d020,color# // 53280 0090 POKE $d021,color# // 53281 0100 ENDPROC set'color 0110 0120 PRINT ""147""; // Clear Screen 0130 PRINT "!!! Das C64-Wiki Sterne-Demo !!!" 0140 farbe#:=0 0150 set'color(farbe#) 0160 0170 // Endlosschleife. 0180 // Kann nur mit RUN/STOP abge- 0190 // brochen werden. 0200 WHILE TRUE DO 0210 farbe#:=RND(0,15) 0220 POKE 646,farbe# // Textfarbe 0230 set'cursor(RND(0,39),RND(0,24)) 0240 PRINT "*"; 0250 // 1/25 Chance, dass Hintergrund- 0260 // farbe geaendert wird. 0270 IF RND(1,25)=1 THEN 0280 set'color(farbe#) 0290 ENDIF 0300 ENDWHILE
- Version 2
0010 USE system 0020 PAGE // Clear Screen 0030 PRINT "!!! Das C64-Wiki Sterne-Demo !!!" 0040 farbe#:=0 0050 textcolors(farbe#,farbe#,-1) 0060 0070 // Endlosschleife. 0080 // Kann nur mit RUN/STOP abge- 0090 // brochen werden. 0100 LOOP 0110 farbe#:=RND(0,15) 0120 textcolors(-1,-1,farbe#) // Textfarbe 0130 PRINT AT RND(1,25),RND(1,40): "*", 0140 // 1/25 Chance, dass Hintergrund- 0150 // farbe geaendert wird. 0160 IF RND(1,25)=1 THEN textcolors(farbe#,farbe#,-1) 0170 ENDLOOP
Implementierungen[Bearbeiten | Quelltext bearbeiten]
C64[Bearbeiten | Quelltext bearbeiten]
C128[Bearbeiten | Quelltext bearbeiten]
CBM[Bearbeiten | Quelltext bearbeiten]
- rev. 1.02 (PET library disk L0-3)
Literatur[Bearbeiten | Quelltext bearbeiten]
- Buch: Neuber, Sperling: "COMAL 2.01 Handbuch für Commodore 64", 1986
- Buch: F. Nestle u. D. Pohlmann: "Comal 80 Programmierpraxis", 1987
- Buch: H. Göhner, B. Hafenbrak "Arbeitsbuch COMAL", 1988
- Buch: Volker Fischer: "MikroComputer-Praxis: COMAL in Beispielen"; Teubner, Stuttgart; 1986
- Was ist Comal in 64'er, August 1984, Seiten 41-43
- Comal - eine Einführung von Volker Everts in 64'er,
- Teil 1: Nov. 1984, Seiten 44-47
- Teil 2: Dez. 1984, Seiten 145-147
- Teil 3: Feb. 1985, Seiten 130-132
- COMAL in Neue Möglichkeiten mit dem Commodore 64 (128), Kap. 6/4
- Englischsprachige Literatur
- Borge R. Christensen: "COMAL Reference Guide", 1984
- Borge Christensen: "Beginning COMAL"; Ellis Horwood Limited, Chichester; 1985
- Len Lindsay: "COMAL Handbook; Reston Publishing Company, Virginia, 1983
- Len Lindsay: "The COMAL Handbook - Second Edition (Now for the Commodore 64"; Reston Publishing Company, Virginia, 1983/84
- Frank Bason, Leo Höjsholt-Poulsen: "COMAL 80 for the Commodore 64"; Commodore DATA A/S, Horsens, Dänemark; 1985 /
- Marcus Bowmann, Stepehn Pople: "COMAL Programming Guide"; Heinemann Educational Books, Lodnon, 1988
- Ingvar Gratte: "Starting with COMAL"; Prentice/Hall International, England; 1985
- J. William Leary: "COMAL Introduction to Computer Programming with comal 80 and the commodore 64/128"; CMAL Users Group, U.S.A., Limited; 1985/86
- Roy Atherton: "Structured Programming with Comal" (The Ellis Hoorwood Series in Computers and Their Applications); University of London; Ellis Horwood Limited, Chichester; 1982/85
- John Kelly: "Foundation in Computer Studies with COMAL Second Edition"; Cahill Printers Limited, Dublin, Ireland; 1984
- Online
Weblinks[Bearbeiten | Quelltext bearbeiten]
Wikipedia: COMAL |
- engl. COMAL-Bücher als PDF auf www.bombjack.org
Quellen
- ↑ Len Lindsay: "The COMAL Handbook - Second Edition (Now for the Commodore 64"; Reston Publishing Company, Virginia, 1983/84; S.2/3
- ↑ UniCOMAL: "Amiga COMAL", 1990