Comal

Aus C64-Wiki
Zur Navigation springenZur Suche springen

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).

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.


COMAL-80 (rev. 00.14) für den C64 als Diskettenversionen.
COMAL-80 (rev. 02.01) für den C64 auf Steckmodul.



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
  • 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 DIMensioniert 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]

Comal80 Cartridge Reversed

CBM[Bearbeiten | Quelltext bearbeiten]

  • rev. 1.02 (PET library disk L0-3)

Literatur[Bearbeiten | Quelltext bearbeiten]

Teil 1: Nov. 1984, Seiten 44-47
Teil 2: Dez. 1984, Seiten 145-147
Teil 3: Feb. 1985, Seiten 130-132
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 Sprache:englisch
  • 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 Sprache:englisch/Sprache:dänisch
  • Marcus Bowmann, Stepehn Pople: "COMAL Programming Guide"; Heinemann Educational Books, Lodnon, 1988 Sprache:englisch
  • 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]

WP-W11.png Wikipedia: COMAL


Quellen

  1. Len Lindsay: "The COMAL Handbook - Second Edition (Now for the Commodore 64"; Reston Publishing Company, Virginia, 1983/84; S.2/3 Sprache:englisch
  2. UniCOMAL: "Amiga COMAL", 1990 Sprache:englisch