____________________________________________________________________________ #on("b")##on ("u")# #center#Betriebssystem E U M E L #off ("u")# #center#Basic #off("b")# #center#Lizenzfreie Software der #on ("b")# #center#Gesellschaft für Mathematik und Datenverarbeitung mbH, #center#5205 Sankt Augustin #off("b")# #center#Die Nutzung der Software ist nur im Schul- und Hochschulbereich für #center#nichtkommerzielle Zwecke gestattet. #center#Gewährleistung und Haftung werden ausgeschlossen ____________________________________________________________________________ #page# #page nr ("%", 1)# #head# EUMEL-BASIC-Compiler Inhalt % #end# Inhalt 1 Einleitung 3 2 Installation des BASIC-Compilers 4 3 Aufruf und Steuerung des BASIC-Compilers 5 4 Umgang mit dem BASIC-Compiler 7 4.1 Erläuterungen zur Syntax 7 4.2 Datentypen und Konstanten 10 4.3 Variablen und Felder 12 4.4 Operatoren 14 4.5 Funktionen 19 4.6 Typanpassung 22 4.7 Aufruf von EUMEL-Prozeduren in BASIC-Programmen 23 5 Steuerung der Bildschirmausgaben 25 6 Grenzen des Compilers 26 7 Fehlerbehandlung 28 7.1 Fehler zur Übersetzungszeit 28 7.2 Fehler zur Laufzeit 30 8 Übersicht über die Anweisungen und Funktionen 31 9 Anpassung von Programmen an den EUMEL-BASIC-Compiler 96 9.1 Unterschiede zwischen BASIC-Interpretern und dem EUMEL-BASIC-Compiler 96 9.2 Abweichungen von ISO 6373-1984 (Minimal-BASIC) 97 9.3 Anpassung von Microsoft-BASIC Programmen an den EUMEL-BASIC-Compiler 98 Anhang A: Reservierte Wörter 100 Anhang B: Vom Scanner erkannte Symboltypen 103 Anhang C: Übersicht über die Fehlermeldungen 106 Anhang D: ELAN-Prozeduren des Compilers 113 #page# #page nr ("%", 3)# #head# EUMEL-BASIC-Compiler 1. Einleitung % #end# 1. Einleitung BASIC entspricht heute nicht mehr den Vorstellungen von einer modernen Program­ miersprache. Dennoch wurde für das EUMEL-Betriebssystem ein Compiler für BASIC entwickelt. Er soll vor allem dazu dienen, schon bestehende BASIC-Programme - gegebenenfalls nach entsprechender Anpassung - auch unter EUMEL verfügbar zu machen. Der Compiler ist weitgehend an die ISO-Norm 6373 für Minimal-BASIC angelehnt. Die Syntax und Bedeutung der Anweisungen orientiert sich in den meisten Fällen an Microsoft-BASIC. Anweichungen treten insbesondere an den Stellen auf, an denen Prinzipien des Betriebssystems EUMEL verletzt würden. Verglichen mit dem ELAN-Compiler des EUMEL-Systems ist der BASIC-Compiler beim Übersetzen recht langsam. Auch aus diesem Grund scheint es nicht sinnvoll, den BASIC-Compiler zur Neuentwicklung größerer Programme einzusetzen. Sinn dieses Handbuchs ist es vor allem, Kenntnisse über den Umgang mit dem EUMEL-BASIC-Compiler zu vermitteln. Das Handbuch ist auf keinen Fall als Ein­ führung in die Programmiersprache BASIC gedacht, sondern es soll dem Benutzer mit BASIC-Erfahrung die Arbeit mit dem EUMEL-BASIC-Compiler ermöglichen und erleichtern. Neben Erfahrung in BASIC setzt dieses Buch an einigen Stellen auch Grundkenntnisse über das EUMEL-System voraus. Zur #ib(4)#Notation#ie(4)# in dieser Beschreibung Bei der Beschreibung der Anweisungen und Funktionen und auch an anderen Stellen werden in dieser Beschreibung Syntaxregeln für BASIC-Programme oder Teile davon angegeben. Dabei werden folgende Zeichen mit besonderer Bedeutung verwendet: [ ] optionale Angabe [...] beliebig häufige Wiederholung der letzten optionalen Angabe | alternative Angabe, d.h. entweder die letzte links stehende Angabe oder die nächste rechts stehende Angabe, aber nicht beide < > in spitzen Klammern stehende Begriffe sind entweder definiert (z.B. ) oder werden hinter der Syntaxregel erläutert Die Notation der exportierten ELAN-Prozeduren des Compilers (besonders in An­ hangD) entspricht der in den EUMEL-Handbüchern üblichen Prozedurkopf- Schreibweise. #page# #head# EUMEL-BASIC-Compiler 2. Installation des BASIC-Compilers % #end# 2. #ib(3)#Installation des BASIC-Compilers#ie(3)# Der EUMEL-BASIC-Compiler wird auf zwei Disketten mit jeweils 360 KByte Speicherkapazität ausgeliefert. Auf der Diskette "BASIC.1" befindet sich das #ib(3)#Generatorprogramm#ie(3)#("gen.BASIC") zur Installation des EUMEL-BASIC-Systems. Legen Sie diese Diskette in das Laufwerk ihres Rechners ein und geben Sie in der Task, in der das BASIC-System installiert werden soll, folgende Zeile nach 'gib kommando :' (oder 'maintenance :') ein: archive ("BASIC.1"); fetch ("gen.BASIC", archive); run Lassen Sie die Diskette 'BASIC.1' im Laufwerk und antworten Sie auf die Frage "Archiv "BASIC.1" eingelegt(j/n)?" mit "j". Das Generatorprogramm holt nun einige Dateien von der Diskette. Nach Zugriff auf das Archiv erscheint die Meldung "Archiv abgemeldet!" und die Frage "Archiv 'BASIC.2' eingelegt(j/n)?". Legen Sie nun statt des Archivs 'BASIC.1' das Archiv 'BASIC.2' in das Laufwerk ein und drücken Sie bitte wiederum "j". Nach weiteren Archivoperationen erscheint dann wieder die Meldung "Archiv abgemeldet". Sie können nun die Diskette "BASIC.2" aus dem Laufwerk entnehmen. Das Generatorprogramm insertiert nun alle Programme des BASIC-Systems in der Task. Dieser Vorgang nimmt einige Zeit in Anspruch. Zum Abschluß erscheint die Meldung "BASIC-System installiert". Der EUMEL-BASIC-Compiler steht Ihnen nun in der Task (und in nachfolgend eingerichteten Söhnen) zur Verfügung. #page# #head# EUMEL-BASIC-Compiler 3. Aufruf und Steuerung des BASIC-Compilers % #end# 3. #ib(4)#Aufruf und #ib(3)#Steuerung des BASIC-Compilers#ie(3)##ie(4)# Übersetzen von BASIC-Programmen Ein BASIC-Programm, das vom Compiler übersetzt werden soll, muß sich dazu in einer EUMEL-Textdatei befinden (Syntax vgl. Kap. 4.). Steht das BASIC-Programm zum Beispiel in der Datei "Programm.17+4", so wird der Compiler mit #ib(3)#basic#ie(3)# ("Programm.17+4") zum Übersetzen dieses Programms aufgerufen. In einem Vordurchlauf werden die Zeilennummern des Programms auf Richtigkeit überprüft. Beim eigentlichen Compilerdurchlauf wird das BASIC-Programm dann mit Hilfe des EUMEL-Coders in einen von der EUMEL-0-Maschine ausführbaren Code übersetzt. Das Programm wird mit 'check on' (Zeilennummergenerierung) übersetzt. Ein 'runagain' wie bei ELAN-Programmen ist bei BASIC-Programmen zur Zeit leider nicht möglich. Insertieren von BASIC-Programmen Der BASIC-Compiler kann BASIC-Programme auch insertieren. Das ganze Pro­ gramm bildet dabei eine Prozedur, die nach dem Insertieren wie eine 'normale' ELAN-Prozedur aufgerufen werden kann. Zum Insertieren wird der Compiler mit einem zusätzlichen Text-Parameter aufge­ rufen: #ib(3)#basic#ie(3)# ("Programm.17+4", "blackjack") Das Programm wird übersetzt und, falls keine Fehler gefunden wurden, fest einge­ tragen ('insertiert'). Gestartet wird das Programm aber nicht. "blackjack" ist nun der Prozedurname, unter dem das BASIC-Programm nach erfolg­ reichem Insertieren aufgerufen werden kann. Bei 'packets' erscheint jetzt der Eintrag 'BASIC.blackjack' in der Liste der insertierten Pakete, und ein 'help ("blackjack")' zeigt, daß eine Prozedur 'blackjack' nun tatsäch­ lich in der Task bekannt ist. Die Prozedur 'bulletin' funktioniert für insertierte BASIC-Programme nicht. Sie ist aber auch nicht nötig, da das 'Paket' mit dem BASIC-Programm ohnehin nur eine Prozedur enthält und ihr Name ja schon aus dem Namen des Paketes hervorgeht. #on ("b")# Beachten Sie: - Der Prozedurname muß der Syntax für ELAN-Prozedurnamen entsprechen, darf aber #on ("b")#keine Leerzeichen enthalten. - Die BASIC-Programme können über den Prozedurnamen nur aufgerufen wer­ den; die Übergabe von Parametern ist ebenso wie Wertlieferung nicht möglich. - Jedes Insertieren belegt Speicherplatz im Codebereich der Task. Weil der Coder und der Compiler ebenfalls recht viel Code belegen, kann es (vor allem, wenn die BASIC-Programme lang sind) schnell zu einem Code-Überlauf kommen (Compiler Error 305). Es sollten daher nur die Programme insertiert werden, für die dies wirklich nötig ist. - Achten Sie bei der Wahl des Namens für die gelieferte Prozedur darauf, daß sie nicht ungewollt Prozeduren des Betriebssystems überdecken. (Der Aufruf 'ba­ sic("tadellos","help")' wäre z.B. gar nicht tadellos, denn 'help' wäre nach dem Insertieren überdeckt). - Auch beim Insertieren werden die BASIC-Programme mit 'check on' übersetzt. #off ("b")# Ausgabe der übersetzten Zeilen während des Compilierens Mit '#ib(3)#basic list#ie(3)# (TRUE)' wird der Compiler so eingestellt, daß beim Übersetzen die aktuelle Programmzeile ausgegeben wird. Diese Ausgabe kann auch mit '#ib(3)#sysout#ie(3)#' umgeleitet werden. Zum Beispiel: sysout ("Fehlerprotokoll"); basic ("Programm.17+4") Dies kann beim #ib(3)#Debugging#ie(3)# von BASIC-Programmen eine wertvolle Hilfe sein, da in der Ausgabedatei die Fehler sofort hinter der betreffenden Programmzeile vermerkt werden. Das 'sysout' muß in Monitortasks ('gib kommando:') direkt vor dem Aufruf des Compilers gegeben werden, weil der Monitor 'sysout' sonst wieder zurücksetzt. Mit 'basic list (FALSE)' kann die Ausgabe der Programmzeilen beim Übersetzen wieder ausgeschaltet werden. #page# #head# EUMEL-BASIC-Compiler 4. Umgang mit dem BASIC-Compiler % #end# 4. Umgang mit dem BASIC-Compiler 4.1. Erläuterungen zur #ib(3)#Syntax#ie(3)# Ein zu übersetzendes Programm muß dem BASIC-Compiler in Form einer #ib(3)#EUMEL-Textdatei#ie(3)# übergeben werden. (Es gelten somit auch die für EUMEL-Text­ dateien üblichen Begrenzungen, z.B. höchstens 32000 Zeichen pro Zeile und höch­ stens 4075 Dateizeilen pro Datei.) BASIC-Programme setzen sich aus Programmzeilen zusammen; jede Dateizeile der #ib(3)#Programmdatei#ie(3)# bildet eine BASIC-Programmzeile. Die Syntax für ein Programm sieht damit so aus: [][...]EOF Dabei bedeutet #ib(3)#EOF (end of file)#ie(3)# das Ende der Programmdatei. Eine #ib(3)#Programmzeile#ie(3)# hat folgende Syntax: [][][:][...][:]EOL Die #ib(3)#Zeilennummer#ie(3)# dient unter anderem als Sprungadresse an den Anfang der Pro­ grammzeile während der Laufzeit des Programms (vgl. 'GOTO' und 'GOSUB'). Sie ist fakultativ (d.h. sie muß nicht geschrieben werden). Durch sparsame Verwendung von Zeilennummern (nämlich nur da, wo sie benötigt werden) kann eine gewisse Steige­ rung der #ib(3)#Übersichtlichkeit von BASIC-Programmen#ie(3)# erreicht werden. Hat eine Pro­ grammzeile keine Zeilennummer, so wird bei Fehlermeldungen (sowohl während der Übersetzung als auch zur Laufzeit des Programms) die letzte Zeilennummer mit angegeben, die davor auftrat. Zeilennummern dürfen im Bereich von 1 bis 32767 liegen und müssen unbedingt in aufsteigender Reihenfolge vergeben werden. Zeilennummern dürfen keine Leerzeichen enthalten und müssen mit einem Leerzeichen abgeschlossen werden. Um spätere Ergänzungen zu ermöglichen, ist eine Numerierung im Abstand zehn empfehlenswert. Hier ein Beispiel, wie ein BASIC-Programm in einer EUMEL-Datei aussehen könnte: ...........................Einmaleins............................ 10 CLS: PRINT "Kleines Einmaleins" FOR zahl% = 1 TO 10 PRINT 'Erzeugung einer Zeile FOR faktor% = 1 TO 10 PRINT TAB (faktor% * 5); PRINT USING "\#\#\#"; faktor% * zahl%; NEXT faktor% NEXT zahl% Die Syntax der Anweisungen, die vom EUMEL-BASIC-Compiler übersetzt werden können, ist ausführlich im Kapitel 8 beschrieben. Der #ib(3)#Doppelpunkt#ie(3)# dient als Trennzeichen zwischen Anweisungen. Ihm muß nicht unbedingt eine Anweisung folgen. Er kann somit als explizites "Ende der Anweisung"-Symbol aufgefaßt werden (#ib(3)#EOS, "end of statement"#ie(3)#). #ib(3)#EOL (end of line)#ie(3)# ist das Ende einer Dateizeile. (Dieses "Zeichen" ist ebenso wie EOF beim Editieren der Datei nicht sichtbar.) Das #ib(3)#Hochkomma#ie(3)# ("'", Code 39) wird vom Compiler ebenfalls als EOL interpretiert. Alle dem Hochkomma in der Dateizeile folgenden Zeichen werden überlesen. Dies ermöglicht das Schreiben von Kommentaren ohne Verwendung der 'REM'-Anweisung. Es sei hier bereits bemerkt, daß sich durch die Realisierung des Übersetzers als #on ("b")#Compiler gewisse Unterschiede gegenüber Interpretern #off ("b")#ergeben (siehe hierzu Kap. 9). Der wesentliche Unterschied ist, daß der Interpreter dem Programmtext analog zum Programmablauf folgt, der Compiler das Programm aber von vorne bis hinten Zeile für Zeile übersetzt. Dies hat zur Folge, daß z.B. die Dimensionierungen von Feldvariablen #on ("b")#textuell vor der Verwendung der Variablen stattfinden müssen#off ("b")# und nicht, wie bei Interpretern, nur im Ablauf des Programms vorher ausgeführt werden müssen. Weitere Schreibregeln #on ("b")# 1. #ib(3)#Groß-/Kleinschreibung#ie(3)##off ("b")# Für den BASIC-Compiler bestehen zwischen kleinen und großen Buchstaben keiner­ lei Unterschiede, es sei denn es handelt sich um Textdenoter (Textkonstanten). Daher können alle #ib(3)#Schlüsselwörter#ie(3)# und #ib(3)#Variablennamen#ie(3)# mit kleinen oder großen Buchstaben geschrieben werden. Aus der Tatsache, daß zwischen großen und kleinen Buchstaben nicht unterschieden wird, folgt aber bespielsweise auch, daß die Variab­ lennamen (vgl. 4.3.) 'hallo' und 'HALLO' ein und dieselbe Variable bezeichnen. #on ("b")# 2. #ib(3)#Reservierte Wörter#ie(3)##off ("b")# Der BASIC-Compiler erkennt eine ganze Reihe #on("i")#reservierter Wörter#off("i")#. Es handelt sich hierbei im wesentlichen um die Namen der Anweisungen und Funktionen. Sie sollten im eigenen Interesse darauf achten, daß sich sowohl vor als auch hinter reservier­ ten Wörtern stets mindestens ein #on ("b")##ib(3)#Leerzeichen#ie(3)##off ("b")# (Blank) befindet. Der #ib(3)#Scanner#ie(3)# (ver­ gleiche AnhangB) erkennt zwar manchmal die reservierten Wörter auch ohne Leer­ zeichen, aber unter bestimmten Umständen kann es auch zu erkannten oder - noch schlimmer - vom Compiler unerkannten Fehlern kommen. Hierzu zwei Beispiele: Die Anweisung 'IF a > b THENPRINT "größer"' führt beim Compilieren zur Fehler­ meldung "Syntaxfehler: THEN oder GOTO erwartet". Wesentlich gefährlicher ist da schon die Programmzeile "LEThallo = 3 : PRINT hallo", denn die unerwartete Wirkung ist die Ausgabe von "0" auf dem Bildschirm. Der Wert "3" wurde nämlich nicht der Variablen mit dem Namen "hallo" zugewiesen, sondern einer Variablen namens "LEThallo". #on ("b")# 3. Bedeutung der #ib(3)#Leerstelle#ie(3)# ("Blank") für den Compiler#off("b")# Wie schon aus dem vorhergehenden Punkt ersichtlich kann das Fehlen von trennen­ den Leerstellen unschöne Effekte haben, denn der #ib(3)#Scanner#ie(3)# (vgl. AnhangB) des BASIC-Compilers erkennt anhand der Leerstelle (Code 32) beim Durchlauf durch das Programm, daß ein #ib(3)#Symbol#ie(3)# zu Ende ist. Es kommt somit immer dann zu Fehlern, wenn zwei Symbole (z.B. reservierte Wörter, Konstanten, Variablen etc.) nicht durch Leerzeichen getrennt sind, und der Scanner sie als ein Symbol "versteht". Beispiel: "a = 3 : b = 4 : PRINT a b" erzeugt die Ausgabe "34". "a = 3 : b = 4 : PRINT ab" erzeugt hingegen die Ausgabe "0", denn der Compiler sieht "ab" als #on ("b")#einen Variablennamen an. #off ("b")# 4.2. #ib(3)#Datentypen#ie(3)# und #ib(3)#Konstanten#ie(3)# Der EUMEL-BASIC-Compiler unterscheidet grundsätzlich zwischen zwei Daten­ typen, nämlich zwischen #ib(3)#Texte#ie(3)#n und #ib(3)#Zahlen#ie(3)#. #on ("b")# #ib(3)#Datentyp TEXT#ie(3)# #off ("b")# Texte dürfen alle Zeichen enthalten (Codes 0 bis 255) und bis zu 32000 Zeichen lang sein. Die zugehörigen Konstanten werden von #ib(3)#Anführungszeichen#ie(3)# begrenzt, z.B.: "Anzahl Einträge: " "2.32 DM" "General-Musik-Direktor" Anführungszeichen (Code 34) dürfen #on("i")#innerhalb#off("i")# von Text-Konstanten nicht vor­ kommen. Bei Zahlen unterscheidet der Compiler noch zwischen #ib(3)#INTs#ie(3)# (#ib(3)#Ganzzahlen#ie(3)#) und REALs (#ib(3)#Gleitkommazahlen#ie(3)#). Diese entsprechen im Hinblick auf den Wertebereich genau den in ELAN bekannten INTs und REALs. #on ("b")# #ib(3)#Datentyp INT#ie(3)# #off ("b")# INT-Werte dürfen zwischen -32768 und 32767 liegen. INT-Konstanten dürfen aber #on("i")#nur#off("i")# aus Ziffern und einem optionalen '%'-Zeichen am Ende bestehen. Das bedeutet, daß die INT-Konstanten im Bereich von 0 bis 32767 liegen können. Ein nachgestelltes '%'-Zeichen kennzeichnet eine Konstante nochmals explizit als INT. (Diese Option wurde aus Kompatibilitätsgründen implementiert.) #on ("b")# #ib(3)#Datentyp REAL#ie(3)# #off ("b")# REALs können Werte zwischen -9.999999999999*10#u#126#e# und 9.999999999999*10#u#126#e# annehmen. Die kleinste positive von Null verschiedene Zahl ist 9.999999999999*10#u#-126#e#. Der kleinste REAL-Wert mit x + 1.0 > 1.0 ist gleich 10#u#-12#e#. REAL-Konstanten werden gebildet aus Vorkommastellen, Dezimalpunkt, Nachkom­ mastellen, Zeichen "E" oder "D" (jeweils auch klein) für den #ib(3)#Exponent#ie(3)#en gefolgt vom Vorzeichen und den Ziffern des Exponenten. Dabei müssen nicht für jede REAL-Konstante alle diese Elemente benutzt werden. Unverzichtbar sind #on("i")#entweder#off("i")# der Dezimalpunkt #on("i")#oder#off("i")# der Exponent. Ebenso müssen zumindest entweder Vor- oder Nachkommastellen vorhanden sein. Beispiele für gültige REAL-Konstanten sind: 0. .01 1E-17 2.9979D8 .3e-102 100.e+7 Nicht erlaubt sind dagegen folgende Schreibweisen für REAL-Konstanten: e12 (#ib(3)#Mantisse#ie(3)# fehlt) 100 (ist INT-Konstante) . (weder Vor- noch Nachkommastellen) .E-12 (dito) 1exp-3 ('exp' nicht erlaubt) -1.99e30 (Mantisse hat Vorzeichen) Das letzte Beispiel zeigt, daß auch vor REAL-Konstanten keine #ib(3)#Vorzeichen#ie(3)# erlaubt sind. Da normalerweise keine REAL-Konstanten, sondern vielmehr numerische Ausdrücke verlangt werden, können durch Voranstellen des Operators '-' (vgl. 4.4.) auch #ib(3)#negative Zahlenwerte#ie(3)# leicht erzeugt werden. An REAL-Konstanten darf eines der Zeichen "!" und "\#" angehängt werden. Diese Option wurde aus Kompatibilitätsgründen eingebaut. Wird ein "!" oder "\#" an eine INT-Konstante angehängt, so verwandelt es diese in eine REAL-Konstante. Beispiel: 10000! oder 10000\# entspricht 10000. oder 1E4 #page# 4.3. Variablen und Felder Variablen Der BASIC-Compiler stellt für die in 4.2. vorgestellten Datentypen TEXT, INT und REAL auch Variablen zur Verfügung. Die #ib(3)#Variablennamen#ie(3)# müssen folgenden Bedingungen genügen: - Ein Variablenname muß mit einem Buchstaben beginnen. - Variablennamen dürfen ab der zweiten Stelle außer Buchstaben auch Ziffern, Dezi­ malpunkte sowie die Zeichen "!", "\#", "$" und "%" enthalten. Leerzeichen dürfen in Variablennamen dagegen nicht vorkommen. - Variablennamen dürfen nicht mit FN beginnen (vgl. 4.5. benutzer-definierte Funk­ tionen). - #ib(3)#Reservierte Wörter#ie(3)# (siehe Anhang A) dürfen kein Variablenname sein. Als Teiltexte dürfen reservierte Wörter aber in Variablennamen enthalten sein (auch am Anfang). Variablennamen dürfen beliebig lang sein, und alle Zeichen eines Variablennamens sind signifikant. Welchen Typ eine Variable hat, entscheidet der Compiler nach folgenden #ib(3)#Kriterien#ie(3, " für den Typ einer Variablen")# (in der Reihenfolge ihrer Beachtung): - Ist das letzte Zeichen des Namens ein "!" oder "\#", so bezeichnet er eine REAL-Variable. - Ist das letzte Zeichen ein "%", so handelt es sich um eine INT-Variable. - Ist das letzte Zeichen des Namens ein "$", so ist die Variable vom Typ TEXT. - Liegt das erste Zeichen des Namens im Bereich der mit einer #ib(3)#DEFINT#ie(3)#-Anweisung (vgl. Kap. 8) festgelegten Buchstaben, so ist die Variable eine INT-Variable. - Liegt das erste Zeichen im Bereich der mit einer #ib(3)#DEFSTR#ie(3)#-Anweisung (vgl. Kap. 8) festgelegten Buchstaben, so handelt es sich um eine TEXT-Variable. - Wenn keine der obigen Bedingungen erfüllt ist, dann bezeichnet der Name eine Variable des Datentyps REAL. Variablen, denen noch kein Wert zugewiesen wurde, haben den Inhalt null (bei INT und REAL) beziehungsweise Leertext (bei TEXT). Felder (#ib(4)#Arrays#ie(4)#) Ein Feld (Array) ist eine Ansammlung von mehreren Variablen gleichen Typs. Jedes Feld hat einen Namen. Für die #ib(3)#Feldnamen#ie(3)# gelten die gleichen Regeln wie für die Namen von normalen Variablen. Auch die Datentypen werden nach den gleichen Kriterien bestimmt wie bei einfachen Variablen. In einem Feld können die Elemente in bis zu 100 #ib(3)#Dimensionen#ie(3)# abgelegt werden. Auf ein Element eines Feldes wird über den Feldnamen und den Index / die #ib(3)#Indizes#ie(3)# des Elements zugegriffen. Beim Zugriff auf das Element müssen so viele Indizes ange­ geben werden, wie das Feld Dimensionen hat. Beispiel: Das Feld 'tabelle' habe zwei Dimensionen. Mit 'tabelle (3, 5)' wird auf das Element mit dem Index 3 in der ersten Dimension und dem Index 5 in der zweiten Dimension zugegriffen. Beim ersten Zugriff auf ein Element eines Feldes wird anhand der Zahl der Indizes die Anzahl der Dimensionen festgestellt und das Feld so eingerichtet, daß in jeder Dimension der größte Index zehn ist. Soll ein Feld mit anderen größten Indizes eingerichtet werden, so muß hierzu die #ib(3)#DIM#ie(3)#-Anweisung verwendet werden (siehe Kapitel 8). Der kleinste Index ist voreingestellt auf null, kann aber mit der #ib(3)#OPTION BASE#ie(3)#- Anweisung (vgl. Kap. 8) auch auf eins eingestellt werden. Die Elemente eines Feldes sind, wie auch die einfachen Variablen, mit den Werten null (INT und REAL) beziehungsweise Leertext (TEXT) vorbesetzt, sofern ihnen noch nichts zugewiesen wurde. #page# 4.4. Operatoren Nachfolgend sind alle Operatoren aufgelistet, die vom EUMEL-BASIC-Compiler übersetzt werden. Arithmetische #ib(4)#Operatoren#ie(4, ", arithmetische")# #ib(3)##ie(3, "+")##ib(3)##ie(3, "-")##ib(3)##ie(3, "*")##ib(3)##ie(3, "/")# #ib(3)##ie(3, "\")##ib(3)##ie(3, "MOD")##ib(3)##ie(3, "^")# Operand(en) Zweck Ergebnistyp + INT positives Vorzeichen INT REAL positives Vorzeichen REAL INT, INT INT-Addition INT REAL, REAL REAL-Addition REAL - INT negatives Vorzeichen INT REAL negatives Vorzeichen REAL INT, INT INT-Subtraktion INT REAL, REAL REAL-Subtraktion REAL * INT, INT INT-Multiplikation INT REAL, REAL REAL-Multiplikation REAL / (INT, INT) #linefeed (0.5)# REAL-Division REAL REAL, REAL #linefeed (1.0)# \ INT, INT #linefeed (0.5)# INT-Division INT (REAL, REAL) #linefeed (1.0)# MOD INT, INT INT-Divisionsrest INT REAL, REAL Divisionsrest nach REAL Runden auf Ganzzahl (nicht INT) ^ (INT, INT) #linefeed (0.5)# Potenzierung REAL REAL, REAL #linefeed (1.0)# #on ("b")# Hinweis: #off ("b")# Wird ein Operator mit numerischen Operanden unterschiedlichen Typs (also INT und REAL) aufgerufen, so wird der INT-Operand nach REAL konvertiert und der Operator mit den beiden REAL-Operanden aufgerufen. Sind die Operandtypen in Klammern angegeben, so werden vor Ausführung der Ope­ ration die Operanden zu den nicht eingeklammerten Typen konvertiert. Da jede #ib(3)#Konvertierung#ie(3)# Zeit benötigt, sollte der Benutzer darauf achten, daß möglichst wenig konvertiert werden muß. Hierzu ein (etwas extremes, aber nicht seltenes) Beispiel: Der Aufruf a%\b bewirkt zunächst eine Konvertierung von a% nach REAL: CDBL(a%)\b. Intern wird die Berechnung dann aber wieder mit INTs ausgeführt: CINT(CDBL(a%))\CINT(b). Das Ergebnis wird also erst nach drei Konvertierungen geliefert. Schreibt man dagegen sofort a%\CINT(b), dann reicht eine Konvertierung aus. Es muß außerdem bei den Operatoren +, - und * für INTs darauf geachtet werden, daß das Ergebnis innerhalb des INT-Wertebereichs liegen muß, da es sonst zu einem #ib(3)#INT-Überlauf#ie(3)# kommt. Text-Operator #ib(4)#+#ie(4)# #ib(3)##ie(3, "Operatoren, Text-")# Für Text-Manipulationen wird der Operator '+' mit zwei TEXT-Operanden zur Verfügung gestellt. Mit '+' werden zwei Texte aneinandergehängt (konkateniert). Vergleichsoperatoren#ib(4)##ie(4, "Operatoren, Vergleichs-")# Im EUMEL-BASIC gibt es folgende Vergleichsoperatoren: #ib(3)#=#ie(3)# gleich #ib(3)#<>#ie(3)# ungleich #ib(3)#<#ie(3)# kleiner #ib(3)#>#ie(3)# größer #ib(3)#<=#ie(3)# kleiner oder gleich #ib(3)#>=#ie(3)# größer oder gleich Bei den numerischen Datentypen werden mit den Vergleichsoperatoren die Zahlen­ werte verglichen. Sollen ein INT und ein REAL verglichen werden, dann wird der INT vorher nach REAL konvertiert und ein REAL-Vergleich vorgenommen. Bei Texten dienen die Vergleichsoperatoren zum Vergleich der Zeichencodes. Dies ermöglicht zum Beispiel ein alphabetisches Sortieren von Wörtern, mit der Einschrän­ kung, daß Groß- und Kleinbuchstaben unterschiedliche Zeichencodes haben (ver­ gleiche EUMEL-Zeichensatz-Tabelle im Benutzerhandbuch) und somit verschieden eingeordnet werden. Es gilt a$ < b$, wenn die Zeichenkette in a$ codemäßig vor der Zeichenkette in b$ steht: "a" < "b" (TRUE) "aa"< "a" (FALSE) Die Vergleichsoperatoren liefern, je nachdem ob die Aussage wahr oder falsch ist, die INT-Werte 0 (falsch) oder -1 (wahr). Anhand des Ergebnisses einer Vergleichsoperation kann zum Beispiel der Programm­ ablauf gesteuert werden (siehe Kapitel 8, IF-Anweisung). Logische Operatoren #ib(3)##ie(3, "Operatoren, logische")# Die logischen Operatoren haben zwei Aufgaben: 1. logische (Boolsche) Verknüpfung von #ib(3)#Wahrheitswerte#ie(3)#n, die zum Beispiel von Vergleichsoperationen geliefert werden und 2. bitweise Ausführung von logischen Verknüpfungen auf den internen (Zweierkom­ plement-) Darstellungen von INT-Werten. Da für beide Aufgaben die gleichen Operatoren benutzt werden, wurden für die Wahr­ heitswerte die INT-Werte 0 für falsch (Bitmuster: 0000000000000000) und -1 für wahr (Bitmuster: 1111111111111111) gewählt. Operand(en) Zweck insbesondere gilt #ib(3)#NOT#ie(3)# INT #linefeed (0.5)# NOT0->-1 #ib(3)#Negation#ie(3)# (REAL) #linefeed (1.0)# NOT-1->0 #ib(3)#AND#ie(3)# INT, INT #ib(3)#UND-Verknüpfung#ie(3)# 0AND0->0 0AND-1->0 -1AND0->0 -1AND-1->-1 #ib(3)#OR#ie(3)# INT, INT #ib(3)#ODER-Verknüpfung#ie(3)# 0OR0->0 0OR-1->-1 -1OR0->-1 -1OR-1->-1 #ib(3)#XOR#ie(3)# INT, INT #ib(3)#Exklusiv-ODER-Verknüpfung#ie(3)# 0XOR0->0 0XOR-1->-1 -1XOR0->-1 -1XOR-1->0 #ib(3)#EQV#ie(3)# INT, INT #ib(3)#Äquivalenz-Verknüpfung#ie(3)# 0EQV0->-1 0EQV-1->0 -1EQV0->0 -1EQV-1->-1 #ib(3)#IMP#ie(3)# INT, INT #ib(3)#Implikations-Verknüpfung#ie(3)# 0IMP0->-1 0IMP-1->-1 -1IMP0->0 -1IMP-1->-1 Prioritäten der Operanden Hier die Übersicht über alle Operatoren in der Reihenfolge ihrer Ausführung Operator Priorität ^ Potenzierung 13 +, - positives/negatives Vorzeichen 12 *, / Multiplikation, REAL-Division 11 \ INT-Division 10 MOD Divisionsrest- (MOD-) Operation 9 +, - Addition, Subtraktion 8 =, <>, <, >, <=, >= Vergleichsoperatoren 7 NOT Negation 6 AND UND-Verknüpfung 5 OR ODER-Verknüpfung 4 XOR Exklusiv-ODER-Verknüpfung 3 EQV Äquivalenz-Verknüpfung 2 IMP Implikations-Verknüpfung 1 Die Reihenfolge der Auswertung von Ausdrücken kann durch Klammern geändert werden. Beachten Sie, daß der Operator '=' in BASIC die Funktion eines Vergleichsoperators und des #ib(3)#Zuweisungsoperators#ie(3)##ib(3)##ie(3, "Operator, Zuweisungs-")# (siehe Kapitel 8, LET-Anweisung) hat. #page# 4.5. #ib(3)#Funktionen#ie(3)# Standard-Funktionen Der EUMEL-BASIC-Compiler unterstützt eine ganze Reihe von Funktionen. Diese Funktionen liefern Werte und können in Ausdrücken zusammen mit Konstanten, Variablen und Operatoren verwendet werden. Viele der eingebauten Funktionen arbeiten mit Argumenten, das heißt es werden den Funktionen Werte übergeben. In Kapitel 8 dieses Handbuches sind alle Funktionen ausführlich beschrieben. Beispiele für #ib(3)#Funktionsaufrufe#ie(3)#: SQR (17) Dieser Ausdruck liefert die Wurzel von 17 als REAL. RIGHT$ (text$, 5) Dieser Ausdruck liefert die letzten fünf Textzeichen #right#aus 'text$' als TEXT. Benutzer-definierte Funktionen Neben der Verwendung der standardmäßig verfügbaren Funktionen besteht für den Benutzer die Möglichkeit, selbst Funktionen innerhalb eines Programms zu definieren. #on ("b")# #ib(3)#Definition benutzer-definierter Funktionen#ie(3)# #off ("b")# Hierzu dient die #ib(3)#DEF FN#ie(3)#-Anweisung (vergleiche Kapitel 8). Die Syntax der DEF FN-Anweisung lautet: DEFFN[([,][...])]= #right# : Zeichenfolge, die der Syntax für Variablennamen ent­ sprechen muß. FN bilden zusammen den Namen der neuen Funktion. <#ib(3)#Parameter#ie(3)#>: Zeichenfolge, die der Syntax für Variablennamen ent­ sprechen muß. : Ausdruck, der Konstanten, Variablen, die Parameter der Funktion und Aufrufe anderer Funktionen enthalten darf. - Die benutzer-definierten Funktionen ("user functions") liefern, genau wie die Standard-Funktionen, Werte. - Das letzte Zeichen des Funktionsnamens gibt den Typ des Wertes an, den die Funktion liefert. Soll die Funktion einen TEXT liefern, so muß der Name mit "$" enden. Soll ein INT geliefert werden, muß der Name mit "%" enden. Für alle anderen Endungen wird eine REAL-liefernde Funktion eingetragen. - Die Syntax der Parameternamen entspricht der Syntax für die Namen von einfachen Variablen. - Die Parameter haben nur bei der Definition Gültigkeit. Hierbei 'überdecken' sie (für diese Zeile) eventuell im BASIC-Programm vorhandene gleichnamige Variablen. - Jeder Parameter darf in der Parameterliste nur einmal vorkommen. - Bezeichnet der Funktionsname eine TEXT-liefernde Funktion, so muß auch die Funktionsdefinition ein Ergebnis vom Typ TEXT liefern. Zwischen INTs und REALs findet eine Typanpassung statt. - Eine Funktion darf nicht in ihrer eigenen Definition erscheinen. - Eine Funktion ist allein durch ihren Namen gekennzeichnet. Generische Funktionen (gleicher Name, aber unterschiedliche Parameter) können somit nicht definiert wer­ den. Beispiele für gültige Funktionsdefinitionen: DEF FNPI = 3.1415927 DEF FNumfang (radius) = 2.0 * FNPI * radius (Enthält Aufruf von FNPI) DEF FNhallo$ (dummy$) = "Hallo " + name$ (name$ kommt im #right#BASIC-Programm vor) DEF FNheavyside% (x) = ABS (SGN (x) = 1) Beispiele für ungültige Funktionsdefinitionen: DEF FNfunct (a, b, a) = a ^ 2 + b (a kommt zweimal als Parameter vor) DEF FNfr (x) = x * FNfr (x - 1) (rekursive Definition) #on ("b")# #ib(3)#Aufruf benutzer-definierter Funktionen#ie(3)# #off ("b")# FN [ ( [, ] [...] ) ] <#ib(3)#Argument#ie(3)#> : Ausdruck, der für den entsprechenden Parameter bei der Evaluation (Auswertung) der Funktion eingesetzt werden soll - Beim Funktionsaufruf werden die Argumente in der Reihenfolge ihres Auftretens für die Parameter eingesetzt. Für TEXT-Parameter müssen die Argumente ebenfalls TEXTe liefern. Zwischen INTs und REALs findet eine Typanpassung statt. - Die Anzahl der Argumente muß genau mit der Anzahl der Parameter übereinstim­ men. - Für in der Funktionsdefinition vorkommende Variablen wird der zum Zeitpunkt des Funktionsaufruf gültige Wert eingesetzt. - Die Definition der Funktion muß dem ersten Aufruf der Funktion textuell voraus­ gehen. - Eine Definition gilt für alle textuell folgenden Aufrufe, bis die Funktion wieder neu definiert wird. Beispiele für korrekte Funktionsaufrufe (bezogen auf obige Beispiel-Definitionen): PRINT FNPI / 2.0 (Ausgabe: 1.570796) PRINT FNumfang (20) (Ausgabe: 125.6637) LET name$ = "Purzelbär":PRINT FNhallo$ ("") (Ausgabe: Hallo Purzelbär) PRINT heavyside% (-17.3) (Ausgabe: 0) Beispiele für falsche Funktionsaufrufe (bezogen auf obige Beispiel-Definitionen): PRINT FNPI (10) (kein Argument erwartet) PRINT FNumfang (Argument erwartet) PRINT FNhallo$ (zahl%) (Falscher Typ des Arguments) PRINT FNheavyside (17.4, -12.3) (Zu viele Argumente) #page# 4.6. #ib(3)#Typanpassung#ie(3)# In BASIC wird, im Gegensatz zu ELAN, nicht sehr streng zwischen den numerischen Datentypen unterschieden, sondern es finden häufig automatische Typanpassungen statt. Zu solchen Typanpassungen kommt es vor allem bei der Zuweisung, bei Opera­ toren und bei Funktionen, aber auch bei einigen Anweisungen. Die automatische Typanpassung hat zwei Nachteile: 1. Die Typkonvertierung von INT nach REAL und umgekehrt kostet Zeit während der Programmausführung. 2. Es kann zu sehr unangenehmen Laufzeitfehlern kommen, wenn eine REAL- INT-#ib(3)#Konvertierung#ie(3)# mit Fehler abbricht, weil der REAL-Wert außerhalb des INT-Wertebereichs liegt. Allgemein gilt also, daß sich der Programmierer auch in BASIC über die Typen der verwendeten Objekte im klaren sein sollte. Außerdem ist zu beachten, daß bei Konver­ tierungen von REAL nach INT immer gerundet wird. Genaueres zur Typanpassung bei der Zuweisung finden Sie in Kapitel 8 bei der LET-Anweisung. Über Typkonvertierung bei Operatoren informiert Kapitel 4.4. Informationen über die Funktionen betreffenden Typkonvertierungen befinden sich am Anfang von Kapitel 8 und direkt bei der Beschreibung der jeweiligen Funktionen (ebenfalls in Kapitel 8). #page# 4.7. Aufruf von EUMEL-Prozeduren in BASIC-Programmen Der EUMEL-BASIC-Compiler bietet die Möglichkeit, insertierte ELAN-Prozeduren (und auch insertierte BASIC-Programme) in BASIC-Programmen aufzurufen. Hierzu werden die beiden Anweisungen #ib(3)#CALL#ie(3)# und #ib(3)#CHAIN#ie(3)# (identisch) sowie die Funktion #ib(3)#USR#ie(3)# zur Verfügung gestellt. Mit der CALL-Anweisung (siehe auch Kapitel 8) können Prozeduren aufgerufen werden, die keinen Wert liefern und nur die BASIC-Datentypen INT, REAL und/oder TEXT als Parameter benötigen. Beispiele: CALL list CALL taskstatus ("PUBLIC") CALL cursor (10, 21) CALL getcursor (x%, y%) Das letzte Beispiel zeigt, daß auch #ib(3)#VAR-Parameter#ie(3)# im ELAN-Sinne übergeben werden können. Die Funktion USR dient im Gegensatz zu CALL zum Aufruf von #ib(3)#wertliefernden Pro­ zeduren#ie(3)#. Die Prozeduren dürfen allerdings nur einen der BASIC-Datentypen INT, REAL oder TEXT liefern. Es gilt auch bei USR, wie bei CALL, daß die aufgerufenen Prozeduren nur Parameter der Typen INT, REAL oder TEXT haben dürfen. Beispiele: PRINT USR e (Ausgabe: 2.718282) PRINT USR compress (" EUMEL ") (Ausgabe: EUMEL) #on ("b")# Wichtige Hinweise zu CALL, CHAIN und USR: #off ("b")# 1. Bei den Parametern finden keinerlei Typkonvertierungen statt (ELAN- Prozeduren werden ja gerade anhand der Typen ihrer Parameter eindeutig identifi­ ziert). 2. Die Prozedurnamen nach CALL, CHAIN und USR dürfen keine Leerzeichen ent­ halten, weil die Prozedur sonst nicht identifiziert werden kann. Beispiel: CALLlernsequenzauftastelegen(...) statt CALLlernsequenzauftastelegen(...) 3. Die Prozedurnamen können (nach BASIC-Konvention) auch Großbuchstaben enthalten. Beispiel: CALLcursor(17,4) ist äquivalent zu CALLCURSOR(17,4) Wie in Kapitel 3 erläutert kann ein BASIC-Programm auch insertiert werden. Somit können mit der CALL-Anweisung auch andere (vorher insertierte) BASIC- Programme aufgerufen werden. Beispiel: CALL blackjack ('blackjack' sei der Prozedurname, unter dem ein BASIC- Programm zuvor insertiert wurde.) Die sonst in einigen BASIC-Dialekten vorhandene Möglichkeit, Programme oder #ib(3)#Programmsegmente#ie(3)# nachzuladen, kann so durch Aufrufe von insertierten Programmen nachgebildet werden. #page# #head# EUMEL-BASIC-Compiler 5. Steuerung der Bildschirmausgaben % #end# 5. #ib(4)#Steuerung der #ib(3)#Bildschirmausgaben#ie(3)##ie(4)# Die Ausgaben von BASIC-Programmen ('PRINT' und 'WRITE') werden im Paket 'basic output' behandelt. Dieses Paket ermöglicht unter anderem, daß die Ausgabe auf das Terminal mit der Prozedur PROC #ib(3)#basic page#ie(3)# (BOOL CONST status) gesteuert werden können. Wird dabei 'TRUE' eingestellt, so wartet die Ausgabe bei Erreichen der letzten Terminalzeile auf die Eingabe eines Zeichens, bevor sie fortfährt. Das Eingabezeichen wird nach Ausgabe von ">>" in der rechten unteren Ecke des Bildschirms erwartet und wie folgt interpretiert: #linefeed (1.5)# Löschen des Bildschirms und Ausgabe der nächsten Bildschirmseite Ausgabe der nächsten Zeile Abbruch des Programms mit der Fehlermeldung "'halt' vom Terminal" 'basic page' wird auf 'FALSE' gesetzt #linefeed (1.0)#und mit der normalen Ausgabe weitergemacht Alle anderen Tasten bewirken eine Ausgabe der nächste Bildschirmseite (#ib(3)#Scrolling#ie(3)#). Ist 'basic page' auf 'FALSE' gesetzt, so kann durch Eingabe von vor einem Zei­ lenwechsel 'basic page' auf 'TRUE' gesetzt werden. #page# #head# EUMEL-BASIC-Compiler 6. Grenzen des Compilers % #end# 6. #ib(3)#Grenzen des Compilers#ie(3)# Es gibt verschiedene Grenzen, die bei der Benutzung des BASIC-Compilers erreicht werden können. #on ("b")# Grenzen des #ib(3)#EUMEL-Coder#ie(3)#s #off ("b")# Da ein BASIC-Programm vom Compiler als eine Prozedur im Coder eingetragen wird, darf der Code für ein BASIC-Programm die #ib(3)#Modulgrenze#ie(3)# von 7500 Byte Code nicht überschreiten. Sollte dies doch einmal der Fall sein (#ib(3)#Compiler Error 308#ie(3)#), so gibt es folgende Abhilfe-Möglichkeiten: - Zerlegen des BASIC-Programms in mehrere BASIC-Programme, wobei ein Programm das andere während der Ausführung aufrufen kann (vgl.4.7.). Bei dieser Methode können die Teilprogramme aber nicht mit gemeinsamen Variab­ len arbeiten. - Auslagerung von Programmteilen (z.B. Unterprogrammen) in ELAN-Prozeduren, die insertiert und vom BASIC-Programm aufgerufen werden können (vgl.4.7.). Dieses Verfahren bietet die Möglichkeit, Variablen zwischen BASIC-Programm und ELAN-Prozedur über die Prozedurschnittstelle auszutauschen. Neben der Begrenzung des Codes ist auch die Größe des Datenspeicherbereichs pro BASIC-Programm begrenzt. Insgesamt dürfen die Datenobjekte eines BASIC- Programms nicht mehr als 32 KByte Speicherplatz belegen. Andernfalls kommt es zum #ib(3)#Compiler Error 307#ie(3)#. Eine weitere Grenze des EUMEL-Coders stellt die maximal zulässige Anzahl der #ib(3)#Labels#ie(3)# (interne Sprungadressen) dar. Es können nur höchstens 2000 Labels vom Coder verwaltet werden. Der BASIC-Compiler vergibt für jede gefundene Zeile mit Zeilennummer ein Label und benötigt auch bei Schleifen (FOR-NEXT, WHILE- WEND), Fallunterscheidungen (IF-Anweisung), Unterprogramm-Aufrufen (GOSUB) und bei der Definition von benutzer-definierten Funktionen (DEF) Labels. Beim Auftreten des #ib(3)#Compiler Errors 304#ie(3)# (zu viele Label) ist Abhilfe relativ leicht dadurch möglich, daß Zeilennummern nur den Zeilen vergeben werden, die tatsächlich angesprungen werden (d.h. zu denen es GOTOs oder GOSUBs gibt). #on ("b")# Grenzen des BASIC-Compilers #off ("b")# Die interne #ib(3)#Namenstabelle#ie(3)# des BASIC-Compilers kann etwa 4240 Einträge aufneh­ men. Ein Eintrag in dieser Tabelle wird für jede Variable, für jedes Feld, für jede benutzer-definierte Funktion und für jeden Parameter einer benutzer-definierten Funktion sowie für jede Konstante erzeugt. Numerische Konstanten erhalten, sofern sie konvertiert werden müssen, sogar zwei Einträge in der Namenstabelle. Bei Auftreten des seltenen Fehlers "volle Namenstabelle" kann durch eine Aufteilung des BASIC-Programms in Teilprogramme oder eine Auslagerung von Unterprogram­ men in ELAN-Prozeduren Abhilfe geschaffen werden. #on ("b")# Sonstige EUMEL-Grenzen #off ("b")# Außer den bisher genannten Begrenzungen sei nochmals auf die Begrenzung des #ib(3)#Codebereichs pro Task#ie(3)# hingewiesen (maximal 256 KByte Code). Da der EUMEL-Coder und der BASIC-Compiler recht viel Code belegen, sollte "vorsichtig" insertiert werden, also nur das, was wirklich benötigt wird. Auch die übrigen Grenzen des EUMEL-Systems sind zu beachten (vergleiche hierzu die Aufstellung der möglichen Compiler Errors im EUMEL-Benutzerhandbuch)! #page# #head# EUMEL-BASIC-Compiler 7. Fehlerbehandlung % #end# 7. #ib(3)#Fehlerbehandlung#ie(3)# 7.1. #ib(3)#Fehler zur Übersetzungszeit#ie(3)# Endeckt der BASIC-Compiler bei der Übersetzung eines BASIC-Programms Fehler, so werden diese auf dem Bildschirm angezeigt und ins #ib(3)#Notebook#ie(3)# eingetragen. Nur (syntaktisch) fehlerfreie Programme werden zur Ausführung gebracht beziehungs­ weise insertiert. Im #ib(3)#Vordurchlauf#ie(3)# werden die Zeilennummern auf Richtigkeit überprüft. Falls bereits hiebei Fehler festgestellt werden, bricht der Compiler die Übersetzung nach dem Vordurchlauf ab. Im #ib(3)#Hauptdurchlauf#ie(3)# wird das Programm Zeile für Zeile auf syntaktische Richtigkeit überprüft und gleichzeitig übersetzt. Wird dabei in einer Programmzeile ein Fehler entdeckt, so wird er angezeigt und die Übersetzung des Programms #on("i")#in der nächsten Programmzeile#off("i")# fortgesetzt. Eine Ausnahme von dieser Regel bildet nur die #ib(3)#DEF FN#ie(3)#- Anweisung, bei der bei gewissen Fehlern die Übersetzung fortgesetzt wird. (Der Grund hierfür liegt darin, daß die Folgefehlerzahl besonders bei der DEF FN- Anweisung sehr groß wäre, wenn beim Auftreten eines Fehlers die Übersetzung der Zeile sofort abgebrochen würde. Die Parameter würden dann nämlich nicht oder falsch abgelegt, und bei jedem Aufruf der Funktion würde ein Fehler gemeldet.) Eine Übersicht über alle verwendeten Fehlermeldungen zur Übersetzungszeit befindet sich im AnhangC. Interne Compilerfehler Neben den "normalen" Fehlern (siehe oben) kann es in seltenen Fällen möglicher­ weise auch zu internen Fehlern kommen. Es gibt zwei verschiedene Sorten von internen Fehlern: 1. interne Fehler, die das Compilerprogramm selbst feststellt. Solche Fehler bewirken die Meldung "Interner Fehler !" (meist mit näherer Erläu­ terung) und die Fortsetzung der Übersetzung in der nächsten Programmzeile. 2. Fehler, die in anderen Paketen des BASIC-Systems oder des EUMELs (z.B. im EUMEL-Coder) während der Übersetzungszeit ausgelöst werden (siehe auch Kapitel 6: "Grenzen des Compilers"). Solche Fehler werden mit "#ib(3)#BASIC-Compiler ERROR#ie(3)#" und eventuell näheren Angaben gemeldet. Beim Auftreten eines solchen Fehlers wird die Übersetzung des gesamten Programms abgebrochen. Sollten bei Ihrer Arbeit mit dem EUMEL-BASIC-Compiler interne Fehler auftreten, die nicht auf das Überschreiten von Compilergrenzen zurückzuführen sind, dann wären wir Ihnen für eine Meldung der Fehler dankbar. Bitte senden Sie eine Fehler­ beschreibung an: Gesellschaft für Mathematik und Datenverarbeitung Schloß Birlinghoven Postfach 1240 5205 Sankt Augustin 1 Die Fehlerbeschreibung sollte nach Möglichkeit folgende Informationen enthalten: - verwendete Hardware - Urlader-Version - EUMEL-Version - Programmtext des Programms, das den Fehler auftreten ließ - genaue Angabe der ausgegebenen Fehlermeldung #page# 7.2. #ib(3)#Fehler zur Laufzeit#ie(3)# Treten während der Laufzeit eines BASIC-Programms Fehler auf, so wird die Ausfüh­ rung des Programms mit einer entsprechenden Fehlermeldung abgebrochen. Da die meisten Laufzeit-Fehlermeldungen durch Prozeduren des EUMEL-Systems (und nicht des BASIC-Systems) erzeugt werden, entsprechen sie oft nicht der BASIC-Terminologie. (Beispielsweise führt ein zu großer Feldindex zu der Fehlermel­ dung "Ueberlauf bei Subskription".) Die bei Laufzeitfehlern gemeldete #ib(3)#Fehlerzeile#ie(3)# bezieht sich nicht (wie bei ELAN-Pro­ grammen) auf die Nummer der Dateizeile, sondern auf die letzte der Programmzeile vorangegangene BASIC-Zeilennummer. Fast alle ausgelösten Laufzeitfehler erzeugen auch #ib(3)#Fehlercodes#ie(3)#. Dabei liefern Fehler aus EUMEL-Betriebssystem-Prozeduren die EUMEL-Standard-Fehlercodes (vgl. Systemhandbuch), zum Beispiel wird beim Fehler "INT-Ueberlauf" der Fehlercode 4 geliefert. Laufzeitfehler, die in Prozeduren des BASIC-Systems ausgelöst werden, liefern dage­ gen den in Microsoft-BASIC üblichen Fehlercode plus 1000. So liefert die Meldung "Keine Daten mehr für READ" den Fehlercode 1004 (MS-BASIC: "Out of data", Fehlercode 4). Es läßt sich so anhand des gelieferten Fehlercodes ermitteln, ob der Fehler im BASIC-System oder an einer anderen Stelle des EUMEL-Systems ausgelöst wurde. Eine Übersicht über die innerhalb des BASIC-Systems erzeugten Fehlermeldungen enthält Anhang C.