diff options
Diffstat (limited to 'lang/basic')
| -rw-r--r-- | lang/basic/1.8.7/doc/basic handbuch.1 | 1075 | ||||
| -rw-r--r-- | lang/basic/1.8.7/doc/basic handbuch.2 | 2441 | ||||
| -rw-r--r-- | lang/basic/1.8.7/doc/basic handbuch.3 | 698 | ||||
| -rw-r--r-- | lang/basic/1.8.7/doc/basic handbuch.index | 232 | ||||
| -rw-r--r-- | lang/basic/1.8.7/source-disk | 1 | ||||
| -rw-r--r-- | lang/basic/1.8.7/src/BASIC.Administration | 1886 | ||||
| -rw-r--r-- | lang/basic/1.8.7/src/BASIC.Compiler | 2305 | ||||
| -rw-r--r-- | lang/basic/1.8.7/src/BASIC.Runtime | 1571 | ||||
| l--------- | lang/basic/1.8.7/src/eumel coder 1.8.1 | 1 | ||||
| -rw-r--r-- | lang/basic/1.8.7/src/eumel0 codes | bin | 0 -> 512 bytes | |||
| -rw-r--r-- | lang/basic/1.8.7/src/gen.BASIC | 80 | 
11 files changed, 10290 insertions, 0 deletions
| diff --git a/lang/basic/1.8.7/doc/basic handbuch.1 b/lang/basic/1.8.7/doc/basic handbuch.1 new file mode 100644 index 0000000..2e604cb --- /dev/null +++ b/lang/basic/1.8.7/doc/basic handbuch.1 @@ -0,0 +1,1075 @@ +____________________________________________________________________________  +  +  +#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. <Va +          riable>) 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:  +  +  +<Programmzeile>[<Programmzeile>][...]EOF  +  +Dabei bedeutet #ib(3)#EOF (end of file)#ie(3)# das Ende der Programmdatei.  +  +Eine #ib(3)#Programmzeile#ie(3)# hat folgende Syntax:  +  +  +[<Zeilennummer>][<Anweisung>][:<Anweisung>][...][:]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<Name>[(<Parameter>[,<Parameter>][...])]=  +#right#<Funktionsdefinition>  +  +<Name>:                   Zeichenfolge, die der Syntax für Variablennamen ent +                          sprechen muß.  +                          FN<Name> bilden zusammen den Namen der neuen +                          Funktion.  +<#ib(3)#Parameter#ie(3)#>:              Zeichenfolge, die der Syntax für Variablennamen ent +                          sprechen muß.  +<Funktionsdefinition>:    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<Name> [ ( <Argument> [, <Argument>] [...] ) ]  +  +<#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.  + diff --git a/lang/basic/1.8.7/doc/basic handbuch.2 b/lang/basic/1.8.7/doc/basic handbuch.2 new file mode 100644 index 0000000..1379e9e --- /dev/null +++ b/lang/basic/1.8.7/doc/basic handbuch.2 @@ -0,0 +1,2441 @@ +#page nr ("%", 31)#  +#head#  +EUMEL-BASIC-Compiler    8. Übersicht über die Befehle und Funktionen    %  +  +#end#  +  +8. Übersicht über die Anweisungen und Funktionen  +     +  +  +In diesem Kapitel sind alle Anweisungen und Funktionen des vom Compiler übersetz +baren BASIC-Sprachumfangs in alphabetischer Reihenfolge aufgeführt.  +Auch die Anweisungsbestandteile (z.B. ELSE und TO) sind mit einem Hinweis auf die +zugehörige Anweisung eingeordnet.  +Sind bei Funktionen INT- oder REAL-Ausdrücke als Argumente angegeben, so ist +dies als Hinweis auf den Sinn der Funktion zu verstehen. Es können auch Ausdrücke +des jeweils anderen Datentyps eingesetzt werden. Wird statt eines INT-Ausdrucks +ein REAL-Ausdruck angegeben, so darf dessen Wert aber nur innerhalb des +Wertebereichs für INTs liegen, da der REAL-Wert bei der Ausführung der Funktion +in einen INT-Wert konvertiert wird.  +  +  +  +Funktion : ABS  +  +Zweck :        Berechnung des Betrages (Absolutwertes) einer Zahl  +  +Syntax :       ABS (<num. Ausdruck>)  +  +Erklärung :   Liefert den Betrag des numerischen Ausdrucks.  +              Das Ergebnis ist vom gleichen Typ wie das Argument.  +  +  +Beispiel :      10 a = -12.74  +                20 PRINT ABS (a)  +                Ausgabe: 12.74  +  +Vergleiche :  SGN-Funktion  +  +  +  +Operator :  AND  +  +Siehe Kapitel 4.4. (Operatoren)  +  +  +  +Anweisungsbestandteil : AS  +  +Siehe NAME-Anweisung  +  +  +  +Funktion : ASC  +  +Zweck :        Ermittlung des ASCII-Codes eines Textzeichens  +  +Syntax :       ASC (<TEXT-Ausdruck>)  +  +Erklärung :   Die Funktion liefert den ASCII-Code des ersten Zeichens des +              TEXT-Ausdrucks.  +              Der Code wird als INT geliefert.  +  +  +Beispiel :      10 a$ = "Guten Tag !"  +                20 PRINT ASC (a$)  +                Ausgabe:  71  +  +Vergleiche :  CHR$-Funktion (Komplementärfunktion)  +  +  +  +Funktion : ATN  +  +Zweck :        Berechnung des Arcustangens  +  +Syntax :       ATN (<num. Ausdruck>)  +  +Erklärung :   Die Funktion liefert den Arcustangens des  +              numerischen Ausdrucks in Radiant.  +  +  +Beispiel :      10 LET x = 4  +                20 PRINT ATN (x)  +                Ausgabe: 1.325818  +  +Vergleiche :  TAN-Funktion (Komplementärfunktion), SIN, COS  +  +  +  +Anweisungsbestandteil : BASE  +  +Siehe OPTION BASE-Anweisung  +  +  +  +Anweisung : CALL  +  +Zweck :        Aufruf einer insertierten Prozedur  +  +Syntax :       CALL <Prozedurname> #right#[ (<Parameter> [, <Parameter>] [...] ) ]  +  +Erklärung :   <Prozedurname>: Folge aus Zeichen, die für Prozeduren im +              EUMEL-System zugelassen sind (also Buchstaben und  - ab der +              zweiten Stelle -  Zahlen), aber keine Leerzeichen.  +  +              <Parameter>: <CONST-Parameter> | <VAR-Parameter>  +  +              <CONST-Parameter>:   Ausdruck (genau des von der Prozedur +                                   benötigten Typs)  +              <VAR-Parameter>:     Variable (genau des von der Prozedur benö +                                   tigten Typs)  +  +              Die Prozedur mit dem angegebenen <Prozedurnamen> wird mit den +              angegebenen Parametern aufgerufen.  +              Die aufgerufene Prozedur darf keinen Wert liefern (vgl. USR-Funk +              tion).  +  +              Mögliche Fehlerfälle:  +              - Eine Prozedur mit dem Namen <Prozedurnamen> und den an +                gegebenen Parametern gibt es nicht.  +              - Die Prozedur liefert einen Wert.  +              - Die Prozedur benötigt Parametertypen, die in BASIC nicht bekannt +                sind (z.B. BOOL, FILE, TASK, QUIET).  +              - Ein Parameter ist CONST, es wird aber ein VAR-Parameter ver +                langt.  +  +              Weitere Informationen finden Sie in Kapitel 4.7.  +  +Hinweis :     1.  Bei den Parametern wird keine Typkonvertierung vorgenommen.  +              2. Der Prozedurname muß (entgegen der ELAN-Gewohnheit) ohne +                 Leerzeichen angegeben werden.  +              3. Statt des Anweisungswortes CALL kann auch CHAIN geschrieben +                 werden. CALL und CHAIN werden im EUMEL-BASIC nicht wie +                 in Microsoft-BASIC benutzt.  +  +  +Beispiel :      10 CALL sysout ("Meine Datei")  +                20 PRINT "Dieser Text geht nun in die Datei"  +                30 CALL sysout ("")  +                40 PRINT "Wieder auf den Bildschirm"  +                  +  +Vergleiche :  USR-Funktion  +  +  +  +Funktion : CDBL  +  +Zweck :        Konvertierung in den Datentyp REAL  +  +Syntax :       CDBL (<num. Ausdruck>)  +  +Erklärung :   Das Ergebnis des numerischen Ausdrucks wird als REAL geliefert.  +  +  +Beispiel :      10 LET a! = 17  +                20 PRINT USR max (CDBL (a!), 152.3)  +                30 REM max benötigt zwei REALs als Parameter  +  +  +Vergleiche :  CINT-Funktion  +  +  +  +Anweisung : CHAIN  +  +Vollkommen identisch mit der CALL-Anweisung (Erklärung siehe dort !)  +  +  +  +Funktion : CHR$  +  +Zweck :        Erzeugung eines Textzeichens mit einem bestimmten ASCII-Code  +  +Syntax :       CHR$ (<INT-Ausdruck>)  +  +Erklärung :   Die Funktion liefert das Zeichen mit dem ASCII-Code, den der +              INT-Ausdruck angibt.  +              Das Zeichen wird als TEXT geliefert.  +              Die Leistung der Funktion ist nur für Werte im Bereich 0 bis 255 +              definiert.  +  +  +Beispiel :      10 PRINT CHR$ (61)  +                Ausgabe:  =  +  +Vergleiche :  ASC-Funktion (Komplementärfunktion)  +  +  +  +Funktion : CINT  +  +Zweck :        Konvertierung in den Datentyp INT  +  +Syntax :       CINT (<num. Ausdruck>)  +  +Erklärung :   Das Ergebnis des numerischen Ausdrucks wird als INT geliefert. +              REALs werden gerundet. Werte außerhalb des INT-Bereichs führen +              zu einem INT-Überlauf.  +  +  +Beispiel :      10 LET a = 17.625  +                20 PRINT CINT (a); CINT (-a)  +                Ausgabe:  18  -18  +  +Vergleiche :  CDBL-, FIX-, INT-Funktionen  +  +  +  +Anweisung : CLS  +  +Zweck :        Löschen des Bildschirms  +  +Syntax :       CLS  +  +Erklärung :   Löscht den Bildschirm und positioniert den Cursor in die linke obere +              Bildschirmecke (Position 1, 1).  +  +  +Beispiel :      10 CLS  +                20 PRINT "PROGRAMMBEGINN"  +  +  +  +  +Funktion : COS  +  +Zweck :        Berechnung des Cosinus eines Radiantwertes  +  +Syntax :       COS (<Winkel>)  +  +Erklärung :   <Winkel>: REAL-Ausdruck, der den Winkel in Radiant angibt.  +              Die Funktion liefert den Cosinus des Winkels als REAL.  +  +  +Beispiel :      10 PI = 3.141593  +                20 PRINT COS (PI/4)  +                Ausgabe:  .7071067  +  +Vergleiche :  SIN-, TAN-Funktionen  +  +  +  +Funktion : CSRLIN  +  +Zweck :        Ermittlung der aktuellen Cursorzeile  +  +Syntax :       CSRLIN  +  +Erklärung :   Geliefert wird die Nummer der Zeile (als INT), in der sich der Cursor +              auf dem Bildschirm befindet. Die oberste Zeile hat die Nummer 1.  +  +  +Beispiel :      10 CLS  +                20 PRINT  +                30 PRINT CSRLIN  +                Ausgabe:  2  +  +Vergleiche :  POS-Funktion  +  +  +  +Funktion : CVD, CVI  +  +Zweck :        Decodierung von in Texten verschlüsselten Zahlenwerten  +  +Syntax :       CVD (<TEXT-Ausdruck>)  +              CVI (<TEXT-Ausdruck>)  +  +Erklärung :   INTs und REALs können (mit MKI$ und MKD$) zu Texten codiert +              werden.  +              CVD decodiert einen in 8 TEXT-Zeichen codierten REAL-Wert.  +              CVI decodiert einen in 2 TEXT-Zeichen codierten INT-Wert.  +              Es wird beim ersten Zeichen des TEXT-Ausdrucks mit der Dekodie +              rung begonnen.  +              Ist der TEXT zu kurz, so wird mit der Meldung "Ueberlauf bei Subs +              kription" abgebrochen.  +  +  +Beispiel :      10 zahl$ = MKD$ (3.1415)  +                20 PRINT CVD (zahl$)  +                Ausgabe:  3.1415  +  +Vergleiche :  MKD$-, MKI$- Funktionen (Komplementärfunktionen)  +  +  +  +Anweisung : DATA  +  +Zweck :        Ablegen von Konstanten  +  +Syntax :       DATA [<string>] [, [<string>]] [...]  +  +Erklärung :   <string>         : <quoted string> | <unquoted string>  +              <quoted string>  : von Anführungszeichen umschlossene Zeichen +                                 folge, die alle Zeichen außer Anführungs +                                 zeichen enthalten darf  +              <unquoted string>: Zeichenfolge, die alle Zeichen außer Komma +                                 und Doppelpunkt enthalten darf  +  +              Eine DATA-Anweisung stellt einen Datenspeicher dar, der mit READ +              (s.d.) ausgelesen werden kann.  +              In der DATA-Anweisung können "quoted strings" oder "unquo +              ted strings" angegeben werden. "quoted strings" können später nur +              noch als Texte ausgelesen werden.  +              Bei "unquoted strings" wird der Datentyp in der DATA-Anweisung +              dagegen nicht festgelegt. Sie können also als INTs, REALs oder +              TEXTe ausgelesen werden. Sollen "unquoted strings" Zahlenwerte +              darstellen, so müssen sie den in BASIC üblichen Schreibregeln für +              die numerischen Konstanten des jeweiligen Typs genügen. Es sind +              allerdings zusätzlich noch Vorzeichen erlaubt.  +              Wenn die <strings> nicht angegeben sind, so wird ein "nil-Datum" +              abgelegt. Dieses bewirkt bei einem READ mit numerischer Variable +              die Lieferung des Wertes null und bei einem READ mit TEXT-Vari +              able die Lieferung eines Leertextes.  +  +              Die DATA-Anweisungen können an beliebiger Stelle im Programm +              (vor oder hinter den zugehörigen READ-Anweisungen) stehen.  +  +              Alle DATA-Anweisungen eines Programms bilden zusammen einen +              großen sequentiellen Speicher, auf den mit READ der Reihe nach +              zugegriffen wird. Intern wird ein sogenannter READ-DATA-Zeiger +              geführt, der immer auf das nächste auszulesende Element zeigt.  +              Die RESTORE-Anweisung (s.d.) ermöglicht es, den READ- +              DATA-Zeiger auf das erste Element einer bestimmten DATA-Zeile +              zu setzen.  +  +  +Beispiel :      2020 PRINT "Stadt", "Land", "Fluß"  +                2030 READ stadt$, land$, fluß$  +                2040 PRINT stadt$, land$, fluß$  +                .  +                5000 DATA Paris, Frankreich, Seine  +  +  +Vergleiche :  READ-, RESTORE-Anweisungen  +  +  +  +Funktion : DATE$  +  +Zweck :        Abrufen des aktuellen Tagesdatums  +  +Syntax :       DATE$  +  +Erklärung :   Das Tagesdatum wird als Text in der Form TT.MM.JJ geliefert.  +  +  +Beispiel :      10 PRINT "Heute ist der " + DATE$  +                Ausgabe (z.B.):  Heute ist der 28.08.87  +  +Vergleiche :  TIME$-Funktion  +  +  +  +Anweisung : DEFDBL, DEFINT, DEFSNG, DEFSTR  +  +Zweck :        Definition von Anfangsbuchstaben zur Kennzeichnung bestimmter +              Variablentypen  +  +Syntax :       DEFDBL <Buchstabe1> [ - <Buchstabe2>]  +              #right#[, <Buchstabe3> [ - <Buchstabe4>] ] [...]  +              DEFINT <Buchstabe1> [ - <Buchstabe2>]  +              #right#[, <Buchstabe3> [ - <Buchstabe4>] ] [...]  +              DEFSNG <Buchstabe1> [ - <Buchstabe2>]  +              #right#[, <Buchstabe3> [ - <Buchstabe4>] ] [...]  +              DEFSTR <Buchstabe1> [ - <Buchstabe2>]  +              #right#[, <Buchstabe3> [ - <Buchstabe4>] ] [...]  +  +  +Erklärung :   Mit den aufgeführten Anweisungen ist es möglich, bestimmte Buch +              staben festzulegen, die, wenn sie als Anfangsbuchstaben eines +              Variablennamens verwendet werden, der Variablen einen bestimmten +              Typ zuordnen.  +  +              Die Typfestlegung durch Kennzeichnung mit den Zeichen '!', '\#', '%' +              oder '$' hat jedoch Vorrang vor den festgelegten Anfangsbuchstaben. +              Eine genaue Erläuterung, nach welchen Kriterien der BASIC-Compi +              ler den Typ einer Variablen feststellt, befindet sich in Kapitel 4.3.  +  +              Die DEFINT-Anweisung legt Anfangsbuchstaben für INT-Variablen +              fest.  +              Mit der DEFSTR-Anweisung werden Anfangsbuchstaben von +              TEXT-Variablen festgelegt.  +              Die Anweisungen DEFDBL- und DEFSNG- wurden nur aus Kom +              patibilitätsgründen implementiert. Sie werden zwar auf syntaktische +              Richtigkeit überprüft, aber ansonsten vom Compiler nicht beachtet.  +  +              Werden bei den Anweisungen ganze Buchstabenbereiche angegeben, +              so muß der Buchstabe vor dem Bindestrich auch im Alphabet vor +              dem Buchstaben hinter dem Bindestrich stehen.  +  +Hinweis :     1.  Die oben beschriebenen Anweisungen gelten stets erst für die im +                 weiteren Text neu benutzten (also neu eingerichteten) Variablen.  +              2. Die beschriebenen Anweisungen dürfen auch mehr als einmal in +                 einem Programm vorkommen. Die Buchstaben, die in der zweiten +                 und in den folgenden Anweisungen festgelegt werden, werden +                 #on("izusätzlich#off("i zu den in der ersten Anweisung festgelegten Buchsta +                 ben als Kennzeichen für den betreffenden Datentyp vom Compiler +                 vermerkt.  +              3. Der Compiler überprüft nicht, ob gleiche Buchstaben als Kennzei +                 chen für mehr als einen Variablentyp angegeben werden (siehe +                 Kapitel 4.3.). Der Benutzer ist also selbst dafür verantwortlich, daß +                 solche Überschneidungen nicht vorkommen.  +  +  +Beispiel :      10 DEFSTR s - z  +                20 DEFINT a - h, n  +                30 DIM tabelle (17) 'TEXT-Feld  +                40 LET c = 4        'INT-Variable  +                50 LET nummer = 17  'INT-Variable  +                60 LET ueberschrift = "Willkommen" 'TEXT-Variable  +                70 LET reellezahl = 19.563 'REAL-Variable  +                80 LET aha\# = -1.36E17     'REAL-Variable  +                  +  +  +  +Anweisung : DEF FN  +  +Zweck :        Definition einer benutzer-definierten Funktion  +  +Syntax :       DEF FN<Name> [ ( <Parameter> [, <Parameter>] #right# [...] ) ] = <Funktionsdefinition>  +  +Erklärung :   <Name>     :  Zeichenfolge, die der Syntax für Variablennamen +                            entsprechen muß  +                            FN<Name> bilden zusammen den Namen der +                            neuen Funktion  +              <Parameter>:  Zeichenfolge, die der Syntax für Variablennamen +                            entsprechen muß  +              <Funktionsdefinition>:  Ausdruck, der Konstanten, Variablen, die +                                      Parameter der Funktion und Aufrufe +                                      anderer Funktionen enthalten darf  +  +              Mit der DEF FN-Anweisung wird eine benutzer-definierte Funktion +              ("user function") mit dem Funktionsnamen FN<Name> definiert +              (vergleiche hierzu auch Kapitel 4.5.).  +              Die benutzer-definierte Funktion liefert, genau wie die standard +              mäßig eingebauten Funktionen, einen Wert, der sich aus der Auswer +              tung des unter <Funktionsdefinition> angegebenen Ausdrucks +              ergibt.  +              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.  +              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.  +  +              Die Parameter stehen für die beim Aufruf der Funktion übergebenen +              Argumente.  +              Sie haben nur bei der Definition Gültigkeit. Hierbei 'überdecken' sie +              (für diese Zeile) eventuell im BASIC-Programm vorhandene gleich +              namige Variablen.  +              Die Syntax der Parameternamen entspricht der Syntax der Namen +              von einfachen Variablen.  +              Jeder Parameter darf in der Parameterliste nur einmal vorkommen.  +  +              In der Definition dürfen auch Aufrufe von zuvor definierten anderen +              "user functions" erscheinen, nicht aber die zu definierende Funktion +              selbst (rekursive Definition).  +  +              Die Funktionen sind allein durch ihre Namen gekennzeichnet. Gene +              rische Funktionen (gleicher Name, aber unterschiedliche Parameter) +              können somit nicht definiert werden.  +  +Hinweis :     1.  Die Definition einer "user function" muß ihrem ersten Aufruf +                 immer textuell vorausgehen.  +              2. "user functions" können auch mehrfach definiert werden. Der +                 Compiler gibt in einem solchen Fall aber eine Warnung aus, da +                 die neue Definition nur für die textuell folgenden Aufrufe gültig ist.  +  +  +Beispiel :      10 LET pi = 3.1415927  +                20 DEF FNkreisflaeche (radius)  +                #right#= 4.0 * pi * radius * radius  +                1010 PRINT FNkreisflaeche (1.75)  +                Ausgabe:  38.48451  +  +  +  +Anweisung : DIM  +  +Zweck :        Dimensionierung eines Feldes  +  +Syntax :       DIM <Felddeklaration> [, <Felddeklaration>] [...]  +  +Erklärung :   <Felddeklaration>: <Feldvariable> (<INT-Konstante>  +                                 #right#[, <INT-Konstante>] [...] )  +              <Feldvariable>: Name des Feldes (Syntax wie Name von einfachen +                              Variablen, vgl. 4.3.)  +  +              Mit der DIM-Anweisung wird ein Feld dimensioniert, das heißt die +              Anzahl seiner Dimensionen sowie der kleinste und größte Index in +              jeder Dimension werden festgelegt und der Speicherplatz für seine +              Elemente (siehe 4.3.) wird reserviert.  +  +              Der kleinste Index in allen Dimensionen richtet sich nach der letzten +              vorausgegangenen OPTION BASE-Anweisung.  +              Geht der Dimensionierung die Anweisung OPTION BASE 0 textuell +              voraus oder ist keine OPTION BASE-Anweisung vor der Dimensio +              nierung vorhanden, so ist der kleinste Index in allen Dimensionen +              null.  +              Wenn der Dimensionierung aber eine OPTION BASE 1-Anweisung +              vorausgeht, dann ist der kleinste Index in allen Dimensionen eins.  +  +              Der größte Feldindex wird für jede Dimension durch die in Klammern +              stehenden INT-Konstanten angegeben. Die Anzahl dieser INT-Kon +              stanten bestimmt auch, wie viele Dimensionen das dimensionierte +              Feld hat.  +  +              Wird auf ein Element einer Feldvariablen zugegriffen, ohne daß die +              Feldvariable vorher dimensioniert wurde, dann wird das Feld automa +              tisch dimensioniert, wobei die Anzahl der Dimensionen anhand der +              Anzahl der Indizes beim Aufruf ermittelt wird. Der größte Feldindex +              wird bei dieser automatischen Dimensionierung in jeder Dimension +              auf zehn gesetzt. Der kleinste Index richtet sich nach den vorausge +              gangenen OPTION BASE-Anweisungen (siehe oben).  +  +              Fehlerfälle bei der Dimensionierung:  +              - "Das Feld ist bereits dimensioniert":  +                Das Feld wurde bereits explizit, oder automatisch durch den Zugriff +                auf ein Feldelement dimensioniert .  +              - "Die Obergrenze muß >= 1 sein":  +                Es wurde versucht, 0 als größten Index in einer Dimension festzu +                legen, obwohl mit OPTION BASE der kleinste Index auf eins fest +                gelegt wurde.  +  +              Fehlerfälle beim Zugriff auf ein Feldelement:  +              - "Dimensioniert in ... Dimensionen, gefundene Anzahl Indizes ...":  +                Beim Zugriff wurde eine Anzahl von Indizes gefunden, die nicht mit +                der Anzahl der Dimensionen übereinstimmt (Fehler zur Über +                setzungszeit).  +              - "Ueberlauf bei Subskription" oder "Unterlauf bei Subskription":  +                Der Index ist zu groß beziehungsweise zu klein (Fehler zur Lauf +                zeit).  +  +  +Beispiel :      10 DIM a% (20, 10), text$ (30, 40)  +                20 DIM tabelle (5, 7, 25)  +                30 LET element = matrix (1, 7)  +  +              Zeile 30 führt eine automatische Dimensionierung durch, die einem +              DIM matrix (10, 10) entspricht.  +  +  +  +Anweisungsbestandteil : ELSE  +  +Siehe IF-Anweisung  +  +  +  +Anweisung : END  +  +Zweck :        Beenden der Programmausführung eines BASIC-Programms  +  +Syntax :       END  +  +Erklärung :   END beendet die Programmausführung des BASIC-Programms ohne +              eine Meldung (im Gegensatz zu STOP, s.d.).  +              END-Anweisungen dürfen im Programm an beliebiger Stelle stehen, +              und es darf auch mehr als eine END-Anweisung in einem +              Programm vorkommen.  +              Der Compiler übersetzt ein Programm auch nach Erreichen einer +              END-Anweisung weiter.  +              Nach der letzten Anweisung eines Programms muß kein END stehen.  +  +  +Beispiel :      2020 PRINT "Das war's !"  +                2030 REM Hiernach hört's auf  +                2040 END  +  +  +Vergleiche :  STOP-Anweisung  +  +  +  +Anweisungsbestandteil : EOF  +  +Siehe INPUT-Anweisung  +  +  +  +  +Operator : EQV  +  +Siehe Kapitel 4.4. (Operatoren)  +  +  +  +Funktion : ERL  +  +Zweck :        Ermittlung der letzten Fehlerzeile  +  +Syntax :       ERL  +  +Erklärung :   Die Nummer der Zeile, in der der letzte Fehler auftrat, wird als INT +              geliefert.  +  +Hinweis :     ERL ist realisiert durch Aufruf der Prozedur 'errorline' des Betriebs +              systems.  +              Da die Fehlerbehandlungs-Anweisung ON ERROR nicht zur Verfü +              gung steht, ist diese Funktion nicht im üblichen BASIC-Sinne +              brauchbar.  +  +Vergleiche :  ERM$, ERR-Funktionen, ERROR-Anweisung  +  +  +  +Funktion : ERM$  +  +Zweck :        Ermittlung der letzten Fehlermeldung  +  +Syntax :       ERM$  +  +Erklärung :   Die letzte Fehlermeldung wird als TEXT geliefert.  +  +Hinweis :     ERM$ ist realisiert durch Aufruf der Prozedur 'errormessage' des +              Betriebssystems.  +              Da die Fehlerbehandlungs-Anweisung ON ERROR nicht zur Verfü +              gung steht, ist diese Funktion nicht im üblichen BASIC-Sinne +              brauchbar.  +  +Vergleiche :  ERL-, ERR-Funktionen, ERROR-Anweisung  +  +  +  +Funktion : ERR  +  +Zweck :        Ermittlung des letzten Fehlercodes  +  +Syntax :       ERR  +  +Erklärung :   Der Code des letzten aufgetretenen Fehlers wird als INT geliefert.  +  +Hinweis :     ERR ist realisiert durch Aufruf der Prozedur 'errorcode' des Betriebs +              systems.  +              Da die Fehlerbehandlungs-Anweisung ON ERROR nicht zur Verfü +              gung steht, ist diese Funktion nicht im üblichen BASIC-Sinne +              brauchbar.  +  +Vergleiche :  ERL-, ERM$-Funktionen, ERROR-Anweisung  +  +  +  +Anweisung : ERROR  +  +Zweck :        Auslösen eines Fehlers mit bestimmtem Fehlercode  +  +Syntax :       ERROR <INT-Ausdruck>  +  +Erklärung :   Es wird ein Fehler mit dem durch den INT-Ausdruck bestimmten +              Fehlercode ausgelöst.  +  +Hinweis :     ERROR ist realisiert durch Aufruf der Prozedur 'errorstop' des Be +              triebssystems.  +              Da die Fehlerbehandlungs-Anweisung ON ERROR nicht zur Verfü +              gung steht, ist diese Anweisung nicht im üblichen BASIC-Sinne +              brauchbar.  +  +Vergleiche :  ERL-, ERM$-, ERR-Funktionen  +  +  +  +Funktion : EXP  +  +Zweck :        Berechnung einer Potenz der Eulerschen Zahl  +  +Syntax :       EXP (<REAL-Ausdruck>)  +  +Erklärung :   Die Funktion liefert e (die Basis des natürlichen Logarithmus) poten +              ziert mit dem Wert des REAL-Ausdrucks.  +              Bei zu großen Werten kommt es zum Fehler 'REAL-Ueberlauf'.  +              Das Ergebnis der Funktion wird als REAL geliefert.  +  +  +Beispiel :      10 PRINT EXP (10.0)  +                Ausgabe:  22026.47  +  +Vergleiche :  LOG-Funktion (Komplementärfunktion)  +  +  +  +Funktion : FIX  +  +Zweck :        Ermittlung der Vorkommastellen einer REAL-Zahl  +  +Syntax :       FIX (<REAL-Ausdruck>)  +  +Erklärung :   Die Funktion schneidet die Nachkommastellen ab und liefert nur die +              Vorkommastellen des REAL-Ausdrucks.  +              Die Vorkommastellen werden ebenfalls als REALs geliefert.  +  +  +Beispiel :      10 zahl = 1.2345E2  +                20 PRINT FIX (zahl)  +                Ausgabe:  123  +  +Vergleiche :  CINT-, INT-Funktionen  +  +  +  +Anweisung : FOR  +  +Zweck :        Beginn einer Zählschleife  +  +Syntax :       FOR <num. Variable> = <Anfangswert> #ib(3)#TO#ie(3)# <Endwert>  +              #right#[ #ib(3)#STEP#ie(3)# <Schrittweite> ]  +              <Schleifenrumpf>  +  +  +Erklärung :   <num. Variable> : INT- oder REAL-Variable  +              <Anfangswert>   : numerischer Ausdruck  +              <Endwert>       : numerischer Ausdruck  +              <Schrittweite>  : numerischer Ausdruck  +              <Schleifenrumpf>: Folge von Programmzeilen  +  +              Die FOR-Anweisung erlaubt die komfortable Programmierung von +              automatischen Zählschleifen (sogenannten FOR-NEXT-Schleifen). +              Gelangt das Programm während der Ausführung an eine FOR-An +              weisung, so werden zunächst die Ausdrücke <Anfangswert>, +              <Endwert> sowie gegebenenfalls <Schrittweite> ausgewertet. Der +              Anfangswert wird dann der Variablen zugewiesen.  +              Wenn der Wert der Variablen größer ist als der Endwert (bzw. kleiner +              als der Endwert bei negativer Schrittweite), dann wird das Programm +              mit der nach dem korrespondierenden NEXT (s.d.) folgenden +              Anweisung fortgesetzt.  +              Ist dies jedoch nicht der Fall, werden die Anweisungen des <Schlei +              fenrumpfs> ausgeführt. Erreicht das Programm nun die zum FOR +              gehörige NEXT-Anweisung (gleiche Variable), so wird der Wert der +              Variablen um die Schrittweite erhöht beziehungsweise erniedrigt (je +              nach Vorzeichen), und wieder an den Anfang der Schleife verzweigt. +              Hier findet dann wieder der Vergleich des Variableninhalts mit dem +              Endwert statt (siehe oben).  +  +              Die Laufvariable darf innerhalb der Schleife in Ausdrücken vorkom +              men. Sie darf sogar verändert werden (, was aber zu unübersichtli +              chen Effekten führen kann). Auch eine Schachtelung mehrerer +              Schleifen mit der gleichen Laufvariable ist syntaktisch möglich, sollte +              aber #on("iunter allen Umständen#off("i vermieden werden.  +  +              FOR-NEXT-Schleifen dürfen (auch mit WHILE-WEND-Schleifen, +              s.d.) geschachtelt werden. Überschneidungen von FOR-NEXT- +              Schleifen und WHILE-WEND-Schleifen sind aber nicht zulässig.  +  +  +Beispiel :      10 DIM name$ (5)  +                20 FOR i = 1 TO 5  +                30 PRINT "Bitte geben Sie den " + STR$ (i)  +                #right#+ ". Namen ein:";  +                40 INPUT name$ (i)  +                50 NEXT i  +  +  +              Es werden die fünf Elemente des Feldes 'name$' eingelesen.  +  +Vergleiche :  NEXT-, WHILE-, IF-Anweisungen  +  +  +  +Funktion : FRE  +  +Zweck :        Ermittlung des verfügbaren Speicherplatzes  +  +Syntax :       FRE (<num. Ausdruck>)  +              FRE (<TEXT-Ausdruck>)  +  +Erklärung :   Die Funktion liefert die Anzahl der freien Bytes.  +              FRE veranlaßt außerdem ein 'collect heap garbage' (EUMEL- +              Systemprozedur).  +  +              Das Ergebnis der Funktion wird als REAL geliefert.  +              Der Argument-Ausdruck ist ein Dummy-Argument (hat keinen +              Einfluß auf den gelieferten Wert).  +  +Hinweis :     Bei der EUMEL M+ Version wird ein korrektes Ergebnis geliefert +              (vgl.'storage info').  +  +  +Beispiel :      10 PRINT FRE (0)  +                Ausgabe (z.B.):  5324800  +  +  +  +Anweisungsbestandteil : GO  +  +Siehe GOSUB und GOTO  +  +  +  +Anweisung : GOSUB  +  +Zweck :        Unterprogramm-Aufruf  +  +Syntax :       GOSUB <Zeilennummer>  +  +Erklärung :   <Zeilennummer>: INT-Konstante  +              Statt GOSUB darf auch GO #ib(3)#SUB#ie(3)# geschrieben werden.  +  +              Die Programmausführung wird in der Zeile mit der angegebenen +              Zeilennummer fortgesetzt. Die Zeile mit der Zeilennummer muß im +              Programm existieren.  +              Wird im weiteren Programmablauf die Anweisung RETURN gefunden, +              so wird hinter dem letzten abgearbeiteten GOSUB die Programm +              ausführung fortgesetzt.  +              GOSUB dient zum Aufruf von #on("iUnterprogrammen#off("i, die von mehr als +              einer Stelle im Programm (und auch in anderen Unterprogrammen) +              aufgerufen werden können.  +  +Hinweis :     Es wird empfohlen, Unterprogramme im Programm deutlich als solche +              zu kennzeichnen und (durch END, STOP oder GOTO) sicherzustel +              len, daß nur mit GOSUB zu ihnen verzweigt wird, da es sonst leicht +              zu der (Laufzeit-) Fehlermeldung "RETURN ohne GOSUB" kommen +              kann.  +  +  +Beispiel :      140 GOSUB 10000  'Zeige Uhrzeit  +                .  +                .  +                370 GOSUB 10000  'Zeige Uhrzeit  +                9990 END  +                10000 REM Unterprogramm Zeige Uhrzeit  +                10010 PRINT "Es ist " + TIME$ + " Uhr"  +                10020 RETURN  +  +  +Vergleiche :  RETURN-, ON-, GOTO- Anweisungen  +  +  +  +Anweisung : GOTO  +  +Zweck :        Sprung zu einer angegebenen Zeile  +  +Syntax :       GOTO <Zeilennummer>  +  +Erklärung :   <Zeilennummer>: INT-Konstante  +              Statt GOTO darf auch GO #ib(3)#TO#ie(3)# geschrieben werden.  +  +              Die Programmausführung wird in der Zeile mit der angegebenen +              Zeilennummer fortgesetzt. Die Zeile mit der Zeilennummer muß im +              Programm existieren.  +  +  +Beispiel :      10 INPUT "Monat (1-12)", monat%  +                20 IF monat% < 1 OR monat% > 12 THEN GOTO 10  +  +  +Vergleiche :  ON-, IF-, GOSUB- Anweisungen  +  +  +  +Funktion : HEX$  +  +Zweck :        Erzeugung der hexadezimalen Darstellung einer Zahl als Text  +  +Syntax :       HEX$ (<INT-Ausdruck>)  +  +Erklärung :   Die Funktion liefert die hexadezimale (Zweierkomplement-) Darstel +              lung der Zahl, die sich aus dem INT-Ausdruck ergibt.  +  +  +Beispiel :      10 PRINT HEX$ (10000)  +                Ausgabe:  2710  +  +Vergleiche :  OCT$-Funktion  +  +  +  +Anweisung : IF  +  +Zweck :        Sprung zu einer angegebenen Zeile  +  +Syntax :       IF <Bedingung>  +              #right#[,] #ib(3)#THEN#ie(3)# <Anweisung(en)>|<Zeilennummer>  +              #right#[ [,] #ib(3)#ELSE#ie(3)# <Anweisung(en)>|<Zeilennummer>]  +              IF <Bedingung> [,] GOTO <Zeilennummer>  +              #right#[ [,] ELSE <Anweisung(en)>|<Zeilennummer>]  +  +Erklärung :   <Bedingung>    : numerischer Ausdruck  +              <Anweisung(en)>: Eine oder mehrere BASIC-Anweisungen, wobei +                               mehrere wie gewohnt durch ':' zu trennen sind  +              <Zeilennummer> : INT-Konstante  +              Statt GOTO darf auch GO TO geschrieben werden.  +  +              Anhand der Bedingung wird entschieden, ob die Abarbeitung des +              Programms mit dem THEN- oder ELSE-Zweig fortgesetzt werden +              soll. Mit dem THEN-Zweig wird das Programm fortgesetzt, wenn die +              Bedingung erfüllt ist (, d.h. der numerische Ausdruck ungleich null +              ist). Im anderen Fall (Bedingung nicht erfüllt, numerischer Ausdruck +              gleich null) wird das Programm mit dem ELSE-Teil fortgesetzt. Ist +              kein ELSE-Teil angegeben, so wird die Abarbeitung des +              Programmes in der folgenden #on("iZeile#off("i (nicht nach ':') fortgesetzt.  +  +              Sind statt Anweisungen Zeilennummern nach THEN oder ELSE +              angegeben, so entspricht dies einem GOTO (s.d.) zu diesen Zeilen +              nummern.  +  +  +Hinweis :     Auch eine IF-Anweisung muß in #on("ieiner#off("i Programmzeile stehen.  +  +  +Beispiel :      10 IF a >= b THEN IF a > b THEN  +                #right#PRINT "a größer b" ELSE PRINT "a gleich b"  +                #right#ELSE PRINT "a kleiner b"  +  +  +              Das Beispiel zeigt, daß bei geschachtelten IF-Anweisungen die +              ELSE-Teile immer auf das letzte vorhergehende IF bezogen werden, +              für das noch kein ELSE-Teil gefunden wurde.  +  +  +  +Vergleiche :  GOTO-, GOSUB-, ON-Anweisungen  +  +  +  +Operator : IMP  +  +Siehe Kapitel 4.4. (Operatoren)  +  +  +  +Funktion : INKEY$  +  +Zweck :        Holen eines Zeichens von der Tastatur  +  +Syntax :       INKEY$  +  +Erklärung :   Die Funktion liefert ein Textzeichen aus dem Tastaturzeichenpuffer. +              Wurde kein Zeichen eingegeben, so wird ein Leertext (niltext) gelie +              fert.  +              Die gelieferten Zeichen erscheinen nicht auf dem Bildschirm.  +  +  +Beispiel :      10 REM Schreibmaschine  +                20 LET a$ = INKEY$  +                30 IF ASC (a$) = 27 THEN STOP  +                40 PRINT a$;  +                50 GOTO 20  +  +  +              Die eingegebenen Zeichen werden ausgegeben. Abbruch mit ESC.  +  +Vergleiche :  INPUT$-Funktion, INPUT-Anweisung  +  +  +  +Anweisung : INPUT  +  +Zweck :        Einlesen von Daten von der Tastatur  +  +Syntax :       INPUT [;] [<Eingabeaufforderung> ,|; ][ #ib(3)#EOF#ie(3)# +        <Zeilennummer>]  +              #right#<Variable> [, <Variable> ] [...]   +  +Erklärung :   <Eingabeaufforderung>:  TEXT-Konstante  +              <Zeilennummer>:         INT-Konstante  +              <Variable>:             Variable, der der eingelesene Werte +                                      zugewiesen werden soll  +  +              Mit der INPUT-Anweisung werden Daten zur Laufzeit des +              Programms von der Tastatur in Variablen eingelesen.  +  +              Folgt dem INPUT-Statement ein Semikolon, so wird nach +              Beendigung der Eingabe kein Zeilenwechsel vorgenommen.  +  +              Fehlt die <Eingabeaufforderung>, so wird "? " als Eingabe +              aufforderung ausgegeben.  +              Folgt der  ein Semikolon, so wird "? " noch zusätzlich ausge +              geben. Bei einem Komma wird dieser Standard-Prompt unter +              drückt.  +  +              Folgt der <Eingabeaufforderung> die Zeichenfolge 'EOF', so wird +              bei Eingabe eines Leertextes zu der nach 'EOF' angegebenen +              Zeilennumer verzweigt.  +  +              Sollen mehrere Variablen eingelesen werden, so muß der Benutzer +              auch entsprechend viele Daten (durch Kommata getrennt) zur Verfü +              gung stellen.  +  +              Wird nichts eingegeben beziehungsweise nur die richtige Anzahl von +              Kommata, so wird den entsprechenden Variablen 0, 0.0 bzw. 'niltext' +              zugewiesen.  +  +              Bei der Eingabe für eine Textvariable können alle Zeichen (außer +              Steuerzeichen) eingegeben werden. Beginnt eine Eingabe mit dem +              Anführungszeichen oder endet sie damit, dann muß sie auch damit +              enden beziehungsweise beginnen. Diese beiden Anführungszeichen +              werden nicht mit zugewiesen. Innerhalb dieser Texteingabe dürfen +              Anführungszeichen stehen, aber keine Kommata.  +  +              Eingaben für numerische Variablen müssen in der für Konstanten +              üblichen Schreibweise erfolgen. Vorzeichen sind allerdings zusätzlich +              erlaubt.  +  +              Vor Zuweisung der eingegebenen Werte an die Variablen werden +              Anzahl und Typ(en)  und die Anzahl überprüft.  +              Dabei können folgende Fehlerfälle auftreten:  +              - "falscher Typ":  +                Es wurde ein Text statt einer Zahl eingegeben, es wurde ein REAL +                statt eines INTs eingegeben oder eine Texteingabe ist fehlerhaft.  +              - "zu wenig Daten"  +              - "zu viele Daten"  +              - "Überlauf":  +                Es wurde eine zu große (oder zu kleine) Zahl eingegeben.  +  +              Kommt es zu einem Fehler, dann wird nach der Meldung "?Eingabe +              wiederholen !  (<Fehlerbeschreibung>)" die Eingabe zum Editieren +              angeboten.  +  +Hinweis :     Bei Eingabe von 'ESC k' kann die letzte Eingabezeile zum Editieren +              zurückgeholt werden.  +  +              Die Eingabe kann mit der Systemprozedur 'sysin' aus einer Datei +              erfolgen. Aus der Eingabedatei wird für jedes INPUT-Statement eine +              Zeile eingelesen. Die Ausgabe der Eingabeaufforderung und der +              Zeilenwechsel nach der Eingabe werden unterdrückt. Sind die +              Eingabedaten fehlerhaft, so wird das Programm mit 'errorstop' +              abgebrochen.  +  +              Wird die Ausgabe mit 'sysout' umgeleitet, so werden die Eingabe +              aufforderung, die Eingabezeichenfolge und der Zeilenwechsel nach +              der Eingabe auf den Bildschirm und in die Ausgabedatei ausgegeben, +              auch dann, wenn der Text der Eingabe aus einer Datei eingelesen +              wurde.  +  +  +Beispiel :      1990 INPUT "Name, Vorname, Alter";  +                #right#name$, vorname$, alter%  +  +  +Vergleiche :  INKEY$-, INPUT$-Funktionen  +  +  +  +Funktion : INPUT$  +  +Zweck :        Holen einer Zeichenfolge von der Tastatur  +  +Syntax :       INPUT$ (<Anzahl Zeichen>)  +  +Erklärung :   <Anzahl Zeichen>: INT-Ausdruck  +  +              Die Funktion liefert eine Folge von <Anzahl Zeichen> Textzeichen +              aus dem Tastaturzeichenpuffer. Enthält der Puffer nicht alle ge +              wünschten Zeichen, so wird auf weitere Zeichen von der Tastatur +              gewartet.  +              Die gelieferten Zeichen erscheinen nicht auf dem Bildschirm.  +  +  +Beispiel :      10 PRINT "Bitte drei Zeichen eingeben !"  +                20 LET a$ = INPUT$ (3)  +                30 PRINT "Danke schön !"  +  +  +Vergleiche :  INKEY$-Funktion, INPUT-Anweisung  +  +  +  +Funktion : INSTR  +  +Zweck :        Suchen einer Zeichenfolge in einer anderen  +  +Syntax :       INSTR ( [<Startposition>,] <TEXT-Ausdruck1>,  +              #right#<TEXT-Ausdruck 2>)  +  +Erklärung :   <Startposition>: INT-Ausdruck  +  +              Die Funktion liefert die Position, ab der der TEXT-Ausdruck 2 das +              erste Mal im TEXT-Ausdruck 1 vorkommt.  +              Die Position wird als INT geliefert.  +  +  +Beispiel :      10 LET a$ = "hallihallo"  +                20 LET b$ = "all"  +                30 PRINT INSTR (a$, b$); INSTR (5, a$, b$)  +                Ausgabe:   2  7  +  +  +  +Funktion : INT  +  +Zweck :        Ermittlung der nächstkleineren ganzen Zahl  +  +Syntax :       INT (<REAL-Ausdruck>)  +  +Erklärung :   Die Funktion liefert die größte ganze Zahl, für die gilt:  +              n kleiner gleich <REAL-Ausdruck>.  +              Bei positiven Werten bedeutet das, daß die Nachkommastellen abge +              schnitten werden.  +              Das Ergebnis wird als REAL geliefert.  +  +  +Beispiel :      10 PRINT INT (11.74); INT (-11.74)  +                Ausgabe:  11  -12  +  +Vergleiche :  CINT-, FIX-Funktionen  +  +  +  +Anweisung : KILL  +  +Zweck :        Löschen einer Datei in der Task  +  +Syntax :       KILL <Dateiname>  +  +Erklärung :   <Dateiname>: TEXT-Ausdruck  +              Die Datei <Dateiname> wird (ohne Nachfrage) gelöscht.  +  +  +Beispiel :      2110 KILL "Scratchdatei"  +  +  +  +  +Funktion : LEFT$  +  +Zweck :        Erzeugung eines Teiltextes aus einem anderen Text  +  +Syntax :       LEFT$ (<TEXT-Ausdruck>, <Anzahl Zeichen>)  +  +Erklärung :   <Anzahl Zeichen>: INT-Ausdruck  +  +              Die Funktion liefert die ersten <Anzahl Zeichen> Textzeichen des +              TEXT-Ausdrucks.  +  +  +Beispiel :      10 LET a$ = "hallihallo"  +                20 PRINT LEFT$ (a$, 4)  +                Ausgabe:   hall  +  +Vergleiche :  MID$-, RIGHT$-Funktionen, LSET-, MID$-, RSET- +              Anweisungen  +  +  +  +Funktion : LEN  +  +Zweck :        Ermittlung der Länge eines Textes  +  +Syntax :       LEN (<TEXT-Ausdruck>)  +  +Erklärung :   Die Funktion liefert die Anzahl der im TEXT-Ausdruck enthaltenen +              Zeichen (also die Länge des Textes). Die Länge wird als INT +              geliefert.  +              Ein Leertext (niltext, "") hat die Länge null.  +  +  +Beispiel :      10 LET a$ = "hallihallo"  +                20 PRINT LEN (a$)  +                Ausgabe:   10  +  +  +  +Anweisung : LET  +  +Zweck :        Zuweisung eines Wertes an eine Variable  +  +Syntax :       [LET] <Variable> = <Ausdruck>  +  +Erklärung :   Die LET-Anweisung ermöglicht das Zuweisen von Werten an Variab +              len (dazu gehören auch die Elemente von Feldern).  +  +              Das Schlüsselwort LET ist optional, d.h. eine Zuweisung wird auch +              ohne dieses Schlüsselwort erkannt.  +  +              #on("iZuweisung an TEXT-Variablen:#off("i  +                LET <TEXT-Variable> = <TEXT-Ausdruck> oder <num. +                Konstante>  +              Die numerische Konstante wird automatisch in einen TEXT umge +              wandelt (vgl. STR$-Funktion)  +  +              #on("iZuweisung an INT-Variablen:#off("i  +                LET <INT-Variable> = <num. Ausdruck>  +              Ist der numerische Ausdruck ein REAL-Ausdruck, so wird automa +              tisch nach INT konvertiert (vgl. CINT-Funktion).  +  +              #on("iZuweisung an REAL-Variablen:#off("i  +                LET <REAL-Variable> = <num. Ausdruck>  +              Ist der numerische Ausdruck ein INT-Ausdruck, so wird automatisch +              nach REAL konvertiert (vgl. CDBL-Funktion).  +  +  +Beispiel :      10 LET t$ = "murmel marmel"  +                20 LET t$ = 1245.3 'wie "1245.3"  +                30 LET i% = 852  +                40 LET i% = 12.73  'aufgerundet: 13  +                50 LET r = 564     'wie 564.  +                60 LET r = 157.36  +  +  +  +  +Anweisung : LINE INPUT  +  +Zweck :        Einlesen einer Eingabe von der Tastatur in eine TEXT-Variable  +  +Syntax :       LINE INPUT [;] [<Eingabeaufforderung>;]  +              #right#<TEXT-Variable>  +  +Erklärung :   Die LINE INPUT-Anweisung ermöglicht das Einlesen von Eingaben +              in TEXT-Variablen, aber im Gegensatz zu INPUT ohne Beachtung +              von Trennzeichen (z.B. ",").  +  +              Steht direkt nach LINE INPUT ein Semikolon, so wird nach Beendi +              gung der Eingabe der Zeilenwechsel unterdrückt.  +  +              Der eingegebene Text wird (bis auf das CR-Zeichen) der TEXT- +              Variablen zugewiesen.  +  +  +Beispiel :      2110 LINE INPUT "Name: ";name$  +  +  +              Der Benutzer könnte nun auch folgendes eingeben:  +              Neumann, Alfred E.  +  +Vergleiche :  INPUT-Anweisung  +  +  +  +Funktion : LOG  +  +Zweck :        Berechnung des natürlichen Logarithmus einer Zahl  +  +Syntax :       LOG (<REAL-Ausdruck>)  +  +Erklärung :   Die Funktion liefert den natürlichen Logarithmus des Wertes des +              REAL-Ausdrucks.  +              Bei nicht-positiven Werten kommt es zu einem Fehler in der +              EUMEL-Prozedur 'log2'.  +              Das Ergebnis der Funktion wird als REAL geliefert.  +  +  +Beispiel :      10 PRINT LOG (10.0)  +                Ausgabe:  2.302585  +  +Vergleiche :  EXP-Funktion (Komplementärfunktion)  +  +  +  +Funktion : LPOS  +  +Zweck :        Ermittlung der aktuellen Druckspalte  +  +Syntax :       LPOS (<num. Ausdruck>)  +  +Erklärung :   Geliefert wird die Nummer der Spalte (als INT), in die das nächste +              nächste Zeichen mit LPRINT ausgegeben wird. Die Spalte ganz links +              hat die Nummer 1.  +              Der Argument-Ausdruck ist ein Dummy-Argument (hat keinen +              Einfluß auf den gelieferten Wert).  +  +  +Beispiel :      3010 IF LPOS (0) > 65 THEN LPRINT  +                3020 LPRINT name$  +  +  +              Falls die Druckposition hinter Spalte 65 liegt, wird eine neue Druck +              zeile begonnen.  +  +Vergleiche :  LPRINT-Anweisung, TAB-, POS-Funktion  +  +  +  +Anweisung : LPRINT  +  +Zweck :        Ausgabe in eine Druckdatei  +  +Syntax :       LPRINT [#ib(3)#USING#ie(3)# <Format> ;]  +              #right#[ #ib(3)#TAB#ie(3)# (<Spalte>) | , | ; | <Ausdruck> ] [...]  +  +Erklärung :   <Format>  : TEXT-Ausdruck für USING (vgl. PRINT)  +              <Spalte>  : INT-Ausdruck (vgl. PRINT)  +              <Ausdruck>: TEXT-Ausdruck oder numerischer Ausdruck  +  +              Die LPRINT-Anweisung arbeitet wie PRINT (siehe dort), mit dem +              Unterschied, daß LPRINT die Zeichen nicht auf den Bildschirm, son +              dern in eine Datei mit dem Namen "BASIC LPRINT OUTPUT" +              ausgibt. Diese Datei wird automatisch eingerichtet, falls sie noch +              nicht existiert. Ist sie schon vorhanden, so werden die auszugeben +              den Zeichen am Ende der Datei angefügt.  +              Nach oder bei Ablauf des Programms kann die Datei (evtl. nach +              vorheriger Aufbereitung durch Textverarbeitungsprogramme) mit +              'print', wie im EUMEL-System üblich, an den Drucker geschickt +              werden. Der Benutzer ist selbst dafür verantwortlich, daß er die +              Druckdatei, sofern die Daten nicht mehr benötigt werden, vor einem +              neuen Programmlauf leert oder löscht. Versäumt er dies, so bleiben +              die alten Daten in der Druckdatei, und die neuen Ausgaben werden +              hinten angefügt. Das Löschen der Druckdatei kann zum Beispiel +              durch das BASIC-Programm mit der KILL-Anweisung erreicht +              werden.  +  +              Die Art der Ausgabe und die Syntax ist sonst analog zur PRINT- +              Anweisung (siehe Erläuterungen dort).  +  +  +Beispiel :      2110 LPRINT "Dieser Text geht in die Druckdatei"  +                2120 LPRINT TAB (12); "Datum: " DATE$  +                2130 LPRINT 1, 2, 3  +  +  +Vergleiche :  PRINT-Anweisung, LPOS-Funktion  +  +  +  +Anweisung : LSET  +  +Zweck :        Ersetzen von Zeichen eines Textes von links her  +  +Syntax :       LSET <TEXT-Variable> = <TEXT-Ausdruck>  +  +Erklärung :   Das Ergebnis des TEXT-Ausdrucks wird, links beginnend, in der +              TEXT-Variablen eingesetzt. Es werden höchstens so viele Zeichen +              ersetzt, wie bisher schon in der Variablen vorhanden waren, das heißt +              die Länge des Textes in der Variablen ändert sich nicht.  +  +  +Beispiel :      210 LET a$ = "12345"  +                220 LSET a$ = "ABCDEFG"  +                230 PRINT a$,  +                240 LSET a$ = "abc"  +                250 PRINT a$  +                Ausgabe:    ABCDE         abcDE  +  +Vergleiche :  MID$-, RSET-Anweisungen, LEFT$-, MID$-, RIGHT$-Funk +              tionen  +  +  +  +Anweisung : MID$  +  +Zweck :        Ersetzen von Zeichen innnerhalb eines Textes  +  +Syntax :       MID$ (<TEXT-Variable>, <Startposition>  +              #right#[, <Anzahl Zeichen>] ) = <TEXT-Ausdruck>  +  +Erklärung :   <Startposition> : INT-Ausdruck  +              <Anzahl Zeichen>: INT-Ausdruck  +  +              Das Ergebnis des TEXT-Ausdrucks wird, bei <Startposition> +              beginnend, in der TEXT-Variablen eingesetzt. Es werden höch +              stens LEN <TEXT-Variable> Textzeichen ersetzt. Ist keine +              <Anzahl Zeichen> angegeben, so werden so viele Zeichen des +              TEXT-Ausdrucks wie möglich in der TEXT-Variablen eingetragen.  +              Außerdem gilt: Es wird nicht über das bisherige Ende des Variablen +              inhalts ersetzt, das heißt die Länge des Textes in der Variablen +              ändert sich nicht.  +  +  +Beispiel :      210 LET a$ = "12345"  +                220 MID$ (a$, 3) = "ABCDEFG"  +                230 PRINT a$,  +                240 MID$ (a$, 2, 1) = "abc"  +                250 PRINT a$  +                Ausgabe:    12ABC           1aABC  +  +Vergleiche :  LEFT$-, MID$-, RIGHT$-Funktionen, LSET-, RSET- +              Anweisungen  +  +  +  +Funktion : MID$  +  +Zweck :        Erzeugung eines Teiltextes aus einem anderen Text  +  +Syntax :       MID$ (<TEXT-Ausdruck>,  +              #right#<Startposition> [, <Anzahl Zeichen>])  +  +Erklärung :   <Startposition> : INT-Ausdruck  +              <Anzahl Zeichen>: INT-Ausdruck  +  +              Die Funktion liefert höchstens <Anzahl Zeichen> Textzeichen des +              TEXT-Ausdrucks von Position <Startposition> an.  +              Wird <Anzahl Zeichen> nicht angegeben, so werden alle Zeichen +              ab Startposition geliefert.  +              Werden rechts von <Startposition> keine Zeichen mehr gefunden +              oder ist <Anzahl Zeichen> gleich null, so wird ein Leertext geliefert.  +  +  +Beispiel :      10 LET a$ = "hallihallo"  +                20 PRINT MID$ (a$, 4, 4),  +                30 PRINT MID$ (a$, 6)  +                Ausgabe:   liha           hallo  +  +Vergleiche :  LEFT$-, RIGHT$-Funktionen, LSET-, MID$-, RSET- +              Anweisungen  +  +  +  +Funktion : MKD$, MKI$  +  +Zweck :        Codierung von Zahlenwerten in Texte  +  +Syntax :       MKD$ (<REAL-Ausdruck>)  +              MKI$ (<INT-Ausdruck>)  +  +Erklärung :   Mit MKD$ und MKI$ können INTs und REALs zu Texten codiert +              werden.  +  +              Die Funktion MKD$ liefert einen 8 Zeichen langen TEXT, der den +              Wert des REAL-Ausdrucks codiert enthält.  +              Vergleichbar arbeitet MKI$, das einen 2 Zeichen langen TEXT liefert, +              der den Wert des INT-Ausdrucks darstellt.  +  +              Mit MKD$ und MKI$ codierte Werte können mit CVD und CVI (s.d.) +              wieder decodiert werden.  +  +  +Beispiel :      10 zahl$ = MKD$ (3.1415)  +                20 PRINT CVD (zahl$)  +                Ausgabe:  3.1415  +  +Vergleiche :  CVD-, CVI-Funktionen  +  +  +  +Operator : MOD  +  +Siehe Kapitel 4.4. (Operatoren)  +  +  +  +Anweisung : NAME  +  +Zweck :        Umbenennen einer Datei  +  +Syntax :       NAME <alter Name> AS <neuer Name>  +  +Erklärung :   <alter Name>: TEXT-Ausdruck  +              <alter Name>: TEXT-Ausdruck  +  +              NAME benennt die Datei <alter Name> in <neuer Name> um.  +  +  +Beispiel :      10 NAME "Käufer" AS "Kunden"  +  +  +  +  +Anweisung : NEXT  +  +Zweck :        Markierung des Endes einer FOR-Schleife  +  +Syntax :       NEXT [<num. Variable>] [, <num. Variable>] [...]  +  +Erklärung :   NEXT markiert das Ende einer FOR-Schleife (vergleiche FOR- +              Anweisung).  +  +              Wird keine Variable angegeben, so bezieht sich das NEXT auf das +              letzte textuell vorhergehende FOR.  +              Wird eine Laufvariable angegeben, so muß sie mit der im letzten +              FOR verwendeten Laufvariable übereinstimmen.  +              Werden mehrere Variablen angegeben, so werden durch die +              NEXT-Anweisung mehrere FOR-Schleifen abgeschlossen.  +              Beachten Sie, daß FOR-Schleifen sich nicht überschneiden dürfen, +              sondern nur Schachtelungen zulässig sind. Es kommt daher auf die +              Reihenfolge der Variablen bei den NEXT-Anweisungen an. Die +              letzte (innerste) FOR-Schleife muß als erste wieder mit dem zuge +              hörigen NEXT abgeschlossen werden.  +  +Vergleiche :  FOR-, WHILE-Anweisungen  +  +  +  +Operator : NOT  +  +Siehe Kapitel 4.4. (Operatoren)  +  +  +  +Funktion : OCT$  +  +Zweck :        Erzeugung der oktalen Darstellung einer Zahl als Text  +  +Syntax :       OCT$ (<INT-Ausdruck>)  +  +Erklärung :   Die Funktion liefert die oktale (Zweierkomplement-) Darstellung der +              Zahl, die sich aus dem INT-Ausdruck ergibt.  +  +  +Beispiel :      10 PRINT OCT$ (10000)  +                Ausgabe:  23420  +  +Vergleiche :  OCT$-Funktion  +  +  +  +Anweisung : ON  +  +Zweck :        Ausführung eines "berechneten" Sprungs oder Unterprogramm- +              Aufrufs  +  +Syntax :       ON <Sprungziel Nr.> GOTO | GOSUB  +              #right#<Zeilennummer> [, <Zeilennummer>] [...]  +  +Erklärung :   <Sprungziel Nr.>: INT-Ausdruck  +              <Zeilennummer>   : INT-Konstante  +  +              ON ermöglicht die Verzweigung des Programms an eine von mehre +              ren Stellen abhängig vom Ergebnis eines INT-Ausdrucks.  +              Gelangt das Programm an eine ON-Anweisung, dann wird zunächst +              der Wert des INT-Ausdrucks berechnet. Dieses Ergebnis bildet dann +              die Nummer n des Sprungziels. Danach wird zur n-ten Zeilen +              nummer, die nach GOTO beziehungsweise GOSUB steht, verzweigt.  +              Die maximale Anzahl von Zeilennummern, die nach GOTO oder +              GOSUB angegeben werden dürfen, ist 512.  +              Nimmt <Sprungziel Nr.> einen Wert an, zu dem keine Zeile in der +              Liste gefunden wird (z.B. Werte kleiner gleich null oder Werte größer +              als die Anzahl der angegebenen Zeilennummern), so wird das Pro +              gramm mit der der ON-Anweisung folgenden Programmzeile fortge +              setzt.  +  +              Statt GOTO und GOSUB darf auch GO TO beziehungsweise +              GO SUB geschrieben werden.  +  +Hinweis :     Die ON-Anweisung muß in #on("ieiner#off("i Programmzeile stehen.  +  +  +Beispiel :      260 INPUT "Menüpunkt 1, 2 oder 3", a  +                270 ON VAL (a) GOTO 300, 400, 500  +                280 GOTO 260  +                300 PRINT "Menüpunkt 1"  +                .  +                .  +                400 PRINT "Menüpunkt 2"  +                .  +                .  +                500 PRINT "Menüpunkt 3"  +  +  +              Entsprechend der Eingabe wird nach 300, 400 oder 500 verzweigt. +              Bei Fehleingaben wird Zeile 280 ausgeführt.  +  +Vergleiche :  GOSUB-, GOTO-, IF-Anweisungen  +  +  +  +Anweisung : OPTION BASE  +  +Zweck :        Festlegung des kleinsten Wertes für Feldindizes  +  +Syntax :       OPTION BASE 0|1  +  +Erklärung :   OPTION BASE legt fest, ob die nachfolgend dimensionierten Felder +              Elemente mit dem Index 0 erhalten, oder ob der niedrigste Index 1 +              ist. Voreingestellt ist OPTION BASE 0.  +  +Hinweis :     Der niedrigste Feldindex kann für jedes Feld individuell eingestellt +              werden. Die OPTION BASE-Anweisung gilt für alle Felder, deren +              Dimensionierung ihr textuell nachfolgen. Eine erneute OPTION +              BASE-Anweisung kann dann die Untergrenze für die #on("iihr#off("i folgenden +              Dimensionierungen festlegen.  +  +  +Beispiel :      10 DIM a (100)       'Indizes 0-100  +                20 OPTION BASE 1  +                30 b$ (3) = "hallo"  'Indizes 1-10  +                40 DIM a% (5)        'Indizes 1-5  +                50 OPTION BASE 0  +                60 DIM c% (9)        'Indizes 0-9  +                70 LET d (4) = 12.3  'Indizes 0-10  +  +  +Vergleiche :  DIM-Anweisung  +  +  +  +Operator : OR  +  +Siehe Kapitel 4.4. (Operatoren)  +  +  +  +Funktion : POS  +  +Zweck :        Ermittlung der aktuellen Cursorspalte  +  +Syntax :       POS (<num. Ausdruck>)  +  +Erklärung :   Geliefert wird die Nummer der Spalte (als INT), in der sich der Cursor +              auf dem Bildschirm befindet. Die Spalte ganz links hat die Num +              mer 1.  +              Der Argument-Ausdruck ist ein Dummy-Argument (hat keinen +              Einfluß auf den gelieferten Wert).  +  +  +Beispiel :      10 CLS  +                20 PRINT "testtext";  +                30 PRINT POS (0)  +                Ausgabe:  testtext 9  +  +  +Vergleiche :  CSRLIN-, LPOS-Funktionen  +  +  +  +Anweisung : PRINT  +  +Zweck :        Ausgabe auf den Bildschirm  +  +Syntax :       PRINT [#ib(3)#USING#ie(3)# <Format> ;]  +              #right#[ #ib(3)#TAB#ie(3)# (<Spalte>) | , | ; | <Ausdruck> ] [...]  +  +Erklärung :   <Format>  : TEXT-Ausdruck für USING (s. u.)  +              <Spalte>  : INT-Ausdruck (s. u.)  +              <Ausdruck>: TEXT-Ausdruck oder numerischer Ausdruck, der +                          ausgegeben werden soll.  +  +               PRINT dient der Ausgabe von Zeichen auf dem Bildschirm.  +               Numerische Werte werden mit sieben signifikanten Ziffer ausgege +               ben. Bei Exponentendarstellung werden für den Exponent maximal 3 +               Ziffern ausgegeben. Hinter allen numerischen Werten und vor posi +               tiven numerischen Werten wird jeweils ein Leerzeichen ausgegeben.  +  +               TAB bewirkt eine Positionierung des Cursors auf die angegebene +               Spalte (die Spalte ganz links hat die Nummer 1). Ist die Spaltenzahl +               größer als die mit WIDTH eingestellte Ausgabebreite, so wird auf die +               Spalte mit der Nummer Spalte MODULO Ausgabebreite positioniert. +               Eine Spaltennummer kleiner gleich null bewirkt eine entsprechende +               Warnung.  +               Ist die Spalte mit der angegebenen Nummer in der aktuellen Zeile +               bereits überschritten, dann wird auf die nächste Zeile positioniert.  +  +               Ein Semikolon bewirkt, daß der Cursor an der gerade erreichten +               Position bleibt.  +  +               Ein Komma bewirkt die Positionierung auf die nächste gültige Spal +               te, für deren Nummer gilt: Nummer MODULO 16 ist 1.  +               Das Komma dient also der Ausgabe in 16 Zeichen breiten Zonen.  +  +               Endet die PRINT-Anweisung mit TAB (<Spalte>), einem Komma +               oder einem Semikolon, dann wird kein Zeilenvorschub ausgelöst.  +  +               #onbold#USING  +               Der EUMEL-BASIC-Compiler unterstützt auch die PRINT +               USING-Anweisung für formatierte Ausgaben.  +               Der nach dem Wort USING angegebene TEXT-Ausdruck spezifi +               ziert das Ausgabeformat für eine PRINT USING-Anweisung.  +  +               Formatierung von Texten:  +               "!": Nur das erste Zeichen einer Zeichenfolge wird ausgegeben  +               "\n Leerzeichen\": Es werden die 2 + n ersten Zeichen einer +                    Zeichenfolge ausgegeben  +               "&": Alle Zeichen einer Zeichenfolge werden ausgegeben  +  +               Formatierung von Zahlen:  +               "\#": bezeichnet eine Ziffernposition  +               ".": Position des Dezimalpunkts  +               "+": (vor oder nach Zahlen) Ausgabe des Vorzeichens  +               "-": (nach Zahlen) gegebenenfalls Ausgabe von "-" hinter der +                    Zahl  +               "**": Führende Leerstellen werden mit Sternchen aufgefüllt; wirkt +                     außerdem wie "\#\#".  +               "$$": Es wird ein Dollarzeichen links vor der formatierten Zahl ausgegeben; +                     wirkt außerdem wie "\#\#".  +               "**$": Führende Leerstellen werden mit Sternchen ausgefüllt und direkt vor +                      der formatierten Zahl wird ein Dollarzeichen ausgegeben; wirkt +                      außerdem wie "\#\#\#".  +               ",": (vor Dezimalpunkt) Unterteilung der Vorkommastellen in Dreier +                    gruppen mittels Komma  +               "^^^^": Position des Exponenten  +               "_": Ein Zeichen, das einem Unterstreichungsstrich folgt, wird unverändert +                    ausgegeben  +  +               Ist der Format-Ausdruck fehlerhaft, so kommt es zum Fehler "USING- +               Format fehlerhaft".  +               Überschreitet eine auszugebende Zahl in irgendeiner Hinsicht die im +               Format-Ausdruck für sie vorgesehene Stellenzahl, so wird das Zeichen "%" +               ausgegeben, um den Fehler anzuzeigen.  +  +  +Hinweis :      1.  PRINT (und PRINT USING) richtet sich bei allen Ausgaben nach +                  der mit WIDTH eingestellten Ausgabebreite.  +               2. Alle Ausgaben von PRINT können mit der Systemprozedur +                  'sysout' in eine Datei umgeleitet werden. Dann wird nichts auf +                  das Terminal ausgegeben.  +               3. Das Verhalten beim Erreichen der letzten Bildschirmzeile kann +                  mit der Prozedur 'basic page' gesteuert werden. Vergleiche +                  hierzu Kapitel 5, "Steuerung der Bildschirmausgabe".  +  +  +Beispiel :      10 PRINT "hallo", 2 ^ 32 TAB (33) "Ende";  +  +               Ausgabe:  hallo            4.294967E+09   Ende  +               Position: 1234567890123456789012345678901234567890  +  +  +Vergleiche :   WRITE-, LPRINT-Anweisungen, POS-, CSRLIN-, SPC- +               Funktionen  +  +  +  +Anweisung : RANDOMIZE  +  +Zweck :        Festlegung eines Anfangswertes für den Zufallszahlengenerator  +  +Syntax :       RANDOMIZE [<num. Ausdruck>]  +  +Erklärung :   Mit RANDOMIZE erhält der Zufallszahlengenerator einen bestimmten +              Startwert.  +              Ist kein numerischer Ausdruck angegeben, so wird während des +              Programmlaufs die Meldung "Startwert des Zufallszahlen +              generators ?" ausgegeben und ein Startwert eingelesen.  +  +              Wird der Zufallszahlengenerator immer mit dem gleichen Wert gestar +              tet, so liefert er auch immer die gleichen Zufallszahlen. Soll er immer +              verschiedene Werte liefern, so kann er zum Beispiel mit der System +              uhr auf zufällige Startwerte gesetzt werden (RANDOMIZE TIMER).  +  +  +Beispiel :      10 RANDOMIZE 4711  +                20 FOR i = 1 TO 5  +                30 PRINT INT (RND * 10);  +                40 NEXT i  +                Ausgabe:   5  6  2  9  6  +  +Vergleiche :  RND-Funktion  +  +  +  +Anweisung : READ  +  +Zweck :        Auslesen von Daten aus DATA-Anweisungen  +  +Syntax :       READ <Variable> [, <Variable>] [...]  +  +Erklärung :   <Variable>: numerische Variable oder TEXT-Variable  +  +              Die READ-Anweisung liest die nächsten Elemente aus der aktuellen +              DATA-Anweisung (s.d.) in die angegebenen Variablen ein.  +  +              In TEXT-Variablen können sowohl "quoted strings" als auch "un +              quoted strings" (vgl. DATA-Anweisung) eingelesen werden.  +              In numerische Variablen können dagegen nur "unquoted strings" +              eingelesen werden. Außerdem müssen die Zeichen des "unquoted +              string" eine gültige Darstellung einer numerischen Konstanten (even +              tuell mit Vorzeichen) sein. Sind diese Bedingungen nicht erfüllt, so +              kommt es bei der Ausführung des Programms zu entsprechenden +              Fehlern.  +  +              Eine READ-Anweisung kann Daten aus vorangehenden und nach +              folgenden DATA-Anweisungen lesen.  +              Alle DATA-Anweisungen eines Programms bilden zusammen einen +              großen sequentiellen Speicher, auf den mit READ der Reihe nach +              zugegriffen wird. Intern wird ein sogenannter READ-DATA-Zeiger +              geführt, der immer auf das nächste auszulesende Element zeigt.  +  +              Die RESTORE-Anweisung (s.d.) ermöglicht es, den READ-DATA- +              Zeiger auf das erste Element einer bestimmten DATA-Zeile zu +              setzen.  +  +              Sind keine Daten mehr für READ vorhanden, so wird die Ausführung +              des Programms mit der Fehlermeldung "Keine Daten mehr für +              READ" abgebrochen.  +  +  +Beispiel :      2020 PRINT "Stadt", "Land", "Fluß"  +                2030 READ stadt$, land$, fluß$  +                2040 PRINT stadt$, land$, fluß$  +                .  +                5000 DATA Köln, Bundesrepublik Deutschland, Rhein  +  +  +Vergleiche :  DATA-, RESTORE-Anweisungen  +  +  +  +Anweisung : REM  +  +Zweck :        Ermöglicht das Einfügen von Kommentaren in ein Programm  +  +Syntax :       REM <Zeichenfolge>  +  +Erklärung :   <Zeichenfolge>: Beliebige Folge von Zeichen  +  +              Wird eine REM-Anweisung gefunden, so wird der Rest der Pro +              grammzeile nicht weiter beachtet. Die Compilierung wird in der fol +              genden Zeile fortgesetzt.  +              Es empfielt sich, von Kommentarzeilen möglichst oft Gebrauch zu +              machen, weil sie den Programmtext dokumentieren und strukturieren.  +  +Hinweis :     Nach REM können keine weiteren Anweisungen mehr in einer Pro +              grammzeile stehen, da sie nicht übersetzt werden. Auch der Doppel +              punkt wird nach REM nicht beachtet.  +  +  +Beispiel :      1000 REM Ausgabe des Feldes  +                1010 FOR i = 1 TO feldgroesse%  +                1020 PRINT "Eintrag"; i; feld (i)  +                1030 NEXT i  +  +  +  +Anweisung : RESTORE  +  +Zweck :        Setzen des READ-DATA-Zeigers auf den Anfang einer angegebe +              nen Zeile  +  +Syntax :       RESTORE [<Zeilennummer>]  +  +Erklärung :   <Zeilennummer>: INT-Konstante  +  +              Der READ-DATA-Zeiger (vgl. DATA-Anweisung) wird auf die Zeile +              <Zeilennummer> gesetzt.  +              Wird keine Zeilennummer angegeben, so wird für <Zeilennummer> +              1 eingesetzt.  +  +              Existiert die Programmzeile <Zeilennummer> nicht oder ist in ihr +              keine DATA-Anweisung vorhanden, so wird der Zeiger auf die +              nächste textuell folgende DATA-Anweisung gesetzt.  +              Folgt der angegebenen Zeilennummer im Programm keine DATA- +              Anweisung mehr, kommt es zu der Fehlermeldung "RESTORE: Keine +              DATA-Anweisung in oder nach Zeile <Zeilennummer> gefunden !"  +  +  +Beispiel :      10 READ a, b, c  +                20 RESTORE  +                30 READ d, e, f  +                40 DATA 2, 3, 5  +                50 PRINT a; b; c; d; e; f  +                Ausgabe:   2  3  5  2  3  5  +  +Vergleiche :  DATA-, READ-Anweisungen  +  +  +  +Anweisung : RETURN  +  +Zweck :        Rücksprung aus einem Unterprogramm  +  +Syntax :       RETURN  +  +Erklärung :   RETURN bewirkt einen Rücksprung aus dem Unterprogramm hinter +              die aufrufende GOSUB-Anweisung.  +  +              Es dürfen auch mehrere RETURN-Anweisungen in einem Unterpro +              gramm vorkommen, um es an verschiedenen Stellen zu verlassen.  +  +              Wird ein RETURN gefunden, ohne daß ein GOSUB durchlaufen +              wurde, so wird mit der Fehlermeldung "RETURN ohne GOSUB" +              abgebrochen.  +  +  +Beispiel :      140 GOSUB 10000  'Zeige Uhrzeit  +                .  +                .  +                370 GOSUB 10000  'Zeige Uhrzeit  +                9990 END  +                10000 REM Unterprogramm Zeige Uhrzeit  +                10010 PRINT "Es ist " + TIME$ + " Uhr"  +                10020 RETURN  +  +  +Vergleiche :  GOSUB-, ON-Anweisungen  +  +  +  +Funktion : RIGHT$  +  +Zweck :        Erzeugung eines Teiltextes aus einem anderen Text  +  +Syntax :       RIGHT$ (<TEXT-Ausdruck>, <Anzahl Zeichen>)  +Erklärung :   <Anzahl Zeichen>: INT-Ausdruck  +  +              Die Funktion liefert die letzten <Anzahl Zeichen> Textzeichen des +              TEXT-Ausdrucks.  +              Ist <Anzahl Zeichen> größer gleich der Länge des TEXT- +              Ausdrucks, so wird der gesamte Ausdruck geliefert.  +  +  +Beispiel :      10 LET a$ = "hallihallo"  +                20 PRINT RIGHT$ (a$, 5)  +                Ausgabe:   hallo  +  +Vergleiche :  LEFT$-, MID$-Funktionen, LSET-, MID$-, RSET-Anweisungen  +  +  +  +Funktion : RND  +  +Zweck :        Erzeugung von Zufallszahlen  +  +Syntax :       RND [<num. Ausdruck>]  +  +Erklärung :   Wird kein Argument angegeben, so wird ein Wert größer null für den +              Ausdruck angenommen.  +  +              RND (x) liefert  +  +              für x > 0:  +              eine neue Zufallszahl. Es gilt immer: 0 <= RND < 1. Der Betrag +              des Arguments hat keinen Einfluß auf das Ergebnis.  +  +              für x = 0:  +              die letzte gelieferte Zufallszahl noch einmal.  +  +              für x < 0:  +              eine neue Zufallszahl. Vorher wird aber RANDOMIZE x (s.d.) ausge +              führt.  +  +              Die Zufallszahlen werden als REALs geliefert.  +              Der Zufallszahlengenerator kann mit der RANDOMIZE-Anweisung +              auf bestimmte Startwerte eingestellt werden.  +  +  +Beispiel :      10 FOR i = 1 TO 5  +                20 PRINT INT (RND * 10)  +                30 NEXT i  +                Ausgabe (z.B.):   7  9  9  5  0  +  +Vergleiche :  RANDOMIZE-Anweisung  +  +  +  +Anweisung : RSET  +  +Zweck :        Ersetzen von Zeichen eines Textes von rechts her  +  +Syntax :       RSET <TEXT-Variable> = <TEXT-Ausdruck>  +  +Erklärung :   Das Ergebnis des TEXT-Ausdrucks wird, rechts beginnend, in der +              TEXT-Variablen eingesetzt. Es werden höchstens so viele Zeichen +              ersetzt, wie bisher schon in der Variablen vorhanden waren, das heißt +              die Länge des Textes in der Variablen ändert sich nicht.  +              Soll ein Text eingesetzt werden, der länger ist als der Text in der +              Variablen, so wird die Variable nicht verändert.  +  +  +Beispiel :      210 LET a$ = "ABCDEFG"  +                220 RSET a$ = "12345"  +                230 PRINT a$,  +                240 RSET a$ = "abc"  +                250 PRINT a$  +                Ausgabe:    AB12345           AB12abc  +  +Vergleiche :  LSET-, MID$-Anweisungen, LEFT$-, MID$-, RIGHT$-Funk +              tionen  +  +  +  +Funktion : SGN  +  +Zweck :        Ermittlung des Vorzeichens einer Zahl  +  +Syntax :       SGN (<num. Ausdruck>)  +  +Erklärung :   SGN (x) liefert  +              für x > 0:   1  +              für x = 0:   0  +              für x < 0:  -1 .  +  +  +Beispiel :      10 a = -12.74  +                20 PRINT SGN (a); SGN (-a); SGN (0 * a)  +                Ausgabe:  -1  1  0  +  +Vergleiche :  ABS-Funktion  +  +  +  +Funktion : SIN  +  +Zweck :        Berechnung des Sinus eines Radiantwertes  +  +Syntax :       SIN (<Winkel>)  +  +Erklärung :   <Winkel>: REAL-Ausdruck, der den Winkel in Radiant angibt.  +              Die Funktion liefert den Sinus des Winkels als REAL.  +  +  +Beispiel :      10 PI = 3.141593  +                20 PRINT SIN (PI/4)  +                Ausgabe:  .7071068  +  +Vergleiche :  COS-, TAN-Funktionen  +  +  +  +Funktion : SPACE$  +  +Zweck :        Erzeugung einer bestimmten Anzahl von Leerzeichen  +  +Syntax :       SPACE$ (<INT-Ausdruck>)  +  +Erklärung :   Die SPACE$-Funktion liefert einen TEXT, der aus so vielen Leerzei +              chen (Code 32) besteht, wie der Wert des INT-Ausdrucks angibt.  +  +  +Beispiel :      10 PRINT "123456789"  +                20 PRINT "^" + SPACE$ (7) + "^"  +  +              Ausgabe:  123456789  +                        ^       ^  +  +  +Vergleiche :  STRING$-Funktion  +  +  +  +Funktion : SPC  +  +Diese Funktion entspricht exakt der SPACE$-Funktion und wurde nur aus Kompatibi +litätsgründen implementiert.  +  +  +  +Funktion : SQR  +  +Zweck :        Berechnung der Quadratwurzel einer Zahl  +  +Syntax :       SQR (<num. Ausdruck>)  +  +Erklärung :   SQR (x) liefert die Quadratwurzel des durch den numerischen Aus +              druck angegebenen Wertes.  +              Das Ergebnis wird als REAL geliefert.  +  +  +Beispiel :      10 PRINT SQR (100);  +                20 PRINT SQR (2);  +                30 PRINT SQR (17.453)  +                Ausgabe:  10  1.414214  4.177679  +  +  +  +Anweisungsbestandteil : STEP  +  +Siehe FOR-Anweisung  +  +  +  +Anweisung : STOP  +  +Zweck :        Beenden der Programmausführung eines BASIC-Programms mit +              Meldung  +  +Syntax :       STOP  +  +Erklärung :   STOP beendet die Programmausführung des BASIC-Programms.  +              Im Gegensatz zu END (s.d.) erzeugt STOP dabei die Meldung "STOP +              beendet das Programm in Zeile ...".  +  +              STOP-Anweisungen dürfen im Programm an beliebiger Stelle +              stehen, und es darf auch mehr als eine STOP-Anweisung in einem +              Programm vorkommen.  +              Der Compiler übersetzt ein Programm auch nach Erreichen einer +              STOP-Anweisung weiter.  +  +  +Beispiel :      3220 IF eingabe$ = "Ende" THEN STOP  +  +  +Vergleiche :  END-Anweisung  +  +  +  +Funktion : STR$  +  +Zweck :        Konvertierung einer Zahl in einen Text  +  +Syntax :       STR$ (<num. Ausdruck>)  +  +Erklärung :   Die Funktion liefert die Darstellung des Wertes des numerischen +              Ausdrucks als TEXT.  +              Die Zahlen werden so als Text geliefert, wie sie bei einer PRINT- +              Anweisung auf dem Bildschirm erscheinen würden.  +  +  +Beispiel :      10 LET zahl$ = STR$ (1e6)  +                20 PRINT zahl$; LEN (zahl$)  +                Ausgabe:   1000000  7  +  +Vergleiche :  VAL-Funktion (Komplementärfunktion)  +  +  +  +Funktion : STRING$  +  +Zweck :        Erzeugung eines Textes mit mehreren gleichen Zeichen  +  +Syntax :       STRING$ (<Anzahl>, <Code>|<TEXT-Ausdruck>)  +  +Erklärung :   <Anzahl>: INT-Ausdruck  +              <Code>  : INT-Ausdruck  (Wert im Bereich 0 bis 255)  +  +              Die Funktion liefert <Anzahl> mal das Zeichen,  +              - das den ASCII-Code <Code> hat oder  +              - das am Anfang vom Ergebnis des TEXT-Ausdrucks steht.  +  +  +Beispiel :      10 LET pfeil$ = STRING$ (10, "=") + ">"  +                20 PRINT pfeil$;" ";STRING$ (5, 35) '35 entspr. \#  +                Ausgabe:   ==========> \#\#\#\#\#  +  +Vergleiche :  SPACE$-Funktion  +  +  +  +Anweisungsbestandteil : SUB  +  +Siehe GOSUB-Anweisung  +  +  +  +Anweisung : SWAP  +  +Zweck :        Tauschen der Inhalte zweier Variablen  +  +Syntax :       SWAP <Variable1>, <Variable2>  +  +Erklärung :   SWAP tauscht die Inhalte der beiden Variablen.  +  +              Die beiden Variablen müssen vom gleichen Typ sein.  +  +  +Beispiel :      3220 LET a = 10  +                3230 LET b = 20  +                3240 SWAP a, b  +                3250 PRINT a; b  +                Ausgabe:  20  10  +  +  +  +Anweisungsbestandteil : TAB  +  +Siehe PRINT- und LPRINT-Anweisung  +  +  +  +Funktion : TAN  +  +Zweck :        Berechnung des Tangens eines Radiantwertes  +  +Syntax :       TAN (<Winkel>)  +  +Erklärung :   <Winkel>: REAL-Ausdruck, der den Winkel in Radiant angibt.  +              Die Funktion liefert den Tangens des Winkels als REAL.  +  +  +Beispiel :      10 PI = 3.141593  +                20 PRINT TAN (PI/4)  +                Ausgabe:  1  +  +Vergleiche :  COS-, SIN-Funktionen  +  +  +  +Anweisungsbestandteil : THEN  +  +Siehe IF-Anweisung  +  +  +  +Funktion : TIMER  +  +Zweck :        Lesen der Systemuhr (CPU-Zeit der Task)  +  +Syntax :       TIMER  +  +Erklärung :   Die bisher von der Task verbrauchte CPU-Zeit (in Sekunden) wird +              als REAL geliefert.  +  +              TIMER eignet sich auch zum Starten des Zufallszahlengenerators +              (vgl. RANDOMIZE-Anweisung).  +  +  +Beispiel :      2010 LET starttime = TIMER  +                .  +                .  +                2620 PRINT "Verbrauchte CPU-Zeit:";  +                2630 PRINT TIMER - starttime; "Sekunden"  +  +  +Vergleiche :  TIME$-Funktion  +  +  +  +Funktion : TIME$  +  +Zweck :        Abrufen der aktuellen Tageszeit  +  +Syntax :       TIME$  +  +Erklärung :   Die Tageszeit wird als Text in der Form HH.MM.SS geliefert.  +  +  +Beispiel :      10 PRINT "Es ist jetzt "; TIME$; " Uhr"  +                Ausgabe (z.B.):  Es ist jetzt 10:51:17 Uhr  +  +Vergleiche :  DATE$-, TIMER-Funktionen  +  +  +  +Anweisungsbestandteil : TO  +  +Siehe FOR- und GOTO-Anweisungen  +  +  +  +Anweisung : TRON / TROFF  +  +Zweck :        Ein- und Ausschalten der TRACE-Funktion  +  +Syntax :       TRON  +              TROFF  +  +Erklärung :   Der TRACE-Modus dient der Suche nach logischen Fehlern bei der +              Entwicklung von BASIC-Programmen.  +  +              TRON schaltet den TRACE-Modus für die nachfolgend übersetzten +              Programmzeilen ein.  +  +              Ist der TRACE-Modus eingeschaltet, so wird für jede gefundene +              Zeilennummer die Ausgabe dieser Zeilennummer in eckigen +              Klammern mit in den erzeugten Code aufgenommen. Dies hat dann +              während des Laufens den Effekt, daß immer bei Abarbeitung der im +              TRACE-Modus übersetzten Zeilen die aktuelle Zeilennummer aus +              gegeben wird. Es ist so leicht zu verfolgen, in welcher Reihenfolge +              die Zeilen des Programms ausgeführt werden.  +  +              TROFF schaltet den TRACE-Modus für die textuell folgenden Pro +              grammzeilen wieder aus.  +  +  +Beispiel :      5220 TRON  +                5230 REM hier beginnt die kritische  +                5240 REM Programmstelle  +                .  +                .  +                .  +                5970 TROFF  +  +  +              Die Zeilen 5230 bis 5970 werden im TRACE-Modus übersetzt.  +  +  +  +Anweisungsbestandteil : USING  +  +Siehe PRINT-Anweisung  +  +  +  +Funktion : USR  +  +Zweck :        Aufruf einer wertliefernden insertierten Prozedur  +  +Syntax :       USR <Prozedurname>  +              #right#[ (<Parameter> [, <Parameter>] [...] ) ]  +  +Erklärung :   <Prozedurname>: Folge aus Zeichen, die für Prozeduren im +              EUMEL-System zugelassen sind (also Buchstaben und  - ab der +              zweiten Stelle -  Zahlen), jedoch keine Leerzeichen.  +  +              <Parameter>: <CONST-Parameter> | <VAR-Parameter>  +  +              <CONST-Parameter>:   Ausdruck (genau des von der Prozedur +                                   benötigten Typs)  +              <VAR-Parameter>:     Variable (genau des von der Prozedur benö +                                   tigten Typs)  +  +              Die Prozedur mit dem angegebenen <Prozedurnamen> und den +              angegebenen Parametern wird aufgerufen.  +              Die USR-Funktion liefert nach Ausführung der Prozedur das von der +              Prozedur übergebene Ergebnis (Typ INT, REAL oder TEXT).  +  +              Mögliche Fehlerfälle:  +              - Eine Prozedur mit dem Namen <Prozedurnamen> und den ange +                gebenen Parametern gibt es nicht.  +              - Die Prozedur liefert keinen Wert.  +              - Die Prozedur liefert einen Typ, der in BASIC unbekannt ist (zum +                Beispiel BOOL).  +              - Die Prozedur benötigt Parametertypen, die in BASIC nicht bekannt +                sind (z.B. BOOL, FILE, TASK, QUIET).  +              - Ein Parameter ist CONST, es wird aber ein VAR-Parameter ver +                langt.  +  +              Weitere Informationen finden Sie in Kapitel 4.7.  +  +Hinweis :     1.  Bei den Parametern wird keine Typkonvertierung vorgenommen.  +              2. Der Prozedurname muß (entgegen der ELAN-Gewohnheit) ohne +                 Leerzeichen angegeben werden.  +              3. USR ist die einzige Funktion, bei der das Argument (nämlich der +                 Prozeduraufruf) nicht in Klammern stehen darf.  +  +  +Beispiel :      10 LET euler = USR e  +                20 PRINT euler  +                Ausgabe:  2.718282  +  +Vergleiche :  CALL-, CHAIN-Anweisungen  +  +  +  +Funktion : VAL  +  +Zweck :        Konvertierung eines Texts in eine Zahl  +  +Syntax :       VAL (<TEXT-Ausdruck>)  +  +Erklärung :   Die Funktion liefert den Wert der Zahl, deren Darstellung in dem +              übergebenen TEXT-Ausdruck enthalten ist. Führende Leerstellen +              werden dabei überlesen.  +              Sobald ein nicht wandelbares Zeichen festgestellt wird, wird der bis +              dahin ermittelte Wert (am Anfang null) geliefert.  +  +  +Beispiel :      10 LET zahl$ = "-1.256E-63"  +                20 PRINT VAL (zahl$)  +                Ausgabe:   -1.256E-63  +  +Vergleiche :  STR$-Funktion (Komplementärfunktion)  +  +  +  +Anweisung : WEND  +  +Zweck :        Markierung des Endes einer WHILE-Schleife  +  +Syntax :       WEND  +  +Erklärung :   WEND markiert das Ende einer WHILE-Schleife (vergleiche +              WHILE-Anweisung).  +  +Vergleiche :  WHILE-, FOR-Anweisungen  +  +  +  +Anweisung : WHILE  +  +Zweck :        Beginn einer abweisenden Schleife  +  +Syntax :       WHILE <Bedingung>  +              <Schleifenrumpf>  +  +Erklärung :   <Bedingung>     : numerischer Ausdruck  +              <Schleifenrumpf>: Folge von Programmzeilen  +  +              Die WHILE-Anweisung erlaubt die komfortable Programmierung von +              abweisenden Schleifen (sogenannten WHILE-WEND-Schleifen) in +              BASIC.  +              Gelangt das Programm während der Ausführung an eine WHILE- +              Anweisung, so wird zunächst der Bedingungs-Ausdruck ausge +              wertet. Ist die Bedingung nicht erfüllt (falsch, Wert gleich null), so +              wird das Programm mit der nächsten Anweisung hinter der korres +              pondierenden WEND-Anweisung fortgesetzt.  +              Ist die Bedingung dagegen erfüllt (wahr, Wert ungleich null), so +              werden die Anweisungen des Schleifenrumpfs abgearbeitet. Beim +              Erreichen der WEND-Anweisung springt das Programm wieder zur +              WHILE-Anweisung zurück, die Bedingung wird erneut überprüft und, +              je nach Ergebnis, wird der Schleifenrumpf oder die Anweisung nach +              WEND ausgeführt.  +  +              WHILE-WEND-Schleifen dürfen (auch mit FOR-NEXT-Schleifen, +              s.d.) geschachtelt werden. Überschneidungen von WHILE-WEND- +              Schleifen und FOR-NEXT-Schleifen sind jedoch nicht zulässig.  +  +  +Beispiel :      10 LET weiter$ = "j"  +                20 WHILE LEFT$ (weiter$, 1) = "j"  +                30 REM Hier beginnt das eigentliche Programm  +                .  +                .  +                1650 INPUT "Weiter ? (j/n)", weiter$  +                1660 WEND  +  +  +              Das eigentliche Programm wird so lange ausgeführt, bis der Benutzer +              etwas anderes als "j" an der ersten Stelle von 'weiter$' eingibt.  +  +Vergleiche :  FOR-, IF-Anweisungen  +  +  +  +Anweisung : WIDTH  +  +Zweck :        Einstellung der Bildschirmbreite  +  +Syntax :       WIDTH <Zeichen pro Zeile>  +  +Erklärung :   <Zeichen pro Zeile>     : INT-Ausdruck  +  +              Mit der WIDTH-Anweisung wird festgelegt, wie viele Zeichen pro +              Zeile bei Ausgaben auf den Bildschirm oder in Dateien pro Zeile +              ausgegeben werden sollen.  +              Soll für die Druckdatei eine andere Anzahl von Zeichen pro Zeile +              gelten als für den Bildschirm, dann muß vor jeder Sequenz von +              LPRINT-Anweisungen die gewünschte Anzahl mit WIDTH einge +              stellt werden.  +              WIDTH gilt auch für Ausgaben in 'sysout'-Dateien.  +              Insbesondere bei der Ausgabe in Dateien kann ein Wert von mehr als +              80 Zeichen pro Zeile sinnvoll sein.  +  +  +Beispiel :      10 REM es sollen nur 45 Zeichen pro Zeile  +                20 REM ausgegeben werden  +                30 WIDTH 45  +                  +  +Vergleiche :  PRINT-, LPRINT-, WRITE-Anweisungen  +  +  +  +Anweisung : WRITE  +  +Zweck :        Ausgabe von Zahlen und Texten auf dem Bildschirm  +  +Syntax :       WRITE [<Ausdruck>] [, <Ausdruck>] [...]  +  +Erklärung :   <Ausdruck>: numerischer Ausdruck oder TEXT-Ausdruck  +  +              Die WRITE-Anweisung erlaubt die Ausgabe von Daten auf dem +              Bildschirm. Die angegebenen Ausdrücke werden ausgewertet und +              ausgegeben. Dabei werden numerische Werte im gleichen Format +              wie bei der PRINT-Anweisung (s.d.) ausgegeben, mit der Einschrän +              kung, daß den Zahlen keine Leerstelle folgt.  +              Die Ergebnisse von Text-Ausdrücken werden von Anführungszei +              chen umschlossen ausgegeben.  +              Alle Einzelausgaben werden durch Kommata voneinander getrennt.  +  +              Nach Ausgabe aller angegebenen Ausdrücke wird der Cursor an den +              Anfang der nächsten Zeile positioniert.  +  +  +Beispiel :      10 LET a = 10.7: b = 20  +                20 LET c$ = "Testtext"  +                30 WRITE a, b, c$  +                Ausgabe:  10.7, 20,"Testtext"  +  +Vergleiche :  PRINT-, LPRINT-, WIDTH-Anweisungen  +  +  +  +Operator : XOR  +  +Siehe Kapitel 4.4. (Operatoren)  + diff --git a/lang/basic/1.8.7/doc/basic handbuch.3 b/lang/basic/1.8.7/doc/basic handbuch.3 new file mode 100644 index 0000000..14cb499 --- /dev/null +++ b/lang/basic/1.8.7/doc/basic handbuch.3 @@ -0,0 +1,698 @@ +#page nr ("%",97)#  +#head#  +EUMEL-BASIC-Compiler    9. Anpassung von Programmen an den EUMEL-BASIC-Compiler    %  +  +#end#  +  +9. Anpassung von Programmen an den EUMEL-BASIC-Compiler  +    +  +9.1. Unterschiede zwischen BASIC-Inter +     pretern und dem EUMEL-BASIC- +     Compiler  +  +Bei der Anpassung von Programmen für BASIC-Interpreter an den EUMEL- +BASIC-Compiler gibt es einige Besonderheiten zu beachten, die auf den unterschied +lichen Arbeitsweisen von Compilern gegenüber Interpretern beruhen.  +Bei Interpretern fällt die Übersetzung und Ausführung des Quellprogramms zeitlich +zusammen (genau genommen gibt es ja gar keine Übersetzung, sondern das Quell +programm wird #on("i")#interpretiert#off("i")#). Dies hat zur Folge, daß auch nicht zur Ausführung +bestimmte Anweisungen (z.B. Dimensionierungen, Typfestlegungen etc.) erst während +der Ausführung des Programms erkannt und ausgewertet werden.  +Bei Compilern hingegen muß deutlich zwischen der Übersetzungszeit (Compiletime) +und der Laufzeit (Runtime) eines Programms unterschieden werden.  +Der wesentliche Unterschied zwischen Compilern und Interpretern liegt nun in der +Reihenfolge der Kenntnisnahme von den Anweisungen. Während der Interpreter von +den Anweisungen in der Reihenfolge ihres Auftretens entlang des Programmablaufs +Kenntnis nimmt, werden die Anweisungen vom Compiler in der Reihenfolge ihres +textuellen Auftretens zur Kenntnis genommen.  +Da es sich bei dem EUMEL-BASIC-Compiler um einen One-Pass-Compiler +handelt, ist es zwingend notwendig, daß  +- DIM-Anweisungen vor dem ersten Zugriff auf das zu dimensionierende Feld +  stehen.  +- OPTION BASE-Anweisungen vor den betreffenden Dimensionierungen stehen.  +- DEF FN-Anweisungen vor dem ersten Aufruf der zu definierenden Funktion ste +  hen.  +- DEFINT- beziehungsweise DEFSTR-Anweisungen vor der ersten Verwendung der +  betreffenden Variablen erscheinen.  +  +Einige Interpreter lassen sogar den Abschluß von FOR-NEXT- und WHILE- +WEND-Schleifen an mehreren Stellen im Programm zu (z.B. mehrere NEXT- +Anweisungen zu einer FOR-Anweisung). Auch solche "Kunstgriffe" gestattet der +EUMEL-BASIC-Compiler (aus den oben geschilderten Gründen) nicht.  +  +  +  +  +9.2. Abweichungen von ISO 6373-1984 +     (Minimal-BASIC) +      +  +  +Der EUMEL-BASIC-Compiler weicht in folgenden Punkten von der ISO-Norm +6373-1984 für Minimal-BASIC ab:  +- Treten bei der Auswertung von numerischen Ausdrücken Überläufe auf, so wird +  nicht, wie im Standard vorgesehen, eine Warnung ausgegeben und mit bestimmten +  Höchstwerten weitergerechnet, sondern die Ausführung des BASIC-Programms +  wird mit einer entsprechenden Fehlermeldung abgebrochen.  +- Nimmt die Sprungziel-Nummer bei der ON-Anweisung einen fehlerhaften Wert an +  (Nummer < 1 oder Nummer > Anzahl Sprungziele), dann wird nicht, wie im +  Standard empfohlen, mit einer Fehlermeldung abgebrochen, sondern es wird (wie +  auch in Microsoft-BASIC üblich) das Programm mit der der ON-Anweisung fol +  genden Anweisung fortgesetzt.  +- Bei der DATA-Anweisung müssen nicht unbedingt Zeichenfolgen angegeben +  werden. Werden sie weggelassen, dann wird bei Ausführung der READ- +  Anweisung null beziehungsweise Leertext geliefert (vergleiche Kapitel 8, DATA- +  Anweisung).  +- Bei den Eingaben für eine INPUT-Anweisung können ebenfalls die Daten wegge +  lassen werden. Auch hier wird null beziehungsweise Leertext geliefert (vergleiche +  Kapitel 8, INPUT-Anweisung)  +  +  +Die Erweiterungen gegenüber ISO 6373 sollen hier nicht im einzelnen aufgeführt +werden. Bitte vergleichen Sie in Zweifelsfällen die Normungsschrift mit dieser Doku +mentation!  +  +  +  +  +9.3. Anpassung von Microsoft-BASIC Pro +     grammen an den EUMEL-BASIC- +     Compiler +      +  +  +Bei der Entwicklung des EUMEL-BASIC-Compilers wurde zwar auf Übereinstim +mung mit Microsoft-BASIC Wert gelegt, von einer echten Kompatibilität kann aber +aufgrund einer ganzen Reihe fehlender Anweisungen und Funktionen nicht gespro +chen werden.  +Gegenüber Microsoft-BASIC fehlen vor allem:  +- alle "Direkt-Kommandos" (RUN, LIST, LOAD, SAVE, MERGE usw.). Die Aufgaben +  dieser Anweisungen werden von den Prozeduren des EUMEL-Systems über +  nommen.  +- im weiteren Sinne "hardware-nahe" oder an Maschinensprache orientierte Anwei +  sungen und Funktionen (CALL, PEEK, POKE, USR, WAIT usw.)  +- die ERROR-Handling Anweisungen (ON ERROR, RESUME)  +- die Dateiverarbeitungs-Anweisungen und -Funktion (INPUT\#, PRINT\# u.a.; die  +  INPUT- und PRINT-Anweisungen wurden aber auf Zusammenarbeit mit 'sysin' +  und 'sysout' abgestimmt.)  +- die Single-Precision-Variablen (Single- und Double-Precision-Variablen wer +  den beide auf den Datentyp REAL abgebildet.)  +- die hexadezimalen und oktalen Konstanten  +  +Anweisungen und Funktionen, die sich abweichend vom Microsoft-Standard verhal +ten, sind vor allem:  +- CALL, CHAIN, USR  +- ERROR, ERR, ERL  +- LSET, RSET  +  +Wichtige Erweiterungen gegenüber Microsoft-BASIC sind:  +- Möglichkeit des Aufrufs von ELAN-Prozeduren  +- Maximale Anzahl von Zeichen pro Zeile: 32000  +- Maximale Anzahl von Zeichen pro TEXT-Objekt: 32000  +- OPTION BASE wirkt auf einzelne Felder (und nicht unbedingt auf ein ganzes +  Programm)  +  +#on ("b")#  +Hinweis zur Verwendung von MS-BASIC-Programmen im EUMEL-System#off ("b")#  +Sollen Microsoft-BASIC-Programme in das EUMEL-Systemm übernommen wer +den, so ist dabei so vorzugehen:  +1. Speichern Sie das Programm von MS-BASIC aus mit der ASCII-SAVE-Option +   ab.  +   Beispiel: SAVE "PROGRAMM.BAS",A  +2. Lesen Sie das Programm mittels "DOSDAT" (Programm zum Lesen von MS- +   DOS-Dateien) im "file ascii"-Modus ein:  +  +   reserve ("file ascii", /"DOS"); fetch ("PROGRAMM.BAS", /"DOS")  +  +Danach steht ihnen das BASIC-Program in der EUMEL-Textdatei +"PROGRAMM.BAS" zur Verfügung.  +  +#page#  +#head#  +EUMEL-BASIC-Compiler        Anhang A: Reservierte Wörter          %  +  +#end#  +  +Anhang A: #ib(4)#Reservierte Wörter#ie(4)#  +Dieser Anhang enthält eine Übersicht über alle vom EUMEL-BASIC-Compiler +erkannten reservierten Wörter.  +  +ABS                Funktion  +AND                Operator  +AS                 Anweisungsbestandteil  +ASC                Funktion  +ATN                Funktion  +BASE               Anweisungsbestandteil  +CALL               Anweisung  +CDBL               Funktion  +CHAIN              Anweisung  +CHR$               Funktion  +CINT               Funktion  +CLEAR              nicht implementiert  +CLOSE              nicht implementiert  +CLS                Anweisung  +COMMON             nicht implementiert  +FIELD              nicht implementiert  +COS                Funktion  +CSRLIN             Funktion  +CVD                Funktion  +CVI                Funktion  +DATA               Anweisung  +DATE$              Funktion  +DEF                Anweisung  +DEFDBL             Anweisung  +DEFINT             Anweisung  +DEFSNG             Anweisung  +DEFSTR             Anweisung  +DIM                Anweisung  +ELSE               Anweisungsbestandteil  +END                Anweisung  +EOF                Anweisungsbestandteil  +EQV                Operator  +ERL                Funktion  +ERM$               Funktion  +ERR                Funktion  +ERROR              Anweisung  +EXP                Funktion  +FIX                Funktion  +FOR                Anweisung  +FRE                Funktion  +GET                nicht implementiert  +GO                 Anweisungsbestandteil  +GOSUB              Anweisung  +GOTO               Anweisung  +HEX$               Funktion  +IF                 Anweisung  +IMP                Operator  +INKEY$             Funktion  +INPUT              Anweisung  +INPUT$             Funktion  +INSTR              Funktion  +INT                Funktion  +KILL               Anweisung  +LEFT$              Funktion  +LEN                Funktion  +LET                Anweisung  +LINE               Anweisungsbestandteil  +LOC                nicht implementiert  +LOG                Funktion  +LPOS               Funktion  +LPRINT             Anweisung  +LSET               Anweisung  +MID$               Anweisung/Funktion  +MKD$               Funktion  +MKI$               Funktion  +MOD                Operator  +NAME               Anweisung  +NEXT               Anweisung  +NOT                Operator  +OCT$               Funktion  +ON                 Anweisung  +OPEN               nicht implementiert  +OPTION             Anweisung  +OR                 Operator  +OUT                nicht implementiert  +POS                Funktion  +PRINT              Anweisung  +PUT                nicht implementiert  +RANDOMIZE          Anweisung  +READ               Anweisung  +REM                Anweisung  +RESTORE            Anweisung  +RESUME             nicht implementiert  +RETURN             Anweisung  +RIGHT$             Funktion  +RND                Funktion  +RSET               Anweisung  +SGN                Funktion  +SIN                Funktion  +SPACE$             Funktion  +SPC                Funktion  +SQR                Funktion  +STEP               Anweisungsbestandteil  +STOP               Anweisung  +STR$               Funktion  +STRING$            Funktion  +SUB                Anweisungsbestandteil  +SWAP               Anweisung  +TAB                Anweisungsbestandteil  +TAN                Funktion  +THEN               Anweisungsbestandteil  +TIME$              Funktion  +TIMER              Funktion  +TO                 Anweisungsbestandteil  +TROFF              Anweisung  +TRON               Anweisung  +USING              Anweisungsbestandteil  +USR                Funktion  +VAL                Funktion  +WAIT               nicht implementiert  +WEND               Anweisung  +WHILE              Anweisung  +WIDTH              Anweisung  +WRITE              Anweisung  +XOR                Operator  +#page#  +#head#  +EUMEL-BASIC-Compiler       Anhang B: Vom Scanner erkannte Symboltypen    %  +  +#end#  +  +Anhang B: Vom #ib(3)#Scanner#ie(3)# erkannte #ib(3)#Symbol +typen#ie(3)# +  + Der Scanner (ein Paket des EUMEL-BASIC-Systems) hat die Aufgabe, den Pro +grammtext Zeichen für Zeichen durchzugehen und auszulesen ('scannen'). Dabei +werden die Zeichen immer zu logischen Gruppen, sogenannten #on("i")#Symbolen#off("i")# zusammen +gefaßt. Diese Symbole werden dann dem eigentlichen Compilerprogramm geliefert.  +Der Scanner entscheidet nach recht komplizierten Regeln, welche Zeichen aus der +Quelldatei zu einem Symbol zusammengefaßt werden. Dennoch soll in diesem An +hang der Begriff des Symbols etwas näher erklärt werden, da der Anwender (vor allem +bei den Fehlermeldungen) mit Symboltypen konfrontiert wird.  +  +  +  +Reservierte Wörter  +#on ("b")#  +Anfangszeichen:#off ("b")#  Buchstaben  +#on ("b")#  +Folgezeichen:#off ("b")#    Buchstaben  +#on ("b")#  +Beispiele:#off ("b")#       PRINT, VAL, TAB, SUB, TO  +#on ("b")#  +Vergleiche:#off ("b")#      Anhang A  +  +  +  +Operatoren  ++  -  *  /  \  ^  MOD  +NOT  AND  OR  XOR  EQV  IMP  +<  >  =   <=   >=   <>  +  +#on ("b")#  +Vergleiche:#off ("b")#      Kapitel 4.4.  +  +  +  +numerische Konstanten  +#on ("b")#  +Anfangszeichen:#off ("b")#  Ziffern 0 bis 9, Dezimalpunkt '.'  +#on ("b")#  +Folgezeichen:#off ("b")#    zusätzlich: 'd', 'D', 'e' oder 'E', am Schluß auch '%', '!' oder '\#'  +#on ("b")#  +Beispiele:#off ("b")#       1.0, 1.256d123, 12!  +#on ("b")#  +Vergleiche:#off ("b")#      Kapitel 4.2.  +  +  +  +TEXT-Konstanten  +#on ("b")#  +Anfangszeichen:#off ("b")#  Anführungszeichen  +#on ("b")#  +Folgezeichen:#off ("b")#    Alle Zeichen, sogar Doppelpunkte, Apostrophe und Steuerzei +                             chen. Anführungszeichen dürfen #on("i")#innerhalb#off("i")# von +                             TEXT-Konstanten nicht vorkommen. Eine +                             TEXT-Konstante #on("i")#muß#off("i")# aber mit einem Anfüh +                             rungszeichen enden.  +#on ("b")#  +Beispiele:#off ("b")#       "tadellos", "!?': alles mögliche"  +#on ("b")#  +Vergleiche:#off ("b")#      Kapitel 4.2.  +  +  +  +Variablen  +#on ("b")#  +Anfangszeichen:#off ("b")#  Buchstaben  +#on ("b")#  +Folgezeichen:#off ("b")#    zusätzlich: Punkt '.', Ziffern 0 bis 9, Zeichen '$', '%', '!' und '\#'  +#on ("b")#  +Beispiele:#off ("b")#       zeiger, A$, Zahl!, n%, var\#4.3%  +#on ("b")#  +Vergleiche:#off ("b")#      Kapitel 4.3.  +  +  +  +Felder/Feldelemente  +wie Variablen, jedoch gefolgt von '(', den Indexangaben und ')'  +#on ("b")#  +Beispiele:#off ("b")#       zeiger (3), A$ (pointer), Zahl! (7), n%  (a, b, c + d)  +#on ("b")#  +Vergleiche:#off ("b")#      Kapitel 4.3.  +  +  +  +Benutzer-definierte Funktionen  +#on ("b")#  +Anfangszeichen:#off ("b")#  FN  +#on ("b")#  +Folgezeichen:#off ("b")#    Buchstaben, Punkt '.', Ziffern 0 bis 9,  +                             Zeichen '$', '%', '!' und '\#'  +#on ("b")#  +Beispiele:#off ("b")#       FNfunct, FNgauss%, FNf!4.5.6d\#  +#on ("b")#  +Vergleiche:#off ("b")#      Kapitel 4.5.  +  +  +  +EOS (End of Statement, Anweisungsende)  +Doppelpunkt ':'  +  +#on ("b")#  +Vergleiche:#off ("b")#      Kapitel 4.1.  +  +  +  +EOL (End of Line, Zeilenende)  +Apostrophzeichen ' oder Ende der Dateizeile  +EOL bedeutet gleichzeitig auch EOS  +  +#on ("b")#  +Vergleiche:#off ("b")#      Kapitel 4.1.  +  +  +  +EOF (End of File, Dateiende)  +Ende der Quelldatei  +EOF bedeutet gleichzeitig auch EOL (und somit auch EOS)  +  +#on ("b")#  +Vergleiche:#off ("b")#      Kapitel 4.1.  +  +  +  +Trennzeichen  +Alle bisher nicht genannten Zeichen werden vom Scanner als Trennzeichen behan +delt. In BASIC benötigte Trennzeichen sind das Komma (','), das Semikolon (';') sowie +die beiden runden Klammern '(' und ')'.  +Zeichen mit Codes kleiner als 32 (Steuerzeichen) werden vom Scanner überlesen.  +#page#  +#head#  +EUMEL-BASIC-Compiler     Anhang C: Übersicht über die Fehlermeldungen     %  +  +#end#  +  +Anhang C: Übersicht über die Fehlermeldungen  +  +  +Übersicht über die verwendeten Fehlermeldungen zur +Übersetzungszeit +Diese Übersicht enthält alle zur Übersetzungszeit möglichen Fehler, mit Ausnahme +der internen Fehler.  +Die Erläuterungen geben die üblichen Ursachen für die Fehlermeldung an. Es wird +empfohlen, sich im Falle eines Fehlers außerdem in Kapitel 8 über die genaue Syntax +der betreffenden Anweisung beziehungsweise Funktion zu informieren.  +  +  +#on ("b")#AS ohne NAME#off ("b")#  +AS darf nur in NAME-Anweisungen vorkommen.  +  +#on ("b")#Accessrecht VAR erwartet, CONST gefunden#off ("b")#  +Beim Aufruf einer ELAN-Prozedur (CALL, CHAIN oder USR) wurde ein VAR-Para +meter verlangt. Angegeben wurde aber ein CONST-Parameter (zum Beispiel ein +Ausdruck).  +  +#on ("b")#Ausdruck erwartet#off ("b")#  +Es wurde ein numerischer oder TEXT-Ausdruck erwartet. Diese Fehlermeldung +erscheint zum Beispiel, wenn nach einem Operator kein Ausdruck mehr gefunden +wird.  +  +#on ("b")#BASE ohne OPTION#off ("b")#  +BASE darf nur in OPTION BASE-Anweisungen vorkommen.  +  +#on ("b")#Bei SWAP nur gleiche Variablentypen erlaubt#off ("b")#  +Mit SWAP können nur Variablen von genau dem gleichen Typ bearbeitet werden.  +  +#on ("b")#Das Feld ist bereits dimensioniert#off ("b")#  +Diese Fehlermeldung erscheint bei DIM-Anweisungen, wenn das Feld vorher schon +explizit oder automatisch dimensioniert wurde.  +  +#on ("b")#ELSE ohne IF#off ("b")#  +ELSE darf nur in IF-Anweisungen vorkommen. ELSE muß in der gleichen Zeile +stehen wie die zugehörige IF-Anweisung.  +  +#on ("b")#Falsche Felddimension:  +Dimensioniert in ... Dimensionen, gefundene Anzahl Indizes: ...#off ("b")#  +Beim Zugriff auf ein Feldelement wurden zu viele oder zu wenig Indizes angegeben.  +  +#on ("b")#FOR ohne NEXT#off ("b")#  +Diese Fehlermeldung erscheint, wenn am Programmende für eine FOR-Anweisung +kein korrespondierendes NEXT gefunden wurde.  +  +#on ("b")#Falsche Reihenfolge der Zeilennummern#off ("b")#  +Die Zeilennummern wurden nicht in aufsteigender Reihenfolge angegeben.  +  +#on ("b")#Falscher Typ#off ("b")#  +Es wurde ein anderer Datentyp erwartet als angegeben, und es konnte keine automa +tische Konvertierung vorgenommen werden.  +  +#on ("b")#Falscher Typ der Operanden#off ("b")#  +Bei einem dyadischen Operator wurden Operanden angegeben, für deren Typen +dieser Operator nicht definiert ist (vergleiche Kapitel 4.4.).  +  +#on ("b")#Falscher Typ des Operanden#off ("b")#  +Bei einem monadischen Operator wurde ein Operand angegeben, für dessen Typ +dieser Operator nicht definiert ist (vergleiche Kapitel 4.4.).  +  +#on ("b")#Fehlerhafte Bereichsangabe#off ("b")#  +Diese Fehlermeldung kann bei den Anweisungen DEFDBL, DEFINT, DEFSNG und +DEFSTR auftreten, wenn bei einer Bereichsangabe der Buchstabe vor dem Binde +strich im Alphabet nach dem Buchstaben hinter dem Bindestrich steht.  +  +#on ("b")#Fehlerhafte Dimensionierung:   Die Obergrenze muß >= 1 sein#off ("b")#  +Es wurde versucht, ein Feld mit dem größten Index null in einer Dimension zu +dimensionieren, obwohl die Index-Untergrenze mit OPTION BASE auf eins einge +stellt war.  +  +#on ("b")#Fehlerhafte Laufvariable#off ("b")#  +Nach einer NEXT-Anweisung wurde eine Laufvariable gefunden, die nicht zur letzten +anhängigen FOR-Anweisung gehört. Der Fehler tritt auf, wenn Schleifen geschachtelt +wurden.  +  +#on ("b")#Fehlerhafte Zeilennummer#off ("b")#  +Die Zeilennumer entspricht nicht der Syntax für Zeilennumern.  +  +#on ("b")#Fehlerhafter Funktionsaufruf#off ("b")#  +- Die Prozedur liefert keinen Wert  +  Es wurde versucht, eine Prozedur mit USR aufzurufen, die keinen Wert liefert.  +- Der Typ des Resultats ist nicht erlaubt, gefunden: ...  +  Es wurde versucht, eine Prozedur mit USR aufzurufen, die ein Objekt liefert, +  dessen Datentyp in BASIC nicht bekannt ist.  +- Kein Argument erwartet  +  Es wurde versucht, eine benutzer-definierte Funktion, die ohne Parameter definiert +  wurde, mit Argument(en) aufzurufen.  +- ... Argument(e) erwartet  +  Die Anzahl der angegebenen Argumente ist kleiner als die Anzahl der bei der +  Funktionsdefinition angegebenen Parameter.  +- Nur ... Argument(e) erwartet  +  Die Anzahl der angegebenen Argumente ist größer als die Anzahl der bei der Funk +  tionsdefinition angegebenen Parameter.  +- Kein Resultat erlaubt  (gefunden: ...)  +  Bei CALL oder CHAIN wurde versucht, eine wertliefernde Prozedur aufzurufen.  +  +#on ("b")#Funktionsaufruf ohne Zusammenhang#off ("b")#  +Es wurde ein Funktionsaufruf angegeben, wo eine Anweisung erwartet wurde.  +  +#on ("b")#GO ohne TO oder SUB#off ("b")#  +Das reservierte Wort GO kann nur in GO SUB oder GO TO auftreten.  +  +#on ("b")#Interner Fehler#off ("b")#  +Bei der Übersetzung wurde innerhalb des Compilerprogramms ein interner Fehler +ausgelöst. (vergleiche Kapitel 7.1.)  +  +#on ("b")#Nach OPTION BASE ist nur 0 oder 1 erlaubt#off ("b")#  +Es wurde versucht, eine Zahl > 1 nach OPTION BASE anzugeben.  +  +#on ("b")#NEXT ohne FOR#off ("b")#  +Es wurde eine NEXT-Anweisung gefunden, die keiner FOR-Anweisung zuzuordnen +ist, da keine "offenen" FOR-Schleifen mehr anhängig sind.  +  +#on ("b")#Nicht implementiert#off ("b")#  +Einige reservierte Wörter werden vom BASIC-Compiler erkannt, obwohl die zugehö +rigen Anweisungen oder Funktionen nicht implementiert sind (vgl. Anhang A).  +  +#on ("b")#Parametervariable kommt mehrmals vor#off ("b")#  +Bei der Definition einer "user function" kommt ein Parameter in der Parameterliste +mehr als einmal vor.  +  +#on ("b")#Rekursive Funktionsdefinition#off ("b")#  +Es wurde versucht, in der Definition einer "user function" die zu definierende Funk +tion aufzurufen.  +  +#on ("b")#STEP ohne FOR#off ("b")#  +STEP darf nur in FOR-Anweisungen vorkommen.  +  +#on ("b")#SUB ohne GO#off ("b")#  +SUB darf nur in GOSUB vorkommen.  +  +#on ("b")#Syntaxfehler:    <nähere Fehlerangabe>#off ("b")#  +Wenn dieser Fehler erscheint, wurde vom Compiler eine Angabe gefunden, die nach +den Syntaxregeln dort nicht erwartet wurde oder fehlerhaft ist.  +  +#on ("b")#TAB ohne (L)PRINT#off ("b")#  +TAB darf nur in PRINT- und LPRINT-Anweisungen vorkommen.  +  +#on ("b")#THEN ohne IF#off ("b")#  +THEN darf nur in IF-Anweisungen vorkommen. THEN muß in der gleichen Zeile +stehen wie die zugehörige IF-Anweisung.  +  +#on ("b")#TO ohne Zusammenhang#off ("b")#  +TO darf nur in FOR-Anweisungen oder in GO TO vorkommen.  +  +#on ("b")#Text zu lang#off ("b")#  +Dieser Fehler erscheint, wenn ein Anführungszeichen fehlt beziehungsweise ein +Anführungszeichen zu viel gefunden wird.  +  +#on ("b")#Unbekannte Funktion, Argument(e) angegeben: ...#off ("b")#  +Es wurde versucht, eine Funktion mit einem Argument aufzurufen, für dessen Typ die +Funktion nicht definiert ist.  +  +#on ("b")#Unbekannte Prozedur, Parameter angegeben: ...#off ("b")#  +Die angegebene Prozedur konnte mit den angegebenen Parametertypen nicht gefun +den werden.  +  +#on ("b")#Undefinierte 'user function'#off ("b")#  +Es wurde versucht, eine benutzer-definierte Funktion aufzurufen, die (noch) nicht +definiert wurde.  +  +#on ("b")#USING ohne (L)PRINT#off ("b")#  +USING darf nur in PRINT- und LPRINT-Anweisungen vorkommen.  +  +#on ("b")#WEND ohne WHILE#off ("b")#  +Es wurde eine WEND-Anweisung gefunden, die keiner WHILE-Anweisung zuzuord +nen ist, da keine "offenen" WHILE-Schleifen mehr anhängig sind.  +  +#on ("b")#WHILE ohne WEND#off ("b")#  +Diese Fehlermeldung erscheint, wenn am Programmende für eine WHILE-Anweisung +kein korrespondierendes WEND gefunden wurde.  +  +#on ("b")#Zeile mit dieser Nummer existiert nicht#off ("b")#  +Es wurde versucht, mit GOTO oder GOSUB zu einer Zeilennumer zu verzweigen, die +im Programm nicht angegeben wurde.  +  +  +  +  +Übersicht über die innerhalb des BASIC-Systems +ausgelösten Laufzeitfehler +Die meisten Laufzeitfehler werden auch bei BASIC-Programmen im EUMEL-System +erzeugt (vergleiche Kapitel 7.2.). Einige werden aber innerhalb des BASIC-Systems +erzeugt. Die nachfolgende Übersicht enthält die innerhalb des BASIC-Systems aus +gelösten Fehler mit Angabe des gelieferten Fehlercodes und der Fehlermeldung.  +  +#on ("b")#Fehlercode:#off ("b")#     1003  +#on ("b")#Fehlermeldung:#off ("b")#  RETURN ohne GOSUB  +Eine RETURN-Anweisung wurde gefunden, obwohl keine GOSUB-Anweisung mehr +anhängig war.  +  +  +#on ("b")#Fehlercode:#off ("b")#     1004  +#on ("b")#Fehlermeldung:#off ("b")#  RESTORE: Keine DATA-Anweisung in oder nach  +#right#Zeile ... gefunden  +Eine RESTORE-Anweisung konnte nicht ausgeführt werden, weil in oder nach der in +der Anweisung angegebenen Zeilennummer keine DATA-Anweisung mehr steht.  +  +  +#on ("b")#Fehlercode:#off ("b")#     1005  +#on ("b")#Fehlermeldung:#off ("b")#  bei ^: negative Basis, gebrochener Exponent: ...  +Es wurde versucht, eine negative Zahl mit einer gebrochenen Zahl zu potenzieren.  +  +  +#on ("b")#Fehlercode:#off ("b")#     1005  +#on ("b")#Fehlermeldung:#off ("b")#  USING: kein Format gefunden  +Bei einer PRINT USING-Anweisung wurde kein Format für die Ausgabe angegeben +oder die Formatzeichenkette enthält keine Formatzeichen.  +  +  +#on ("b")#Fehlercode:#off ("b")#     1005  +#on ("b")#Fehlermeldung:#off ("b")#  USING-Format fehlerhaft: ...  +Bei einer PRINT USING-Anweisung wurde ein fehlerhaftes Format angegeben.  +  +  +#on ("b")#Fehlercode:#off ("b")#     1004  +#on ("b")#Fehlermeldung:#off ("b")#  Keine Daten mehr für READ  +Es stehen keine Daten mehr für die READ-Anweisung zur Verfügung; der READ- +DATA-Zeiger zeigt hinter das Ende der letzten DATA-Anweisung.  +  +  +#on ("b")#Fehlercode:#off ("b")#     1005  +#on ("b")#Fehlermeldung:#off ("b")#  WIDTH: negative Angabe: ...  +Nach WIDTH wurde eine negative Zahl gefunden.  +  +  +#on ("b")#Fehlercode:#off ("b")#     1013  +#on ("b")#Fehlermeldung:#off ("b")#  READ: Falscher Datentyp, ... ist kein INT  +Einer INT-Variablen konnte kein Wert zugewiesen werden, da das aktuelle Objekt +aus der DATA-Liste keine gültige Darstellung eines INT-Wertes war oder ein +"quoted string" gefunden wurde.  +  +  +#on ("b")#Fehlercode:#off ("b")#     1013  +#on ("b")#Fehlermeldung:#off ("b")#  READ: Falscher Datentyp, ... ist kein REAL  +Einer REAL-Variablen konnte kein Wert zugewiesen werden, da das aktuelle Objekt +aus der DATA-Liste keine gültige Darstellung eines REAL-Wertes war oder ein +"quoted string" gefunden wurde.  +  +  +#on ("b")#Fehlercode:#off ("b")#     1051 (interner Fehler)  +#on ("b")#Fehlermeldung:#off ("b")#  variierend  +Bei der Ausführung des Programms trat in einer Prozedur des BASIC-Systems ein +interner Fehler auf. (Vergleiche Kapitel 7.)  +  +  +#on ("b")#Fehlercode:#off ("b")#     1080  +#on ("b")#Fehlermeldung:#off ("b")#  INPUT-Fehler ( Fehlerart ) : > Eingabezeile <  +Bei einer INPUT-Anweisung, die auf eine mit 'sysin' eingestellte Datei wirken sollte, +kam es zu einem Fehler der angegebenen Fehlerart. Nach dem Doppelpunkt wird die +Eingabezeile aus der Eingabedatei ausgegeben.  +#page#  +#head#  +EUMEL-BASIC-Compiler      Anhang D: ELAN-Prozeduren des Compilers       %  +  +#end#  +  +Anhang D: ELAN-Prozeduren des Compilers  +  +   #on ("b")#PROC #ib(3)#basic#ie(3)# (TEXT CONST dateiname)#off ("b")#  +   Das in der Datei 'dateiname' enthaltene BASIC-Programm wird dem BASIC- +   Compiler zur Übersetzung übergeben. Werden keine Fehler gefunden, so wird das +   Programm direkt nach der Übersetzung ausgeführt.  +   Beispiel:  +  +       basic ("Mein liebstes BASIC-Programm")#off ("b")#  +  +  +   #on ("b")#PROC basic (TEXT CONST dateiname, prozedurname)#off ("b")#  +   Das in der Datei 'dateiname' enthaltene BASIC-Programm wird dem BASIC- +   Compiler zur Übersetzung übergeben. Werden keine Fehler gefunden, dann wird +   das Programm unter dem Namen 'prozedurname' dauerhaft eingetragen (inser +   tiert).  +   Das Programm wird nicht ausgeführt. Beachten Sie, daß der Prozedurname den +   Vorschriften für ELAN-Prozedurnamen entsprechen muß und außerdem #on ("b")#keine +   Leerzeichen#off ("b")# enthalten darf. (Zur Namenswahl siehe auch Kapitel 3.)  +   Beispiel:  +  +       basic ("Mein liebstes BASIC-Programm", "liebstesprogramm")#off ("b")#  +  +  +  +   #on ("b")#PROC #ib(3)#basic list#ie(3)# (BOOL CONST status)#off ("b")#  +   Mit der Prozedur 'basic list' kann eingestellt werden, ob die gerade vom Compiler +   übersetzten Programmzeilen angezeigt werden sollen oder nicht (vergleiche Kapitel +   3.).  +  +   basic list (TRUE)#off ("b")#:  Die übersetzten Zeile werden angezeigt  +   basic list (FALSE)#off ("b")#: Die übersetzten Zeile werden nicht angezeigt  +  +  +   #on ("b")#PROC #ib(3)#basic page#ie(3)# (BOOL CONST status)#off ("b")#  +   Mit der Prozedur 'basic page' kann eingestellt werden, wie die Ausgaben von +   BASIC-Programmen behandelt werden, wenn der Bildschirm voll ist (vergleiche +   Kapitel 5, Steuerung der Bildschirmausgaben).  +  +   basic page (TRUE):  Beim Erreichen des Bildschirmendes wird auf einen +                                           Tastendruck gewartet (vgl. Kap. 5.)  +   basic page (FALSE): Beim Erreichen des Bildschirmendes wird 'gescrollt'.  + diff --git a/lang/basic/1.8.7/doc/basic handbuch.index b/lang/basic/1.8.7/doc/basic handbuch.index new file mode 100644 index 0000000..4ac7e16 --- /dev/null +++ b/lang/basic/1.8.7/doc/basic handbuch.index @@ -0,0 +1,232 @@ +#page nr ("%",115)#  +#head#  +EUMEL-BASIC-Compiler             Stichwortverzeichnis       %  +  +#end#  +  +Stichwortverzeichnis  +  +>=                                                  15  +\                                                   14  +-                                                   14  ++                                                   14  ++                                                   15  +<=                                                  15  +*                                                   14  +/                                                   14  +=                                                   15  +>                                                   15  +<                                                   15  +<>                                                  15  +^                                                   14  +ABS                                                 31  +AND                                                 16  +Anführungszeichen                                   10  +Argument                                            21  +Arithmetische Operatoren                            14  +Arrays                                              13  +ASC                                                 32  +ATN                                                 32  +Äquivalenz-Verknüpfung                              17  +Aufruf benutzer-definierter Funktionen              21  +Aufruf und Steuerung des BASIC-Compilers            5  +basic                                               5, 113  +BASIC-Compiler ERROR                                28  +basic list                                          6, 113  +basic page                                          25, 114  +benutzer-definierte Funktionen                      19, 104  +Bildschirmausgaben                                  25  +CALL                                                23, 33  +CDBL                                                35  +CHAIN                                               23, 35  +CHR$                                                35  +CINT                                                36  +CLS                                                 36  +Codebereichs pro Task                               27  +Compiler Error 304                                  26  +Compiler Error 307                                  26  +Compiler Error 308                                  26  +COS                                                 37  +CSRLIN                                              37  +CVD, CVI                                            38  +DATA                                                38  +DATE$                                               40  +Datentypen                                          10  +Datentyp INT                                        10  +Datentyp REAL                                       10  +Datentyp TEXT                                       10  +Debugging                                           6  +DEFDBL, DEFINT, DEFSNG, DEFSTR                      40  +DEF FN                                              19, 28, 42  +Definition benutzer-definierter Funktionen          19  +DEFINT                                              12  +DEFSTR                                              12  +DIM                                                 13, 43  +Dimensionen                                         13  +Doppelpunkt                                         8  +ELSE                                                54  +END                                                 45  +EOF                                                 56  +EOF (End of File, Dateiende)                        7, 105  +EOL (End of Line, Zeilenende)                       8, 105  +EOS (End of Statement, Anweisungsende)              8, 105  +EQV                                                 17  +ERL                                                 46  +ERM$                                                47  +ERR                                                 47  +ERROR                                               48  +EUMEL-Coder                                         26  +EUMEL-Textdatei                                     7  +Exklusiv-ODER-Verknüpfung                           17  +EXP                                                 49  +Exponent                                            10  +Fehlerbehandlung                                    28  +Fehlercodes                                         30  +Fehlerzeile                                         30  +Fehler zur Laufzeit                                 30, 111  +Fehler zur Übersetzungszeit                         28, 106  +Felder (Arrays)                                     13  +Felder/Feldelemente                                 104  +Feldnamen                                           13  +FIX                                                 49  +FOR                                                 50  +FRE                                                 51  +Funktionen                                          19  +Funktionsaufrufe                                    19  +Ganzzahlen                                          10  +Generatorprogramm                                   4  +Gleitkommazahlen                                    10  +GOSUB                                               52  +GOTO                                                53  +Grenzen des Compilers                               26  +Groß-/Kleinschreibung                               9  +Hauptdurchlauf                                      28  +HEX$                                                54  +Hochkomma                                           8  +IF                                                  54  +IMP                                                 17  +Implikations-Verknüpfung                            17  +Indizes                                             13  +INKEY$                                              56  +INPUT$                                              58  +INPUT                                               56  +Insertieren von BASIC-Programmen                    5  +Installation des BASIC-Compilers                    4  +INSTR                                               59  +INT                                                 59  +Interne Compilerfehler                              28  +INTs                                                10  +INT-Überlauf                                        15  +KILL                                                60  +Konstanten                                          10  +Konvertierung                                       15, 22  +Kriterien für den Typ einer Variablen               12  +Labels                                              26  +Leerzeichen                                         9  +LEFT$                                               60  +LEN                                                 61  +LET                                                 61  +LINE INPUT                                          62  +LOG                                                 63  +Logische Operatoren                                 16  +LPOS                                                63  +LPRINT                                              64  +LSET                                                65  +Mantisse                                            11  +MID$                                                65, 66  +MKD$, MKI$                                          67  +MOD                                                 14  +Modulgrenze                                         26  +NAME                                                68  +Namenstabelle                                       27  +Negation                                            16  +negative Zahlenwerte                                11  +NEXT                                                50, 68  +NOT                                                 16  +Notation                                            3  +Notebook                                            28  +numerische Konstanten                               103  +OCT$                                                69  +ODER-Verknüpfung                                    17  +ON                                                  69  +Operatoren                                          103  +Operatoren, arithmetische                           14  +Operatoren, logische                                16  +Operatoren, Text-                                   15  +Operatoren, Vergleichs-                             15  +Operator, Zuweisungs-                               18  +OPTION BASE                                         13, 71  +OR                                                  17  +Parameter                                           19  +POS                                                 72  +PRINT                                               72  +Prioritäten der Operanden                           18  +Programmdatei                                       7  +Programmsegmente                                    24  +Programmzeile                                       7  +RANDOMIZE                                           75  +READ                                                75  +REM                                                 77  +Reservierte Wörter                                  9, 12, 100, 103  +RESTORE                                             77  +RETURN                                              78  +RIGHT$                                              79  +RND                                                 80  +RSET                                                81  +Scanner                                             9, 103  +Schlüsselwörter                                     9  +Scrolling                                           25  +SGN                                                 81  +SIN                                                 82  +SPACE$                                              82  +SPC                                                 83  +SQR                                                 83  +Standard-Funktionen                                 19  +STEP                                                50  +Steuerung der Bildschirmausgaben                    25  +Steuerung des BASIC-Compilers                       5  +STOP                                                84  +STR$                                                84  +STRING$                                             85  +SUB                                                 52  +SWAP                                                86  +Symbol                                              9  +Symboltypen                                         103  +Syntax                                              7  +sysout                                              6  +TAB                                                 64, 72  +TAN                                                 86  +Texte                                               10  +TEXT-Konstanten                                     104  +Text-Operator +                                     15  +THEN                                                54  +TIME$                                               88  +TIMER                                               87  +TO                                                  50, 53  +Trennzeichen                                        105  +TRON / TROFF                                        88  +Typanpassung                                        22  +UND-Verknüpfung                                     16  +USING                                               64, 72  +USR                                                 23, 90  +Übersetzen von BASIC-Programmen                     5  +Übersichtlichkeit von BASIC-Programmen              7  +VAL                                                 91  +Variablen                                           12, 104  +Variablennamen                                      9, 12  +VAR-Parameter                                       23  +Vergleichsoperatoren                                15  +Vordurchlauf                                        28  +Vorzeichen                                          11  +Wahrheitswerte                                      16  +Weitere Schreibregeln                               9  +WEND                                                92  +wertliefernden Prozeduren                           23  +WHILE                                               92  +WIDTH                                               93  +WRITE                                               94  +XOR                                                 17  +Zahlen                                              10  +Zeilennummer                                        7  +Zuweisungsoperator                                  18  + diff --git a/lang/basic/1.8.7/source-disk b/lang/basic/1.8.7/source-disk new file mode 100644 index 0000000..c87f56d --- /dev/null +++ b/lang/basic/1.8.7/source-disk @@ -0,0 +1 @@ +informatikpaket/02_basic.img diff --git a/lang/basic/1.8.7/src/BASIC.Administration b/lang/basic/1.8.7/src/BASIC.Administration new file mode 100644 index 0000000..6df6854 --- /dev/null +++ b/lang/basic/1.8.7/src/BASIC.Administration @@ -0,0 +1,1886 @@ +(***************************************************************************) +(*                                                                         *) +(*           Zweite von drei Dateien des EUMEL-BASIC-Systems               *) +(*                                                                         *) +(*           Autor: Heiko Indenbirken                                      *) +(*           Überarbeitet von: Rudolf Ruland und Michael Overdick          *) +(*                                                                         *) +(*           Stand: 27.10.1987                                             *) +(*                                                                         *) +(***************************************************************************) + +PACKET basic errors DEFINES basic error,      (* Autor: Heiko Indenbirken *) +                            return error,     (* Stand: 26.08.1987/rr/mo  *) +                            basic warning: + +TEXT VAR erste zeile, +         message; +LET errorsize = 40; +LET ERROR = STRUCT (INT no, TEXT msg); + +ROW errorsize ERROR CONST error msg :: ROW errorsize ERROR :  +(ERROR:( 1, "NEXT ohne FOR"), + ERROR:( 2, "Syntaxfehler:"), + ERROR:( 5, "Fehlerhafter Funktionsaufruf"), + ERROR:( 8, "Zeile mit dieser Nummer existiert nicht"), + ERROR:(10, "Das Feld ist bereits dimensioniert"), + ERROR:(13, "Falscher Typ:"), + ERROR:(15, "Text zu lang"), + ERROR:(18, "Undefinierte 'user function'"), + ERROR:(22, "Ausdruck erwartet"), + ERROR:(26, "FOR ohne NEXT"), + ERROR:(29, "WHILE ohne WEND"), + ERROR:(30, "WEND ohne WHILE"), + ERROR:(51, "Interner Fehler"), + ERROR:(80, "Fehlerhafte Zeilennummer"), + ERROR:(81, "Falsche Reihenfolge der Zeilennummern"), + ERROR:(82, "Falscher Typ des Operanden:"), + ERROR:(83, "Falscher Typ der Operanden:"), + ERROR:(84, "Falsche Felddimension:"), + ERROR:(85, "Rekursive Funktionsdefinition"),  + ERROR:(86, "Fehlerhafte Laufvariable:"), + ERROR:(87, "Fehlerhafte Bereichsangabe:"), + ERROR:(88, "Fehlerhafte Dimensionierung:"), + ERROR:(89, "Parametervariable kommt mehrmals vor"), + ERROR:(90, "AS ohne NAME"), + ERROR:(91, "BASE ohne OPTION"), + ERROR:(92, "ELSE ohne IF"), + ERROR:(93, "STEP ohne FOR"), + ERROR:(94, "TAB ohne (L)PRINT"), + ERROR:(95, "THEN ohne IF"), + ERROR:(96, "TO ohne Zusammenhang"), + ERROR:(97, "USING ohne (L)PRINT"), + ERROR:(98, "Unbekannte Funktion,"), + ERROR:(99, "Unbekannte Prozedur,"), + ERROR:(100,"Nicht implementiert"), + ERROR:(101,"SUB ohne GO"), + ERROR:(102,"GO ohne TO oder SUB"), + ERROR:(103,"Accessrecht VAR erwartet, CONST gefunden"), + ERROR:(104,"Funktionsaufruf ohne Zusammenhang"), + ERROR:(105,"Nach OPTION BASE ist nur 0 oder 1 erlaubt"), + ERROR:(106,"Bei SWAP nur gleiche Variablentypen erlaubt")); + +TEXT PROC errortext (INT CONST no): +  INT VAR i; +  FOR i FROM 1 UPTO errorsize +  REP IF errormsg [i].no = no +      THEN LEAVE errortext WITH errormsg [i].msg FI +  PER; +  "Unbekannter BASIC-Fehler #" + text (no)  . +END PROC errortext; + +PROC basic error (TEXT CONST packet, +                  INT CONST error nr, +                  INT CONST line nr, +                  INT CONST statement nr, +                  TEXT CONST position, addition, +                  BOOL CONST leave statement): +  erste zeile aufbauen; +  einfache fehlermeldung aufbauen;  +  diese auf terminal ausgeben;  +  diese in sysout datei ausgeben wenn noetig;                    (* F20/rr *) +  fehlermeldung in fehlerdatei ausgeben; +  IF leave statement                                             (* DEF/mo *) +    THEN errorstop (101, packet + "-Fehler") +  FI. + +erste zeile aufbauen: +  IF line nr = 0 AND statement nr = 0 +  THEN erste zeile := "FEHLER" +  ELSE erste zeile := "FEHLER (Dateizeile "; +       erste zeile CAT text (line nr); +       erste zeile CAT ") in Zeile "; +       erste zeile CAT text (statement nr); +  FI; +  +  erste zeile CAT " bei >> "; +  erste zeile CAT position; +  erste zeile CAT " << : "  . + +einfache fehlermeldung aufbauen: +  message := "   "; +  message CAT error text (error nr); +  message CAT "   "  . +  +diese auf terminal ausgeben:                                     (* F20/rr *) +  display (""13""10""); +  display (erste zeile); +  display (""13""10""); +  display (message + addition); +  display (""13""10"") . +  +diese in sysout datei ausgeben wenn noetig :                      (* F20/rr *) +  IF sysout <> "" +     THEN putline (erste zeile); +          putline (message + addition); +          line; +  FI . + +fehlermeldung in fehlerdatei ausgeben: +  note (erste zeile); +  note line; +  note (message); +  note (addition); +  note line . +  +END PROC basic error; + +PROC basic warning (INT CONST line nr,                   (* mo *) +                              statement nr, +                    TEXT CONST warning text): +generate warning; +on screen; +in sysout file; +into the notebook. + +generate warning: +  IF line nr = 0 AND statement nr = 0 +  THEN erste zeile := "WARNUNG" +  ELSE erste zeile := "WARNUNG (Dateizeile "; +       erste zeile CAT text (line nr); +       erste zeile CAT ") in Zeile "; +       erste zeile CAT text (statement nr); +  FI; +  erste zeile CAT ": "; +  erste zeile CAT warning text. + +on screen: +  display (""13""10""); +  display (erste zeile); +  display (""13""10""). + +in sysout file: +  IF sysout <> "" +     THEN putline (erste zeile); +          line; +  FI. + +into the notebook: +  IF warnings +    THEN note (erste zeile); +         note line +  FI. + +END PROC basic warning; + +PROC return error: +  errorstop (1003, "RETURN ohne GOSUB") +END PROC return error; + +END PACKET basic errors; + +PACKET basic types DEFINES symbol of,         (* Autor: Heiko Indenbirken *) +                           type of,           (* Stand: 07.09.1987/rr/mo  *) +                           dim of, +                           shift, deshift, +                           reserved, +                           param list, +                           is bool op: + +LET (*                 S y m b o l    T y p e n                          *) +    any      =  0,    const    =  1,    var     =  2,    array    =  3, +    expr     =  4,    unused   =  5,    letter  =  6,    param    =  7, +    res word =  8,    operator =  9,    eos     = 10,    del      = 11, +    stat no  = 12,    eol      = 13,    eop     = 14, +    user fn  = 20;  (* DEF/mo *) +(*                               Operatoren                              *) +LET less equal = 28,  unequal = 29,  greater equal = 30; + +TEXT VAR dummy; +  +TEXT PROC symbol of (INT CONST n) : +  IF n < 0 +  THEN ""19"" + symbol of (-n) +  ELSE SELECT n OF +       CASE less equal    : "<=" +       CASE unequal       : "<>" +       CASE greater equal : ">=" + +       CASE eos           : "EOS" +       CASE eol           : "EOL" +       CASE eop           : "EOF" +       OTHERWISE : character END SELECT +  FI  .  + +character : +  IF n > 32 AND n < 128 +  THEN code (n) +  ELIF n >= 128 AND n <= 255 +  THEN res word of (n) +  ELSE "%" + subtext (text (n+1000), 2) + " " FI  . + +END PROC symbol of; + +TEXT PROC type of (INT CONST n) : +  SELECT n OF +  CASE any      : "ANY" +  CASE const    : "Konstante" +  CASE var      : "Variable" +  CASE array    : "Feld" +  CASE expr     : "Ausdruck" +  CASE unused   : " -?- " +  CASE letter   : "Buchstabe"  +  CASE param    : "Parameter" +  CASE res word : "reserviertes Wort" +  CASE operator : "Operator" +  CASE eos      : "EOS" +  CASE del      : "Trennzeichen" +  CASE stat no  : "Zeilennumer" +  CASE eol      : "EOL" +  CASE eop      : "EOF" +  CASE user fn  : "'user function'"                   (* DEF/mo *) +  OTHERWISE "?TYPE #" + text (n) ENDSELECT. +END PROC type of; + +TEXT PROC dim of (TEXT CONST parameter): +  IF parameter = "" +  THEN "" +  ELSE base limits and size FI  . + +base limits and size: +  INT CONST dimension :: (LENGTH parameter DIV 2) - 2; +  TEXT VAR result :: text (parameter ISUB dimension+1); +  INT VAR i; +  result CAT ": ["; +  FOR i FROM 1 UPTO dimension-1 +  REP result CAT text (parameter ISUB i); +      result CAT ", " +  PER; +  result CAT text (parameter ISUB dimension); +  result CAT "]  "; +  result CAT text (parameter ISUB dimension+2); +  result  . + +END PROC dim of; + +TEXT PROC param list (INT CONST first, no): +  IF no < first +  THEN "keine" +  ELSE parameter list FI  . + +parameter list: +  INT VAR i; +  TEXT VAR result :: "("; +  FOR i FROM first UPTO no +  REP result CAT dump (dtype (i)); +      IF i = no +         THEN result CAT ")" +         ELSE result CAT ", " FI +  PER; +  result  . + +END PROC param list; + +TEXT PROC shift (TEXT CONST word) : +  INT VAR i; +  dummy := word; +  FOR i FROM 1 UPTO length (word) +  REP shift char PER; +  dummy  . + +shift char: +  INT VAR local letter :: code (dummy SUB i); +  IF 97 <= local letter AND local letter <= 122 +  THEN replace (dummy, i, code (local letter - 32)) FI  . + +END PROC shift; + +TEXT PROC deshift (TEXT CONST word) : +  INT VAR i; +  dummy := word; +  FOR i FROM 1 UPTO length (word) +  REP deshift char PER; +  dummy  . + +deshift char: +  INT VAR local letter :: code (dummy SUB i); +  IF 65 <= local letter AND local letter <= 90 +  THEN replace (dummy, i, code (local letter + 32)) FI; + +END PROC deshift; + +(*                Verwaltung der Reservierten BASIC-Wörter               *) +LET first operator = 249,             (* MOD  NOT  AND   OR  XOR  EQV  IMP *) +    first bool op  = 250;             (* 249  250  251  252  253  254  255 *) + +INT VAR index; +ROW 9 TEXT VAR res words :: ROW 9 TEXT : +("", + ""129"as"163"go"167"if"188"on"217"to"252"or", + ""128"abs"130"asc"131"atn"141"cos"142"cvd"143"cvi"145"def"150"dim"152"end"153"eof"154"erl"155"err"157"exp"159"fix"160"for"161"fre"162"get"172"int"175"len"176"let"178"loc"179"log"191"out"192"pos"194"put"202"rnd"197"rem"204"sgn"205"sin"207"spc"208"sqr"214"tab"215"tan"221"val"227"cls"234"usr"235"sub"249"mod"250"not"251"and"253"xor"254"eqv"255"imp", + ""132"base"133"call"134"cdbl"136"chr$"137"cint"144"data"151"else"165"goto"166"hex$"173"kill"177"line"181"lset"182"mid$"183"mkd$"184"mki$"185"name"186"next"187"oct$"189"open"196"read"203"rset"209"step"210"stop"211"str$"213"swap"216"then"219"tron"222"wait"223"wend"228"erm$"230"lpos", + ""135"chain"138"clear"139"close"156"error"158"field"164"gosub"169"input"171"instr"174"left$"193"print"218"troff"220"using"224"while"225"width"226"write"231"time$"232"date$"233"timer", + ""140"common"146"defdbl"147"defint"148"defsng"149"defstr"168"inkey$"170"input$"180"lprint"190"option"199"resume"200"return"201"right$"206"space$"229"csrlin", + ""198"restore"212"string$", + "", + ""195"randomize"); + +BOOL PROC reserved (TEXT CONST name, INT VAR no, type): +  IF reserve is not possible COR not found within res words +  THEN FALSE +  ELSE no   := code (this words SUB (index-1)); +       type := res word or op; +       TRUE +  FI  . + +reserve is not possible: +  INT CONST len :: length (name); +  len < 2 OR len > 9  . + +not found within res words: +  index := pos (this words, name); +  index = 0  . + +this words: +  res words [len]  . + +res word or op: +  IF no >= first operator +  THEN operator +  ELSE res word FI  . + +END PROC reserved; + +INT PROC reserved (TEXT CONST name): +  IF reserve is not possible COR not found within res words +  THEN 0 +  ELSE code (this words SUB (index-1)) FI  . + +reserve is not possible: +  INT CONST len :: length (name); +  len < 2 OR len > 9  . + +not found within res words: +  index := pos (this words, name); +  index = 0  . + +this words: +  res words [len]  . + +END PROC reserved; + +TEXT PROC res word of (INT CONST no): +  INT VAR i; +  FOR i FROM 2 UPTO 9 +  REP index := pos (res words [i], code (no)); +      IF index > 0 +      THEN LEAVE res word of WITH shift (this name) FI +  PER; +  ""  . + +this name: +  subtext (res words [i], index+1, next code)  . + +next code: +  INT VAR c := pos (res words [i], ""127"", ""255"", index+1); +  IF c = 0 +  THEN length (res words [i]) +  ELSE c-1 FI  . + +END PROC res word of; + +BOOL PROC is bool op (INT CONST no):            (* mo *) +  no >= first bool op +END PROC is bool op; + +END PACKET basic types; + +PACKET basic table handling DEFINES init table, (* Autor: Heiko Indenbirken *) +                              put name,         (* Stand: 13.08.1987/rr/mo  *) +                              known, name of, +                              remember, +                              recognize, +                              table entries, +                              hash table, next table, +                              scope compulsory:          (* DEF/mo *) + +LET hash length = 1024,  +    hash length minus one = 1023, +    start of name table = 256, +    table length = 4500; +  +LET SYMBOL = STRUCT (INT type, ADDRESS adr, DTYPE data, TEXT dim); +LET TABLE = STRUCT (INT entries, +                    ROW hash length INT hash table, +                    ROW table length INT next,  +                    ROW table length TEXT name table, +                    ROW table length SYMBOL symbol table); +  +DATASPACE VAR table space; +BOUND TABLE VAR table; +INITFLAG VAR tab := FALSE; +SYMBOL CONST nilsymbol :: SYMBOL:(0, LOC 0, void type, ""); +INT VAR i; +BOOL VAR compulsory with scope :: TRUE;                     (* DEF/mo *) + +PROC init table: +  IF NOT initialized (tab) +  THEN table space := nilspace; +       table := table space; +  FI; +  table.entries := start of name table; +  FOR i FROM 1 UPTO hash length +  REP table.hash table [i] := 0 PER; +  compulsory with scope := TRUE;                            (* DEF/mo *) + +END PROC init table; + +PROC put name (TEXT CONST scope, name, INT VAR pointer):    (* DEF/mo *) +  IF compulsory with scope +    THEN put name (scope + name, pointer) +  ELIF NOT in table +    THEN put name (name, pointer) +  FI. + +in table: +  hash (scope + name, pointer); +  pointer := hash table (pointer); +  WHILE not end of chain +  REP IF name is found THEN LEAVE in table WITH TRUE FI; +      pointer := table. next (pointer); +  PER; +  FALSE . + +name is found: +  table.name table [pointer] = scope + name. +  +not end of chain: +  pointer > 0  . + +END PROC put name; + +PROC put name (TEXT CONST name, INT VAR pointer): +  IF no entry in hash table +  THEN create a new chain +  ELSE create a new entry in chain FI; +  insert name in name table  . +  +no entry in hash table: +  INT VAR hash index; +  hash (name, hash index);  +  table.hash table [hash index] = 0  . + +create a new chain: +  table.hash table [hash index] := table.entries  . +  +create a new entry in chain: +  pointer := table.hash table [hash index]; +  REP IF name is found +      THEN LEAVE put name +      ELIF end of chain +      THEN table.next [pointer] := table.entries; +           LEAVE create a new entry in chain +      ELSE pointer := next pointer FI +  PER  . +  +name is found: +  table.name table [pointer] = name. +  +end of chain: +  INT CONST next pointer := table.next [pointer]; +  next pointer = 0  . + +insert name in name table: +  IF table.entries >= table length  +  THEN errorstop ("volle Namenstabelle") FI; + +  pointer := table.entries; +  table.symbol table [pointer] := nilsymbol; +  table.name table [pointer] := name;  +  table.next [pointer] := 0;  +  table.entries INCR 1  . + +END PROC put name;  + +PROC hash (TEXT CONST name, INT VAR index) : +  INT VAR j; +  index := 0; +  FOR j FROM 1 UPTO length (name) +  REP addmult cyclic PER; +  index INCR 1  . +  +addmult cyclic : +  index INCR index ; +  IF index > hash length minus one +  THEN wrap around FI; +  index := (index + code (name SUB j)) MOD hash length minus one  . + +wrap around: +  index DECR hash length minus one  . + +ENDPROC hash ; +  +INT PROC table entries: +  table.entries +END PROC table entries; + +INT PROC hash table (INT CONST n): +  table.hash table [n] +END PROC hash table; + +INT PROC next table (INT CONST n): +  table.next [n] +END PROC next table; + +TEXT PROC name of (INT CONST index):  +  IF index < 0 +  THEN errorstop ("PROC name of: negativer Index"); "" +  ELIF index < start of name table +  THEN symbol of  (index) +  ELIF index <= table.entries +  THEN table.name table (index)  +  ELSE errorstop ("PROC name of: Index größer als nametable"); +       "" +  FI + +END PROC name of;  +  +PROC recognize (INT CONST symb, type, ADDRESS CONST adr, DTYPE CONST data, TEXT CONST dim): +  symbol.type  := type; +  symbol.adr   := adr; +  symbol.data  := data;  +  symbol.dim   := dim  . + +symbol: table.symboltable [symb]  . +END PROC recognize; + +PROC remember (INT CONST symb, INT VAR type, ADDRESS VAR adr, DTYPE VAR data, TEXT VAR dim): +  SYMBOL CONST symbol := table.symboltable [symb]; +  type  := symbol.type; +  adr   := symbol.adr; +  data  := symbol.data;  +  dim   := symbol.dim +END PROC remember; + +BOOL PROC known (INT CONST symb) : +  table.symboltable [symb].type > 0 +END PROC known; + +PROC scope compulsory (BOOL CONST new state):       (* DEF/mo *) +  compulsory with scope := new state +END PROC scope compulsory; + +END PACKET basic table handling; + +PACKET basic scanner DEFINES begin scanning,  (* Autor: Heiko Indenbirken *) +                             next symbol,     (* Stand: 27.10.1987/rr/mo  *) +                             next data, +                             next statement, +                             define chars, +                             scan line, +                             scan line no,                       (* F29/rr *) +                             get data types of input vars,       (* F25/rr *) +                             basic error, +                             basic warning, +                             basic list, +                             set scope, +                             scanner scope: + + +LET (*                    S y m b o l    T y p e n                       *) +    any     = 0,  const   = 1,  var     = 2,  array   = 3, +    res word= 8,  operator= 9,  eos     = 10, del     =11, +    stat no = 12, user fn = 20;         (* DEF/mo *) + +LET (*                    S y m b o l z e i c h e n                      *) +    less         = 60,  greater       = 62, +    less equal   = 28,  unequal       = 29,  greater equal = 30,  +    point        = 46,  eol           = 13,  eop           = 14, +    go           = 163, gosub         = 164, goto          = 165, +    sub          = 235, to            = 217; + +LET name chars    = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.0123456789!#$%", +    quote         = """",       open bracket    = "(", +    comma         = ",",        close bracket   = ")", +    colon         = ":", +    exponent chars= "dDeE"; + +FILE VAR source file; +TEXT VAR defint chars, defstr chars, record, letter, +         scope, new name;     (* DEF/mo *) +REAL VAR r dummy; +INT VAR act stat no, record no, rec len, scan pos, i dummy; +BOOL VAR eol generated, at line begin, listing := FALSE; + +PROC define chars (TEXT CONST begin, end, DTYPE CONST data): +  INT VAR i; +  FOR i FROM code (begin) UPTO code (end) +  REP IF data = int type +        THEN defint chars CAT code (i)  +      ELIF data = text type +        THEN defstr chars CAT code (i)  +      FI +  PER  . + +END PROC define chars; + + +PROC scanline (TEXT VAR line, INT VAR col): +  line := record; +  col  := scan pos +END PROC scanline; + +INT PROC scan line no : record no END PROC scan line no; + + +PROC get data types of input vars (ROW 100 DTYPE VAR input var data, (* F25/rr *) +                                   INT VAR number input vars) : + +  TEXT VAR first var char; +  INT VAR var pos := scan pos; +  to begin of actual var; +  REP get next input var; +      skip brackets if necessary; +      IF var char <> comma THEN LEAVE get data types of input vars FI; +      skip comma; +  PER; +  +  . var char : record SUB var pos + +  . to begin of actual var : +      WHILE pos (name chars, var char) <> 0 REP var pos DECR 1 PER; +      var pos         INCR 1; +      number input vars := 0; +  +  . get next input var : +      first var char := deshift (var char); +      WHILE pos (name chars, var char) <> 0 REP var pos INCR 1 PER; +      var pos           DECR 1; +      number input vars INCR 1; +      input var data (number input vars) := var datatype (first var char, var char); +      var pos := pos (record, ""33"", ""255"", var pos + 1); + +  . skip brackets if necessary : +      IF var char =  open bracket +         THEN INT VAR bracket counter := 1; +              REP count bracket UNTIL bracket counter = 0 PER; +              var pos := pos (record, ""33"", ""255"", var pos + 1); +      FI; + +      . count bracket : +          INT CONST open  := pos (record, open  bracket, var pos + 1), +                    close := pos (record, close bracket, var pos + 1); +          IF open > 0 +             THEN IF close > 0 +                     THEN IF open > close +                             THEN close bracket found +                             ELSE open  bracket found +                          FI; +                     ELSE open bracket found +                  FI; +             ELSE IF close > 0 +                     THEN close bracket found +                     ELSE LEAVE get data types of input vars  +                  FI; +          FI; + +          . open bracket found : +               bracket counter INCR 1; +               var pos := open; + +          . close bracket found : +               bracket counter DECR 1; +               var pos := close; + +  . skip comma : +      var pos := pos (record, ""33"", ""255"", var pos + 1); + +END PROC get data types of input vars; + + +PROC begin scanning (FILE VAR basic file): +  enable stop; +  source file := basic file; +  to first record (source file); +  col (source file, 1); +  IF eof (source file)  +  THEN errorstop ("Datei ist leer") FI;  + +  defint chars := ""; +  defstr chars := "";  +  scope := "";                              (* DEF/mo *) +  act stat no := 0; +  read record (source file, record);  +  rec len := length (record); +  scan pos := 0;  +  record no := 1; +  eol generated := FALSE; +  at line begin := TRUE; +  IF listing +    THEN line; +         putline (record); +         IF sysout <> "" +           THEN cout (record no) +         FI +    ELSE cout (record no) +  FI. + +END PROC begin scanning; +  +PROC next statement: +  IF eof (source file) +  THEN errorstop (99, "") +  ELSE eol generated := FALSE; +       at line begin := TRUE; +       down (source file); +       read record (source file, record);  +       rec len := length (record); +       scan pos := 0;  +       record no INCR 1; +  FI; +  IF listing +    THEN putline (record); +         IF sysout <> "" +           THEN cout (record no) +         FI +    ELSE cout (record no) +  FI. +   +END PROC next statement; + +PROC next symbol (TEXT VAR name, INT VAR no, type, DTYPE VAR data): +  enable stop; +  clear symbol; +  IF eol generated +  THEN next statement FI; + +  IF eol reached +  THEN generate eol +  ELIF at line begin CAND stat no found                          (* F15/rr *) +  THEN generate stat no +  ELSE generate chars FI  . + +clear symbol: +  name := ""; +  no   := 0; +  type := any; +  data := void type  . +  +eol reached: +  scan pos := pos (record, ""33"", ""255"", scan pos+1);  +  scan pos = 0  . + +generate eol : +  IF eof (source file) +  THEN name := "EOF";  no := eop;  type := eos +  ELSE name := "EOL";  no := eol;  type := eos FI; +  eol generated := TRUE  . + +stat no found:                                                   (* F15/rr *) +  at line begin := FALSE; +  pos ("0123456789", act char) <> 0 . +  +generate stat no:                                                (* F15/rr *) +  INT CONST next scan pos := last number pos; +  name        := subtext (record, scan pos, next scan pos); +  act stat no := int (name); +  scan pos    := next scan pos; +  no := act stat no;  type := stat no  . + +last number pos :                                                (* F15/rr *) +  INT CONST high := pos (record, ""058"", ""255"", scan pos), +            low  := pos (record, ""032"", ""047"", scan pos); +  IF   high > 0 +       THEN IF low > 0 +               THEN min (high, low) - 1 +               ELSE high - 1 +            FI +  ELIF low > 0 +       THEN low - 1 +       ELSE LENGTH record +  FI . + +generate chars: +  SELECT code (act char) OF +  CASE 32: next symbol (name, no, type, data)            (* Space        *)  +  CASE 34: generate text denoter                         (* "            *)  +  CASE 39: generate eol                                  (* '            *) +  CASE 42, 43, 45, 47, 92, 94, 61: generate operator     (* *,+,-,/,\,^,=*) +  CASE 60: generate less op                              (*<, <=, <>     *)  +  CASE 62: generate greater op                           (*>, >=         *) +  CASE 46: treat point                                   (* .            *) +  CASE 48, 49, 50, 51, 52, 53, 54, 55, 56, 57:  +           generate numeric const                        (* 0  -  9      *) +  CASE 58: generate eos                                  (* :            *) +  CASE 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, +       82, 83, 84, 85, 86, 87, 88, 89, 90,  97, 98, 99, 100, 101, 102, 103, +       104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, +       118, 119, 120, 121, 122,               (* small and large letters *) +       generate res word or id +  OTHERWISE generate delimiter END SELECT  . + +generate text denoter: +  get text const (name, data); +  type := const  . + +generate operator: +  name := act char;  no := code (name);  type := operator  . + +generate less op: +  IF next char = "=" +  THEN name := "<=";  no := less equal; skip char +  ELIF next char = ">" +  THEN name := "<>";  no := unequal;    skip char +  ELSE name := "<";  no := less FI; +  type := operator  . + +generate greater op: +  IF next char = "=" +  THEN name := ">=";  no := greater equal;  skip char  +  ELSE name := ">";  no := greater;  FI; +  type := operator  . + +treat point: +  IF pos ("0123456789", next char) <> 0 +    THEN generate numeric const +    ELSE name := "."; +         no := point; +         type := del +  FI. + +generate numeric const: +  get numeric const (name, data); +  type := const  . + +last name char: +  name SUB LENGTH name  . + +generate eos: +  name := ":";  no := eos;  type := eos  . + +generate res word or id: +  get name chars; +  IF reserved (deshift name, no, type) +    THEN IF type = res word AND no = go +           THEN treat go +         FI +    ELSE IF function name +           THEN data := ftn datatype; +                type := user fn +           ELSE data := var datatype (deshift (name) SUB 1, last name char); +                type := var or array +         FI; +         put name (scope, deshift name, no) +  FI. + +treat go: +  next symbol (new name, no, type, data); +  IF no = to AND type = res word +    THEN name CAT new name; +         no := goto +  ELIF no = sub AND type = res word +    THEN name CAT new name; +         no := gosub +    ELSE scan error (102, name, "") +  FI. + +get name chars: +  TEXT VAR deshift name :: ""; +  INT VAR begin of name :: scan pos; +  FOR scan pos FROM scan pos UPTO rec len +  WHILE name chars found +  REP deshift name CAT deshifted char PER; +  scan pos DECR 1; +  name := subtext (record, begin of name, scan pos). + +name chars found: +  pos (name chars, act char) > 0  . + +function name: +  subtext (deshift name, 1, 2) = "fn"  . + +ftn datatype: +  IF last name char = "$" +  THEN text type +  ELIF last name char = "%" +  THEN int type +  ELSE real type FI  . + +var or array: +  IF array name +  THEN name CAT "()"; +       deshift name CAT "()";                                (* F30/rr *) +       array +  ELSE var FI  . + +array name: +  next scan char = "("  . + +deshifted char: +  letter := act char; +  IF letter >= "A" AND letter <= "Z" +  THEN code (code (letter) + 32) +  ELSE letter FI  . + +generate delimiter: +  name := act char;  no := code (name);  type := del  . + +next scan char: record SUB pos (record, ""33"", ""255"", scan pos+1).  +next char: (record SUB scan pos + 1)  . +act char: record SUB scan pos  . +skip char:  scan pos INCR 1  . +END PROC next symbol; + +DTYPE PROC var datatype (TEXT CONST first name char, last name char) : + +  IF last name char = "!" OR last name char = "#" +  THEN real type +  ELIF last name char = "$" +  THEN text type +  ELIF last name char = "%" +  THEN int type +  ELIF pos (defint chars, first name char) > 0 +  THEN int type +  ELIF pos (defstr chars, first name char) > 0 +  THEN text type +  ELSE real type FI  . + +END PROC var datatype; + +BOOL PROC next data (TEXT VAR data text, DTYPE VAR data type) :  (* F17/rr *) + +  data type := void type; +  IF   no more data +       THEN scan pos  := rec len; +            data text := ""; +            FALSE +  ELIF quoted string +       THEN get quoted string; +            TRUE +       ELSE get unquoted string; +            TRUE +  FI + +  . no more data : +      scan pos := pos (record, ""33"", ""255"", scan pos+1); +      scan pos = 0 + +  . quoted string : +      (record SUB scan pos) = quote + +  . get quoted string : +      get text const (data text, data type); + +  . get unquoted string : +      INT CONST comma or colon pos 1 := position of comma or colon minus one; +      data text := compress (subtext (record, scan pos, comma or colon pos 1)); +      scan pos  := comma or colon pos 1; + +  . position of comma or colon minus one : +      INT CONST colon pos := pos (record, colon, scan pos), +                comma pos := pos (record, comma, scan pos); +      IF colon pos > 0 +         THEN IF comma pos > 0 +                 THEN min (colon pos, comma pos) - 1 +                 ELSE colon pos - 1 +              FI +         ELSE IF comma pos > 0 +                 THEN comma pos - 1 +                 ELSE LENGTH record +              FI +      FI + +END PROC next data; + +PROC get numeric const (TEXT VAR value, DTYPE VAR data): +  get sign; +  get const; +  check datatype  . + +get sign: +  IF act char = "-" +  THEN value := "-"; +       scan pos INCR 1 +  ELIF act char = "+" +  THEN value := "+"; +       scan pos INCR 1 +  ELSE value := "" FI  . + +get const: +  get digits; +  get point; +  get digits; +  get exponent  . + +get digits: +  FOR scan pos FROM scan pos UPTO rec len +  WHILE digit found +  REP value CAT act char PER  . + +get point: +  IF act char = "." +  THEN value CAT "."; +       scan pos INCR 1 +  ELIF pos (exponent chars, act char) > 0 +  THEN value CAT ".0" +  ELSE LEAVE get const FI  . + +get exponent: +  IF pos (exponent chars, act char) > 0                 (* F1/rr *) +  THEN value CAT "e"; +       scan pos INCR 1; +       evtl get sign; +       get digits +  FI  . + +evtl get sign: +  IF act char = "+" OR act char = "-" +  THEN value CAT act char; +       scan pos INCR 1 +  FI  . + +digit found: +  "0" <= act char AND act char <= "9"  . + +check datatype: +  IF act char = "%"  +  THEN IF integer ok (value) +       THEN data := int type +       ELSE scan error (2, value, "INT-Konstante nicht korrekt") FI +  ELIF act char = "!" OR act char = "#" +  THEN IF real ok (value) +       THEN data := real type +       ELSE scan error (2, value, "REAL-Konstante nicht korrekt") FI +  ELIF integer ok (value) +  THEN scan pos DECR 1;  data := int type +  ELIF real ok (value) +  THEN scan pos DECR 1; +       data := real type +  ELSE scan error (2, value, "Numerische Konstante nicht korrekt") FI  .  + +act char: record SUB scan pos  . +END PROC get numeric const; +  +PROC get text const (TEXT VAR value, DTYPE VAR data): +  INT CONST quote 1 := scan pos; +  scan pos := pos (record, """", scan pos+1); +  IF quote 1 < scan pos +  THEN value := subtext (record, quote 1+1, scan pos-1); +       data := text type +  ELSE scan error (15, subtext (record, quote 1), "("" fehlt)") FI  . + +END PROC get text const; + +BOOL PROC integer ok (TEXT VAR zahl): +  disable stop; +  i dummy := int (zahl); +  IF is error +  THEN clear error; +       FALSE +  ELIF last conversion ok +  THEN zahl := ""0""0""; +       replace (zahl, 1, i dummy); +       TRUE +  ELSE FALSE FI  . + +END PROC integer ok; + +BOOL PROC real ok (TEXT VAR zahl): +  disable stop; +  r dummy := real (zahl); +  IF is error +  THEN clear error; +       FALSE +  ELIF last conversion ok +  THEN zahl := ""0""0""0""0""0""0""0""0""; +       replace (zahl, 1, r dummy); +       TRUE +  ELSE FALSE FI  . + +END PROC real ok; + +PROC basic error (INT CONST no, TEXT CONST name, addition): +  basic error ("Compiler", no, record no, act stat no, name, addition, TRUE) +END PROC basic error; + +PROC basic error (INT CONST no, TEXT CONST name, addition, BOOL CONST leave statement): +  basic error ("Compiler", no, record no, act stat no, name, addition, leave statement) +END PROC basic error; + +PROC scan error (INT CONST no, TEXT CONST name, addition): +  basic error ("Scanner", no, record no, act stat no, name, addition, TRUE) +END PROC scan error; + +PROC basic warning (TEXT CONST warning text):               (* mo *) +  basic warning (record no, act stat no, warning text) +END PROC basic warning; + +PROC basic list (BOOL CONST t): +  listing := t  +END PROC basic list; + +BOOL PROC basic list: +  listing +END PROC basic list; + +PROC set scope (TEXT CONST new scope):                          (* DEF/mo *) +  scope := new scope +END PROC set scope; + +TEXT PROC scanner scope:                                        (* DEF/mo *) +  scope +END PROC scanner scope; + +END PACKET basic scanner; + + +PACKET basic stat no DEFINES init stat no,    (* Autor: Heiko Indenbirken *) +                             stat no pos,     (* Stand: 27.10.1987/rr/mo  *) +                             label pos, +                             all stat no: + +LET nil = ""; + +TEXT VAR found stat no :: nil; +INT VAR i, akt stat no :: 0, found no :: 0; + +PROC init stat no (FILE VAR f, INT VAR error no):                (* F21/rr *) +(*Die Datei 'f' muß im 'modify-Mode' sein.                               *) +  INT VAR line no; +  akt stat no := -1;                                             (* F28/rr *) +  found no := 0; +  found stat no := nil; +  error no := 0;                                                 (* F21/rr *) +  to first record (f); +  col (f, 1); +  disable stop; +  FOR line no FROM 1 UPTO 4000 +  REP exec (PROC (TEXT CONST, INT CONST) check, f, line no); +      IF is error THEN check error FI; +      IF eof (f) +      THEN LEAVE init stat no +      ELSE down (f) FI +  PER; + +. check error :                                                  (* F21/rr *) +    IF error code = 100 +       THEN clear error; +            error no INCR 1; +       ELSE LEAVE init stat no; +    FI; + +END PROC init stat no; + +PROC check (TEXT CONST record, INT CONST line no): +  IF statement no vorhanden +  THEN remember statement no FI  . + +statement no vorhanden:                                          (* F15/rr *) +   INT CONST first number pos := pos (record, ""048"", ""057"", 1); +   first number pos > 0 CAND first number pos = first non blank pos . + +first non blank pos :                                            (* F15/rr *) +   pos (record, ""033"", ""255"", 1) . + +remember statement no: +  get statement no; +  IF neue nummer ist groesser als vorherige +  THEN akt stat no := neue nummer; +       cout (neue nummer); +       found no INCR 1; +       found stat no CAT mki (neue nummer) +  ELSE basic error ("Stat no", 81, line no, neue nummer, number, +                    "Letzte Zeilennummer davor: " + text (akt stat no), TRUE) +  FI  . + +get statement no :                                               (* F15/rr *) +  disable stop; +  TEXT CONST number := subtext (record, first number pos, last number pos); +  INT VAR neue nummer := int (number); +  IF NOT last conversion ok OR is error +  THEN clear error; +       basic error ("Stat no", 80, line no, akt stat no, number, +                    "Die Zeilennummer muß im Bereich 0-32767 liegen", TRUE) +  FI; +  enable stop . + +last number pos :                                                (* F15/rr *) +  INT CONST high := pos (record, ""058"", ""255"", first number pos), +            low  := pos (record, ""032"", ""047"", first number pos); +  IF   high > 0 +       THEN IF low > 0 +               THEN min (high, low) - 1 +               ELSE high - 1 +            FI +  ELIF low > 0 +       THEN low - 1 +       ELSE LENGTH record +  FI . + +neue nummer ist groesser als vorherige: +  neue nummer > akt stat no  . + +END PROC check; + +INT PROC stat no pos (INT CONST stat no): +  FOR i FROM found no DOWNTO 1 +  REP IF (found stat no ISUB i) = stat no +      THEN LEAVE stat no pos WITH i FI +  PER; +  0 +END PROC stat no pos; + +INT PROC label pos (INT CONST stat no): +  FOR i FROM found no DOWNTO 1 +  REP IF (found stat no ISUB i) = stat no +      THEN LEAVE label pos WITH i FI +  PER; +  basic error (8, text (stat no), nil);                         (* F16/rr *) +  0 +END PROC label pos; + +PROC all stat no (TEXT VAR stat no, INT VAR no): +  stat no := found stat no; +  no      := found no +END PROC all stat no; + +END PACKET basic stat no; + +PACKET basic storage DEFINES init storage,     (* Autor: Heiko Indenbirken *) +                             next local adr,   (* Stand: 12.06.86          *) +                             next ref, +                             local adr, +                             local storage, +                             type size, +                             quiet type:          +                                               +                                               + +LET ref length = 2; + +INT VAR quiet size, quiet align; +ADDRESS VAR loc adr, free loc adr; +DTYPE VAR quiet value; +identify ("QUIET", quiet size, quiet align, quiet value); + +PROC init storage: +  free loc adr := LOC 0; +  loc adr      := LOC 0; + +END PROC init storage; + +(*        Verwaltung der lokalen Addressen für Zwischenergebnisse        *) +ADDRESS PROC next local adr (DTYPE CONST type): +  INT VAR type len :: type size (type); +  loc adr := free loc adr; +  adjust (loc adr, type len); +  free loc adr := loc adr + type len; +  loc adr  . + +END PROC next local adr; + +ADDRESS PROC next ref: +  loc adr := free loc adr; +  adjust (loc adr, ref length); +  free loc adr := loc adr + ref length; +  loc adr  . + +END PROC next ref; + +ADDRESS PROC local adr: +   loc adr +END PROC local adr; + +INT PROC local storage: +  int (subtext (dump (free loc adr), 6)) +END PROC local storage; + +INT PROC type size (DTYPE CONST type): +   IF type = int type OR type = bool type +   THEN 1 +   ELIF type = row type +   THEN 2 +   ELIF type = real type +   THEN 4 +   ELIF type = text type +   THEN 8 +   ELIF type = quiet value +   THEN quiet size +   ELSE errorstop ("Unbekannter DTYPE: " + dump (type));  0 FI  . + +END PROC type size; + +DTYPE PROC quiet type: +  quiet value +END PROC quiet type; + +END PACKET basic storage; + +PACKET basic identify DEFINES                 (* Autor: Heiko Indenbirken *) +                                              (* Stand: 20.08.1987/rr/mo  *) +                           identify, +                           convert paramfield, +                           dump ftn, +                           is basic function:            (* mo *) + +LET nil = ""; + +LET ENTRY = STRUCT (TEXT param, INT no, next, OPN opn, DTYPE result); + +ROW 256 ENTRY VAR ftn table; + +clear ftn table; +init ftn names; +init int operator; +init real operator; +init text operator; +init predefined funktions; + +PROC dump ftn (INT CONST n, TEXT VAR param, INT VAR no, next, +               OPN VAR opn, DTYPE VAR result): + param  := ftn table [n].param; + no     := ftn table [n].no; + next   := ftn table [n].next; + opn    := ftn table [n].opn; + result := ftn table [n].result + +END PROC dump ftn; + +PROC identify (INT CONST ftn no, first, params, OPN VAR operation, BOOL VAR found): +  TEXT VAR param; +  INT VAR pos :: min (ftn no, 256); +  convert paramfield (first, params, param); +  REP IF param = ftn table [pos].param  AND ftn no = ftn table [pos].no +      THEN declare (params+1, ftn table [pos].result); +           declare (params+1, 1); +           operation := ftn table [pos].opn; +           found     := TRUE; +           LEAVE identify +      ELSE pos := ftn table [pos].next FI +  UNTIL pos <= 0 PER;                                           (* F14/rr *) +  operation := nop; +  found     := FALSE  . + +END PROC identify; + +PROC next free entry (INT VAR free pos): +  FOR free pos FROM 1 UPTO 256 +  REP IF ftn table [free pos].next < 0 AND ftn table [free pos].no = 0  (* mo *) +    THEN LEAVE next free entry FI +  PER; +  errorstop ("Überlauf der Funktionstabelle")  . + +END PROC next free entry; + +PROC convert paramfield (INT CONST first, params, TEXT VAR param): +  INT VAR i; +  param := nil; +  FOR i FROM first UPTO params +  REP param CAT datatype PER  . + +datatype: +  DTYPE CONST data :: dtype (i); +  IF data = int type +  THEN "I" +  ELIF data = real type +  THEN "R" +  ELIF data = text type +  THEN "T" +  ELIF data = bool type +  THEN "b" +  ELSE errorstop ("Falscher DTYPE: " + dump (data)); +       nil +  FI  . + +END PROC convert paramfield; + +PROC convert paramfield (TEXT CONST params, INT CONST first): +  INT VAR i; +  FOR i FROM first UPTO first+length (params)-1 +  REP parameter (i, this type, 1, GLOB 0) PER  . + +this type: +  IF (params SUB i) = "I" +  THEN int type +  ELIF (params SUB i) = "R" +  THEN real type +  ELIF (params SUB i) = "T" +  THEN text type +  ELSE errorstop ("Unbekannter Typ: " + params); +       undefined type +  FI  . + +END PROC convert paramfield; + +PROC init op (INT CONST ftn no, TEXT CONST param, ftn name): +  IF elan opn found +  THEN insert new opn in chain +  ELSE errorstop ("PROC " + ftn name + " (" + param + ") nicht gefunden") FI  . + +elan opn found: +  OPN VAR opn; +  BOOL VAR found; +  convert paramfield (param, 1); +  identify (ftn name, 1, length (param), opn, found); +  found  . + +insert new opn in chain: +  INT VAR ftn pos :: ftn no; +  REP IF end of chain found +      THEN cat new entry in chain +      ELIF free entry in chain found +      THEN cover this entry +      ELSE next entry FI +  UNTIL ftn pos <= 0 PER  . + +end of chain found: +  act entry.next = 0  . + +cat new entry in chain: +  INT VAR free pos; +  next free entry (free pos); +  act entry.next := free pos; +  free entry := ENTRY:(param, ftn no, 0, opn, dtype (LENGTH param+1)); +  LEAVE insert new opn in chain  . + +free entry in chain found: +  act entry.next = -1 . + +cover this entry: +  act entry := ENTRY:(param, ftn no, 0, opn, dtype (LENGTH param+1)); +  LEAVE insert new opn in chain  . + +next entry: +  ftn pos := act entry.next  . + +act entry: ftn table [ftn pos]  . +free entry: ftn table [free pos]  . + +END PROC init op; + +BOOL PROC is basic function (INT CONST ftn no):         (* mo *) + +  pos (ftn names, code (ftn no)) <> 0 + +END PROC is basic function; + +. +clear ftn table: +  INT VAR k; +  FOR k FROM 1 UPTO 256 +  REP ftn table [k] := ENTRY:(nil, 0,-1, nop, undefined type) PER  . + +init ftn names: +  TEXT CONST ftn names :: "+-*/\^<=>"28""29""30""249""251""252""253""254"" + +                          ""128""130""131""134""136""137""141""143""142"" + +                          ""153""154""155""157""159""161""166""168""170""171""172"" + +                          ""174""175""178""179""182""184""183""187""192"" + +                          ""201""202""204""205""206""207""208""211""212"" + +                          ""215""221""228""229""230""231""232""233""; +  FOR k FROM 1 UPTO length (ftn names) +  REP ftn table [ftn pos] := ENTRY:(nil, ftn pos,-1, nop, void type) PER  . + +ftn pos: +  code (ftn names SUB k)  . + +init int operator: +  init op ( 43, "II", "+"); +  init op ( 45, "II", "-"); +  init op ( 42, "II", "*"); +  init op ( 47, "II", "/");                 (* mo *) +  init op ( 92, "II", "DIV");               (* mo *) +  init op ( 94, "II", "^"); +  init op ( 61, "II", "EQU"); +  init op ( 29, "II", "UEQ"); +  init op ( 60, "II", "LES"); +  init op ( 28, "II", "LEQ"); +  init op ( 62, "II", "GRE"); +  init op ( 30, "II", "GEQ"); +  init op (249, "II", "MOD");               (* mo *) +  init op (251, "II", "AND"); +  init op (252, "II", "OR"); +  init op (253, "II", "XOR"); +  init op (254, "II", "EQV"); +  init op (255, "II", "IMP"). + +init real operator: +  init op ( 43, "RR", "+"); +  init op ( 45, "RR", "-"); +  init op ( 42, "RR", "*"); +  init op ( 47, "RR", "/"); +  init op ( 92, "RR", "DIV");              (* mo *) +  init op ( 94, "RR", "^"); +  init op ( 61, "RR", "EQU"); +  init op ( 29, "RR", "UEQ"); +  init op ( 60, "RR", "LES"); +  init op ( 28, "RR", "LEQ"); +  init op ( 62, "RR", "GRE"); +  init op ( 30, "RR", "GEQ"); +  init op (249, "RR", "realmod").          (* mo *) + +init text operator: +  init op ( 43, "TT", "+"); +  init op ( 61, "TT", "EQU"); +  init op ( 29, "TT", "UEQ"); +  init op ( 60, "TT", "LES"); +  init op ( 28, "TT", "LEQ"); +  init op ( 62, "TT", "GRE"); +  init op ( 30, "TT", "GEQ")  . + +init predefined funktions: +  init op (128, "I", "abs"); +  init op (128, "R", "abs"); +  init op (130, "T", "asc"); +  init op (131, "R", "arctan"); +  init op (131, "I", "arctan"); +  init op (134, "I", "cdbl"); +  init op (134, "R", "cdbl"); +  init op (136, "I", "chr"); +  init op (136, "R", "chr"); +  init op (137, "R", "cint"); +  init op (137, "I", "cint"); +  init op (141, "R", "cos"); +  init op (141, "I", "cos"); +  init op (143, "T", "cvi"); +  init op (142, "T", "cvd"); +# init op (153, "", "eof");#                                     (* File *) +  init op (154, "", "errorline"); +  init op (155, "", "errorcode"); +  init op (157, "R", "exp"); +  init op (157, "I", "exp"); +  init op (159, "R", "floor"); +  init op (159, "I", "floor"); +  init op (161, "I", "fre"); +  init op (161, "R", "fre"); +  init op (161, "T", "fre"); +  init op (166, "I", "hex"); +  init op (166, "R", "hex"); +  init op (168, "", "incharety"); +  init op (170, "I", "inchars"); +  init op (170, "R", "inchars"); +  init op (171, "TT", "instr"); +  init op (171, "ITT", "instr"); +  init op (171, "RTT", "instr"); +  init op (172, "I", "ent"); +  init op (172, "R", "ent"); +  init op (174, "TI", "left"); +  init op (174, "TR", "left"); +  init op (175, "T", "length"); +# init op (178, "I", "line no");#                                (* File *) +  init op (179, "R", "ln"); +  init op (179, "I", "ln"); +  init op (182, "TII", "mid"); +  init op (182, "TI", "mid"); +  init op (182, "TRR", "mid"); +  init op (182, "TR", "mid"); +  init op (183, "I", "mkd"); +  init op (183, "R", "mkd"); +  init op (187, "I", "oct"); +  init op (187, "R", "oct"); +  init op (192, "I", "pos"); +  init op (192, "R", "pos"); +  init op (201, "TI", "right"); +  init op (201, "TR", "right"); +  init op (202, "", "rnd");                                      (* F12/rr *) +  init op (202, "I", "rnd"); +  init op (202, "R", "rnd"); +  init op (204, "I", "sign"); +  init op (204, "R", "sign"); +  init op (205, "R", "sin"); +  init op (205, "I", "sin"); +  init op (206, "I", "space"); +  init op (206, "R", "space"); +  init op (207, "I", "space"); +  init op (207, "R", "space"); +  init op (208, "R", "sqrt"); +  init op (208, "I", "sqrt"); +  init op (211, "I", "basictext"); +  init op (211, "R", "basictext"); +  init op (212, "IT", "string"); +  init op (212, "RT", "string"); +  init op (212, "II", "string"); +  init op (212, "RR", "string"); +  init op (212, "RI", "string"); +  init op (212, "IR", "string"); +  init op (215, "R", "tan"); +  init op (215, "I", "tan"); +  init op (221, "T", "val");                                      (* F18/rr *) +  init op (228, "", "errormessage"); +  init op (229, "", "csrlin"); +  init op (230, "I", "lpos"); +  init op (230, "R", "lpos"); +  init op (231, "", "time"); +  init op (232, "", "date"); +  init op (233, "", "timer"). + +END PACKET basic identify; + +PACKET basic data handling                          (* Autor: R. Ruland   *) +                                                    (* Stand: 23.10.87/mo *) +       DEFINES init data,        +               data line,        +               data, read, +               restore, +               next int, +               next real, +               next text:        + +LET (*                     R e s u l t    T y p e n                      *)  +    stat code = 0,   stat char = ""0"", +    data code = 1,   data char = ""1"", +    text code = 2,   text char = ""2"", + +    int  overflow  =  4, +    real overflow  =  6; + +INT VAR type; +TEXT VAR data text :: "", number text; + +PROC init data: + +   data text := "" + +END PROC init data; + + +PROC init data (TEXT VAR data, INT VAR data pos): + +  data      := data text; +  data pos  := 1 + +END PROC init data; + + +PROC restore (TEXT CONST data, INT VAR data pos, INT CONST line no): + +  INT CONST data length :: LENGTH data; +  data pos := 1; +  WHILE data pos < data length +  REP type := code (data SUB data pos); +      data pos INCR 1; +      SELECT type OF +         CASE stat code            : IF int value (data, data pos) >= line no +                                        THEN LEAVE restore FI +         CASE data code, text code : data pos INCR int value (data, data pos) +         OTHERWISE : errorstop (1051, "Fehlerhaften Dateneintrag gefunden: " + text (type)) +      ENDSELECT; +  PER; +  errorstop (1004, "RESTORE: Keine DATA-Anweisung in oder nach Zeile " + text (line no) +                     + " gefunden"); + +END PROC restore; + +  +INT PROC next int (TEXT CONST data, INT VAR data pos): + +   number text := next text (data, data pos); +   disable stop; +   INT VAR result := int (number text); +   IF   is error +        THEN IF error code = int overflow THEN handle overflow FI; +   ELIF NOT last conversion ok CAND number text <> ""  +        THEN errorstop (1013, "READ: Falscher Datentyp, " + number text + " ist kein INT") +   FI; +   result + +   . handle overflow : +       clear error; +       result := result value; +       IF cursor x pos <> 1 THEN next line FI; +       basic out ("WARNUNG : INT-Überlauf bei READ, gefunden: " + number text); +       next line; + +       . result value : +           IF (number text SUB 1) = "-" THEN minint ELSE maxint FI + +END PROC next int; + +  +REAL PROC next real (TEXT CONST data, INT VAR data pos): + +   number text := next text (data, data pos); +   disable stop; +   REAL VAR result := val (number text); +   IF   is error +        THEN IF error code = real overflow OR error code = int overflow  (* <- wegen Fehler in REAL PROC real (T C) *) +                THEN handle overflow or underflow +             FI; +   ELIF NOT last conversion ok CAND number text <> ""  +        THEN errorstop (1013, "READ: Falscher Datentyp, " + number text + " ist kein REAL") +   FI; +   result + +   . handle overflow or underflow :                          (* F23/rr *)  +       clear error; +       IF cursor x pos <> 1 THEN next line FI; +       basic out ("WARNUNG : " + overflow or underflow + " bei READ, gefunden: " + number text); +       next line; + +   . overflow or underflow : +       IF is overflow                             +          THEN result := sign * (max real - 0.99999999999994e120); (* <- wegen Fehler in TEXT PROC text (R C) *) +               "REAL-Überlauf" +          ELSE result := 0.0; +               "REAL-Unterlauf" +       FI + +       . sign : +           IF (number text SUB 1) = "-" THEN -1.0 ELSE 1.0 FI + +       . is overflow : +           INT VAR exponent pos := pos (number text, "E");  +           IF exponent pos = 0 THEN exponent pos := pos (number text, "e") FI; +           IF exponent pos = 0 +              THEN TRUE +              ELSE (number text SUB (exponent pos + 1)) <> "-" +           FI + +END PROC next real; + + +TEXT PROC next text (TEXT CONST data, INT VAR data pos): + +   INT CONST len :: int value (data, data pos); +   data pos INCR len; +   subtext (data, data pos-len, data pos-1) + +END PROC next text; + + +INT PROC int value (TEXT CONST data, INT VAR data pos): + +   data pos INCR 2; +   subtext (data, data pos-2, data pos-1) ISUB 1 + +END PROC int value; +  + +PROC data line (INT CONST line no): + +  data text CAT stat char; +  data text CAT mki (line no) + +END PROC data line; + + +PROC data (TEXT CONST string, DTYPE VAR data type) : + +  data text CAT data + mki (length (string)); +  data text CAT string; + +  . data : +      IF   data type = void type +           THEN data char +      ELIF data type = text type +           THEN text char +           ELSE errorstop (1051, "Unbekannter DTYPE: " + dump (data type)); "" +      FI + +END PROC data; + + +PROC read (TEXT CONST data, INT VAR data pos, INT VAR i): + +  type := code (data SUB data pos); +  data pos INCR 1; +  IF   data pos >= LENGTH data +       THEN errorstop (1004, "Keine Daten mehr für READ") +  ELIF type = data code +       THEN i := next int (data, data pos) +  ELIF type = stat code +       THEN data pos INCR 2; +            read (data, data pos, i) +       ELSE errorstop (1013, "READ: Falscher Datentyp, " + data string (data,data pos) + " ist kein INT") +  FI; + +END PROC read; + + +PROC read (TEXT CONST data, INT VAR data pos, REAL VAR r): + +  type := code (data SUB data pos); +  data pos INCR 1; +  IF   data pos >= LENGTH data +       THEN errorstop (1004, "Keine Daten mehr für READ") +  ELIF type = data code +       THEN r := next real (data, data pos) +  ELIF type = stat code +       THEN data pos INCR 2; +            read (data, data pos, r) +       ELSE errorstop (1013, "READ: Falscher Datentyp, " + data string (data,data pos) + " ist kein REAL") +  FI; + +END PROC read; + + +PROC read (TEXT CONST data, INT VAR data pos, TEXT VAR t): + +  type := code (data SUB data pos); +  data pos INCR 1; +  IF   data pos >= LENGTH data +       THEN errorstop (1004, "Keine Daten mehr für READ") +  ELIF type = data code OR type = text code +       THEN t := next text (data, data pos) +  ELIF type = stat code +       THEN data pos INCR 2; +            read (data, data pos, t) +       ELSE errorstop (1013, "READ: Falscher Datentyp, " + data string (data,data pos) + " ist kein TEXT") +  FI; + +END PROC read; +  + +TEXT PROC data string (TEXT CONST data, INT VAR data pos): + +  IF type = text code +     THEN """" + next text (data, data pos) + """" +     ELSE "unbekannter DTYPE: " + text (type) +  FI + +END PROC data string; + +END PACKET basic data handling; + + +PACKET basic odds and ends DEFINES trace,       (* Autor: Heiko Indenbirken *) +                                   start basic, (* Stand: 26.10.1987/rr/mo  *) +                                   end basic, +                                   loop end, +                                   basic stop: + +(*                            Fehlerbehandlung                           *) + +PROC trace (INT CONST stat no): +  basic out ("[" + text (stat no) + "]") + +END PROC trace; + +(*Laufzeitprozeduren                                                     *) +PROC start basic: +  set line nr (0); +  initialize random (0.1);                                   (* F26/rr *) +  init output; +  init input + +END PROC start basic; + +PROC end basic: +  IF is error +    THEN switch back to old sysout state +  FI  . + +END PROC end basic;  + +(*                          Schleifenüberprüfung                         *) +BOOL PROC loop end (REAL CONST x, max, step) : +  IF step > 0.0 +  THEN x > max +  ELSE x < max FI + +END PROC loop end; + +BOOL PROC loop end (INT CONST x, max, step) : +  IF step > 0 +  THEN x > max +  ELSE x < max FI + +END PROC loop end; + +PROC basic stop (INT CONST stat no): +  basic out ("STOP beendet das Programm in Zeile " + text (stat no)); +  next line + +END PROC basic stop; + +END PACKET basic odds and ends + diff --git a/lang/basic/1.8.7/src/BASIC.Compiler b/lang/basic/1.8.7/src/BASIC.Compiler new file mode 100644 index 0000000..d4e4c21 --- /dev/null +++ b/lang/basic/1.8.7/src/BASIC.Compiler @@ -0,0 +1,2305 @@ +(***************************************************************************) +(*                                                                         *) +(*           Dritte von drei Dateien des EUMEL-BASIC-Systems               *) +(*                                                                         *) +(*           Autor: Heiko Indenbirken                                      *) +(*           Überarbeitet von: Rudolf Ruland und Michael Overdick          *) +(*                                                                         *) +(*           Stand: 27.10.1987                                             *) +(*                                                                         *) +(***************************************************************************) + +PACKET basic compiler DEFINES basic,          (* Autor: Heiko Indenbirken *) +                              basic version:  (* Stand: 27.10.1987/rr/mo  *) + +PROC basic version : + +putline (""13" "15"              BASIC - Compiler     Version 1.1   (27.10.1987)              "14""); + +END PROC basic version; + +LET compiler msg  = "       *******  ENDE DER UEBERSETZUNG  *******", +    compiler err msg = " Fehler entdeckt"; + +LET (*                    S y m b o l    T y p e n                       *) +    any     = 0,  const   = 1,  var     = 2,  array   = 3,  denoter = 5, +    res word= 8,  operator= 9,  eos     = 10, del     =11,  stat no = 12, +    result const = 13,                                           (* F3/rr *) +    user fn = 20;     (* DEF/mo *) + +LET (*                    S y m b o l z e i c h e n                      *) +    plus         = 43,  minus        = 45,  mult          = 42, +    div          = 47,  backslash    = 92,  exponent      = 94, +    equal        = 61,  semicolon    = 59,  comma         = 44, +    numbersign   = 35,  open bracket = 40,  close bracket = 41, +    eol          = 13,  eop          = 14,  mod op        = 249; + +LET  (*                   Reservierte Worte                              *) +  as s       = 129,  base s     = 132,  call s     = 133,  chain s    = 135, +  clear s    = 138,  close s    = 139,  common s   = 140,  data s     = 144, +  def s      = 145,  defdbl s   = 146,  defint s   = 147,  defsng s   = 148, +  defstr s   = 149,  dim s      = 150,  else s     = 151,  end s      = 152, +  eof s      = 153,  error s    = 156,  field s    = 158,  for s      = 160, +  get s      = 162,  gosub s    = 164,  goto s     = 165,  if s       = 167,  (* F2/rr *) +  input s    = 169,  kill s     = 173,  let s      = 176,  line in s  = 177, +  lprint s   = 180,  lset s     = 181,  mid s      = 182,  name s     = 185, +  next s     = 186,  on s       = 188,  open s     = 189,  option s   = 190, +  print s    = 193,  put s      = 194,  rand s     = 195,  read s     = 196, +  rem s      = 197,  restore s  = 198,  resume s   = 199,  return s   = 200, +  rset s     = 203,  step s     = 209,  stop s     = 210,  swap s     = 213, +  tab s      = 214,  then s     = 216,  to s       = 217,  troff s    = 218, +  tron s     = 219,  using s    = 220,  wait s     = 222,  wend s     = 223, +  while s    = 224,  width s    = 225,  write s    = 226,  not        = 250, +  cls s      = 227,  usr        = 234,  sub        = 235;     (* mo *) + +LET nil   = "", +    intern error = 51; + +LET SYMBOL = STRUCT (TEXT name, INT no, type, ADDRESS adr, DTYPE data); +ADDRESS CONST niladr :: LOC -4; +SYMBOL CONST nilsymbol :: SYMBOL : (nil, any, any, nil adr, void type); +SYMBOL VAR symb; +BOOL VAR found; +OPN VAR opn; + +TEXT OP NAME (SYMBOL CONST val): +  IF val.type = const +  THEN constant value +  ELIF val.type = stat no +  THEN text (val.no) +  ELSE val.name FI  . + +constant value: +  IF val.data = int type AND length (val.name) = 2 +  THEN text (val.name ISUB 1) +  ELIF val.data = real type AND length (val.name) = 8 +  THEN text (val.name RSUB 1) +  ELSE val.name FI  . + +END OP NAME; + +PROC careful error (INT CONST no, TEXT CONST name, addition):    (* DEF/mo *) +  IF at end of statement +    THEN basic error (no, name, addition) +    ELSE basic error without leaving statement +  FI. + +at end of statement: +  symb.type = eos. + +basic error without leaving statement: +  basic error (no, name, addition, FALSE); +  error no INCR 1. + +END PROC careful error; + +(*                       P r e c o m p i l e r                           *) +PROC next symbol: +  symb.adr := niladr; +  next symbol (symb.name, symb.no, symb.type, symb.data);  + +  IF symb.no = end symbol AND symb.type = res word +  THEN symb.no   := -symb.no; +       symb.type := eos; +  FI +END PROC next symbol; + +PROC skip (INT CONST symbol, type): +  IF symb.type = type AND symb.no = symbol +  THEN next symbol +  ELSE basic error (2, NAME symb, name of (symbol) + " erwartet")  FI  . +END PROC skip; + +PROC get letter (SYMBOL VAR symbol): +  IF symb.type = var AND (LENGTH symb.name) = 1 +  THEN symbol := symb; +       next symbol +  ELSE basic error (2, NAME symb, "Buchstabe erwartet, " + type of (symb.type) + " gefunden") FI  . + +END PROC get letter; + +PROC get var (SYMBOL VAR symbol): +  IF symb.type = var +  THEN variable (symbol) +  ELIF symb.type = array +  THEN array var (symbol) +  ELSE basic error (2, NAME symb, "Variable erwartet, " + type of (symb.type) + " gefunden") FI  . + +END PROC get var; + +PROC get expr (SYMBOL VAR symbol): +  get expression (symbol, 0) +END PROC get expr; + +PROC get const (SYMBOL VAR symbol, DTYPE CONST data): +  IF symb.type = const +  THEN symbol := symb; +       declare const (symbol, data);                             (* F3/rr *) +       next symbol +  ELSE basic error (2, NAME symb, "Konstante erwartet, " + type of (symb.type) + " gefunden")  FI  . +  +END PROC get const; + +PROC get var (SYMBOL VAR symbol, DTYPE CONST data): +  get var (symbol); +  convert (symbol, data) +END PROC get var; + +PROC get expr (SYMBOL VAR symbol, DTYPE CONST data): +  get expression (symbol, 0); +  convert (symbol, data) +END PROC get expr; + +PROC get expression (SYMBOL VAR result, INT CONST last prio): +  get single result; +  WHILE symb.type = operator AND higher priority +  REP get dyadic operand; +      gen dyadic operation +  PER  . + +get single result: +  INT VAR prio; +  SELECT symb.type OF +  CASE var:      variable (result) +  CASE array:    array var (result) +  CASE const:    get const +  CASE operator: get monadic operator +  CASE res word: basic function (result) +  CASE user fn:  user function (result)                      (* DEF/mo *) +  OTHERWISE get bracket END SELECT  . + +get const: +  result := symb; +  declare const (result, result. data);                      (* F3/rr *) +  next symbol  . + +get monadic operator: +  get operator; +  prio := monadic op prio;                                  (* mo *) +  get monadic operand; +  generate monadic operator  . + +monadic op prio:                                            (* mo *) +  IF op no = not +    THEN 6 +    ELSE 12 +  FI. + +get monadic operand: +  SYMBOL VAR operand; +  next symbol; +  get expression (operand, prio). + +generate monadic operator: +(*                      Mögliche Ops:  +, - und NOT                      *) +  parameter (1, operand.data, const, operand.adr);  +  parameter (2, operand.data, var, next local adr (operand.data)); +  parameter (3, void type, const, nil adr); + +  IF op no = plus +  THEN result := operand +  ELIF op no = minus +  THEN generate minus op +  ELIF op no = not +  THEN generate not op +  ELSE basic error (2, op name, "Kein monadischer Operator") FI  . + +generate minus op: +  IF operand.data = int type +  THEN apply (1, 2, int minus) +  ELIF operand.data = real type +  THEN apply (1, 2, real minus) +  ELSE basic error (82, op name, NAME operand + " : " + dump (operand.data)) FI; +  result := SYMBOL:(op name, 0, result const, local adr, operand.data)  . + +generate not op: +  IF operand.data = int type +  THEN apply (1, 1, int not opn) +  ELIF operand.data = real type +  THEN apply (1, 1, real not opn) +  ELSE basic error (82, op name, NAME operand + " : " + dump (operand.data)) FI; +  result := SYMBOL:(op name, 0, result const, local adr, operand.data)  . + +get operator: +  INT CONST op no :: symb.no; +  TEXT CONST op name :: symb.name  . + +higher priority: +  get operator; +  prio := dyadic op prio; +  prio > last prio  . + +dyadic op prio: +  IF is bool op (op no)                 THEN bool op prio +  ELIF op no = plus OR op no = minus    THEN 8 +  ELIF op no = mod op                   THEN 9 +  ELIF op no = backslash                THEN 10 +  ELIF op no = mult OR op no = div      THEN 11 +  ELIF op no = exponent                 THEN 13 +  ELSE (* relational operator *)             7 +  FI. + +bool op prio: +  256 - op no. + +get bracket: +  IF symb.type = del AND symb.no = open bracket +  THEN next symbol +  ELSE basic error (22, NAME symb, "") FI; +  get expression (result, 0); +  skip (close bracket, del)  . + +get dyadic operand: +  next symbol; +  get expression (operand, prio)  . + +gen dyadic operation: +  convert operands; +  identify dyadic operator; +  generate dyadic operator  . + +convert operands: + DTYPE CONST op type :: type of operation; + convert (result, op type); + convert (operand, op type)  . + +type of operation: +  IF is bool op (op no) +  THEN int type +  ELIF result.data = operand.data +  THEN result.data +  ELSE real type FI  . + +identify dyadic operator: +  BOOL VAR local found; +  OPN VAR local opn; +  DTYPE VAR data; +  parameter (1, result.data,  const, result.adr);  +  parameter (2, operand.data, const, operand.adr); +  identify (op no, 1, 2, local opn, local found); +  IF NOT local found +  THEN basic error (83, symbol of (op no), +                    NAME result + " : " + dump (result.data) + " und " + +                    NAME operand + " : " + dump (operand.data)) +  ELSE data := dtype (3) FI  . + +generate dyadic operator: +  declare (3, var); +  define (3, next local adr (data)); +  apply (3, push); +  apply (1, 2, local opn); +  result := SYMBOL:(op name, 0, result const, local adr, data)  . + +END PROC get expression; + +PROC variable (SYMBOL VAR symbol): +   symbol := symb; +   next symbol; +   IF known (symbol.no) +   THEN get adr from table +   ELSE declare var (symbol, nil) FI  . + +get adr from table: +  TEXT VAR defined dim; +  remember (symbol.no, symbol.type, symbol.adr, symbol.data, defined dim)  . + +END PROC variable; + +PROC array var (SYMBOL VAR symbol field): +(*           Aufbau der Dimensionsangaben in der Symboltabelle           *) +(*               limit 1   [limit 2]...   Basis   Elemente               *) +(*                    jeweils als 2 Byte Integer/Text                    *) +(*                    Die Dimension ist dann   DIM/2-2                   *) +  ROW 100 SYMBOL VAR indizes; +  TEXT VAR limits; +  INT VAR dim; + +  symbol field := symb;  next symbol; +  get paramfield (indizes, dim, int type); + +  IF known (symbol field.no) +  THEN check field dim and data +  ELSE declare new field FI; +  generate field index  . + +check field dim and data: +  INT VAR type; +  DTYPE VAR data; +  remember (symbol field.no, type, symbol field.adr, data, limits); + +  IF old dim <> dim +  THEN basic error (84, symbol field.name, "Dimensioniert in " + text (old dim) + " Dimensionen, gefundene Anzahl Indizes: " + text (dim)) +  ELIF NOT (symbol field.data = data) +  THEN basic error (intern error, symbol field.name, dump (data) + " <=> " + dump (symbol field.data)) +  ELIF NOT (symbol field.type = type) +  THEN basic error (intern error, symbol field.name, "Feld erwartet, " + type of (type) + " gefunden") FI  . + +old dim: (length (limits) DIV 2) - 2  . + +declare new field: +  limits := dim * ""10""0"" + mki (array base) + +            mki ((10 - array base + 1)**dim); +  declare var (symbol field, limits)  . + +generate field index: +  init field subscription; +  FOR j FROM 1 UPTO dim +  REP increase field index; +      calc index length and limit; +      calculate field pointer; +      symbol field.adr := REF pointer +  PER  . + +init field subscription: +  ADDRESS VAR pointer :: next local adr (row type), +              index adr :: next local adr (int type); +  INT VAR j, elem length :: (limits ISUB (dim+2)) * typesize (symbol field.data), +             elem limit, +             elem offset :: 1 - (limits ISUB (dim+1)); +  BOOL CONST base zero := elem offset = 1  . + +increase field index: +   IF base zero +   THEN parameter (1, int type, const, index.adr); +        parameter (2, int type, const, one value); +        parameter (3, int type, var, index adr); +        parameter (4, void type, const, nil adr); +        apply (1, 3, int add); +   ELSE index adr := index.adr FI  . + +index: indizes [j]  . + +calc index length and limit: +  elem limit  := (limits ISUB j) + elem offset; +  elem length := elem length DIV elem limit  . + +calculate field pointer: +  parameter (1, int type, const, symbol field.adr); +  parameter (2, int type, const, index adr); +  parameter (3, int type, elem length); +  parameter (4, int type, elem limit); +  parameter (5, int type, const, pointer); +  parameter (6, void type, const, nil adr); +  apply (1, 5, subscript); + +END PROC array var; + +PROC get paramfield (ROW 100 SYMBOL VAR params list, INT VAR no): +  skip (open bracket, del); +  FOR no FROM 1 UPTO 100 +  REP get expression (params list [no], 0); +      IF symb.type = del AND symb.no = close bracket +      THEN next symbol; +           LEAVE get paramfield +      ELSE skip (comma, del) FI +  PER  . + +END PROC get paramfield; + +PROC get paramfield (ROW 100 SYMBOL VAR params list, INT VAR no, DTYPE CONST data): +  skip (open bracket, del); +  FOR no FROM 1 UPTO 100 +  REP get expression (params list [no], 0); +      convert (params list [no], data); +      IF symb.type = del AND symb.no = close bracket +      THEN next symbol; +           LEAVE get paramfield +      ELSE skip (comma, del) FI +  PER  . + +END PROC get paramfield; + +PROC examine access rights (ROW 100 SYMBOL VAR params list, INT CONST no): + +  INT VAR j; +  FOR j FROM 1 UPTO no REP +    IF params list [j].type = const OR params list [j].type = result const +      THEN IF access (j) = 2 +             THEN basic error (103, NAME params list [j], "im " + text (j) +                                     + ". Eintrag der Parameterliste") +           FI +    FI +  PER + +END PROC examine access rights; + +PROC basic function (SYMBOL VAR ftn):                  (* Änd. 11.08.87, mo *) +  init and check function; +  IF symb.type = del AND symb.no = open bracket +    THEN get paramfield (params list, number params); +  FI; +  apply function  . + +init and check function: +  ROW 100 SYMBOL VAR params list; +  INT VAR number params :: 0; +  BOOL CONST is usr :: symb.no = usr; +  IF is usr +    THEN check proc name +  FI; +  ftn := symb; +  next symbol   . + +check proc name: +  next symbol; +  IF symb.type = array +    THEN symb.name := subtext (symb.name, 1, LENGTH symb.name-2) +  ELIF symb.type <> var +    THEN basic error (2, NAME symb, "Prozedurname erwartet") +  FI. + +apply function: +  OPN VAR ftn local opn; +  BOOL VAR ftn found; +  INT CONST result :: number params+1; + +  INT VAR j; +  FOR j FROM 1 UPTO number params +  REP parameter (j, params list [j].data, const, params list [j].adr) PER; +  IF is usr +    THEN identify proc; +         examine access rights (params list, number params); +    ELSE identify function +  FI; +   +  ftn.adr := next local adr (ftn.data); + +  declare (result, var); +  define (result, ftn.adr); +  apply (result, push); +  apply (1, number params, ftn local opn). + +identify proc: +  identify (deshift (ftn.name), 1, number params, ftn local opn, ftn found); +  ftn.data := dtype (result); +  IF NOT ftn found +    THEN basic error (99, ftn.name, "Parameter angegeben: " + param list (1, number params)) +  ELIF ftn.data = void type +    THEN basic error (5, ftn.name, "Die Prozedur liefert keinen Wert") +  ELIF NOT (ftn.data = int type) AND NOT (ftn.data = real type) AND NOT (ftn.data = text type) +    THEN basic error (5, ftn.name, "Der Typ des Resultats ist nicht erlaubt, gefunden: " +                                   + dump (dtype (result))) +  FI. + +identify function: +  identify (ftn.no, 1, number params, ftn local opn, ftn found); +  IF ftn found +    THEN ftn.data := dtype (result) +  ELIF is basic function (ftn.no) +    THEN basic error (98, ftn.name, "Argument(e) angegeben: " + param list (1, number params)) +    ELSE basic error (22, ftn.name, "Anweisung(sbestandteil) gefunden") +  FI. + +END PROC basic function; + +PROC user function (SYMBOL VAR result):                     (* DEF/mo *) +  check if function defined; +  get arguments if expected; +  gosub (user function label); +  copy result. + +check if function defined: +  TEXT CONST scope :: name of (symb.no) + "?"; +  IF NOT known (symb.no) +    THEN basic error (18, symb.name, "") +  ELIF scanner scope = scope +    THEN basic error (85, symb.name, "") +  FI. + +get arguments if expected: +  INT VAR param counter; +  TEXT VAR dim text; +  result := symb; +  remember (symb.no, symb.type, result.adr, result.data, dim text); +  INT VAR number of params :: LENGTH dim text DIV 2 - 1; +  next symbol; +  IF number of params > 0 +    THEN get all arguments +  ELIF symb.no = open bracket AND symb.type = del +    THEN basic error (5, symb.name, "Kein Argument erwartet") +  FI. + +get all arguments: +  IF symb.no <> open bracket OR symb.type <> del +    THEN basic error (5, NAME symb, text (number of params) + " Argument(e) erwartet") +  FI; +  next symbol; +  FOR param counter FROM 2 UPTO number of params REP +    get one argument; +    skip comma; +  PER; +  get one argument; +  skip close bracket. + +get one argument: +  SYMBOL VAR ftn param; +  ftn param.no := dim text ISUB param counter; +  remember (ftn param.no, ftn param.type, ftn param.adr, ftn param.data, ftn param.name); +  IF ftn param.type <> var +    THEN basic error (intern error, name of (ftn param.no), "Parametereintrag fehlerhaft") +  FI; +  SYMBOL VAR expr res; +  get expr (expr res, ftn param.data); +  apply move (ftn param.adr, expr res.adr, ftn param.data). + +skip comma: +  IF symb.no = close bracket AND symb.type = del +    THEN basic error (5, symb.name, text (number of params) + " Argumente erwartet") +  ELIF symb.no <> comma OR symb.type <> del +    THEN basic error (2, NAME symb, "  , in Argumentenliste erwartet") +  FI; +  next symbol. + +skip close bracket: +  IF symb.no = comma AND symb.type = del +    THEN basic error (5, symb.name, "Nur " + text (number of params) + " Argument(e) erwartet") +  ELIF symb.no <> close bracket OR symb.type <> del +    THEN basic error (2, NAME symb, "  ) nach Argumentenliste erwartet") +  FI; +  next symbol. + +user function label: +  label list [dim text ISUB 1]. + +copy result : +  apply move (next local adr (result.data), result.adr, result.data); +  result.adr := local adr. + +END PROC user function; + +PROC apply move (ADDRESS CONST dest adr, source adr, DTYPE CONST datype): +  parameter (1, datype, var, dest adr); +  parameter (2, datype, const, source adr); +  parameter (3, void type, const, nil adr); + +  IF datype = int type +  THEN apply (1, 2, int move) +  ELIF datype = real type +  THEN apply (1, 2, real move) +  ELIF datype = text type +  THEN apply (1, 2, text move) +  ELSE basic error (2, "=", "Unbekannter Datentyp: " + dump (datype)) FI  . + +END PROC apply move; + +PROC convert (SYMBOL VAR symbol, DTYPE CONST to data):           (* F3/rr *) +  IF   to data = from data +  THEN +  ELIF symbol.type = const +  THEN declare const (symbol, to data) +  ELIF to data = int type  +  THEN make int +  ELIF to data = real type +  THEN make real +  ELSE basic error (13, NAME symbol, dump (to data) + " erwartet, " + dump (from data) + " gefunden") FI  . + +from data : symbol.data  . + +make real : +  IF   symbol.data = int type +  THEN parameter (1, symbol.data, const, symbol.adr); +       parameter (2, real type, var, next local adr (real type)); +       parameter (3, void type, const, nil adr); +       apply (1, 1, int to real); +       symbol.adr  := local adr; +       symbol.data := real type +  ELSE basic error (13, NAME symbol, dump (to data) + " erwartet, " + dump (from data) + " gefunden") FI  . + +make int : +  IF   symbol.data = real type +  THEN parameter (1, symbol.data, const, symbol.adr); +       parameter (2, int type, var, next local adr (int type)); +       parameter (3, void type, const, nil adr); +       apply (1, 1, real to int); +       symbol.adr  := local adr; +       symbol.data := int type +  ELSE basic error (13, NAME symbol, dump (to data) + " erwartet, " + dump (from data) + " gefunden") FI  . + +END PROC convert; + +PROC declare const (SYMBOL VAR symbol constant, DTYPE CONST data): +  convert symb value; +  IF new constant +  THEN declare this constant +  ELSE get table entry FI  . + +convert symb value: +  IF data = symbol constant.data +  THEN LEAVE convert symb value +  ELIF data = int type AND symbol constant.data = real type +  THEN symbol constant.name := mki (symbol constant.name RSUB 1); +  ELIF data = real type AND symbol constant.data = int type +  THEN symbol constant.name := mkd (symbol constant.name ISUB 1); +  ELIF data = text type AND symbol constant.data = int type +  THEN symbol constant.name := text (symbol constant.name ISUB 1) +  ELIF data = text type AND symbol constant.data = real type +  THEN symbol constant.name := text (symbol constant.name RSUB 1) +  ELSE basic error (13, NAME symbol constant, dump (data) + " erwartet, " +                          + dump (symbol constant.data) + " gefunden") FI; +  symbol constant.data := data  . + +new constant: +(*                 Konstanten werden wie folgt abgelegt:                 *) +(*                           INT:   § HL                                 *) +(*                           REAL:  § MMMMMMME                           *) +(*                           TEXT:  § Text                               *) +  put name ("§ " + symbol constant.name, symbol constant.no); +  NOT known (symbol constant.no)  . + +declare this constant: +  IF data = int type +  THEN allocate denoter (symbol constant.adr, symbol constant.name ISUB 1) +  ELIF data = real type +  THEN allocate denoter (symbol constant.adr, symbol constant.name RSUB 1) +  ELIF data = text type +  THEN allocate denoter (symbol constant.adr, symbol constant.name) FI; +  recognize (symbol constant.no, const, symbol constant.adr, data, nil)  . + +get table entry: +  INT VAR table type; +  TEXT VAR table dim; +  remember (symbol constant.no, table type, symbol constant.adr, symbol constant.data, table dim); +  IF table dim <> nil +  THEN basic error (intern error, NAME symbol constant,  "Dimension in Tabelle ungleich niltext") +  ELIF NOT (symbol constant.data = data) +  THEN basic error (intern error, NAME symbol constant, "Falscher DTYPE in Tabelle, erw: " + dump (data) +                        + ", gef: " + dump (symbol constant.data)) FI  . + +END PROC declare const; + +PROC declare var (SYMBOL VAR symbol var, TEXT CONST dim):               (* F4/rr *) +  allocate variable; +  recognize (symbol var.no, symbol var.type, symbol var.adr, symbol var.data, dim) . + +allocate variable : +  symbol var.adr := next local adr (symbol var.data); +  IF dim <> nil +     THEN INT VAR index; +          ADDRESS VAR dummy; +          FOR index FROM 2 UPTO no of elements +             REP dummy := next local adr (symbol var.data) PER; +  FI . + +no of elements: +  (dim ISUB (LENGTH dim DIV 2)) . +END PROC declare var; + +PROC parameter (INT CONST p, DTYPE CONST d type, INT CONST value): +  declare (p, d type); +  declare (p, denoter); +  define (p, value); +END PROC parameter; + +PROC apply  (INT CONST first, number params, TEXT CONST name): +  identify (name, first, number params, opn, found); +  IF NOT found +  THEN errorstop (1051, "PROC " + name + ", Parameter: " + param list (first, number params) + ", nicht gefunden!") FI; +  apply (first, number params, opn) + +END PROC apply; + +PROC clear local stack :                                         (* F4/rr *) + +  define local variables; +  clear index; +  define (rep); index incr one; +                if local storage less or equal index then goto end; +                get cell address;  +                clear cell; +                apply (rep); +  define (end); +  clear cell address; + +  . define local variables : +      LABEL VAR rep, end; +      ADDRESS VAR index; +      declare (rep); declare (end); +      allocate variable (index, type size (int type)); + +  . clear index : +      parameter (1, int type, var, index); +      apply (1, 1, clear); + +  . index incr one : +      parameter (1, int type, var, index); +      apply (1, 1, incone); + +  . if local storage less or equal index then goto end : +      parameter (1, int type, const, loc storage); +      parameter (2, int type, const, index); +      apply (1, 2, lsequ); +      apply (end, TRUE); + +  . get cell address : +      parameter (1, int type, const, LOC 2); +      parameter (2, int type, const, index); +      parameter (3, int type, 1); +      parameter (4, int type, 16000); +      parameter (5, int type, const, LOC 0); +      apply (1, 5, subscript); + +  . clear cell : +      parameter (1, int type, var, REF LOC 0); +      apply (1, 1, clear); + +  . clear cell address : +      parameter (1, int type, var, LOC 0); +      apply (1, 1, clear); +      parameter (1, int type, var, LOC 1); +      apply (1, 1, clear); + +END PROC clear local stack; + +(*                                M a i n                                *) +(* ̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃̃ *) +(*                         C o m p i l e r                               *) +(* *****              G l o b a l e   V a r i a b l en             ***** *) +INT VAR end symbol :: 0,  error no :: 0, act stat no :: 0, array base :: 0; +BOOL VAR basic trace, was warning; +ADDRESS VAR data pos, data text; + + +(*            Globale Operationen                                        *) +OPN VAR basic init, basic frame, basic module, ret, equal op, +        int minus, real minus, int not opn, real not opn, +        trace op, ln op, push, +        int incr, real incr, int add, +        int move, real move, text move, test, +        real to int, int to real, subscript, +        clear, incone, lsequ,                                    (* F4/rr *) +        basic out text; + +(*                             Parameter VOID                            *) +  init ("RTN", 1, 0, ret); + +(*                             Parameter INT                             *) +  declare (1, int type); +  init ("intnot", 1, 1, int not opn);         (* mo *) +  init ("PP",  1, 1, push); +  init ("LN", 1, 1, ln op); +  init ("real", 1, 1, int to real); +  init ("TEST", 1, 1, test); +  init ("CLEAR", 1, 1, clear);  +  init ("INCONE", 1, 1, incone);  +  init ("trace", 1, 1, trace op); + +(*                           Parameter INT INT                           *) +  declare (2, int type); +  init ("COMPLINT", 1, 2, int minus); +  init ("MOVE", 1, 2, int move);  +  init ("INC", 1, 2, int incr); +  init ("EQU", 1, 2, equal op); +  init ("LSEQU", 1, 2, lsequ);  + +(*                         Parameter INT INT INT                         *) +  declare (3, int type); +  init ("ADD", 1, 3, int add); + +(*                             Paramter REAL                             *) +  declare (1, real type); +  init ("realnot", 1, 1, real not opn);       (* mo *) +  init ("cint", 1, 1, real to int); + +(*                          Parameter REAL REAL                          *) +  declare (2, real type); +  init ("COMPLREAL", 1, 2, real minus); +  init ("FMOVE", 1, 2, real move); +  init ("INCR", 1, 2, real incr); + +(*                             Parameter TEXT                            *) +  declare (1, text type); +  init ("basicout", 1, 1, basic out text); + +(*                           Paramter TEXT TEXT                          *) +  declare (2, text type); +  init ("TMOVE", 1, 2, text move); + +(*             Parameter ADDRESS INT DENOTER DENOTER ADDRESS             *) +  declare (3, denoter); +  declare (4, denoter); +  init ("SUBSCRIPT", 1, 5, subscript); + +PROC init (TEXT CONST name, INT CONST local from, number params, OPN VAR local opn): +  identify (name, local from, number params, local opn, found); +  IF NOT found +  THEN errorstop (1051, "PROC init (TC, IC, IC, OPN VAR): OPN für """ + name + """ nicht gefunden") FI +END PROC init; + +(*                           Runtime Konstanten                          *) +  ADDRESS VAR true value, false value, niltext value, +              zero value, one value, two value, three value, +              comma value, int one value, real one value, +              loc storage;                                  (* F4/rr *) + +(* +++++                     Globale Variablen                     +++++ *) +  BOOL VAR proc found; +  INT VAR deftype, field elems, i, params; +  ROW 100 SYMBOL VAR param; +  SYMBOL VAR base size, begin range, end range, expr result, field, filename, +             from, len, image, label, old name, new name, +             question, size, tab pos, var result; +  TEXT VAR constant, field size, proc name; + +(*                            Label-Verwaltung                           *) +LET label list size = 4100; +BOUND ROW label list size LABEL VAR label list; +DATASPACE VAR label ds; +INITFLAG VAR label init :: FALSE; +INT VAR last label no; + +(* *****           I n t e r f a c e     P r o z d u r e n         ***** *) +PROC basic: +  basic (last param) +END PROC basic; + +PROC basic (TEXT CONST basic file name): +  basic (basic file name, nil) +END PROC basic; + +PROC basic (TEXT CONST basic file name, prog name): +  IF NOT exists (basic file name) +    THEN errorstop ("""" + basic file name + """ gibt es nicht") +    ELSE FILE VAR basic file :: sequential file (modify, basic file name); (* F5/rr *) +         headline (basic file, basic file name); +         last param (basic file name); +         basic (basic file, prog name) +  FI; + +END PROC basic; + +PROC basic (FILE VAR source file, TEXT CONST prog name): +  IF prog name <> nil CAND prog name is not a tag                (* F5/rr *) +     THEN errorstop ("unzulässiger Programmname : """ + prog name + """"); +  FI; +  modify (source file);                                          (* F5/rr *) +  disable stop; +  init label table; +  store status; +  coder on (data allocation by coder);  +  compile (source file, progname); +  restore status; +  start basic prog  .  + +prog name is not a tag :                                         (* F5/rr *) +  LET tag = 1; +  INT  VAR symbol type; +  TEXT VAR symbol name; +  scan (prog name); +  next symbol (symbol name, symbol type); +  symbol name <> prog name OR symbol type <> tag . + +init label table: +  IF NOT initialized (label init) +  THEN label ds    := nilspace; +       label list  := label ds; +  FI  . + +store status: +  INT CONST source line :: line no (source file),  +            source col  :: col (source file); +  BOOL CONST check status :: check; +  check on  . + +restore status: +  to line (source file, source line); +  col (source file, source col); +  IF NOT check status +  THEN check off FI  . + +start basic prog: +  IF error no > 0 OR is error +    THEN basic error end +    ELSE normal end +  FI; +  close (source file)  . + +basic error end: +  coder off (FALSE, FALSE, nop); +  IF is error +    THEN put error; +         clear error +    ELSE display (""13""10""10"");                            (* F20/rr *) +         display (text (error no) + compiler err msg); +         display (""13""10""10""); +         display (compiler msg); +         display (""13""10""); +         IF sysout <> "" +            THEN line (2); +                 put (text (error no) + compiler err msg); +                 line (2); +                 put (compiler msg); +                 line +         FI +  FI; +  show file and error  . + +show file and error:                                             (* F20/rr *) +  IF anything noted CAND command dialogue +     THEN noteedit (source file); +  FI; +  errorstop (nil) . + +normal end: +  IF prog name = nil +  THEN run basic proc +  ELSE insert basic proc FI; +  IF warnings AND was warning +    THEN show file and error +  FI. + +run basic proc: +  coder off (FALSE, TRUE, basic frame);  +  display (""13""10"") . +  +insert basic proc: +  coder off (TRUE, TRUE, basic frame); +  coder on (data allocation by coder); +  coder off (FALSE, FALSE, basic init); +  display (""13""10"") . + +END PROC basic; + +PROC compile (FILE VAR source file, TEXT CONST progname): +  enable stop; +  init compiler; +  init basic prog; + +  begin scanning (source file); +  next symbol; +  get statement group (eop); +  end compiling  . +  +init compiler: +  end symbol  := 0; +  error no    := 0; +  act stat no := 0; +  array base  := 0; +  basic trace := FALSE; +  was warning := FALSE; + +  init storage; +  init label; +  init data; +  init table . +  +init label:                                                       +  TEXT VAR local stat no; +  INT VAR stat nos; +  init stat no (source file, error no);                          (* F21/rr *) +  IF error no > 0 THEN LEAVE compile FI; +  all stat no (local stat no, stat nos); +  FOR i FROM 1 UPTO stat nos +  REP declare (label list [i]) PER; +  last label no := stat nos.                                     (* DEF/mo *) + +init basic prog: +  LIB VAR packet; +  declare (basic packet name, packet); +  define (packet); +  parameter (1, void type, const, nil adr); +  declare (basic init); +  IF progname = nil +  THEN declare (basic frame) +  ELSE declare (progname, 1, 0, basic frame) FI; +  declare (basic module); +  declare runtime const; +  declare basic init; +  declare basic frame; +  declare basic module  . + +basic packet name: +  IF progname <> "" +    THEN "BASIC." + progname +    ELSE "BASIC" +  FI. + +declare runtime const: +  allocate variable (data text, type size (text type)); +  allocate variable (data pos, type size (int type)); +  allocate variable (loc storage, type size (int type));         (* F4/rr *) + +  allocate denoter (true value, 0); +  allocate denoter (false value, -1); +  allocate denoter (niltext value, nil); +  allocate denoter (one value, 1); +  allocate denoter (two value, 2); +  allocate denoter (three value, 3); +  allocate denoter (real one value, 1.0); +  allocate denoter (comma value, ","); + +  zero value    := true value; +  int one value := one value  . + +declare basic init: +  begin module; +  define (basic init, 4); +  parameter (1, text type, var, data text);  +  parameter (2, int type, var, data pos); +  apply (1, 2, "initdata"); +  parameter (1, void type, const, nil adr); +  apply (1, 0, ret); +  end module  . + +declare basic frame: +  begin module; +  define (basic frame, 4); + +  IF prog name = nil +  THEN parameter (1, void type, const, nil adr); +       apply (1, 0, basic init); +  FI; +  +  declare (1, int type); +  declare (1, const); +  define (1, 0); +  parameter (2, void type, const, nil adr); +  apply (1, 1, ln op); + +  apply (1, 0, "disablestop"); +  apply (1, 0, "startbasic"); + +  parameter (1, int type, var, data pos); +  parameter (2, int type, const, one value); +  parameter (3, void type, const, nil adr); +  apply (1, 2, int move); + +  parameter (1, void type, const, nil adr); +  apply (1, 0, basic module); +  apply (1, 0, "endbasic"); +  parameter (1, void type, const, nil adr); +  apply (1, 0, ret); +  end module  . + +declare basic module: +  LABEL VAR start lab; +  begin module; +  define (basic module); +  declare (start lab); +  apply (1, 0, "enablestop"); +  gosub (start lab); +  parameter (1, void type, const, nil adr); +  apply (1, 0, "returnerror");                                   (* mo *) +  define (start lab); +  clear local stack .                                            (* F4/rr *) + +end compiling: +  parameter (1, void type, const, nil adr); +  apply (1, 0, ret);  +  define (loc storage, local storage - 1);                       (* F4/rr *) +  set length of local storage (basic module, max (2, local storage));  (* F4/rr *) +  IF error no = 0 +  THEN end module FI  . + +END PROC compile; + +PROC get statement group (INT CONST new symbol):  +(* 'get statement group' compiliert das ganze Programm bis zum Auftreten *) +(* von 'end symbol'                                                      *) +  disable stop; +  new end symbol; +  get all basic lines; +  old end symbol  . + +new end symbol: +  INT CONST old symbol :: end symbol; +  end symbol := new symbol  . + +old end symbol: +  end symbol := old symbol  . + +get all basic lines: +  REP get basic line; +  +      IF is error +      THEN error handling +      ELIF symb.type = eos +      THEN check this eos FI +  PER  . + +error handling:                                                  (* F20/rr *) +  IF error in basic program  +       THEN error no INCR 1 +  ELIF end of source file +       THEN clear error; +            LEAVE get all basic lines +  ELIF halt from terminal +       THEN LEAVE get statement group +       ELSE error no INCR 1; +            handle internal error; +            LEAVE get statement group +  FI; +  clear error; +  scope compulsory (TRUE);                                      (* DEF/mo *) +  set scope ("");                                               (* DEF/mo *) +  next statement; +  next symbol  . + +error in basic program: +  errorcode = 101. + +end of source file: +  errorcode = 99. + +halt from terminal: +  errorcode = 1. + +handle internal error :                                          (* F20/rr *) +  TEXT VAR error :: "BASIC-Compiler ERROR"; +  IF errorcode <> 0 +  THEN error CAT " #" + text (errorcode) FI; +  IF errorline > 0 +  THEN error CAT " at " + text (errorline) FI; +  error CAT "  : "; +  error CAT errormessage; +  IF sysout <> "" THEN putline (error) FI; +  note (error); +  noteline; +  clear error; +  errorstop (error). + +check this eos: +  IF symb.no = eol +  THEN next symbol +  ELIF symb.no = -new symbol OR symb.no = eop +  THEN LEAVE get all basic lines                      (* mo *) +  ELSE basic error (intern error, NAME symb, "EOL erwartet, " + +                    type of (symb.type) + " gefunden") +  FI  . + +END PROC get statement group; + +PROC get basic line (INT CONST new symbol): +(*Die Abbruchbedingungen werden neu gesetzt und bei Verlassen der        *) +(*Prozedur zurückgesetzt.                                                *) +  disable stop; +  INT CONST old symbol :: end symbol; +  end symbol := new symbol;  +  get basic line; +  end symbol := old symbol  . + +END PROC get basic line; + +PROC get basic line: +(* 'get basic line' behandelt genau eine Zeile mit Zeilennummer.         *) +  enable stop; +  IF symb.type = stat no +  THEN gen stat no (symb.no) FI; + +  REP get one basic statement PER  . +  +get one basic statement: +(* 'get one basic statement' behandelt genau ein Statement.              *) +  IF symb.type = eos +  THEN get end of statement +  ELIF symb.type = res word OR symb.type = var OR symb.type = array +  THEN get one statement +  ELSE basic error (2, NAME symb, type of (symb.type) + " ohne Zusammenhang") FI  . + +get end of statement: +  IF symb.no = eos +  THEN next symbol +  ELSE LEAVE get basic line FI  . + +get one statement: +  IF symb.type = res word +    THEN get res word statement +  ELIF symb.type = var OR symb.type = array +    THEN let statement +  FI; +  skip comma if else expected; +  IF symb.type <> eos +    THEN basic error (2, NAME symb, "EOS erwartet, " + type of (symb.type) + " gefunden") +  FI. + +skip comma if else expected: +  IF end symbol = else s AND symb.type = del AND symb.no = comma +    THEN next symbol; +         IF symb.type <> eos OR symb.no <> -else s +           THEN basic error (2, NAME symb, "ELSE erwartet") +         FI +  FI. +   +get res word statement: +  SELECT symb.no OF +  CASE as s     : basic error (90, symb.name, "")  +  CASE base s   : basic error (91, symb.name, "") +  CASE call s,     +       chain s  : call statement +  CASE clear s  : not implemented +  CASE close s  : not implemented +  CASE cls s    : cls statement                           (* mo *) +  CASE common s : not implemented +  CASE data s   : data statement  +  CASE def s    : def statement                           (* mo *) +  CASE defint s, +       defdbl s, +       defsng s, +       defstr s : def type statement +  CASE dim s    : dim statement +  CASE else s   : basic error (92, symb.name, "") +  CASE end s    : end statement +  CASE error s  : error statement +  CASE field s  : not implemented +  CASE for s    : for statement +  CASE get s    : not implemented +  CASE gosub s  : gosub statement +  CASE goto s   : goto statement +  CASE if s     : if statement +  CASE input s  : input statement +  CASE kill s   : kill statement +  CASE let s    : let statement +  CASE line in s: line statement +  CASE lprint s : lprint statement                        (* mo *) +  CASE l set s  : l set statement +  CASE mid s    : mid statement +  CASE name s   : name statement +  CASE next s   : basic error (1, symb.name, "") +  CASE on s     : on statement +  CASE open s   : not implemented +  CASE option s : option statement +  CASE print s  : print statement +  CASE put s    : not implemented +  CASE rand s   : randomize statement +  CASE read s   : read statement +  CASE rem s    : rem statement +  CASE restore s: restore statement  +  CASE resume s : not implemented +  CASE return s : return statement +  CASE r set s  : r set statement +  CASE step s   : basic error (93, symb.name, "") +  CASE stop s   : stop statement +  CASE sub      : basic error (101, symb.name, "") +  CASE swap s   : swap statement +  CASE tab s    : basic error (94, symb.name, "") +  CASE then s   : basic error (95, symb.name, "") +  CASE to s     : basic error (96, symb.name, "") +  CASE troff s  : troff statement +  CASE tron s   : tron statement +  CASE using s  : basic error (97, symb.name, "") +  CASE wait s   : not implemented +  CASE wend s   : basic error (30, symb.name, "") +  CASE while s  : while statement +  CASE width s  : width statement +  CASE write s  : write statement +  OTHERWISE basic error (104, symb.name, "") END SELECT. +   +not implemented: +  basic error (100, symb.name, ""). + +call statement: +(*CALL <proc name> [(<argument list>)]                                   *) +  next symbol; +  get proc name; +  get proc parameter; +  apply proc  . + +get proc name: +  proc name := symb.name; +  IF symb.type = array +  THEN proc name := subtext (proc name, 1, LENGTH proc name-2) FI; +  next symbol  . + +get proc parameter: +  params := 0; +  IF symb.type = del AND symb.no = open bracket +  THEN get paramfield (param, params) FI  . + +apply proc: +  OPN VAR proc opn; +  FOR i FROM 1 UPTO params +  REP parameter (i, param [i].data, const, param [i].adr) PER; +  identify (deshift (proc name), 1, params, proc opn, proc found); + +  IF NOT proc found +    THEN basic error (99, proc name, "Parameter angegeben: " + param list (1, params)) +  ELIF result found +    THEN basic error (5, proc name, "Kein Resultat erlaubt (gefunden: " + dump (result data) + ")") +  FI; + +  examine access rights (param, params); + +  parameter (params+1, void type, const, nil adr); +  apply (1, params, proc opn)  . + +result found: +  NOT (result data = void type)  . + +result data: +  dtype (params+1)  . + +cls statement: +(*CLS                                                                    *) +  next symbol; +  apply (1, 0, "nextpage"). + +data statement: +(*DATA <list of constants>                                               *) +  DTYPE VAR const data; +  data line (act stat no); +  REP IF next data (constant, const data) +      THEN data (constant, const data) +      ELSE basic error (2, "EOL", "Daten fehlen !") FI; + +      next symbol; +      IF symb.type = eos +      THEN LEAVE data statement +      ELIF symb.type <> del OR symb.no <> comma +      THEN basic error (2, NAME symb, "  , erwartet") FI +  PER  . + +def statement:                         (* DEF/mo *) +(*DEF FN<name> [(parameter list)] = <function definition>                *) +  get function name; +  store label of function; +  get all params; +  get function definition. + +get function name: +  next symbol; +  IF symb.type <> user fn +    THEN treat wrong function name +  ELIF LENGTH symb.name <= 2 +    THEN basic error (2, symb.name, "Unerlaubter Funktionsname") +  ELIF known (symb.no) +    THEN basic warning ("Die Funktion """ + symb.name + """ wurde bereits definiert"); +         was warning := TRUE +  FI; +  SYMBOL VAR function :: symb; +  function.name := name of (function.no). + +treat wrong function name: +  IF symb.type = var OR symb.type = array +    THEN basic error (2, symb.name, "Funktionsname muß mit FN beginnen") +    ELSE basic error (2, NAME symb, "Funktionsname erwartet") +  FI. + +store label of function: +  IF last label no < label list size +    THEN last label no INCR 1 +    ELSE errorstop ("Zu viele Label") +  FI; +  declare (label list [last label no]); +  TEXT VAR dim text :: ""; +  dim text CAT last label no; +  recognize (function.no, user fn, niladr, function.data, dim text). + +get all params: +  set scope (function.name + "?"); +  next symbol; +  IF symb.type = del AND symb.no = open bracket +    THEN REP +           try to get a param; +           try to get del +         UNTIL symb.no = close bracket OR +                    (symb.type <> del AND symb.type <> var) PER; +         skip close bracket +  FI. + +try to get a param: +  REP +    IF symb.type <> var +      THEN next symbol +    FI; +    IF symb.type <> var +      THEN careful error (2, NAME symb, "Parametervariable erwartet"); +           IF symb.type <> del +             THEN next symbol +           FI +      ELSE treat param +    FI +  UNTIL symb.type <> del OR symb.no = close bracket PER. + +treat param: +  IF NOT known (symb.no)  +    THEN declare var (symb, nil); +  ELIF already appeared in param list +    THEN careful error (89, symb.name, ""); +  FI; +  dim text CAT symb.no. + +already appeared in param list: +  INT VAR param counter; +  FOR param counter FROM 2 UPTO LENGTH dim text DIV 2 REP +    IF (dim text ISUB param counter) = symb.no +      THEN LEAVE already appeared in param list WITH TRUE +    FI +  PER; +  FALSE. + +try to get del: +  IF symb.type = var +    THEN next symbol +  FI; +  IF symb.type = var OR (symb.type = del CAND (symb.no <> comma AND symb.no <> close bracket)) +    THEN careful error (2, symb.name, "  , in Parameterliste erwartet") +  FI. + +skip close bracket: +  IF symb.type = del AND symb.no = close bracket +    THEN next symbol +    ELSE careful error (2, NAME symb, "  ) nach Parameterliste erwartet") +  FI. + +get function definition: +  scope compulsory (FALSE); +  skip (equal, operator); +  generate forward jump; +  define this label; +  get expr (expr result, function.data); +  recognize (function.no, user fn, expr result.adr, function.data, dim text); +  goret; +  define (behind); +  scope compulsory (TRUE); +  set scope (""). + +generate forward jump: +  LABEL VAR behind; +  declare (behind); +  apply (behind). + +define this label: +  define (label list [last label no]). + + +def type statement: +(*DEFINT/DBL/SNG/STR <range(s) of letters>                              *) +  deftype := symb.no; +  next symbol; +  REP get letter (begin range); +      IF symb.type = operator AND symb.no = minus +      THEN next symbol; +           get letter (end range) +      ELSE end range := begin range FI;  + +      IF name of (begin range.no) > name of (end range.no) +      THEN basic error (87, begin range.name + "-" + end range.name, "")  +      ELSE define chars (name of (begin range.no), name of (end range.no), data type) FI; + +      IF symb.type = eos +      THEN LEAVE def type statement +      ELSE skip (comma, del) FI +  PER  . +  +data type: +  SELECT deftype OF +  CASE defint s: int type +  CASE defstr s: text type +  OTHERWISE real type ENDSELECT  . + + dim statement: +(*DIM <list of subscripted var results>                                    *) +  next symbol; +  REP get field var; +      get field size; +      declare field; + +      IF symb.type = eos +      THEN LEAVE dim statement +      ELSE skip (comma, del) FI +  PER  . + +get field var: +  IF symb.type = array +    THEN IF known (symb.no) +           THEN basic error (10, symb.name, "") +           ELSE field := symb; +                next symbol +         FI +  ELIF symb.type = var +    THEN basic error (2, symb.name, "Dimensionsangabe fehlt") +    ELSE basic error (2, NAME symb, "Feldname erwartet") +  FI. + +get field size: +  field size := ""; +  field elems := 1; +  skip (open bracket, del); + +  REP get const (size, int type); +      INT CONST field limit :: size.name ISUB 1; +      IF field limit < array base +      THEN basic error (88, NAME size, "Die Obergrenze muß >= " + +                                        text (array base) + " sein") +      ELSE field size CAT (mki (field limit)); +           field elems := field elems * (field limit + 1 - array base) +      FI; + +      IF symb.type = del AND symb.no = close bracket +      THEN next symbol; +           LEAVE get field size +      ELSE skip (comma, del) FI +  PER  . + +declare field: +  field size CAT mki (array base); +  field size CAT mki (field elems); +  declare var (field, field size)  . + +end statement: +(*END                                                                    *) +  next symbol; +  parameter (1, void type, const, nil adr); +  apply (1, 0, ret)  . + +error statement: +(*ERROR <integer expr result>                                             *) +  next symbol; +  get expr (expr result, int type); +  parameter (1, int type, const, expr result.adr); +  parameter (2, text type, const, niltext value); +  apply (1, 2, "errorstop")  . + +gosub statement: +(*GOSUB <line number>                                                    *)  +  next symbol; +  get const (label, int type); +  gosub (this label)  . + +goto statement : +(*GOTO <line number>                                                     *) +  next symbol; +  get const (label, int type); +  apply (this label)  . + +this label: label list [label pos (label no)]  . +label no:  label.name ISUB 1  . + +input statement: +(*INPUT [;]["Anfrage" ;/,] Variable [, Variable]                         *)  +  ROW 100 DTYPE VAR input var data; +  INT VAR number input vars; +  LABEL VAR input lab; +  next symbol; +  declare (input lab); +  define (input lab); +  get semicolon for cr lf; +  get question and question mark; +  apply (1, 3, "readinput"); +  get input eof; +  get data types of input vars (input var data, number input vars); (* F25/rr *) +  check data types of input vars;                                (* F8/F25/rr *) +  apply (1, 0, "inputok"); +  apply (input lab, FALSE);                                       +  assign list of input var .                                     (* F8/F25/rr *) + +get semicolon for cr lf: +  IF symb.type = del AND symb.no = semicolon +  THEN next symbol; +       parameter (1, bool type, const, false value) +  ELSE parameter (1, bool type, const, true value) FI   . + +get question and question mark: +  IF symb.type = const AND symb.data = text type +  THEN get const (question, text type); +       parameter (2, text type, const, question.adr); +       parameter (3, bool type, const, question mark value); +       next symbol +  ELSE parameter (2, text type, const, niltext value); +       parameter (3, bool type, const, true value);              (* F7/rr *) +  FI  . + +question mark value: +  IF symb.type = del AND symb.no = semicolon +  THEN true value +  ELIF symb.type = del AND symb.no = comma +  THEN false value +  ELSE basic error (2, NAME symb, "  ; oder , erwartet"); nil adr FI  . + +get input eof: + IF symb.type = res word AND symb.no = eof s + THEN next symbol; +      get const (label, int type); +      apply (1, 0, "inputeof"); +      apply (this label, TRUE) + FI . +  +check data types of input vars :                                (* F8/F25/rr *) +  FOR i FROM 1 UPTO number input vars +  REP parameter (1, int type, const, input data type); +      apply (1, 1, "checkinput"); +      apply (input lab, FALSE); +  PER . + +input data type :                                               (* F8/F25/rr *) +   IF   input var data (i) =  int type THEN one value +   ELIF input var data (i) = real type THEN two value +   ELIF input var data (i) = text type THEN three value +                                       ELSE zero value +   FI . + +assign list of input var :                                       (* F8/F25/rr *) +  REP get var (var result); +      parameter (1, var result. data, var, var result. adr); +      apply (1, 1, "assigninput"); + +      IF symb.type = del AND symb.no = comma +      THEN next symbol +      ELSE LEAVE assign list of input var FI +  PER . + +kill statement: +(*KILL <filename>                                                        *) +  next symbol; +  get expr (filename, text type); + +  parameter (1, text type, const, filename.adr); +  parameter (2, quiet type, const, next local adr (int type)); +  apply (2, 0, "quiet"); +  apply (1, 2, "forget")  . + +let statement: +(*[LET] <var> = <expression>                                             *) +  IF symb.type = res word AND symb.no = let s +  THEN next symbol FI; +  get var (var result); +  skip (equal, operator); +  get expr (expr result, var result.data); +  apply move (var result.adr, expr result.adr, var result.data). + +line statement:                                                  (* F9/rr *) +(*1.  LINE INPUT [;][<"prompt string">;]<string var result>                *) +  next symbol; +  skip (input s, res word); +  get semicolon; +  get prompt string; +  apply (1, 3, "readinput"); +  assign string var result  . + +get semicolon: +  IF symb.type = del AND symb.no = semicolon +  THEN next symbol; +       parameter (1, bool type, const, false value) +  ELSE parameter (1, bool type, const, true value) FI   . + +get prompt string: +  IF symb.type = const AND symb.data = text type +  THEN get const (question, text type); +       parameter (2, text type, const, question.adr); +       skip (semicolon, del); +  ELSE parameter (2, text type, const, niltext value); +  FI; +  parameter (3, bool type, const, false value) . + +assign string var result : +  get var (var result, text type); +  parameter (1, text type, var, var result.adr); +  apply (1, 1, "assigninputline") . + +lprint statement: +(*LPRINT        (cf. PRINT)                                              *) +  apply (1, 0, "switchtoprintoutfile"); +  print statement; +  apply (1, 0, "switchbacktooldsysoutstate"). + +l set statement: +(*LSET <string var> = <string expression>                                *)  +  next symbol; +  get var (var result, text type); +  skip (equal, operator); +  get expr (expr result, text type); +  parameter (1, text type, var, var result.adr); +  parameter (2, text type, const, expr result.adr); +  apply (1, 2, "lset")  . + +mid statement: +(*MID$  (<string var>, from [,len]) = <string expression>                *)  +  next symbol; +  skip (open bracket, del); +  get var (var result, text type); +  skip (comma, del); +  get expr (from, int type); +  IF symb.type = del AND symb.no = comma +  THEN next symbol; +       get expr (len, int type) +  ELSE len := nilsymbol FI; +  skip (close bracket, del); +  skip (equal, operator); +  get expr (expr result, text type); + +  parameter (1, text type, var, var result.adr); +  parameter (2, int type, const, from.adr); +  parameter (3, text type, const, expr result.adr); +  IF len.data = int type +  THEN parameter (4, int type, const, one value); +       parameter (5, int type, const, len.adr); +       parameter (6, text type, var, next local adr (text type)); +       apply (3, 3, "subtext"); +       parameter (3, text type, const, local adr); +  FI; +  apply (1, 3, "replace")  . + +name statement: +(*NAME <old filename> AS <new filename>                                  *)  +  next symbol; +  get expr (old name, text type); +  skip (as s, res word); +  get expr (new name, text type); +  parameter (1, text type, const, old name.adr); +  parameter (2, text type, const, new name.adr); +  apply (1, 2, "rename")  . + +option statement: +(*OPTION BASE 0|1                                                        *) +  next symbol; +  skip (base s, res word); +  get const (base size, int type); +  IF new array base > 1 +    THEN basic error (105, NAME base size, "") +    ELSE array base := new array base +  FI. + +new array base: +  base size.name ISUB 1. + +randomize statement: +(*RANDOMIZE [<expression>]                                               *) +  next symbol; +  IF symb.type = eos +  THEN apply (1, 0, "initrnd") +  ELSE get expr (expr result, real type); +       parameter (1, real type, const, expr result.adr); +       apply (1, 1, "initrnd") +  FI  . + +read statement: +(*READ <list of var>                                                *)  +  next symbol; +  REP get var (var result); +      parameter (1, text type, const, data text); +      parameter (2, int type, var, data pos); +      parameter (3, var result.data, var, var result.adr); +      apply (1, 3, "read"); + +      IF symb.type = eos +      THEN LEAVE read statement +      ELSE skip (comma, del) FI +  PER  . + +rem statement: +(*REM <remark>                                                           *) +  next statement; +  symb := SYMBOL : ("", eol, eos, LOC 0, void type);  +  LEAVE get basic line  . + +restore statement: +(*RESTORE [<line number>]                                                *)  +  next symbol; +  IF symb.type = eos +  THEN parameter (1, int type, var, data pos); +       parameter (2, int type, const, one value); +       parameter (3, void type, const, nil adr); +       apply (1, 2, int move); +  ELSE get const (label, int type); +       parameter (1, text type, const, data text); +       parameter (2, int type, var, data pos); +       parameter (3, int type, const, label.adr); +       apply (1, 3, "restore") +  FI  . + +return statement : +(*RETURN                                                                 *) +  next symbol; +  goret  . + +r set statement: +(*RSET <string var> = <string expression>                           *)  +  next symbol; +  get var (var result, text type); +  skip (equal, operator); +  get expr (expr result, text type); +  parameter (1, text type, var, var result.adr); +  parameter (2, text type, const, expr result.adr); +  apply (1, 2, "rset")  . + +stop statement:  +(*STOP                                                                   *) +  next symbol; +  expr result := SYMBOL: (nil, any, const, nil adr, int type); +  expr result.name CAT act stat no; +  declare const (expr result, int type); +  parameter (1, int type, const, expr result.adr); +  apply (1, 1, "basicstop"); +  parameter (1, void type, const, nil adr); +  apply (1, 0, ret)  . + +swap statement: +(*SWAP <var>,<var>                                             *) +  next symbol; +  get var (var result); +  parameter (1, var result.data, var, var result.adr); +  DTYPE CONST first var result data :: var result.data; +  skip (comma, del); +  get var (var result); +  IF first var result data = var result.data +    THEN parameter (2, var result.data, var, var result.adr); +         apply (1, 2, "swap") +    ELSE basic error (106, var result.name, "gefunden: " +           + dump (first var result data) + ", " + dump (var result.data)) +  FI. + +troff statement: +(*TROFF                                                                  *) +  next symbol; +  basic trace := FALSE  . + +tron statement: +(*TRON                                                                   *) +  next symbol; +  basic trace := TRUE  . + +width statement: +(*WIDTH Größe                                                            *) +  next symbol; +  get expr (expr result, int type); +  parameter (1, int type, const, expr result.adr); +  apply (1, 1, "width")  . + +write statement: +(*WRITE [<list of expr results>]                                          *) +  next symbol; + +  IF symb.type = eos +  THEN apply (1, 0, "nextline") +  ELSE write list of expr results FI  . + +write list of expr results: +  REP get expr (expr result); +      parameter (1, expr result.data, const, expr result.adr); +      apply (1, 1, "basicwrite"); + +      IF symb.type = eos +      THEN apply (1, 0, "nextline"); +           LEAVE write list of expr results +      ELSE skip (comma, del); +           parameter (1, text type, const, comma value); +           apply (1, 1, "basicout")  +      FI +  PER  . + +END PROC get basic line; + +PROC gen stat no (INT CONST local stat no): +(*               Die Zeilennummer wird als Label definiert               *) +(*     Die Prozedur 'stat no' wird mit der Statementnummer aufgerufen    *) +  act stat no := local stat no; +  define (label list [label pos (act stat no)]); + +  declare (1, int type); +  declare (1, const); +  define (1, act stat no); +  parameter (2, void type, const, nil adr); +  apply (1, 1, ln op); + +  IF basic trace +  THEN expr result := SYMBOL: (nil, any, const, nil adr, int type); +       expr result.name CAT act stat no; +       declare const (expr result, int type); +       parameter (1, int type, const, expr result.adr); +       apply (1, 1, trace op) +  FI; +  next symbol  . + +END PROC gen stat no; + +PROC for statement: +(*FOR <var> = x TO y [STEP z]                                       *) +  SYMBOL VAR local var result, init val, limit val, step val; +  LABEL VAR start loop, end loop; +  INT CONST  for stat no      := act stat no,                     (* F29/rr *) +             for scan line no := scan line no; +  TEXT CONST for symb name    := symb.name; +  declare (start loop); +  declare (end loop); + +  next symbol; +  get loop var; +  skip (equal, operator); +  get expr (init val, local var result.data); +  skip (to s, res word); +  get expr (limit val, local var result.data); +  get step val; + +  init loop var; +  define (start loop); +  gen check of variable; +  get statement group (next s); + +  IF symb.type = eos AND symb.no = -next s +  THEN next var statement +  ELSE define (end loop); +       basic error ("Compiler", 26, for scan line no, for stat no, for symb name, "", TRUE); (* F29/rr *) +  FI  . + +get loop var: +  get var (local var result); +  IF NOT (local var result.data = int type OR local var result.data = real type) +    THEN basic error (2, NAME local var result, "INT oder REAL erwartet, " +                        + dump (local var result.data) + " gefunden") +  FI  . + +get step val: +  IF symb.type = res word AND symb.no = step s +  THEN next symbol; +       get expr (step val, local var result.data) +  ELIF local var result.data = int type +  THEN step val.data := int type; +       step val.adr  := int one value +  ELSE step val.data := real type; +       step val.adr  := real one value +  FI  . + +init loop var: +  IF local var result.data = int type +  THEN init int loop +  ELSE init real loop FI . + +init int loop: +  IF limit val.type = var +  THEN parameter (1, int type, var, next local adr (int type)); +       parameter (2, int type, const, limit val.adr); +       parameter (3, void type, const, nil adr); +       apply (1, 2, int move); +       limit val.adr := local adr; +  FI; +  IF step val.type = var +  THEN parameter (1, int type, var, next local adr (int type)); +       parameter (2, int type, const, step val.adr); +       parameter (3, void type, const, nil adr); +       apply (1, 2, int move); +       step val.adr := local adr; +  FI; +  IF NOT (init val.no = local var result.no) +  THEN parameter (1, int type, var, local var result.adr); +       parameter (2, int type, const, init val.adr); +       parameter (3, void type, const, nil adr); +       apply (1, 2, int move)  +  FI  . + +init real loop: +  IF limit val.type = var +  THEN parameter (1, real type, var, next local adr (real type)); +       parameter (2, real type, const, limit val.adr); +       parameter (3, void type, const, nil adr); +       apply (1, 2, real move); +       limit val.adr := local adr; +  FI; +  IF step val.type = var +  THEN parameter (1, real type, var, next local adr (real type)); +       parameter (2, real type, const, step val.adr); +       parameter (3, void type, const, nil adr); +       apply (1, 2, real move); +       step val.adr := local adr; +  FI; +  IF NOT (init val.no = local var result.no) +  THEN parameter (1, real type, var, local var result.adr); +       parameter (2, real type, const, init val.adr); +       parameter (3, void type, const, nil adr); +       apply (1, 2, real move)  +  FI  . + +gen check of variable: +  parameter (1, local var result.data, const, local var result.adr); +  parameter (2, limit val.data,  const, limit val.adr); +  parameter (3, step val.data, const, step val.adr); +  parameter (4, bool type, const, nil adr);  apply (4, nop); +(*    In der nächsten Coder-Version ist eine PUSH-Angabe nop nicht nötig *) +  apply (1, 3, "loopend"); +  apply (end loop, TRUE)  . + +next var statement: +(*NEXT [<var>][,<var>...]                                  *) +  next symbol; +  generate loop end; +  IF symb.type <> eos +  THEN check next var result FI  . + +check next var result: +  IF symb.no = local var result.no +  THEN next symbol; +       IF symb.type = del AND symb.no = comma +       THEN next for loop FI +  ELSE basic error (86, NAME symb, local var result.name + " erwartet") FI  . + +next for loop: +  IF end symbol = next s +    THEN symb := SYMBOL:("", -next s, eos, nil adr, void type) +    ELSE basic error (1, symb.name, "")                        (* mo *) +  FI. + +generate loop end: +  parameter (1, local var result.data, var, local var result.adr); +  parameter (2, step val.data, const, step val.adr); +  parameter (3, void type, const, nil adr); +  IF local var result.data = int type +  THEN apply (1, 2, int incr) +  ELSE apply (1, 2, real incr) FI; + +  apply (start loop); +  define (end loop)  . + +END PROC for statement; + +PROC if statement :                                   (* Änd. 11.08.87, mo *) +(*  IF <expression> THEN <statement(s)>|<line number>                    *) +(*                 [ELSE <statement(s)>|<line number>]                   *) +(*  IF <expression> GOTO <line number>                                   *) +(*                 [ELSE <statement(s)>|<line number>]                   *) +  SYMBOL VAR local expr result; +  next symbol; +  get expr (local expr result, int type); +  skip comma if there; +  IF symb.type = res word AND (symb.no = then s OR symb.no = goto s) +    THEN test expr result; +         IF symb.no = goto s +           THEN next symbol; +                if goto statement +         ELIF next symbol is stat no +           THEN if goto statement +           ELSE if then statement +         FI +  ELSE basic error (2, NAME symb, "THEN oder GOTO erwartet") FI  . + +skip comma if there: +  IF symb.no = comma AND symb.type = del +    THEN next symbol +  FI. + +test expr result: +  parameter (1, int type, const, local expr result.adr); +  parameter (2, bool type, var, nil adr);  apply (2, nop); +  apply (1, 1, test)  . + +next symbol is stat no: +  next symbol; +  symb.type = const AND symb.data = int type. + +if goto statement: +  SYMBOL VAR stat label; +  get const (stat label, int type); +  expect else if comma found; +  IF symb.type = res word AND symb.no = else s +    THEN apply (this label, FALSE); +         treat else case +  ELIF symb.type <> eos OR symb.no <> eol +    THEN declare (else label); +         apply (this label, FALSE); +         apply (else label); +         get basic line (else s); +         IF symb.type = eos AND symb.no = -else s +           THEN else statement +           ELSE define (else label) +         FI +    ELSE apply (this label, FALSE) +  FI. + +this label: label list [label pos (label no)]  . +label no:  stat label.name ISUB 1  . + +expect else if comma found: +  IF symb.type = del AND symb.no = comma +    THEN next symbol; +         IF symb.no <> else s OR symb.type <> res word +           THEN basic error (2, NAME symb, "ELSE erwartet") +         FI +  FI. + +treat else case: +  IF next symbol is stat no +    THEN get const (stat label, int type); +         apply (this label) +    ELSE get basic line +  FI. + +if then statement: +  LABEL VAR fi label; +  declare (else label); +  apply (else label, TRUE); +  get basic line (else s); + +  IF symb.type = eos AND symb.no = -else s +  THEN declare (fi label); +       apply (fi label); +       else statement; +       define (fi label) +  ELSE define (else label) FI  . + + +else statement: +  LABEL VAR else label; +  define (else label);  +  treat else case. + + +END PROC if statement; + +PROC on statement: +(*2.  ON <expression> GOSUB <list of line numbers>                       *) +(*3.  ON <expression> GOTO <list of line numbers>                        *) +  LABEL VAR before case, after case, return case; +  declare (before case); +  declare (after case); +  declare (return case); + +  next symbol; +  IF symb.type = res word AND symb.no = error s +    THEN basic error (100, symb.name, "") +  FI; +  get expr (expr result, int type); +  IF on gosub statement +  THEN gosub (before case); +       apply (after case) +  ELIF NOT on goto statement +  THEN basic error (2, symb.name, "GOTO oder GOSUB erwartet") FI; + +  get case stat no; +  define (before case); +  gen case branches; +  gen return case; +  define (after case)  . + +on gosub statement: +  BOOL CONST gosub found := symb.type = res word AND symb.no = gosub s; +  gosub found  . + +on goto statement: +  symb.type = res word AND symb.no = goto s. + +get case stat no: +  TEXT VAR case stat no :: nil; +  INT VAR case no :: 0; +  next symbol; +  REP get const (label, int type); +      case no INCR 1; +      case stat no CAT label.name; + +      IF symb.type = eos +      THEN LEAVE get case stat no +      ELSE skip (comma, del) FI +  PER  . + +gen case branches: +  computedbranch (expr result.adr, case no + 1, otherwise lab);  (* F6/rr *) +  apply (otherwise lab); +  FOR i FROM 1 UPTO case no +  REP apply (label i) PER  . + +gen return case: +  IF gosub found +  THEN define (return case); +       goret +  FI  . + +otherwise lab: +  IF gosub found +  THEN return case +  ELSE after case FI  . + +label i: +  label list [label pos (case stat no ISUB i)]  . + +END PROC on statement; + +PROC print statement: +(*PRINT [<list of expr results>]                                         *) +(*PRINT USING <string exp>;<list of expression>                          *) +(*PRINT #<file number>,<list of expr results>                            *)  +(*PRINT #<file number>, USING <string exp>;<list of expression>          *) +  next symbol; +  IF symb.type = del AND symb.no = numbersign +  THEN print file statement +  ELSE print display statement FI  . + +print file statement: +  basic error (100, symb.name, "")  . + +print display statement: +  get format string; +  print list of expr results; +  reset format string  . + +get format string: +  IF symb.type = res word AND symb.no = using s +  THEN next symbol; +       get expr (image, text type); +       skip (semicolon, del); +       parameter (1, text type, const, image.adr); +       apply (1, 1, "using"); +  ELSE image := nilsymbol FI  . + +reset format string: +  IF image.type <> any +  THEN apply (1, 0, "clearusing") FI  . + +print list of expr results: +  REP IF symb.type = res word AND symb.no = tab s +      THEN get tabulation +      ELIF symb.type = del AND symb.no = comma +      THEN get next zone +      ELIF symb.type = del AND symb.no = semicolon +      THEN get next pos +      ELIF symb.type = eos +      THEN apply (1, 0, "nextline"); +           LEAVE print list of expr results  +      ELSE get print expr result FI; +  PER  . + +get tabulation: +  next symbol; +  skip (open bracket, del); +  get expr (tab pos, int type); +  skip (close bracket, del); +  parameter (1, int type, const, tab pos.adr); +  apply (1, 1, "tab")  . + +get next zone: +  next symbol; +  IF image.type = any +  THEN apply (1, 0, "nextzone") FI; +  IF symb.type = eos +  THEN LEAVE print list of expr results FI  . + +get next pos: +  next symbol; +  IF symb.type = eos +  THEN LEAVE print list of expr results FI  . + +get print expr result: +  get expr (expr result); +  parameter (1, expr result.data, const, expr result.adr); +  apply (1, 1, "basicout")  . + +END PROC print statement; + +PROC while statement: +(*WHILE <expression>                                                     *) +  LABEL VAR while lab, wend lab; +  SYMBOL VAR while expr result; +  INT CONST  while stat no      := act stat no,                   (* F29/rr *) +             while scan line no := scan line no; +  TEXT CONST while symb name    := symb.name; +  next symbol; +  declare (while lab); +  declare (wend lab); + +  define (while lab); +  get expr (while expr result, int type); +  parameter (1, int type, const, while expr result.adr); +  parameter (2, bool type, const, nil adr);  apply (2, nop); +  apply (1, 1, test); +  apply (wend lab, TRUE);              (* 'test' vergleicht mit 0 *) + +  get statement group (wend s); +  IF symb.type = eos AND symb.no = -wend s +  THEN wend statement +  ELSE basic error ("Compiler", 29, while scan line no, while stat no, while symb name, "", TRUE) FI. (* F29/rr *) + +wend statement: +(*WEND                                                                   *) +  apply (while lab); +  define (wend lab); +  next symbol  . + +END PROC while statement; + +END PACKET basic compiler + diff --git a/lang/basic/1.8.7/src/BASIC.Runtime b/lang/basic/1.8.7/src/BASIC.Runtime new file mode 100644 index 0000000..854002a --- /dev/null +++ b/lang/basic/1.8.7/src/BASIC.Runtime @@ -0,0 +1,1571 @@ +(***************************************************************************) +(*                                                                         *) +(*           Erste von drei Dateien des EUMEL-BASIC-Systems                *) +(*                                                                         *) +(*           Autor: Heiko Indenbirken                                      *) +(*           Überarbeitet von: Rudolf Ruland und Michael Overdick          *) +(*                                                                         *) +(*           Stand: 27.10.1987                                             *) +(*                                                                         *) +(***************************************************************************) + +PACKET basic std DEFINES EQU, UEQ,            (* Autor: Heiko Indenbirken *) +                         LES, LEQ,            (* Stand: 23.10.1987/rr/mo  *) +                         GRE, GEQ, +                         EQV, IMP, +                         ^, swap, +                         val, asc, cdbl, chr, +                         cint, cvi, cvd, fre, +                         hex, inchars, +                         instr, ent, left, +                         mid, mki, mkd, +                         oct, right, +                         rnd, init rnd, +                         space, string,   +                         l set, r set, +                         int not, real not, +                         /, DIV, real mod, +                         time, timer, +                         arctan, cos, sin, tan, +                         exp, ln, floor, +                         sqrt: + + +INT CONST true := -1, +          false := 0; + +LET real overflow = 6; + + +(*BASIC-Integervergleiche                                                *) +INT OP EQU (INT CONST a, b): +  IF a=b +  THEN true +  ELSE false FI +END OP EQU; + +INT OP UEQ (INT CONST a, b): +  IF a=b +  THEN false +  ELSE true FI +END OP UEQ; + +INT OP LES (INT CONST a, b): +  IF a<b +  THEN true +  ELSE false FI +END OP LES; + +INT OP LEQ (INT CONST a, b): +  IF a<=b +  THEN true +  ELSE false FI +END OP LEQ; + +INT OP GRE (INT CONST a, b): +  IF a>b +  THEN true +  ELSE false FI +END OP GRE; + +INT OP GEQ (INT CONST a, b): +  IF a>=b +  THEN true +  ELSE false FI +END OP GEQ; + +(*BASIC-Realvergleiche                                                   *) +INT OP EQU (REAL CONST a, b): +  IF a=b +  THEN true +  ELSE false FI +END OP EQU; + +INT OP UEQ (REAL CONST a, b): +  IF a=b +  THEN false +  ELSE true FI +END OP UEQ; + +INT OP LES (REAL CONST a, b): +  IF a<b +  THEN true +  ELSE false FI +END OP LES; + +INT OP LEQ (REAL CONST a, b): +  IF a<=b +  THEN true +  ELSE false FI +END OP LEQ; + +INT OP GRE (REAL CONST a, b): +  IF a>b +  THEN true +  ELSE false FI +END OP GRE; + +INT OP GEQ (REAL CONST a, b): +  IF a>=b +  THEN true +  ELSE false FI +END OP GEQ; + +(*BASIC-Tesxtvergleiche                                                  *) +INT OP EQU (TEXT CONST a, b): +  IF a=b +  THEN true +  ELSE false FI +END OP EQU; + +INT OP UEQ (TEXT CONST a, b): +  IF a=b +  THEN false +  ELSE true FI +END OP UEQ; + +INT OP LES (TEXT CONST a, b): +  IF a<b +  THEN true +  ELSE false FI +END OP LES; + +INT OP LEQ (TEXT CONST a, b): +  IF a<=b +  THEN true +  ELSE false FI +END OP LEQ; + +INT OP GRE (TEXT CONST a, b): +  IF a>b +  THEN true +  ELSE false FI +END OP GRE; + +INT OP GEQ (TEXT CONST a, b): +  IF a>=b +  THEN true +  ELSE false FI +END OP GEQ; + + +(*BASIC         INTEGER / BOOL Operatoren                                *) +REAL PROC real not (REAL CONST a):          (* mo *) +  real (int (a) XOR -1) +END PROC real not; + +INT PROC int not (INT CONST a):             (* mo *) +  a XOR -1 +END PROC int not; + +INT OP EQV (INT CONST l, r): +  int not (l XOR r) +END OP EQV; + +INT OP IMP (INT CONST l, r): +  (l EQV r) OR r +END OP IMP; + +LET smallest significant = 5.0e-12; +REAL OP ^ (REAL CONST x, y):                                  (* F22/rr *) +  IF   x > 0.0 +       THEN x ** y +  ELIF x = 0.0 +       THEN IF   y > 0.0 +                 THEN 0.0 +            ELIF y = 0.0 +                 THEN 1.0 +                 ELSE errorstop (real overflow, ""); +                      max real +            FI +       ELSE REAL VAR floor y := floor (y + round value);             +            IF   (abs (y - floor y) > smallest significant) +                      COR (floor y = 0.0 AND y <> 0.0) +                 THEN errorstop (1005, "bei " + text (x) + +                                        " ^ " + text (y, 19) + +                                        " : neg. Basis, gebr. Exponent"); +                      0.0 +            ELIF (floor y MOD 2.0) = 0.0 +                 THEN     (-x) ** floor y +                 ELSE - ( (-x) ** floor y ) +            FI +  FI . + +  round value : IF y >= 0.0 THEN 0.5 ELSE -0.5 FI . + +END OP ^; + +REAL OP ^ (INT CONST x, y): +  real (x) ** y +END OP ^; + +REAL OP / (INT CONST l, r):                 (* mo *) +  real (l) / real (r) +END OP /; + +INT OP DIV (REAL CONST l, r):               (* mo *) +  cint (l) DIV cint (r) +END OP DIV; + +REAL PROC real mod (REAL CONST l, r):       (* mo *) +  round (l, 0) MOD round (r, 0) +END PROC real mod; + +(*                            Basic Arithmetik                           *) +REAL VAR r swap; +PROC swap (REAL VAR left, right): +  r swap := left; +  left := right; +  right := r swap +END PROC swap; + +INT VAR i swap; +PROC swap (INT VAR left, right): +  i swap := left; +  left := right; +  right := i swap +END PROC swap; + +TEXT VAR t swap; +PROC swap (TEXT VAR left, right): +  t swap := left; +  left := right; +  right := t swap +END PROC swap; + +(*Internkonvertierungen                                                  *) +INT PROC cvi (TEXT CONST v): +  v ISUB 1 +END PROC cvi; + +REAL PROC cvd (TEXT CONST v): +  v RSUB 1 +END PROC cvd; + +TEXT VAR i text :: 2*""0"", r text :: 8*""0""; +TEXT PROC mki (REAL CONST x): +  mki (cint (x)) +END PROC mki; + +TEXT PROC mki (INT CONST i): +  replace (i text, 1, i); +  i text +END PROC mki; + +TEXT PROC mkd (INT CONST i): +  mkd (real (i)) +END PROC mkd; + +TEXT PROC mkd (REAL CONST r): +  replace (r text, 1, r); +  r text +END PROC mkd; + +(*Textoperationen                                                        *) +PROC l set (TEXT VAR left, TEXT CONST right): +  replace (left, 1, right) +END PROC l set; + +PROC r set (TEXT VAR left, TEXT CONST right): +  replace (left, length (left)-length (right)+1, right) +END PROC r set; + +TEXT PROC left (TEXT CONST string, REAL CONST no): +  left (string, cint (no)) +END PROC left; + +TEXT PROC left (TEXT CONST string, INT CONST no): +  subtext (string, 1, no) +END PROC left; + +TEXT PROC right (TEXT CONST string, REAL CONST no): +  right (string, cint (no)) +END PROC right; + +TEXT PROC right (TEXT CONST string, INT CONST no): +  subtext (string, length (string)-no+1) +END PROC right; + +TEXT PROC mid (TEXT CONST source, REAL CONST from): +  mid (source, cint (from)) +END PROC mid; + +TEXT PROC mid (TEXT CONST source, INT CONST from): +  subtext (source, from) +END PROC mid; + +TEXT PROC mid (TEXT CONST source, REAL CONST from, length): +  mid (source, cint (from), cint (length)) +END PROC mid; + +TEXT PROC mid (TEXT CONST source, INT CONST from, length): +  subtext (source, from, from+length-1) +END PROC mid; + +TEXT PROC string (REAL CONST x, y): +  string (cint (x), cint (y)) +END PROC string; + +TEXT PROC string (INT CONST x, REAL CONST y): +  string (x, cint (y)) +END PROC string; + +TEXT PROC string (REAL CONST x, INT CONST y): +  string (cint (x), y) +END PROC string; + +TEXT PROC string (INT CONST i, j): +  i * code (j) +END PROC string; + +TEXT PROC string (REAL CONST i, TEXT CONST x): +  string (cint (i), x) +END PROC string; + +TEXT PROC string (INT CONST i, TEXT CONST x): +  i * (x SUB 1) +END PROC string; + +(*Konvertierungen                                                       *) + +REAL PROC val (TEXT CONST text) :                               (* F18/rr *) + +  TEXT VAR buffer := text; +  change (buffer, "d", "e"); +  change (buffer, "D", "e"); +  change (buffer, "E", "e"); +  real (buffer) + +END PROC val; + +REAL PROC asc (TEXT CONST text): +  real (code (text SUB 1)) +END PROC asc; + +TEXT PROC chr (INT CONST n): +  code (n) +END PROC chr; + +TEXT PROC chr (REAL CONST n): +  code (cint (n)) +END PROC chr; + +TEXT PROC hex (REAL CONST x): +  hex (cint (x)) +END PROC hex; + +TEXT PROC hex (INT CONST x): +  TEXT VAR value :: "12"; +  replace (value, 1, x); +  high byte + low byte  . + +low byte: +  hexdigit (code (value SUB 1) DIV 16) + hexdigit (code (value SUB 1) MOD 16)  . + +high byte: +  IF (value SUB 2) = ""0"" +  THEN "" +  ELSE hexdigit (code (value SUB 2) DIV 16) + +       hexdigit (code (value SUB 2) MOD 16)  +  FI  . + +END PROC hex; + +TEXT PROC oct (REAL CONST x): +  oct (cint (x)) +END PROC oct; + +TEXT PROC oct (INT CONST x): +  INT VAR number :: x AND maxint; +  generate oct number; +  IF x < 0 +    THEN "1" + oct number +    ELSE subtext (oct number, pos (oct number, "1", "7", 1)) +  FI. + +generate oct number: +  TEXT VAR oct number :: ""; +  INT VAR digit; +  FOR digit FROM 1 UPTO 5 REP +    oct number := hexdigit (number MOD 8) + oct number; +    number := number DIV 8 +  PER. + +END PROC oct; + +TEXT PROC hexdigit (INT CONST digit): +  IF 0 <= digit AND digit <= 9 +  THEN code (digit + 48) +  ELIF 10 <= digit AND digit <= 15 +  THEN code (digit + 55) +  ELSE errorstop (1051, "Hexziffer außerhalb des gültigen Bereichs"); "" FI +END PROC hexdigit; + +TEXT PROC inchars (REAL CONST n): +  inchars (cint (n)) +END PROC inchars; + +TEXT PROC inchars (INT CONST n): +  TEXT VAR buffer :: "", char; +  INT VAR i; +  FOR i FROM 1 UPTO n +  REP inchar (char); +      buffer CAT char +  PER; +  buffer + +END PROC inchars; + +(*Mathematische Prozeduren                                               *) +REAL PROC ent (INT CONST r): +  real (r) +END PROC ent; + +REAL PROC ent (REAL CONST r): +  IF r >= 0.0 OR frac (r) = 0.0 +  THEN floor (r) +  ELSE floor (r-1.0) FI +END PROC ent; + +REAL PROC cdbl (INT CONST r): +  real (r) +END PROC cdbl; + +REAL PROC cdbl (REAL CONST r): +  r +END PROC cdbl; + +INT PROC cint (INT CONST r): +  r +END PROC cint; + +INT PROC cint (REAL CONST r): +  IF r >= 0.0 +  THEN int (r+0.5) +  ELSE int (r-0.5) FI +END PROC cint; + +REAL VAR last rnd :: rnd (1.0); +REAL PROC rnd (INT CONST x): +  rnd (real (x)) +END PROC rnd; + +REAL PROC rnd (REAL CONST x): +  IF x > 0.0 +  THEN last rnd := random; +       last rnd +  ELIF x = 0.0 +  THEN last rnd +  ELSE init rnd (x); +       last rnd := random; +       last rnd +  FI + +END PROC rnd; + +REAL PROC rnd: +  rnd (1.0) +END PROC rnd; + +PROC init rnd (REAL CONST init value) : + +  REAL VAR init := init value; +  IF init <= -1.0 OR 1.0 <= init +     THEN set exp (- decimal exponent (init) - 1, init) FI;  +  initialize random (init)  + +END PROC init rnd; + + +REAL PROC fre (TEXT CONST dummy): +  INT VAR f, u; +  collect heap garbage; +  storage (f, u); + +  real (f - u) * 1024.0 +END PROC fre; + +REAL PROC fre (REAL CONST dummy): +  fre ("") +END PROC fre; + +REAL PROC fre (INT CONST dummy): +  fre ("") +END PROC fre; + +(*Inputroutinenen                                                        *) +INT PROC instr (TEXT CONST source, pattern): +  pos (source, pattern) +END PROC instr; + +INT PROC instr (REAL CONST from, TEXT CONST source, pattern): +  instr (cint (from), source, pattern) +END PROC instr; + +INT PROC instr (INT CONST from, TEXT CONST source, pattern): +  pos (source, pattern, from) +END PROC instr; + +TEXT PROC space (REAL CONST len): +  space (cint (len)) +END PROC space; + +TEXT PROC space (INT CONST len): +  len * " " +END PROC space; + +TEXT PROC time:                                        (* mo *) +  subtext (time (clock (1) MOD day), 1, 8)          (* hh:mm:ss *) +END PROC time; + +REAL PROC timer: +  clock (0) +END PROC timer; + +REAL PROC arctan (INT CONST x): +  arctan (real (x)) +END PROC arctan; + +REAL PROC cos (INT CONST x): +  cos (real (x)) +END PROC cos; + +REAL PROC sin (INT CONST x): +  sin (real (x)) +END PROC sin; + +REAL PROC tan (INT CONST x): +  tan (real (x)) +END PROC tan; + +REAL PROC exp (INT CONST x): +  exp (real (x)) +END PROC exp; + +REAL PROC ln (INT CONST x): +  ln (real (x)) +END PROC ln; + +REAL PROC floor (INT CONST x): +  real (x) +END PROC floor; + +REAL PROC sqrt (INT CONST x): +  sqrt (real (x)) +END PROC sqrt; + +END PACKET basic std; + +PACKET basic using DEFINES using,             (* Autor: Heiko Indenbirken *) +                           clear using,       (* Stand: 05.08.1987/rr/mo  *) +                           basic text: + + +LET exclamation point = "!", +    backslash         = "\", +    comercial and     = "&", +    numbersign        = "#", +    plus              = "+", +    minus             = "-", +    asterisk dollar   = "**$", +    asterisk          = "**", +    dollarsign        = "$$", +    comma             = ",", +    point             = ".", +    caret             = "^^^^", +    underscore        = "_", +    blank             = " ", +    nil               = "", + +    number format chars = "#+-*$.^", +    format chars        = "!\&#+-$*."; + +TEXT VAR result, using format :: "", pre format :: ""; +INT VAR using pos :: 0; +BOOL VAR image used :: FALSE; + +PROC using (TEXT CONST format): +  using format := format; +  using pos := 0; +  result := ""; +  image used := TRUE + +END PROC using; + +PROC clear using: +  using format := ""; +  image used := FALSE +END PROC clear using; + +TEXT PROC next format: +  pre format := ""; +  IF using pos = 0 +  THEN "" +  ELSE search rest of format FI  . + +search rest of format: +  WHILE using pos <= length (using format) +  REP IF at underscore +      THEN using pos INCR 1; +           pre format CAT akt char +      ELIF at format char +      THEN LEAVE next format WITH pre format +      ELSE pre format CAT akt char FI; +      using pos INCR 1 +  PER; +  using pos := 0; +  pre format  . +  +at underscore: +  akt char = underscore  . + +at format char: +  pos (format chars, akt char) > 0 CAND +  evtl double asterisk CAND +  evtl point with numbersign  . + +evtl double asterisk: +  akt char <> asterisk COR next char = asterisk  . + +evtl point with numbersign: +  akt char <> point COR next char = numbersign  . + +akt char: using format SUB using pos  . +next char: using format SUB using pos+1  . +END PROC next format; + +PROC init (TEXT VAR l result): +  IF using pos = 0 +  THEN using pos := 1; +       l result := next format; +       IF using pos = 0 +       THEN errorstop (1005, "USING: kein Format gefunden") FI +  ELSE l result := "" FI + +END PROC init; + +TEXT PROC basic text (TEXT CONST string): +  IF image used +  THEN using text +  ELSE string FI  . + +using text: +  init (result); +  result CAT format string; +  using pos INCR 1; +  result CAT next format; +  result  . + +format string: +  IF akt char = exclamation point +  THEN string SUB 1 +  ELIF akt char = backslash +  THEN given length string +  ELIF akt char = comercial and +  THEN string +  ELSE errorstop (1005, "USING-Format fehlerhaft: " + using format); ""  FI  . + +given length string: +  INT VAR len :: 2; +  FOR using pos FROM using pos+1 UPTO length (using format) +  REP IF akt char = "\" +      THEN LEAVE given length string WITH text (string, len) FI; +      len INCR 1 +  UNTIL akt char <> " "PER; +  errorstop (1005, "USING-Format fehlerhaft: " + using format); +  ""  . + +akt char: using format SUB using pos +END PROC basic text; +  +TEXT PROC basic text (INT CONST number): +  IF image used +  THEN basic text (real (number)) +  ELSE sign + text (number) FI  . + +sign: +  IF number >= 0 +  THEN " " +  ELSE "" FI  . + +END PROC basic text; + +TEXT PROC basic text (REAL CONST number): +  IF image used +  THEN using text +  ELSE normal text FI  . + +normal text: +(*   Bei Real Zahlen werden maximal 7 signifikante Stellen ausgegeben,   *) +(*          führende und nachfolgende Nullen werden unterdrückt,         *) +(*           der Dezimalpunkt wird im Normalformat unterdrückt           *) +  calculate sign; +  REAL VAR mantissa := round (abs (number), 6-decimal exponent (number)); +  INT CONST exp :: decimal exponent (mantissa); + +  IF mantissa = 0.0 +  THEN result := " 0" +  ELIF exp > 6 OR exp < -7 OR (exp < 0 AND more than 7 signifikant digits) +  THEN scientific notation +  ELIF exp < 0 +  THEN short negative notation +  ELSE short positive notation FI; +  result  . + +more than 7 signifikant digits: +   REAL VAR signifikant := mantissa; +   set exp (7+exp, signifikant); +   frac (signifikant) <> 0.0  . + +calculate sign: +  IF number >= 0.0 +  THEN result := " " +  ELSE result := "-" FI  . + +scientific notation: +  set exp (0, mantissa); +  result CAT non zero (text (mantissa, 8, 6)); + +  IF exp < 0 +  THEN result CAT "E-" +  ELSE result CAT "E+" FI; + +  IF abs (exp) > 9 +  THEN result CAT text (abs (exp)) +  ELSE result CAT "0"; +       result CAT text (abs (exp)) +  FI  . + +short positive notation: +  result CAT non zero (text (mantissa, 8, 6-exp)); +  IF (result SUB LENGTH result) = "." +  THEN delete char (result, LENGTH result) FI  . + +short negative notation: +  result CAT non zero (subtext (text (abs (mantissa), 9, 7), 2)).(* F13/rr *) + +using text: +  init (result); +  result CAT format number (subformat, number); +  result CAT next format; +  result  . + +subformat: +  INT VAR from :: using pos, to :: last format char; +  subtext (using format, from, to)  . + +last format char: +  FOR using pos FROM using pos+1 UPTO length (using format) +  REP IF non format char +      THEN LEAVE last format char WITH using pos-1 FI +  PER; +  using pos := 0; +  length (using format)  . + +non format char: +  IF (using format SUB using pos) = comma +  THEN (using format SUB (using pos+1)) <> point +  ELSE pos (numberformat chars, using format SUB using pos) = 0  FI  . + +END PROC basic text; + +TEXT PROC non zero (TEXT CONST text): +  INT VAR i; +  FOR i FROM length (text) DOWNTO 2 +  REP UNTIL (text SUB i) <> "0" PER; +  subtext (text, 1, i) +END PROC non zero; + +TEXT PROC format number (TEXT CONST format, REAL CONST number): +  IF no digit char +  THEN errorstop (1005, "USING-Format fehlerhaft: " + using format);  "" +  ELIF exponent found +  THEN exponent format +  ELSE normal format FI  . + +no digit char: +  pos (format, numbersign) = 0 AND +  pos (format, asterisk) = 0 AND +  pos (format, dollarsign) = 0  . + +exponent found: +  INT CONST exponent pos := pos (format, caret); +  exponent pos > 0  . + +exponent format: +  IF leading plus +  THEN plus or minus + exponent field (subtext (format, 2), number, exponent pos-1)  +  ELIF trailing plus +  THEN exponent field (format, number, exponent pos) + plus or minus  +  ELIF trailing minus +  THEN exponent field (format, number, exponent pos) + nil or minus  +  ELSE blank or minus + exponent field (subtext (format, 2), number, exponent pos-1) FI  . + +normal format: +  IF leading numbersign +  THEN number field (format, number, "", " ") +  ELIF leading point +  THEN number field (format, number, "", " ") +  ELIF leading plus  +  THEN number field (format, abs (number), plus or minus, " ") +  ELIF leading asterisk dollar +  THEN number field (format, number, "$", "*") +  ELIF leading asterisk  +  THEN number field (format, number, "", "*") +  ELIF leading dollarsign +  THEN number field (format, number, "$", " ") +  ELSE errorstop (1005, "USING-Format fehlerhaft: " + using format); "" FI  .  +  +leading numbersign:      (format SUB 1) = numbersign  . +leading point:           (format SUB 1) = point  . +leading plus:            (format SUB 1) = plus  . +leading asterisk dollar: subtext (format, 1, 3) = asterisk dollar  . +leading asterisk:        subtext (format, 1, 2) = asterisk  . +leading dollarsign:      subtext (format, 1, 2) = dollarsign  . + +trailing minus: (format SUB LENGTH format) = minus   . +trailing plus:  (format SUB LENGTH format) = plus  . + +plus or minus:  IF number < 0.0 THEN minus ELSE plus FI  . +nil or minus:   IF number < 0.0 THEN minus ELSE nil FI  . +blank or minus: IF number < 0.0 THEN minus ELSE blank FI . + +END PROC format number; + +TEXT PROC exponent field (TEXT CONST format, REAL CONST value, INT CONST exponent pos): +  REAL VAR number := abs (value); +  INT CONST point pos := pos (format, point); +  calc leading and trailing; +  INT CONST new exponent :: decimal exponent (value) - leading + 1; +  IF abs (new exponent) >= 100 +    THEN "%" + mantissa + "E" + null text (new exponent, 4) +    ELSE mantissa + exponent +  FI. + +calc leading and trailing: +  INT VAR leading, trailing; +  IF point pos = 0 +  THEN leading := exponent pos-1; +       trailing := 0 +  ELSE leading := point pos-1; +       trailing := exponent pos-point pos-1 +  FI  . + +mantissa: +  set exp (leading - 1, number); +  IF point pos = 0 +  THEN subtext (text (number, leading+1, 0), 1, leading) +  ELSE subtext (text (number, leading+trailing+2, trailing), 2) FI  . + +exponent: +  "E" + null text (new exponent, 3)  . + +END PROC exponent field; + +TEXT PROC number field (TEXT CONST format, REAL CONST value, +                        TEXT CONST pretext, lead char): +  INT CONST point pos :: pos (format, point); +  calc fraction; +  calc digits; +  calc commata if necessary; +  fill with lead chars and sign  . + +calc fraction: +  INT VAR fraction :: 0, i; +  FOR i FROM point pos+1 UPTO length (format) +  WHILE (format SUB i) = numbersign +  REP fraction INCR 1 PER  . + +calc digits: +  TEXT VAR valuetext; +  IF point pos = 0 +  THEN valuetext := digits (abs (value), 0, TRUE); +       delete char (valuetext, length (valuetext)) +  ELSE valuetext := digits (abs (value), fraction, point pos <> 1) FI  . + +calc commata if necessary: +  IF comma before point +  THEN insert commata FI  . + +comma before point: +  point pos > 0 CAND (format SUB point pos-1) = comma   . + +insert commata: +  i := pos (valuetext, point)-3; +  WHILE i > 1 CAND (valuetext SUB i) <> " " +  REP insert char (valuetext, ",", i); +      i DECR 3 +  PER  . + +fill with lead chars and sign: +  IF trailing minus +  THEN fillby (pretext + valuetext, length (format)-1, lead char) + nil or minus +  ELIF trailing plus +  THEN fillby (pretext + valuetext, length (format)-1, lead char) + plus or minus +  ELIF value < 0.0 +  THEN fillby (pretext + minus + valuetext, length (format), lead char) +  ELSE fillby (pretext + valuetext, length (format), lead char) FI  . + + +plus or minus:  IF value < 0.0 THEN minus ELSE plus FI  . +nil or minus:   IF value < 0.0 THEN minus ELSE nil FI  . +trailing minus: (format SUB LENGTH format) = minus   . +trailing plus:  (format SUB LENGTH format) = plus  . +END PROC numberfield; + +TEXT PROC null text (INT CONST n, digits): +  TEXT VAR l result := text (abs (n), digits); +  IF n < 0 +  THEN replace (l result, 1, "-") +  ELSE replace (l result, 1, "+") FI; +  change all (l result, " ", "0"); +  l result  . +END PROC null text; + +TEXT PROC fillby (TEXT CONST source, INT CONST format, TEXT CONST with): +  IF differenz >= 0 +  THEN differenz * with + source +  ELSE "%" + source FI  . + +differenz:  format - length (source)  . +END PROC fillby; + +TEXT PROC digits (REAL CONST value, INT CONST frac, BOOL CONST null): +  IF decimal exponent (value) < 0 +  THEN TEXT VAR l result := text (value, frac+2, frac); + +       IF null AND first char <> "0" +       THEN replace (l result, 1, "0"); +            l result +       ELIF (NOT null AND first char = "0") OR first char = " " +       THEN subtext (l result, 2) +       ELSE l result FI +  ELSE text (value, decimal exponent (value)+frac+2, frac) FI  . + +first char: +  (l result SUB 1)  . + +END PROC digits; + +TEXT PROC right (TEXT CONST msg, INT CONST len): +  IF length (msg) >= len +  THEN subtext (msg, 1, len) +  ELSE (len - length (msg)) * " " + msg FI + +END PROC right; + +END PACKET basic using; + +PACKET basic output                          (* Autor: R. Ruland        *) +                                             (* Stand: 28.08.1987/rr/mo *) +       DEFINES basic page, +               width,            +               init output,      +               basic out, +               basic write, +               tab, +               next zone, +               next line, +               next page, +               cursor x pos, +               pos, +               csrlin, +               l pos, +               switch to printout file, +               switch back to old sysout state: + +LET zone width = 16;  (*  sd.ddddddEsdddb  (s = sign, d = digit, b = blank) *) +LET printfile name = "BASIC LPRINT OUTPUT"; + +INT VAR screen width, x cursor, y cursor, line no; +BOOL VAR paging := FALSE, first time, +         in lprint;     (* mo *) +TEXT VAR buffer, output line, last sysout file, old sysout, char; + +PROC basic page (BOOL CONST status): + +  paging := status + +END PROC basic page; + +BOOL PROC basic page:  paging  END PROC basic page; + + +PROC width (INT CONST max): + +  IF   max < 0 +       THEN errorstop (1005, "WIDTH: negatives Angabe: " + text (max)) +  ELIF max = 0 +       THEN screen width := 1 +       ELSE screen width := max +  FI; +  last sysout file := ""; + +END PROC width; + +INT PROC width :  screen width  END PROC width; + + +PROC init output: + +  clear using; +  width (max (1, x size)); +  line no      := 1; +  output line  := ""; +  first time   := TRUE; +  in lprint := FALSE + +END PROC init output; + + +PROC basic out (INT  CONST i):   bas out (basic text (i) + " ")  END PROC basic out; +  +PROC basic out (REAL CONST r):   bas out (basic text (r) + " ")  END PROC basic out; +  +PROC basic out (TEXT CONST t):   bas out (basic text (t))        END PROC basic out; + +PROC basic write (INT  CONST i): bas out (basic text (i))  END PROC basic write; + +PROC basic write (REAL CONST r): bas out (basic text (r))  END PROC basic write; + +PROC basic write (TEXT CONST t): bas out (basic text ("""" + t + """"))  END PROC basic write; + +  +PROC bas out (TEXT CONST msg): + +  get cursor; +  IF length (msg) > free +     THEN IF first time +             THEN first time := FALSE; +                  next line; +                  bas out (msg); +             ELSE buffer := subtext (msg, 1, free); +                  IF sysout = "" +                    THEN out (buffer) +                    ELSE sysout write (buffer) +                  FI; +                  next line; +                  buffer := subtext (msg, free + 1); +                  bas out (buffer); +          FI; +     ELSE first time := TRUE; +          IF sysout = "" +            THEN out (msg) +            ELSE sysout write (msg) +          FI; +  FI; + +  . free : screen width - x cursor + 1 + +END PROC bas out; + + +PROC tab (INT CONST n): + +  get cursor; +  IF   n <= 0 +       THEN tab position out of range +  ELIF n > screen width +       THEN tab (n MOD screen width); +  ELIF x cursor > n +       THEN next line; +            tab (n); +  ELIF sysout = "" +       THEN cursor (n, y cursor); +       ELSE buffer := (n - x cursor) * " "; +            sysout write (buffer) +  FI; + +  . tab position out of range : +      IF x cursor <> 1 THEN next line FI; +      write ("WARNUNG : TAB-Position <= 0"); +      next line; + +END PROC tab; + + +PROC next zone: + +  get cursor; +  IF   x cursor > screen width - zone width +       THEN next line; +  ELIF sysout = "" +       THEN free TIMESOUT " "; +       ELSE buffer := free * " "; +            sysout write (buffer) +  FI; + +  . free : ((x cursor - 1) DIV zone width + 1) * zone width - x cursor + 1 + +END PROC next zone; + + +PROC next line : + +  IF sysout = "" +     THEN next line on screen +     ELSE line; +          write ("");              (* generates new record *) +          output line := ""; +  FI; + +  . next line on screen: +      line no INCR 1; +      IF paging CAND line no > y size +        THEN IF in last line +               THEN warte; +               ELSE out (""13""10""); +                    line no := y cursor + 1; +             FI; +      ELIF NOT paging +        THEN char := incharety; +             IF char <> "" +               THEN IF char = "+" +                      THEN paging := TRUE +                      ELSE type (char) +                    FI +             FI; +             out (""13""10"") +        ELSE out (""13""10"") +      FI + +  . in last line : +      get cursor; +      y cursor = y size + +  . warte : +      cursor (x size - 2, y size); +      out (">>"); +      inchar (char); +      IF   char = ""13"" +           THEN next page +      ELIF char = ""10"" +           THEN out (""8""8"  "13""10"")  +      ELIF char = ""27"" +           THEN clear editor buffer; +                errorstop (1, "") +      ELIF char = "-" +           THEN out (""8""8"  "13""10""); +                line no := 1; +                paging  := FALSE; +           ELSE out (""8""8"  "13""10""); +                line no := 1; +      FI; + +      . clear editor buffer: +          REP UNTIL get charety = "" PER; + +END PROC next line; + + +PROC next page: + +  IF sysout = "" +    THEN out (""1""4"") +    ELSE line +  FI; +  clear using; +  line no     := 1; +  output line := ""; + +END PROC next page; + + +INT PROC pos (REAL CONST dummy):           (* mo *) + +  cursor x pos + +END PROC pos; + + +INT PROC pos (INT CONST dummy):            (* mo *) + +  cursor x pos + +END PROC pos; + + +INT PROC cursor x pos : + +  get cursor; +  x cursor + +END PROC cursor x pos; + + +INT PROC csrlin:                              (* mo *) + +  get cursor; +  y cursor + +END PROC csrlin; + + +PROC get cursor : + +  IF sysout = "" +     THEN get cursor (x cursor, y cursor); +     ELSE x cursor := LENGTH output line + 1; +  FI; + +END PROC get cursor; + + +INT PROC l pos (REAL CONST dummy):                   (* mo *) + +  l pos (0) + +END PROC l pos; + + +INT PROC l pos (INT CONST dummy):                    (* mo *) + +  INT VAR lprint position :: 1; +  IF exists (printfile name) +    THEN disable stop; +         FILE VAR printfile :: sequential file (modify, printfile name); +         IF lines (printfile) > 0 +           THEN to line (printfile, lines (printfile)); +                lprint position := len (printfile) + 1 +         FI; +         output (printfile) +  FI; +  lprint position + +END PROC l pos; + + +PROC switch to printout file:                       (* mo *) + +  in lprint := TRUE; +  old sysout := sysout; +  careful sysout (printfile name); + +END PROC switch to printout file; + + +PROC switch back to old sysout state:               (* mo *) + +  IF in lprint +    THEN careful sysout (old sysout); +         in lprint := FALSE +  FI + +END PROC switch back to old sysout state; + + +PROC sysout write (TEXT CONST string): +  check sysout; +  write (string); +  output line CAT string. + +check sysout: +  IF sysout <> last sysout file +    THEN careful sysout (sysout) +  FI. + +END PROC sysout write; + + +PROC careful sysout (TEXT CONST new sysout):                  (* mo *) + +IF new sysout <> "" +  THEN disable stop; +       FILE VAR outfile :: sequential file (modify, new sysout); +       max line length (outfile, screen width); +       last sysout file := sysout; +       IF lines (outfile) > 0 +         THEN to line (outfile, lines (outfile)); +              read record (outfile, output line); +              delete record (outfile) +         ELSE output line := "" +       FI; +       sysout (new sysout); +       write (output line); +  ELSE sysout ("") +FI + +END PROC careful sysout; + +END PACKET basic output; + + +PACKET basic input                              (* Autor: R. Ruland        *) +                                                (* Stand: 27.10.1987/rr/mo *) + +       DEFINES init input, +               read input,        +               check input, +               assign input, +               assign input line, +               input ok, +               input eof:             + + +LET comma             = ",", +    quote             = """", + +    wrong type        = 1, +    insufficient data = 2, +    too much data     = 3, +    overflow          = 4, + +    int overflow      = 4, +    real overflow     = 6; + +INT VAR input line pos, input error no; +BOOL VAR on terminal; +TEXT VAR input line :: "", previous input line := "", input value; + +. first quote found : (input value SUB 1) = quote +.; + +PROC init input : + +  input error no      := 0; +  input line pos      := 0; +  input line          := ""; +  previous input line := ""; + +END PROC init input; + + +PROC read input (BOOL CONST cr lf, TEXT CONST msg, BOOL CONST question mark): + +  on terminal := sysout <> "" AND sysin = ""; +  check input error; +  out string (msg); +  IF question mark THEN out string ("? ") FI; +  IF sysin <> "" +     THEN getline (input line); +     ELSE editget input line; +  FI; +  out string (input line); +  IF crlf THEN out line FI; +  input line pos := 0; +  input error no := 0; + +  . check input error : +      IF input error no = 0 +         THEN input line := ""; +         ELSE IF sysin = "" +                 THEN BOOL CONST old basic page := basic page; +                      basic page (FALSE); +                      IF cursor x pos <> 1 THEN next line FI; +                      basic out ("?Eingabe wiederholen ! (" + error text + ")"); +                      next line; +                      basic page (old basic page); +                 ELSE errorstop (1080,"INPUT-Fehler (" + error text + +                                               ") : >" + input line + "<"); +              FI; +       FI; + +       . error text : +           SELECT input error no OF +             CASE wrong type        : "falscher Typ" +             CASE insufficient data : "zu wenig Daten" +             CASE too much data     : "zu viele Daten" +             CASE overflow          : "Überlauf" +                          OTHERWISE : "" +           END SELECT + +  . editget input line : +      TEXT VAR exit char; +      INT VAR x, y; +      get cursor (x, y); +      REP IF width - x < 1 +            THEN out (""13""10""); +                 get cursor (x, y) +          FI; +          editget (input line, max text length, width - x, "", "k", exit char); +          cursor (x, y); +          IF exit char = ""27"k" +             THEN input line := previous input line; +             ELSE previous input line := input line; +                  LEAVE editget input line; +          FI; +      PER; +       +END PROC read input; + + +PROC out string (TEXT CONST string) : + +  basic out (string); +  IF on terminal THEN out (string) FI; + +END PROC out string; + + +PROC out line : + +  next line; +  IF on terminal THEN out (""13""10"") FI; + +END PROC out line; + + +BOOL PROC check input (INT CONST type) : + +  get next input value; +  input value := compress (input value); +  set conversion (TRUE); +  SELECT type OF +    CASE 1 : check int input +    CASE 2 : check real input +    CASE 3 : check text input +  END SELECT; +  IF NOT last conversion ok THEN input error no := wrong type FI; +  input error no = 0 + +  . check int input : +      IF input value <> "" +         THEN disable stop; +              INT VAR help int value; +              help int value := int (input value); +              IF is error CAND error code = int overflow +                 THEN clear error; +                      input error no := overflow; +              FI; +              enable stop; +      FI; + +  . check real input : +      IF input value <> "" +         THEN disable stop; +              REAL VAR help real value; +              help real value := val (input value); +              IF is error CAND (error code = real overflow +                                OR error code = int overflow) (* <-- Aufgrund eines Fehlers in 'real' *) +                 THEN clear error; +                      input error no := overflow; +              FI; +              enable stop; +        FI; + +  . check text input : +      (* IF input value = "" THEN input error no := wrong type FI; *) +      IF NOT is quoted string CAND quote found +         THEN input error no := wrong type +      FI;  + +      . is quoted string : +          first quote found CAND last quote found + +          . last quote found : +              (input value SUB LENGTH input value) = quote + +      . quote found : +          pos (input value, quote) > 0 + +END PROC check input; + + +PROC assign input (INT VAR int value) : + +  get next input value; +  int value := int (input value); + +END PROC assign input; + +PROC assign input (REAL VAR real value) : + +  get next input value; +  real value := val (input value); + +END PROC assign input; + +PROC assign input (TEXT VAR string value) : + +  get next input value; +  input value := compress (input value); +  IF first quote found +     THEN string value := subtext (input value, 2, LENGTH input value -1) +     ELSE string value := input value +  FI; + +END PROC assign input; + +PROC assign input line (TEXT VAR string line) : + +  string line := input line; + +END PROC assign input line; + + +PROC get next input value :                                  (* F27/rr *) + +  IF input line pos > LENGTH input line  +     THEN input value    := ""; +          input error no := insufficient data; +     ELSE IF next non blank char = quote +             THEN get quoted string +             ELSE get unquoted string +          FI; +  FI; + +  . next non blank char : +      INT CONST next non blank char pos := pos (input line, ""33"", ""255"", input line pos + 1); +      input line SUB next non blank char pos + +  . get quoted string : +      INT CONST quote pos := pos (input line, quote, next non blank char pos + 1); +      IF quote pos = 0 +         THEN input value    := subtext (input line, next non blank char pos); +              input line pos := LENGTH input line + 1; +              input error no := wrong type; +         ELSE input value    := subtext (input line, next non blank char pos, quote pos); +              input line pos := pos (input line, ""33"", ""255"", quote pos + 1); +              IF   input line pos = 0 +                   THEN input line pos := LENGTH input line + 1; +              ELIF (input line SUB input line pos) <> comma +                   THEN input error no := wrong type; +                        input line pos DECR 1; +              FI; +      FI; + +  . get unquoted string : +      INT VAR comma pos := pos (input line, comma, input line pos + 1); +      IF comma pos = 0 +         THEN input value    := subtext (input line, input line pos + 1); +              input line pos := LENGTH input line + 1; +         ELSE input value    := subtext (input line, input line pos + 1, comma pos - 1); +              input line pos := comma pos; +      FI; + +END PROC get next input value; + + +BOOL PROC input ok: + +  IF input line pos <= LENGTH input line +     THEN input error no := too much data FI; +  input line pos := 0; +  input error no = 0 + +END PROC input ok; + +BOOL PROC input eof:  input line = ""  END PROC input eof; + + +END PACKET basic input;  + +PACKET basic std using io                         (* Autor: R. Ruland      *) +                                                  (* Stand: 26.10.87/rr/mo *) + +       DEFINES init rnd: + + +PROC init rnd: + +  REAL VAR init; +  REP read input (TRUE, "Startwert des Zufallszahlengenerators ? ", FALSE); +  UNTIL check input (2) CAND input ok PER;                      (* F24/rr *) +  assign input (init); +  init rnd (init); + +END PROC init rnd; + + +END PACKET basic std using io; + diff --git a/lang/basic/1.8.7/src/eumel coder 1.8.1 b/lang/basic/1.8.7/src/eumel coder 1.8.1 new file mode 120000 index 0000000..5fead18 --- /dev/null +++ b/lang/basic/1.8.7/src/eumel coder 1.8.1 @@ -0,0 +1 @@ +../../../../system/eumel-coder/1.8.1/src/eumel coder 1.8.1
\ No newline at end of file diff --git a/lang/basic/1.8.7/src/eumel0 codes b/lang/basic/1.8.7/src/eumel0 codesBinary files differ new file mode 100644 index 0000000..226014c --- /dev/null +++ b/lang/basic/1.8.7/src/eumel0 codes diff --git a/lang/basic/1.8.7/src/gen.BASIC b/lang/basic/1.8.7/src/gen.BASIC new file mode 100644 index 0000000..9690ae6 --- /dev/null +++ b/lang/basic/1.8.7/src/gen.BASIC @@ -0,0 +1,80 @@ +(**************************************************************************) +(*                                                                        *) +(*     Generatorprogramm zur Installation des EUMEL-BASIC-Systems         *) +(*                                                                        *) +(*     Autor: Heiko Indenbirken                                           *) +(*     Überarbeitet von: Michael Overdick                                 *) +(*                                                                        *) +(*     Stand: 27.08.1987                                                  *) +(*                                                                        *) +(**************************************************************************) + +LET coder name = "eumel coder 1.8.1"; + +show headline; +from archive ("BASIC.1", (coder name & "eumel0 codes") - all); +from archive ("BASIC.2", +       ("BASIC.Runtime" & "BASIC.Administration" & "BASIC.Compiler") - all); +set status; +insert ("eumel coder 1.8.1"); +insert ("BASIC.Runtime"); +insert ("BASIC.Administration"); +insert ("BASIC.Compiler"); +forget (coder name & "BASIC.Runtime" +               & "BASIC.Administration" & "BASIC.Compiler" & "gen.BASIC"); +restore status; +show end . + +show headline: +  page; +  putline ("                 "15"Einrichten des EUMEL-BASIC-Systems "14""); +  line  . + +set status: +  BOOL VAR old check := check, +           old warnings := warnings, +           old command dialogue := command dialogue; +  check off; +  warnings off; +  command dialogue (FALSE). + +restore status: +  IF old check     THEN do ("check on") ELSE do ("check off") FI; +  IF old warnings  THEN warnings on                           FI; +  command dialogue (old command dialogue). + +show end: +  line (2); +  putline ("                      "15"BASIC-System installiert "14""); +  line  . +  +PROC from archive (TEXT CONST name, THESAURUS CONST files): +  IF highest entry (files) > 0 +  THEN ask for archive; +       archive (name); +       fetch (files, archive); +       release (archive); +       putline ("Archiv abgemeldet !") +  FI  . + +ask for archive: +  line; +  IF no ("Archiv """ + name + """ eingelegt") +  THEN errorstop ("Archive nicht bereit") FI  . + +END PROC from archive; + +THESAURUS OP & (TEXT CONST left, right): +  THESAURUS VAR result := empty thesaurus; +  insert (result, left); +  insert (result, right); +  result +END OP &; + +THESAURUS OP & (THESAURUS CONST left, TEXT CONST right): +  THESAURUS VAR result := left; +  insert (result, right); +  result +END OP &; + + | 
