Version 2.66 |
|||||
|
Dieses Dokument beschreibt die Fähigkeiten von Yabasic. Kurz gesagt, Yabasic umfasst die bekanntesten (und einfachsten) Elemente der BASIC-Programmiersprache mit einigen grafischen Möglichkeiten, die Jedem vertraut sein sollten, der schon einmal Basic-Programme geschrieben hat.
Diese Seite umfasst alle Fähigkeiten von Yabasic. Man braucht keinerlei weitere Literatur, um es zu lernen. Es gibt gar keine andere Literatur über Yabasic, weder eine Unix/Linux-man-page noch eine Windows-Helpdatei.
Dieser Text ist keine Basic-Einführung, sondern setzt Grundkenntnisse der BASIC-Programmierung voraus.
Es gibt drei Möglichkeiten Yabasic zu starten:
1. |
Das BASIC-Programm als Text-Datei
schreiben (z.B. foo.yab) und Yabasic aufrufen mit dieser Datei als Argument:
|
2. |
Yabasic ohne Argument (Dateiname)
starten. |
3. |
Das BASIC-Programm als Text-Datei
schreiben und diese Textzeile als allererste
Zeile eintragen. |
Zurück zum Inhaltsverzeichnis ...
Die Farben, Schriftart und die Fensterposition sollte
mit der Kommandozeile gesetzt werden,
oder in der Benutzereinstellungs-Datei (Das ist meist die
Datei .Xresources
im Stammverzeichnis) angegeben werden; z.B.:
yabasic*background: gold yabasic*geometry: +10+10 yabasic*font: 9x15
Dies setzt den Vordergrund des Grafik-Fensters auf blau,
den Hintergrund auf gold,
das Fenster wird bei Position 10,10 (Pixel) positioniert
und die Schrift wird 9x15 (Pixel) sein.
Zurück zum Inhaltsverzeichnis ...
Nach Durchlaufen des Setup-Programms gibt es drei Möglichkeiten Yabasic zu starten::
1. |
Wähle "yabasic" im Start-Menü: Yabasic wird in einem Fenster geöffnet, in dem der Basic-Programmname einfach eingegeben werden kann. |
2. |
Klicke mit der rechten Maustaste auf den Desktop.
Wähle "new" im aufklappenden Kontext-Menü. Dies erzeugt
ein neues Icon auf dem Desktop. Das Kontext-Menü dieses Icons
hat drei Einträge "Execute", "Edit" und "View
docu" (was die verknüpfte
Dokumentation zeigt, falls vorhanden). |
3. |
Erzeuge eine Datei mit dem Yabasic-Programm.
Diese Datei soll die Erweiterung ".yab" haben. |
Zurück zum Inhaltsverzeichnis ...
Zurück zum Inhaltsverzeichnis ...
Um die Vorgaben für Grafik-Schrift, Schriftgröße und Fenster-Position zu setzen, muss man die Registry bearbeiten.
Yabasic speichert die Vorgaben unter:
Man kann die Unterschalter "font" und "geometry" bearbeiten. Diese Unterschalter akzeptieren dieselben Werte wie die entsprechende Kommandozeilen-Optionen-font und -geometry. Kommandozeilen haben Vorrang vor Registry-Einstellungen.
Zurück zum Inhaltsverzeichnis ...
Dies ist das erste Beispiel:
input "Gib zwei Zahlen ein:" a,b print a,"+",b,"=",a+b print "Gib bitte deinen Namen ein:"; INPUT a$ print "Hallo ",a$," !"
Dieses Programm erzeugt die folgende Ausgabe
Benutzereingabe wird so angezeigt):
2+3=5 Gib bitte deinen Namen ein: Bill Hallo Bill !
Diese einfachen Programme enthalten drei Kommandos:
Weiterhin sollten einige allgemeine Eigenschaften von Yabasic beachtet werden:
Zurück zum Inhaltsverzeichnis ...
Yabasic kennt fünf Rechenarten: + (Addition), -
(Subtraction), * (Multiplikation), / (Division) und ^
(Potenzieren (hoch...)).
Sie verhalten sich wie üblich, z.B. die Programmzeile
erzeugt diese Ausgabenzeile:
Hinweis: Der Potenzieren-Operand (^) darf auch Potenzbrüche enthalten: 8^(1/3) ergibt 2 als Resultat.
Dieser Abschnitt beschreibt und erklärt die Rechenfunktionen von Yabasic.
print atan(2),atan(1,2)
0.841471 -1 -0.142547
0.523599 0.795399
1.10715
0.463648
print exp(1),log(2),log(euler)
log() und exp() beziehen sich auf
die Basis e (=2.17828), die als reservierte Variable euler verfügbar ist.
Deshalb
wird es Sie nicht überraschen, wenn Sie damit folgende Ausgabe
erhalten:
2.71828 0.693147 1
print int(2.34),frac(2.34) ergibt: 2 0.34
Die Division von 11 durch 4 ergibt 2 und einen Rest von 3.
print min(2,3),max(2,3) ergibt: 2 3
print sqrt(2),sqr(2) ergibt 1.41421 4
print hex$(255)," ist ",dec("ff") ergibt: ff ist 255
Ganz ähnlich funktioniert die Umwandlung in binäre Zahlen: So ergibt bin$(8) den Wert "100" und umgekehrt hex("100",2) den Wert 8; dabei verlangt die funktion dec() als zweites Argument die Basis (hier: 2), wenn sie vom Standardwert 16 abweicht.
Die ran()-Funktion von Yabasic benutzt die ran()-Funktion der C standard library, deshalb darf man nicht ein zu gutes Ergebnis an Zufallszahlen erwarten....
Sie können die bitweisen Operationen and(), or(), eor(), die auch als xor() geschrieben werden können, benutzen wie z.B. hier:
print and(10,7),or(9,3),eor(15,4)
Das entspricht der Art, wie Yabasic
Zahlen behandelt (Es gibt keine echten Ganzzahlen).
dennoch kann das gewünschte Ergebnis leicht
erzielt werden, indem man eor() benutzt, mit einem Argument,
bestehend aus binären Einsen: (a hoch 2,
minus1) eor(255,123) und
eor(65535,266) sind Beispiele.
Zurück zum Inhaltsverzeichnis ...
Um zu verzweigen, muss der if-Befehl benutzt werden:
input "Gib bitte eine Zahl ein" a if (a>10) then print "Die Zahl ist größer als 10" elsif (a>5) then print "Die Zahl ist gößer als 5, aber kleiner oder gleich 10" else print "Die Zahl ist kleiner als oder gleich 5" endif
Wie Sie hier sehen, muss
die Verzweigungsbedingung in runden Klammern eingeschlossen
sein (...).
Der else
und der elsif-Teil
der if-Anweisung
sind beliebig ound können auch weggelassen werden, so wie im folgenden
Beispiel:
input "Bitte gib eine Zahl ein" a if (a>10 and a<20) print "größer als 10":print "aber kleiner als 20" fi
Beachten Sie, dass endif auch als fi geschrieben werden kann!
Falls Sie noch weniger schreiben wollen, dann versuchen Sie mal:
input "Bitte eine Zahl eingeben" a if (a>10 and a<20) print "größer als 10 aber weniger als 20"
Beachten Sie, dass then und endif
(oder fi) weggelassen wurden.
Obwohl eine einfache Anweisung der folgenden Art ausführbar
ist, z.B.
if (a>10 and a<20) print "größer
als 10":print "aber weniger als 20" (Zwei
print-Anweisungen)
wird nicht das gewünschte Ergebnis ausgeben: Der Satzteil
"aber weniger als 20" wird, unabhängig vom Wert a, immer
ausgegeben.
Nun wollen wir uns die Bedingungen (a>10 and a<20) der if-Anweisung genauer ansehen:
Strings können mit denselben Operatoren verglichen
werden, wobei Buchstaben entsprechend ihrer Nummer in der ASCII-Tabelle
eingeordnet werden. Z.B. ("a"<"b") ist WAHR (weil "a" eine niedrigere ASCII-Nummer hat als "b") und demnach ist ("a"="b")FALSCH.
Mehrere Vergleiche
können mittels runder Klammern ()und den Schlüsselwörter or, and,
not kombiniert
werden.
Beachten Sie, dass not dem and vorgeht,das wiederum dem or vorgeht (In gleicher Weise wie *dem +
in Rechenausdrücken vorgeht).
Es
gibt noch andere Bedingungen, die für Prüfungen benutzt werden
können:
print "größer als 10":print
"aber weniger als 20"
Die
Befehle sind durch Doppelpunkte (:) voneinander zu trennen.
Zurück zum Inhaltsverzeichnis
...
Basic war immer einfach und stark in der String-Verarbeitung. Und auch Yabasic versucht, diese Tradition fortzusetzen:
input "Gib bitte ein Wort ein:" a$
for a=len(a$) to 1 step -1:print mid$(a$,a,1);:next a
print " ist ",a$," rückwärts !"
Wenn Sie dieses Programm ausprobieren, werden Sie diese Ausgabe erhalten:
ollaH ist Hallo rückwärts !
Beachte die step-Anweisung: Die Zahl hinter step (hier -1) wird zu a nach jeder Wiederholung addiert.
Im
Beispiel verringert die step-Angabe a mit jeder Wiederholung.
Wenn
Sie die step-Angabe weglassen wird step
1 angenommen.
Und
beachten Sie, dass die for next loop-Schleife
jederzeit mit goto verlassen werden kann.
Sie
können die for-loop-Schleife auch für seltene Fälle nutzen:
z.B. for a=1 to
100 step a:print a:next a ergibt die Quadratzahlen
von 2 bis 64.
input "Bitte gib ein Wort ein" a$
a=len(a$):repeat: print mid$(a$,a,1);:a=a-1:until(a=0)
print " ist ",a$," rückwärts !"
(Bedingungsprüfung nach Durchlauf der Schleife)
oder
(Bedingungsprüfung vor Durchlauf der Schleife)
input "Bitte gib ein Wort ein"
a$
a=len(a$):while(a>0):print mid$(a$,a,1);:a=a-1: wend
print " ist ",a$," rückwärts !"
Alle diese Schleifen führen zum selben Ergebnis (So lange wenigstens ein Buchstabe eingegeben wird !).
Innerhalb der obigen for-next-loop- Schleife werden
die String-Funktionen len() und mid$()
angewandt,
aber es gibt noch viele andere
String-Funktionen:
a$="123456"
print left$(a$,2),"-",mid$(a$,2,3),"-",right$(a$,3)
erzeugt folgende Ausgabe: 12-234-456
Wie Sie sehen, schneidet left$() so viele Buchstaben von links ab, wie es im zweiten
Argument angegeben ist.
right$() schneidet von rechts und mid$() schneidet aus der Mitte,
wobei
das zweite Argument die Startstelle und das dritte Argument die
Anzahl der auszuschneidenden Zeichen angibt. Wenn man das dritte
Argument wegläßt erhält man den string von der angegebenen
Position bis zum Ende: mid$("Hallo",2) gibt also "allo" zurück.
Darüber hinaus kann mid$() und seine 'Verwandten' sogar benutzt werden, um ausgewählte
Teile eines Strings zu ersetzen:
a$="123456":left$(a$,2)="abcd":print
a$
ergibt ab3456
Wie Sie sehen wurden nur die beiden linken
Buchstaben ausgetauscht (obwohl der String "abcd" vier Buchstaben enthält).
Dasselbe
kann mit mid$()
oderr right$()
erzielt werden. Schließlich ist noch zu erwähnen, daß
die Zuweisung an left$()/mid$()/right$() nie die Länge des
Strings ändert.
print str$(12)
ergibt den String (Text) "12" als Resultat.
Die
Formatierung der Zahl kann durch ein wahlweises weiteres Argument
bestimmt werden:
print str$(12.123455,"##.##") ergibt den String 12.12.
Das zweite Argument
hat denselben Effekt wie der Formatstring des print using Befehls.
Genau das Umgekehrte macht die Funktion
val():
print 2+val("23") ergibt 25 als Resultat, während print
val("e2") eine 0 liefert, weil "e2" keine
gültige Zahl ist.
asc() ergibt
die Nummer eines Zeichens im aktiven Zeichensatz:
print
asc("e") ergibt 101 als Ergebnis, weil
das Zeichen "e" die Nummer 101 im Zeichensatz hat.
Umgekehrt ergibt die Funktion chr$() das Zeichen der entsprechenden Nummer im Zeichensatz:
Sonderzeichen |
ä |
ö |
ü |
Ä |
Ö |
Ü |
ß |
§ |
¦ |
© |
é |
@ |
# |
Euro |
® |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ASCII-Nummer |
132 |
148 |
129 |
142 |
153 |
154 |
225 |
21 |
|
|
130 |
64 |
35 |
(238) |
|
Latin1-Nummer |
228 |
246 |
252 |
196 |
214 |
220 |
223 |
167 |
166 |
169 |
233 |
64 |
35 |
128 |
174 |
PC850-Nummer |
132 |
148 |
129 |
142 |
153 |
154 |
226 |
245 |
221 |
184 |
130 |
64 |
35 |
128? |
169 |
Windows-Nummer |
228 |
246 |
252 |
196 |
214 |
220 |
223 |
167 |
166 |
169 |
233 |
64 |
35 |
128 |
174 |
Mit dem folgenden Programm sehen Sie alle Bildschirmzeichen und ihre Nummern
clear screen:i=0 while (i<256) print chr$(i),"=",i, i=i+1 wend
Sie können \n benutzen statt chr$(10), sobald Sie einen Zeilenvorschub brauchen.
(Natürlich sind nur solche Escape-Folgen verfügbar, die auch in der C-Sprache vorhanden sind):
Escape-Folgen |
ASCII-Zeichen |
---|---|
\n |
Zeilenvorschub |
\t |
Tabulatorsprung |
\v |
vertikalerTabulator |
\b |
Rückschritt |
\r |
Wagenrücklauf |
\f |
Seitenvorschub |
\a |
Glocke |
\\ |
Backslash |
\` |
Einf. AnfStrich |
\" |
Dopp. AnfStrich |
Escape-Folgen stehen immer zwischen doppelten Anführungsstrichen (""), z.B. innerhalb von Strings. Benutzereingaben über die input-Anweisung ist in keiner Weise hiervon betroffen.
Jedoch beachten Sie, dass Windows-Pfadangaben Zeichenfolgen beinhalten, die leider ebenfalls als Escape-Folgen erkannt werden.
Hier ein weiteres Beispiel, das in die übrigen String-Funktionen von Yabasic einführt:
- label schleife
print "Bitte geben Sie eine String ein, der das Wort \"Yabasic\" enthält" input a$ if (instr(lower$(a$),"yabasic")<>0) then (Kleinschreibung) gosub danke else print "Nein, bitte noch einmal!" endif goto schleife label danke print "Vielen Dank!" return
Wenn Sie dieses Programm starten, werden Sie folgende Ausgabe erhalten:
- Bitte geben Sie eine String ein, der das Wort "Yabasic" enthält
?thequickbrownfox (Eingabe) Nein, bitte noch einmal! Bitte geben Sie eine String ein, der das Wort "Yabasic" enthält ?jumpedyabasicoverthelazydog (Eingabe) Vielen Dank!
Beachten Sie, dass Sie sogar eine for-next-Schleife mit goto verlassen oder in sie eintreten können.
Verwandt mit dem goto-Befehl ist der gosub-Befehl. Wenn Yabasic auf einen gosub-Befehl stößt, sucht es nach dem richtigen
Label (label danke
im Beispiel) und setzt die Ausführung ab der Position des Labels
fort, bis es einen return-Befehl findet.
return veranlasst Yabasic, an die ursprüngliche gosub-Position
zurückzukehren und das Programm von dort fortzusetzen.
Merke dass beide, goto und gosub, auch als on goto und on gosub benutzt werden können.
l$=" eins zwei drei "
dim words$(1)
num=token(l$,words$())
for a=1 to num:print words$(a):next a
eins zwei drei
l$="::eins::zwei:drei::vier"
dim words$(1)
num=split(l$,words$(),":")
for a=1 to num:print "Token: ",words$(a):next a
Token: Token: Token: eins Token: Token: zwei Token: drei Token: Token: vier
glob-Bedingung |
WAHR/FALSCH ? |
---|---|
glob("abcd","abc?") |
WAHR |
glob("abab","*") |
WAHR |
glob("abc","ab??") |
FALSCH |
glob("abcdabab","ab*ab") |
WAHR |
glob("abcd","*a") |
FALSCH |
Zurück zum Inhaltsverzeichnis ...
Eines Tages werden Sie sich nicht mehr mit Yabasic's eingebauten
Funktionen und Befehlen zufrieden geben.
Dies wird der Zeitpunkt sein, die erste Subroutine
zu schreiben und zu nutzen:
print vielfach$("Hallo",3) sub vielfach$(a$,a) local b$,b for b=1 to a:b$=b$+a$:next b return b$ end sub
Dieses Programm gibt einfach den String HalloHalloHallo aus bestehend aus Hallo, verdreifacht. Da es aber in Yabasic keine Funktion zum "Verdreifachen"
von Strings gibt, definiert das Programm selbst eine eigene Funktion vielfach$() (beginnend mit sub vielfach$(a$,a)).
vielfach$() ist eine
Benutzerdefinierte String-Funktion. Aufgrund des $-Zeichens in vielfach$() kann man ableiten, dass die Funktion einen String zurückgibt.
vielfach$() braucht
zwei Argumente, einen String und eine Zahl, die der Funktion durch die Variablen
a$ und a übergeben werden. Diese Variablen, und genauso b$ und b
(definiert in local b$,b),
gelten nur innerhalb der Funktion. Sie werden bei Eintritt in die Subroutine
angelegt und sie halten ihren Wert nur so lange, wie die Subroutine ausgeführt
wird. Die Berechnung innerhalb der Subroutine ist unverzweigt und das Resultat
wird mit dem Befehl return b$
zurückgegeben.
Anstelle von return b$ können Sie auch einfach return schreiben oder return ganz weglassen. In diesem Fall wird ein leerer String zurückgegeben (oder 0.0 bei numerischen Funktionen) . Das wäre aber nicht besonders sinnvoll bei einer Subroutine.
Hier sind einige Beispiele, die zeigen, dass Yabasic ziemlich tolerant mit benutzerdefinierten Subroutines umgeht:
print sum(1,4),sum(2),sum(),sum(2,3) sub sum(a,b) if (numparams<2) b=1 return a+b end sub
sub() ist eine numerische Subroutine (weil sub() kein $-Zeichen enthält) und gibt einfach die Summe seiner beiden numerischen Argumente zurück. Dieses Programm gibt die Zeile "5 3 1" aus. Dies sind die drei Werte, die durch die drei Aufrufe von sum() zurückgegeben werden.
Wie Sie sehen, kann die Funktion sum() mit weniger als zwei Argumenten aufgerufen werden. In diesem Fall wird 0.0 eingesezt für ein fehlendes numerisches Argument und der Leersting "" für ein fehlendes Stringargument. Dennoch lassen sich die lokalen Variablen abfragen.
numparams ist eine von Yabasic reservierte Variable, um die Anzahl
der durch den Subroutinen-Aufruf ausgegebenen Parameter anzugeben.. Wenn Sie
ein Array-Argument weglassen, wird Yabasic ein lokales Ersatz-Array einrichten.
Trotzdem, sobald Sie versuchen, das Array anzusprechen, werden Sie eine Fehlermeldung
erhalten.
Deshalb ist es gute Praxis, numparams zu prüfen, bevor man auf einen Array-Parameter
zugreift.
Des weiteren können Sie eine Subroutine aufrufen
(im Beispiel sub(2,3)),
ohne sich um den zurückgegebenen Wert zu kümmern.
(Technisch gesehen gibt es in Yabasic keine Unterschied zwischen Funktionen
und Proceduren).
Lokale Variable existieren außerhalb der Subroutine
nicht. Sie werden jedesmal neu angelegt, wenn die Subroutine aufgerufen wird.
Aber manchmal möchten Sie vielleicht die Werte der Variablen in der Subroutine
halten. I
In diesem Fall können Sie static-Variable benutzen wie hier:
for a=1 to 4:stars():next a sub stars() static a$ (a$ bleibt für den nächsten Aufruf erhalten) local b$ a$=a$+"*" b$=b$+"*" print a$," ",b$ end sub
Der Programmlauf erzeugt folgendes Muster:
* * ** * *** * **** *
Wie Sie sehen, hält die static-Variable a$ ihren Wert über Aufrufe von stars() hinweg, während b$ jedesmal zurückgesetzt wird.
Und merke, dass Subroutinen leicht Arrays in Subroutinen
als Parameters, local- oder static-Variable benutzen können.
Hier
ist ein Beispiel.
Zurück zum Inhaltsverzeichnis ...
Hin und wieder möchte ein Programm während seiner Ausführung Unterroutinen definieren: Z.B. möchte ein Benutzer einen beliebiegen arithmetischen Ausdruck eingeben, den das Programm dann plotten soll:
input "Bitte geben Sie einen arithmetischen Ausdruck ein: f(x) = " f$
compile "sub f(x):return "+f$+":end sub" for x=1 to 10:for i=1 to f(x):print "*";:next i:print:next x
Dieses Programm liest einen arithmetischen Ausdruck in die Variable f$; mögliche Werte wären z.B. "sin(x)" oder "x*x". Mit diesem Ausdruck wird dann die Definition einer einfachen Unterroutine zusammengesetzt und an das compile-Kommando übergeben, das sein string-argument in normalen yabasic-code umwandelt. Danach kann man die neu definierte Funktion f(x) ganz normal benutzen; wie in der dritten Zeile, die die Funktion grafisch darstellt.
Ein anderes Feature (das aber auch mit Unterroutinen zu tun hat) ist die Fähigkeit eine Funktion über Namen und Argumente auszuführen: execute("f",x) ist genau dasselbe wie f(x); Natürlich is execute("f",x) häßlich, aber mit diesem Feature kann genutzt werden, um eine Funktion zu plotten deren Name spezifiziert ist:
sub plot(f$)
local x,y,a
for x=1 to 10
y=execute(f$,x)
for i=1 to y:print "*";:next i print
next x
end sub
Mit dieser praktischen plot-Funktion ist es möglich plot("f") zu sagen, um einen Plot der Funktion f zu erhalten. Allerdings würde plot("x*x") einen Fehler liefern, weil versuch würde eine Funktion mit Namen "x*x" auszuführen, die es natürlich nicht gibt.
Je nachdem, ob Sie den Wert, den execute zurückgibt werwenden wollen (oder ob die per execute ausgeführte Funktion überhaupt einen Wert zurückliefert), können sie execute in einer Zuweisung oder als eigene Befehl verwenden: execute("f",x) und y=execute("f",x) sind beide gültig.
Schließlich sollten Sie noch execute$ für Funktionen verwenden, die eine Zeichenkette zurückgeben.
Zurück zum Inhaltsverzeichnis ...
Eine Library ist eine besondere Datei, die "fertige Subroutinen" enthält. Libraries sind nützlich, wenn Sie mehrere Subroutinen geschrieben haben, die Sie in mehr als einem Yabasic-Programm verwenden wollen. Noch besser ist es, wenn jemand anderes eine Library geschrieben hat, die Sie ohne eigene Anstrengung nutzen können.
Machen wir weiter und versuchen wir ein Beispiel (weil Libraries meistens Subroutinen enthalten, können Sie abzweigen und zuerst über sie lesen). Dies benutzt einfach eine Library:
import ufirst print uf$("foO")
Wenn Sie dieses Programm ablaufen lassen, gibt es "Foo" aus. Das entspricht "foO" mit dem ersten Buchstaben groß geschrieben ("f") und der Rest ("oO") verändert in Kleinschreibung. Der Name dieser Subroutine ("uf") ist einfach eine Abkürzung von "upper-first".
Die Subroutine uf$() ist definiert in der Library ufirst, die aktiviert wird mit dem Befehl import ufirst. Die Library ucfirst ist ziemlich einfach:
rem Hier ist die eingebettete Dokumentation: docu docu Diese Llibrary ufirst stellt eine einzige Funktion zur Verfügung: uf$(), doc Sie gibt das String-Argument in Kleinschreibung zurück, mit Ausnahme doc des Ersten Buchstabens. Der wird groß geschrieben. doc docu Z.B. uf$("foo") ergibt "Foo" und uf$("bAr") ergibt "Bar" docu a=2: rem Dieser Befehl ist zwecklos ! export sub uf$(a$) : rem uf$() exportieren return upper$(left$(a$,1))+lower$(butfirst$(a$)) end sub sub butfirst$(a$) : rem butfirst$() ist nur lokal sichtbar return right$(a$,len(a$)-1) end sub
Wenn Sie diese Library mit import ufirst in ihr Yabasic-Programm importieren, liest Yabasic in der Library und fügt sie in ihr Programm ein: Jeder Befehl in der Library (z.B. a=2 im Beispiel) wird ausgeführt und jede Subroutine (uf$() und butfirst$()) ist definiert. Nach diesem Import sind die Variable a und die Funktionen uf$() und butfirst$() definiert in ihrem Programm. Um Konflikte zu vermeiden zwischen den Variablen und Subroutinen, die im Programm definiert sind und denen der Library, werden all diese Variablen und Subroutinen verbunden mit dem Namen der Library. Z.B. wird a importiert als ufirst.a, uf$(), wird importiert als ufirst.uf$() und butfirst$() wird importiert als ufirst.butfirst$(). Sie können prüfen, dass das a der Library ufirst unabhängig ist von jedem anderen a in ihrem Progamm:
import ufirst a=1 print a,ufirst.a
Dies gibt einfach "12" aus. Es zeigt, dass "a" in ihrem Program und "a" in der Library ufirst nicht durcheinander geraten.
Andererseits möchten Sie einige spezielle Subroutinen der Library benutzen, ohne sie mit dem Library-Namen zu verknüpfen, Dies kann erreicht werden, indem der Definition der Routine das Schlüsselwort export hinzugefügt wird. (im Beispiel: export sub uf$(a$)). So eine exportierte Subroutine kann ohne Verknüpfung mit dem Library Namen benutzt werden. (wie in print uf$("foO")).
Die Library beginnt mit einer Folge von docu (oder doc) Befehlen, die die eingebettete Dokumentation der Library enthält. Diese eingebettete Dokumentation kann gelesen werden, indem man Yabasic mit der Option "-lib" aufruft. Benutzen Sie yabasic -lib ufirst um den Text der docu Befehle zu lesen. Deshalb ist es stets eine lobenswerte Idee, die Library mit einigen Kommentaren Auszustatten, die erklären, welche Subroutinen die Library bietet . Des weiteren sollten Sie der Library zusammen mit einem kleinen eingebetteten Beispielprogramm bereitstellen, das die Benutzung aufzeigt. Wenn sie das Beispielprogramm in if (peek$("library"="main")) then ... endif verpacken, wird ihr eingebettetes Beispielprogramm nur ausgeführt, wenn die Library als Programm ausgeführt wird, jedoch nicht, wenn andere Programme Ihre Library importieren.
Sobald Sie einige eingebettete Dokumentationen geschrieben haben, können
Sie darauf auch von ihrem Programm aus zugreifen.
Fragen Sie einfach das Array mit docu$() ab, das automatisch den Text aller docu-Befehle enthält.
Nachdem Sie eine Library geschrieben oder erhalten haben, müssen Sie sie installieren. Das ist einfach: Der Dateiname, der die Library enthält, sollte auf ".yab" (z.B. ucfirst.yab) enden. Diese Datei soll in ein eigenes Verzeichnis kopiert werden. Dieses besondere Verzeichnis (z.B. c:\yabasic\libunter Windows oder \usr\lib\yabasic unter Unix /Linux) erscheint (zusammen mit der Erklärung der -lib Option), wenn Sie Yabasic mit der Option -help aufrufen (z.B. yabasic -help). Nachdem Sie die Datei in das richtige Verzeichnis kopiert haben, haben Sie's geschafft! Von jetzt ab können Sie die Library in Ihren Yabasic-Programmen benutzen, z.B. um import ucfirst zu schreiben. Des weiteren findet Yabasic eine Library sogar, wenn sie sich im aktuellen Verzeichnis befindet,z.B. im Verzeichnis, in dem sich das Yabasic-Programm befindet (mit dem import-Befehl) . Dies ist sehr bequem, um eine Library zu Bearbeiten und zu erproben.
Beachten Sie, dass der Dateiname des Programms und der Name der Library, der im import-Befehl erscheint, immer gleich sein müssen.
Nachdem Sie all dieses nun über Libraries
gelesen haben, werde Sie sich fragen, wie Sie an Libraries kommen können.
Eine Lösung wird sein, selbst welche zu schreiben. Aber es wird bestimmt
viel leichter sein, weil es weniger Arbeit bedeutet, Libraries zu benutzen,
die schon von anderen Leute geschrieben wurden.
Libraries sind eine neue Fähigkeit in Yabasic, deshalb gibt es bisher keine
Standard-Llibraries, aber ich hoffe, dass Benutzer nützliche Libraries
entwickeln und veröffentlichen werden. Legen Sie los!!
Zurück zum Inhaltsverzeichnis
...
Yabasic bringt einige einfache, allgemein brauchbare Grafik-Befehle mit:
- open window 400,400
line 0,0 to 400,400 circle 200,200,150 clear fill circle 200,200,130 clear line 0,400 to 400,0 dot 200,200 a$=inkey$ clear window text 100,200,"Hallo !" print "Drücke eine Taste, um das Fenster zu schließen!" inkey$ close window
Wenn Sie wollen, dann können Sie diese Befehle noch erweitern um die Schlüsselwörter clear und fill: Z.B. löscht clear line die angegebene Linie. fill circle zeichnet einen schwarz gefüllten Kreis, während clear fill circle einen Kreis und seine Innenfläche löscht.
Nachdem der Benutzer eine Taste gedrückt hat (siehe unten) wird der Fensterinhalt gelöscht mit dem clear window-Befehl. Wenn Sie ihren Drucker geöffnet haben (z.B. wenn Sie den open printer-Befehl gesendet haben) beendet clear window die aktuelle Seite, sendet es an den Drucker und beginnt eine neue Seite.
Der nächste Befehl im Beispiel ist der text-Befehl, der seinen
Text an die angegebene Stelle schreibt. Die Position gibt die linke
untere Ecke des Textes an. Um die Ausrichtung zu ändern, können
Sie als drittes Argument bestimmte Zwei-Zeichen-Strings angeben. Der
erste gibt die horizontale Ausrichtung an, mit "l" (Text ist linksbündig, "r"(rechtsbündig) oder "c" (zentriert). Das zweite Zeichen gibt die senkrechte Ausrichtung
an, mit "t"(top, oben), "b" (bottom, unten) oder "c" (zentriert).
Gültige Argumente sind "ct", "rb", "lc", ... Übrigens:
Textausrichtung kann auch durch pokingin "textalign"
erzielt werden.
Schließlich: close window schließt das Grafik-Fenster.
Aber bevor das Fenster geschlossen ist, wartet der inkey$-Befehl bis der Benutzer eine beliebige Taste drückt (in der Tastatur oder im grafischen Fenster) und dann gibt diese Taste einen String zurück. In diesem Beispiel ist nicht wichtig, welche Taste gedrückt wurde. Deshal brauchen Sie nur inkey$ (ohne Zuordnung) zu schreiben.
Einige wichtige, nicht druckfähige Tasten (z.B. die Funktions- oder Cursortasten) geben folgende längere Strings aus: up, down, left, right, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, esc, ins, del, home, end, scrnup, scrndown, enter, tab, backspace. Wenn ihre Tastatur andere Tastaturcodes ausgibt als meines, oder wenn Sie eine Taste drücken, die Yabasic nicht erkennt, werden Sie einen ziemlich langen String erhalten (z.B. key1b5b31317e).
Normalerweise wartet Yabasic's inkey$ bis der Benutzer eine Taste drückt; aber wenn die inkey$-Funktion
einen String ausgeben soll, obwohl keine Taste gedrückt wurde, können
Sie ein Zeit-Aus-Argument hinzufügen (in Sekunden) .
Z.B. inkey$(9)
gibt ein Zeichen aus, wenn der Benutzer sofort eine Taste drückt, aber
in jedem Fall automatisch nach 9 Sekunden. Dann wird ein 'leerer' String ausgegeben. Beachten
Sie, dass auch ein Zeit-Aus von 0 Sekunden möglich ist, ein üblicher
Wert in anderen BASICs. (Was aber nicht immer sinnvoll ist!)
Wenn Sie eine Maustaste in einem Grafik-Fenster drücken, werden Sie einen String wie "MB1d+1:0100,0200" erhalten, was für "Maustaste 1 wurde mit gedrückter shift-Taste bei x=100, y=200 gedrückt" steht. Genauso steht "MB2u+0:0300,0400" für "Maustaste 2 wurde ohne shift oder control-Taste bei x=300, y=400 gedrückt".
Die Funktionen mousex(), mousey(), mousemod() und mouseb()
können benutzt werden, um die Angaben aus dem String auszuwerten, der
von inkey$ geliefert wird:
a$=inkey$:if
(left$(a$,2)="MB") print mousex(a$),mousey(a$),mousemod(a$),mouseb(a$)
Wenn Sie das Argument weglassen (z.B. print mousex) erhalten Sie die Werte des letzten Maus-Ereignisses durch inkey$ zurück. Dies bedeutet, dass Sie mousex nicht benutzen können, um die Position der Maus zu verfolgen, weil sein Wert nur vom inkey$-Befehl erneuert wird. Schließlich ergibt mouseb einen positiven Wert, wenn die Taste gedrückt wurde und einen negativen Wert, wenn die Taste losgelassen wurde.
open window 200,200 open printer circle 100,100,80 close printer close window
open #1,printer print #1 "Hallo Welt !" close #1
Zurück zum Inhaltsverzeichnis
...
Weitere Grafiken (Nur für Grafik-Bildschirm)
open window 600,400 window origin "lb" new curve for x=-3 to 3 step 0.1: rem Diese Schleife zeichnet eine sinus-Funktion y=sin(x) line to 300+90*x,200+150*y next x rectangle 10,10 to 110,60: rem zeichne die Legende text 55,35,"Sinus-Funktion","cc" inkey$ close window
Sobald der Ursprung verändert wurde, gilt er für jede grafische Operation.
Zurück zum Inhaltsverzeichnis ...
Yabasic erlaubt es, rechteckige Bereiche auf dem Bilschirm mit einfachen Befehlen zu erzeugen und zu ändern ...:
open window 200,200 for a=0 to 200 step 10 line a,0 to a,200:line 0,a to 200,a: rem Zeichne einige Muster auf den Bildschirm next a rem Dies ist das Bild eines Sterns star$="24,24:00c10000e10000f10000f10008f3" star$=star$+"0008f30008f700fff700ffff30fff" star$=star$+"fffefffffefffff0ffff70eff700e" star$=star$+"ff000cff100eff300fff70cfff70e" star$=star$+"f7ef1ef1cf3e700e3e100c3000000" for a=50 to 150 saved$=getbit$(a,150,a+24,150+24): rem speichern des alten Fensterinhalts bitblit star$ to a,150,"or": rem Den Stern an einen neuen Ort setzen pause 0.1 bitblit saved$ to a,150: rem Alten Fensterinhalt wiederherstellen next a
Dieses Programm bewegt einen kleinen Stern über das
Fenster. Yabasic speichert Bitmaps in üblichen Strings, z.B. die Stern-Bitmap
ist in der Variablen star$
enthalten.
Die getbit$()-Funktion
gibt so einen Bitmap-String zurück, wenn sie mit den Koordinaten eines
Rechtecks aufgerufen wird. Im Beispiel speichert die Zeile saved$=getbit$(a,150,a+24,150+24) den Inhalt eines 24x24 ixel-Rechtecks mit den Ecken (a,150)
und (a+24,150+24) in der Variablen saved$.
Sobald Sie einen Bitmap-String haben, können Sie
ihn mit dem putbit-Befehl
im Fenster darstellen.
Z.B. zeigt putbit star$ to a,150,"or" die Bitmap, die in star$ enthalten ist, auf dem Bildschirm auf
Position (a,150).
Das vierte mögliche Argument ("or" imBeispiel) gibt an,
wie die Pixel des Fensters mit denen der Bitmap verknüpft werden sollen:
Verknüpfung |
Ergebnis |
---|---|
"and" |
Das Pixel wird gesetzt, wenn das Fenster- und das Bitmap-Pixel gesetzt ist. |
"or" |
Das Pixel wird gesetzt, wenn das Fenster- und/oderdas Bitmap-Pixel gesetzt ist. |
"replace" |
Das Pixel wird gesetzt, wenn das Bitmap-Pixel gesetzt ist. Dies ist die Vorgabe. |
"xor" |
Das Pixel wird gesetzt, wenn entweder ein Fenster- oder ein Bitmap-Pixel gesetzt ist. |
"nand" |
Das Pixel wird gesetzt, wenn nicht beide, Fenster- und Bitmap-pixel, gesetzt sind. |
"clear" |
Wenn das Bitmap-Pixel gesetzt ist, wird das entsprechende Fenster-Pixel gelöscht |
"1" |
Das Fenster-Pixel wird gesetzt, ohne Beachtung des Bitmap-Pixels |
"0" |
Das Fenster-Pixel wird gelöscht, ohne Beachtung des Bitmap-Pixels |
Wenn Sie das Verknüpfungsargument weglassen, wird "replace" angenommen.
Aber es gibt eine wichtige Einschränkung: Sie können zwar Bitmaps im Fenster erzeugen, jedoch nicht drucken!
Zurück zum Inhaltsverzeichnis ...
Ab und zu ist es erforderlich, einem Programm Anfangswerte anzugeben.
restore namen read maxnum dim namen$(maxnum) for a=1 to maxnum:read namen$(a):next a label schleife input "Bitte gib eine Zahl ein: " nummer:nummer=int(nummer) if (nummer>=1 and nummer<=maxnum) then print nummer,"=",namen$(nummer) goto schleife endif print "Schade, kann "; nummer; " nicht wandeln " label namen data 9,"eins","zwei","drei","vier","fünf","sechs" data "sieben","acht","neun"
Wenn Sie dieses Programm starten, erhalten Sie folgende Ausgaben:
Bitte gib eine Zahl ein: 2 2=zwei Bitte gib eine Zahl ein: 3 3=drei Bitte gib eine Zahl ein: 8 8=acht Bitte gib eine Zahl ein: 12 Schade, kann 12 nicht wandeln
Wenn Sie von der zeilenweisen Reihenfolge abweichen möchten, um die data-Inhalte zu lesen, können Sie den restore-Befehl benutzen. Im obigen Beispiel bewirkt restore namen, dass der nächste read-Befehl die Daten ab dem Label namen liest.
Komplexere Aufgaben können sogar multidimensionale
Arrays erfordern, mit mehr als einem Index.
dim
matrix(10,10) richtet ein zweidimensionales
Array ein. Es kann bis zu zehn Array-Dimensionen geben, falls erforderlich.
Arrays bieten mehr Funktionsumfang als in diesem
einfachen Beispiel gezeigt wurde.
Darüber können Sie
mehr erfahren im Abschnitt Erweiterter
Einsatz von Arrays.
Es sollte erwähnt werden, dass die Funktion
des obigen Beispiels auch durch völlig anderen Programmaufbau erzielt
werden kann:
- label schleife
input "Bitte gib eine Zahl ein: " nummer:nummer=int(nummer) on nummer+1 gosub schade,eins,zwei,drei,vier,fuenf,schade goto schleife label schade:print "Schade, kann "; nummer; " nicht wandeln ":end label eins:print "1=eins":return label zwei:print "2=zwei":return label drei:print "3=drei":return label vier:print "4=vier":return label fuenf:print "5=fünf":return
Diese Programm erzeugt dieselbe Ausgabe wie das Beispiel darüber.
Und beachtenSie, dass das on-Konstrukt auch als
on goto benutzt
werden kann.
Zurück zum Inhaltsverzeichnis ...
Sehen Sie sich diese Programm an:
dim a$(3,4) for a=1 to 3:for b=1 to 4 a$(a,b)=str$(a)+","+str$(b) next b:next a print_array(a$()) dim a$(5,6) print_array(a$()) sub print_array(b$()) local x,y,a,b x=arraysize(b$(),1) y=arraysize(b$(),2) for a=1 to x for b=1 to y b$(a,b)="("+b$(a,b)+")" print left$(b$(a,b)+" ",10); next b print next a print end sub
Wenn Sie diese Programm ablaufen lassen, werden Sie etwa dieses sehen:
(1,1) (1,2) (1,3) (1,4) (2,1) (2,2) (2,3) (2,4) (3,1) (3,2) (3,3) (3,4) ((1,1)) ((1,2)) ((1,3)) ((1,4)) () () ((2,1)) ((2,2)) ((2,3)) ((2,4)) () () ((3,1)) ((3,2)) ((3,3)) ((3,4)) () () () () () () () () () () () () () ()
Zuerst richtet dieses Programm das String-Array a$(4,3) ein und ordnet jedem Element einen String zu, der aus den Indizes der einzelnen Elemente besteht. Dann ruft das Programm die Subroutine print_array() auf, die das Array ausgibt.
print_array() akzeptiert ein Array als Parameter. Wenn die Subroutine aufgerufen wird (z.B. print_array(a$())), wird das Array trotz fehlender Indizes (z.B. einfach a$() ) übergeben.
Zuerst ermittelt die Subroutine die Größe
des übergebenen Arrays.
arraysize(b$(),1) gibt dieGröße der ersten Dimension des Arrays b$() wieder.
Genauso gibt arraydim(b$()) die Anzahl der Dimension des angegebenen Arrays ( 2
im Beispiel) aus.
Die Routine print_array() gibt nicht nur das
Array aus, sondern ergänzt es auch.
Der Ausdruck b$(a,b)="("+b$(a,b)+")" versieht jedes Element mit Klammern.
Sobald print_array() ein zweites mal aufgerufen wird, werden die Array-Elemente doppelt
ergänzt, z.B. werden sie in doppelte Klammern eingeschlossen.
Dies zeigt, dass das Array a$(), das der Subroutine
übergeben wird, sofort ergänzt wird. Obgleich die Subroutine einen
anderen Namen ( b$() ) für das Array benutzt, so hat sie doch keine lokale
Kopie des Arrays. Stattdessen arbeitet sie mit dem Array des Hauptprogramms
( a$() ). Dieses Verhalten wird "Aufruf
durch Adressverweis" genannt, anders
als die Behandlung von Nicht-Array-Parametern (einfache Strings und Zahlen)
die "Aufruf durch Wertübergabe" genannt wird.
Nach erstem Aufruf der Routine print_array(), führt das Beispielprogramm erneut dim für das Array a$() aus, das einfach die Array-Größe
ändert. Dieses Neu-Dimensionieren (Sie können auch redim schreiben), behält den ganzen alten Inhalt und richtet jedes
neue Element mit einem leeren String ein (oder mit 0.0 für numerische Arrays).
Wenn Sie versuchen, die Größe eines Arrays zu verkleinern (z.B.
aus dim a(10) ein
dim a(5) machen wollten
), wird dieser Befehl nicht ausgeführt.
Zurück zum Inhaltsverzeichnis ...
Um die Beispiele dieses Abschnitts zu verstehen, wollen wir annehmen, dass eine Datei test.dat im aktuellen Verzeichnis vorhanden ist und dass sie die folgenden drei Zeilen enthält:
eins zwei drei vier fünf sechs sieben acht neun
Das nächste Beispiel öffnet diese Datei und gibt seinen Inhalt aus:
open 1,"test.dat","r" while(!eof(1)) input #1 a$ line input b$ print "a$=\"",a$,"\", b$=\"",b$,"\"" wend
Dateimodus |
Zweck |
"r" |
Öffnen zum Lesen, Lesebeginn am Anfang der Datei |
"w" |
Öffnen zum Schreiben, bisheriger Inhalt wird gelöscht und überschrieben |
"a" |
Öffnen zum Schreiben durch Anhängen
an die bestehende Datei |
Wenn Sie mit einer Dateibearbeitung fertig sind, sollten Sie sie schließen (close), um die Dateinummer für den nächsten open-Befehl frei zu machen.
Es gibt eine besondere Variante des open-Befehls, der es ermöglicht zu prüfen, ob sich eine Datei öffnen lässt:
Zurück zu unserem obigen Beispielprogramm. Wenn sie es ablaufen lassen, werden Sie folgende Ausgabe erhalten:
a$="eins",b$="zwei drei" a$="vier", b$="fünf" a$="sechs", b$="sieben acht neun"
Dies gilt unabhängig davon ob Sie aus einer Datei lesen (z.B. input a$) oder von einem Terminal (z.B. input #1 a$)
open #1,"test.dat","w":print #1 "abcdefghijkl";:close #1 open #1,"test.dat","r" print chr$(peek(#1))," "; seek #1,2:print chr$(peek(#1))," "; seek #1,3,"here":print chr$(peek(#1))," "; seek #1,-2,"end":print chr$(peek(#1))," "; print tell(#1) close #1
Das Programm erzeugt zuerst eine Datei test.dat, die den Text "abcdefghijkl" enthält. Danach werden einzelne Zeichen aus der Datei ausgelesen mit peek(). Zwischen den 'Peeks' wird die Position in der Datei durch seek geändert; schließlich ermittelt tell() die Position in der Datei. Der Ablauf des Programms erzeugt eine Ausgabezeile: "a c g k 11".
seek hat zwei oder drei Argumente. Die Dateinummer,
die neue Startposition in der Datei und (wahlweise) die Position, von der aus
die Startposition gezählt wird. Diese Position kann sein "begin"
(Die Startposition zählt vom Anfang der Datei. Das ist die Vorgabe), "here"
(Die Startposition zählt von der aktuellenPosition in der Datei) und "end"
(Die Startposition zählt vom Ende der Datei).
Schließlich können Sie auch (ähnlich wie beim open Kommando) seek() in der einer if-Bedingung benutzen (z.B. if (!seek(...)) error "Shit !"); damit kann man auf einfache Weise den Erfolg eines
seek() testen.
a=open("test.dat","r") while(!eof(a)) input #(a) a$ print a$ wend
open() ist eine Funktion, um die erste freie Dateinummer zu ermitteln (vielleicht 1). Diese Dateinummer können Sie mit dem print-Befehl benutzen. Aber denken Sie daran, dass Yabasic runde Klammern nach der Raute erwartet (wie in input #(a) a$).
Zurück zum Inhaltsverzeichnis ....
Obwohl Yabasic überhaupt nicht als Script-Sprache entwickelt wurde, kann es begrenzt mit dem Betriebssystem zusammenarbeiten:
if (peek$("os")="unix") then command$="ls" else; command$="dir /w" endif cont$=system$(command$) print "Dies ist der Inhalt des aktuellen Verzeichnisses:" print cont$ print len(cont$)," Zeichen wurden ausgegeben."Die system$()-Funktion ist das Herz dieses Programms. Es übergibt seine Argumente zur Ausführung an das Steuerprogramm (shell) des zugrundeliegenden Betriebssystems. Unter Unix ist es die bourne-shell sh und unter Windows ist es die command.com, die die Argumente aus der system()-Funktion ausführen wird.
Wenn ich dieses Programm unter Windows95 ausführe, erhalte ich folgende Ausgabe:
Dies ist der Inhalt des aktuellen Verzeichnisses: Datenträger in Laufwerk C: heisst WIN95 Seriennummer des Datenträgers: 0B1D-10F8 Verzeichnis von C:\WINDOWS\Desktop FLOPPY.LNK EMACS.LNK DRUCKER.LNK T.YAB TELNET.LNK TEST.YAB MICROS~1.LNK CD.LNK PLATTE.LNK WATCOM~1.LNK [YABDOK~1] TEST.DAT WINDOW~1.LNK [KINO] 12 Datei(en) 2.693 Bytes 4 Verzeichnis(se) 199.753.728 Bytes frei 456 Zeichen wurden ausgegeben.Natürlich werden Sie etwas anderes von Ihrem System erhalten (Besonders falls Sie keine deutsche Windowsinstallation haben).
Weil dieses Yabasic-Programm sowohl unter Unix wie auch unter Windows arbeiten soll, muss das Argument der system$()-Funktion (command$) passend zum Betriebssystem gewählt werden. Um die Art des Betriebssystems zu ermitteln ("unix", "Linux" oder "windows"), enthältdas Programm das Kommando peek$("os").
Nun gibt es aber noch einen sehr ähnlichen Befehl system() (ohne $), der die Ausgabe aufgrund eines ausgeführten Kommandos nicht als String übernimmt, sondern stattdessen den vom Kommando veranlassten Text auf dem Bildschirm ausgibt.
system() gibt einen numerischen Wert zurück, der vom ausgeführten Kommando erzeugt wurde.
Wenn Sie diesen Wert nicht benötigen, können Sie ihn einfach außer Acht lassen.
z.B. system("dir") (ohne Zuordnung) ist genauso gültig wie a=system("dir").date$ (Datum) und time$ (Zeit)
Um Datum und Zeit aktuell auszugeben können Sie schreiben:
- print date$," ",time$
Dies erzeugte folgende Ausgabe (Ihre Ergebnis wird natürlich anders aussehen, weil sich die Zeiten ändern):
- 5-08-28-1998-Fri-Aug 13-51-53-0
Der date$-String hat sechs Stellen: 5 ist der Wochentag (0-6, 0 ist Sonntag, 6 Samstag), 08 ist der Monat (01-12), 28 ist der Tag desMonats (01-31), 2000 ist das Jahr, Fri ist der Name des Tages und Aug ist der Name des Monats.
Der time$-String hat vier Stellen: 13 ist die Stunde (00-23), 51 ist die Minute (00-59), 53 ist die Sekunde (00-59) und 0 ist die Zeit, die seit dem Programmstart vergangen ist.
Da die meisten Stellen von date$ und time$ eine feste Länge haben (Mit Ausnahme der letzten Stelle in time$), ist es leicht, die Felder mittels der mid$-Funktion auszuwerten.
Zurück zum Inhaltsverzeichnis ....
Peek und Poke
peek und poke sind eine Schnittstelle zu einigen Internas von Yabasic und erlauben den Status von Yabasic's und sein Verhalten abzufragen und zu verändern. Anders als bei früheren Homecomputern, können Sie nicht einfach irgendwo im Arbeitsspeicher herum-peeken und -poken. Nur einige reservierte Variable sind erlaubt. Hier ein Beispiel:
- print peek$("infolevel")
poke "infolevel","diagnostic"Dies wird den aktuellen infolevel ausgeben und ihn dann auf "diagnostic" ändern.
An diesem Beispiel erkennen Sie: peek und poke akzeptieren String-Argumente (einige poke-Kommandos akzeptieren auch eine Ganzzahl als Argument) und peek kann einen String zurückgeben (in diesem Falle erscheint er als peek$).
Trotzdem gibt es schon jetzt einige peek's und poke's, deshalb sollen sie hier vollständig aufgeführt werden:
- peek$("infolevel")
- Gibt den aktuellen infolevel zurück.
- poke "infolevel", "error"
- Setzt den infolevel auf "debug", "note", "warning", "error" oder "fatal".
- peek("fontheight")
- Gibt in Pixeln die Schrifthöhe des Grafik-Textes aus.
- peek$("os")
- Gibt das Betiebssystem aus (operating system ,"windows" oder "unix" oder "Linux")
- poke "textalign","cc"
- Dieses bestimmt die Textausrichtung, bezogen auf den Punkt, der im text-Befehl angegeben ist.
- peek$("textalign")
- Gibt einen String aus, der die aktuelle Einstellung der Textausrichtung enthält. Mögliche Werte sind "cb", "rc", "cc", ...
- peek("version")
- Dies gibt die Yabasic Version aus (z.B. 2.47).
- peek$("library")
- Dies gibt die Library aus, die das peek enthält. Wenn vom Yabasic-Programm aufgerufen, wird "main" ausgegeben.
- peek("argument")
- Gibt die Anzahl der Argumente aus, die dem Yabasic-Programm übergeben wurden. Dies kann nützlich sein, wenn Sie Yabasic nur von der Kommandozeile aus aufgerufen haben. Nehmen wir an, Sie hätten yabasic test.yab 1 2 3 eingegeben. Dies würde den Yabasic-Interpreter starten, um das Programm test.yab ablaufen zu lassen. In test.yab könnten Sie dann peek("argument") abfragen, um die Anzahl der Argumente zu erhalten, die in der Kommandozeile übergeben wurden. Im Beispiel würde peek("argument") eine 3 ausgeben, weil es drei Argumente ("1", "2" und "3") über die Kommandozeile gab. (Der Programmname "test.yab" zählt nicht als Argument).
Um die Argumenten-Inhalte wieder zu erhalten, benutzen Sie peek$("argument"). Jeder Aufruf von peek$("argument") verringert den Wert, der von peek("argument") zurückgegeben wird um eins.
- peek$("argument")
- Jeder Aufruf von peek$("argument") gibt eines der Kommandozeilen-Argumente zurück, die dem Yabasic-Program übergeben wurden. Lautete beispielsweise der Aufruf yabasic test.yab 1 2 3, dann würde der erste Aufruf mit peek$("argument") eine "1" zurückgeben, der zweite Aufruf eine "2", der dritte "3" und jeder weitere Aufruf würde einen leeren String ("") zurückgeben.
Yabasic bietet begrenzte Unterstützung, um binäre Dateien zu bearbeiten:
- peek(#1)
- Dies gibt das nächste Byte der Datei #1 aus (#2 ... #9 sind natürlich auch möglich).
Merke, dass es keine Anführungszeichen rund um #1 gibt.- poke #1,byte
- Schreibt das angegebene Byte in die Datei #1. byte kann jede Zahl 0...255 sein.
- poke #1,string
- Schreibt den Inhalt von string$ in Datei #1.
Diese peek's und poke's für binäre Dateien sollten nicht mit normalen Datei-I/O-Zugriffen mit print und input gleichgesetzt werden. Sie könnten Probleme mit Yabasic's interner Pufferung bekommen.
Und übrigens ist es ratsam, solche Dateien im Dateimodus "b" (binär) zu öffnen.Zurück zum Inhaltsverzeichnis ...
Fortgeschrittenes Drucken:
print at(), print colour und print usingFür interaktive Programme möchten Sie vielleicht auf bestimmte Stellen drucken. Probieren Sie das nächste Beispiel:
clear screen print at(10,5) "1 -- Einstellungen" print at(10,7) "2 -- sichern" print reverse at(10,9) "3 -- Beenden" input at(5,12) "Ihre Wahl: " a$Wenn Sie dieses Programm ablaufen lassen, erhalten Sie einen Bildschirm mit dem folgenden Layout. Beachten Sie, dass die dritte Zeile in umgekehrten Farben erscheint:
1 -- Einstellungen 2 -- sichern 3 -- Beenden Diese Zeile wird reversiv dargestellt ! Ihre Wahl:Merken Sie sich, Sie sollten clear screen aufrufen, bevor Sie invers ausgeben.
Danach sollten Sie auch in print oder input-Befehlen die at()-Klausel benutzen, um zu jeder Position des Bildschirms zu gelangen
anzugeben mit den beiden Argumenten der at()-Klausel).
at() kann auch als @() geschrieben werden.Wenn Sie Farbe brauchen, dann können Sie diese Programm testen:
rem Alles vorbereiten clear screen dim c$(8) for a=1 to 8:read c$(a):next a rem mehrere Farben ausgeben for a=1 to 8:for b=1 to 8 print colour(c$(a),c$(b)) " -- Hallo -- "; next b:next a rem Ein Rechteck über den Bildschirm bewegen a$=getscreen$(1,1,10,10) for a=1 to 100:putscreen a$ to a,a:next a rem verfuegbare Farben data "black","white","red","blue","green","yellow","magenta","cyan"Dieses Programm gibt "-- Hallo --" mit den acht Farben aus, die Yabsic kennt: black, white, red, blue, green, yellow, magenta und cyan.
Mit der Anweisung colour(f$,b$) (oder color(f$,b$)) können Sie die Vorder- und Hintergundfarbe für die nachfolgende print-Anweisung festlegen.Der Zweite Teil des Beispielprogramms bewegt ein 10x10-Pixel-Rechteck mit Zeichen über den Bildschirm.
Die getscreen$(xfrom,yfrom,xto,yto) Funktion wandelt den Inhalt des angegebenen Bildschirm-Rechtecks in eine String,
der in einer String-Variablen (a$ im Beispiel) abgespeichert werden kann.
Ist einmal ein solches Rechteck erzeugt, kann man es an jedem Ort des Bildschirms mit dem putscreen Kommando erscheinen lassen.Weil nicht alle Bildschirme die gleiche Größe haben (natürlich ist 80x25 Zeichen die gebräuchlichste Größe), möchten Sie vielleicht die aktuellen Dimensionen Ihres Bildschirms wissen. Dafür gibt es zwei vordefinierte Variable. Die Breite Ihres Bildschirms kann durch besondere peek's ausgelesen werden.
peek("screenwidth") holt die Breite des Bildschirms als Zeichenanzahl , währen peek("screenheight") die Höhe zurückgibt.
Beide peeks sind nur unmittelbar nach clear screen verlässlig.print using (Zur Formatierung von Zahlen)
Um die Zahlendarstellung zu steuern, benutzt man die print using-Anweisung. print 12.34 using "###.####" erzeugt 12.3400.
Der Formatstring ("###.####") besteht aus Rauten (#) mit einem beliebig plazierten Punkt und das repräsentiert das Erscheinungsbild der zu druckenden Zahl.
Hier einige Beispiele:
Anweisung
Ausgabe
Bemerkungen
print "=",12.34 using "###.####","="
= 12.3400=
Die Ausgabe wird von links mit Leerzeichen aufgefüllt und mit Nullen von rechts, wie es die Formatvorgabe erfordert.
print "=",12.36 using ##.#,"="
=12.4=
Die letzte Stelle der Ausgabe ist gerundet.
print "=",12.34 using #.#,"="
=***=
Die Zahl kann mit dieser Vorgabe nicht dargestellt werden.
Diese Art der Formatierung ist klar und einfach, aber nicht sehr flexibel.
z.B. ist es nicht möglich, Zahlen linksbündig oder mit führenden Nullen auszugeben.Um solche Effekte zu erzielen, erlaubt die print using Anweisung den Format-String auch wie in der printf()-Funktion der Programmiersprache C.
Einige Beispiele:
Print-Anweisung
Ausgabe
print "==",str$(12.123455,"%08.3f"),"=="
==0012.123==
print "==",str$(12.123455,"% 8.2f"),"=="
== 12.12==
print "==",str$(12.123455,"%- 6.2f"),"=="
==12.12 ==
- . = Position des Dezimalpunktes
- 3 bzw. 2 = Anzahl Stellen rechts des Dezimalpunktes
- 8 bzw. 6 = insgesamt acht bzw. sechs Zeichen
- 0 = Mit diesem Zeichen links auffüllen (hier: Nullen)
- f = Festkomma, die Position entsprechend den Nachkommastellen
- e oder E = Fließkomma- und Exponentialdartstellung
- g oder G = Gleitkomma je nach Wert, ggf. exponential
- - = rechts mit Leerzeichen auffüllen
- + = immer Vorzeichen (+/-) angeben
Mehr über diese Formate kann in jedem Buch über die Sprache C gefunden werden.
All diese Formate können auch für die str$()-function verwendet werden.
Zurück zum Inhaltsverzeichnis ....
Ende offen
Einige Eigenschaften von Yabasic sind immer noch nicht erklärt. Hier ist ein Beispielprogramm, das sie verwendet:
- 10 beep
pause 1 goto 10Dieses Programm piept jede Sekunde einmal:
- beep erzeugt das Piepen (kann auch als bell geschrieben werden) und
- pause erzeugt die Pause (kann auch als wait geschrieben werden),
sein Argument ist die Verzögerung in SekundenUnd das Programm benutzt eine Zeilennummer (10) um eine bestimmte Zeile zu kennzeichnen. Diese Eigenschaft macht Yabasic kompatibel zu traditionellem BASIC. Zeilennummern sind spezielle Labels. Sie haben folgende Eigenschaften:
- Zeilennummern dürfen nur am Anfang von Zeilen stehen.
- Nicht jede Zeile muss eine Nummer haben und sie müssen nicht fortlaufend sein.
- Zeilennummern können auch von der restore-Anweisung angesprungen werden.
Tastatur-Interrupts
Eine Eigenschaft, die Sie gebrauchen könnten, ist die Fähigkeit, Tastatur-Interrupts zu unterdrücken (z.B. drücken von Ctrl-C).
Normalerweise würde Yabasic sofort beenden, wenn der Benutzer Ctrl-C drückt.
Das kann wie folgt abgefangen werden:
- on interrupt continue
Nach Verarbeitung dieser Anweisung werden Tastatur-Interrupts nicht mehr beachtet.
Das alte Verhalten wird wieder hergestellt mit dem Kommando on interrupt break.Zurück zum Inhaltsverzeichnis ...
Index- Inhaltsverzeichnis
Index der Yabasic-Schlüsselwörter
A: abs() acos() and and() arraydim() arraysize() asc() asin() at() atan()
B: beep bell bin$() break
C: chr$() circle clear circle clear rect clear screen clear window close close printer close window colour color compile continue cos() curve
D: date$ data dec() dim doc docu docu$() dot
E: else elsif end endif end sub eof() eor() error euler execute execute$ exit exp() export
F: fi fill for frac()
G: getbit$() getscreen$() glob() gosub goto
H: hex$()
I: ifimport inkey$ input input at input # instr() int() interrupt
J:
K:
L: label left$() len() line line input line to locallog() lower$() ltrim$()
M: map() mapx() mapy() max() mid$() min() mod() mouseb mousex mousey
N: new curve next not numparams
O: on gosub on goto open open printer open window or or() origin
P: pause peek peek$ pi poke print print at print using print # printer putbit putscreen
Q:
R: ran() rectangle read rem redim repeat restore return reverse right$() rinstr() rtrim$()
S: seek() sig() sin() static step split() sqr() sqrt() str$() subsystem() system$()
T: tan() tell text then time$ token() trim$()
U: until upper$() using
V: val()
W: wait wend while window window origin
X: xor()
Y:
Z:Zurück zum Inhaltsverzeichnis ....
Von Yabasic benutzte Ausdrücke, die nicht als beliebige Variable benutzt werden sollten
argument
arraysize
at
backspace
cc
cb
circledate$
debug
del
downend
enter
error
escfatal
fontheight
f1...f12
homeinfolevel
ins
interrupt
left
library
lower$main
maxnum
note
new curve
numparamson
origin
os
pi
printerrc
rightscreen
screenheight
screenwidth
scrdown
scrup
statictab
textalign
time$
up
upper$version
warning
window
Index der Abschnitte
Arrays
Binäre Dateien
Bitmanipulation
Schreibweise von Schlüsselwörtern und Variablen
Kommandozeilen-Agumente
Verzweigungen mit der if-Anweisung
Escape-Folgen in Strings
Zahlen formatieren
Maus einlesen
Globbing
Wie die input-Anweisung eine Zeile aufteilt
Tastatur-Interrupts
Zeilennummern
Viele Kommandos in einer Zeile
Text drucken
Zugriff auf Dateien
In Windows Pfad angeben
VariableZurück zum Inhaltsverzeichnis ....
Über Yabasic
Entwicklung
Die Idee Yabasic entstand etwa um Ostern 1995. Eine erste Version wurde etwa einen Monat später vollendet, jedoch fehlten noch viele Fähigkeiten. Nach diesem schnellen Start folgte eine lange Zeit ,in der Fähigkeiten hinzugefügt und Fehler behoben wurden, was mehr oder weniger bis heute so geblieben ist.
Die einzige Unterbrechung während jener friedvollen Tage gab es im Sommer 1996, als ich meinen Windows95-Rechner bekam. Yabasic darauf zu übertragen brauchte zwei Wochen, und um ein Installationsprogramm zu schreiben brauchte ich einen Monat.
Flex und Bison
Sie haben vielleicht im vorigen Absatz bemerkt, dass Yabasic einen ziemlich schnellen Start hatte. Das beruht hauptsächlich auf Flex und Bison, hervorragende Werkzeuge um Yabasic zu verwirklichen.
Bison und Flex bringen die Grammatik und erzeugen ein C-Programm, das diese Grammatik umsetzt. Das einzige, was dem Programmierer bleibt, ist dieses Skelett mit Fleisch zu füllen und mit Haut zu bedecken.
Dieses Vorgehen ist bemerkenswert wirkungsvoll: 17 KBytes der Flex- und Bison-Instruktionen generieren 129 KBytes C-Code, was verglichen werden muss mit 108 KBytes C-Code, den ich schrieb. Zusammen sorgen sie für die Funktionalität von Yabasic. Deshalb kann man sagen, der größere Teil des Programmkodes wurde von Flex und Bison generiert!
Ausführen eines Yabasic-Programms
Obwohl Yabasic sich meist verhält wie ein Interpreter, ist er in Wirklichkeit keiner. Eher ist es ein Compiler.
Wenn Sie ihm irgendein BASIC-Programm zur Ausführung geben, wird das BASIC so kompiliert, dass dies Instruktionen für eine stapelverarbeitende Maschine darstellt. Und erst diese Instruktionen werden dann von YABASIC interpretiert, und zwar so, dass Sie von der Stapelverarbeitung nie etwas merken.
Sie können die Zeit, die für diesen Prozess erforderlich ist, anzeigen. Dazu rufen Sie Yabasic mit dem Infolevel note auf.Zurück zum Inhaltsverzeichnis ...
Copyright
Yabasic darf nur kopiert werden unter Anerkennung der Artistic License oder der GNU General Public License (GPL).
Frühere Versions von Yabasic wurden nur mit der GPL versehen und es wurde Rückwärtskompatibilität erhalten.
Seit Version 2.60 haben Sie die Wahl, Yabasic unter den Bestimmungen der Artistic License zu benutzen, die Sie berechtigt,
Yabasic in mehr oder weniger kundengerechter Art zu benutzen und zu vetreiben, verbunden mit der Erlaubnis, brauchbare Veränderung zu machen, solange dem Urheber Einblick in die Fortentwicklung von Yabasic gewährt wird.Unabhängig davon, welche Lizenz Sie für Yabasic wählen (GPL oder Artistic), gilt dies nicht für Ihre eigenen Yabasic-Programme. Die Programme die Sie schreiben sind Ihre eigene Arbeit und Sie dürfen jede Lizenz Ihrer Wahl benutzen.
Nun einige Beispiele, was unter den Regeln der Artistic License möglich ist:
- Stellen Sie Yabasic in Ihre eigene Webseite , CD oder ein anderes Medium. Nehmen Sie Geld für ihren Yabasic-Verteil-Service.
- Schreiben Sie ihre eigenen Yabasic-Programme, übernehmen Sie Yabasic in ein Paket und verkaufen Sie es.
"Verkaufen" ist mehr als nur Geld für die Verteilungskosten und die Zeit zu nehmen.
Sie können echten Gewinn mit ihren eigenen Programmen machen.- Verändern Sie Yabasic, verändern Sie die Leistungsmerkmale und Möglichkeiten, verkaufen Sie die veränderte Version.
Wenn Sie immer noch zweifeln, dann prüfen Sie anhand der obigen Lizenzen.
Zurück zum Inhaltsverzeichnis ...
Übersetzt aus dem Englischen von Peter.Vieweger@visselhoevede.de , Edition 25.04.2000