Stringy stellt eine Basic-Interpretererweiterung dar, die den Befehlssatz des C 64 um acht Befehle ergänzt. Mit diesen Befehlen ausgestattet, kann man sich einen Programmgenerator von Basic aus programmieren.
Das Listing zu Stringy entstand mit Hilfe von Stringy. Dabei wurden die Zahlen formatiert, die Prüfsummen berechnet und nach jeder vierten Zeile angefügt. Mit Stringy kann man Strubs-ähnliche Erweiterungen programmieren (Der Grund, weshalb ich Stringy schrieb). Man könnte auch ein Programm schreiben, das die in einem Basic-Programm vorkommenden Grafikzeichen durch die entsprechenden CHR$-Funktionen ersetzt, damit sie im Listing besser zu erkennen sind. Auch Sprite- oder Bildschirmmasken-Generatoren sind recht einfach zu programmieren. Der wichtigste Befehl von Stringy ist der !INPUT-Befehl. Mit ihm kann man einen String, der eine Basic-Zeile mit Zeilennummer darstellt, bei laufendem Programm in das Basic-Programm übernehmen — ohne, daß dabei die Programmausführung unterbrochen wird.
Umgekehrt kann es sinnvoll sein, eine Zeile aus dem Basic-Programm herauszuholen, um sie einer Stringvariablen zuzuordnen. Dies ermöglicht der !GET-Befehl.
Damit es keine Komplikationen mit den Basic-Zeilennummern gibt, teilt der !NEXL-Befehl Ihnen die Folge der Zeilennummern mit.
Die anderen fünf Befehle dienen der Stringverarbeitung. Vier davon sind dem Sinn nach identisch mit den entsprechenden Stringoperationen aus Simons Basic, mit dem Unterschied, daß die Parameter beliebig komplizierte Ausdrücke sein können (dies gilt für alle Befehle von Stringy).
Der letzte der fünf Stringbefehle ist der !REPLACE-Befehl.
Die Stringy-Befehle
Nachfolgend bedeuten str1, str2, str3 immer Stringausdrücke und m, n, p, w, z immer numerische Ausdrücke.
!PLACE
Format:
!PLACE (str1,str2)
!PLACE (str1,str2,m)
!PLACE (str1,str2,m,n)
Funktion: Bestimmung der Position, an der str2 in str1 steht. Die Angabe von m und n grenzt str1 auf einen Teilstring ein. Nur dieser Teilstring von str1 wird dann durchsucht, und nicht der ganze String, m gibt den Beginn dieses Teilstrings an, gerechnet vom Anfang von str1, n bestimmt das Ende des Teilstrings. Vorsichtig: n wird vom Ende von str1 aus gezählt, also in anderer Richtung als m.
Beispiel: »PRINT !PLACE ("COMMODORE", "O")« liefert 2 als Antwort.
»PRINT !PLACE ("COMMODORE", "O",3)« liefert 5 als Antwort, da nur in "MMODORE" gesucht wurde
»PRINT !PLACE ("COMMODORE", "E", 1, 4)« liefert 0 als Ergebnis, da "E" nicht in dem Teilstring "COMMOD" enthalten ist.
!REPLACE
Format:
!REPLACE (str1,str2,str3)
!REPLACE (str1,str2,str3,m)
!REPLACE (str1,str2,str3,m,n)
Funktion: Ersetzen aller str2, die in str1 vorkommen, durch str3. Dabei kann str1, wie beim !PLACE-Befehl beschrieben, durch n und m eingegrenzt werden.
Beispiel: A$=!DUP(".",255) liefert einen String mit 255 einzelnen Punkten.
!INPUT
Format: !INPUT(str)
Funktion: Hat str keine Zeilennummer am Anfang, so geht der Computer in den Direktmodus über und führt str sofort aus. Soll der Computer anschließend zum Programm zurückkehren, so muß der letzte Befehl in str ein »GOTO (Zeilennummer)« sein.
Beginnt str mit einer Zeilennummer, so wird str als Basic-Zeile in das laufende Programm eingefügt, sofern in dem Programm nicht bereits eine Zeile mit derselben Zeilennummer existiert. Andernfalls wird die betreffende Zeile vor dem Einfügen gelöscht. Wenn allerdings diese zu löschende Zeile eine noch offene FOR…TO-Anweisung oder ein noch nicht durch RETURN abgeschlossenes GOSUB enthält, so erfolgt ein CAN’T CONTINUE ERROR.
Die gleiche Fehlermeldung erscheint auch, wenn Sie eine Zeile löschen wollen, in der sich der DATA-Zeiger momentan befindet. Beispiel:
10 DATA56
20 READA:!INPUT(STR$(10))
Nach RUN erfolgt ein CAN’T CONTINUE ERROR, da sich der DATA-Zeiger in Zeile 10 befindet. Durch einen RESTORE-Befehl, läßt sich diese Zeile dennoch löschen:
10 DATA56
20 READA:RESTORE:!INPUT("10")
Nach Ausführung dieser beiden Zeilen ist die Zeile 10 gelöscht. Enthielt die gelöschte Basic-Zeile eine DEF-Anweisung, so gilt diese Funktion als nicht definiert. Enthielt die gelöschte Basic-Zeile eine Stringvariablenzuordnung der Art »AA$="ABCD"« oder »A$(n)="ABCDE"«, so ist anschließend die Variable nur noch als Leerstring definiert.
Soll der !INPUT-Befehl direkt nach einem THEN stehen, dann ist ein Doppelpunkt einzufügen »…THEN:!INPUT…«
!GET
Format: !GET(z)
Funktion: Es wird die Basic-Zeile mit der Zeilennummer z in Stringformat geholt. Der Parameter z darf dabei nicht den Wert 0 haben. Beispiel:
10 REM !GET-DEMO
20 PRINT!GET(10):PRINT!GET(20)
30 A$ = !GET(30)
40 PRINT MID$(A$,!PLACE(A$," ") + 1)
!NEXL
Format: !NEXL(z)
Funktion: Es wird die auf z folgende Basic-Zeilennummer geholt. Hat !NEXL(z) den Wert 0, so bedeutet dies, daß auf z keine Basic-Zeilen mehr folgen. Beispiel:
10 REM !NEXL-DEMO
20 REM SIMULATION DES LIST-BEFEHLS
30 Z = 0
40 Z=!NEXL(Z):IF Z = 0 THEN END
50 PRINT !GET(Z):GOTO 40
Zum Schluß noch einige Daten zu Stringy. Stringy belegt den Speicher von $c100 bis $c85a. Der Bereich von $c000 bis $c0ff dient als Stringzwischenspeicher (je nach Befehl wird dieser Raum benutzt). Die Speicherplätze $c85b bis $c865 dienen als Zwischenspeicher für einige wichtige Betriebssystemdaten. Der unter dem Basic-ROM liegende Speicherbereich wird mitbenutzt.