EUMEL-Benutzerhandbuch TEIL 5: ELAN-Compiler Der ELAN-Compiler im EUMEL-System In diesem Kapitel wird die Benutzung des ELAN-Compilers im EUMEL-System be- schrieben. Es enthält Angaben, welche Einschränkungen bzw. Erweiterungen gegenüber dem Sprachstandard existieren. Eine Einführung in die Programmier- sprache ELAN wird hier nicht gegeben. 1. Einführung Der im EUMEL-System eingesetzte ELAN-Compiler wurde von J. Liedtke und U. Bartling am HRZ Bielefeld in den Jahren 1975/76 erstellt und in den folgenden Jahren erweitert und der Sprachbeschreibung angepaßt. Der gleiche ELAN-Compiler wird auch auf verschiedenen Großrechnern (TR440, IBM, SIEMENS) eingesetzt. Den ELAN-Compiler kann man sich als aus zwei Teilen bestehend vorstellen. Einmal gibt es den "eigentlichen" ELAN-Compiler, der ein ELAN-Programm in eine Maschinensprache (im EUMEL-System der sogenannte EUMEL0-Code) übersetzt. Zum anderen verwaltet der ELAN-Compiler übersetzte Moduln (in ELAN Packets genannt). In einem Packet können Prozeduren, Datentypen und/oder Operatoren definiert werden. Ist ein solches Packet vorübersetzt (im EUMEL-System wird dieser Vorgang 'insertieren' genannt), stehen diese Objekte zur Benutzung zur Ver- fügung. Durch Packets kann man somit die Sprache ELAN erweitern. Weitere Informationen über die Programmiersprache ELAN finden Sie in den folgenden Büchern: Hommel / Jähnichen / Koster: Methodisches Programmieren W. de Gruyter, Berlin, 1983 Klingen / Liedtke: Programmieren mit ELAN Teubner, Stuttgart, 1983 In der Regel sind in einem EUMEL-System die Standard-Packets bereits in- sertiert (Ausnahmen: Datentypen #ib#VECTOR#ie# und #ib#MATRIX#ie#). Zusätz- lich sind weitere Packets vorübersetzt, die Kommandos zur Verfügung stellen. Welche weiteren Packets insertiert werden, kann jede EUMEL-Installation und jeder Nutzer entscheiden. Somit kann man sein System auf spezielle Anwendungen zuschneiden. 2. Übersetzen mit dem ELAN-Compiler In diesem Abschnitt wird erklärt, wie Programme mit dem ELAN-Compiler über- setzt oder vorübersetzt werden können. Einfaches Übersetzen: 'run'-Kommando Mit dem 'run'-Kommando kann ein ELAN-Programm übersetzt und ausgeführt werden. Das 'run'-Kommando (vergl. auch die Kommandos in der Beschreibung des Monitors) übersetzt ein in einer Datei befindliches ELAN-Programm. Beispiel: run ("mein programm") übersetzt das ELAN-Programm, welches in der Datei 'mein programm' enthalten ist. (Wie man ELAN-Programme schreibt, ist u.a. im Editor-Kapitel beschrie- ben). Der Fortschritt der Übersetzung wird durch laufende Nummern auf dem Bild- schirm des Benutzers angezeigt, die die gerade verarbeiteten Zeilennummern anzeigen. Da der ELAN-Compiler ein Zwei-Paß Compiler ist, werden alle Zeilen (mindestens) zweimal überprüft. Ist das Programm syntaktisch korrekt, d.h. hat der ELAN-Compiler keine Fehler gefunden, wird eine Ende-Meldung abgesetzt, die den Speicherumfang des übersetzten Programms enthält. Die Ende-Meldung entfällt, wenn die Task an kein Terminal angekoppelt ist. Nach der Ende-Meldung wird das Programm unmittelbar ausgeführt (ein Binder ist im EUMEL-System nicht notwendig). Merke: Das Kommando 'run' übersetzt ein in einer Datei befindliches Programm und führt fehlerfreie Programme aus. Korrektur von Fehlern In diesem Abschnitt wird beschrieben, wie (syntaktische bzw. semantische) Fehler korrigiert werden können. Entdeckt der ELAN-Compiler Fehler, so meldet er sie dem Benutzer unter An- Angabe der Zeilennummer. Die zwei Pässe des Compilers sind so konstruiert, daß sie unterschiedliche Fehler entdecken. Ist bereits im ersten Paß ein Fehler entdeckt worden, wird der zweite Paß nicht gestartet. Somit kann es vorkommen, daß man glaubt, alle Fehler beseitigt zu haben und dann werden wieder (andere) Fehler durch den zweiten Paß gemeldet ... Fehlermeldungen und Quelldatei werden nach Abschluß der Übersetzung durch den Paralleleditor angezeigt. Vergl. dazu auch die Beschreibung des Editors. Merke: Eventuelle Fehler und das zu korrigierende Programm werden durch den Paralleleditor angezeigt. So kann man das fehlerhafte Programm bequem ver- ändern. Nochmalige Ausführung eines Programms: 'run again' Mit 'run again' kann das zuletzt fehlerfrei übersetzte Programm nochmals ausgeführt werden. Ist ein Programm fehlerfrei übersetzt worden, so kann man es mit dem Komman- do 'run again' (beispielsweise mit anderen Eingabedaten) nochmals ausführen. Merke: Das Kommando 'run again' führt das zuletzt übersetzte Programm noch- mals aus. Übersetzen von Kommandos Auch Kommandos werden in der Regel vom ELAN-Compiler übersetzt. Der ELAN-Compiler wird nicht nur für Programme eingesetzt, sondern auch als Übersetzer für die EUMEL-Kommandosprache (in anderen Systemen "job control language", abgekürzt JCL genannt) und für Kommandos, die man im Editor geben kann. Jedes Kommando der EUMEL-Kommandosprache ist ein kleines ELAN-Programm, welches in der Regel aus einem Prozeduraufruf besteht. Einige häufig be- nutzte Kommandos werden der Effizienz halber über einen Kommando-Interpreter abgewickelt. Beispiel: edit ("mein erstes Programm") Natürlich ist es möglich, mehrere Kommandos oder ein richtiges, einzeiliges Programm als Kommando zu verwenden. Beispiele: put (17 * 4) INT VAR i; FOR i FROM 1 UPTO 100 REP put ("i") PER edit ("datei"); lineform ("datei"); print ("datei") INT VAR i; FOR i FROM 1 UPTO 10 REP print ("d") END REP Mit vorübersetzten Prozeduren (siehe auch das Kommando 'insert') ist es möglich, eine eigene Kommandosprache zusammenzustellen. Merke: Der ELAN-Compiler wird auch für die Übersetzung und Ausführung von Kommandos benutzt. Vorübersetzen: 'insert' Das Kommando 'insert' übersetzt ein in einer Datei befindliches ELAN-Pro- gramm und trägt dieses in den Tabellenspeicher des Compilers ein. Mit dem Kommando 'insert' kann ein ELAN-Programm (d.h. ein Packet oder eine Packetfolge) in den Tabellenspeicher (eine Art "Compilerdatenbank") des ELAN-Compilers eingetragen werden. Die in den Packets enthaltenen Objekte stehen nach Abschluß der Übersetzung zur Verfügung. Beispiel: Die Datei 'mein druck' enthalte folgendes Programm: PACKET mein druck DEFINES drucke: PROC drucke (TEXT CONST datei): edit (datei); lineform (datei); pageform (datei); print (datei) END PROC drucke; END PACKET drucke; Mit dem Kommando insert ("mein druck") wird das Packet 'drucke' in die Tabellen des ELAN-Compilers aufgenommen. Nun kann (als Kommando oder in einem Programm) der Prozeduraufruf 'drucke' verwandt werden. Man beachte, daß der Nutzer beim Einrichten seiner Task alle insertierten Ob- jekte der Vater-Task erhält. Insertiert der Benutzer in seiner Task weitere Packets, so sind diese nur ihm verfügbar (oder ggf. seinen Sohn-Tasks). Es ist somit möglich, Tasks mit unterschiedlichem Sprachumfang einzurichten. Einmal insertierte Packets können nicht mehr aus den Compilertabellen ent- fernt werden. Man kann also nur die Task löschen (bitte vorher alle Dateien archivieren oder bei der Vater-Task aufheben (siehe Kommando: 'save')). Das Kommando 'insert' arbeitet auch mit einem Thesaurus (vergl. dazu auch den Teil über Dateien). Beispiel: insert (ALL myself) insertiert alle Dateien der Benutzer-Task in Reihenfolge. Merke: Das Kommando 'insert' übersetzt die in einer Datei enthaltene Packet- folge und trägt diese in die Tabellen des Compilers ein. Programme von einem Programm übersetzen lassen Manchmal ist es notwendig, daß ein Programm den ELAN-Compiler zur Über- setzung und Ausführung eines Programms aufrufen muß. Natürlich kann man auch die Kommandos 'run' oder 'insert' von einem Programm aus aufrufen. Leider müssen die zu übersetzenden Programme in einer Datei enthalten sein. Will man jedoch nur eine Anweisung übersetzen und ausführen lassen und nicht den "Umweg" über eine Datei gehen (wie z.B. die Kommandos im Monitor oder Editor), so kann man die Prozedur '#ib#do#ie#' verwenden. Beispiel: ... get (eingabe); do (eingabe); ... Findet der ELAN-Compiler bei der Übersetzung eines Textes der Prozedur 'do' einen Fehler, so wird dieser Fehler über 'errorstop' gemeldet (vergl. dazu auch das Kapitel über die Fehlerbehandlung im System-Handbuch) und die Über- setzung bei der ersten Fehlermeldung abgebrochen. In diesem Fall kann ein Nutzer den Fehler durch eine #ib#Fängerebene#ie# leicht selbst behandeln. Merke: Die Prozedur 'do' übersetzt (kleinere) ELAN-Programme von einem Pro- gramm aus. Kommandos zur Steuerung des ELAN-Compilers In diesem Abschnitt beschreiben wir die Kommandos für die Steuerung des ELAN-Compilers#ie#. Ebenso wie die Kommandos zur Übersetzung eines Programms müssen die Kommandos zur Steuerung des Compilers vom Monitor gegeben werden. Mit dem Kommando prot ("datei name") wird das Listing des ELAN-Compilers eingeschaltet und in die angegebene Datei ausgegeben. Mit prot off wird es wieder ausgeschaltet. 'prot off' ist voreingestellt. Normalerweise werden Zeilennummern des Quellprogramms im übersetzten Pro- gramm mitgeführt, so daß bei einem Fehler zusätzlich zur Fehlermeldung auch die Nummer der Zeile ausgegeben werden kann, in der der Fehler aufgetreten ist. Mit dem Kommando check off kann die Generierung von Zeilenummern für das Objektprogramm abgeschaltet werden. Durch die Angabe dieses Kommandos wird weniger Code für das Programm erzeugt. Mit check on wird die Generierung von Zeilennummern durch den Compiler wieder einge- schaltet. 'check on' ist voreingestellt. Mit der Prozedur check die ein boolesches Resultat liefert, kann in einem Programm abgefragt werden, ob der 'check'-Zustand ein- oder ausgeschaltet ist. Beispiel: IF check THEN check off FI Merke: Die Kommandos 'check on' bzw. 'check off' schalten das Einfügen von Zeilennummern in den erzeugten Code ein bzw. aus. 3. Abweichungen gegenüber dem Sprachstandard Der im HRZ Bielefeld entwickelte ELAN-Compiler weist einige Abweichungen gegenüber dem Sprachstandard auf, wie er in der Sprachbeschreibung formu- liert ist. Es existieren einige Einschränkungen, die einen Programmierer jedoch nicht weiter behindern. Die Spracherweiterungen wurden meist speziell für das EUMEL-System geschaffen. Weitere Abweichungen gegenüber dem aktuellen Sprachstandard, die aber in der nächsten Sprachbeschreibung enthalten sein werden, sind in einem weiteren Abschnitt aufgeführt. Einschränkungen gegenüber dem Sprachstandard * Das "row display" wurde nicht implementiert. Der Grund dafür liegt in dem unverhältnismäßig hohen Aufwand, dieses Sprachmittel bei der gegen- wärtigen Compiler-Struktur zu implementieren. Abhilfe: Man verwende den Konstruktor. Beispiel: ROW 5 INT VAR vektor; vektor := [1, 2, 3, 4, 5]; (* nicht möglich *) vektor := ROW 5 INT :(1, 2, 3, 4, 5); (* Ersatz: Konstruktor *) * Einige alternative Darstellungen von Symbolen können nicht verwendet werden. Diese sind: "&"-Zeichen für "AND", "/="-Zeichen für "<>", "%"- und "//"-Zeichen für "DIV". * Eine Typ-Definition muß einer Deklaration immer textuell vorangehen. Beispiel: TYPE QUADRAT = ... (* erlaubt *) QUADRAT VAR rundes quadrat; ... PUNKT VAR meiner; (* verboten *) TYPE PUNKT = ... Es ist jedoch erlaubt, einen Typ in einer Typ-Definition zu verwenden, der textuell erst später definiert wird. Beispiel: TYPE PERSON = STRUCT (TEXT name, vorname, ADRESSE wohnort); TYPE ADRESSE = ... Diese Einschränkung ("defined before applied") gilt nur für Typen, nicht für Datenobjekte u.ä.. Selbstverständlich ist otto := 0; INT VAR otto; ... erlaubt (aber kein besonders schöner Programmierstil)! * Die Operatoren AND und OR können nicht redefiniert werden, sofern einer ihrer Operanden vom Typ BOOL ist. Implementationsbedingte Einschränkungen * Es sind bis zu 32 000 Zeichen in einem TEXT zugelassen. Hat ein TEXT bis 13 Zeichen, so wird er vollständig auf dem Stack untergebracht. TEXTe mit mehr als 13 Zeichen werden auf dem Heap gespeichert. Die Benutzung des Heaps bedeutet unter Umständen eine Verlangsamung eines Programms. Darum ist max text length = 32 000 * Die Anzahl der Zeichen in einem TEXT-Denoter (Angabe eines TEXTes in einem Programm) ist auf 254 Zeichen beschränkt. * INT-Werte werden in sechzehn Bit dargestellt (einschließlich Vor- zeichen). Das bedeutet, daß maxint = 32 767 minint = - 32 768 ist. * REAL-Werte werden intern mit einer Mantisse von 13 Stellen abgespei- chert, von denen die ersten sieben Stellen bei der Ausgabe dargestellt werden. Das bedeutet, daß maxreal = 9.999999999999e126 ist. * Die lexikographische Reihenfolge von Zeichen entspricht dem ASCII-Code (vergl. dazu die Code-Tabelle). * Weiterhin sieht der ASCII-Code noch eine Anzahl von Steuerzeichen vor, die jedoch von Herstellern leider nicht immer gleich interpretiert werden. Diese Zeichen sind im EUMEL-System teilweise normiert und können verwandt werden. Die verfügbaren Steuerzeichen sind ebenfalls im EUMEL-Taschenbuch aufgeführt. * Die Initialisierung von Paketen (genauer: die Initialisierung von Datenobjekten, die in vorübersetzten PACKETs außerhalb von Prozeduren deklariert wurden) wird nur einmal, während der Übersetzung, durchge- führt. Werden mehrere Pakete hintereinander (aus einer Datei) übersetzt, dürfen die Prozeduren 'run', 'run again', 'insert' und 'do', die wieder den ELAN-Compiler aufrufen, nur bei der Ausführung des letzten Packets verwandt werden, weil der ELAN-Compiler nicht rekursiv benutzbar ist. Erweiterungen gegenüber dem Standard * Einem Datenobjekt, das an einen #ib#Datenraum#ie# gebunden werden soll, wird bei der Deklaration das Schlüsselwort #ib#BOUND#ie# vorangestellt. Damit wird dem ELAN-Compiler mitgeteilt, daß er für ein solches Objekt keinen Speicherplatz reservieren muß. Die Assoziation mit einem Daten- raum erfolgt bei der Deklaration mit Hilfe der Initialisierung. Beispiel: BOUND INT VAR objekt :: old ("hugo"); (* eine bereits errichtete Datei wird unter dem Namen "hugo" benutzt. "objekt" ist jetzt an die Datei mit dem Namen "hugo" "gebunden" *) Vorweggenommene Implementation des nächsten Standards In diesem Abschnitt sind Erweiterungen/Einschränkungen des ELAN-Compilers hinsichtlich der aktuellen ELAN-Sprachbeschreibung aufgeführt, die in der nächsten Sprachbeschreibung mit aufgenommen werden. * ASCII-Zeichen, die nicht unmittelbar dargestellt werden können, können in TEXT-Denotern angegeben werden, sofern sie in Anführungszeichen eingeschlossen werden. Beispiele: ""13"" ist ein TEXT-Denoter, der nur CR (carriage return) enthält. "Jetzt erfolgt ein Zeilenwechsel "13""10"" Hier wird nach der Ausgabe des Textes ein "Wagenrücklauf" ('CR', Code = 13) und einen Zeilenvorschub ('LF', Code = 10) erzeugt. ""1""4"" positioniert in die linke obere Ecke eines Bildschirms (Code = 1) und löscht den Bildschirm (Code = 4). * Im aktuellen Standard wurde die #ib#Reihenfolge der Auswertung von Operanden#ie# nicht definiert. Nunmehr wird zusätzlich nicht garantiert, daß alle Operanden ausgewertet werden, wenn dies nicht notwendig ist. Beispiel: IF f (x) > 0 AND x <> 0 THEN ... FI Hier muß beispielsweise 'f (x)' nicht ausgewertet werden, wenn 'x = 0' ist. * Die booleschen Operatoren CAND und COR stehen zusätzlich zur Verfügung. Wirkung: a CAND b :<==> IF a THEN b ELSE FALSE FI a COR b :<==> IF a THEN TRUE ELSE b FI Beispiel: IF element vorhanden THEN verarbeite element FI. element vorhanden: index > 0 CAND liste (index) > 0. * Prozeduren als Parameter. Beispiel: (* Deklaration: *) PROC draw (REAL PROC (REAL CONST) funktion, REAL CONST von, bis, delta) (* Aufruf: *) draw (REAL PROC (REAL CONST) sin, -pi, pi, 0.1) Die obige Form von Prozedur-Parametern wird als "Langform" bezeichnet. Die Langform muß verwandt werden, wenn generische aktuelle Parameter benutzt werden. Eine "Kurzform" reicht aus, wenn der aktuelle Prozedur- Parameter keine generischen Prozedur ist, d.h. eindeutig über den Prozedurnamen (und nicht noch über die Datentypen seiner Parameter) identifiziert werden kann. Die Kurzform unterscheidet sich von der Langform nur beim Aufruf, bei dem eventuelle Resultate und die Daten- typen der Parameter nicht mit angegeben werden müssen. Beispiel: (* Aufruf obiger Prozedur bei nichtgenerischer aktueller Prozedur 'sin' *) draw (PROC sin, -pi, pi, 0.1) * In Paketen sind auch außerhalb von Prozeduren Refinements zugelassen. In solchen "Paket-Refinements" dürfen nur Paket-Objekte angesprochen werden. Insbesondere ist es erlaubt, auch im letzten Paket ('main packet') neben Prozeduren auch Refinements in beliebiger Reihenfolge zu benutzen. Beispiel: PROC kommando erkennung: ... END PROC kommando erkennung; PROC kommando ausführung: ... END PROC kommando ausführung; datei assoziieren; saetze lesen und bearbeiten; ende behandlung. datei assoziieren: FILE VAR f :: sequential file ...; ... saetze lesen und bearbeiten: ... ende behandlung: put ("Ende der Bearbeitung"). Dies ist die Schreibweise, die wir empfehlen. Will man aber Refinements auch zwischen Prozeduren deklarieren, wird es etwas komplizierter. Beispiel: PROC a: END PROC a; ref; (* Refinement Aufruf *) PROC b: END PROC b; (* Achtung: Semikolon, Punkt vor dem Refinement *) .ref: . ; (* Punkt, Semikolon nach dem Refinement *) PROC c: END PROC c Paket-Refinements dürfen auch von Prozeduren benutzt werden, allerdings sind dann auch die Sichtbarkeitsregeln zu beachten. D.h. die Paket- Refinements, die in Prozeduren verwandt werden, dürfen dann auch nur Paket-Objekte ansprechen. Die Aufnahme eines Refinements in das Inter- face ist verboten. 4. Interne Fehlermeldungen des Compilers Interne Fehlermeldungen des Compilers#ie# erfolgen, wenn der ELAN-Übersetzer an implementationsbedingte Einschränkungen stößt. Interne Fehlermeldungen erfolgen in der Form: COMPILER ERROR: wobei folgende Werte annehmen kann: Bedeutung und eventuelle Abhilfe: 101 name table overflow: Die Anzahl der Namen im Programm ist zu groß oder es wurden die Anführungstriche eines TEXT-Denoters vergessen. Keine Abhilfe. 102 symbol table overflow: Die Anzahl der deklarierten Objekte ist zu groß. Abhilfe: Programm in Pakete unterteilen. 103 intermediate string overflow: Abhilfe: Programm in Pakete unterteilen. 104 permanent table overflow Zu viele Pakete insertiert. Abhilfe: Keine (neue Task beginnen). 106 packet address overflow: Insgesamt zu viele Adressen in Paketen ( > 64K ), d.h. ein Daten- objekt ist zu groß. Keine Abhilfe. 107 local data overflow: Ein Datenobjekt in einer Prozedur ist zu groß ( > 32K ). Abhilfe: Datenobjekt in mehrere unterteilen. 204 compiler stack overflow: Keine Abhilfe. 301 too many modules: Zu viele Pakete, Prozeduren und Operatoren ( > 2048 ). Keine Abhilfe. 303 applied table overflow: siehe 304 304 too many labels: In dem gerade übersetzten Modul (Prozedur, Operator oder Paket- rumpf) werden vom Compiler zu viele Marken benötigt (mehr als 2000). Marken werden z.B. für die Codegenerierung von Auswahl (IF ...) und Wiederholung (REP ...) gebraucht. Insbesondere bei SELECT-Anweisungen werden 'casemax - casemin + 2' Marken benötigt, wobei 'casemax' der INT-Wert des maximalen, 'casemin' der des minimalen CASE-Wertes ist. Dieser Fehler ist somit fast immer auf zu viele und/oder zu weit gespannte SELECT-Anweisungen zurückzuführen. Abhilfe: SELECT-Anweisungen über mehrere Prozeduren verteilen oder Spannweiten verringern. 305 code overflow: Der insgesamt erzeugte Code ist zu umfangreich ( > 256K ). Keine Abhilfe. 306 packet data overflow: Insgesamt zu viele Datenobjekte in den Paketen ( > 128K ). Keine Abhilfe. 307 local data overflow: Zu viele (lokale) Datenobjekte in einer Prozedur ( > 32K ). Abhilfe: Prozedur in mehrere unterteilen, so daß die Datenobjekte sich über mehrere Prozeduren verteilen. 308 module code overflow: Ein Modul (Prozedur, Operator oder Paket-Initialisierungsteil) ist zu groß ( > 7.5 KB Code). Abhilfe: In mehrere Prozeduren oder Pakete zerlegen. Anmerkung: Fehlermeldungen, die hier nicht aufgeführt sind, weisen in der Regel auf ein fehlerhaftes Arbeiten des ELAN-Compilers hin. In diesem Fall bitten wir um die Einsendung des Programms (Listing, Quelldatei auf Diskette bei umfangreichen Programmen) und entsprechender Fehlermeldung. 5. Übersicht über die Compiler-Kommandos check BOOL PROC check Zweck: Informationsprozedur. PROC check on Zweck: Einschalten der Generierung von Zeilennummern durch den ELAN-Compiler. Voreingestellt ist 'check on'. PROC check off Zweck: Ausschalten der Generierung von Zeilennummern durch den ELAN-Compiler. do PROC do (TEXT CONST program) Zweck: Übersetzen und Ausführen von 'program' von einem Programm aus. insert PROC insert Zweck: Insertieren eines oder mehrerer PACKETs. Der Programmtext muß sich in einer Datei befinden. Der Dateiname ist der zuletzt benutzte Dateiname. PROC insert (TEXT CONST dateiname) Zweck: Wie oben. Der Programmtext wird aus der Datei mit dem Namen 'dateiname' geholt. PROC insert (THESAURUS CONST t) Zweck: Insertieren aller PACKETs, die in den Dateien des Thesaurus 't' enthalten sind. prot BOOL PROC prot Zweck: Informationsprozedur, ob 'prot' eingeschaltet ist. PROC prot (TEXT CONST dateiname) Zweck: Einschalten des Compilerlistings auf dem Bildschirm. Das Listing wird gleichzeitig in die Datei 'dateiname' geschrieben. prot off PROC prot off Zweck: Ausschalten des Listings. run PROC run Zweck: Übersetzen und Ausführen eines ELAN-Programms. Der Programmtext muß sich in einer Datei befinden. Der Dateiname ist der zuletzt benutzte Dateiname. PROC run (TEXT CONST dateiname) Zweck: Wie oben. Der Programmtext wird aus der Datei mit dem Namen 'dateiname' geholt.