Deutsche Übersetzung des Handbuchs

Dieses Dokument enhält nicht die ausführliche Befehlsreferenz. Diese finden Sie im englischen Benutzerhandbuch und in der Android-Direkthilfe.

1. X11-BASIC Version 1.25 Benutzerhandbuch

(c) 1997-2018 Markus Hoffmann
(kollo@users.sourceforge.net)
(siehe auch: http://x11-basic.sourceforge.net/)

1.1. Über dieses Dokument

Dieses Dokument beschreibt die Funktionen von X11-Basic. Sie finden Informationen zum X11-Basic-Interpreter (das Programm xbasic unter Unix oder xbasic.exe unter Windows) und dem Compiler (das Programm xbc unter UNIX oder xbc.exe unter Windows) sowie zur Sprache selbst. Für eine kompaktere Beschreibung bzw. Einführung möchten Sie vielleicht die man-page x11basic(1) oder die man-page des X11-Basic-Compilers xbc(1) jeweils von Fall zu Fall zu rate ziehen.

Die neuesten Informationen und Updates sowie neue Versionen von X11-Basic finden Sie unter http://x11-basic.sourceforge.net/ .

1.2. Vorwort

Schön, daß Sie sich für mein kleines Projekt X11-Basic interessieren. Es wird gelegentlich der Wunsch an mich herangetragen, das Benutzerhandbuch zur Programmiersprache, welches es derzeit nur in einer englischen Version gibt, ins Deutsche zu übersetzten. Da ich froh bin, daß es ein einigermaßen brauchbares Handbuch überhaupt gibt und kaum Zeit habe, noch eine deutsche Version zu machen, werde ich an dieser Stelle wenigstens einige grundlegende Hilfestellungen zum Benutzen der Programmiersprache X11-Basic geben.

Aus dem kleinen Projekt ist inzwischen über die Jahre eine recht ansehnliche und rubuste Programmierumgebung geworden, von der man in den 80er Jahren des vergangenen Jahrhunderts nur träumen konnte. Dennoch hat sich in Sachen IT-Technik, Programmieranwendungen und auch Programmiertechniken seitdem einiges getan, so daß X11-Basic heutigen Ansprüchen an eine zeitgemäße Entwicklungsumgebung nicht genügt. Das war aber auch nie so gedacht. X11-Basic richtet sich nicht an den (angehenden) professionellen Programmierer, sondern mehr an den mathematisch interessierten Programmier-Laien, oder zumindest an solche, welche zu faul sind, sich die Eigenheiten heutiger Programmiersprachen anzulernen, nur um ein etwas komplexeres Problem rechnerisch umzusetzen. Diese Diskrepanz zwischen Computerprogrammierung und Umsetzen von mathematischen Algorithmen hat es schon immer gegeben, und das war nicht zuletzt der Grund, warum die BASIC Programmiersprache vor mehr als 50 Jahren überhaupt entstanden ist.

Um es kurz zu machen: Suchen Sie eine Programmiersprache, mit der Sie Anwenderprogramme mit Benutzerschnittstellen, evtl. sogar Apps für Smartphones oder dergleichen machen wollen, nutzen Sie besser gleich die dort übliche Programmiersprache. Dann lohnt es sich auch, die zu lernen. Ihre App wird sowieso nicht an einem Tag fertig lauffähig sein. Dafür bekommen Sie aber massenhaft Hilfe im Internet in einschlägigen Foren. Die meisten Probleme, die Sie treffen werden, hat eh schon jemand vor Ihnen gelöst. Sie müssen sie nur finden, abwandeln und für Ihre App einsetzen.

X11-Basic hingegen würden Sie nutzen, wenn Sie eine neue Idee für einen Algorithmus schnell ausprobieren wollen. Die Stärken von X11-Basic sind seine Rechenfähigkeit. Sie können leicht mit komplexen Zahlen, beliebig großen ganzen Zahlen oder auch nur mit normalen rationalen Zahlen Berechnungen anstellen. Es gibt weiterhin Funktionen, um mit Matritzen zu rechnen. Nebenbei ist X11-Basic recht schnell in der Ausführung, und es bedarf nur einer kurzen Lernphase, bis Sie ihr erstes Programm schreiben und laufen lassen können. Die graphischen Fähigkeiten helfen Ihnen dabei, die Berechnungen auch plastisch und in Farbe darzustellen. Schliesslich eignet sich X11-Basic auch besonders für Datenmanipulationen aller Art, dank einer vollständigen Implementierung aller I/O-Funktionen des Betriebsystems.

Wenn Sie jetzt denken, dass X11-Basic dann doch recht eingeschränkt ist, so darf ich Sie beruhigen: X11-Basic erlaubt fast alles, was das Betriebsystem an Dateimanipulationen, Datenverarbeitung direkten Speicherzugriff etc. ermöglicht. Und das trotzdem weitgehend unabhängig vom tatsächlich eingesetzten Betriebsystem (ob WINDOWS, Linux oder Android).

Genug der einführenden Worte. Installieren Sie einfach X11-Basic, und sehen Sie selbst.

1.3. Schnellinstallation

1.3.1. Installation unter Android

Die Installation auf Android-Geräten ist denkbar einfach: Suchen Sie die App X11-Basic im Play-Store und installieren Sie sie. Nach dem Öffnen der App können Sie direkt mit der Tastatur einzelne Befehle eingeben, welche sofort ausgeführt werden. Ein Programm laden Sie mit MENU→load, Datei mit der Endung .bas auswählen, und dann mit MENU→Run starten.

1.3.2. Installaiton unter Linux

Nicht minder einfach ist die Installation unter (Debian-basierten) Linux-Systemen: Laden Sie das X11-Basic Paket (eine entsprechende .deb Datei) herunter, klicken Sie in einem Dateimanager zweimal drauf und installieren Sie. Alternativ können Sie ein .deb Paket auch in einem Terminal mit dem Kommando

dpkg -i xxx.deb

installieren. Den Interpreter starten Sie dann aus dem Anwendungmenü heraus oder direkt von einer Shell mit

xbasic

oder

xbasic meinprogramm.bas

wenn Sie direkt ein Programm ausführen lassen wollen.

1.3.3. Installation unter WINDOWS

Laden Sie die .zip Datei mit dem Installationpaket runter und entpacken Sie es in Ihrem User-Verzeichnis. Starten Sie dann das ausgepackte Setup-Programm. Bei der neuesten Version laden Sie anstelle der .zip Datei gleich das Installationprogramm runter.

X11-Basic installiert sich nun auf der C: Partition im Verzeichnis X11-Basic. Darin finden Sie dann u.a. den Interpreter xbasic.exe sowie den Compiler xbc.exe welche Sie von dort mit Doppelklick oder draufziehen eines .bas Programms starten können.

1.4. Mein erstes Programm

Warscheinlich möchten Sie sofort ein Programm schreiben und zum Laufen bringen. Hierzu müssen Sie wissen, dass X11-Basic Programme ganz normale Textdateien mit der Endung .bas sind. Diese müssen Sie erstellen und zwar mit einem Text Editor. Das Schreiben eines X11-Basic Programms geht also nicht mit X11-Basic selbst sondern mit einem separaten Programm. Ein solches müssen Sie also noch besorgen, wenn es noch nicht auf Ihrem Computer installiert ist. Unter Android installieren Sie eine entsprechende App aus dem Play-Store, z.B. "Jota Text Editor". In Windows können Sie den vorhandenen aber sehr rudimentären Editor "notepad" benutzen. Nach einer Weile werden Sie herausfinden, was Ihnen in Notepad fehlt und dann vielleicht eine bessere Alternative installieren. In Linux sind üblicherweise bereits jede Menge Texteditoren installiert. Versuchen Sie mal gedit.

Erwähnenswert ist vielleicht noch, daß Sie in Android nach der Installaiton des Editors direkt von der X11-Basic App über MENU→Editor in den Editor ihrer Wahl gelangen können. Nach Beendigung des Editors wird das Programm dann automatisch in X11-Basic neu geladen, so daß Sie es gleich starten können.

Was für ein Programm sollen Sie schreiben? Wenn Sie noch nichts anderes wissen, schreiben Sie die drei Zeilen

PRINT "Hallo"
PAUSE 10
END

in die Datei und speichern sie als hallo.bas ab.

In Android laden Sie die Datei mit MENU→Load, dann MENU→Run zum Starten. In Windows ziehen Sie die Datei einfach auf den Interpreter xbasic.exe, lassen Sie los und Ihr Programm wird gestartet. In Linux öffnen Sie ein Terminal und geben xbasic hallo.bas ein. Und schon gehts los. Mehr müssen SIe für den Anfang nicht wissen, um losprogrammieren zu können.

Sie müssen Sich nun nur noch anlernen, wie man Berechnungen in BASIC formuliert, und was all die einzelnen Befehle machen. Diese Informationen finden Sie im Benutzerhandbuch (in den Kapiteln weiter unten) bzw. in der integrierten Hilfe der Android Version der X11-Basic App.

Vielleicht erinnern Sie sich an GFA-Basic (z.B. für den ATARI ST aus den 80er Jahren), dann kennen Sie die meisten Befehle schon.

2. Über X11-Basic

X11-Basic ist ein Dialekt der Programmiersprache BASIC. X11-Basic unterstützt Grafik und Sound, sowie alle Funktionen welche die traditionellen BASIC Dialekte auch bieten. Es eigenet sich deshalb für Shell-Skripte, CGI-Programmierung sowie zur Berechnung von komplexen Mathematischen Algorithmen sowie zur Visualisierung und grafischen Darstellung der Ergebnisse. Die BASIC Programme sind in der Regel gut strukturiert. X11-Basic verwendet keine Zeilennummern.

Die Syntax von X11-Basic ähnelt am ehesten der von GFA-Basic in seiner ursprünglichen Implementierung für den ATARI ST. Alte GFA-Basic Programme sollten nur mit wenigen Änderungen laufen. Auch DOS / QBASIC Programmierer werden sich schnell zuhause fühlen.

X11-Basic eignet sich für nahezu alle Programmieraufgaben. Für die Wissenschaft und Technik hat X11-Basic bereits seine Fähigkeit bewiesen, in komplexen Simulationen und Regelungs- sowie Automatisierungs-Lösungen. X11-Basic bietet eine hohe Abstraktionsebene im Sprachdialekt, eignet sich aber ebenso gut für Hardware-Nahe Aufgaben, Datenanalyse bis zum letzen Bit, sowie Steuerung von Elektronik. Und das mit einem Sprachdialekt, der viel einfacher zu lesen, verstehen und pflegen ist, als viele andere Programmiersprachen. X11-Basic wurde konzipiert für alle Anwendungen und ermöglicht die schnelle Entwicklung von kompakten, effizienten, zuverlässigen, lesbaren, portierbaren, gut strukturierten Programmen.

X11-Basic unterstützt komplexe Zahlen und komplexe mathematische sowie Berechnungen mit Zahlen mit beliebiger Präzision wo es benötigt wird, sowie sehr schnelle 32bit-Ganzzahl-Arithmetrik und 64bit Fließkommaoperationen. Weiterhin sind die Möglichkeiten der Datenmaipulationen mit Strings und Stringfunktionen umfassend.

X11-Basic hat das Motto: "klein und schnell". Dabei ist das Ziel, mit den wenigsten Systemresourcen auszukommen und dabei die höchstmögliche Ausführungsgeschwindigkeit zu erzielen. X11-Basic erreicht das durch Bereitstellung sehr mächtiger integrierter Befehle und Funktionen und eines sehr schnellen Compilers, der umso schnellere Programme erzeugt.

Mit X11-Basic können Sie mal eben schnell eine kleine Anwendung mit sehr wenig Aufwand schreiben. Sollten einmal die eingebauten Befehle und Funktionen des X11-Basic Dialektes für eine Aufgabe nicht ausreichen, so können problemlos alle systemweiten Shell-Kommandos sowie alle dynamsichen Libraries mit eingebunden werden. Eine Mischung von X11-Basic mit anderen Programmiersprachen, z.B. C und Assembler ist so leicht möglich.

Weil es eine interpretierende Sprache ist, kann jeder neue Schritt in Ihrem Programm schnell getestet werden, um schnell zu sehen, wie es läuft. Wenn dann Ihr Programm fertig ist, können Sie den X11-Basic-Compiler verwenden, um einen sehr schnelles unabhängig lauffähiges Programm daraus zu erstellen.

2.1. Portabilität

Der X11-Basic-Dialekt wurde so konzipiert, dass sie soweit möglich plattformunabhängig ist. Sie können also erwarten, dass X11-Basic-Programme auf vielen Betriebssystemen laufen, und überall etwa dasselbe tun und das gleiche Aussehen produzieren. X11-Basic-Programme sind portabel.

X11-Basic wurde entwickelt, um auf vielen Betriebsystemen mit extrem niedrigen Ressourcen zu laufen. Es wurde ursprünglich für UNIX-Workstations und Linux-Systeme mit dem X-Window-System entwickelt.

Note

Deshalb auch das "X11", da X damals als X11 bekannt war, basierend auf seiner aktuellen Hauptversion 11. Heute heißt das Projekt X.org.

Nichtsdestotrotz wurden bald X11-Basic Versionen auch für andere Betriebssysteme (MS WINDOWS, MAC OSX, ATARI ST / TOS) erstellt.

In den Fällen, in denen kein X11-Fenstergrafiksystem vorhanden ist, kann X11-Basic stattdessen auch mit einer Unterstützung des Framebuffers kompiliert werden. Die Android-Version z.B. verwendet die Framebuffer-Schnittstelle. Ebenfalls ist eine solche Implementierung für die TomTom-Navigationsgeräte und für den Raspberry Pi (ohne X.org) möglich. Die SDL (= Simple Direct-Media Library) wird ebenfalls unterstützt als alternative Grafik-Engine. Die MS-Windows-Version nutzt dies. Aber es ist auch möglich, SDL-Unterstützung für andere Betriebssysteme in X11-Basic hinein zu kompilieren.

So ist es auch möglich, X11-Basic auf sehr einfachen Systemen, den sogenannten embedded (=eingebettete) Systemen mit einer sehr geringen Menge an RAM und bei kleiner Prozessorleistung zu portieren.

Schließlich ist es sogar möglich, eine Version von X11-Basic ohne Grafik zu kompilieren. Auf diese Weise entsteht eine sehr leichte Skript-Engine, z.B. zum Aufbau von Servern.

Sound ist nicht auf jedem System verfügbar. Wo es verfügbar ist, nutzt X11-Basic einen 16-Kanal-Sound-Synthesizer sowie die Möglichkeit, Sound-Samples aus Standard-Sounddateiformaten (wie .wav und .ogg) abzuspielen. Auf LINUX-Systemen wird das meist durch die ALSA Sound-Engine ermöglicht. Auf dem Android-Betriebsystem nutzt X11-Basic zusätzlich das Android-Sprachmodul.

Die X11-Basic-Bibliothek enthält eine grafische Benutzerschnittsteölle (GUI), welche dem GEM nachempfunden ist. Dies macht das Schreiben von GUI-Programmen in X11-Basic schneller, einfacher und portabler als das Programmieren mit jeweils nativen GUI-Tools.

Note

GEM=*G*raphics *E*nvironment *M*anager, eine Betriebsystemumgebung, die ursprünglich von Digital Research Inc. (DRI) für den ATARI ST entwickelt wurde und z.B. auch von GFA-BASIC verwendet wurde.

Note

GUI=Graphical User Interface (grafische Benutzerschnittstelle)

Die Android-Version von X11-Basic enthält eine voll ausgestattete farbige VT100/ANSI Terminalemulation und Unterstützung für Unicode-Zeichensätze (UTF-8 codiert) auf der Standardausgabe für Text.

2.2. Strukturierte Programmierung

X11-Basic ist eine strukturierte prozedurale Programmiersprache. Struktur ist eine Form der visuellen und funktionalen Verkapselung, in denen mehrzeilige Abschnitte des Programms sich wie einzelne Einheiten verhalten und aussehen. Anfang und Ende der Blöcke sind mit aussagekräftigen Schlüsselwörtern markiert.

Im Gegensatz zu traditionellen BASIC-Implementierungen werden Zeilennummern in X11-Basic nicht verwendet. Jede Zeile enthält nur eine Anweisung. Sprünge mit GOTO sind möglich, aber nicht notwendig. Alle gebräuchlichen Schleifentypen sind verfügbar sowie zusätzliche Kommandos zum vorzeitigen Abbrechen (-→ EXIT IF, BREAK).

Prozeduren und Funktionen können mit Rückgabewerten beliebigen Typs definiert werden. Auf diese Weise können BASIC-Programme modular aufgebaut werden. Ein Programm kann einen Hauptteil enthalten, von dem aus Unterfunktionen und Unterprozeduren aufgerufen werden können, die in der gleichen Quelldatei definiert sein können (aber nicht unbedingt müssen). Einzelne Quellen können eine Bibliothek bilden. Ganze Bibliotheken können mit dem Zusammenführungsbefehl (-→ MERGE) hinzugefügt werden.

Um die Portierung von ANSI-Basic-Programmen (mit Zeilennummern) nach X11-Basic zu erleichtern, wurde ein Konverter (→ bas2x11basic) geschrieben. Dieser ist im X11-Basic-Paket enthalten.

Da skleine und nützliche Programm gfalist von Peter Backes erlaubt sogar die Dekodierung vom GFA-BASIC Programmen, erkennbar an der Endung .gfa, nach ASCII.

Note

Das sogenannte ANSI-­Basic wurde vom American National Standards Institute genormt. ANSI-Basic benutzt aber Zeilennummern und die Syntax kann recht verschieden von der des X11-Basics sein.

Tip

Einen Link zum Herunterladen von gfalist finden Sie auf der X11-Basic Homepage.

2.3. Optimaler Programmcode

Als Mindestanforderung benötigt der X11-Basic Interpreter und der Bytecode Interpreter (die sogenannte virtual machine) etwa 350 KB Speicher und weitere 400 kB als Dateigröße. Die X11-Basic Runtime-Library ist dann darin enthalten. Das ist also der Overhead, den all Ihre selbstgeschrebenen BASIC-Programme haben werden. Im Vergleich zu einigen Windows-Programmen ist das gar nicht so übel. Höchtwahrscheinlich ist Ihr Programmcode oder Bytecode sowieso kleiner als 50 kB (für eine mittelgroße Anwendung), plus alle Ressourcen und Grafiken, die Sie natürlich hinzufügen möchten. Schlussendlich wird der produzierte Code relativ klein und leicht genug sein, um auch auf tragbaren Geräten (z. B. Mobiltelefone, eBook-Lesegeräte und Navigationsgeräte) verwendet zu werden. Jene Geräte haben nur wenig Speicher (und einen relativ langsamen Prozessor).

Copyright © 1997­-2018 by Markus Hoffmann

Es ist erlaubt, dieses Dokument zu kopieren, zu verteilen und / oder zu modifizieren unter den Bedingungen der GNU-Lizenz für freie Dokumentation, Version 1.2 oder einer späteren Version veröffentlicht von der Free Software Foundation; aber nur ohne invariante Abschnitte, ohne Front- oder Deckblatttexte und ohne Die Texte auf der Rückseite. Eine Kopie der Lizenz ist in im Abschnitt "GNU-Lizenz für freie Dokumentation" wiedergegeben.

X11-Basic ist freie Software; Sie können es weitergeben und / oder modifizieren, aber nur unter den Bedingungen der GNU General Public License, wie sie von der Free Software Foundation veröffentlicht wurden; entweder Version 2 der Lizenz oder (nach Ihrer Wahl) eine spätere Version.

Dieses Programm wird in der Hoffnung verteilt, dass es nützlich sein wird, aber OHNE JEGLICHE GARANTIE ohne auch nur die stillschweigende Gewährleistung der MARKTGÄNGIGKEIT oder Eignung für einen bestimmten Zweck. Siehe die GNU General Public License für mehr Details.

Tip

Lesen Sie die Datei COPYING für Details. (Zusammengefaßt heißt es dort: frei, Open Source, verwenden und ändern wie Sie möchten, nicht in nicht-freie Software einbauen, keine Garantie irgendeiner Art, beschimpfen Sie mich nicht, wenn es nicht funktioniert.)

3. Benutzung

In diesem Kapitel wird beschrieben, wie Sie X11-Basic für die gängigsten Betriebssysteme installieren und wie man den Interpreter ausführt und wie man BASIC-Programme kompiliert.

Der X11-Basic-Interpreter heißt xbasic (xbasic.exe unter Windows). Der Compiler xbc (xbc.exe unter Windows). Unter Unix sind diese ausführbaren Dateien normalerweise in /usr/bin/ installiert (falls über das Paketverwaltungssystem installiert wurde) oder im Pfad /usr/local/bin (falls manuell vom Quellpaket installiert wurde). Unter Windows werden die Dateien normalerweise unter dem Verzeichnis C:\x11basic installiert. Neuerdings auch unter C:\Programmdateien\x11basic. Unter Android müssen Sie sich nicht um die einzelnen Komponenten von X11-Basic kümmern, weil dort die X11-Basic App mit einem kleinen IDE (Integrated Development Environment = Integrierte Entwicklerumgebung) ausgestattet ist. Das Terminal, der Editor, laden, ausführen und kompilieren handhabt die App für Sie.

3.1. X11-Basic installieren

Für die gängigsten Betriebssysteme stehen fertige Pakete zum Installieren des gesamten X11-Basic Pakets zur Verfügung. Sie ermöglichen eine einfache Installation von X11-Basic, ohne dass es aus den (freien und offenen) Quellen kompiliert werden muss.

Auf anderen Betriebssysteme, die hier nicht erwähnt werden, kann X11-Basic funktionieren oder nicht. Im Allgemeinen ist möglicherweise kein Binärpaket verfügbar. Dies hängt immer davon ab, ob sich jemand die Mühe gemacht hat, X11-Basic für das jeweilige Betriebsystem zu kompilieren und dann ein fertiges Paket zur Verfügung zu stellen. Suchen Sie ruhig im Internet, aber seien sie etwas vorsichtig, von wem Sie ein Binärpaket annehmen und auf Ihren Rechner lassen. Bei Binärpaketen brauchen Sie immer besonderes Vertrauen in dessen Urheber. In den Fällen, wo Sie nichts fertiges finden, werden Sie nicht darumherum kommen, X11-Basic selbst aus seinen Quellen zu kompilieren. Je nach Betriebsystem kann das jedoch etwas (Hand-)Arbeit machen. Vielleicht haben Sie Glück und Sie sind nicht der erste, der dies versucht. Also im Internet nach Hinweisen suchen ist generell eine gute Idee.

Aber wahrscheinlich lesen Sie dieses Handbuch, weil Sie bereits X11-Basic auf Ihrem System installiert haben, oder Sie haben mindestens ein Paket bereit für die sofortige Installation.

3.1.1. SuSE­Linux and RedHat

Wenn Sie ein sogenanntes Red-hat-Packet (RPM) haben, z. eine Datei namens X11Basic-1.25-1.i386.rpm, dann können Sie dieses Paket (als root) mit folgendem Kommandoe leicht installieren

rpm -i X11Basic-1.25-1.i386.rpm .

Dies ist zumindest für die Linux-Distributionen Feodora, Mandriva, SuSe und RedHat (und vielleicht auch andere, im wesentlichen abgeleitete Distributionen) ein sehr komfortabler Weg den Interpreter, den Compiler und seine Dokumentation, die Hilfeseiten und eine kleine Sammlung von Beispielprogrammen zu installieren.

Tip

Eine Liste mit auf RPM basierenden Linuxdistributionen können Sie hier finden: http://en.wikipedia.org/wiki/Category:RPM­based_Linux_distributions

Folgende Dateien werden normalerweise mit dem Paket installiert:

/usr/bin/xbasic ­­         Der X11-­Basic Interpreter
/usr/bin/xbc ­­            Der Kompiler
/usr/bin/xbbc ­­           Der bytecode Kompiler
/usr/bin/xvbm ­­           Der bytecode Interpreter (virtual machine)
/usr/bin/xb2c ­­           Der bytecode nach C Übersetzer
/usr/bin/bas2x11basic ­  ­ Ein ANSI BASIC nach X11-­Basic Übersetzer
/usr/lib/libx11basic.so ­­ Die Laufzeit-Bibliothek (shared object)
/usr/lib/libx11basic.a ­­  Die Laufzeit-Bibliothek (statisch)
/usr/include/x11basic/x11basic.h ­­  Ein header file für die C-Programmierschnittstelle
/usr/include/x11basic/xb2csol.h ­­   Ein header file für das Kompilieren der xb2c Ausgabe
/usr/share/man/man1/x11basic.1 ­­    Die man-­page von X11-­Basic
/usr/share/man/man1/xbasic.1 ­­      Die man-­page des X11-­Basic Interpreters
/usr/share/man/man1/xbc.1 ­­         Die man-­page des Kompilers
/usr/share/man/man1/xbbc.1 ­­        Die man-­page des bytecode Kompilers
/usr/share/man/man1/xbvm.1 ­­        Die man-­page der virtual machine
/usr/share/man/man1/xb2c.1 ­      ­  Die man-­page des X11-­Basic nach C Übersetzers
/usr/share/man/man1/bas2x11basic.1 ­­Die man-­page des ANSI nach X11-­Basic Übersetzers

Nachdem Sie das Paket installiert haben, können Sie den Interpreter mit

xbasic

ausführen oder Sie lesen Sie die man-Seiten mit

man xbasic

oder

man x11basic .

Die Dokumentation sollte in das Verzeichnis /usr/share/doc/packages/X11Basic/ installiert werden. Dort sollten Sie dann folgende Dateien finden:

-rw-r--r--   1005 ACKNOWLEGEMENTS      Danksagungen an Beitragende
-rw-r--r--     46 AUTHORS              Die Kontaktadresse des Autors
-rw-r--r--  17982 COPYING              Lizenzbestimmungen
-rw-r--r--   2960 INSTALL              Installationsanweisungen
-rw-r--r--   1752 README               Eine kurze Beschreibung
-rw-r--r--    170 RELEASE_NOTES        release notes
-rw-r--r-- 164370 X11-Basic-manual.txt  Das Handbuch in txt version auf Englisch
drwxr-xr-x   1024 editors/             Konfigurationsdateien für Texteditoren / Syntax Highlighting
drwxr-xr-x   1024 examples/            Einige Beispielprogramme

3.1.2. Debian-basierte Distributionen, Ubuntu und Knoppix

Wenn Ihre Linux-Distributionen das RedHat-Paketsystem nicht verwendet, ist es sehr wahrscheinlich dass sie stattdessen das Debian-Paketsystem nutzt. Die beliebtesten Debian-basierte Linux-Distributionen sind Knoppix und Ubuntu, und natürlich Debian selbst.

Tip

Eine Liste mit Debian basierenden Linuxdistributionen können Sie hier finden: http://en.wikipedia.org/wiki/Category:Debian­based_distributions

X11Basic kommt auch in Paketen mit (z. B.) der Bezeichnung x11basic_1.25-1_i386.deb. Normalerweise können Sie die Datei sehr einfach aus einem Dateibrowser mit einfachem Doppelklick installieren. Auch ein

dpkg -i x11basic_1.25-1_i386.deb

von einem Terminal aus wird es tun. Die Dateisystemstruktur sollte ähnlich sein wie schon im vorherigen Kapitel über RedHat-Pakete beschrieben, also sollten Sie erwarten dürfen, dass Sie dieselben Dateien an den gleichen Stellen finden. Bitte beachten Sie, dass Sie ein spezielles Debian-Paket benötigen, wenn Sie es auf 64-Bit-Linux-Installationen installieren möchten. Es heißt dann z.B. x11basic_1.25-1_amd64.deb.

3.1.3. Andere Linux- und UNIX-Distributionen

Der Autor bietet derzeit nur 32bit und 64bit debian binär-Pakete für Linux (speziell Ubuntu Linux) direkt zum herunterladen bei sourceforge an. Ein RPM-Paket kann aus einem Debian-Paket gemacht werden mit einem Programm-Werkzeug namens alien. Für exotische Linux-basierte Geräte werden manchmal einfache zip-Dateien bereitgestellt (wie z.B. die TomTom-Version). In diesen Fällen sind Instruktionen zum Installieren in Form einer README-Datei dabei.

Das Paket für Android kommt in einer Datei namens X11-Basic-1.25-44.apk, welche normalerweise aus einem sogenannten App-Store heruntergeladen und installiert wird.

Sie finden X11-Basic für Android im Google Play Store (früher bekannt als Android Market). Wenn Sie keinen App-Store verwenden, dann können Sie die .apk-Datei auch von der X11-Basic-Homepage direkt auf Ihr Android-Gerät herunterladen und dann mit einem File-Browser anwählen. Dann sollte Ihnen die Installationsmöglichkeit für die Datei angeboten werden.

Für alle anderen Systeme müssen Sie X11-Basic aus den Quellen kompilieren. Ein Paket mit den Quellen können Sie entweder von der Homepage bzw. sourceforge-Seite aus runterladen oder aber aus den git-Repositories bei guthub oder gitlab erzeugen. Wenn Sie schonmal mit git gearbeitet haben, ist dies unbedingt zu empehlen.

Auf irgendeine Art haben Sie also das Quellpaket (z.B. X11Basic-1.25.tar.gz) erhalten. Das Kompilieren sollte für alle Linux-Distributionen funktionieren, und wahrscheinlich mit kleinen Modifikationen auch für HP-UX (Hewlett-Packard UniX), für DEC/alpha, für MAC/OSX, für SUN/SOLARIS und FreeBSD und vielleicht auch andere. X11-Basic kompiliert auch auf Cygwin, und auf ARM-Linux wie z.B. dem Standartbetriebsystem für den Raspberry Pi.

Bitte beachten Sie, dass X11-Basic für 32-Bit-Betriebsysteme ausgelegt ist X11-Basic kompiliert zwar auch auf 64-Bit-Systemen, ber einige Funktionen funktioniert möglicherweise nicht immer wie erwartet, besonders Zeiger-aritmetric (→ VARPTR(), PEEK(), POKE, usw.) wird insbesondere bei Verwendung vor riesigen zu addressierenden Speichermengen zu Segmentierungsfehlern führen können. X11-Basic verwendet jedoch einige Tricks, um 32bit Adressierungen auch korrekt auf 64bit Systemen zu übersetzen.

Note

In X11-Basic sind alle Zeiger auf Speicheradressen in 32bit Ganzzahlen-Variablen gespeichert. Ein 64bit Betriebsystem verwendet jedoch 64bit für Speicheradressen. Die oberen 32 Bits der Adressen werden bei X11-Basic deshalb intern zur weiteren Verwendung gespeichert. Also wenn Sie eine Speicheradresse verwenden, z.B. VARPTR(a), werden die oberen 32bit zwischengespeichert und für die folgenden Adressberechnungen wieder angefügt. Unmittelbar folgende Speicherzugriffe z.B. mittels POKE werden also in der Regel ohne Fehler funktionieren. Es kann jedoch sein, dass mehrere Speicherbereiche adressiert werden, welche zu weit voneinander entfernt liegen, so dass sich der Teil in den oberen 32bits unterscheidet. In dem Fall gibt X11-Basic eine Warnung aus. Auf diese Weise können Zeiger und Zeigerberechnungen wie auch auf 32bit Betriebsystemen normal verwendet werden, wenn ein wenig Sorgfalt bei der Speicheraufteilung im X11-Basic Programm bei 64-Bit-Betriebssystemen verwendet wird.

Tip

Es hat sich herausgestellt, dass auch die GEM AES Grafikfunktionen Zeiger-Konversionen (um mit dem ATARI ST-Format kompatibel zu bleiben) nutzen. Hier kann evtl. ein Speicherproblem bei 64bit Betriebsystmen auftreten. Die statisch verknüpften Versionen von X11-Basic funktionieren eher richtig, weil die shared libraries in den obersten Speicherbereich geladen werden, was so vermieden werden kann. Wenn Sie die WARNUNG-Meldungen sehen, versuchen Sie, eine statische Version von X11-Basic zu verwenden (xbasic.static)..

3.1.4. X11-Basic aus den Quellen kompilieren unter UNIXartigen Betriebsystemen

Wenn Sie ein Binärpaket von X11-Basic haben, können Sie dieses Kapitel überspringen.

Um X11-Basic zu kompilieren, benötigen Sie Folgendes:

  • Einen C-Compiler, vorzugsweise GNU C (aber andere ANSI-C-Compiler werden es auch tun),

  • Die X11-Bibliotheken (für die Grafik) oder ein Framebuffer-Gerät oder die SDL-Bibliothek,

  • optional die `readline´ Bibliothek,

  • optional die LAPACK Bibliothek,

  • optional die GMP Bibliothek,

  • optional die ALSA Bibliothek (libasound) und/oder das SDL-Framework.

Das reicht aus, um loszulegen. Wenn eine oder mehrere dieser Bibliotheken auf Ihrem System nicht vorhanden sind, werden die configure und make Skripte versuchen, eine Version von X11-Basic zu konfigurieren, die diese Bibliotheken nicht benötigen. (Natürlich werden dann später einige Funktionen in X11-Basic fehlen.)

  1. Installieren Sie die Entwicklungsumgebungspakete, z.B. durch den Befehl:

    sudo apt-get install Xorg-dev libreadline-dev liblapack-dev libgmp-dev fftw2 libasound-dev
  2. Entpacken Sie X11Basic-1.25.tar.gz mit

    tar xzf X11Basic-1.25.tar.gz
  3. wechseln Sie in das Verzeichnis X11Basic-1.25 und führen Sie folgende Befehle aus:

    ./configure
    make
    sudo make install

Wenn das funktioniert hat, dann wars das. Das ist alles, was Sie tun müssen. (Für detailliertere Installationsanweisungen lesen Sie die Dateien BUILD und INSTALL, die mit dem Paket geliefert werden.) Wenn das Skript configure fehlschlägt, kontaktieren Sie mich bitte (kollo@users.sourceforge.net) und senden Sie mir die erzeugte Ausgabe (config.log). Ich werde versuchen, Ihnen zu helfen, das Problem zu beheben. Vielleicht möchten Sie auch einen Fehlerbericht in den X11-Basic Foren oder dem Issue-Tracker erstellen, dann können Ihnen auch andere Nutzer von X11-Basic helfen.

Spezielle Kommentare zur Framebuffer-Version

Sehr nützlich auf dem Raspberry Pi und anderen Low-Memory-/Low-Resource-Computern ist die Option, keine X- oder SDL-Bibliotheken zu verwenden. Sie können trotzdem ein voll ausgestattetes X11-Basic mit Grafik- und Mauseingabe haben, wenn Sie die Framebuffer-Version kompilieren (make fb). Dies erzeugt die einzige Datei xbasic.framebuffer. Dies ist der Interpreter (und die virtuelle Maschine), der von einer Konsole (und ohne X) verwendet werden kann. So haben Sie trotzdem die volle Kontrolle über Bildschirm, Maus und Tastatur. Gewöhnlich ist das alles, was Sie benötigen, damit der Raspberry Pi mit dem Benutzer interagieren und etwas anzeigen kann.

3.1.5. Cross-Kompilierung anderer Versionen von X11-Basic

Das Makefile ermöglicht es Ihnen auch, den Kompiler (make xbc), den Bytecode-Compiler (make xbbc), die virtuelle Maschine (make xbvm) und den X11-Basic-nach-C-Übersetzer (make xb2c) zu erzeugen.

Wenn Sie die separaten Bibliotheken benötigen, lassen Sie sie mit folgenden Kommandos erzeugen:

make x11basic.a
make libx11basic.so

Diese Bibliotheken werden zum Beispiel vom Compiler xbc benötigt.

Wenn Sie eine Version erstellen möchten, die den Framebuffer (anstelle des X-Servers) verwendet, geben Sie ein:

make fb .

Wenn Sie eine Version mit der SDL-Bibliothek möchten, führen Sie aus:

make sdl .

Die TomTom-Distribution wird so generiert:

make TomTom .

(Der ARM-Linux Cross-Compiler wird benötigt).

Die MS-WINDOWS Version kann mit folgenden Kommandos generiert werden:

make windows .

(In diese, Fall wird der mingw Cross-compiler benötigt.)

3.1.6. Support und Hilfe

Wenn Sie Probleme mit X11-Basic haben, können Sie mir eine Mail senden. Bitte haben Sie Verständnis, dass ich die Zeit finden muss, um Ihre Mails zu beantworten. Auf http://sourceforge.net/projects/x11-basic/ gibt es ein Forum (Fehlerberichte, Patches, Hilfeanfragen, Verbesserungsvorschläge) zu X11-Basic. Sie können dort auch Ihre Fragen stellen, so dass auch andere X11-Basic-Benutzer dazu beitragen können. Es lohnt sich auch, die Themen durchzublättern. Vielleicht hat jemand schon eine Lösung für Ihr Problem gefunden. Die Benutzer können ihre Erfahrungen mit anderen X11-Basic-Benutzern teilen. Wenn Sie Probleme mit einem X11-Basic-Befehl oder -Programm haben, und Sie denken, dass es sich um einen Fehler im X11-Basic-Interpreter oder -Compiler selbst handelt, sollten Sie ein minimales Beispielprogramm erstellen, um den Fehler zu reproduzieren. Bitte halten Sie dieses Beispielprogramm so klein wie möglich. Dann nehmen Sie bitte das Programm und senden es mir. Fügen Sie eine kurze Beschreibung Ihres Problems hinzu, die Folgendes enthält:

  • Welches Betriebssystem verwenden Sie: Windows oder UNIX, Linux, Android?

  • Wie verhält sich das Programm auf Ihrem Computer? Was haben Sie erwartet?

  • Welche Version von X11-Basic verwenden Sie? Bitte versuchen Sie immer die Neueste!

3.2. Den X11-Basic Interpreter ausführen

Es gibt mehrere Möglichkeiten, den X11-Basic-Interpreter zu starten, abhängig vom verwendeten Betriebssystem.

3.2.1. Den X11-Basic Interpreter auf UNIX oder Linux starten

Der einfachste Weg, den Interpreter aufzurufen ist es, einfach mit dem Befehl “xbasic” aus einem Terminalfenster oder einer Konsole zu starten. Dann können Sie den Interpreter im interaktiven Modus verwenden. Versuchen Sie einfach, einige X11-Basic-Befehle einzugeben. Der Interpreter selbst akzeptiert auch mehrere Optionen über die Kommandozeile. Bitte lesen Sie auch die Man-Page (man xbasic) für weitere Details.

In Ubuntu oder Lubuntu finden Sie X11-Basic auch im Startmenü. Wenn Sie X11-Basic aus dem Startmenü auswählen, sollte der Interpreter mit einem eigenen Terminalfenster erscheinen.

Wenn Sie X11-Basic bzw xbasic aus einem Terminal starten, dann meldet sich der Interpreter mit folgender Ausgabe:

**********************************************************
*        xbasic                     V. 1.25              *
*                       by Markus Hoffmann 1997-2017 (c) *
*                                                        *
* version date:             Tue Jan 23 22:55:46 CET 2018 *
* library V.1.25 date:      Tue Jan 23 22:55:46 CET 2018 *
**********************************************************

Usage: xbasic [-e -h -l] [<filename>] --- run basic program [new.bas]

 -l             --- do not run the program (only load)
 -e <command>   --- execute basic command
 --eval <exp>   --- evaluate num. expression
 -h --help      --- Usage
 --help <topic> --- Print help on topic

Das bedeutet, der Interpreter kann mit einigen wenigen Kommandozeilenparametern gestartet werden. Haupsächlich aber übergibt man lediglich den Dateinamen des auszuführenden Programms.

Beispiele:

xbasic testme.bas
xbasic -e 'alert 1,"Hallo !",1," OK ",b'
xbasic --eval 1+3-4*3

3.2.2. Der X11-Basic Interpreter als Shell

X11-Basic-Programme können wie Shell-Skripte ausgeführt werden. Stellen Sie sicher, dass die erste Zeile Ihres X11-Basic-Programms mit den Zeichen “#!” beginnt gefolgt vom vollständigen Pfadnamen des X11-Basic-Interpreters xbasic; also z.B.:

#!/usr/bin/xbasic

Diese sogenannte She-Bang-Zeile stellt sicher, dass Ihr UNIX xbasic aufruft, um Ihr Programm auszuführen. Darüber hinaus müssen Sie die Berechtigungen Ihres X11-Basic-Programms ändern, z.B.:

chmod 755 myprog.bas

Danach kann Ihr Programm einfach von Ihrer Shell aus ausgeführt werden und der Interpreter arbeitet im Hintergrund wie Shells. Sie müssen nicht einmal die Erweiterung .bas für Ihre Skripte verwenden.

Beispiel: draftit: Ein Tool zum Stempeln einer Postscript-Datei mit "draft" auf jeder Seite.
#!/usr/bin/xbasic
i=1
WHILE LEN(PARAM$(i))
  inputfile$=PARAM$(i)
  INC i
WEND
CLR flag,count
IF NOT EXIST(inputfile$)
  QUIT
ENDIF
OPEN "I",#1,inputfile$
WHILE NOT EOF(#1)
  LINEINPUT #1,t$
  IF count=3
    PRINT "%% Created by draftit X11-Basic (c) Markus Hoffmann from "+inputfile$
  ENDIF
  IF GLOB(t$,"%%Page: *") AND NOT GLOB(t$,"%%Page: 1 1*")
    IF flag
      PRINT "grestore"
    ENDIF
    flag=1
    PRINT t$
    PRINT "gsave"
    PRINT ".80 setgray"
    PRINT "/Helvetica-Bold findfont 140 scalefont setfont"
    PRINT "0 80 800 { 306 exch moveto"
    PRINT "(Draft) dup"
    PRINT "stringwidth pop 4 div neg 0 rmoveto 6 rotate show } for"
    PRINT "grestore"
  ELSE
    PRINT t$
  ENDIF
  INC count
WEND
CLOSE
QUIT

3.2.3. X11-Basic unter WINDOWS benutzen

Die Installation erfolgt in gewohnter Weise mit einem Setup-Programm, z.B. X11-Basic-1.25-47-setup.exe, welches Sie von der Homepage herunterladen können. Alle Dateien werden auf C: in den Programm-Ordner installiert. Dies sind neben einigen Hinweistexten zu verwendeten Bibliotheken unter anderem:

demo.bas      -- ein Beispielprogramm
readme.txt    -- Hinweise zu X11-Basic
SDL.dll       -- Die Simple Direct Media Bibliothek
setup.exe     -- Installations und Uninstall Programm
X11-Basic.pdf -- Das X11-Basic Benutzerhandbuch
xb2c.exe      -- Der bytecode to C Übersetzer
xbasic.exe    -- Der X11-Basic Interpreter
xbc.exe       -- Der X11-Basic Kompiler
xbvm.exe      -- Die virtual machine

X11-Basic kann auf die folgenden drei Arten aufgerufen werden:

  1. Wählen Sie "X11-Basic" aus dem Startmenü: Sie können wählen zwischen

    COMPILER

    Öffnet die Compiler-Anwendung. Diese fragt nach einer .bas-Datei, die dann zu .exe kompiliert werden soll.

    DEMO

    Öffnet und startet das Beispielprogramm demo.bas,

    DOKU

    Öffnet das X11-Basic Benutzerhandbuch,

    X11-Basic

    Öffnet den X11-Basic-Interpreter. xbasic.exe erscheint mit einem Konsolenfenster und der Interpreter wartet auf die Eingabe von Befehlen.

  2. Klicken Sie mit der rechten Maustaste auf Ihren Desktop. Wählen Sie "Neu" aus dem Kontextmenü, das angezeigt wird; Dadurch wird ein neues Symbol auf Ihrem Desktop erstellt. Das Kontextmenü dieses Symbols hat drei Einträge "Ausführen", "Bearbeiten" und "Doku anzeigen" (zeigt ggf. die eingebettete Dokumentation an); Ein Doppelklick führt das Programm aus.

  3. Erstellen Sie eine Datei mit Ihrem X11-Basic-Programm. Diese Datei sollte die Erweiterung ".bas" haben. Doppelklicken Sie auf diese Datei und rufen Sie dann X11-Basic auf, um Ihr Programm auszuführen.

Der Compiler verfügt über eine rudimentäre grafische Benutzeroberfläche, die nach der Kompilierung der .bas-Datei und später nach dem Namen der ausführbaren Datei fragt.

Standardmäßig unterstützt die WINDOWS- oder DOS-Konsole keine ANSI/VT100-Codierung. So würde PRINT AT () und die Zeilenbearbeitung bei INPUT wahrscheinlich nicht funktionieren. Um dies zu beheben, muss ANSI.SYS für die Konsolenfenster installiert und eingeschaltet werden. Anweisungen zur Installation von ANSI.SYS finden Sie im Internet. (Es kann auch eine alternative Erweiterung namens ANSICON verwendet werden.)

Das Kontextmenü

Jedes Icon unter WINDOWS bietet ein Kontextmenü, wenn Sie mit der rechten Maustaste darauf klicken. Ein Klick auf ein Icon eines X11-Basic-Programms öffnet dieses Kontextmenü mit folgenden Optionen:

  • [Execute] ruft den X11-Basic-Interpreter auf, um Ihr Programm auszuführen. Das Gleiche passiert, wenn Sie auf das Symbol doppelklicken.

  • [Edit] ruft notepad auf, damit Sie Ihr Programm bearbeiten können.

  • [View docu] öffnet ein Fenster, das die eingebettete Dokumentation Ihres Programms anzeigt, falls vorhanden. Eingebettete Dokumentationen in einer .bas-Datei sind Kommentare, die mit einem doppelten Kommentarzeichen ## beginnen.

3.2.4. Die Android Version von X11-Basic

Eine Version von X11-Basic, die auf Android-Smartphones und Tablets installiert werden kann, ist im Android Market (heutzutage auch als "Google Play" bezeichnet) verfügbar und kann von dort ganz leicht installiert werden.

Die jeweils neueste Version findet sich normalerweise im Dateibereich der Projektseiten von X11-Basic auf sourceforge. Suchen Sie eine Datei namens X11-Basic-1.25-44.apk, die die App enthält. Laden Sie diese Datei auf Ihr Android-Tablet oder Smartphone herunter und installieren Sie sie (eventuell müssen Sie vorher das Installieren von Apps aus anderen Quellen in den Systemeinstellungen erlauben).

Im Gegensatz zu den anderen Versionen von X11-Basic ist der Interpreter und die virtuelle Maschine in eine kleine IDE (= Integrierte Entwicklungsumgebung) eingebettet, die es dem Benutzer ermöglicht, die Programme zu laden, auszuführen, zu bearbeiten und zu kompilieren.

Die App registriert sich als Viewer für die Dateien ".bas" und ".b" auf dem System. Von jedem Dateibrowser aus können BASIC-Programme mit einer einzigen Berührung gestartet werden.

Wenn Sie die X11-Basic App selbst öffnen, können Sie Befehle direkt mit der virtuellen Tastatur eingeben. Durch Drücken der MENÜ-Taste können Sie BASIC-Programme laden und ausführen, die Ausführung anhalten und fortsetzen, die Tastatur öffnen (wenn sie vom Bildschirm verschwunden ist) und BASIC-Programme in Bytecode übersetzen bzw. kompilieren.

Die virtuelle Maschine ist integriert, so dass der kompilierte Bytecode direkt ausgeführt werden kann. Abhängig von der Endianess der Prozessorarchitektur ist der Bytecode möglicherweise kompatibel mit dem, welcher auf einem Linux-PC oder einer WINDOWS-Maschine erzeugt wurde.

Die Standardausgabe wird mit einer VT100-kompatiblen Terminalemulation direkt in den Grafikbildschirm gerendert. Nicht alle Grafikfunktionen haben das gleiche Ergebnis wie bei einer X11-Windows-Installation. Der gesamte Bildschirm zählt als ein einziges Vollbildfenster. Schließlich können Verknüpfungen zu X11-Basic-Programmen auf dem Desktop platziert werden, so dass sie mit einem Klick gestartet werden können. Auch X11-Basic ist als eine Methode zum Öffnen von Dateien (von einem Dateibrowser) registriert. Eine kleine Auswahl an Beispielprogrammen ist im Android-Paket enthalten. Wenn Sie Spaß mit einem Spiel haben möchten, versuchen Sie ballerburg.bas.

Benutzung auf Android-Geräten

Android-Geräte haben normalerweise eine BACK-Taste, eine HOME-Taste und eine MENU-Taste.

  • Die HOME-Taste unterbricht X11-Basic und kehrt zum Android-Desktop zurück. Wenn Sie die X11-Basic-App erneut auswählen, wird sie fortgesetzt. Wenn ein BASIC-Programm ausgeführt wurde, wird es weiterhin im Hintergrund ausgeführt.

  • Mit der BACK-Taste wird ein laufendes BASIC-Programm gestoppt. Wenn Sie die Taste BACK erneut drücken, wird der X11-Basic-Interpreter beendet.

  • Die Taste MENU öffnet ein Menü mit folgenden Optionen: About, LOAD program, RUN program, STOP/CONT program, NEW, Keyboard, Paste from clipboard, Info/Settings, Editor, Compile und Quit.

    About

    zeigt Informationen über die aktuelle Version von X11-Basic, Neuigkeiten und das Impressum.

    Load …​

    öffnet einen Dateiwähler, der alle .bas und alle` .b` Programme im Verzeichnis /mnt/sdcard/bas anzeigt. Das ausgewählte Programm wird in den Speicher geladen. Ein eventuell dort gespeichertes Programm wird überschrieben. Sie können den Quellcode anzeigen, indem Sie "LIST" eingeben.

    Run

    startet einfach die Ausführung eines zuvor geladenen Programms. (Sie können auch 'RUN' eingeben)

    STOP / CONT

    unterbricht die Ausführung des Programms oder setzt es fort. (Sie können auch einmal die BACK-Taste drücken, um das Programm zu stoppen, und Sie können CONT eingeben, um fortzufahren).

    New

    löscht das aktuell geladene Programm aus dem Speicher.

    Tastatur

    zeigt oder versteckt die virtuelle Tastatur auf dem Bildschirm. Wenn Sie eine Hardware-Tastatur oder eine externe USB / Bluetooth-Tastatur haben, können Sie auch damit Befehle eingeben.

    Aus Zwischenablage einfügen

    fügt Text ein, den Sie zuvor aus einer anderen Anwendung in die Zwischenablage kopiert haben.

    Info / Einstellungen

    öffnet einen Dialog mit zusätzlichen Informationen, Links und Einstellungen. Die Einstellungen können wie folgt festgelegt werden:

    Splash-Screen bei Start

    Hier kann dieser ausgeschaltet werden.

    Bildschirmfokus

    Wenn der Bildschirm teilweise von der virtuellen Bildschirmtastatur abgedeckt wird, können Sie angeben, welcher Teil des Bildschirms sichtbar sein soll: Der obere Teil, der untere Teil oder der gesamte Bildschirm, aber skaliert. Der Sichtbare Ausschnitt des Bildschirms passt sich dabei an die Umgebung des Textcursors oder des Mauszeigers an. Der Standardwert ist: "skaliert".

    Schriftgröße

    Wenn der Bildschirm klein ist, aber die Auflösung hoch ist, sollten Sie die Schriftgröße auf "LARGE" ändern. Diese Einstellung betrifft sowohl die Konsolenschriftart (Textmodus) als auch die Darstellung der Grafik / Benutzeroberfläche.

    Titel anzeigen

    Dies kann hier ausgeschaltet werden.

    Statusleiste anzeigen

    Dies kann hier ausgeschaltet werden.

    Tastatur beim Start anzeigen

    Hier kann diese ausgeschaltet werden.

    Editor

    führt einen Texteditor eines Drittanbieters aus (z. B. Ted oder Jota oder 920 Text Editor, falls installiert), um das aktuell geladene Programm zu bearbeiten. Wenn kein Programm geladen wurde, lautet der Standarddateiname new.bas. Nach dem Speichern und Schließen des Texteditors wird das geänderte Programm automatisch in den X11-Basic-Interpreter geladen.

    Compile

    kompiliert den BASIC-Quellcode in Bytecode, der etwa 20-mal schneller ausgeführt werden kann (aber nicht mehr bearbeitet oder zusammengeführt werden kann). Der Bytecode wird mit .b Erweiterung im bas/-Ordner gespeichert.

    Hilfe

    öffnet ein Fenster, in dem Sie etwas in der Befehlsreferenz suchen können.

    Beenden

    beendet die X11-Basic App.

Ein Programm erstellen/editieren

Wenn Sie ein bestehendes Programm bearbeiten möchten, führen Sie die folgenden Schritte aus (in diesem Beispiel ist der verwendete Editor TED. Es funktioniert aber ähnlich mit Jota oder mit vielen anderen Texteditoren.):

  1. Laden Sie ein vorhandenes Programm mit Menu → Load,

  2. wählen Sie Menü → Editor, um das Programm zu bearbeiten,

  3. beenden Sie die Bearbeitung (und speichern Sie sie im Editor). Verlassen Sie den Editor mit "EXIT" im Menü oder mit der Taste BACK (nicht aber mit der Taste HOME).

  4. Das Programm wird automatisch neu geladen,

  5. wählen Sie Menu → run, um es auszuführen.

Gehen Sie folgendermaßen vor, wenn Sie ein neues Programm erstellen möchten (in diesem Beispiel ist der verwendete Editor ebenfalls TED):

  1. Wählen Sie MENU → New

  2. Wählen Sie dann MENU → Editor. Der Editor wird mit dem Standarddateinamen (new.bas) ausgeführt. Wenn Sie mehrere Editoren installiert haben, werden Sie gefragt, welcher verwendet werden soll. Wählen Sie TED Texteditor.

  3. Innerhalb des Editors wählen Sie dann schließlich Speichern unter und geben einen anderen Namen, z.B. "mything.bas" ein. Überprüfen Sie, dass diese Datei auch im Ordner "bas" gespeichert wird.

  4. Drücken Sie die BACK-Taste (nicht die HOME-Taste), so dass der Editor zu X11-Basic zurückkehrt.

  5. X11-Basic lädt nun neu.bas, aber das ist nicht das, was Sie wollen.

  6. Laden Sie deshalb in X11-Basic nun mything.bas.

Das nächste Mal, wenn Sie Ihr Programm bearbeiten, hat es den richtigen Namen, und eine regelmäßige Speicherung im Editor sollte es tun, dann funktioniert auch das automatische Neuladen in X11-Basic.

Wenn beim Aufruf des Texteditors ein Fehler auftritt, müssen Sie einen installieren. Es gibt viele zur Auswahl, z.B. 920 Text Editor oder Ted (tiny text editor). Installieren Sie einen aus dem Android-Market. Sie können auch mehrere Editoren installieren. Dann werden Sie immer gefragt, welchen Sie verwenden möchten, wenn Sie den Editor anrufen.

Ein Programm auswählen und laden

Um ein Programm zu laden, drücken Sie Menu → load. Sie können nun eine Programmdatei (entweder .bas oder` .b`) zum Laden auswählen. Wenn Sie den Dateinamen lange berühren, erhalten Sie ein weiteres Menü mit erweiterten Funktionen:

LOAD

lädt das Programm.

MERGE

füge das Programm dem bereits geladenen Programm hinzu (funktioniert nur mit .bas-Dateien).

LOAD + RUN

lädt das Programm und startet es sofort.

LOAD + LIST

lädt das Programm und listet es auf.

LOAD + edit

lädt das Programm und startet sofort den Editor.

LOAD + compile

lädt das Programm und kompiliert es.

compile + RUN

kompiliert das Programm und startet sofort das kompilierte.

delete

löscht die ausgewählte Datei (Sie werden zur Bestätigung aufgefordert).

CANCEL

kehrt zum Dateimenü zurück.

Diese Funktionen dienen nur der Bequemlichkeit. Wahrscheinlich werden Sie LOAD + RUN oder compile + RUN häufiger verwenden.

Ein Programm im Hintergrund ausführen

Wenn ein Programm ausgeführt wird und Sie die Home-Taste drücken, wird das Programm weiterhin im Hintergrund ausgeführt. Wenn Sie die X11-Basic-App erneut auswählen, kommt das Programm wieder in den Vordergrund und die laufende Bildschirmausgabe wird angezeigt.

Note

Wenn Sie den Bildschirm drehen, sollte das laufende Programm weiter ausgeführt werden. Aber das Programm muss herausfinden, dass sich die Bildschirmgröße geändert hat. GET_GEOMETRY ist der richtige Befehl dafür.

Desktop-Verknüpfungen

Sie können Desktop-Verknüpfungen zu Ihren BASIC-Programmen erstellen. Platzieren Sie eine Verknüpfung auf dem Startbildschirm, indem Sie einfach irgendwo auf den Hintergrund des Desktop-Bildschirms drücken (und für 1 Sekunde gedrückt halten) (auf Android 4.x-Geräten gehen Sie zu Apps → Widgets). Zuerst werden Sie aufgefordert, die Verknüpfung irgendwo auf dem Desktop zu platzieren. Der X11-Basic-Launcher fragt dann nach einer .bas- oder .b-Datei und platziert den Link auf dem Desktop. Wenn Sie diesen Link anklicken, wird automatisch X11-Basic und das .bas-Programm geladen und ausgeführt.

Sie können eine beliebige Datei aus dem Ordner /sdcard/bas auswählen, die dann auf dem Desktop platziert wird.

Updates der Beispielprogramme

Die X11-Basic App enthält eine kleine Auswahl an Beispielprogrammen. Sie werden in das Verzeichnis /mnt/sdcard/bas/ kopiert. Die X11-Basic App überschreibt niemals eine Datei in bas/, die bereits vorhanden ist. Wenn Sie möchten, dass ein bestimmtes Beispielprogramm aktualisiert wird (also durch eine möglicherweise neuere Version ersetzt wird, die mit einem Update der X11-Basic-App geliefert wurde), löschen Sie einfach die Datei. Sie wird dann beim nächsten Start von X11-Basic wiederhergestellt.

Problembehebung für die Android Version

Es gibt leider bei der Android Version auf einigen Geräten bisher ungelöste Probleme. Hier einige Möglichkeiten, diese zu umgehen:

Bildschirmaktualisierungs Problem

(Wurde manchmal auf Samsung Tabs für alle Android-Versionen gemeldet) z. Galaxie Note 1, Android 4.1.2: Symptome: Beim Ausführen der X11-Basic-App wird die Bildschirmausgabe nicht aktualisiert während X11-Basic ein Programm ausführt. Behandlung: Sie sollten die Systemeinstellungen überprüfen:

  • Entwicklereinstellungen → Hardware-Overlays deaktivieren: AN

  • Entwicklereinstellungen → Gpu erzwingen: AUS

Getippte Zeichen sind nicht sichtbar

Die ganze Zeile erscheint, nachdem Sie die EINGABETASTE gedrückt haben, aber Sie können nicht sehen, was Sie eingeben. In diesem Fall müssen Sie die Einstellungen der Tastatur ändern (automatische Vervollständigung und so weiter ausschalten, wodurch die Tastatur den Text zurückhält, bis Sie die Eingabetaste drücken.) Wenn nach ENTER immer noch nichts angezeigt wird, haben Sie wahrscheinlich das Bildschirmaktualisierungs Problem (siehe oben).

3.3. Kommandozeilen-Parameter

Wenn Sie X11-Basic unter Android verwenden, können Sie diesen Abschnitt überspringen.

Der X11-Basic-Interpreter xbasic kann mit zusätzlichen, aber optionalen Kommandozeilenparametern aufgerufen werden. Er akzeptiert die folgenden:

xbasic <filename>	läd und startet ein BASIC Programm
-l			läd das Programm nur, startet es aber nicht
-e <command>		führt ein BASIC Kommando aus
--eval <expression>	berechnet einen numerischen Ausdruck und schreibt das Ergebnis
--daemon		schaltet das prompting und echoing auf der Konsole aus
-h --help		gibt einen kurzen Hilfetext aus
--help <topic>		gibt Hinweise zur Syntax eines Kommandos aus

Die Framebuffer-Version von X11-Basic unterstützt zusätzlich noch weitere Kommandozeilenoptionen:

--keyboard <device>	bestimmt das device für die Tastatureingaben (default: /dev/input/event4)
--mouse <device>	bestimmt das device für die Mausbewegungen (default: /dev/input/mice)
--framebuffer <device>	bestimmt das framebuffer device (default: /dev/fb0)
daemon

Diese Befehlszeilenoption erlaubt es dem Interpreter, im Daemon-Modus, also ohne angebundenes Terminal zu laufen. Es wird keine Eingabeaufforderung angezeigt und die Eingabe wird nicht zurückgemeldet. Dies ist nützlich, wenn Sie X11-Basic-Programme als Hintergrunddienst ausführen möchten.

framebuffer

Zum Beispiel: Der sense hat für den Raspberry Pi verwendet das Framebuffer-Gerät /dev/fb1 für seine LED-Matrix. Wenn Sie also auf dem LED-Matrix-Display zeichnen möchten, geben Sie dies für die Grafikausgabe an.

3.4. X11-Basic Programme erstellen und modifizieren

X11-Basic-Programme (Quellcode, .bas-Dateien) sind reguläre ASCII-Dateien und können daher mit jedem verfügbaren Texteditor erstellt werden.

Benutzer von UNIX-ähnlichen Betriebssystemen sind mit jedem Texteditor gut bedient. Einfache wie "Pico" oder "Nano" sind schon absolut perfekt. MS-WINDOWS-Benutzer können den einfachen Texteditor notepad verwenden.

Benutzer von X11-Basic unter Android müssen einen guten Texteditor installieren. TED (Texteditor), 920 Text Editor oder` Jota` funktionieren gut. Andere Texteditoren, die möglicherweise bereits vorinstalliert wurden, können Grund für Frustration und Ärger sein. Wenn Sie sich also nicht sicher sind, installieren Sie einen der genannten Editoren aus dem Android Market. Wenn Sie mehr als einen Editor installiert haben, ist dies kein Problem, Sie werden gefragt, welchen Sie verwenden möchten, wenn der Editor aufgerufen wird.

Neben den grundlegenden Bearbeitungsfunktionen empfehle ich einen Texteditor mit Syntax-Highlighting zu verwenden. Derzeit sind X11-Basic-Syntaxdefinitionen für den "Nirvana Editor" nedit (verfügbar für Linux, UNIX und WINDOWS) und für den "920 Text Editor" und "Jota" für Android verfügbar.

X11-Basic unterstützt Fremdsprachenzeichen. Daher kann das BASIC-Programm in UTF-8 codiert sein. UTF-8 ist mit ASCII kompatibel, kann aber jedes Unicode-Zeichen codieren. Solche Zeichen können in X11-Basic-String-Konstanten verwendet werden, dürfen aber nicht in Variablennamen vorkommen. Derzeit unterstützt nur die Standardausgabe (Konsole) den vollständigen UTF-8-Zeichensatz..

Note

LTEXT akzeptiert einige Sonderzeichen (zur Zeit nur Deutsch), TEXT funktioniert mit UTF-8 nur auf Android-Geräten (alle latin, griechisch, kyrillischen Zeichensätze).

Nedit mit X11-Basic
Figure 1. Der Nirvana Editor mit Syntax-Highlighting für ein X11-Basic-Program.

3.5. Der Bytecode Compiler und die Virtuelle Maschine

Wenn Sie die Android-Version von X11-Basic verwenden, können Sie dieses Kapitel überspringen. Alles, was Sie wissen müssen, ist, dass es die Möglichkeit gibt, X11-Basic-Programme (zu Bytecode) zu kompilieren, wodurch sie viel schneller laufen.

Unter UNIX, Linux und Windows muss ein separates Programm verwendet werden, um .bas-Dateien zu kompilieren und Bytecode-Dateien oder Standalobe-EXE-Dateien daraus zu machen.

Wenn Sie WINDOWS verwenden, besteht die praktischste Möglichkeit zum Kompilieren von X11-Basic-Programmen darin, den Compiler xbc.exe auszuführen, der über eine kleine Benutzeroberfläche verfügt. Auch unter UNIX/Linux ist es sehr praktisch, den Compilermanager xbc mit entsprechenden Befehlszeilenoptionen zu verwenden (achten Sie auf die` -virtualm` Option).

Fortgeschrittene Benutzer möchten sich wahrscheinlich mit den Bytecode-Dateien befassen, die beim Kompilieren erzeugt werden. Für jeden Übersetzungsschritt gibt es separate Programme, die das tun; nämlich: xbbc,` xb2c` und xbvm.

xbbc

kompiliert X11-Basic-Programme (.bas-Dateien) in Bytecode-Dateien (.b).

xb2c

kann Bytecode-Dateien in C-Quellcode übersetzen.

xbvm

ist eine virtuelle Maschine (Interpreter für Bytecode).

Die Idee ist, die Ausführungsgeschwindigkeit von X11-Basic-Programmen zu erhöhen, indem man sie zu einem Bytecode kompiliert, der immer noch lauffähig ist. Der Bytecode selbst wird von einem Bytecode-Interpreter (auch als virtuelle Maschine bezeichnet) interpretiert. Diese virtuelle Maschine muss auf dem Zielcomputer vorhanden sein, und dann können alle Bytecode-Programme dort verwendet werden. Auf diese Weise muss der X11-Basic-Compiler nicht mit verschiedenen Zielmaschinenarchitekturen umgehen, und auch der Bytecode kann viel schneller als der interpretierte BASIC-Quellcode ausgeführt werden.

Die Umwandlung in Bytecode ist eine echte Übersetzung. Der Schritt zum Assembler- oder Maschinencode ist nicht weit. Auch eine Übersetzung nach C oder nach JAVA oder einer anderen Sprache wäre unkompliziert. Wie bei JAVA ist der Bytecode plattformunabhängig und kann auf jedem System ausgeführt werden, auf das eine virtuelle Maschine portiert wurde.

Note

X11-Basic Bytecode kann nicht in BASIC Quellcode (.bas) zurückkonvertiert werden, sondern ist eine sehr abstrakte Darstellung Ihres Programms.

Wenn Sie wissen möchten, worum es dabei geht, öffnen Sie eine .c-Quelldatei, die vom Bytecode-nach-C-Übersetzer xb2c erzeugt wurde. Ausgedrückt in einer Makro-Sprache ist der Bytecode in gewisser Weise lesbar.

Hier ist ein Beispiel:

...
    PUSH2;              /* 2  */
    ZUWEIS(2);          /* I= */
LBL_38:  PUSHV(2);      /* I */
    X2I;
    PUSHARRAYELEM(3,1); /* F(.) */
    X2I;
    JUMPIFZERO LBL_91;	/* JEQ(0x91); */
    PUSH2;              /* 2 */
    PUSHV(2);           /* I */
    EXCH;
    X2F;
    MULf;
    PUSHV(0);           /* S */
    LESS;
    JUMPIFZERO LBL_81;	/* JEQ(0x81); */
    PUSH2;
    PUSHV(2);           /* I */
    EXCH;
    X2F;
    MULf;
    ZUWEIS(5);          /* K */
LBL_61:  PUSHV(5);      /* K */
    X2I;
    PUSHVVI(3,1);       /* F */
    PUSHCOMM(30,1);     /* CLR */
    PUSHV(5);           /* K */
    PUSHV(2);           /* I */
    ADD;
    DUP;
    ZUWEIS(5);          /* K */
    PUSHV(0);           /* S */
    GREATER;
    JUMPIFZERO LBL_61;	/* BEQ_s(-29); */
    PUSHCOMM(74,0);     /* FLUSH */
LBL_81:  PUSHX("I");
    PUSHLEER;
    PUSHCOMM(147,2);    /* PRINT */
    PUSHVV(4);          /* C */
    COMM_INC;           /* INC */
LBL_91:  PUSHV(2);      /* I */
    PUSH1;
    ADD;
    DUP;
    ZUWEIS(2);          /* I= */
    PUSHV(0);           /* S */
    GREATER;
    JUMPIFZERO LBL_38;  /* BEQ_s(-104); */
...

Dies ist Bytecode, welcher aus folgenden (X11-Basic) Zeilen generiert wurde:

...
FOR i=2 TO s
  IF f(i)
    IF 2*i<s
      FOR k=2*i TO s STEP i
        CLR f(k)
      NEXT k
      FLUSH
    ENDIF
    PRINT i,
    INC c
  ENDIF
NEXT i
...

Es ist nicht nötig, etwas davon zu verstehen, aber es gibt Ihnen vielleicht ein Gefühl dafür, was Bytecode wirklich ist, und dass es wirklich schwierig ist, die ursprünglichen BASIC-Zeilen daraus zu rekonstruieren.

Bitte probieren Sie den Bytecode-Compiler ruhig aus. Viele der Beispielprogramme funktionieren mit dem Bytecode-Compiler recht gut: z.B. mandel-einfach.bas. Der Bytecode wird etwa 10 mal schneller ausgeführt als das interpretierte Programm.

Hier wird gezeigt, wie man vorgeht:

xbbc mandel-einfach.bas -o mandel-einfach.b
xbvm mandel-einfach.b

3.6. Den Bytecode nach C Übersetzer benutzen

Es ist möglich, den durch xbbc erzeugten Bytecode in C-Quellcode zu übersetzen und schließlich diesen C-Quellcode zu einer ausführbaren binär-Datei zu kompilieren (z.B. mit dem GNU C-Compiler gcc). Auf diese Weise wird das endgültige Programm eine echte ausführbare Datei in Maschinencode, die (noch) etwas schneller läuft als der von der virtuellen Maschine interpretierte Bytecode.

Solche Programme können mit der dynamischen Laufzeitbibliothek (.so oder .dll) von X11-Basic oder der statischen Bibliothek (.a oder .lib) verknüpft werden. Am Ende laufen sie unabhängig von einem Interpreter oder einer virtuellen Maschine. Es gelten jedoch einige Einschränkungen für den Code. Was bedeutet: Nicht jedes Programm, das interpretiert werden kann, kann auch kompiliert werden.

Die generierten C-Quellen hängen von der Header-Datei xb2csol.h (normalerweise installiert unter /usr/include/x11basic/) und den Bibliotheken x11basic.a oder libx11basic.so ab, die daher vorhanden sein müssen.

xb2c verarbeitet eine Eingabedatei. Die Dateiendung der Eingabedatei ist normalerweise .b (was eine Bytecodedatei sein sollte, die von` xbbc` erzeugt wurde). Der Name der Standardausgabedatei ist 11.c, aber Sie können natürlich alternative Namen mit der Option -o angeben.

Eigentlich ist xb2c kein echter Compiler, sondern ein Übersetzer. Die Kompilierung wurde bereits vom Bytecode-Compiler durchgeführt. xb2c selbst führt lediglich eine Eins-zu-Eins-Übersetzung des Bytecodes durch (derzeit nur in C). Dieser Übersetzungsprozess ist noch nicht stark optimiert, aber sehr robust und portabel.

Es gibt keine Möglichkeit, den .bas-Quellcode aus der .c-Datei neu zu erstellen. Dennoch ist die C-Datei plattformunabhängig und kann auf allen Plattformen kompiliert werden, wo ein C-Compiler verfügbar ist (und die x11basic-Bibliothek portiert ist).

Hier wird gezeigt, wie man es benutzt (alle Beispiele laufen unter Linux):

xbbc myprogram.bas -o b.b
xbvm b.b
xb2c b.b -o 11.c
gcc  11.c -lm -lX11 -lx11basic -lasound -lreadline -lgmp \
    -llapack -o a.out

Aus Bequemlichkeit kann man auch folgendes Kommando ausführen:

xbc -virtualm myprogram.bas -o a.out

Das macht exakt das gleiche.

3.7. Der X11-Basic Compiler-Manager xbc

Das X11-Basic-Paket wird mit dem X11-Basic-Compiler xbc ausgeliefert, der eigenständige Binärdateien aus dem X11-Basic-Quellcode erstellt. Es kann auch .o Objektdateien, sogenannte Shared Objekte (oder DLLs) und Bytecode erzeugen.

Es gibt drei Methoden, wie die Kompilierung durchgeführt werden kann:

  1. Die Pseudo-Methode :: Der Quellcode wird zusammen mit dem X11-Basic-Interpreter in eine ausführbare Datei gebündelt, die ausgeführt werden kann. Die Ausführungsgeschwindigkeit ist nicht schneller als der interpretierte Quellcode, aber alle Programme laufen und verhalten sich genau so, als wären sie im Interpreter ausgeführt worden. Derzeit ist diese Methode nicht für WINDOWS verfügbar, da gcc verwendet wird, um die X11-Basic-Laufzeitbibliothek zu komprimieren und zu verknüpfen. Dies ist jedoch die Standardeinstellung für UNIX- und Linux-Betriebssysteme.

  2. Die Bytecode-Methode :: Der Quellcode wird in Bytecode kompiliert und dieser Bytecode wird zusammen mit der virtuellen X11-Basic-Maschine in eine ausführbare Datei gebündelt, die ausgeführt werden kann. Die Ausführungsgeschwindigkeit ist viel schneller als der interpretierte Quellcode. Es gelten jedoch einige Einschränkungen für den kompilierten Quellcode, z.B. GOTOs über Prozeduren hinweg sind nicht möglich, ebenso wie ON ERROR und ON BREAK zur Zeit nicht funktionieren. So wird etwas obskurer Code wahrscheinlich nicht korrekt kompiliert. Diese Methode wird jedoch als die bevorzugte Methode empfohlen und ist die Standardeinstellung für MS WINDOWS.

  3. Das unabhängige Verfahren :: Der Quellcode wird in Bytecode kompiliert und dann in den C-Quellcode übersetzt, der schließlich unter Verwendung eines C-Compilers (z. B. GNU gcc) oder eines Cross-Compilers kompiliert wird. Dies ist die bevorzugte Methode auf UNIX-Systemen (obwohl dies nicht der Standard ist), wo eine Entwicklungsumgebung (GCC und Entwicklungspakete für Bibliotheken) verfügbar ist. Unter WINDOWS ist dies normalerweise nicht der Fall, daher kann Methode 3 nicht verwendet werden. Unter Ubuntu Linux müssen Sie mindestens folgende Pakete installieren: gcc, libreadline-dev, libasound-dev, libgmp-dev, liblapack-dev und vielleicht andere. Wenn dies geschehen ist, wird der Compiler mit Methode 3 funktionieren.

Um Methode 3 auf UNIX / Linux-Systemen auszuwählen, verwenden Sie die Befehlszeilenoption -virtualm. Die Windows-Version des Compilers verwendet automatisch nur Methode 2.

Der Compiler xbc selbst wurde in X11-Basic geschrieben und beruht auf dem Vorhandensein von` xbbc` und xv2c (für Methoden 2 und 3).

Sie finden den Compiler-Quellcode in examples/compiler/xbc.bas. Ja, der Compiler kompiliert sich selbst. Stellen Sie nur sicher, dass Sie die gemeinsam genutzte Bibliothek libx11basic.so und die Bibliothek für die statische Verknüpfung zuvor erstellt und nach /usr/lib verschoben haben.

   make lib x11basic.a

Dann können sie den Kompiler starten:

   xbasic xbc.bas

Weitere Informationen zum Compiler finden Sie auf der Manpage xbc (1).

3.8. Der ANSI-Basic zu X11-Basic Konverter

Im X11-Basic-Paket ist ein einfacher ANSI-Basic zu X11-Basic Konverter bas2x11basic enthalten.

Tip

Der Quellcode bas2x11basic.bas des Konverters befindet sich im Verzeichnis examples/compiler/.

Er hilft dabei, alte (echte) BASIC-Programme mit Zeilennummern und mehreren Befehlen pro Zeile in die X11-Basic-Struktur zu konvertieren. Da es so viele verschiedene BASIC-Versionen gibt, müssen Sie diese Dateien in den meisten Fällen manuell nachbearbeiten. Aber die meiste Arbeit wurde bereits von diesem Konverter erledigt. Details zur Kompatibilität zu anderen Dialekten von BASIC finden Sie in Kapitel {compat}.

Hier ein Beispiel:

xbasic bas2x11basic.bas ansibasic.bas -o newname.bas

Für weitere Optionen versuchen Sie mal

xbasic bas2x11basic.bas --help

und konsultieren Sie auch die man-page man bas2x11basic. Wenn Sie den Konverter verbessern möchten, tun Sie dies bitte. Vielleicht möchten Sie mir das Ergebnis senden.

3.9. GFA-BASIC Programme verwenden

GFA-Basic-Programme haben ein tokenisiertes Binärformat und normalerweise die Endung .gfa. Dieses Binärformat muss in ASCII-Dateien dekodiert werden, bevor sie mit X11-Basic verwendet werden können. Dieser Job wird mit dem Hilfsprogramm gfalist (manchmal auch` gfa2lst` oder ons-gfalist genannt) von Peter Backes erledigt.

Die resultierenden GFA-Basic-Programme benötigen normalerweise einige manuelle Korrekturen. Nur sehr einfache werden direkt und ohne Korrekturen mit X11-Basic. Details zur Kompatibilität finden Sie im Kapitel {gfacompat}.

4. Programmieren in X11-BASIC

Dieses Kapitel beschreibt alles, was Sie zum Schreiben Ihrer eigenen Programme in X11-Basic benötigen.

4.1. Der X11-BASIC Dialekt

Die Programmiersprache BASIC gibt es seit den 1960er Jahren. BASIC ist ein Akronym und steht für Beginners All Purpose Symbolic Instruction Code. BASIC wurde ursprünglich entwickelt, um eine Programmiersprache zu sein, die für eine breite Palette von Projekten von jedermann einfach zu bedienen und zu erlernen ist.

X11-Basic ist ein Dialekt davon, aber es ist kein BASIC in seiner ursprünglichen Form. Es ist eher eine Mischung aus klassischem BASIC mit strukturierten Sprachen wie PASCAL und Modula-2.

Die Syntax von X11-Basic orientiert sich am berühmten GFA-BASIC, welches 1985 für den ATARI ST entwickelt wurde. GFA BASIC (ab Version 3.5, der populärsten Version) war für damalige Verhältnisse eine sehr moderne Programmiersprache. Wie X11-Basic verzichtet es auf Zeilennummern und verfügt über eine vernünftige Auswahl an strukturierten Programmierbefehlen.

X11-Basic hat viele Eigenschaften, die die Sprache von der ursprünglichen Zielsetzung (ANSI-Basic) unterscheiden. Wie bei GFA-Basic helfen diese Abwandlungen bei der Entwicklung von Programmen. Diese haben dann nämlich eine strukturiertere Form, und nutzen außerdem die seit Mitte der 80er Jahre verfügbaren modernen grafischen Benutzeroberflächen:

  • Ein Befehl oder eine Deklaration pro Zeile für bessere Lesbarkeit,

  • Verwendung von Unterprogrammen (Prozeduren) und Funktionen mit lokalen Variablen und Parameterübergabe nach Wert oder Verweis,

  • Datenanweisungen und Arrays,

  • leistungsfähige Schleifen- und Programmablaufkonstrukte,

  • Datei- und Socket-Operationen,

  • komplexe Zahl Mathematik,

  • Operationen zur Bearbeitung von beliebigen / unendlichen Präzisionszahlen,

  • Befehle zum direkten Zugriff auf die Betriebssystem-Shell,

  • Befehle für die Verwendung von Grafiken in mehreren Fenstern,

  • ein Port des AES (die grafische Benutzeroberfläche des ATARI ST), die die einfache Verwendung von Elementen einer grafischen Benutzeroberfläche in Ihrem Programm ermöglicht,

  • Befehle für die direkte Speicherbearbeitung, mit denen Sie fast wie mit Maschinensprache auf den Computer zugreifen können,

  • Möglichkeit, Quellcode für Bibliotheken zusammenzuführen und wiederzuverwenden,

  • Inline-Datenkomprimierung und -verschlüsselung (in US-Versionen deaktiviert),

  • Unicode (UTF-8) Unterstützung,

  • Unterstützung für den Zugriff auf USB und Bluetooth-Geräte,

  • leistungsfähige Mathematik (einschließlich komplexer Zahlen, Matrix / Lineare Gleichungen, Regressionen, große Ganzzahlen und schnelle Fourier-Transformationen) und

  • Ein Compiler ist verfügbar.

4.1.1. Interpreter und Compiler

X11-Basic-Programme (oder Skripte) werden standardmäßig interpretiert. Das heißt, der sogenannte Interpreter nimmt jede Zeile Ihres Codes und schaut, was damit zu tun ist. Der Compiler macht das anders, er nimmt Ihren Code einmal, übersetzt ihn in Bytecode oder Maschinencode, was zu einer schnelleren Programmausführung führt, da der Schritt zur Befehlssuche nicht mehr angezeigt wird. Das kompilierte Programm kann einfach aus der Box heraus ausgeführt werden. Der Vorteil eines Interpreters besteht dagegen darin, dass Sie Ihr Programm direkt testen und ausführen können, ohne zuerst einen Compiler zu starten. Dies ist hilfreich bei der Entwicklung, aber natürlich steht auch ein Compiler zur Verfügung, mit dem Sie nach Abschluss des Tests einen recht schnellen Maschinencode aus Ihrem X11-Basic-Programm erstellen können.

4.2. Erste Schritte

Um ein erstes X11-Basic-Programm zu schreiben, benötigen Sie einen Editor, in den Sie den Quellcode eingeben können. Das X11-Basic-Paket enthält keinen Editor, aber viele so genannte Texteditoren sind fast überall verfügbar und zufällig sind sie bereits auf Ihrem System installiert. Sie können Notapad2 auf MS WINDOWS-Systemen, pico, nano, vi, emacs, nedit, gedit und viele mehr auf UNIX- und Linux-Systemen verwenden, pico auf einem TomTom-Gerät, "Ted" oder "920 Texteditor" auf Android. Dies ist nur eine kleine Liste von Möglichkeiten hier.

Öffnen Sie einen solchen Editor und Sie können mit der Programmierung beginnen.

4.3. Mein erstes X11-Basic-Programm

Wir gehen davon aus, dass Sie ein Konsolenfenster (eine Shell) unter Linux oder WINDOWS geöffnet haben. Die Android-Version ist ein bisschen anders.

Öffnen Sie Ihren bevorzugten Editor und geben Sie die folgende Codezeile in den Editor ein.

PRINT "Hallo X11-Basic!"

Speichern Sie nun die Datei als "hallo.bas" und starten Sie den Interpreter mit

xbasic hallo.bas

X11-Basic sollte sich nicht beschweren. Wenn dies der Fall ist, prüfen Sie nochmal sorgfältig auf Tippfehler. Das Programm sollte jetzt Ihre Hallo-Nachricht an der Konsole oder im Konsolenfenster ausgeben, von dem der Interpreter gestartet wurde. Es wird nicht zur Shell zurückkehren, sondern nur nach zusätzlichen Befehlen fragen. Geben Sie nun

> quit

ein und Sie kehren zur Shell zurück.

Natürlich können Sie den quit Befehl auch gleich in Ihr hello.bas einfügen:

PRINT "Hallo X11-Basic!"
QUIT

Jetzt kehrt das Programm immer zum Shell-Prompt zurück, wenn es fertig ist.

Jetzt können wir es kompilieren:

xbbc hallo.bas -o hallo.b

erzeugt eine Bytecode-Binärdatei hallo.b.

Sie können dies ausführen:

xbvm hallo.b

gibt Ihnen die gleiche Ausgabe "Hallo X11-Basic!".

Echte Compilierung benötigt zwei weitere Schritte:

xb2c hallo.b -o hallo.c

produziert eine C-Quelldatei hallo.c.

Wenn Sie den gnu C Compiler verfügbar haben, können Sie die C-QUelldatei in ein unabhängiges ausführbares Programm mit dem Namen hallo (oder hallo.exe auf Windows) kompilieren:

gcc hallo.c -o hallo -lm -lX11 -lx11basic -lasound -lreadline

Bittesehr! Ihr Programm kann jetzt direkt gestartet werden mit:

./hallo

4.4. Programmstruktur

Wenn Sie anspruchsvollere Programme als das Hallo-Beispiel schreiben möchten, sollten Sie die allgemeine Struktur eines X11-Basic-Programms verstehen.

Ein X11-Basic-Programm besteht aus einem Hauptprogrammblock und Unterprogrammen und -funktionen. Der Hauptprogrammblock ist der Abschnitt zwischen der ersten Zeile und dem Schlüsselwort END (oder QUIT). Der Code im Hauptblock steuert die Logik Ihres Programms. In einem einfachen Programm ist das alles, was benötigt wird. In größeren und komplexeren Programmen macht das Einfügen des gesamten Codes in den Hauptblock das Programm schwer lesbar und schwer verständlich. Mit Unterprogrammen können Sie Ihr Programm in überschaubare Abschnitte aufteilen, von denen jeder seine eigenen, aber begrenzten Aufgaben ausführt.

4.5. Allgemeine Syntax

Die Syntax einer typischen X11-Basic-Zeile lautet:

KOMMANDO Parameterliste

Die Parameterliste besteht normalerweise aus einer Liste von durch Kommas getrennten Ausdrücken.

Ein anderer Typ von X11-Basic-Zeilen sind Zuweisungen:

Variable = Ausdruck

Variablen haben typischerweise einen Namen und können verschiedene Typen haben. Das Ergebnis des Ausdrucks wird unter diesem Namen zur weiteren Bezugnahme gespeichert. Jede Zeile des X11-Basic-Codes kann genau einen Befehl oder eine Zuweisung (oder einen Kommentar) enthalten.

Hier ist ein typisches Stück X11-Basic-Code:

  LOCAL l,ll,content$,g$,gg$,comp
  CLR comp
  IF EXIST(f$)
    OPEN "I",#1,f$
    ll=LOF(#1)
    content$=INPUT$(#1,ll)
    CLOSE #1
  ENDIF
  ' und so weiter ...

4.5.1. Zeilen anfügen

Bei vielen Editoren gilt eine Begrenzung der maximalen Zeilenlänge (z.B. 4096 Zeichen pro Zeile) (Beachten Sie, dass es in X11-Basic selbst keine Begrenzung der Zeilenlängen gibt.) In X11-Basic kann in seltenen Fällen ein einzelner Befehl aus mehr als 4096 Zeichen bestehen (z.B. indem man einem Array eine Array-Konstante zuweist). Daher wurde eine Möglichkeit implementiert, Zeilen in zwei (oder mehr) aufzuteilen: Wenn das letzte Zeichen einer Zeile ein \ ist (es muss wirklich das letzte Zeichen der Zeile sein und darf nicht durch ein Leerzeichen ersetzt werden!), wird die folgende Zeile an erstere angehängt, indem das \ und das folgende Zeilenumbruchzeichen durch Leerzeichen ersetzt werden.

Beispiel:
PRINT "Hello,"; \
 " that's it"

Das wird intern so behandelt, als stünde da:

PRINT "Hello,";  " that's it"
Note

Bitte beachten Sie: Das \-Zeichen muss an einer Position innerhalb des Befehls platziert werden, an der auch ein Leerzeichen zulässig wäre.

4.5.2. Kommentare

Ein Kommentar kann mit dem REM-Befehl oder der Abkürzung ' in Ihren Programmcode eingefügt werden. Auch das # als erstes Zeichen einer Programmzeile reserviert den Rest der Zeile für einen Kommentar. Alles, was hinter dem REM steht, wird von X11-Basic ignoriert.

Wenn Sie Kommentare am Ende einer Zeile platzieren möchten, müssen sie mit ! vorangestellt werden.

Beispiel:
' Dies ist eine Demonstration von Kommentaren
DO      ! Endlosschleife
LOOP    ! mit nichts drin
Note

Diese Zeilenende-Kommentare können nicht nach DATA (und REM) verwendet werden.

4.6. Der Basisbefehlssatz: PRINT, INPUT, IF und GOTO

Mit dem PRINT-Befehl wird Text auf den Textbildschirm ausgegeben. Der Textbildschirm ist Ihr Terminal (unter UNIX) oder das Konsolenfenster (unter Windows). PRINT wird verwendet, um eine Standardausgabe zu erzeugen, z.B. Text, Zeichenfolgen, Zahlen, das Ergebnis einer Berechnung. Formatierungen der Zahlen sind ausserdem möglich.

Beispiel:
PRINT "Das Ergebnis von 1 + 1 ist:";1+1

Mit dem Befehl INPUT lässt man den Benutzer Daten eingeben, z.B. Zahlen oder Text. Die Daten können auf dem Textbildschirm bzw. Konsolenfenster eingegeben werden. Zusammen mit PRINT ermöglicht dies bereits die Implementierung einer sehr einfachen Benutzeroberfläche.

Beispiel:
INPUT "Bitte geben Sie Ihren Namen ein:",name$
PRINT "Hallo", name$

Der IF-Befehl lässt das Programm abhängig vom Ergebnis einer Berechnung verschiedene Dinge tun. Dazu wird der Code in einen Block gruppiert, der nur ausgeführt werden soll, wenn das Ergebnis des Ausdrucks nach IF nicht Null ist. Der Block beginnt mit dem IF-Befehl und endet mit einem ENDIF-Befehl. Wenn das Ergebnis des Ausdrucks nach IF Null ist, wird das Programm nach dem ENDIF fortgesetzt und die Codezeilen zwischen dem IF und dem ENDIF werden nicht ausgeführt.

Beispiel:
INPUT "Bitte geben Sie eine Zahl ein:";a
IF a=13
   PRINT "Oh, Sie mögen offensichtlich die Dreizehn!"
ENDIF
PRINT "Danke für die ";a;"."
Note

X11-Basic definiert zwei Systemvariablen FALSE und TRUE, die den Wahrheitswert falsch oder wahr representieren. Dabei gilt FALSE=0 und TRUE=-1. Diese Systemvariablen können wie andere Variablen in den Ausdrücken verwendet werden.

Mit GOTO können Sie in einen anderen Teil Ihres Programms verzweigen. GOTO, trotz seines schlechten Rufs (es galt als schädlich), hat immer noch seinen guten Nutzen. Da keine Zeilennummern verwendet werden, müssen Sie eine Markierung der Zeile verwenden, zu der Sie mit dem GOTO-Befehl springen wollen. Diese Markierung muss am Zeilenanfang stehen und mit einem Doppelpunkt enden.

Beispiel:
nochmal:
INPUT "Bitte geben Sie eine Zahl ein, aber nicht die 13:";a
IF a=13
   PRINT "Oh, Sie mögen offensichtlich die Dreizehn!"
   PRINT "Aber bitte geben Sie eine andere Zahl ein."
   GOTO nochmal
ENDIF
PRINT "Danke für die ";a;"."

Neben diesen vier sehr grundlegenden Befehlen (die in jedem BASIC-Dialekt existieren) hat X11-Basic viele weitere Funktionen, die das Leben einfacher und Ihre Programme benutzerfreundlicher machen.

4.7. Variablen

Variablen im BASIC-Dialekt sind analog zu Variablen in der Mathematik. Variablenbezeichner (Namen) bestehen aus alphanumerischen Zeichenfolgen. Diese Bezeichner beziehen sich auf Werte im Computerspeicher. Im X11-Basic-Programm ist ein Variablenname eine Möglichkeit, eine Variable an einen Speicherort zu binden. Der entsprechende Wert wird als Datenobjekt an diesem Ort gespeichert, so dass später über den Variablennamen auf das Objekt zugegriffen werden kann.

Beispiel:
a=1    ! Weist einer Variablen mit dem Namen a eine 1 zu
b=a+1  ! Auf die Variable a kann Bezug genommen werden, um eine Berechnung durchzuführen
PRINT "Die Variable b enthält jetzt eine ";b

Die Variablen werden dynamisch verwaltet, so sind beliebig große Zeichenketten und Felder möglich. Die Grenze ist hier nur der maximal allozierbare Speicher und max. 31 Bit für die Indizierung. Das sollte vorerst ausreichen.

Variablennamen dürfen sehr lang sein, wenn Sie möchten, und können auch Ziffern und einen Unterstrich enthalten, mit der Ausnahme, dass der erste Buchstabe des Variablennamens keine Ziffer sein darf.

Beispiel:
mein_sehr_langer_variablenname=1.23456
PRINT mein_sehr_langer_variablenname

Sie können auf eine Variable verweisen, indem Sie ihren Namen an der Stelle angeben, an der der Wert der Variablen verwendet werden soll. X11-Basic weiss automatisch, wo die Daten gespeichert sind und wie damit umgegangen wird.

Es ist auch wichtig, X11-Basic mitzuteilen, welche Art von Daten Sie speichern möchten. Sie können Variablen haben, die nur Zahlen speichern, aber auch Variablen, die sich auf ein Zeichen oder eine ganze Zeichenfolge beziehen, z.B. eine Textzeile. Die folgende Zeile des X11-Basic-Codes erstellt eine Variable namens "alter" für Sie und weist ihr den Wert 18 zu.

alter=18

Wenn Sie jedoch einen Text speichern möchten, muss die Variable Zeichen anstelle von Zahlen enthalten können. In diesem Fall markieren Sie die Variable mit einem $, um zu sagen, dass sie Text und nicht Zahlen speichern soll:

name$="Rainer"

Textkonstanten müssen übrigens mit "" eingeschlossen sein, um X11-Basic mitzuteilen, dass der Text nicht als Programmcode interpretiert werden darf, sondern nur als beliebiger Text behandelt werden soll.

Die Zuweisung erfolgt mit dem Operator =. Der Operator = wird auch in Ausdrücken verwendet, z.B. nach einem IF-Befehl. Aber dort wird er nicht als Zuweisungsoperator verwendet, sondern als Vergleichsoperator behandelt. In X11-Basic sind beide =-Operatoren identisch. Der Interpreter unterscheidet zwischen ihnen nur durch den Zusammenhang.

Beispiel:
x=(a=3)

Hier ist das erste = eine Zuweisung und das zweite ist der Vergleichsoperator. x wird eine -1 (TRUE, wahr) zugewiesen, wenn a 3 ist und eine 0 (FALSE, falsch) ansonsten. Die Klammern sind hier nicht notwendig, sie helfen nur, diesen Ausdruck zu lesen. Verwirrt? Nun, Sie werden sich irgendwann daran gewöhnen.

Eine Zuweisung überschreibt übrigens den alten Wert, der in der Variable evtl. gespeichert ist. Solange Sie einer Variablen keinen Wert zuweisen, enthält sie einen Standardwert von 0 oder eine leere Zeichenkette.

4.7.1. Der Geltungsbereich einer Variablen

X11-Basic verwendet zwei Bereiche für Variablen: global (Standard) und lokal.

Globale Variablen können von überall innerhalb des Programms geändert werden, und jeder Teil des Programms kann davon abhängen. Sofern nicht anders mit LOCAL deklariert, sind alle X11-Basic-Variablen standardmäßig global und dies muss nicht explizit deklariert werden.

Ein Nachteil globaler Variablen ist jedoch: Die Verwendung globaler Variablen erschwert das Lesen und Verstehen von Software. Da jede Codezeile irgendwo im Programm den Wert der Variablen jederzeit ändern kann, kann das Verstehen der Verwendung der Variablen das Verständnis eines großen Teils des Programms erfordern. Außerdem kann es zu Benennungsproblemen führen, da eine globale Variable die Verwendung desselben Namens für jede andere ggf. in einer Unterroutine nur lokal verwendetet Variable gefährlich macht. Es kann zu Nebenwirkungen kommen. Auch die rekursive Programmierung ist fast unmöglich mit nur globalen Variablen. Nicht zuletzt wird die Verwendung von Prozeduren und Funktionen viel klarer, wenn Sie alle internen Variablen dieser Funktion einkapseln können und Sie nicht außerhalb des Funktionsumfangs verändert werden können. Wenn Sie versehentlich eine dieser internen Variablen an einer anderen Stelle im Code verwenden, wird möglicherweise das Funktionsverhalten geändert.

Aus diesem Grund stellt X11-Basic auch lokale Variablen zur Verfügung, die nur innerhalb einer bestimmten Funktion oder Prozedur und ihrem Kontext existieren.

Lokale Variablen müssen innerhalb der Funktion oder Prozedur, zu der sie gehören, mit dem Befehl LOCAL deklariert werden. Außerhalb dieser spezifischen Prozedur oder Funktion existieren sie einfach nicht, oder wenn eine globale Variable mit demselben Namen existiert, beziehen sie sich auf unterschiedliche Inhalte.

4.7.2. Datentypen

Lassen Sie uns nun auf den Typ einer Variablen zurückkommen. Woran kann man erkennen, welche Art von Inhalt eine Variable speichern kann? Woran erkennt X11-Basic das? An der Art, die der Name der Variablen geschrieben ist! Um zwischen verschiedenen Arten von Datentypen zu unterscheiden, hängt X11-Basic ein spezielles Typisierungszeichen als Suffix an den Variablennamen an, um zwischen verschiedenen Möglichkeiten zu unterscheiden, Daten in Variablen zu speichern.

Der X11-Basic-Interpreter kennt 64-Bit-Gleitkommavariablen, 32-Bit-Ganzzahlvariablen, Zeichenfolgen und beliebigdimensionale Felder obengenannter Typen. Eine Deklaration der Variablen und ihres Typs ist nicht notwendig (außer für Arrays → DIM), da der Interpreter den Typ der Variablen an deren Endung erkennt: 32bit Integer-Variablen haben das Suffix %, beliebig große Integer-Variablen habe ein &, komplexe Variablen ein #, Zeichenketten ein $, Arrays ein (). Variablen ohne Endung werden als reele 64-Bit Gleitkommavariablen interpretiert. Zeiger sind Ganzzahlen, Funktionsaufrufe bzw. -ergebnisse sind durch @ gekennzeichnet. Logische Ausdrücke sind ebenfalls vom Typ Integer. Es ist wichtig zu wissen, dass Variablen mit einem speziellen Suffix sich von denen ohne unterscheiden (auch wenn der Rest des Namens identisch ist).

Beispiele:
x=10.3        ! das ist eine Variable für reelle Zahlen (64bit Gleitkomma)
x$="Hallo"    ! das ist eine andere Zeichenkettenvariable
x%=5          ! das ist eine (32bit) Ganzzahlvariable, verschieden(!)
x&=79523612688076834923316 ! das ist eine Variable für große Ganzzahlen,
                           ! weiterhin verschieden
x#=3+4i       ! das ist eine variable für komplexe Zahlen,
@x            ! dies bezieht sich auf eine Funktion oder Procedur x
x()=[1,2,3,4] ! Dieses Biest definiert ein Array.

4.7.3. Variablennamen

Sie können beliebige Buchstaben und Zahlen für Ihre Variablennamen verwenden. Leerzeichen sind nicht zulässig, aber Unterstriche innerhalb des Variablennamens. Der Variablenname kann beliebig lang sein. X11-Basic beschränkt Sie nur auf folgende Weise: Eine Variable darf nicht mit einer Zahl oder einem Unterstrich beginnen, nur mit Buchstaben. Vermeiden Sie es, Ihre Variablen wie X11-Basic-Befehle zu benennen. Es funktioniert zwar, aber es kann Probleme verursachen. Versuchen Sie niemals, Systemvariablen X11-Basic Werte zuzuweisen (z.B. TRUE, FALSE, TIMER, PC, TERMINALNAME$). Die Werte werden zwar zugewiesen, aber Sie können die zugewiesenen Werte nicht verwenden, da immer die internen Werte verwendet werden.

Gültige Variablennamen sehen wie folgt aus:

x, auto%, lives%, bonus1%, x_1, city_name$, debit, z#   .

Ungültige Variablennamen sehen wie folgt aus und X11-Basic würde einen Fehler melden:

_blank, 1x, ?value%, 5s$, 1i, #u.
Tip

Beginnen Sie Ihre Variablennamen immer mit einem Buchstaben von A-Z und Sie sind auf der sicheren Seite!

Variablennamen und Befehle unterscheiden nicht zwischen Groß- und Kleinschreibung. Jeder Name ist nur an eine Art von Variablen gebunden; A$ ist eine ganz andere Variable als A, die sich von A% oder A$(1,1) unterscheidet.

Leerzeichen zwischen Befehlen werden ignoriert. Beachten Sie jedoch, dass kein Leerzeichen zwischen dem Namen einer Variablen oder einem Befehl und dem '(' der Parameterliste zulässig ist. ASC("A") ist gut, ASC( "A" ) auch, aber ASC ("A") ist es nicht.

Beispiele:
Ganzzahlvariablen:     i%=25
                       my_adr%=VARPTR(b$)
                       b%=MALLOC(100000)
Grosse Ganzzahlvariablen:  i&=79523612688076834923316
                           a&=FACT(100)
Gleitkommavariablen:       a=1.2443e17
                           b=@f(x)
Komplexe Variablen:        a#=1.2443e17+1.2i
                           b#=CONJ(a#)
Zeichenketten:		   t$="Hello everybody !"
Felder und Arrays:         i%(),a(),t$(), [1,3,5;7,6,2]|

4.7.4. Zahlen

X11-Basic verwendet normalerweise ganze Zahlen (32 Bit), die von -2147483648 bis 2147483647 reichen, und Fließkommazahlen, die 64Bit IEEE 754-Standardwerte sind. Diese 64-Bit Gleitkommazahlen haben eine Mantisse von 52 Bits und einen Exponenten von 11 Bits und ein Vorzeichenbit. Diese Zahlen können 15 bis 16 signifikante Ziffern und Potenzen von 1e-308 bis 1e308 darstellen. Komplexe Zahlen bestehen aus zwei 64-Bit-Fließkommawerten.

X11-Basic unterstützt derzeit auch Integer-Zahlen mit unendlicher Genauigkeit bzw. beliebiger Größe. Diese Zahlen werden in einem Speicherbereich variabler Größe gespeichert, so dass eine beliebige Anzahl von Ziffern gespeichert werden kann. Die Berechnung mit großen Ganzzahlen ist jedoch langsam und nur einige eingebaute Funktionen können mit ihnen verwendet werden.

Die Zahlendarstellung sieht so aus: Einer Zahl (Konstanten) kann ein Vorzeichen + oder - vorangestellt sein gefolgt von einer Folge von Ziffern, mit oder ohne Dezimalpunkt, dann ein "E" und darauf der positive oder negative Exponent als Potenz zur 10, z.B.

 -253 	67.3 	0.25 	-127.42E-3 	-1.3E7 	1

Der Imaginärteil der komplexen Zahlkonstanten ist mit einem nachgestellten "i" markiert, z.B.

 -2i 	1i 	0.25+3i     -127.42E-3i
Note

Ein einzelnes "i" wird immer als reeller Variablenname behandelt. Wenn Sie die imaginäre Einheit haben möchten, benutzen Sie bitte immer "1i".

Ganzzahlige Zahlen ohne Dezimalbruch oder Exponent können auch hexadezimal oder binär sein. Hexadezimalen Zahlen sollte ein "$" (oder "0x") vorangestellt sein und Binärzahlen ein "%", z.B.

%101010     -$FFE0    0xA0127BD     -%10001001     %00011010

4.7.5. Zeichenketten

String-Variablen können Zeichenfolgen (Bytes) beliebiger Länge enthalten. Es gibt kein Längenlimit für eine Zeichenfolge außer dem Speicher des Computers. Zeichenfolgen enthalten im Allgemeinen ASCII-Text, können aber beliebige Bytefolgen enthalten, sogar Zeichen, die den ASCII-Code Null haben. Mit anderen Worten, eine Zeichenfolge ist eine Sammlung von einer ANzahl von Bytes. Sie können Strings als beliebig langer Speicherbereich für Binärdaten behandeln. Strings sind automatisch elastisch, d.h. sie werden automatisch so vergrößert oder verkleinert, dass sie genau die Anzahl der Bytes enthalten können, die ihnen zugewiesen wird. Wenn sich die Größe einer Zeichenfolge ändert, kann sich ihre Position im Speicher ändern, z. B. wenn eine längere Zeichenfolge zugewiesen wird und nicht genügend Platz hinter der Zeichenfolge zum Speichern der zusätzlichen Bytes vorhanden ist.

String-Variablen unterscheiden sich von anderen Variablennamen durch das Anhängsel $.

String-Konstanten werden von (doppelten) Anführungszeichen "" eingeschlossen.

Eine Fülle von intrinsischen Funktionen und Funktionen werden von X11-Basic bereitgestellt, um effiziente String-Verarbeitung und Datenmanipulation zu ermöglich.

Es gibt eine Möglichkeit, Sonderzeichen in String-Konstanten einzufügen. Der übliche Weg in BASIC besteht darin, die Zeichenkette in Sub-Strings aufzuteilen und die Teile während der Laufzeit wie im folgenden Codefragment zu verketten:

Beispiel:
st$="Dies ist eine spezielle Zeichenfolge, die am Ende ein Klingelzeichen enthält "+CHR$(7)
Tip

Anführungszeichen erhält man übrigens mit CHR$(34).

4.7.6. Felder

Arrays sind Speicherbereiche, in denen viele Werte desselben Typs gleichzeitig gespeichert werden. Während normale Variablen jeweils einen einzelnen Wert speichern, kann eine Array-Variable viele Werte speichern. Der Zugriff auf die Werte erfolgt über den Namen der Variablen und die entsprechenden Indizes. Der Index oder die Indizes folgen dem Namen der Variablen zwischen ( und ).

Die Anzahl der Indizes (die Dimension) ist nicht begrenzt. Sie können beliebig viele verwenden. Es gibt auch keine Begrenzung für die Indexwerte, außer dass die Indexwerte eine positive Ganzzahl sein müssen und dass der Speicher die Arraygrößen begrenzen kann.

X11-Basic-Arrays können Variablen eines beliebigen Datentyps einschließlich Strings enthalten. Alle Arrays, sogar mehrdimensionale Arrays, können neu dimensioniert werden, ohne den Inhalt zu verändern. Eine Besonderheit von X11-Basic ist die implizite Dimensionierung von Arrays und die Existenz von Array-Konstanten. Sie können ein Array mit dem Befehl DIM definieren. Sie können das Array auch durch eine Zuweisung wie folgt definieren

DIM b(10)
a()=b()

falls b() bereits dimensioniert war, oder durch

a()=[1,2,3,4;6,7,8,9]

Zuweisen einer Array-Konstante. (In diesem Beispiel wird ein zweidimensionales Array erstellt. Spalten der Matrix werden wie bisher mit Komma getrennt und die Zeilen durch ';'.)

4.7.7. Zahlen mit beliebiger Präzision

X11-Basic unterstützt auch Zahlen mit unendlicher Präzision oder besser ausgedrückt mit beliebiger Genauigkeit. Hierfür gibt es einen speziellen Datentyp.

Arithmetrik mit beliebiger Genauigkeit, auch Große-Zahlen-Arithmetrik oder manchmal Arithmetik mit unendlicher Genauigkeit genannt, bedeutet, daß Berechnungen mit Zahlen durchgeführt werden, deren Genauigkeit nur durch den verfügbaren Speicher des Computers begrenzt sind. Dies steht im Gegensatz zu der normalerweise verwendeten Arithmetik mit fester fester Genauigkeit (z.B. 32Bit), oder Gleitkommaarithmetrik, welche ebenfalls eine begrenzte Genauikeit aufweist.

Rechnen mit solchen Zahlen ist langsam, und nicht alle Funktionen sind für diesen Datentyp verfügbar. Unendliche Präzision wird verwendet, wenn die Geschwindigkeit der Arithmetik kein begrenzender Faktor ist oder wo genaue Ergebnisse mit sehr großen Zahlen erforderlich sind. Prominentes Beispiel dafür ist die starke Kryptographie und alle Ihre Anwendungen. X11-Basic ist also auch dafür schon gut gerüstet.

Der Datentyp mit der Endung & unterstützt nur ganze Zahlen. Es ist Aufgabe des Benutzers (und nicht besonders schwierig), Routinen für rationale Zahlen (unter Verwendung von zwei großen ganze Zahlen, Zähler und Nenner) und entsprechende Routinen zum Addieren, Subtrahieren, Multiplizieren und Dividieren von Brüchen zu schreiben. Irrationale Zahlen mit beliebiger, aber festgelegter Genauigkeit, die eine Fließkommadarstellung benötigen, werden (derzeit) nicht unterstützt. Wenn jemand das braucht, lassen Sie es mich wissen.

Es gibt in X11-Basic folgende Operatoren für große Ganzzahlen: + - * / = <> <> MOD und DIV. Funktionen sind ABS(), SQRT(), NEXTPRIME(), FACT(), PRIMORIAL(), FIB(), LUCNUM(), RANDOM(), ADD(), SUB(), MUL(), DIV(), MOD(), POWM(), ROOT(), GDC(), LCM(), INVERT(), MIN(), MAX() und viele mehr. Auch `STR$(), BIN$(), OCT$() und HEX$() funktionieren mit großen Ganzzahlen.

Mit diesen Funktionen können Sie schon einige Berechnungen für die Kryptographie und Zahlentheorie anstellen.

Variablen sowohl normaler Zahlentypen als auch der großen Ganzzahlen können in Ausdrücken verwendet und gemischt werden. Sie werden bei Bedarf jeweils in entsprechnde passende Typen umgewandelt. Man sollte sich nur des evtl. möglichen Verlustes an Präzision bewusst sein.

Hier ist ein Beispiel, wie man große Zahlen-Arithmetik in X11-Basic verwendet, um eine große Zahl in ihre Primfaktoren zu faktorisieren:

Beispiel:
' Faktorisiere eine (große) Ganzzahl in ihre Primfaktoren.
' mit X11-Basic  >= V.1.23
'
DIM smallprimes&(1000000)
CLR anzprimes
smallprimes&(0)=2
INC anzprimes

INPUT "Geben Sie eine (große) Zahle ein: ",a&
PRINT "Ich berechne Primzahlen bis ";lim&;". Bitte warten..."
lim&=SQRT(a&)   ! Limit bis zu dem Primzahlen gesucht werden
FOR i=1 TO DIM?(smallprimes&())-1
  b&=NEXTPRIME(smallprimes&(i-1))
  EXIT IF b&>lim&
  smallprimes&(i)=b&
NEXT i
anzprimes=i
PRINT "Es wurden ";anzprimes;" Primzahlen berechnet bis: ";b&

PRINT "Faktorisierung:"
PRINT a&;"=";
FOR i=0 TO anzprimes-1
  WHILE (a& MOD smallprimes&(i))=0
    PRINT smallprimes&(i);"*";
    FLUSH
    a&=(a& DIV smallprimes&(i))
    lim&=SQRT(a&)
  WEND
  EXIT IF smallprimes&(i)>lim&
NEXT i
IF nextprime(a&-1)=a& or a&=1
  PRINT a&
ELSE
  ' Die Zahl ist zu groß und wir können nicht sicher sein,
  ' dass es sich wirklich um eine Primzahl handelt.
  PRINT "----incomplete test -----";a&
ENDIF
END
Note

Beachten Sie, dass die Liste der kleinen Primzahlen auch durch ein Sieb erzeugt werden kann. Die verwendete Methode basiert auf Primzahltests (mit der Funktion NEXTPRIME()) und ist möglicherweise nicht optimal.

4.8. Arithmetrik und Berechnungen

X11-Basic kann mit Zahlen und Arithmetik umgehen: Sie können trigonometrische Funktionen wie SIN() oder ATAN() oder Logarithmen (mit LOG()) berechnen lassen. Bitweise Operationen, wie AND oder` OR` sind ebenso verfügbar wie MIN() und MAX() (berechnet das Minimum oder Maximum ihres Arguments) oder MOD oder INT() (Rest bei einer Division bzw. der ganzzahliger Teiler einer Zahl). Viele andere Anweisungen geben einen vollständigen Satz von mathematischen Funktionen.

Die meisten dieser Funktionen können mit verschiedenen Eingabedatentypen arbeiten. Z.B. können Sie die Funktion SQRT() auch für komplexe Zahlen verwenden, wodurch ein komplexes Ergebnis zurückgegeben wird.

Note

X11-Basic sieht keine besonderen Operatoren und Funktionen für logische Ausdrücke vor. Man kann einfach die Bitweisen Verknüpfungen z.B. mit AND, OR oder NOT verwenden, wobei eine 0 (also alle Bits sind 0) als falsch und eine -1 (also alle Bits sind 1) als wahr interpretiert werden kann.

4.8.1. Ausdrücke und Bedingungen

Kein Unterschied macht den Unterschied.

Ausdrücke

werden benötigt, um Werte zu berechnen. Der einfachste Ausdruck ist eine numerische oder eine String-Konstante. Komplexere Ausdrücke können Konstanten, Variablen, Operatoren, Funktionsaufrufe und möglicherweise Klammern enthalten. Das von X11-Basic verwendete Ausdrucksformat ist identisch mit dem vieler anderer BASIC-Pakete: Die Operatoren haben einen Rang und werden in der üblichen Reihenfolge (also Punktrechnung vor Strichrechnung) ausgewertet. Sie können die Reihenfolge der Operatorauswertung mit Klammern ändern. Hier ist ein Beispiel für einen numerischen Ausdruck, der nach einer PRINT-Anweisung folgt:

PRINT (x-1)*10+SIN(x)
Bedingungen

und Ausdrücke werden in X11-Basic gleich behandelt. Da X11-BASIC keine separaten booleschen Operatoren für Bedingungen und Ausdrücke hat, operieren die Operatoren (AND, OR, XOR, NOT) tatsächlich mit binären Werten. Daher ist ein TRUE -1, was bedeutet, dass jedes Bit eins ist. Daher werden die Operatoren auf jedem dieser Bits arbeiten. Solch eine Bedingung wird als WAHR betrachtet, wenn der Ausdruck nicht FALSCH ist (bedeutet, dass das Ergebnis ein anderer Wert als Null sein muss). Es reicht also schon, wenn irgendein Bit von null verschieden ist.

4.8.2. Operatoren

X11-Basic stellt Operatoren für numerische Ausdrücke, Zeichenfolgen und Arrays eines beliebigen Typs und einer beliebigen Dimension bereit.

Man unterscheidet zwischen numerischen, Zeichenketten- und Feld- bzw. Matritzenoperatoren, je nachdem, ob das ergebnis der Operation eine Zahl oder eine Zeichenkette ist.

Numerische Operatoren

Die numerischen Operatoen können grob in drei Kategorien gegliedert werden:

  • Arithmetische Operatoren ^ * / +

  • Vergleichsoperatoren = <> < > ⇐ >=

  • Logische Operatoren NOT AND OR XOR …​

X11-Basic wertet die folgenden Operatoren in der Reihenfolge fallender Priorität aus (die Priorität der BASIC-Operatoren beeinflusst die Reihenfolge der Auswertung der einzelnen Teilausdrücke):

Rang

Operator

Beschreibung

1

( )

Klammerausdruck

2

^

Exponent/hoch

3

-

Vorzeichen

3

+

Vorzeichen

4

NOT

Bitweises logisches nicht

5

/

Division

5

*

Multiplikation

5

DIV

Ganzzahldivision

5

MOD

Modulus (Rest bei Division)

6

+

Addition

6

-

Subtraktion

7

<<

Bitweises nach links Schieben (*)

7

>>

Bitweises nach rechts Schieben (*)

8

=

Logisches "gleich"

8

<>

Logisches "ungleich"

8

<

Logisches "kleiner als"

8

>

Logisches "größer als"

8

Logisches "kleiner oder gleich"

8

>=

Logisches "größer oder gleich"

9

AND

Bitweises logisches und

9

NAND

Bitweises logisches nicht und

10

OR

Bitweises logisches oder

10

NOR

Bitweises logisches nicht oder

10

XOR

Bitweises logisches Exklusiv-Oder

10

IMP

Bitweises logisches Impliziert

10

EQV

Bitweises logische Äquivalenz

11

=

Zuweisung

(*) = nicht implementiert

Additions- und Subtraktionsoperatoren

sind sowohl binäre als auch unäre Operatoren. In ihrer unären Form werden sie außerhalb der Rangordnung verwendet. Unäre Operatoren werden immer zuerst angewendet, es sei denn, Klammern erzwingen eine andere Berechnungsreihenfolge.

Der Potenzoperator

`a^b' berechnet die b-te Potenz von a. Die tatsächliche Implementierung des Operators verwendet immer die Funktion "pow()", die alle Operanden als reelle Zahlen behandelt. Unter bestimmten Umständen kann es besser sein, "a*a" anstelle von "a^2" zu verwenden. Das ist schneller und Rundungsfehler werden vermieden.

Der Multiplikationsoperator

multipliziert die Operanden. Wenn einer der Operanden ein Array ist, ist das Ergebnis ein Array.

Der Divisionsoperator

teilt den ersten Operanden durch den zweiten. Wenn der zweite Operand Null ist, gibt es einen Fehler.

Der Ganzzahl-Divisionsoperator

teilt den ersten Operanden durch den zweiten. Zur Berechnung werden die operanden zuerst in ganze Zahlen gewandelt (durch Abschneiden der Nachkommastellen) und das Ergebnis wird ebenfalls durch Abschneiden der Nachkommastellen in eine ganze Zahl verwandelt.

Bitweise und logisch NOT

Dieser unäre Operator berechnet das logische Negieren (das Komplement) des Operanden. Die Berechnung erfolgt mit ganzen Zahlen, der Operand wird also in einen ganzzahligen Wert umgewandelt. Der Operator invertiert dann jedes Bit des Operanden.

Logische Operatoren (AND, OR, XOR)

Diese Operatoren können sowohl für logische als auch für bitweise Operationen verwendet werden. X11-Basic hat keinen separaten Typ für logische Werte. Der logische Wert TRUE wird als ganzzahliger Wert -1 dargestellt (alle Bits sind auf 1 gesetzt) ​​und der logische Wert FALSE ist 0. Die Operatoren AND, OR und XOR führen die Berechnung für ganzzahlige Werte durch. Wenn einer der Operanden keine Ganzzahl ist, wird er vor der Operation in einen Ganzzahlwert konvertiert. Die Operationen werden für jedes Bit der Operanden ausgeführt.

Vergleichsoperatoren

können zwischen zwei Ausdrücken gleichen Typs stehen, also zwischen Zeichenkettenausdrücken, numerischen Ausdrücken oder Feld-Ausdrücken. Abhängig vom Wahrheitswert (wahr oder falsch) wird dem Vergleich entweder der Wert -1 (wahr) oder 0 (falsch) zugeordnet. (Da sich in jedem Fall eine Zahl ergibt, zählt auch der Vergleich von Zeichenketten zu den numerischen Operatoren.)

Zum Vergleich von numerischen Ausdrücken sollen hier nur einige Beispiele aufgeführt werden:

PRINT 3=1.5*2  übergibt den Wert  -1   (wahr)
PRINT 5>5      übergibt den Wert   0   (falsch)
Logische Operatoren: AND OR NAND OR NOT XOR EQV IMP

Mit Hilfe der logischen Operatoren können Ausdrücke oder Beziehungen zwischen Ausdrücken miteinander verbunden werden.

In der Regel werden mit logischen Operatoren Wahrheitswerte verknüpft und als Ergebnis wiederum Wahrheitswerte ausgegeben. Dabei wird jedem numerischen Ausdruck ungleich 0 der Wahrheitswert "wahr" und jedem Ausdruck, dessen Wert gleich 0 ist, der Wahrheitswert "falsch" zugeordnet. Die von den Logischen Operatoren erzeugten Wahrheitswerte ergeben sich aus der Bit-weisen Operation, wenn die Operanden als 32-Bit Integerwerte angesehen werden. Deshalb gehoert zum Wahrheitswert 0 (falsch) der Wahrheitswert -1 (wahr). Hierfür gibt es auch die Systemvariablen TRUE=-1 und FALSE=0. Dies kann man auch in numerischen Ausdrücken verwenden, z.B.: a=ABS(x=0)*100+ABS(x=1)*200. Je nach dem Wert von x erhält die Variable a die Werte 100 oder 200.

AND

Konjunktion Das Ergebnis von AND ist nur dann w, wenn beide Argumente w sind:

  A  |  B  |  A AND B
-----+-----+-----------
  w  |  w  |    w
  w  |  f  |    f
  f  |  w  |    f
  f  |  f  |    f
Beispiele:
Print 3=3 AND 4>2        ergibt  -1 (w)
Print 3>3 AND 5>3        ergibt   0 (f)
OR

Disjunktion Das Ergebnis von OR ist nur dann f, wenn beide Argumente f sind:

  A  |  B  |  A OR B
-----+-----+-----------
  w  |  w  |    w
  w  |  f  |    w
  f  |  w  |    w
  f  |  f  |    f
Beispiele:
Print "A"<"a" OR 3=5     ergibt  -1 (w)
Print 2>7 OR 10=20       ergibt   0 (f)
XOR

Exclusives (oder ausschließendes) Oder Das Ergebnis von XOR ist f, wenn die Argumente gleiche Wahrheitswerte haben:

  A  |  B  |  A XOR B
-----+-----+-----------
  w  |  w  |    f
  w  |  f  |    w
  f  |  w  |    w
  f  |  f  |    f
Beispiele:
Print 3=3 XOR 6=6     ergibt   0 (f)
Print 3>5 XOR 3<5     ergibt  -1 (w)
NOT

Die Negation vertauscht Wahrheitswerte in ihr Gegenteil.

  A  |  NOT A
-----+----------
  w  |   f
  f  |   w
Beispiel:
Print NOT 3=3      ergibt   0 (f)
IMP

Implikation Das Resultat der Operation ist dann falsch, wenn falsch auf wahr folgt.

  A  |  B  |  A IMP B
-----+-----+-----------
  w  |  w  |    w
  w  |  f  |    f
  f  |  w  |    w
  f  |  f  |    w
EQV

Äquivalenz Dier Operation ist identisch mit (A IMP B) AND (B IMP A)

  A  |  B  |  A EQV B
-----+-----+-----------
  w  |  w  |    w
  w  |  f  |    f
  f  |  w  |    f
  f  |  f  |    w

Die logischen Operatoren werden hauptsächlich dazu benutzt, um abhängig vom Wahrheitswert verbundener Ausdrücke verschiedene Programmabläufe zu ermöglichen (z.B. über die Befehle IF, WHILE, EXIT IF …​) Logische Operatoren können aber auch dazu benutzt werden, um Bitfolgen zu verknüpfen.

Zeichenkettenoperatoren

Es gibt ein paar Operationen, die direkt mit Zeichenketten oder String-Variablen durchgeführt werden können.

Plusoperator, Konjunktion

Der Operator '+' für Strings verbindet/verkettet zwei Zeichenketten miteinander. Dabei werden die durch + verbundenen Strings lückenlos aneinandergefügt.

Beispiel:
  a$="X11"
  b$="-"
  c$="BASIC"
  d$=a$+b$+c$

ergibt eine Zeichenkette " X11-BASIC ".

Vergleichsoperatoren, <, , =, ⇒,>, <>

Vergleichsfunktionen gehören zu numerischen (booleschen) Funktionen, da das Ergebnis eine Zahl ist, obwohl sie mit Strings verwendet werden können.

Beispiel:
  IF a$="X11"
    ...
  ENDIF
  Ergebnis=(a$<>"Hallo")
Ausdruck-Auswerte-Operator &

der eval-Operator wertet einen Befehl oder einen Ausdruck aus, der in einer Zeichenkette enthalten ist. Beispiel siehe unten.

Regeln für den Vergleich von Strings

Der Vergleich von Zeichenketten vollzieht sich nach folgenden Regeln:

  1. Zwei Zeichenketten sind gleich, wenn sie vollständig übereinstimmen, also wenn alle Zeichen identisch sind (auch Leerzeichen und Interpunktionszeichen).

Beispiel:
"123 v fdh.-" = "123 v fdh.-"
  1. Bein Größenvergleich zweier Strings wird folgendermaßen verfahren: Die Zeichenketten werden Zeichenweise verglichen, solange, bis der ASCII-Code des Zeichens des einen Strings kleiner ist als der des Zeichens des anderen Strings, oder das Zeichenkettenende eines Strings erreicht wird. Dieser Ist dann kleiner als der andere.

Beispiele:
"X11">"X11"   Ergebnis: 0
"X11"<"x11"   Ergebnis: -1
"123"<"abc"   Ergebnis: -1
"123">"1234"  Ergebnis: 0
Der Evaluierungsoperator &

Der &-Operator, gefolgt von einer Zeichenkette, wertet deren Inhalt als Programmcode aus.

Beispiel
REM generiert zehn mal das Kommando 'print a$'
CLR i
a$="print a$"
label1:
INC i
IF i>10
  b$="label2"
ELSE
  b$="label1"
ENDIF
&a$
GOTO &b$
label2:
END

So zu programmieren kann einen wirklich unlesbaren Code erzeugen.

4.8.3. Zeichenkettenverarbeitung und -funktionen

X11-Basic hat die üblichen Funktionen, um Teile aus einer Zeichenkette zu extrahieren: LEFT$(), MID$() und RIGHT$().

Wenn Sie einen String in Einzelteile aufteilen wollen, sollten Sie den Befehl SPLIT oder die Funktion WORD$() verwenden.

Es gibt eine ganze Reihe weiterer Funktionen zur String-Verarbeitung, wie UPPER$() (konvertiert den String in Großbuchstaben), INSTR() (findet eine Zeichenfolge innerhalb der anderen), CHR$() (konvertiert ein ASCII-Code in ein Zeichen), GLOB() (testet eine Zeichenkette gegen ein Muster) und mehr, z.B. SPACE$, STRING$, STR$, USING$ HASH$ …​

4.8.4. Felder

Arrays sind spezielle Variablen, die aus vielen Werten (des gleichen Typs) bestehen. Es kann Fließkomma-Arrays, Integer-Arrays, String-Arrays und Array-Arrays geben. Der Speicher für ein Array muss deklariert werden, bevor es verwendet werden kann. Dies kann mit dem DIM-Kommando geschehen oder durch direkte Zuweisung eines Wertes an das Array.

4.8.5. Array Konstanten

Eine bequeme Art, alle Daten eines ganzen Arrays auf einmal zuzuweisen, besteht darin, gleich eine ganze Array-Konstante zuzuweisen. Array-Konstanten werden gebildet, indem man eine Liste von Daten in eckige Klammern setzt. Dies bildet so eine Array-Konstante. Dann kan man diese einer Array-Variablen wie folgt zuzuweisen:

a()=[1,2,3;4,5,6]

Ein Komma wird verwendet, um Spaltenelemente zu trennen, und ein Semikolon wird verwendet, um Zeilen zu trennen. So ist [1,2,3] ein Zeilenvektor und `[1;2;3] `ist ein Spaltenvektor.

Jetzt, da Sie wissen, wie man ein einfaches Array definiert, sollten Sie wissen, wie Sie auf seine Elemente zugreifen können. Der Zugriff auf den Inhalt eines Arrays erfolgt über den Operator (), wobei der Index innerhalb der Klammer steht. Die Indexierung des ersten Elements ist 0:

b=a(0)
a(1)=5

Der Zugriff auf ein Element außerhalb der Grenzen führt zu einem Fehler: "Feldindex zu groß."

Um auf ein einzelnes Matrixelement eines zweidimensionalen Arrays zuzugreifen, können Sie den Index (i,j) verwenden, wobei i der Index in der Zeile und j in der Spalte ist:

b=a(1,2)
a(3,4)=3

Es ist auch möglich, auf Blöcke von Matrizen zuzugreifen, indem der Doppelpunkt (:) Operator verwendet wird. Dieser Operator ist wie ein Platzhalter; so teilen Sie X11-Basic mit, dass Sie alle Elemente einer bestimmten Dimension oder alle Indizes zwischen zwei angegebenen Werten haben möchten. Das Ergebnis dieser Operation ist dann nicht ein einzelnen Array-Element, sonder wiederum ein nazes Array (ggf. anderer Dimension), welches Sie einer anderen Array-Variable zuweisen können. Angenommen, Sie möchten auf die gesamte erste Zeile der Matrix a oben, aber nicht auf die zweite Zeile zugreifen. Dann können Sie schreiben:

b()=a(1,:)

Angenommen, Sie möchten nur die ersten zwei Elemente in der ersten Zeile. Verwenden Sie dazu die folgende Syntax:

b()=a(1,1:2)

Es ist auch möglich, Arrays jeder höheren Dimension zu verwenden. Jedoch können Sie hier nicht mehr so einfach Array-Konstanten definieren. Nehmen Sie deshalb DIM und weisen Sie die einzelnen Elemente explizit zu:

DIM a(10,10,10,10,10)
a(1,1,1,1,1)=4
b=a(2,5,4,2,7)

4.8.6. Array Operatoren

Arrays eignen sich nicht nur zum Speichern von Informationen in Tabellen, sondern auch zum Anwenden von Operationen auf Arrays. Sie können zum Beispiel die klassischen arithmetischen Operationen + und - für jedes Array in X11-Basic verwenden: Dies führt zu der Vektoraddition und -subtraktion, wie sie in klassischen Vektorräumen definiert ist, was einfach die Addition und Subtraktion elemtweise ist.

Für Zweidimensionale Arrays ist auch die Matrix-Multiplikation definiert. Für Vektoren können Sie mit dem * Operator ein Kreuzprodulkt berechen (resultiert in eine Matrix) oder ein Skalarprodukt (wenn Sie einen Spaltenvektor mit einem Zeilenvektor multiplozieren). Um Zeilen und Spalten zu vertauschen, wibt es die Funktion TRANS(), wleche auf das ganze Array angewendet wird.

Table 1. Array-Operatoren:

Array Operator

Beschreibung

+

Vector/Matrix Addition Element für Element

-

Vector/Matrix Subtraktion Element für Element

*

Array/Matrix Multiplication

:

Subarray (ein Block)

=,<>

Vergleich Element für Element

<,>,⇐,>=

Vergleich unter Verwendung einer Norm

Array-Funktionen und -Operatoren wirken auf ganze Arrays. Einige geben eine Liste zurück, die dann entweder als Wert für eine andere Array-Funktion oder als Array-Variable verwendet werden kann.

Arrayvergleiche vergleichen den Array-Inhalt elementweise, wobei die Standardvergleichsfunktion für den Elementdatentyp (=,>,<) verwendet wird. In mehrdimensionalen Arrays werden die Elemente in "row major"-Reihenfolge besucht (der letzte Index variiert am schnellsten). Wenn der Inhalt von zwei Arrays gleich ist, aber die Dimensionalität unterschiedlich ist, bestimmt der erste Unterschied in der Dimensionalitätsinformation die Sortierreihenfolge.

4.9. Prozeduren und Funktionen

In X11-Basic gibt es zwei Arten von Unterprogrammen: Prozeduren und Funktionen. Der Hauptunterschied zwischen den beiden besteht darin, dass eine Funktion einen einzelnen Wert zurückgibt und in Ausdrücken verwendet werden kann, während eine Prozedur keinen Wert zurückgibt, und wie ein Kommando aufgerufen wird. Eine Prozedur oder Funktion muss hinter dem Hauptprogrammblock erscheinen. Daher ist die Struktur eines X11-Basic-Programms wie folgt:

Hauptprogrammblock
END      ! oder QUIT
Prozeduren und Funktionen
Prozeduren

sind Codeblöcke, die von einer anderen Stelle in einem Programm aufgerufen werden können. Diese Subroutinen können Argumente übernehmen, aber keine Ergebnisse liefern. Sie können auf alle verfügbaren Variablen zugreifen, können aber auch lokale Variablen haben (→ LOCAL).

Funktionen

sind Blöcke von Code, die von anderswo in einem Ausdruck aufgerufen werden können (z.B. a=3*@myfunction(b)). Variablen sind global, sofern sie nicht als lokal deklariert sind. Für lokale Variablen haben Änderungen außerhalb einer Funktion keine Auswirkungen innerhalb der Funktion, außer wie explizit in der Funktion angegeben. Funktionsargumente können Variablen und Arrays beliebiger Datentypen sein. Funktionen können Variablen eines beliebigen Datentyps zurückgeben. Standardmäßig werden Argumente "nach Wert" übergeben.

4.9.1. Prozeduren

Eine Prozedur beginnt mit dem Schlüsselwort PROCEDURE gefolgt von dem Prozedurnamen und den Parametern, die an die Prozedur übergeben werden. Alle Prozeduren müssen mit dem Schlüsselwort RETURN enden. Prozeduren verwenden das folgende Format:

PROCEDURE ProcName(parameters)
  LOCAL vars
  procedure logic
RETURN

Die Parameter der Subroutine sind in Klammern hinter dem Unterprogrammnamen angeordnet und müssen in derselben Reihenfolge wie beim Prozeduraufruf vom Hauptprogramm aus sein. Alle innerhalb der Subroutine verwendeten Variablen sollten mit der Anweisung LOCAL als lokal deklariert werden. Der Rest der Prozedur bestimmt die Aufgabe, die das Unterprogramm ausführen muss.

Eine Prozedur kann auf zwei Arten aufgerufen werden: mit dem Schlüsselwort GOSUB oder @. Zum Beispiel kann die Prozedur progress (), die einen Fortschrittsbalken auf der Textkonsole mit der Gesamtmenge 'a' und dem Bruchteil 'b' anzeigt, so aufgerufen werden:

GOSUB progress(100,i)
@progress(100,i)

PROCEDURE progress(a,b)
  LOCAL t$
  IF verbose
    PRINT CHR$(13);"[";STRING$(b/a*32,"-");">";
    PRINT STRING$((1.03-b/a)*32,"-");"| ";
    PRINT STR$(INT(b/a*100),3,3);"% ]";
    FLUSH
  ENDIF
RETURN

4.9.2. Funktionen

Eine Funktion beginnt mit dem Schlüsselwort FUNCTION gefolgt von einem Funktionsnamen und endet mit dem Schlüsselwort 'ENDFUNCTION`. Die Funktion ist entweder eine numerische oder eine Zeichenkettenfunktion. Eine numerische Funktion verwendet standardmäßig den Gleitkommadatentyp und benötigt kein Postfix. Eine String-Funktion gibt einen String zurück und der Funktionsname endet mit einem $. Eine Funktion muss mindestens eine 'RETURN'-Anweisung enthalten, um den Funktionswert zurückzugeben. Funktionen verwenden dieses Format:

FUNCTION FuncName[$](parameters)
  LOCAL vars
  function logic
  RETURN value[$]
ENDFUNCTION

Der Typ des Rückgabewerts muss mit dem Funktionstyp übereinstimmen. Eine String-Funktion muss eine Zeichenfolge und eine numerische Funktion einen numerischen Wert zurückgeben. Die Funktion kehrt zum Aufrufer zurück, wenn die Anweisung RETURN ausgeführt wird. Die 'ENDFUNCTION'-Anweisung zeigt nur das Ende der Funktionsdeklaration an und verursacht ein Fehler, wenn das Programm versucht, diese Anweisung auszuführen.

Eine Funktion wird aufgerufen, indem der Funktionsname mit @ vorangestellt wird. Als Beispiel wird die String-Funktion Copy$() wie folgt aufgerufen:

Right$=@Copy$("X11-Basic",4)

wobei die Funktion Copy$() wie folgt definiert werden kann:

FUNCTION Copy$(a$,p)
  LOCAL b$
  b$=MID$(a$,p)
  RETURN b$
ENDFUNC

Natürlich können SIe die Funktion stattdessen auch so definieren;

FUNCTION Copy$(a$,p)
  RETURN MID$(a$,p)
ENDFUNC

Eine Alternative für "FUNCTION" ist die "DEFFN"-Anweisung, die eine Ein-Zeilen-Funktion definiert. Die im obigen Beispiel verwendete Funktion Copy$() könnte auch in einer 'DEFFN`-Anweisung verwendet werden:

DEFFN Copy$(a$,p)=MID$(a$,p)

Im Gegensatz zu Prozeduren und Funktionen können DEFFN-Funktionen in einer Prozedur oder einem Funktionskörper platziert werden, obwohl sie nicht die lokalen Variablen der Subroutine verwenden. Es gibt einen weiteren Unterschied zwischen DEFFN und FUNCTION: Der Compiler verwendet den 'DEFFN`-Ausdruck als Inline-Ausdruck und erzeugt keine Funktion mit einem Symbolnamen. Dies ist dann ein bisschen schneller, aber produziert mehr Code.

4.9.3. Parameter und lokale Variablen

Jeder X11-Basic-Variablentyp kann an eine Prozedur oder Funktion übergeben werden. Standardmäßig werden alle Parameter "'nach Wert", "by value"' übergeben. Natürlich können Parameter auch "nach Verweis, 'by reference"' übergeben werden. Verwenden Sie die dafür die Anweisung VAR.

Das Schlüsselwort VAR steht vor der Liste der Variablen, die als Aufruf von Referenzparametern übergeben werden. Diese Variablen sollten immer am Ende der Parameterliste in der Prozedur- oder Funktionsüberschrift aufgeführt sein. Der Unterschied zwischen den beiden ist, dass ein call by value-Parameter eine Kopie des übergebenen Wertes erhält und ein Aufruf per Referenz nicht. Eine Variable VAR verweist auf die gleiche Variable, die an die Unterroutine übergeben wird. Die ursprüngliche Variable ändert sich, wenn eine Unterroutine die entsprechende VAR-Variable ändert. Tatsächlich verweisen beide Variablennamen auf dasselbe Speicherelement, das den Variablenwert enthält.

Intern verwaltet X11-Basic eine Liste aller Variablen. Jeder Eintrag in der Liste zeigt auf einen Speicherort, der den Variablenwert enthält. Ein Aufruf durch Referenzvariable zeigt auf den gleichen Ort wie die übergebene Variable. Daher können Konstanten oder Ausdrücke nicht an eine VAR-Variable übergeben werden.

Note

Obwohl ein Array an eine Subroutine als Wert übergeben werden kann, können die Funktionen keine Arrays zurückgeben.

Tip

Wenn eine Funktion Informationen in Form eines Arrays zurückgeben muss, sollte das Rückgabearray als VAR-Parameter in der Parameterliste übergeben werden. Die Rückgabewerte können dann innerhalb der Funktion zugewiesen werden.

Das folgende Beispiel zeigt eine einfache Funktion, die einen Namen in einem gegebenen String-Array sucht:

idx%=@SearchName("Jack",Name$())

FUNCTION SearchName(n$,VAR n$())
  LOCAL idx
  CLR idx
  WHILE idx<DIM?(n$()) AND n$(idx)<>n$
    INC idx
  WEND
  RETURN idx
ENDFUNC

Das lokal verwendete Array n$() verweist auf das globale Array Name$(). Das Array n$() ist nur innerhalb der Prozedur gültig, wo es auf den Deskriptor des Arrays Name$() verweist.

Sie könnten die Funktion auch wie folgt deklarieren:

FUNCTION SearchName(n$,n$())

Dann würde eine lokale Kopie des gesamten Arrays Name$() innerhalb der Funktion verwendet, alle Änderungen an n$() hätten keine Auswirkungen auf das ursprüngliche Array Name$(). Aber falls Sie doch Änderungen am Array vornehmen möchten, wie im folgenden Beispiel:

idx%=@EliminateName("Jack",Name$())

FUNCTION EliminateName(n$,VAR n$())
  LOCAL i
  FOR i=0 TO DIM?(n$())
    IF n$=n$(i)
      n$(i)="deleted."
    ENDIF
  NEXT i
  RETURN i
ENDFUNC

Dann müssen Sie VAR verwenden.

Die LOCAL-Anweisung listet die Variablen auf, die nur innerhalb der Prozedur oder Funktion bekannt sind. Unterprogrammparameter sind ebenfalls lokale Variablen. Wenn eine Subroutine eine andere Subroutine aufruft, sind die lokalen Variablen der aufrufenden Routine in der aufgerufenen Routine bekann, als ob sie globale Variablen wären.

Mehrere lokale Variablen, die durch Kommata getrennt sind, können nach der Anweisung LOCAL aufgelistet werden. Mehrere LOCAL Zeilen sind erlaubt.

5. Einfache Ein- und Ausgabe

In X11-Basic gibt es viele Möglichkeiten, Daten vom Benutzer zu übernehmen und andere Daten anzuzeigen. Dies kann über die Tastatur, durch die Maus, von einem Mikrofon usw. geschehen. Daten können auf der Textkonsole, im Grafikfenster, über den Lautsprecher usw. erfolgen. Außerdem kann ein X11-Basic Programm in Dateien schreiben und daraus lesen, und Internet-, Bluetooth- oder USB-Verbindungen herstellen.

Die einfachste Ein- und Ausgabe von und zum Benutzer erfolgt über die Textkonsole, die sogenannte Standardeingabe und Standardausgabe. Dies geschieht in X11-Basic wie in allen BASIC-Dialekten mit den Grundbefehlen PRINT und INPUT.

5.1. Daten auf die Konsole ausgeben

Sie kennen tatsächlich bereits einen X11-Basic-Befehl, um Daten auf den Bildschirm zu schreiben. Dieser Befehl ist PRINT. Es ist sehr vielseitig und Sie können ihn auf verschiedene Arten erweitern.

Die Syntax von PRINT ist einfach:

PRINT <data>

wobei <data> darauf ankommt, welche Art von Daten Sie auf dem Bildschirm drucken möchten. Das können Variablen, Zahlen, das Ergebnis einer Berechnung, ein String oder eine Mischung aus allen sein. Sie können Ihrer PRINT-Anweisung sogar spezielle Befehle und Funktionen zur Bildschirmsteuerung hinzufügen, wie z. B. die Cursorpositionierung und Formatierung der Daten. Einige Beispiele für den Befehl 'PRINT' finden Sie hier:

PRINT 10+5
PRINT x%
PRINT 10;20;30
PRINT 10,20,30
PRINT "Hallo!"
PRINT 10.123 USING "+##.###"
PRINT "y= ";y
PRINT "x=";x;" y=";y;" z=";z
PRINT "Ihr Name ist ";nam$
PRINT AT(5,5);"AT() is one of my favorites"
PRINT CHR$(27);"[2J This is a cleared console..."

Dies sind die einfachsten Varianten des Befehls 'PRINT'. Sie können natürlich komplizierter sein, und alle Merkmale können kombiniert werden.

Nun, warum schreiben wir PRINT "y =";y anstelle von PRINT "y =",y? Wenn Sie ; verwenden, werden die folgenden Daten direkt hinter Ihrem Text hinzugefügt, ohne die Cursorposition zu verändern, während , den Cursor zur nächsten vertikalen Tabellenposition bringt. Sie können damit Ihre Daten in Tabellen auf dem Bildschirm ausrichten. Kurz gesagt, wenn Sie Daten direkt hinter eine Art Eingabeaufforderung oder hinter einen Text schreiben möchten, verwenden Sie die Notation ;. Setzen Sie als letztes Zeichen Ihrer PRINT-Anweisung ein ;, damit der Cursor auf der aktuellen Zeile bleibt. Sie können dies verwenden, um zu verhindern, dass in der letzten Bildschirmzeile gescrollt wird, oder wenn Sie das Schreiben von Prompts und Daten einfach in zwei Codezeilen aufteilen möchten. Technisch gesehen wird das Zeichen ; als letzte Anweisung einen Wagenrücklauf unterdrücken.

5.2. Bildschirmausgabekontrolle

Jetzt, wo Sie wissen, wie Sie Ihre Daten auf dem Bildschirm schreiben, möchten Sie auch wissen, wie Sie die Bildschirmausgabe im Detail handhaben. Wie kann ich eine Textzeile leer lassen? Schreiben Sie einfach PRINT ohne irgendwelche Daten hinterher, um eine leere Zeile auf dem Bildschirm auszugeben. Probieren Sie dieses 3-Zeilen-Programm aus:

PRINT "Hallo!"
PRINT
PRINT "Das ist das erste Beispiel für Bildschirmkontrolle!"

Wie Sie sehen, wird die Begrüßung und die andere Zeile mit einer leeren Zeile dazwischen gedruckt.

Eine sehr wichtige Sache ist, wie man den Bildschirm löscht. So werden die Reste der vorhergehenden Textausgabe gelöscht. Sie löschen den Bildschirm einfach mit dem folgenden Befehl.

CLS

Eine nette Sache ist es, auf dem Bildschirm an genau ader Position zu schreiben, wo man den Text hin platzieren möchte, und nicht dahin, wo PRINT ihn selbst im Fluss der Ausgaben schreiben würde. Sie können dafür die Anweisung AT() verwenden. Dieser spezielle Zusatz für PRINT ermöglicht es Ihnen, den Cursor frei auf dem Bildschirm zu positionieren, damit Sie Ihre Daten an die gewünschte Stelle schreiben können. Lassen Sie uns das folgende Beispielprogramm ausprobieren:

CLS
PRINT AT(1,1);"Oben links"
PRINT AT(5,13);"Middle line, text indented 5 chars"
PRINT AT(20,25);"bottom line";

Die Syntax für PRINT AT () ist PRINT AT (Spalte, Zeile);, wobei Zeile 1 oben auf dem Bildschirm und Spalte 1 am linken Ende steht. Spalte und Zeile können Variablen, Ausdrücke oder einfach einfache Zahlen sein. Gültige PRINT AT () Befehle sind:

PRINT AT(1,5);"Hallo"
PRINT AT(5+x%,10);"x"
PRINT AT(4+8,y%);"y = "

Wie viele Zeichenpositionen Sie haben, hängt von der aktuellen Bildschirmgröße der Textkonsole ab. Sie haben fast immer mindestens 24 Textzeilen. 80 Spalten sind Standard. Wenn Sie die Anzahl der Zeilen und Spalten des Textfensters genau kennen möchten, können Sie die (System-) Variablen ROWS und` COLS` verwenden.

> PRINT ROWS,COLS
24      80

Es gibt weitere Zusatz-Befehle, die Sie mit PRINT verwenden können. Z.B. SPC() und TAB(). Bitte schlagen Sie diese in der Befehlsreferenz am Ende dieses Handbuch nach, wenn Sie mehr darüber wissen möchten.

5.3. Die Ausgabe mit PRINT USING formatieren

X11-BASIC gibt normalerweise Zahlen in einer Form aus, die für die meisten Zwecke geeignet ist. Aber gelegentlich bevorzugen Sie vielleicht eine ausführlichere Form. Sie möchten z.B. Finanzdaten, Geldmengen oder Buchungen mit zwei Dezimalstellen (für Cent) korrekt formatier ausgeben lassen. Oder Sie möchten die Zahlen in wissenschaftlicher Notation ausdrucken. PRINT USING bietet Möglichkeiten, Zahlen in dieser und fast jeder anderen Form darzustellen.

Note

Es gibt auch andere integrierte Befehle zum Formatieren von Ausgabedaten. X11-Basis bietet hier z.B. noch STR$(). Einzelheiten zur Syntax von STR\$() finden Sie in den Abschnitten zu String-Funktionen.

Die allgemeine Syntax ist:

PRINT <expression> USING "<format string>"

Das Ergebnis des Ausdrucks sollte eine Zahl sein. Die Formatzeichenfolge definiert, wie Ihre Daten auf dem Bildschirm formatiert werden sollen. Die Formatzeichenfolge kann eine Stringvariable, eine Zeichenfolge in Anführungszeichen oder ein allgemeinerer Zeichenkettenausdruck sein.

Mit 'PRINT USING' können Sie auch Zeichenfolgen formatieren. In diesem Fall beschränken sich die Möglichkeiten jedoch auf das Ausgeben der Zeichenfolge zentriert, rechtsbündig oderlinksbündig innerhalb des Formatfeldes.

Die Funktion USING$() macht fast exakt dasselkbe wie PRINT USING, Es können jedoch nur Zahlen formatiert werden, keine Strings. Das Ergebnis wird als String zurückgegeben, anstatt es auf dem Bildschirm auszugeben.

Im Gegensatz zu STR$(), wo Sie die Länge des Strings, die Anzahl der signifikanten Stellen der Zahl und ein Flag angeben können, ob führende Nullen verwendet werden sollen, verwenden Sie USING $() und PRINT USING, um eine klassische Formatierzeichenfolge im BASIC-Stil zum Formatieren von Zahlen zu verwenden.

5.3.1. Zahlen formatieren

Die Formatzeichenfolge kann beliebige Buchstaben enthalten, aber einige haben eine besondere Bedeutung. Alle anderen Zeichen werden einfach so übernommen, wie sie sind. Die Länge der Format-Zeichenfolge definiert die Länge des Ausgabefeldes. Was immer formatiert wird, es nimmt genau so viel Platz ein, wie die Zeichen in der Formatzeichenfolge.

Das wichtigste Sonderzeichen in der Formatzeichenfolge ist das Symbol #, das für eine Ziffernstelle steht, die mit einer Ziffer von der zu formatierenden Zahl gefüllt wird. Vergleichen Sie zum Beispiel die Ausgabe, die sich aus zwei ähnlichen PRINT-Anweisungen ergibt: Die erste ist eine normale PRINT-Anweisung, und die zweite verwendet die USING Funktion.

 x=   |PRINT x| PRINT x USING "###"
 -----+-------+--------------------
 1    | 1     |   1
 12   | 12    |  12
 123  | 123   | 123
 1234 | 1234  | ***
 -12  | -12   | -12

Ohne USING wird die Zahl linksbündig gedruckt und belegt nur so viel Platz wie nötig. Mit USING gibt die Formatzeichenfolge "###" eine Feldlänge von genau drei Zeichen vor. In diesem Feld wird die Zahl dann rechtsbündig dargestellt. Wenn das Feld nicht lang genug ist, um die Zahl richtig darzustellen, werden stattdessen Sternchen gedruckt. Wenn Sie lediglich ganzzahlige Zahlen in einer Spalte drucken müssen, aber mit Rechtausrichtung, dann reicht das vorhergehende Beispiel aus. Beachten Sie, dass eine negative Zahl mit dem Vorzeichen gedruckt wird, das eines der Ziffernfelder belegt.

Beim Ausgeben von Finanzbuchungen ist es üblich, dass die Dezimalpunkte ausgerichtet sind. Sie können auch zwei Dezimalstellen (für die Cents) drucken, auch wenn sie Null sind. Das folgende Beispiel zeigt, wie das gemacht wird. (Um negative Zahlen zu drucken und das Zeichen an einer festen Position zu haben, sollte die Formatzeichenfolge mit einem Minuszeichen beginnen.)

 x=    |PRINT x USING "-##.##"
 ------+-----------------------
 1     |  1.00
 1.9   |  1.90
 -3.14 |- 3.14
 1.238 |  1.24
 123   |******
 0     |  0.00
 -123  |******

Beachten Sie, dass in diesem Beispiel immer zwei Dezimalziffern gedruckt werden, selbst wenn sie aus Nullen bestehen. Außerdem wird das Ergebnis zunächst auf zwei Dezimalstellen gerundet. Wenn die Zahl negativ ist, nimmt das Minuszeichen die Position der führenden Stelle oder die Position ein, die in der Formatzeichenkette durch ein - oder + angegeben wird. Wenn die Zahl zu lang ist, um richtig gedruckt zu werden (möglicherweise wegen eines Minuszeichens), werden stattdessen Sternchen gedruckt.

Finanzielle Mengen werden oft mit einem führenden Dollarzeichen ($) und mit Kommas, die dreistellige Gruppen links vom Komma bilden, gedruckt. Das folgende Beispiel zeigt, wie man dies mit PRINT USING macht.

 x=         |PRINT x USING "$#,###,###.##"
 -----------+------------------------------
 0          |$        0.00
 1          |$        1.00
 1234       |$    1,234.00
 1234567.89 |$1,234,567.89
 1e6        |$1,000,000.00
 1e7        |10,000,000.00
 1e8        |*************

Das Dollarzeichen wird nur gedruckt, wenn der Platz für eine Ziffer nicht benötigt wird. Es ist immer in der gleichen Position (zuerst) im Feld. Die Trennkommas werden nur bei Bedarf gedruckt.

Wenn Sie möchten, dass das Dollarzeichen ($) nach rechts schwebt, sodass es neben der Zahl erscheint, und alle Leerzeichen zwischen dem Dollarzeichen und der ersten Ziffer verschwinden, so machen Sie es wie in folgenden Beispiel:

 x=         |PRINT x USING "$$,$$$,$$#.##"
 -----------+----------------------------
 0          |        $0.00
 1          |        $1.00
 1234       |    $1,234.00
 1234567.89 |$1,234,567.89

Die Formatzeichenfolge kann auch die Ausgabe von führenden Nullen ermöglichen oder anstelle der Nullen Sternchen (*) setzen.

x=         |PRINT x USING "$0,000,000.##"
-----------+------------------------------
0          |$0,000,000.00
1          |$0,000,001.00
1234       |$0,001,234.00
1234567.89 |$1,234,567.89

x=         |PRINT x USING "$*,***,***.##"
-----------+------------------------------
0          |$********0.00
1          |$********1.00
1234       |$****1,234.00
1234567.89 |$1,234,567.89

x=         |PRINT x USING "*$$,$$$,$$#.##"
-----------+------------------------------
0          |*********$0.00
1          |*********$1.00
1234       |*****$1,234.00
1234567.89 |*$1,234,567.89

Aus Kompatibilitätsgründen kann ein % anstelle der Nullen in der Formatzeichenfolge verwendet werden, mit einer Ausnahme: Das erste Zeichen in der Formatzeichenfolge darf kein % sein.

Note

Wenn das erste Zeichen ein % ist, wird die Formatzeichenfolge als C-Stil-Printf-Formatzeichenfolge interpretiert (siehe unten).

Sie können Zahlen auch mit wissenschaftlicher Notation formatieren. Da die wissenschaftliche Notation aus zwei Teilen besteht, dem Dezimalteil und dem Exponententeil, muss die Formatzeichenfolge auch zwei Teile haben. Der Dezimalteil folgt den bereits dargestellten Regeln. Der Exponent-Teil besteht aus drei bis fünf Carets (^), die unmittelbar dem Dezimalteil folgen sollten. Das folgende Beispiel zeigt, wie.

x=          |PRINT x USING "+#.#####^^^^"
------------+-----------------------------
0           |+0.00000e+00
123.456     |+1.23456e+02
-.001324379 |-1.32438e-03
7e30        |+7.00000e+30
0.5e100     |+5.00000e+99
5e100       |************

Das vorangestellte Pluszeichen (+) im Formatstring garantiert, dass das Vorzeichen der Zahl gedruckt wird, auch wenn die Zahl positiv ist. Beachten Sie, dass die letzte Zahl nicht formatiert werden kann, da der Exponententeil 100 wäre, was ein Exponentenfeld mit fünf Carets erfordert. Beachten Sie auch, dass führende Nullen eingefügt werden, wenn mehr als die für den Exponenten erforderlichen Einträge vorhanden sind. Beachten Sie schließlich, dass nachgestellte Nullen im Dezimalteil gedruckt werden.

Zusätzlich zu den oben beschriebenen Formatregeln bietet X11-Basic eine andere, alternative Formatzeichenfolge. Wenn das erste Zeichen der Formatzeichenfolge ein % ist, wird die Formatzeichenfolge als C-Stil behandelt, das sogenannte printf-Formatierungsprogramm.

Hier sind einige Beispiele:

x=          |format$=     |PRINT x USING format$
------------+------------------------------------
0           | "%012g"     |000000000000
123.456     | "%.1g"      |1e+02
-.001624    | "%.1g"      |-0.002

Diese Formatierungszeichenfolgen folgen einem Standard, der normalerweise nicht in BASIC verwendet wird (sondern in C). Der Standard ist in Wikipedia gut erklärt: http://en.wikipedia.org/wiki/Printf_format_string#Format_placeholders

5.3.2. Zeichenketten formatieren

Strings können auch mit PRINT USING formatiert werden, jedoch nicht mit der Funktion USING$(), obwohl es weniger Optionen für Strings als für Zahlen gibt. Zeichenfolgen können im formatierten Feld entweder linksbündig, zentriert oder rechtsbündig gedruckt werden. Wie bei Zahlen, wenn die Zeichenfolge zu lang ist, um zu passen, werden Sternchen gedruckt.

Diese Beispiele sollten klarstellen:

PRINT "|";"OK" USING "#####";"|"     ! result: | OK  |
PRINT "|";"OK" USING ">####";"|"     ! result: |   OK|
PRINT "|";"Hello" USING ">####";"|"  ! result: |Hello|
PRINT "|";"Goodby" USING ">####";"|" ! result: |*****|

Wenn die Zentrierung nicht exakt sein kann, wird der zusätzliche Platz rechts platziert.

Eigentlich kann jeder String als Formatzeichenfolge verwendet werden. Nur die Länge des Strings ist entscheidend und definiert die Länge des Ausgabefeldes. Nur das erste Zeichen des Formatstrings ist wichtig. Wenn es ein < ist, wird die Zeichenfolge linksbündig, wenn es ein > ist, wird es rechtsbündig und in jedem anderen Fall zentriert ausgegeben. Dies ist besonders beim Drucken von Kopfzeilen für eine numerische Tabelle hilfreich. Das folgende Beispiel zeigt, wie Sie eine Kopfzeile mit der gleichen Formatzeichenfolge formatieren können, die wir zuvor für Zahlen verwendet haben.

 s$=                    |PRINT s$ USING "$#,###,###.##"
 -----------------------+-------------------------------
 "Cash"                 |                    Cash
 "Liabilities"          |                 Liabilities
 "Debitorenbuchhaltung" |                *************

5.4. Benutzereingaben

Sie können Ihr Programm interaktiv gestalten, und den Benutzer auffordern, Daten zur Laufzeit Ihres Programms einzugeben.

Mit dem Befehl INPUT kann der Benutzer mit der Tastatur auf der Textkonsole eine Datenzeile eingeben. Die Daten werden interpretiert und in einer oder mehreren Variablen gespeichert, die durch die Anweisung INPUT angegeben werden. Wenn Sie eine Zeichenfolgenvariable angeben, können Sie Text eingeben, während Sie numerische Daten nur eingeben können, wenn Sie eine numerische Variable verwenden. Ein Minuszeichen und ein optionaler Dezimalpunkt sind für numerische Eingaben zulässig. Zahlen können auch in wissenschaftlicher Schreibweise eingegeben werden. Hexadezimale Werte sind ebenfalls möglich.

INPUT "x= ",x
INPUT "Wie lautet Ihr Name? ",your_name$

Dies fordert den Benutzer auf, einen Wert für x einzugeben, der in einer (Gleitkomma-) Variable x gespeichert wird. Sie können diese Variable dann wie gewohnt in Ihrem Programm verwenden und damit rechnen. Bitte beachten Sie, dass Ihr Programm stoppt, bis die RETURN-Taste oder die ENTER-Taste gedrückt wurde, um die Eingabe zu beenden.

Sie können mehr als eine Variable mit einer INPUT-Anweisung lesen. Listen Sie einfach Ihre Variablen auf (mit Kommas getrennt), an die die Eingabe gehen soll.

PRINT "enter 3 values, separated with commas (eq 3,4,5):"
INPUT x%,y%,z%

Der Benutzer muss dann an den entsprechenden Stellen Kommas eingeben, um zu bestimmen, welcher Datenwert zu welcher Variablen geht. Im obigen Beispiel würde der Benutzer mit 5,6,7 antworten.

CLS
INPUT "Geben Sie eine Zahl für x ein:",x
PRINT "x = ";x
INPUT "Wie lautet Ihr Name?",your_name$
PRINT "Ihr Name ist ";your_name$;"."
PRINT "Tschüss, ";your_name$;"!"

Bei der Eingabe von Strings ist Ihnen vielleicht schon aufgefallen, dass X11-Basic die Eingabe eines Kommas als Trennzeichen behandelt, wodurch die Zeichenkette effektiv abgeschnitten wird.

Tip

Verwenden Sie den Befehl LINEINPUT anstelle von INPUT, um ganze Zeilen (mit Kommas) in Strings zu lesen.

LINEINPUT txt$

Sie können jetzt Zeichenfolgen mit einem Komma eingeben und sie werden auch in der Stringvariablen gespeichert. Sie können auch mehrere Zeichenfolgen mit LINEINPUT lesen, aber der Benutzer muss die RETURN-Taste drücken, um jede Zeichenfolge, die eingegeben werden soll, zu beenden.

5.5. Ablaufkontrolle

In diesem Kapitel wollen wir Ihre Programme schließlich dazu bringen, Dinge mehr als einmal zu tun, ohne dass Sie Ihren Code erneut eingeben müssen. Das Erstellen von sogenannten Schleifen ist wesentlich, um komplexe Programme zum Laufen zu bekommen. Das Konzept von Schleifen und einfachen Zählschleifen soll hier vorgestellt werden.

Bevor Sie weiter gehen, lassen Sie mich die grundlegende Idee der Schleifen erläutern. Die Idee ist, dass Ihr Programm für eine bestimmte Zeit einen Codeabschnitt wiederholt. Sie können X11-Basic eine Variable für sich zählen lassen und Sie können dann den Wert dieser Variablen in einer laufenden Berechnung verwenden. Oder Sie können X11-Basic einen bestimmten Teil des Codes durchlaufen lassen, bis eine spezielle Bedingung erfüllt ist. Sehen Sie sich das folgende Beispielprogramm an:

FOR i%=1 TO 5
  PRINT i%
NEXT i%

Dieses kleine Beispielprogramm läuft 5 mal über die Anweisung PRINT i% und zählt die Variable i% von 1 bis 5 und gibt den aktuellen Wert auf dem Bildschirm aus. Diese Art von Schleife wird FOR-NEXT-Schleife genannt. Sie können eine beliebige numerische Variable zum Zählen verwenden. Meistens wird diese Art von Schleife verwendet, um Dinge eine bestimmte Zeit lang auszuführen oder um über eine Liste zu iterieren. Die Schleife wiederholt den Code zwischen dem FOR und dem zugehörigen NEXT. Jedes Mal, wenn X11-Basic das NEXT erreicht, inkrementiert es die Zählvariable und stoppt die Schleife, sobald die maximale Anzahl, bzw. der bei FOR angegebene Maximalwert erreicht wird.

Sie können natürlich noch eine andere Schleife innerhalb der aktuellen haben. Stellen Sie sicher, dass Sie nicht dieselbe Variable zum Zählen verwenden, sonst gibt es Durcheinander:

FOR i%=1 TO 5
  FOR j%=1 TO 10
    PRINT i%;" * ";j%;" = ";i%*j%
  NEXT j%
NEXT i%

Dieses Beispielprogramm hat eine FOR-NEXT-Schleife innerhalb einer anderen und berechnet das Produkt der beiden Zählervariablen, wodurch eine Art Multiplikationstabelle erzeugt wird.

Hier einige Regeln und Ratschläge, die man bei FOR-NEXT-Loops beachten sollte:

  1. Beenden Sie immer ein geöffnetes FOR mit einem entsprechenden` NEXT`.

  2. Schließen Sie FOR-Schleifen immer in der richtigen Reihenfolge ab. Wenn Sie FOR i% = …​ zuerst und FOR j% = …​ danach schreiben, achten Sie darauf, die innere Schleife zuerst zu beenden.

  3. Sie können abwärts mit dem Wort DOWNTO anstelle von TO zählen. Versuchen Sie:

      FOR i%=5 DOWNTO 1
  4. Mit dem Schlüsselwort STEP können Sie in Schritten ungleich 1 zählen:

      FOR i%=1 TO 10 STEP 2

    Das wird i% in Schritten von 2 erhöhen, bis es 10 erreicht.

  5. Sie können die FOR-NEXT-Schleife mit der Anweisung EXIT IF beenden.

5.5.1. Bedingungen und bedingte Verzweigung

Eine sehr grundlegende Idee beim Programmieren ist das Erstellen und Verwenden von Bedingungen. Dadurch können Sie unter bestimmten Bedingungen Entscheidungen treffen und Ihr Programm ein alternatives Codesegment durchlaufen lassen.

Stellen Sie sich vor, Sie zählen eine spezielle Variable und möchten etwas anderes tun, wenn der Wert Ihres Zählers 5 ist:

FOR i%=1 to 10
  IF i%=5
    PRINT "i% ist jetzt 5"
  ELSE
    PRINT "i% ist nicht 5"
  ENDIF
NEXT i%

Dieses Programm wird 10 mal durchlaufen und zählt in der Variablen i%. Für jede Iteration der Schleife wird überprüft, ob i% in der IF-Zeile 5 ist. Wenn diese Bedingung erfüllt ist, ist i% 5, dann führt der Interpreter den Programmzweig bis zum ELSE aus und lässt den folgenden Teil weg. Wenn die Bedingung nicht zutrifft, führt X11-Basic nur den Teil hinter dem ELSE aus. Stellen Sie sicher, dass jede IF-Bedingung mit einem ENDIF beendet wird, sonst wird sich X11-Basic verlaufen und eine Fehlermeldung erzeugen.

Sie können den Teil mit dem ELSE auch weglassen. X11-Basic wird dann nichts tun, wenn die Bedingung nicht zutrifft.

5.5.2. Bedingte und Endlose Schleifen

Manchmal wissen Sie nicht, wie weit Sie für eine spezielle Operation zählen müssen. Oder Sie wollen die Schleife solange laufen lassen, bis eine bestimmte Bedingung erfüllt ist. Oder nur so lange wie eine Bedingung erfüllt ist. Auch hierfür gibt es spezielle Schleifentypen:

Die erste neue Schleife wird solange durchlaufen, bis eine Bedingung erfüllt ist:

REPEAT
...
UNTIL <condition>

Dies ist eine sogenannte REPEAT-UNTIL-Schleife. Sie wird mindestens einmal durchlaufen und erst nach der Ausführung des Schleifeninhalts wird X11-Basic die Bedingung überprüfen. Nur solange die Bedingung falsch ist, wird die Schleife wiederholt. Verwenden Sie diesen Schleifentyp für Dinge, die mindestens einmal durchgeführt werden müssen. Sie können auch eine FOR-NEXT-Schleife damit emulieren, wenn Sie kniffliger zählen wollen:

i%=1
REPEAT
  PRINT "i%=";i%
  i%=i%+1
UNTIL i%>5

Manchmal ist es nötig, eine Bedingung zu prüfen, bevor man in die Schleife eintritt. Z.B. wenn Sie nur dann eine Schleife ausführen möchten, wenn eine bestimmte Bedingung bereits erfüllt ist. Hierfür nehmen Sie am Besten die folgende Konstruktion:

WHILE <condition>
...
WEND

Dies ist die sogenannte WHILE-WEND-Schleife. Hier wird die die Bedingung bereits am Schleifenanfang überprüft, und der Schleifenkörper wird gar nicht erst ausgeführt, wenn die Bedingung nicht erfüllt (wahr) ist.

Manchmal möchten Sie endlos Schleifen. X11-Basic hat zu diesem Zweck ein spezielles Schleifenkonstrukt, obwohl Sie endlose Schleifen mit den oben genannten Typen leicht erstellen können, wenn Sie eine Bedingung verwenden, die niemals wahr wird. Die nie endende Schleife wird als DO-Schleife bezeichnet. Die 3 Schleifen im Beispiel sind alle gleich in der Funktionalität und werden endlos wiederholt.

DO
  PRINT "endlos"
LOOP

i%=0
REPEAT
  PRINT "endlos"
UNTIL i%=1

i%=0
WHILE i%=0
  PRINT "endlos"
WEND

An dieser Stelle sollten Sie wissen, dass Sie Ihr X11-Basic-Programm jederzeit beenden bzw. abbrechen können. Dies ist nötig, wenn Ihr Programm in einer Endlosschleife stecken bleibt, die nicht beabsichtigt war. Drücken Sie CONTROL-c und X11-Basic stoppt das Programm. Ein erneutes CONTROL-c beendet den Interpreter.

Manchmal möchten Sie eine laufende Schleife an einem anderen Punkt als dem offiziellen Schleifenanfang oder Schleifenende verlassen. Verwenden Sie die Anweisung EXIT IF in Ihrer Schleife für zusätzliche Bedingungen. Dies beendet auch FOR-NEXT-Schleifen, wenn Sie möchten, und es ist die einzige Möglichkeit, eine DO-LOOP-Schleife zu verlassen.

i%=1
DO
  PRINT "i%=";i%
  EXIT IF i%=5
  i%=i%+1
LOOP

Bitte beachten Sie, dass die Anweisung EXIT IF kein ENDIF oder ähnliches benötigt. Es beendet die Schleife, wenn die Bedinging wahr ist, und setzt Ihr Programm hinter dem Schleifenende fort.

5.6. Laufzeitfehler und Fehlerdiagnose

Einige Fehler können vom Anwenderprogramm mit dem Befehl ON ERROR GOTO oder ON ERROR GOSUB abgefangen werden. Wenn keine Fehlerabfangroutine spezifiziert wurde, wird die Programmausführung beendet und eine Nachricht mit der entsprechenden Zeilennummer ausgegeben. Die Fehlermeldungen sind standardisiert. Jede Fehlermeldung hat eine entsprechende Nummer. Die Nummer wird auch in der Systemvariable ERR abgelegt und kann in der Fehlerabfangroutine ausgewertet werden. Eine Liste der Standardfehlermeldungen nach Nummer finden Sie im Kapitel {errors}.

6. Addressbereiche im Speicher

Der gesamte zugängliche Programmspeicher kann mit PEEK/POKE, LPEEK/LPOKE, DPEEK/DPOKE, etc. angesprochen werden. Achtung. Sie können alle Symbole des Interpreters und der dynamisch verknüpften Bibliotheken und Ihres Programms manipulieren. Adressräume, die zu anderen Programmen gehören, die keine gemeinsam genutzten Speicherblöcke sind, können nicht angesprochen werden. Beim Versuch, dies zu tun, erhalten Sie einen Segmentierungsfehler.

7. Grafik: Malen und Zeichnen

Ein Grafikfenster wird automatisch geöffnet, wenn der erste Grafikbefehl in Ihrem Programm erscheint. Ohne grafische Befehle wird kein X11-Server benötigt und Ihre Programme laufen auch unter einer Textkonsole oder als Daemon oder als CGI-Skripte. Aber wenn Sie etwas mit z.B. LINE, CIRCLE oder BOX zeichnen, den Mauszeiger abfragen oder die Tastatur, oder wenn Sie die grafische Benutzerschnittstelle verwenden mit z.B. ALERT oder MENU, dann öffnet sich ein Grafikfenster mit der Standardgröße von 640x400 Pixeln. Alle Grafikausgaben können in voller Farbe erfolgen, die mit den Anweisungen GET_COLOR() und COLOR für alle folgenden Zeichenoperationen gesetzt werden können. Außerdem können bis zu 16 verschiedene Grafikfenster gleichzeitig geöffnet sein. Bitte beachten Sie, dass alle Grafiken nur nach einem `SHOWPAGE'-Befehl angezeigt werden. Dies ermöglicht schnelle Animationen.

Um animierte Bitmap-Grafiken und -Symbole zu ermöglichen, bietet X11-Basic die Befehle GET und PUT, die rechteckige Bereiche aus dem Grafikfenster in eine Zeichenkettenvariable ablegen oder Bitmap-Grafikdaten aus der Zeichenkette in den Grafikbildschirm oder das Fenster zurücklegen. Das Dateiformat, das mit PUT verwendet wird, ist eine Standard-BMP-Bitmap, so dass Sie auch extern erstellte Symbole aus anderen Dateien laden und verwenden können. Transparenz und Alphakanäle werden unterstützt.

8. Daten aus Dateien lesen und schreiben

Bevor Sie eine Datei lesen oder in eine Datei schreiben können, müssen Sie diese öffnen (mit OPEN). Sobald Sie fertig sind, sollten Sie sie wieder schließen (mit CLOSE). Jede geöffnete Datei wird durch eine einfache Nummer gekennzeichnet, die innerhalb einer Variablen gespeichert werden kann und zusammen mit dem Befehlen PRINT und INPUT genutzt wird, wenn Sie auf die Datei zugreifen möchten.

Wenn Sie mehr Kontrolle benötigen, können Sie mit den Mehrzweckbefehlen INP() und OUT ein Byte gleichzeitig lesen und schreiben oder Sie lesen die ganze Datei auf einmal als Binärblock ein mit BLOAD.

9. Internet- und Bluetooth-Verbindungen, spezielle Dateien und Sockets

X11-Basic ermöglicht die Verbindung eines Programms mit einem anderen Programm auf einem anderen (oder demselben) Host-Computer über Standard-Internet- oder Bluetooth-Protokolle oder Pipes.

Grundsätzlich gibt es zwei Arten von Verbindungen zu anderen Computern in einem Netzwerk: Eine streambasierte Verbindung (bekannt ist das TCP/IP-Protokoll für Internetverbindungen) und ein verbindungsloser, unzuverlässiger Datagrammpaketdienst (UDP bei Internetverbindungen und z.B. L2CAP für Bluetooth).

Eine andere Möglichkeit, Daten zwischen zwei Anwendungen auf demselben Computer zu übertragen, sind sogenannte Pipes. Pipes sind spezielle Dateien, die im lokalen Dateisystem erstellt werden.

9.1. Lokale Kommunikation zwischen Prozessen: Pipes

Eine Pipe ist ein unidirektionaler Datenkanal, der für die Interprozesskommunikation verwendet werden kann. Der UNIX-Kernel unterstützt normalerweise diesen Mechanismus. Die Pipe kann verwendet werden, um Informationen oder Daten von einem Prozess zu einem anderen zu senden. Hier ist ein kleines Beispielprogramm, mit dem Sie spielen können:

PIPE #1,#2
a=FORK()
IF a=0    ! Kind-Instanz
  GPRINT "Hallo, ich bin ein Kind !",b
  DO
    SHOWPAGE
    LINEINPUT #1,t$
    GPRINT t$
  LOOP
  ' Diese Instanz wird nicht beendet...
ELSE IF a=-1
  PRINT "ERROR, fork() failed !"
  QUIT
ELSE      ! Die Elterninstanz
  DO
    DUMP
    ALERT 1,"Hi, I am Parent. Child PID="+str$(a),1," OK | Kill Child ! ",b
    DUMP
    PRINt #2,SYSTEM$("date")
    FLUSH #2
    IF b=2
      SYSTEM "kill "+str$(a)
      ALERT 1,"Child PID="+str$(a)+" killed !",1," OK ",b
      QUIT
    ENDIF
  LOOP
ENDIF
QUIT

Statt mit Pipes kann die Interprozesskommunikation auch über ein gemeinsames Speichersegment erfolgen. X11-Basic unterstützt auch Befehle zum Erstellen und Zugriff auf solche geteilten Speichersegmente.

9.2. Weltweite Kommunikation: Sockets

Die meiste Kommunikation zwischen Prozessen verwendet das Client-Server-Modell. Diese Begriffe beziehen sich auf die zwei Prozesse, die miteinander kommunizieren. Einer der beiden Prozesse, der Client, verbindet sich mit dem anderen Prozess, dem Server, um typischerweise eine Informationsanforderung zu stellen. Eine gute Analogie ist eine Person, die eine andere Person anruft.

Beachten Sie, dass der Client von der Existenz und der Adresse des Servers wissen muss, aber der Server die Adresse (oder sogar die Existenz) des Clients nicht kennen muss, bevor die Verbindung hergestellt wird. Beachten Sie auch, dass nach dem Verbindungsaufbau beide Seiten Informationen senden und empfangen können.

Wenn ein Socket erstellt wird, muss das Programm die Adressdomäne und den Socket-Typ angeben. Zwei Prozesse können nur miteinander kommunizieren, wenn ihre Sockets vom selben Typ und in derselben Domäne sind. Es gibt zwei weit verbreitete Adressdomänen, die (lokale) Unix-Domäne, in der zwei Prozesse, die sich ein gemeinsames Dateisystem teilen, kommunizieren, und die Internetdomäne, in der zwei Prozesse auf zwei beliebigen Hosts im Internet kommunizieren. Jeder von diesen hat sein eigenes Adressenformat. Eine weitere zu erwähnende Domäne ist die Bluetooth-Domäne für Kurzstrecken-Funkverbindungen. Es funktioniert ähnlich wie die Internetverbindungen, verwendet aber einen eigenen Adressraum.

Die Adresse eines Sockets in der Unix-Domäne ist eine Zeichenkette, die im Grunde genommen ein Eintrag im Dateisystem ist. Es kann von dort aus wie eine Datei aufgerufen werden. In X11-Basic können all die normalen Datei-Ein- und -Ausgabe-Befehle verwendet werden.

Die Adresse eines Sockets in der Internetdomäne besteht aus der Internetadresse des Host-Rechners (jeder Computer im Internet hat eine eindeutige 32-Bit-Adresse, oft als IP-Adresse (oder Bluetooth-ID) bezeichnet.). Darüber hinaus benötigt jeder Socket eine Portnummer auf diesem Host. Portnummern sind 16-Bit-Ganzzahlen ohne Vorzeichen. Die niedrigeren Nummern sind im Internet für Standarddienste reserviert. Die Portnummer für den FTP-Server lautet beispielsweise 21. Es ist wichtig, dass sich die Standarddienste auf allen Computern auf demselben Port befinden, damit die Clients ihre Adressen kennen. Portnummern über 2000 sind jedoch in der Regel frei verfügbar.

9.2.1. Socket Typen

Es gibt zwei weit verbreitete Socket-Typen, Stream-Sockets und Datagramm-Sockets. Stream-Sockets behandeln die Kommunikation als kontinuierlichen Zeichenstrom bzw. Bytestrom, während Datagramm-Sockets ganze Nachrichten bzw. Datenblöcke gleichzeitig senden und empfangen. Jeder Sockettyp verwendet sein eigenes Kommunikationsprotokoll. Stream-Sockets für Internetverbindungen verwenden TCP (Transmission Control Protocol). Das ist ein zuverlässiges, streamorientiertes Protokoll. Datagrammsockets verwenden UDP (Unix Datagram Protocol), das unzuverlässig und nachrichtenorientiert ist. Unzuverlässig heißt hier, dass nicht garantiert werden kann, dass das Datenpaket unverfälscht oder überhaupt ankommt, oder dass mehrere Pakete ind er richtigen reihenfolge eintreffen.

Gleiches gilt für Bluetooth-Verbindungen, Stream-Sockets verwenden das sogenannte RFCOMM-Protokoll und Datagramm-Sockets verwenden das L2CAP-Protokoll.

Sockets in X11-Basic können mit dem Befehl OPEN erstellt werden.

9.2.2. TCP/IP

Das Transmission Control Protocol (TCP) stellt einen zuverlässigen Byte-Stream-Übertragungsdienst zwischen zwei Endpunkten in einem Computernetzwerk bereit. TCP hängt von IP ab, um Pakete in durch das Netzwerk zu verschicken. IP ist von Natur aus unzuverlässig, daher schützt TCP vor Datenverlust, Datenverfälschung, Neuordnung von Paketen und Datenduplizierung, indem Prüfsummen und Sequenznummern zu übertragenen Daten hinzugefügt werden. Auf der Empfangsseite werden ankommende Pakete quittiert und ggf. neu angefordert, sollten Datenpakete nicht angekommen sein.

Bevor Daten über das Netzwerk gesendet werden, baut TCP über einen Austausch von Management-Paketen eine Verbindung mit dem Ziel auf. Die Verbindung wird genauso auch wieder abgebaut, wenn , keine Daten mehr übertragen werden sollen.

TCP verfügt über einen mehrstufigen Flusssteuerungsmechanismus, der die Datenrate des Senders kontinuierlich anpasst, um einen maximalen Datendurchsatz zu erreichen und gleichzeitig Überlastung und nachfolgende Paketverluste im Netzwerk zu vermeiden. Es versucht auch, Netzwerkressourcen optimal auszunutzen, indem so viele Daten wie möglich in ein einzelnes IP-Paket gepackt werden.

Die Systemaufrufe zum Herstellen einer Verbindung sind etwas unterschiedlich für den Client und den Server, aber beide beinhalten das Grundkonstrukt eines Sockets. Ein Socket ist ein Ende eines Interprozess-Kommunikationskanals. Die beiden Prozesse bauen jeweils ihren eigenen Socket auf.

Die Schritte zum Einrichten eines Sockets auf der Clientseite sind wie folgt:

  1. Erstellen Sie ein Socket mit dem Befehl OPEN, der eine Portnummer bereitstellt,

    OPEN "US",#1,"client",5000
  2. Verbinden Sie den Socket mit der Adresse des Servers mit dem Befehl CONNECT,

    CONNECT #1,"ptbtime1.ptb.de",13
  3. Anstatt die Schritte 1 und 2 zu verwenden, können Sie alternativ den kombinierten Befehl verwenden:

    OPEN "UC",#2,"ptbtime1.ptb.de",13
  4. Senden und empfangen Sie Daten. Es gibt mehrere Möglichkeiten, dies zu tun, aber am einfachsten verwenden Sie die Befehle PRINT, SEND, WRITE, READ, RECEIVE und INPUT.

    PRINT #2,"GET /index.html"
    FLUSH #2
    WHILE INP?(#2)
      LINEINPUT #2,t$
      PRINT "got: ";t$
    WEND
  5. Schliessen Sie die Verbindung mit:

    CLOSE #1

Die Schritte zum Einrichten eines Sockets auf der Serverseite sind wie folgt:

  1. Erstellen Sie mit dem Befehl OPEN einen Socket und binden Sie den Socket an eine Portnummer auf dem Hostcomputer.

    OPEN "US",#1,"server",5000
  2. Lauschen Sie auf eingehende Verbindungen und

  3. nehmen Sie eine Verbindung an mit noch einem (anderen) OPEN Befehl. Eine Verbindung zum Client wird geöffnet:

    OPEN "UA",#2,"",1

    Dieser Aufruf blockiert so lange, bis ein Client eine Verbindung mit dem Server herstellt.

  4. Senden und empfangen Sie Daten über die angenommene Verbindung:

      PRINT #2,"Willkommen zum X11-Basic Test-server ..."
      FLUSH #2
      DO
        IF INP?(#2)
          LINEINPUT #2,t$
          PRINT "got: ";t$
        ENDIF
        EXIT IF t$="quit"
      LOOP
      PRINT #2,"Auf Wiedersehen..."
      FLUSH #2
  5. Schließen Sie die eingerichtete Verbindung mit:

    CLOSE #2

    und warten Sie auf die nächste Verbindung (Schritt 3) oder

  6. Schließen Sie den Socket, wenn Sie ihn nicht weiter benötigen.

    CLOSE #1

9.2.3. UDP

Das User Datagram Protocol (UDP) stellt einen unzuverlässigen paketierten Datenübertragungsdienst zwischen Endpunkten in einem Netzwerk bereit.

Zuerst muss ein Socket mit dem Befehl OPEN erstellt werden:

  OPEN "UU",#1,"sender",5556

Wenn ein UDP-Socket erstellt wird, sind seine lokalen und Remoteadressen nicht angegeben. Datagramme können sofort mit SEND mit einer gültigen Zieladresse (131.195.15.200) und einem Port (5000) als Argument gesendet werden:

SEND #1,"This is my message",CVL(CHR$(131)+CHR$(195)+CHR$(15)+CHR$(200)),5000

UDP verwendet das IPv4-Adressformat, daher muss eine 32bit Ganzzahl übergeben werden. Diese wird in obigem Beispiel mit der CVL() Funktion hergestellt.

Wenn CONNECT für den Socket aufgerufen wird, wird die Standardzieladresse festgelegt, und Datagramme können jetzt mit SEND gesendet werden, ohne eine Zieladresse anzugeben. Es ist weiterhin möglich, an andere Ziele zu senden, wenn man SEND mit einer Adresse verwendet.

CONNECT #1,"localhost",5555
SEND #1,"This is my message"

Alle Empfangsoperationen geben jeweils nur ein Paket zurück.

IF INP?(#1)
  RECEIVE #1,t$,adr
  PRINT "Received Message: ";t$;" from ";HEX$(adr)
ENDIF

INP?(#n) Gibt die Größe des nächsten ausstehenden Datagramms in Bytes zurück oder 0, wenn kein Datagramm aussteht.

Der Socket sollte geschlossen werden, wenn die Verbindung nicht mehr genutzt wird:

CLOSE #1

UDP garantiert nicht, daß die Daten tatsächlich am Ziel ankommen, noch garantiert es, dass Datenpakete in der Reihenfolge, in der sie von der Quelle gesendet wurden, ankommen, noch garantiert es, dass nur eine Kopie der Daten ankommt. UDP garantiert allerdings die Datenintegrität, und zwar durch Hinzufügen einer Prüfsumme zu den Daten vor der Übertragung.

10. Bluetooth Verbindungen

Das Herstellen einer Verbindung zwischen zwei Geräten mit einem Bluetooth-Adapter ähnelt den Internetverbindungen. Auch hier können Sie eine streambasierte Verbindung (mit RFCOMM) oder eine datensatzbasierte Verbindung (mit L2CAP) verwenden.

Die X11-Basic-Befehle dafür sind ebenfalls ähnlich. Der einzige bemerkenswerte Unterschied besteht darin, dass anstelle einer IP-Adresse eine Bluetooth-ID verwendet werden muss und es kein Domain-Namen-System gibt, mithilfe dessen man einen Geräte-Namen in eine ID übersetzen lassen könnte.

Das heißt, wenn Sie eine Verbindung zu einem Bluetooth-Gerät herstellen möchten, müssen Sie seine ID zuvor kennen. Die ID besteht aus sechs Bytes (anstelle von vier im Fall einer IPV4-Internetadresse). Sie werden üblicherweise als eine Zeichenkette notiert im Format: hh:hh:hh:hh:hh:hh mit allen 6 Bytes in zweistelligen Hex-Werten, die durch Doppelpunkte getrennt sind: z.B. 78:F5:FD:15:4A:3A.

Sie können die ID entweder in Ihrem Programm fest codieren oder nach sichtbaren Bluetooth-Geräten suchen.

Der Scan kann in X11-Basic mit den Funktionen FSFIRST$() und FSNEXT$() durchgeführt werden:

a$=FSFIRST$("","*","b")
WHILE LEN(a$)
  PRINT a$
  PRINT "Adress: ";WORD$(a$,1)
  PRINT "Name:   ";WORD$(a$,2)
  adr$=WORD$(a$,1)
  a$=FSNEXT$()
WEND

10.1. RFCOMM

RFCOMM (Radio Frequency Communication) stellt dem Benutzer, ähnlich wie TCP, eine einfache, zuverlässige Datenstromverbindung zur Verfügung.

Viele Bluetooth-Anwendungen verwenden RFCOMM, da es weit verbreitet ist und von vielen frei verfügbaren Programmierschnittstellen auf den meisten Betriebssystemen unterstützt wird. Darüber hinaus können Anwendungen, die eine serielle Schnittstelle für die Kommunikation verwenden, schnell auf RFCOMM portiert werden.

Wie bei TCP/IP ist für den Aufbau einer Verbindung über RFCOMM das Grundkonstrukt ein Socket. Die beiden Prozesse (Server und Client) bauen jeweils einen eigenen Socket auf.

Die Schritte zum Einrichten eines Sockets auf der Client-Seite sind wie folgt (angenommen, die Bluetooth-ID, mit der Sie sich verbinden wollen, liegt in adr$.):

  1. Erstellen Sie ein Socket mit dem Befehl OPEN, der eine Portnummer (TODO ??) bereitstellt,

  2. Verbinden Sie das Socket mit der Adresse des Servers mit dem Befehl CONNECT,

  3. Anstatt die Schritte 1 und 2 zu verwenden, können Sie alternativ den kombinierten Befehl verwenden:

  4. Senden und empfangen Sie Daten. Es gibt mehrere Möglichkeiten, dies zu tun, aber am einfachsten verwenden Sie die Befehle PRINT, SEND, WRITE, READ, RECEIVE und INPUT.

      PRINT #2,"Hello"
      FLUSH #2
      WHILE INP?(#2)
        LINEINPUT #2,t$
        PRINT "got: ";t$
      WEND
  5. Schliessen Sie die Verbindung mit:

    CLOSE #1

Die Schritte zum Einrichten eines Sockets auf der Serverseite sind wie folgt:

  1. Erstellen Sie mit dem Befehl OPEN einen Socket und binden Sie den Socket an eine Portnummer auf dem Hostcomputer.(TODO: port number ????)

  2. Lauschen Sie auf eingehende Verbindungen und

  3. nehmen Sie eine Verbindung an mit noch einem (anderen) OPEN Befehl. Eine Verbindung zum Client wird geöffnet:

    OPEN "UA",#2,"",1

    Dieser Aufruf blockiert so lange, bis ein Client eine Verbindung mit dem Server herstellt.

  4. Senden und empfangen Sie Daten über die angenommene Verbindung:

      PRINT #2,"Willkommen zum X11-Basic Test-server ..."
      FLUSH #2
      DO
        IF INP?(#2)
          LINEINPUT #2,t$
          PRINT "got: ";t$
        ENDIF
        EXIT IF t$="quit"
      LOOP
      PRINT #2,"Auf Wiedersehen..."
      FLUSH #2
  5. Schließen Sie die eingerichtete Verbindung mit:

    CLOSE #2

    und warten Sie auf die nächste Verbindung (Schritt 3) oder

  6. Schließen Sie den Socket, wenn Sie ihn nicht weiter benötigen.

    CLOSE #1

10.2. L2CAP

(L2CAP=Logical link control and adaptation protocol)

Zuerst muss ein Socket mit dem Befehl OPEN erstellt werden:

Wenn ein L2CAP-Socket erstellt wird, sind seine lokalen und Remoteadressen nicht angegeben. Datagramme können sofort mit SEND mit einer gültigen Zieladresse und einem Port als Argument gesendet werden:

TODO …​. verwendet das IPv4-Adressformat, so dass eine lange Ganzzahl übergeben werden muss.

Wenn CONNECT für den Socket aufgerufen wird, wird die Standardzieladresse festgelegt, und Datagramme können jetzt mit SEND gesendet werden, ohne eine Zieladresse anzugeben.

Alle Empfangsoperationen geben nur ein Paket zurück.

INP?(#n) Gibt die Größe des nächsten ausstehenden Datagramms in Bytes zurück oder 0, wenn kein Datagramm aussteht.

Der Socket sollte geschlossen werden, wenn die Verbindung nicht mehr genutzt wird:

CLOSE #1

Die maximale Paketgröße sollte 672 Bytes nicht überschreiten.

Die Bluetooth-Unterstützung von X11-Basic ist noch neu und noch in Arbeit und funktioniert noch nicht unter Android und WINDOWS.

11. USB-Geräte ansprechen

X11-Basic verfügt über eine integrierte USB-Programmierschnittstelle, über die X11-Basic-Programme auf USB-Geräte zugreifen können, die an den Computer angeschlossen sind. Die Schnittstelle befindet sich auf einer nahen Hardware-Ebene, so dass der Treiber für die spezifische angeschlossene Hardware in X11-Basic geschrieben werden muss. Daher ist es gut möglich, Datenlogger und USB-zu-RS232-Adapter mit diesen Methoden zu verwenden. Im Prinzip kann auf jedes USB-Gerät zugegriffen werden, wenn das Protokoll für Datentransfer und Dateninterpretation bekannt ist.

Bitte beachten Sie das Beispielprogramm usb-VDL101T.bas. Für ein Beispiel, wie Daten aus einem VOLTCRAFT VDL101-T-Datenlogger gelesen werden.

USB-Unterstützung ist in Arbeit und funktioniert möglicherweise noch nicht auf Android und WINDOWS.

USB-Geräte werden mit dem Befehl OPEN geöffnet. Anstelle eines Dateinamens wird eine Kombination aus PID/VID verwendet. Nach dem Öffnen können die Befehle CLOSE, IOCTL(), SEND und RECEIVE mit diesem Gerät verwendet werden. (PRINT und INPUT werden zur Zeit leider nicht funktionieren).

12. Daten im Programm-Quelltext

Sie können Daten innerhalb Ihres Programms in DATA-Anweisungen speichern. Diese werden Sie während der Ausführung des Programms wahrscheinlich in Variablen oder Arrays eingelesen. Dasselbe kann man auch bequem durch Zuweisung von Konstanten zu Arrays realisieren. Nicht zuletzt gibt es die INLINE$() Funktion, welche verwendet werden kann, um große binäre Datensegmente im Quelltext zu speichern. Letztere werden vorher passend codiert.

Das erste Beispiel zeigt, wie konventionelle Daten (Zahlen und Strings) im Sourcecode eines Basisprogramms gespeichert werden:

' Beispiel, wie man die DATA Anweisung verwendet

RESTORE mydata
READ name$,age,address$,code

mydata:
DATA "Bud Spencer",30,"Holywood Street",890754
DATA "Hannelore Isendahl",15,"Max-Planck-Allee",813775

Das folgende Beispiel zeigt, wie beliebige Binärdaten gespeichert werden, z.B. um die Daten für eine Bitmap zu speichern. Oder auch für andere Ressourcen wie Piktogramme und andere Bitmaps oder Icons.

' output of inline.bas for X11-Basic 23.04.2002
' demo 104 Bytes.
demo$=""
demo$=demo$+"5*II@V%M@[4D=*9V,)5I@[4D=*9V,(IR?*IR=6Y*A:]OA*IS?F\.&IAI?J\D8ZII"
demo$=demo$+",*5M=;1I@V%P=;1I?F%OaJ]R=:\P,*5E?J\D>*)X,*9W,*AI>ZUE@+%X/F\R&JAV"
demo$=demo$+"A;1W&HXR&DL$"
a$=INLINE$(demo$)
PRINT len(a$),a$

' show a bitmap
biene$="($$43$%*<(1G,=E5Z&MD%_DVW'b*%H-^,EQ6>VTL$$$$"

CLEARW
t$=INLINE$(biene$)
COLOR COLOR_RGB(1,1,1)
FOR i=0 TO 40
  PUT_BITMAP t$,i*16,0,16,16
NEXT i

Der Einfachheit halber wurde ein Programm namens inline.bas mit X11-Basic mitgeliefert. Es konvertiert und komprimiert jede Binärdatei in den gebrauchsfertigen X11-Basic-Quellcode.

13. Dynamische Bibliotheken

Eine Dynamic-Link-Bibliothek (.so = shared object) ist eine Sammlung von Funktionen (Subroutinen), die von Programmen oder anderen Bibliotheken verwendet werden können. Eine Funktion aus einer dynamischen Bibliothek muss direkt oder indirekt von einer laufenden Anwendung aufgerufen werden und kann nicht als eigenständiges Programm ausgeführt werden.

Dynamic Link Libraries sparen Speicherplatz, da viele Anwendungen gleichzeitig eine einzelne shared object-Datei verwenden können, die nur einmal in den Speicher geladen werden muss. Ein weiterer Vorteil von separaten und zu Laufzeit hinzufügbaren Funktionen in einer dynamischen Bibliothek ist, dass man diese separat und unabhängig von den Anwendungen, die sie spaeter benutzen, ändern kann, solange sich die Argumente und Rückgabewerte der Funktion nicht ändern. Ein Nachteil bei der Verwendung von .so`s ist, dass eine Anwendung von der Existenz eines separaten `.so Moduls abhängt. Wenn das .so nicht gefunden wird, wird die Anwendung beendet.

Alle dokumentierten Funktionen aus den shared Objekten anderer Softwarepakete können in Ihrem X11-Basic-Programm verwendet und aufgerufen werden.

X11-Basic führt allerdings keine Überprüfung der Anzahl und des Typs der Funktionsparameter durch.Das liegt dann in Ihrer Verantwortung, diese im richtigen Format und in der richtigen Reihenfolge zu übergeben.

13.1. C-Funktionen in shared libraries nutzen

Wenn Sie eigene Funktionen, welche sie in einer anderen Programmiersprache (wie z.B. C) als X11-Basic geschrieben haben, zusammen mit X11-Basic verwenden wollem, dann müssen sie diese zuvor in eine dynamische Bibliothek kompilieren. Es entsteht so eine .so-Datei oder eine .dll-Datei.

Bevor eine X11-Basic-Anwendung eine Funktion aus einem .so verwenden kann, muss die dynamische Bibliothek geladen werden. Die geschieht mit dem LINK Kommando.

LINK #1,"myfile.so"

Die Bibliothek wird also zur Laufzeit hinzugelinkt.

Wenn Sie jetzt zum Beispiel eine C-funktion binit() aus der Bibliothek`trackit.so` aufrufen möchten, können SIe das mit den folgenden Codezeilen tun:

IF NOT EXIST("./trackit.so")
  SYSTEM "gcc -O3 -shared -o trackit.so trackit.c"
ENDIF
LINK #11,"./trackit.so"
~CALL(SYM_ADR(#11,"binit"),L:n,L:200,P:VARPTR(x(0)),P:VARPTR(bins(0)))

Zur Verdeutlichung hier auch der C-Quelltext für die erwähnte Funktion:

trackit.c
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

void binit(int n,int dn,double *x,double *data) {
  int i,j;
  int over=0,under=0;
    for(i=0;i<n;i++) {
      j=(int)((x[i]+PI)/2/PI*dn);
      if(j<0) under++;
      else if(j>=dn) over++;
      else data[j]++;
    }
}

X11-Basic-Anwendungen können bis zu 99 shared object Dateien gleichzeitig laden, obwohl der Kanalnummernbereich auch für die geöffneten Dateien verwendet wird.

X11-Basic verwaltet eine interne Tabelle mit 99 Einträgen, um die interne Referenz der geladenen Dateien zu speichern. Diese Referenzen sind notwendig, um auf die Daten zuzugreifen.

Die `.so’s werden mit dem Befehl 'UNLINK' wieder aus dem Speicher entfernt:

UNLINK #11

Die CALL() Funktion erlaubt nur einen Integer (int) Typ für den Rückgabewert. Um einen Gleitkomma-Rückgabewert zu erhalten, verwenden Sie stattdessen CALLD(). Wenn die aufgerufene Funktion eine komplizierte Datenstruktur zurückgibt, verwenden Sie stattdessen CALL$().

Tip

Derzeit gibt es eine Einschränkung bei der Verwendung von CALL(), CALLD() und CALL$() auf 64-Bit-Betriebssystemen. Hier werden nur Integer- und Pointer-Parameter korrekt an die aufgerufene Funktion übergeben. Wenn Sie die Bibliotheksfunktion selbst geschrieben haben, könnten Sie diese Einschränkung umgehen, indem Sie statt (double *) einen Zeiger auf die Fließkomma-Variablen übergeben.

Note

Der Aufrufmechanismus hängt von der Programmierschnittstelle (ABI) ab, die für verschiedene Plattformen unterschiedlich ist. Leider ist die AMD86x64-Schnittstelle bereits so kompliziert, dass es keine direkte portable Möglichkeit gibt, sie vollständig zu implementieren. Die Hoffnung ist, dass in Zukunft eine externe Bibliothek verwendet werden kann, die einen portablen Weg bietet. Ein guter Kandidat wäre die Fremdfunktionsschnittstellenbibliothek libffi.

Folgende Parametertypen sind möglich:

D:

64-bit float (double)

L:

32-bit integer (int) (%)

W:

16-bit signed (short)

B:

8-bits signed (char)

F:

4 byte float (float)

R:

8 byte long integer (long long)

P:

4 or 8 byte pointer (void *)

Die Option P: verhält sich genauso wie L: auf 32-Bit-Betriebssystemen. Aber Sie sollten P: für Zeiger (VARPTR() usw.) in den Speicher verwenden, damit sie von der 32-Bit-X11-Basic-Darstellung in 64-Bit-Adressen auf 64it-Betriebssystemen übersetzt werden können. Die Optionen B: und W: verhalten sich genauso wie die Option L:.

Die Funktion SYM_ADR() bestimmt die Adresse der Funktion anhand ihres Namens. Die Schreibweise des Funktionsnamens muss daher genau mit der Schreibweise der Funktion im .so identisch sein.

Wenn Sie die Adresse einer Zeichenfolge übergeben, muss ein Nullbyte am Ende der Zeichenfolge hinzugefügt werden.

14. Speicherverwaltung

Normalerweise kümmert sich X11-Basic um den größten Teil der Speicherverwaltung für den Programmierer. Wenn eine Variable, eine Zeichenfolge oder ein Array deklariert wird, weist X11-Basic den erforderlichen Speicher zu und gibt ihn frei, wenn die Anwendung beendet wird. Es kann jedoch Situationen geben, in denen ein Programmierer zusätzlichen Speicher reservieren möchte.

14.1. Speicher Allozieren

Wenn eine Anwendung geringe Datenmengen speichern muss, sollten Strings verwendet werden, um diese zu speichern. Strings werden oft auch als DatenPuffer für Funktionen verwendet. Die Adresse des von einem String belegten Speichers kann mit der VARPTR() Funktion erhalten werden. Seine Länge durch die LEN() Funktion. Strings dürfen 2 Gigabyte gross sein und können beliebige Bytes speichern. Also genug für viele Anwendungen. Die Adresse eines Strings kann sich jedoch nach jeder Zuweisung von Daten ändern. Das sollten Sie bedenken.

Um Speicher aus dem globalen und systemweiten Programm-User-Space-Speicherpool zu reservieren, können Sie die Funktion MALLOC() verwenden. Um beispielsweise 2000 Bytes zu reservieren, könnten Sie Folgendes schreiben:

ptr%=MALLOC(2000)

Die Adresse des Begins des Speicherbereichs befindet sich dann in ptr%. Im Gegensatz zu Strings, bleibt der reservierte Speicherbereich immer an derselben Stellen, seine Adresse ändert sich also nicht.

Ein globaler Speicherblock, der mit MALLOC() reserviert wurde, muss mit der Funktion FREE() wieder freigegeben werden. Eine Anwendung sollte immer alle Speicherblöcke freigeben, bevor sie beendet wird.

Zum Beispiel:

FREE ptr%

14.2. Shared memory

Speicher, der mit MALLOC() zugeordnet wurde, kann nur von einem einzigen Prozess aus benutzt werden. Wenn zwei verschiedene X11-Basic-Instanzen oder im Allgemeinen zwei verschiedene laufende X11-Basic-Programme auf denselben Speicher zugreifen möchten (z.B. um Daten gemeinsam zu nutzen oder auszutauschen), müssen sie stattdessen einen gemeinsam genutzten Speicher verwenden, sogenannte shared mamory.

Das Shared Memory-Segment muss zuerst erstellt und zugewiesen werden. Dies sollte nur von einem der Programme durchgeführt werden. Der Ersteller wählt auch einen Schlüssel (der nur eine Ganzzahl ist) und muss allen anderen Programmen bekannt sein, die später auf diesen Speicher zugreifen wollen. Als Beispiel wählen wir den Schlüssel 4711. Um beispielsweise 2000 Bytes zuzuweisen, könnten Sie Folgendes schreiben:

id=SHM_MALLOC(2000,4711)

Im Gegensatz zu MALLOC() gibt SHM_MALLOC() nicht direkt eine Adresse zurück. Stattdessen liefert es einen Bezeichner des gemeinsamen Speichersegments, welcher mit dem Schlüssel verknüpft ist. Die Kennung ist auch nur eine ganze Zahl. Ein neues Shared-Memory-Segment wird erstellt, wenn noch kein dem Schlüssel entsprechendes Shared-Memory-Segment existiert, ansonsten wird ein bereits vorhandenes verwendet.

Um eine Adresse zu erhalten, die Sie dann normal wie alle anderen Speicheradressen verwenden können, müssen Sie die Funktion SHM_ATTACH() bemühen:

adr%=SHM_ATTACH(id)

Sobald der andere Prozess den Schlüssel und die Größe des Shared-Memory-Segments (oder zumindest seine ID) kennt, kann er das gleiche Segment auch an seinen Adressraum anhängen. Es wird schließlich eine andere Adresse erhalten (adr%), aber das Schreiben in den Speicher und das Lesen von diesem wird nun auch alle anderen Prozesse betreffen, die dieses gemeinsame Segment verwenden.

Wenn es nicht mehr verwendet wird, sollte das Segment von jedem der Prozesse, die es verwenden, vom Adressraum getrennt werden (so dass adr% nicht mehr verwendet werden kann). Wenn das gemeinsam genutzte Speichersegment vollständig aus dem Speicher entfernt werden sollte (und alle seine Inhalte verworfen werden sollten), kann der Ersteller dieses Segments es mit SHM_FREE freigeben.

SHM_DETACH adr%
SHM_FREE id

Wenn es nicht freigegeben wird, bleibt es und die darin enthaltenen Daten persistent im Speicher des Rechners bestehen, bis dieser ausgeschaltet oder neu gebootet wird.

15. Weitere Eigenarten des X11-Basic

  • X11-Basic-Programme können andere Programme mit den Befehlen SYSTEM und SYSTEM$() starten..

  • Die Funktion ENV$() ermöglicht den Zugriff auf (globale) Umgebungsvariablen.

  • Die aktuelle Uhrzeit oder das Datum kann abgerufen werden mit TIME$ und DATE$.

  • Der Interpreter erlaubt selbst-modifizierenden Code.

16. Graphical User Interface

In diesem Kapitel wird beschrieben, wie Sie die in X11-Basic integrierte grafische Benutzeroberfläche (GUI) verwenden.

16.1. ALERT und FILESELECT

Die zwei am häufigsten verwendeten Nutzerschnittstellen sind

  1. grafische Ausgabe von Meldungen, welche vom Nutzer quittiert werden,

  2. eine Dateiauswahl, in der der Nutzer eine Datei auswählen kann.

Beide sind als voll funktionsfähige grafisches Dialogfeld implementiert.

Darüber hinaus gibt es noch weitere Dialogfelder für Listen-Auswahl, Einfache Texteingabefelder, Pull-Down-Menüs und die Möglichkeit, beliebige Dialogfelder aus einfachen Objekten zusammenzustellen. Beliebige Dialoge können mit den Objekt- und Ressourcenfunktionen erstellt werden.

ALERT Box mit X11-Basic
Figure 2. Eine ALERT-Box für Mitteilungen.

Abb. {img-alert} zeigt eine typische Nachrichtenbox. Der Befehl, der es erzeugt, ist:

ALERT 3,"This file is write protected.|You can only read or \
         delete it.",1,"OK|DELETE|CANCEL",sel

ALERT-Felder können auch verwendet werden, um einfache Eingabeformulare zu verwalten, wie sie in Abb. {img-alert3} zu sehen sind. Hier ist ein kleines Beispielprogramm:

CLEARW
i=1
name$="TEST01"
posx$="N54°50'32.3"
posy$="E007°50'32.3"
t$="Edit waypoint:||Name:   "+CHR$(27)+name$+"|"
t$=t$+"Breite: "+chr$(27)+posx$+"|"
t$=t$+"Länge:  "+chr$(27)+posy$+"|"
t$=t$+"Höhe:   "+chr$(27)+str$(alt,5,5)+"|"
t$=t$+"Typ:    "+chr$(27)+hex$(styp,4,4)+"|"
ALERT 0,t$,1,"OK|UPDATE|LÖSCHEN|CANCEL",a,f$
WHILE LEN(f$)
  WORT_SEP f$,CHR$(13),0,a$,f$
  PRINT "Feld";i;": ",a$
  INC i
WEND
QUIT
ALERT Box mit Eingabefeldern
Figure 3. Eine ALERT-Box mit Eingabefeldern.
FILESELCT Box
Figure 4. Der Datei-Auswahldialog.

Abb. {img-fileselect} zeigt das Dateiauswahlfeld. Der Befehl, der es erzeugt, ist:

FILESELECT "load program:","./*.bas","in.bas",f$

Der vollständige Pfad und Dateiname der ausgewählten Datei wird in f$ zurückgegeben.

PullDown Menü
Figure 5. Pull-Down Menü.

16.2. Grafische Resourcen

X11-Basic-Ressourcen bestehen aus Objektbäumen, Strings und Bitmaps, die von einem BASIC-Programm verwendet werden. Sie kapseln die Benutzerschnittstelle und erleichtern die Internationalisierung, indem sie alle Zeichenfolgen mit Meldungen und Beschriftungen in einer einzigen separaten Datei ablegen. Das Datenformat der X11Basic-Ressource ist abwärtskompatibel zu der Atari-ST GEM-Implementierung.

Dialogfeld
Figure 6. Eine komplexere Mitteilungsbox.
Dialogfeld
Figure 7. Eine komplexeres Eingabedialogfeld.
Formular
Figure 8. Eine komplexeres EingabeFormular.

Die Abbildungen zeigen drei Beispiele für komplexere Dialogfelder, welche in X11-Basic benutz werden können. Ressourcen werden in der Regel mithilfe eines Resource Construction Set (RCS) erstellt und in einer .RSC-Datei gespeichert. Diese wird dann vom X11-Basic-Programm mit RSRC_LOAD() zur Programminitialisierungszeit geladen.

Ressourcen können auch als Datenstrukturen im Quellcode eingebettet sein (die Hilfsprogramme rsc2gui.bas und gui2bas.bas konvertieren .RSC Dateien in den Quellcode). Ressourcen enthalten Zeiger und Koordinaten, die vor der Verwendung an die aktuelle Bildschirmgröße angepasst werden. RSRC_LOAD() macht dies automatisch, wenn Sie jedoch eine eingebettete Ressource verwenden, müssen Sie sich selbst um jedes Objekt in jeder Objektbaumstruktur kümmern, um die ursprünglichen Zeichenkoordinaten in Bildschirmkoordinaten zu konvertieren. Dadurch können Ressourcen, die auf Bildschirmen mit unterschiedlichen Seitenverhältnissen und Systemschriftarten erstellt wurden, gleich aussehen. Sobald eine Ressource geladen ist, verwenden Sie rsrc_gaddr(), um Zeiger auf einzelne Objektbäume zu erhalten, die dann direkt oder mit den eingebauten X11-Basic-Funktionen manipuliert werden können.

16.2.1. Objekte der Grafischen Benutzerschnittstelle

Objekte können Boxen, Schaltflächen, Text, Bilder und mehr sein. Ein Objektbaum ist ein Array von OBJECT-Strukturen, die miteinander verknüpft sind, um eine strukturierte Beziehung zu bilden. Das Objekt selbst ist eine Datenbereich, der in X11-Basic durch einen String gehalten werden kann.

Die OBJECT-Struktur hat folgendes Format:

object$=MKI$(ob_next)+MKI$(ob_head)+MKI$(ob_tail)+
        MKI$(ob_type)+MKI$(ob_flags)+MKI$(ob_state)+
        MKL$(ob_spec)+MKI$(ob_x)+MKI$(ob_y)+MKI$(ob_width)+
        MKI$(ob_height)

Ein Objektbaum ist eine Sammlung von Objekten:

tree$=object0$+object1$+ ... +objectn$

Das erste Objekt in einem OBJEKT-Baum heißt das ROOT-Objekt (OBJECT 0). Die Koordinaten sind relativ zur oberen linken Ecke des Bildschirms bzw. des Grafikfensters. Das ROOT-Objekt kann beliebig viele Kinder haben und jedes Kind kann eigene Kinder haben. In jedem Fall sind die Koordinaten des OBJEKTS ob_x, ob_y, ob_width und ob_height relativ zu dem seines Elternteils. Die X11-Basic-Funktion objc_offset() kann verwendet werden, um die genauen absoluten Bildschirmkoordinaten eines Kindobjekts zu bestimmen. objc_find() wird verwendet, um das Objekt zu bestimmen, innerhalb dessen eine bestimmte Bildschirmkoordinate liegt (z.B. der Mauszeiger).

Die Felder ob_next, ob_head, und ob_tail bestimmen diese Beziehung zwischen übergeordneten und untergeordneten Objekten.

ob_next

der Index des nächsten (zählt Objekte vom ersten Objekt in der Objektbaumstruktur) gleichrangigen Objekts auf der gleichen Ebene im Objektbaum-Array. Das ROOT-Objekt sollte diesen Wert auf -1 setzen. Das letzte Kind auf einer gegebenen Ebene des Objekt-Baumes sollte dies auf den Index seines Elternteils setzen.

ob_head

der Index des ersten untergeordneten Elements des aktuellen Objekts. Wenn das Objekt keine Kinder hat, sollte dieser Wert -1 sein.

ob_tail

der Index des letzten untergeordneten Elements: das Ende der Liste der untergeordneten Objekte des Objekts im Objektbaum-Array Wenn das Objekt keine untergeordneten Elemente hat, sollte dieser Wert -1 sein.

ob_type

der Objekttyp. Das Low-Byte des Felds ob_type gibt den Objekttyp wie folgt an:

ob_type

Name

Beschreibung

20

G_BOX

Box

21

G_TEXT

Formatted Text

22

G_BOXTEXT

Formatted Text in a Box

23

G_IMAGE

Monochrome Image

24

G_PROGDEF

Programmer-Defined Object

25

G_IBOX

Invisible Box

26

G_BUTTON

Push Button w/String

27

G_BOXCHAR

Character in a Box

28

G_STRING

Un-formatted Text

29

G_FTEXT

Editable Formatted Text

30

G_FBOXTEXT

Editable Formatted Text in a Box

31

G_ICON

Monochrome Icon

32

G_TITLE

Menu Title

33

G_CICON

Color Icon

ob_flags

Das Feld ob_flags der Objektstruktur ist eine Bitmaske verschiedener Flags, die auf ein beliebiges Objekt angewendet werden können. Vielleicht möchten Sie ein oder mehrere Flags gleichzeitig anwenden. Fügen Sie einfach jeweils folgende Werte hinzu:

ob_flags

Name

Beschreibung

0

NONE

Kein Flag, Nichts.

1

SELECTABLE

Das Objekt kann angewählt werden. Der Zustand kann geändert werden, indem man mit der Maus draufklickt.

2

DEFAULT

Ein EXIT Objekt, welches dieses Flag gesetzt hat, wird mit einer dickeren Umrandung gezeichnet und es wird ausgelöst, wenn der Benutzer die Return-Taste drückt.

4

EXIT

Wenn man auf dieses Objekt klickt, und die Maus dann wieder losläßt, während der Mauszeiger sich noch über diesem Objekt befindet, wird der Dialog beendet.

8

EDITABLE

Dieses Flag wird für FTEXT und FBOXTEXT Objekte gesetzt, um anzuzeigen, dass diese Objekte zur Texteingabe den Cursor-Fokus erhalten können.

16

RBUTTON

Dieses Flag zeigt an, dass dieses Objekt zu einer Gruppe von Radio-Knöpfen gehört. Klickt man auf eines dieser Objekte, werden die anderen aus dem gleichen Level des Baumes alle abgewählt. Entsprechend wird es selbst automatisch abgewählt, wenn eines der anderen Objekte angeklickt wird.

32

LASTOB

Dieses Flag markiert das Objekt als das letzte im Objektbaum. In jedem Objektbaum muss es genau ein LASTOB Objekt geben.

64

TOUCHEXIT

Der Dialog wird sofort beendet, wenn man ein Objekt anklickt, welches dieses Flag hat.

256

HIDETREE

Dieses OBJECT und alle seine Kinder werden nicht Gezeichnet.

512

INDIRECT

Wenn dieses Flag gesetzt ist, wird das ob_spec Feld als Zeiger interpretiert, der auf einen ob_spec Wert zeigt.

1024

FL3DIND

Mit diesem Flag wird das OBJECT mit einem 3D-Aussehen dargestellt. Das ist nützlich für Radio-Knöpfe und Toggle-Buttons.

2048

FL3DACT

Setting this flag causes the OBJECT to be drawn as a 3D activator. This is appropriate for EXIT buttons.

3072

FL3DBAK

If these bits are set, the object is treated as an AES background object. If it is OUTLINED, the outlined is drawn in a 3D manner. If its color is set to WHITE and its fill pattern is set to 0 then the OBJECT will inherit the default 3D background color.

4096

SUBMENU

Dieses Bit ist gesetzt bei Menüeinträgen, die ein Untermenü besitzen. Dieses Flag zeigt außerdem an, daß das High-Byte des ob_type Feldes vom Menüsystem benutzt wird.

ob_state

Das Feld` ob_state` bestimmt den Anzeigezustand des Objekts wie folgt:

ob_state

Name

Beschreibung

0

NORMAL

Normal

1

SELECTED

Das Objekt erscheint angewählt. Es wird mit invertierten Farben gezeichnet. Eine Ausnahme ist ein G_CICON Objekt. Dieses nutzt stattdessen eine spezielle 'selected' Bitmap.

2

CROSSED

Ein OBJECT, welches dieses Bit gesetzt hat, wird mit einem weissen Kreuz gezeichnet. Tatsächlich kann man das nur bei farbigen oder SELECTED Objekten sehen.

4

CHECKED

Ein OBJECT mit diesem Zustand bekommt ein Häkchen in seiner oberen linken Ecke.

8

DISABLED

Ein solches OBJECT ignoriert jede Benutzereingabe oder -Aktion. Textobjekte mit diesem Bit werden grau oder gestrichelt dargestellt.

16

OUTLINED

G_BOX, G_IBOX, G_BOXTEXT, G_FBOXTEXT, and G_BOXCHAR OBJECTe mit diesem Bit bekommen einen doppelten Rahmen.

32

SHADOWED

G_BOX, G_IBOX, G_BOXTEXT, G_FBOXTEXT, and G_BOXCHAR OBJECTe bekommen einen Schatten.

ob_spec

Das objektspezifische Feld ob_spec enthält abhängig vom Objekttyp unterschiedliche Daten wie in der folgenden Tabelle angegeben:

G_BOX

In den unteren 16 Bits befinden sich Farbinformationen für das Objekt. Bits 23-16 enthalten ein signed BYTE, welches die Randdicke der Box angibt.

G_TEXT

Das ob_spec Feld enthält einen Zeiger auf eine TEDINFO Datenstruktur.

G_BOXTEXT

Das ob_spec Feld enthält einen Zeiger auf eine TEDINFO Datenstruktur.

G_IMAGE

Das ob_spec Feld enthält einen Zeiger auf eine BITBLK Datenstruktur.

G_PROGDEF

Das ob_spec Feld enthält einen Zeiger auf eine APPLBLK Datenstruktur.

G_IBOX

In den unteren 16 Bits befinden sich Farbinformationen für das Objekt. Bits 23-16 enthalten ein signed BYTE, welches die Randdicke der Box angibt.

G_BUTTON

Das ob_spec Feld enthält einen Zeiger auf den Text, der im BUTTON angezeigt werden soll. Der Text muss mit einem Null-Byte abgeschlossen sein.

G_BOXCHAR

In den unteren 16 Bits befinden sich Farbinformationen für das Objekt.Bits 23-16 enthalten ein signed BYTE, welches die Randdicke der Box angibt. Bits 31-24 enhalten den ASCII code des Zeichens, welches in der Box dargestellt werden soll.

G_STRING

Das ob_spec Feld enthält einen Zeiger auf den Text, der im BUTTON angezeigt werden soll. Der Text muss mit einem Null-Byte abgeschlossen sein.

G_FTEXT

Das ob_spec Feld enthält einen Zeiger auf eine TEDINFO Datenstruktur.

G_FBOXTEXT

Das ob_spec Feld enthält einen Zeiger auf eine TEDINFO Datenstruktur.

G_ICON

Das ob_spec Feld enthält einen Zeiger auf eine ICONBLK Datenstruktur.

G_TITLE

Das ob_spec Feld enthält einen Zeiger auf den Text, der im BUTTON angezeigt werden soll. Der Text muss mit einem Null-Byte abgeschlossen sein.

G_CICON

Das ob_spec Feld enthält einen Zeiger auf eine CICONBLK Datenstruktur.

objc_colorword

Fast alle Objekte verweisen auf ein WORD, das die unten definierte Objektfarbe enthält.

objc_colorword=bbbbcccctpppcccc

Bits 15-12   Farbe des Randes
Bits 11- 8   Farbe des Textes
Bit    7     ist 1 wenn undurchsichtig oder 0 wenn transparent
Bits  6- 4   Füllmuster-Index
Bits  3- 0   Farbe der Füllung

Verfügbare Farben für Füllmuster, Text und Rahmen sind unten aufgeführt:

Wert

Name

Farbe

0

WHITE

Weiß

1

BLACK

Schwarz

2

RED

Rot

3

GREEN

Grün

4

BLUE

Blau

5

CYAN

Cyan

6

YELLOW

Gelb

7

MAGENTA

Magenta

8

LWHITE

Hellgrau

9

LBLACK

Dunkelgrau

10

LRED

Hellrot

11

LGREEN

Hellgrün

12

LBLUE

Hellblau

13

LCYAN

Hell Cyan

14

LYELLOW

Hellgelb

15

LMAGENTA

Hell Magenta

TEDINFO

Die Objekte G_TEXT, G_BOXTEXT, G_FTEXT und G_FBOXTEXT verweisen alle auf eine TEDINFO-Struktur in ihrem ob_spec-Feld. Die TEDINFO-Struktur ist wie folgt definiert:

tedinfo$=MKL$(VARPTR(te_ptext$))+MKL$(VARPTR(te_ptmplt$))+
         MKL$(VARPTR(te_pvalid$))+MKI$(te_font)+MKI$(te_fontid)+
         MKI$(te_just)+MKI$(te_color)+MKI$(te_fontsize)+
         MKI$(te_thickness)+MKI$(te_txtlen)+MKI$(te_tmplen)

Die drei Zeiger zeigen auf Textzeichenfolgen, die für G_FTEXT und G_FBOXTEXT Objekte nötig sind. te_ptext zeigt auf den tatsächlich anzuzeigenden Text und ist das einzige Feld, das von allen Textobjekten verwendet wird. te_ptmpt zeigt auf die Textvorlage für bearbeitbare Felder. Für jedes Zeichen, das der Benutzer eingeben kann, muss die Textzeichenfolge ein Tilde-Zeichen enthalten (ASCII 126). Andere Zeichen werden angezeigt, können aber vom Benutzer nicht überschrieben werden. te_pvalid enthält Validierungszeichen für jedes Zeichen, das der Benutzer eingeben darf. Die derzeit gültigen Validierungszeichen sind:

Buchstabe

erlaubt

9

Ziffern 0-9

A

Großbuchstaben A-Z sowie Leerzeichen

a

Groß- und Kleinbuchstaben sowie Leerzeichen

N

Ziffern 0-9, Großbuchstaben A-Z sowie Leerzeichen

n

Ziffern 0-9, Groß- und Kleinbuchstaben sowie Leerzeichen

F

Gültige Zeichen für DOS Dateinamen sowie Fragezeichen und Sternchen

P

Gültige Zeichen für DOS Dateinamen sowie backslash, Doppelpunkt, Fragezeichen und Sternchen

p

Gültige Zeichen für DOS Dateinamen sowie backslash und Doppelpunkt

X

Alle Zeichen

te_font

darf folgende Werte haben:

te_font

Name

Beschreibung

3

IBM

Standard monospaced font.

5

SMALL

Kleiner monospaced font.

te_just

bestimmt die Ausrichtung des Textes innerhalb des Objektes und darf folgende Werte haben:

te_just

Name

Beschreibung

0

TE_LEFT

Linksbündig

1

TE_RIGHT

Rechtsbündig

2

TE_CNTR

Zentriert

te_thickness

setzt die Randstärke (positive und negative Werte sind akzeptabel) des G_BOXTEXT- oder G_FBOXTEXT-Objekts.

te_txtlen und te_tmplen

sollten auf die Länge des Anfangstexts bzw. der Vorlagenlänge gesetzt werden.

BITBLK

G_IMAGE-Objekte enthalten einen Zeiger auf eine BITBLK-Struktur in ihrem ob_spec-Feld. Die BITBLK-Struktur ist wie folgt definiert:

bitblk$=MKL$(VARPTR(bi_pdata$))+MKI$(bi_wb)+MKI$(bi_hl)+
        MKI$(bi_x)+MKI$(bi_y)+MKI$(bi_color)
bi_pdata

sollte ein monochromes Bitmap-Bild enthalten.

bi_wb

gibt die Breite (in Bytes) des Bildes an. Alle BITBLK-Bilder müssen ein Vielfaches von 16 Pixel breit sein, daher muss dieser Wert gerade sein.

bi_hl

Gibt die Höhe des Bildes in Zeilen an.

bi_x und bi_y

werden als Pixel-Offsets in bi_pdata verwendet. Alle Daten, die vor diesen Koordinaten auftreten, werden ignoriert.

bi_color

ist ein Standardfarbwort, bei dem die Füllfarbe die Farbe angibt, in der das Bild dargestellt wird.

ICONBLK

Das ob_spec Feld von G_ICON-Objekten zeigt auf eine ICONBLK-Struktur wie unten definiert:

iconblk$=MKL$(VARPTR(ib_pmask$))+MKL$(VARPTR(ib_pdata$))+MKL$(VARPTR(ib_ptext$))+
         MKI$(ib_char)+MKI$(ib_xchar)+MKI$(ib_ychar)+
         MKI$(ib_xicon)+MKI$(ib_yicon)+MKI$(ib_wicon)+MKI$(ib_hicon)+
	 MKI$(ib_xtext)+MKI$(ib_ytext)+MKI$(ib_wtext)+MKI$(ib_htext)
ib_pmask und ib_pdata

enthalten jeweils die monochrome Maske und die Bilddaten.

ib_ptext

ist ein String-Zeiger auf den Symboltext.

ib_char

definiert das Symbolzeichen (für Laufwerkssymbole) und die Vorder- und Hintergrundfarbe des Symbols wie folgt:

Table 2. ib_char

Bits 15-12

Bits 11-8

Bits 7-0

Icon Foreground Color

Icon Background Color

ASCII Character (or 0 for no character).

ib_xchar und ib_ychar

Geben die Position des Buchstabens relativ zu ib_xicon und ib_yicon an.

ib_xicon und ib_yicon

Geben die Position des Symbols relativ zu ob_x und ob_y des Objekts an.

ib_wicon und ib_hicon

Geben die Breite und Höhe des Symbols in Pixel an. Wie bei Bildern müssen Symbole ein Vielfaches von 16 Pixel breit sein.

ib_xtext und ib_ytext

Geben die Position der Textzeichenfolge relativ zu ob_x und ob_y des Objekts an.

ib_wtext und ib_htext

Geben die Breite und Höhe des Symboltextbereichs an.

CICONBLK

Das G_CICON-Objekt enthält in seinem ob_spec Feld einen Zeiger auf eine CICONBLK-Struktur, wie unten definiert:

ciconblk$=monoblk$+MKL$(VARPTR(mainlist$))
monoblk

enthält ein monochromes Symbol, das dargestellt wird, wenn ein Farbsymbol, das den Anzeigeparametern entspricht, nicht gefunden werden kann. Außerdem werden der Symboltext, die Zeichen, die Größe und die Positionierungsdaten des einfarbigen Symbols immer auch für das farbige Symbol verwendet.

mainlist

enthält die erste CICON-Struktur in einer verknüpften Liste von Farbsymbolen für verschiedene Auflösungen. CICON | ist wie folgt definiert:

cicon$=MKI$(num_planes)+MKL$(VARPTR(col_data$))+MKL$(VARPTR(col_mask$))+
       MKL$(VARPTR(sel_data$))+MKL$(VARPTR(sel_mask$))+
       MKL$(VARPTR(cicon2$))
num_planes

gibt die Anzahl der Bitebenen an, die dieses Farbsymbol enthält.

col_data und col_mask

enthalten die Symboldaten und die Maske für das nicht ausgewählte Symbol. Entsprechend

sel_data und sel_mask

enthält die Symboldaten und die Maske für das ausgewählte Symbol.

cicon2$

enthält die nächste Farbsymboldefinition. Verwenden Sie MKL$(0) wenn nicht mehr verfügbar sind.

Die GUI-Bibliothek durchsucht das CICONBLK-Objekt nach einem Farbsymbol mit der gleichen Anzahl von Farbebenen wie der Bildschirm. Wenn keine gefunden wird, verwendet die GUI-Bibliothek einfach das monochrome Symbol.

APPLBLK

G_PROGDEF-Objekte ermöglichen es Programmierern, benutzerdefinierte Objekte zu definieren und diese nahtlos in ein Objektbaum mit einzubunden. Das ob_spec Feld der G_PROGDEF-Objekte enthält einen Zeiger auf ein APPLBLK Datenstruktur wie unten definiert:

applblk$=MKL$(SYM_ADR(#1,"function"))+MKL$(ap_parm)

Das erste ist ein Zeiger auf eine benutzerdefinierte Routine, die das Objekt zeichnen wird. Diese Routine muss eine c-Funktion sein, die mit dem LINK-Befehl mit dem X11-Basic Programm verknüpft werden muss. Der Routine wird ein Zeiger auf eine PARMBLK-Struktur übergeben, die die Informationen enthält, die zum Zeichnen des Objekts benötigt werden. ap_parm ist ein benutzerdefinierter Wert, der wie folgt in die PARMBLK-Struktur kopiert wird:

typedef struct parm_blk {
        OBJECT          *tree;
        short            pb_obj;
        short            pb_prevstate;
        short            pb_currstate;
        short            pb_x;
        short            pb_y;
        short            pb_w;
        short            pb_h;
        short            pb_xc;
        short            pb_yc;
        short            pb_wc;
        short            pb_hc;
        long             pb_parm;
} PARMBLK;
tree

zeigt auf den OBJEKT-Baum des Objekts, das gezeichnet wird. Das Objekt hat den Index pb_obj innerhalb des Baums. Der Routine wird das alte ob_state des Objekts übergeben in pb_prevstate und das neue ob_state des Objekts in pb_currstate. Wenn pb_prevstate und pb_currstate gleich sind, dann soll das Objekt vollständig gezeichnet werden, ansonsten ist nur soviel Neu-Zeichnung notwendig, um das Objekt von pb_prevstate in den neuen Zustand pb_currstate zu bringen.

pb_x, pb_y`, pb_w und pb_h

geben die Bildschirmkoordinaten des Objekts an.

pb_xc, pb_yc, pb_wc und `pb_hc

geben das Clipping-Rechteck an.

pb_parm

enthält eine Kopie des ap_parm-Werts in der APPLBLK-Struktur.

Die benutzerdefinierte Routine soll einen Wert zurückgeben, der alle verbleibenden ob_state-Bits enthält, die die GUI-Bibliothek nachträglich über das benutzerdefinierte Objekt zeichnen soll.

16.2.2. Dialogfelder und Formulare

Dialogfelder sind modale Formen der Benutzereingabe. Dies bedeutet, dass keine weitere Interaktion zwischen dem Benutzer und der Anwendung stattfinden kann, bis die Anforderungen des Dialogfelds erfüllt und der Dialog beendet sind. Ein normales Dialogfeld besteht aus einem Objektbaum mit einer Box als Wurzel-Objekt und einer beliebigen Anzahl anderer Steuerelemente, die Benutzereingaben akzeptieren. Sowohl ALERT-Meldungen als auch die Dateiauswahl (FILESELECT) sind Beispiele für Dialogfelder.

Die Funktion form_do() stellt die einfachste Methode zur Verwendung eines Dialogfelds dar. Sie übernimmt die Kontrolle der Maus und der Tastatur und managed die Funktion des Dialogs mit dem Benutzer. Konstruieren Sie einfach einen OBJECT-Baum mit mindestens einem EXIT- oder TOUCHEXIT-Objekt und rufen Sie dann form_do() auf.

Vorher sollten Sie das Dialogfeld mit der Funktion objc_draw() auf dem Bidschirm angezeigt haben. Vielleicht möchten Sie auch den Dialog mit form_center() zuvor zentrieren und den Hintergrund mit form_dial() speichern und nach Beendigung des Dialogs wiederherstellen.

Alle Interaktion mit dem Dialog, Eingabe-Felder, Optionsschaltflächen und auswählbare Objekte werden von der X11-Basic selbstständig bedient, bis der Benutzer ein EXIT- oder TOUCHEXIT-Objekt anwählt.

16.3. The gui file format

Bei dem Dateiformat .gui handelt es sich im Wesentlichen um eine ASCII-Darstellung der ATARI ST-Ressourcendateien (.rsc). Diese können so in X11-Basic-Code konvertiert werden, der dann Nachrichtenfelder und Formulare beinhalten kann. Der Konverter gui2bas(1) macht genau das. Zur Konvertierung von ATARI ST-Ressourcendateien in *.gui-Dateien gibt es auch einen praktischen Konverter. Siehe rsc2gui(1).

Eine *.gui-Datei besteht aus Zeilen und Blöcken, die Objekte spezifizieren und ihre hierarchischen Abhängigkeiten enthalten.

Das generische Format eines solchen Objekts ist:

label: TYPE(variables) {
 ... block ...
}

Das Label ist optional und gibt dem Objekt einen Namen. Je nach TYPE des Objekts werden eine oder mehrere Variablen als durch Kommas getrennte Liste in Klammern angegeben.

Jedes Objekt kann einen Block mit { am Ende der Zeile beginnen. Innerhalb dieses Blocks können ein oder mehrere Objekte definiert werden, die dann als Unterobjekte desjenigen betrachtet werden, der den Block geöffnet hat. Der Block wird mit einem } in einer einzigen Zeile geschlossen.

Beispiel:
' Little selector box  (c) Markus Hoffmann    07.2003
' convert this with gui2bas !
' as an example for the use of the gui system
' with X11-Basic

BOX(X=0,Y=0,W=74,H=14, FRAME=2, FRAMECOL=1, TEXTCOL=1, BGCOL=0, PATTERN=0, TEXTMODE=0, STATE=OUTLINED+) {
  BOXTEXT(X=2,Y=1,W=70,H=1, TEXT="Select option ...", FONT=3, JUST=2, COLOR=4513, BORDER=253, STATE=SHADOWED+)
  BOX(X=2,Y=3,W=60,H=10, FRAME=-1, FRAMECOL=1, TEXTCOL=1, BGCOL=0, PATTERN=0, TEXTMODE=0) {
    FTEXT(X=1,Y=1,W=30,H=1,COLOR=4513,FONT=3,BORDER=1,TEXT="Line 1",
          PTMP="_______________________________________",
          PVALID="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", FLAGS=EDITABLE)
    FTEXT(X=1,Y=2,W=30,H=1,COLOR=4513,FONT=3,BORDER=1,TEXT="",
          PTMP="_______________________________________",
          PVALID="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", FLAGS=EDITABLE)
    FTEXT(X=1,Y=3,W=30,H=1,COLOR=4513,FONT=3,BORDER=1,TEXT="",
          PTMP="_______________________________________",
          PVALID="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", FLAGS=EDITABLE)
    FTEXT(X=1,Y=4,W=30,H=1,COLOR=4513,FONT=3,BORDER=1,TEXT="",
          PTMP="_______________________________________",
          PVALID="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", FLAGS=EDITABLE)
    BOX(X=2,Y=6,W=50,H=3, FRAME=-1, FRAMECOL=1, TEXTCOL=1, BGCOL=1, PATTERN=5,
          TEXTMODE=0) {
      BUTTON(X=2,Y=1,W=4,H=1, TEXT="ON",STATE=SELECTED,
             FLAGS=RADIOBUTTON+SELECTABLE,FRAME=2, FRAMECOL=1, TEXTCOL=1,
             BGCOL=1, PATTERN=0, TEXTMODE=0)
      BUTTON(X=8,Y=1,W=4,H=1, TEXT="OFF",FLAGS=RADIOBUTTON+SELECTABLE,FRAME=2,
             FRAMECOL=1, TEXTCOL=1, BGCOL=1, PATTERN=0, TEXTMODE=0)
    }
  }
  ok:	  BUTTON(X=65,Y=4,W=7,H=4, TEXT="OK", FLAGS=SELECTABLE+DEFAULT+EXIT)
  cancel: BUTTON(X=65,Y=9,W=7,H=4, TEXT="CANCEL", FLAGS=SELECTABLE+EXIT+LASTOB+)
}

16.4. Menus

Die meisten Anwendungen verwenden eine Menüleiste, damit der Benutzer durch Programmoptionen navigieren kann.

Hier ist ein einfaches Beispielprogramm, das die Handhabung eines Dropdown-Menüs demonstriert.

' Test-program for Drop-Down-Menus
'
DIM field$(50)
FOR i=0 TO 50
  READ field$(i)
  EXIT IF field$(i)="***"
NEXT i
oh=0
field$(i)=""
DATA "INFO","  Menutest"
DATA "---------------"
DATA "- Access.1","- Access.2","- Access.3","- Access.4","- Access.5"
DATA "- Access.6",""
DATA "FILE","  new","  open ...","  save","  save as ...","--------------"
DATA "  print","--------------","  Quit",""
DATA "EDIT","  cut","  copy","  paste","----------","  help1","  helper"
DATA "  assist",""
DATA "HELP","  online help","--------------","  edifac","  editor","  edilink"
DATA "  edouard",""
DATA "***"

grau=GET_COLOR(32000,32000,32000)
COLOR grau
PBOX 0,0,640,400
MENUDEF field$(),menuaction
DO
  PAUSE 0.05
  MENU
LOOP
QUIT

PROCEDURE menuaction(k)
  LOCAL b
  IF (field$(k)="  Quit") OR (field$(k)="  exit")
    QUIT
  ELSE IF field$(k)="  online help"
    oh=not oh
    MENUSET k,4*abs(oh)
  ELSE IF field$(k)="  Menutest"
    ~FORM_ALERT(1,"[0][- Menutest -||(c) Markus Hoffmann 2001|X11-Basic V.1.03][ OK ]")
  ELSE
    PRINT "MENU selected ";k;" contents: ";field$(k)
    b=FORM_ALERT(1,"[1][--- Menutest ---||You selected item (No. "+str$(k)+ \
                   "),| for which was no|function defined !][ OK |disable]")
    IF b=2
      MENUSET k,8
    ENDIF
  ENDIF
RETURN

17. WEB Programmierung

In diesem Kapitel wird erläutert, wie Sie X11-Basic-Programme für WEB-Schnittstellen verwenden können. Insbesondere durch die Verwendung sogenannter CGI-Scripts.

17.1. Was ist CGI?

CGI steht für Common Gateway Interface — ein Begriff, den Sie nicht wirklich kennen müssen. Kurz gesagt definiert CGI, wie Webserver und Webbrowser Informationen aus HTML-Formularen auf Webseiten verarbeiten. Dies bedeutet, dass anstelle des WEB-Servers, der statische Webseiten an die Clients sendet, ein Programm, typischerweise ein CGI-Skript genannt, aufgerufen werden kann, um die Seite zu dem Zeitpunkt zu erzeugen, zu dem die Anfrage empfangen wurde. Diese CGI-Skripte ergreifen einige Maßnahmen und senden dann eine Ergebnisseite an den Webbrowser des Benutzers zurück. Die Ergebnisseite kann bei jeder Ausführung des Programms anders aussehen.

Und diese Programme können X11-Basic-Programme sein.

17.1.1. Konfiguration

  1. Alle X11-Basic-Skripte müssen mit der folgenden Anweisung in der ersten Zeile beginnen:

    #!/usr/bin/xbasic

    Da Unix keine speziellen Dateiendungen für Programme hat, müssen Sie so dem Betriebsystem (Unix) mitteilen, dass es sich bei dieser Datei um ein X11-Basic-Programm handelt und dass es vom X11-Basic-Interpreter xbasic ausgeführt werden soll. Dies funktioniert genauso wie bei Shell-Skripten. Der X11-Basic Interpreter xbasic befindet sich nach der Installation normalerweise im Verzeichnis /usr/bin. Dies kann bei einigen Systemen aber auch anders sein. Wenn Sie nicht sicher sind, wo die ausführbare Datei xbasic ist, geben Sie which xbasic in die Befehlszeile ein und es gibt Ihnen den Pfad zurück.

  2. Alle Skripte müssen als ausführbar markiert sein.

    Ausführbare Dateien sind solche, die Maschinenanwewisungen oder Code für einen Interpreter wie xbasic enthalten. Um eine Datei als ausführbar zu markieren, müssen Sie die Dateiberechtigungen ändern. Dies geschieht mit dem folgenden Befehl (aus einem Terminalfenster):

    chmod 755 filename.bas

    Die Nummer 755 ist die Dateizugriffsmaske. Die erste Ziffer ist Ihre Erlaubnis; es ist 7 für den vollen Zugriff. Die Einstellungen für andere sind 5 zum Lesen und Ausführen (aber nicht verändern).

  3. Die allererste PRINT-Anweisung in einem X11-Basic CGI-Skript, das HTML zurückgibt, muß sein:

    PRINT "Content-type: text/html"+CHR$(13)
    PRINT ""+CHR$(13)
    FLUSH

    Wenn Ihr X11-Basic-Skript HTML-Daten zurückgibt, müssen Sie dies als erste PRINT-Anweisung haben, um dem Webserver mitzuteilen, dass es sich um eine HTML-Datei handelt. Es müssen zwei Zeilenendezeichen (CR + LF) verwendet werden (das erklärt das zusätzliche CHR$(13)), damit dies funktioniert. Die FLUSH-Anweisung stellt sicher, dass diese Anweisung an den Webserver gesendet wird. Danach kommt normalerweise ein

    PRINT "<HTML><BODY>"
    .... und so weiter......
  4. Beenden Sie das Programm unbedingt mit QUIT.

    Ansonsten bleibt das cgi-Programm als Zombie im Speicher des Servers.

  5. Verwenden Sie immer die POST-Methode mit HTML-Formularen,

    Es gibt zwei Möglichkeiten, um Informationen vom Client zurück zum Webserver zu bekommen. Die GET-Methode übernimmt alle Daten aus den Formularen und verknüpft sie mit dem Ende der URL. Diese Information wird dann als Umgebungsvariable QUERY_STRING an das CGI-Programm übergeben. Da die GET-Methode eine Beschränkung auf 1024 Zeichen hat, empfiehlt es sich, die POST-Methode zu verwenden. Diese nimmt die Daten und sendet sie zusammen mit der Anfrage an den Webserver, ohne dass der Benutzer die hässlichen Zeichenfolgen in der URL sieht. Diese Information wird an das CGI-Programm über die Standard-Eingabe übergeben, von dem das CGI-Programm leicht (mit LINEINPUT) lesen kann. Stellen Sie sicher, dass Ihr HTML-Formular-Tag METHOD=POST hat, um die POST-Methode zu verwenden (keine Anführungszeichen).

  6. HTML-Formulare müssen auf das auszuführende CGI-Skript verweisen.

    In Ihrem FORM-Tag gibt es ein ACTION-Attribut. Dies ist wie das HREF-Attribut für einen Link. Es sollte die URL des CGI-Programms sein, an das die Formulardaten gesendet werden sollen. Normalerweise ist dies ACTION="/cgi-bin/filename.bas".

  7. X11-Basic-CGI-Dateien müssen normalerweise im Verzeichnis cgi-bin Ihres Webservers abgelegt werden.

    Jeder Webserver hat ein Wurzel-Verzeichnis. Dies ist das höchste Verzeichnis, auf das Ihre HTML-Dateien zugreifen können. (Sie möchten nicht, dass Clients in der Lage sind, Ihr gesamtes System zu durchsuchen.). In diesem Verzeichnis befindet sich normalerweise ein weiteres namens cgi-bin, in dem alle CGI-Programme abgelegt werden. Nur dort dürfen sie gestartet werden. Einige Web-Service-Provider geben jedem Benutzer ein eigenes lokales cgi-Verzeichnis in seinem Home-Verzeichnis, in das sie ihre CGI-Skripte legen können. Wenn dies der Fall ist, verwenden Sie stattdessen also dieses Verzeichnis.

17.2. Wie CGI funktioniert

Wenn ein Benutzer einen Link zu einem Gateway-Skript ansurft, werden Daten an den Server gesendet. Der Server formatiert diese Daten in Umgebungsvariablen und prüft, ob zusätzliche Daten über den Standard-Eingabestream übermittelt wurden. Die Umgebungsvariablen können dann im CGI-Skript ausgewertet werden.

17.2.1. Environment Variables

Eingangsdaten für CGI-Skripte werden normalerweise in Umgebungsvariablen übergeben. Die Daten werden vom Browser übergeben, der die Seite angesurft hat.

Umgebungsvariablen unterscheiden zwischen Groß- und Kleinschreibung und werden normalerweise wie in diesem Abschnitt beschrieben verwendet. Einige häufig verwendetete standartisierte (und plattformunabhängige) Umgebungsvariablen sind in der folgenden Tabelle aufgeführt:

Variable

Bedeutung

AUTH_TYPE

Gibt die Authentifizierungsmethode an und wird verwendet, um den Zugriff eines Benutzers zu überprüfen.

CONTENT_LENGTH

Länge der Datenzeichenfolge als numerischen Wert.

CONTENT_TYPE

Der MIME-Typ der Daten.

GATEWAY_INTERFACE

Gibt an, welche Version des CGI-Standards der Server verwendet.

HTTP_ACCEPT

Gibt die MIME-Typen an, die der Browser akzeptiert, wenn sie über den Server an das Gateway-Skript übergeben werden.

HTTP_USER_AGENT

Gibt den Typ des Browsers an, der zum Senden der Anfrage verwendet wurde.

PATH_INFO

Identifiziert die zusätzlichen Informationen in der URL nach der Identifizierung des CGI-Skripts.

PATH_TRANSLATED

Wird vom Server basierend auf der Variablen PATH_INFO festgelegt. Der Server übersetzt die Variable PATH_INFO in diese Variable.

QUERY_STRING

Anfragezeichenfolge (wenn die URL eine Anfragezeichenfolge enthält).

REMOTE_ADDR

Identifiziert die Internetprotokolladresse des Remotecomputers, der die Anforderung stellt.

REMOTE_HOST

Name des Computers, der die Anforderung stellt.

REMOTE_IDENT

Machinenidentifikation des Computers, der die Anforderung stellt.

REMOTE_USER

Benutzername zur Authentifizierung des Benutzers

REQUEST_METHOD

Gibt die Methode an, mit der die Anforderung durchgeführt wurde.

SCRIPT_NAME

Identifiziert den virtuellen Pfad zum ausgeführten Skript.

SERVER_NAME

Identifiziert den Server anhand seines Hostnamens, Alias oder seiner IP-Adresse.

SERVER_PORT

Gibt die Portnummer an, an der der Server die Anforderung erhalten hat.

SERVER_PROTOCOL

Gibt das Protokoll der an den Server gesendeten Anforderung an.

AUTH_TYPE

Die `AUTH_TYPE'-Variable ermöglicht die Zugriffssteuerung für geschützte Bereiche des Webservers und kann nur auf Servern verwendet werden, die die Benutzerauthentifizierung unterstützen. Wenn ein Bereich der Website Zugriffssteuerung hat, ist die 'AUTH_TYPE'-Variable auf einen Wert gesetzt, der das verwendete Authentifizierungsschema angibt. Z.B. "Basic".

Mit diesem Mechanismus kann der Server Nutzernamen und Passwort abfragen und überprüfen. Dazu legt der Server einen Wert für die Variable AUTH_TYPE fest und der Client liefert einen passenden Wert. Der nächste Schritt besteht darin, den Benutzer zu authentifizieren. Unter Verwendung des zugrundeliegenden Authentifizierungsschemas muss der Browser des Benutzers Authentifizierungsinformationen bereitstellen, die den Benutzer eindeutig identifizieren. Diese Information enthält eine Benutzer-ID und ein Passwort.

CONTENT_LENGTH

Die CONTENT_LENGTH-Variable bietet eine Möglichkeit, die Länge der Datenfolge zu ermitteln, die der Client dem Server über den Standard-Eingabestream übermitteln möchte. Der Wert der Variablen entspricht der Anzahl der Zeichen in den mit der Anfrage übergebenen Daten. Wenn keine Daten übergeben werden, hat die Variable keinen Wert.

CONTENT_TYPE

Die Variable CONTENT_TYPE gibt den MIME-Typ der Daten an. Diese Variable wird nur gesetzt, wenn angehängte Daten mit dem Standardeingabe- oder -ausgangsstrom übergeben werden. Der der Variablen zugewiesene Wert identifiziert den zugrundeliegenden MIME-Typ und Subtyp wie folgt:

Typ

Beschreibung

application

Binärdaten welche als Programm ausgeführt werden können oder mit einer anderen application verwendet werden.

audio

Ein Sound-file welches auf einem Ausgabegerät abgespielt werden kann.

image

Ein Bild

message

Eine eingekapselte e-mail-Nachricht

multipart

Daten, welche aus meheren Teilen und möglicherweise verschiedenenen Datentypen bestehen.

text

Text-Daten

video

Ein Video-file

x-world

Experimentelle Daten für world files

MIME-Subtypen sind in drei Kategorien eingeteilt: primär, zusätzlich definiert und erweitert. Der primäre Subtyp ist der primäre Datentyp, der zur Verwendung als MIME-Inhaltstyp verwendet wird. Zusätzlich definierte Datentypen sind immer Subtypen, die offiziell als MIME-Inhaltstypen übernommen wurden. Erweiterte Datentypen sind experimentelle Subtypen, die nicht offiziell als MIME-Inhaltstypen übernommen wurden. Sie können erweiterte Subtypen leicht identifizieren, da sie mit dem Buchstaben x gefolgt von einem Bindestrich beginnen. Die folgende Tabelle listet häufige MIME-Typen und ihre Beschreibungen auf:

Typ/Subtyp

Beschreibung

application/octet-stream

Binärdaten zum Ausführen oder für eine externe Anwendung als Octet-Datenstrom.

application/pdf

Ein ACROBAT PDF Document

application/postscript

Eine Postscript-Datei

application/x-compress

Daten, die mit dem UNIX compress Programm komprimiert wurden.

application/x-gzip

Daten, die mit GNU gzip komprimiert wurden.

application/x-tar

Daten, die mit UNIX tar archiviert wurden

audio/x-wav

Eine Audio-Date im Microsoft WAV Format

image/gif

Ein Bild im gif Format

image/jpeg

Ein Bild im JPEG Format

image/tiff

Ein Bild im TIFF Format

multipart/mixed

Daten in mehreren Teilen verschiednener Formate

text/html

HTML-formatierter text

text/plain

Plain text ohne HTML Formatierungen

video/mpeg

Video im MPEG Format

Beachten Sie, dass es noch mehr als die oben aufgeführten Typen gibt.

Einige MIME-Inhaltstypen können mit zusätzlichen Parametern verwendet werden. Diese Inhaltstypen umfassen text/plain, text/html und alle mehrteiligen Nachrichtendaten. Der optionale charset-Parameter wird mit dem text/plain-Typ verwendet, um den für die Daten verwendeten Zeichensatz zu bestimmen. Wenn kein Zeichensatz angegeben wird, wird der Standardwert charset=us-ascii angenommen. Andere Werte für Zeichensatz umfassen alle Zeichensätze, die von der International Standards Organization genehmigt wurden. Diese Zeichensätze sind durch ISO-8859-1 bis ISO-8859-9 definiert und können etwa so spezifiziert werden:

 CONTENT_TYPE = text/plain; charset=iso-8859-1

Bei mehrteiligen Daten ist der Boundary-Parameter erforderlich, um die Grenzzeichenfolge anzugeben, die Nachrichtenteile trennt. Die Zeichenfolge darf 1 bis 70 Zeichen lang sein und beliebige Buchstaben, Ziffern und Leerzeichen sowie eine begrenzte Anzahl von Sonderzeichen enthalten, darf aber nicht mit einem Leerzeichen enden. Sie muss eindeutig sein und darf in den Teilen der Nachrich nicht vorkommen. So etwa sieht das dann aus:

 CONTENT_TYPE = multipart/mixed; boundary=boundary_string
GATEWAY_INTERFACE

Die Variable GATEWAY_INTERFACE gibt an, welche Version der CGI-Spezifikation der Server verwendet. Der der Variablen zugewiesene Wert identifiziert den Namen und die Version der verwendeten Spezifikation wie folgt:

 GATEWAY_INTERFACE = name/version

Die Version der CGI-Spezifikation ist 1.1. Ein Server, der dieser Version entspricht, würde die GATEWAY_INTERFACE-Variable also wie folgt setzen:

 GATEWAY_INTERFACE = CGI/1.1
HTTP_ACCEPT

Die Variable HTTP_ACCEPT definiert die Datentypen, die der Client akzeptiert. Die akzeptablen Werte werden jeweils als "Typ/Subtyp"-Paare ausgedrückt. Jedes Typ/Untertyp-Paar ist durch Kommas getrennt.

HTTP_USER_AGENT

Die Variable HTTP_USER_AGENT identifiziert den Typ des Browsers, der zum Senden der Anfrage verwendet wird. Die zulässigen Werte werden als "Softwaretyp/Version" oder Bibliothek/Version ausgedrückt.

PATH_INFO

Die PATH_INFO-Variable gibt zusätzliche Pfadinformationen an und kann verwendet werden, um zusätzliche Informationen an ein Gateway-Skript zu senden. Die zusätzlichen Pfadinformationen folgen der URL des verwiesenen Gateway-Skripts. Im Allgemeinen ist diese Information ein virtueller oder relativer Pfad zu einer Ressource, die der Server interpretieren muss.

PATH_TRANSLATED

Server übersetzen die PATH_INFO-Variable in die PATH_TRANSLATED-Variable, indem sie den Verzeichnispfad des Standard-Web-Dokuments vor die zusätzlichen Pfadinformationen einfügen.

QUERY_STRING

Die Variable QUERY_STRING gibt eine URL-codierte Suchzeichenfolge an. Sie legen diese Variable fest, wenn Sie die GET-Methode zum Senden eines Formulars verwenden. Die Abfragezeichenfolge wird durch ein Fragezeichen von der URL getrennt. Der Benutzer sendet alle Informationen nach dem Fragezeichen, die die URL von der Abfragezeichenfolge trennen. Hier ein Beispiel:

URL:
 /cgi-bin/doit.cgi?word1+word2+word3

Gleichheitszeichen trennen die von der Seite vorgegebenen Schlüsselwörter von den vom Benutzer eingegebenen Werten. Im folgenden Beispiel ist das Schlüsselwort "key" und der vom Benutzer eingegebene Wert "never":

URL:
 /cgi-bin/doit.cgi?response=never

Und-Symbole (&) trennen Schlüssel/Werte-Paare. Im folgenden Beispiel erhält der erste Schlüssel "response" den Wert "sometimes" und der zweite Schlüssel "reason" den Wert "I+am+not+really+sure":

URL:
 /cgi-bin/doit.cgi?response=sometimes&reason=I+am+not+really+sure

Schließlich wird das Prozentzeichen verwendet, um Sonderzeichen zu kennzeichnen. Dem Prozentzeichen folgt ein Escape-Code für ein Sonderzeichen, ausgedrückt als hexadezimaler Wert. So könnte die vorherige Abfragezeichenfolge mithilfe des Escape-Codes für ein Apostroph umgeschrieben werden:

URL:
 /cgi-bin/doit.cgi?response=sometimes&reason=I%27m+not+really+sure
REMOTE_ADDR

Die Variable REMOTE_ADDR wird auf die Internetprotokoll (IP)-Adresse des Remote-Computers gesetzt, der die Anfrage stellt.

REMOTE_HOST

Die Variable REMOTE_HOST gibt den Namen des Host-Rechners an, der eine Anfrage stellt. Diese Variable wird nur gesetzt, wenn der Server diese Informationen über eine Anfrage an den Nameserver ermitteln kann.

REMOTE_IDENT

Die REMOTE_IDENT-Variable identifiziert den Benutzer, der eine Anfrage stellt. Die Variable wird nur gesetzt, wenn der Server und der Rechner, der die Anfrage stellt, das Identifikationsprotokoll unterstützt. Darüber hinaus sind Informationen zum Benutzer nicht immer verfügbar, weshalb Sie sich nicht darauf verlassen sollten.

REMOTE_USER

Die REMOTE_USER-Variable ist der Benutzername, der vom Benutzer authentifiziert wurde, und als solche ist dies die einzige Variable, auf die Sie sich verlassen können, um einen Benutzer zu identifizieren. Wie bei anderen Arten der Benutzerauthentifizierung wird diese Variable nur dann gesetzt, wenn der Server die Benutzerauthentifizierung unterstützt.

REQUEST_METHOD

Die Variable REQUEST_METHOD gibt die Methode an, mit der die Anfrage gemacht wurde. Die Methoden können "GET", "HEAD", "POST", "PUT", "DELETE", "LINK" und "UNLINK" sein.

Die Methoden GET,` HEAD` und POST sind die am häufigsten verwendeten Anforderungsmethoden. Sowohl "GET" als auch "POST" werden zum Senden von Formularen verwendet.

SCRIPT_NAME

gibt den virtuellen Pfad zum ausgeführten Skript an. Diese Information ist nützlich, wenn das Skript ein HTML-Dokument generiert, das auf das Skript verweist.

SERVER_NAME

identifiziert den Server anhand seines Hostnamens, Alias oder seiner IP-Adresse. Diese Variable ist immer gesetzt.

SERVER_PORT

gibt die Portnummer an, auf der der Server die Anfrage erhalten hat. Diese Information kann bei Bedarf von der URL zum Skript interpretiert werden. Die meisten Server verwenden jedoch den Standardport 80 für HTTP-Anforderungen.

SERVER__PROTOCOL

identifiziert das Protokoll, das zum Senden der Anfrage verwendet wird. Der der Variablen zugewiesene Wert identifiziert den Namen und die Version des verwendeten Protokolls. Das Format ist "Name/Version", z.B. HTTP/1.0.

17.2.2. CGI Standard Input

Die meisten Daten, die an einen Webserver gesendet werden, werden zum in Umgebungsvariablen gespeichert, aber nicht alle Eingaben passen in eine Umgebungsvariable. Wenn ein Benutzer Daten übermittelt, die von einem Gateway-Skript verarbeitet werden sollen, werden diese Daten als URL-codierte Suchzeichenfolge oder über den Standard-Eingabestream empfangen. Der Server weiß, wie diese Daten verarbeitet werden, da die Methode (POST oder GET in HTTP 1.0) zum Übermitteln der Daten verwendet wird.

Das Senden von Daten über die Standardeingabe ist der direkteste Weg zum Senden von Daten. Der Server teilt dem Gateway-Skript mit, wie viele Bytes aus der Standardeingabe gelesen werden sollen. Das Skript öffnet dann den Standard-Eingabestream und liest die angegebene Datenmenge. Lange URL-codierte Suchzeichenfolgen können abgeschnitten werden. Daten, die über den Standard-Eingabestream gesendet werden, bleiben immer vollständig erhalten, egal, wie lang. Folglich ist der Standard-Eingabestrom der bessere Weg, um Daten zu übergeben.

17.2.3. Welche CGI Eingabe-Daten-Methode soll man nutzen?

Sie können eine Methode für die Datenübermittlung angeben, wenn Sie Ihre Web-Formulare erstellen. Es gibt zwei Eingabemethoden für Formulare. Die HTTP-GET-Methode verwendet URL-codierte Suchzeichenfolgen. Wenn ein Server eine URL-codierte Suchzeichenfolge erhält, weist der Server den Wert der Suchzeichenfolge der Variable QUERY_STRING zu.

Die HTTP-POST-Methode verwendet die Standard-Eingabeströme. Wenn ein Server Daten über den Standard-Eingabestream empfängt, ordnet der Server der Variablen CONTENT_LENGTH deren Länge in Bytes zu. Vom CGI-Script aus können die Daten dann z.B. mit INPUT$() gelesen werden.

Vielleicht möchten Sie einige der X11-Basic Beispielprogramme studieren, um die für Ihren Einsatzzweck geeignete Methode zu finden.

17.2.4. Die Ausgaben des CGI-Skripts

Nachdem das Skript die Eingabedaten gelesen und verarbeitet hat, sollte das Skript irgendeine Art von Ausgabe an den Server zurückgeben. Der Server wird dann die Ausgabe an den Client zurücksenden. Im Allgemeinen hat diese Ausgabe die Form einer HTTP-Antwort. Also eine Kopfzeile gefolgt von einer Leerzeile und dann gefolgt vom eigentlichen Textkörper, der dann den HTML-Code enthalten kann. Der Hauptteil kann beispielsweise ein HTML-Dokument enthalten, das der Client anzeigen soll.

17.2.5. CGI Kopfzeilen

CGI-Kopfzeilen (Header) enthalten Anweisungen für den Server. Derzeit sind diese drei Server-Direktiven gültig:

  • Content-Type

  • Location

  • Status

Ein einzelner Header kann eine oder alle Serverdirektiven enthalten. Ihr CGI-Skript gibt diese Anweisungen an den Server aus. Obwohl auf den Header eine Leerzeile folgt, die den Header vom Hauptteil trennt, muss die Ausgabe keinen Hauptteil enthalten.

Das Feld Content-Type in einem CGI-Header identifiziert den MIME-Typ der Daten, die Sie an den Client zurücksenden. Normalerweise ist die Datenausgabe eines Skripts ein vollständig formatiertes Dokument, z.B. ein HTML-Dokument. Sie könnten diese Ausgabe in der Kopfzeile wie folgt angeben:

Content-Type: text/html

Aber wenn Ihr Programm andere Daten wie Bilder etc. ausgibt, sollten Sie natürlich den entsprechenden Inhaltstyp angeben.

Location

Die Ausgabe Ihres Skripts muss kein im Skript erstelltes Dokument sein. Sie können auf jedes Dokument im Web verweisen, indem Sie das Feld Location verwenden. Das Feld Location kann auf eine Datei verweisen, die anhand ihrer URL angegeben wird. Server verarbeiten diese Referenzen entweder direkt oder indirekt abhängig vom Speicherort der Datei. Wenn der Server die Datei lokal finden kann, übergibt er die Datei an den Client. Andernfalls leitet der Server die URL an den Client um, und der Client muss die Datei selbst abrufen. Sie können einen Speicherort in einem Skript wie folgt angeben:

 Location: http://www.new-jokes.com/
Status

Das Feld Status übergibt eine Statuszeile an den Server zur Weiterleitung an den Client. Statuscodes werden als dreistelliger Code gefolgt von einem String ausgedrückt, der allgemein erklärt, was passiert ist. Die erste Ziffer eines Statuscodes zeigt den allgemeinen Status wie folgt an:

  1XX Not yet allocated
  2XX Success
  3XX Redirection
  4XX Client error
  5XX Server error

Obwohl viele Statuscodes von Servern verwendet werden, sind die Statuscodes, die Sie über Ihr CGI-Skript an einen Client übergeben, in der Regel Client-Fehlercodes. Angenommen, das Skript konnte keine Datei finden und Sie haben angegeben, dass das Skript in solchen Fällen einen Fehlercode ausgeben soll, anstatt nichts zurückzugeben. Hier ist eine Liste der Client-Fehlercodes, die Sie möglicherweise verwenden möchten:

401 Unauthorized Authentication has failed.
    Der Benutzer hat keine Zugriffsrechte auf diese Datei. Er muss sich Authentifizieren.

403 Forbidden. The request is not acceptable.
    Der Benutzer darf auf das File nicht zugreifen.

404 Not found.
    Die angegebene Datei oder Daten konnte nicht gefunden werden.

405 Method not allowed.
    Die Übertragungsmethode ist nicht erlaubt hier.

17.3. Ein Beispiel CGI Skript

Hier ist ein einfaches Beispiel-CGI-Skript, das einfach alle Informationen zurückgibt, die es vom Webserver als HTML-Seite erhält.

#!/usr/bin/xbasic
PRINT "Content-type: text/html"+CHR$(13)
PRINT ""+CHR$(13)
FLUSH
PRINT "<html><head><TITLE>Test CGI</TITLE><head><body>"
PRINT "<h1>Commandline:</h1>"
i=0
WHILE LEN(PARAM$(i))
  PRINT STR$(i)+": "+PARAM$(i)+"<br>"
  INC i
WEND
PRINT "<h1>Environment:</h1><pre>"
FLUSH      ! flush the output before another program is executed !
SYSTEM "env"
PRINT "</pre><h1>Stdin:</h1><pre>"
length=VAL(ENV$("CONTENT_LENGTH"))
IF length
  FOR i=0 TO length-1
    t$=t$+CHR$(inp(-2))
  NEXT i
  PRINT t$
ENDIF
PRINT "</pre>"
PRINT "<FORM METHOD=POST ACTION=/cgi-bin/envtest.cgi>"
PRINT "Name: <INPUT NAME=name><BR>"
PRINT "Email: <INPUT NAME=email><BR>"
PRINT "<INPUT TYPE=submit VALUE="+CHR$(34)+"Test POST Method"+CHR$(34)+">"
PRINT "</FORM>"
PRINT "<hr><h6>(c) Markus Hoffmann cgi with X11-basic</h6></body></html>"
FLUSH
QUIT

18. Quick Reference

18.1. Reservierte Variablennamen

Es gibt einige reservierte Variablen bzw. Variablennamen. Einige Schlüsselwörter funktionieren außerdem möglicherweise nicht als Variablennamen. Obwohl der Interpreter die Variablennamen nicht explizit überprüft, können Syntaxfehler bei Zuweisungen auftreten. Bitte versuchen Sie in solchen Fällen den Befehl LET. Solange sich eine Endung eines Variablennamens von einem Befehl oder Schlüsselwort unterscheidet, kann sie im Allgemeinen als Name verwendet werden.

Reservierte und Systemvariablen sind:

Typ

Name

Beschreibung

int

ANDROID?

ergibt -1 auf Android Systemen, sonst 0

int

COLS

Anzahl der Zeichen pro Zeile im Text Terminal

int

CRSCOL

Textcursorposition: Aktuelle Spalte im Text Terminal

int

CRSLIN

Textcursorposition: Aktuelle Zeile im Text Terminal

flt

CTIMER

CPU System Timer (in Sekunden) in Einheiten der CPU-Zeit

int

ERR

Fehlernummer des zuletzt aufgetretenen Fehlers

int

FALSE

Konstante: 0

int

GPS?

-1 wenn ein GPS verfügbar ist, sonst 0

flt

GPS_ALT

Höhe über Meeresspiegel in m vom GPS

flt

GPS_LAT

Geografische Breite in Grad vom GPS

flt

GPS_LON

Geografische Länge in Grad vom GPS

int

MOUSEK

Zustand der Maustasten (Bitrepresentation)

int

MOUSES

Zustand der Umschalttasten Shift, Alt, Ctrl, Caps Tasten

int

MOUSEX

x-Koordinate der Mausposition relativ zum Fensterursprung

int

MOUSEY

y-Koordinate der Mausposition relativ zum Fensterursprung

int

PC

program counter: Zeilennr der nächsten auszuführenden Zeile

flt

PI

Konstante: 3.14159265359…​

int

ROWS

Anzahl der Zeilen im Text Terminal

int

SENSOR?

-1 wenn die Sensoren verfügbar sind, sonst 0

int

SP

Interner Stack Pointer (Verschachtelungstiefe)

int

STIMER

Ganzzahliger System-Timer in Sekunden

flt

TIMER

Unix System Timer in Sekunden

int

TRUE

Konstante: -1

int

UNIX?

-1 wenn das Betriebsystem UNIX-artig ist (Linux, BSD)

int

WIN32?

-1 wenn das Betriebsystem MS WINDOWS 32 bit ist

DATE$

Aktuelles Datum

FILEEVENT$

Dateisystemereignis abfragen

INKEY$

Inhalt des Tastaturpuffers

TERMINALNAME$

Name des Standard Terminals

TIME$

Aktuelle Zeit

TRACE$

Aktuelle Program Code Zeile

Beachten Sie, dass Sie diesen Variablen nichts zuweisen können. Sie haben immer ihren Wert je nach Funktion.

18.2. Bedingungen

Bedingungen und Ausdrücke sind gleich, FALSE ist definiert als 0 und TRUE als -1. Boolesche Operatoren wie AND, OR, XOR usw. werden als bitweise Operation angewendet. Auf diese Weise können sie sowohl in Ausdrücken als auch in Bedingungen verwendet werden.

18.3. Zahlen und Konstanten

Zahlenkonstanten können mit 0x vorangestellt werden, um Hexadezimalwerte darzustellen. String-Konstanten werden mit Paaren von "" markiert. Array-Konstanten haben folgendes Format: [ , , ; , ; , , ].

18.4. Operatoren

Die Rangfolge ist wie folgt definiert (höchster zuerst):

  1. () (Klammern)

  2. ^ (Hoch)

  3. * / (Multiplikation, Division)

  4. \ (Modulus, Rest)

  5. - + (Addition Subtraktion)

  6. MOD DIV (modulus, Ganzzahldivision)

  7. < > = <> ⇐ >= (Vergleichsoperatoren)

  8. AND OR XOR NOT EQV IMP (Logische Operatoren)

18.5. Matritzenoperatoren — 

Matritzenoperatoren oder allgemein Feld-Operatoren operieren auf Feldern. Je nach Feldtyp und Dimension koennen sie unterschiedliche Bedeuting haben.

Weiterhin gibt es Operatorn/Funktionen, die zwischen verschiedenen Variablenklassen Operieren: z.B.

a%=INT(b), c=DET(d()), s=SMUL(a(),b()), a=NULL(2,4,5), ...

Insbesondere sei auf den Reduktionsoperator hingewiesen: a(:,3) ist ein eindimensionaler Vektor, nämlich die Spalte Nr. 3 der Matrix a.

18.6. Abkürzungen

Im Interpreter kann jeder Befehl abgekürzt werden, solange der Befehlsparser den Befehl eindeutig identifizieren kann. Sie können also q anstelle von QUIT verwenden.

Zusätzlich gibt es Abkürzungen, die eigentlich alternative Befehle sind wie:

'                     -- Abkürzung fuer REM
?                     -- Abkürzung fuer PRINT
@                     -- Abkürzung fuer GOSUB, bzw Funktionsaufruf
~                     -- Abkürzung fuer VOID
!                     -- Kommentar hinter einer Zeile
&                     -- Indirektes Kommando

18.7. Interpreter-Kommandos

CLEAR           löscht und entfernt alle Variablen aus dem Speicher
CONT            Programmausführung fortfahren (nach STOP)
DUMP            Listet alle benutzen Variablennamen auf
DUMP "@"        Listet alle Funktionen und Prozeduren auf
DUMP ":"        Listet alle Labels auf
DUMP "#"        Listet alle offenen Dateien auf
DUMP "K"        Listet alle implementierten Kommandos auf
DUMP "F"        Listet alle internen Funktionen  auf
ECHO ON/OFF     dasselbe wie TRON * TROFF
EDIT            Ruft den Editor auf, um das Programm zu bearbeiten.
HELP <expr>     Gibt eine kurze Anleitung zum Stichwort aus.
LIST [s,e]      Listet Programmzeilen (von Zeile s bis e)
LOAD file$      Läd ein Programm
NEW             Löscht das Programm und alle Variablen aus dem Speicher.
PLIST           Gibt ein Formatiertes Listing des Programms aus
PROGRAM options Setzt den Titel des Programm und Copiler Anweisungen
QUIT            Verläßt den X11-BASIC-Interpreter (und beendet das Programm)
REM comment     Kommentar im Programm
RUN             Startet das Programm
STOP            Stoppt das Programm
SAVE [file$]    Speichert das Programm in eine Datei
TROFF           Schaltet den Trace Modus aus
TRON            Schaltet den Trace Modus an (zur Fehlersuche)
VERSION         Zeigt die X11-Basic Versionsnummer und -Datum
XLOAD           Dateiauswahl zum Laden eines Programms
XRUN            Dateiauswahl zum starten eines Programms

18.8. Kommandos für die Ablaufkontrolle

AFTER n,procedure   Ruft eine Prozedur nach n Sekunden auf
BREAK               Dasselbe wie EXIT IF TRUE
CASE const          SELECT * CASE * DEFAULT * ENDSELECT
CHAIN bas$          Ruft ein anderes X11-Basic Program auf
CONTINUE            SELECT * CASE * CONTINUE * ENDSELECT
DEFAULT             SELECT * CASE * DEFAULT * ENDSELECT
DEFFN               Definiert ein Funktionsmakro .
DO * LOOP           (Endlos-)Schleife
DOWNTO              FOR ... DOWNTO
ELSE                siehe IF * ELSE * ENDIF
ELSE IF             siehe IF * ELSE * ENDIF
END                 Programm Ende, kehrt zurueck in den Direktmodus
ENDFUNCTION         FUNCTION * ENDFUNCTION
ENDIF               IF * ELSE * ENDIF
ENDSELECT           SELECT * CASE * DEFAULT * ENDSELECT
EVERY n,procedure   Ruft eine Prozedur alle n Sekunden auf
EXIT IF a           Verlasse die Schleife wenn die Bedingung wahr ist
FOR * NEXT          For-Next-Schleife
FUNCTION * ENDFUNC  Definiere eine Funktion
GOSUB proc(...)     Rufe eine Unterroutine auf
GOTO label          Gehe zum  label
IF * ELSE * ENDIF   Bedingte Blöcke
LOOP                DO * LOOP
NEXT                FOR * NEXT
ON BREAK GOSUB proc Definiert eine Prozedur für Programmabbruch
ON ERROR GOSUB proc  Definiert eine Prozedur für Fehlerbehandlung
ON * GOSUB proc1,... Ruft je nach Wert eine Routine aus einer Liste von Prozeduren auf
ON * GOTO label1,... Verzweige zu verschiednenen Labels je nach Wert
PAUSE sec            Hält Programmausführung für sec Sekunden an
REPEAT               REPEAT * UNTIL
RESUME               Setze Programm fort nach Fehler
RETURN               Definiert Ende vom Prozedur bzw. gibt Rückgabewert
SELECT expr          SELECT * CASE * DEFAULT * ENDSELECT
UNTIL exp            REPEAT * UNTIL
SPAWN procedure      Schnüre einen neuen Thread ab

18.9. Ein-/Ausgabekommandos für die Textkonsole

BEEP                 Glockenton (auf TTY/Konsole)
BELL                 Dasselbe wie BEEP
CLS                  Lösche den  (Text)Bildschirm
FLUSH                flush output
HOME                 Textcursor in obere linke Ecke
INPUT "text";varlist Erfrage Benutzereingaben und weise Variablen zu
LINEINPUT t$         Lese ganze Zeile von Kanal/Datei/Konsole
LOCATE row,column    Platziere den Textcursor an Position Spalte/Zeile
PRINT a;b$           Gebe Text oder Daten an Konsole aus. BASIC-Standard-Befehl
PRINT AT(x,y);       Platziere den Textcursor an Position Spalte/Zeile
PRINT COLOR(x,y);    Setze Text-Farbe
PRINT TAB(x);        Platziere den Textcursor in Spalte  x
PRINT SPC(x);        Bewege den Textcursor x columns nach rechts
PRINT a USING f$     Gib eine Formatierte Zahle auf Konsole aus
PUTBACK a            Gebe ein Zeichen an Konsole zurück

18.10. Ein-/Ausgabekommandos für Dateien

BGET #f,a,n       Lese n Bytes aus Datei #f nach Adresse a
BLOAD f$,a[,l]    Lese ganzes File über Filenamen nach Addresse a
BPUT #f,a,n       Schreibe n Bytes von Addresse a in ein File/Kanal f
BSAVE f$,a,l      Soeichere l Bytes am Adresse a im Speicher in Datei f$
CHDIR path$       Wechsele aktuelles Arbeitsverzeichnis
CHMOD file$,m     Setze Datei-Berechtigungen
CLOSE [[#]n]      Schliesse offene Datei, I/O-Kanal oder Link
FLUSH [#n]        Flush Outbut
KILL file$        Lösche eine Datei
MAP               maps a file into memory
UNMAP             unmaps memory
MKDIR path$       Erstelle einen Dateiordner
OPEN m$,#n,file$  Öffne eine Datei oder Socket zum Lesen und/oder Schreiben
OUT #n,a          Gebe ein Byte an Kanal n aus
PRINT #n;         Schreibe in eine Datei oder Kanel
PUTBACK [#n,]a    Gebe ein Zeichen zurück in Datei oder Kanal
RELSEEK #n,d      Platziere den Dateizeiger auf eine neue relative Position
RENAME file$,dst$ Nenne eine Datei um bzw. verschiebe sie
RMDIR path$       Lösche einen leeren Dateiordner
SEEK #n,d         Platziere den Dateizeiger auf eine neue absolute Position
TOUCH #n          Aktualisiere den Zeitstempel eines offenen Files
WATCH file$       Beobachte Datei-Änderungen

18.11. Kommandos für Variablen

ABSOLUTE x,adr%       Weist einer Variablen x die Speicheradresse adr% zu.
ARRAYCOPY dst(),src() Kopiert ein Array (einschl. Dimensionierung)
ARRAYFILL a(),b       Füllt ein Array mit einem Wert
CLR a,b,c(),f$        Löscht Variablen inhalte: a=0;b=0;c()=[];f$=""
DEC var               Erniedrigt eine Variable um 1
DIM                   Deklariert ein Array
ERASE a()[,...]       Löscht Array (einschl. Dimensionierung)
INC a                 Erhöht Variable um 1
LET a=b               Erzwingt Zuweisung
LOCAL var[,...]       Deklariere lokale Variablen in Prozedur oder Funktion
SORT a(),n[,b()]      Sortiere ein Array
SWAP a,b              Vertausche Variableninhalte
VAR vars              Deklariere Argumente eine Funktion als Übergabe "by reference"

18.12. Kommandos für Speichermanipulation

ABSOLUTE x,adr% Weist einer Variablen x die Speicheradresse adr% zu..
BMOVE q,z,n     Kopiert einen Block von n Bytes von Addresse q nach z
DPOKE adr,word  Schreibe ein "short int word" an Speicheradresse adr
FREE adr%       Gebe einen vorher reservierten Speicherblock wieder frei
LPOKE adr,long  Schreibe ein "long int" an Speicheradresse adr
MFREE adr%      Gebe einen vorher reservierten Speicherblock wieder frei.
MSYNC adr%,l    flushes changes map memory back to disk
POKE adr,byte   Schreibe ein Byte an Speicheradresse adr
SHM_DETACH adr% Löse ein Shared Memory Segment
SHM_FREE adr%   Gebe ein Shared Memory Segment frei

18.13. Mathematik-Kommandos

ADD a,b               Dasselbe wie a=a+b, aber schneller
DEC var               Dasselbe wie var=var-1, aber schneller
DIV a,b               Dasselbe wie a=a/b, aber schneller
FFT a(),i             Schnelle Fouriertransformation auf 1D-Array
FIT x(),y()[,yerr()],n,func(x,a,b,c,...)
                      fits function to data
FIT_LINEAR x(),y()[,[xerr(),]yerr()],n,a,b[,siga,sigb,chi2,q]
                      Lineare Regression mit Fehlern
FIT_POLY x(),y(),dy(),n%,a(),m%
                      fit a polynom to datapoints
INC var               Dasselbe wie var=var+1, aber schneller
MUL a,b               Dasselbe wie a=a*b, aber schneller
SORT a(),n[,b()]      Sortiere n Werte von a() in aufsteigende Folge
SUB a,b               Dasselbe wie a=a-b, aber schneller

18.14. Sonstige Kommandos

CALL adr[,par,...]     Siehe EXEC
CONNECT #n,t$[,i%]     Verbinde mit Kanal
DATA 1,"Hallo",...     Definiert Konstanten im Programm
DELAY sec              Siehe PAUSE
ERROR n                Löse Fehler Nummer n aus
EVAL t$                Führt X11-Basic Kommando in t$ aus
EXEC adr[,var,...]     Ruft eine C Unterroutine an Adresse adr auf.
GET_LOCATION ,,,,,,,   Gibt Geografische Position des Gerätes aus
GPS ON/OFF             Schaltet GPS-Empfänger an oder aus
LINK #n,t$             Läd ein Shared Object File t$
UNLINK #n              entfernt Shared Object aus Speicher
MERGE f$               Füge ein bas-file an das aktuelle Programm an
NOP                    Tu nichts
NOOP                   Tu nichts
PAUSE sec              Hält Programmausführung für sec Sekunden an
PIPE #l,#k             Verbindet zwei Kanäle mit einer Pipe
PLAYSOUND c,s$         Spielt ein WAV Ton ab
PLAYSOUNDFILE file$    Spielt eine Tondatei ab
PROCEDURE proc(p1,...) PROCEDURE * RETURN
RANDOMIZE [seed]       Setzt den Seed für den Zufallsgenerator
READ var               Liest eine Konstante von den DATA Zeilen
RECEIVE #n,t$          Empfängt eine Nachricht von einem Socket
RESTORE [label]        Setzt den Datazeiger für READ zurück oder auf ein Label
RETURN expr            Gibt einen Wert zurück von FUNCTION
RSRC_LOAD file$        läd ein GEM rsc-File (ATARI ST)
RSRC_FREE              gibt GEM rsc-File wieder frei
SEND #n,t$             Sende eine Nachrcht über ein Socket
SENSOR ON/OFF          Schaltet die Sensoren an oder aus
SETENV t$=a$           Setzt Umgebungsvariablen (nicht implementiert)
SOUND freq             Läßt den internen Lautsprecher einen Ton ausgeben
SPLIT t$,d$,mode,a$,b$ Teilt t$ an d$ in a$ und b$
SHELL t$               Ruft eine Shell auf
SPEAK t$               Spricht den Text
SYSTEM t$              Führt ein Shell-Kommando aus
UNLINK #n              entfernt Shared Object aus Speicher
VOID a                 Berechnet Ausdruck a und vergisst das Ergebnis
WAVE c,f,              Setzt Tonkanäle für den Synthesizer
WORT_SEP               siehe SPLIT

19. Graphic commands

19.1. Drawing and painting

BOUNDARY f              Schaltet Umrandung an oder aus
BOX x1,y1,x2,y2         Zeichnet einen Rahmen/Rechteck
CIRCLE x,y,r,,          Zeichnet einen Kreis
CLIP ,,,,,              Begrenze Grafikausgabe auf rechteckigen Bereich
COLOR f[,b]             Setzt die Vordergrund- (und Hintergrund-)Farbe
COPYAREA ,,,,,          Kopiert rechteckigen Bereich
CURVE ,,,,,,,           zeichne eine Qubische Bezier-Kurve
DEFFILL c,a,b           Setze Füllmuster
DEFLINE a,b             Setze Linienbreite und -Typ
DEFMARK c,a,g           Setze Farbe, Größe und Typ für POLYMARK
DEFMOUSE i              Setze das Maus-Cursor-Erscheinungsbild
DEFTEXT c,s,r,g         Setze Text-Eigenschaften für LTEXT
DRAW [[x1,y1] TO] x2,y2 Zeichnet eine Line von (x1,y1) nach (x2,y2)
ELLIPSE x,y,a,b[,a1,a2] Zeichnet eine Ellipse
FILL x,y                Flächen füllen (flood fill)
GET x,y,w,h,g$          Ausschnitt des Grafikbildschirms als Bitmap in g$ speichern
GPRINT                  wie PRINT, aber es wird auf dem Grafikbildschirm ausgegeben
GRAPHMODE mode          Setze den Grafik-Modus
LINE x1,y1,x2,y2        Zeichnet eine Linie
LTEXT x,y,t$            Liniengrafik-Textausgabe
PBOX x1,y1,x2,y2        Zeichnet ein gefülltes Rechteck
PCIRCLE x,y,r[,a1,a2]   Zeichnet einen gefüllten Kreis
PELLIPSE x,y,a,b[,a1,a2] Zeichnet eine gefüllte Ellipse
PLOT x,y                Zeichnet einen Punkt
POLYLINE n,x(),y()      Zeichnet ein Vieleck aus Linien
POLYFILL n,x(),y()      Zeichnet ein gefülltes Vieleck (Polygon)
POLYMARK n,x(),y()      Zeichnet Eckpunkte eines Vielecks
PRBOX x1,y1,x2,y2       Zeichnet ein gefülltes Rechteck mit abgerundeteten Ecken
PUT x,y,g$              Zeichnet eine Grafik an Position
PUT_BITMAP t$,i,i,i,i   Zeichnet eine Bitmap
RBOX x1,y1,x2,y2        Zeichnet ein Rechteck mit abgerundeteten Ecken
SCOPE a(),typ,ys,yo     Schneller Datenplot
SCOPE y(),x(),typ,ys,yo,xs,xo Schneller zweidimensionaler Datenplot
SETFONT f$              Setze Zeichensatz
SETMOUSE x,y            Setze Maus an Position
SGET screen$            Speichere den Inhalt des Grafikfensters in screen$
SPUT screen$            Schreibe gespeicherte Grfik wieder zurück
TEXT x,y,t$             Gebe Text aus (bitmap font)

19.2. Bildschirmkommandos

CLEARW [#n]         Lösche das Grafik-Fenster
CLOSEW [#n]         Schließe das Grafik-Fenster
FULLW n             Öffne das Fenster maximal
GET_GEOMETRY ,,,,   Bestimmt die Größe und Position des Fensters oder Bildschirms
GET_SCREENSIZE ,,,, Bestimmt die Größe des Bildschirms
INFOW n,t$          Setze Fensterinformationszeile
MOVEW n,x,y         Verschiebe Fenster
OPENW n             Öffne Fenster
ROOTWINDOW          Zeichne auf den Bildschrimhintergrund
NOROOTWINDOW        Zeichne in ein Fenster
SAVESCREEN file$    Speichere Bildschirm-Grafik in eine Datei
SAVEWINDOW file$    Speichere Fenster-Grafik in eine Datei
SCREEN n            wähle Bildschirm n für die Grafikausgabe
SHOWPAGE            Führe alle noch ausstehenden Grafikoperation aus
SIZEW n,w,h         Ändere die Größe des Fensters
TITLEW n,t$         Setze den Titel des Fensters
TOPW n              Bringe das Fenster nach vorne
USEWINDOW #n        Wähle Fenster n für die Grafikausgabe
VSYNC               Dasselbe wie SHOWPAGE

19.3. Kommandos der Grafischen Benutzerschnittstelle

ALERT a,b$,c,d$,var[,ret$] Zeigt eine Alert/Infobox und wartet auf Benutzereingaben
EVENT ,,,,,,,,         Wartet auf einen Ereignis durch Benutzer
FILESELECT tit$,path$,dflt$,f$ Zeigt eine Dateiauswahlbox und wartet auf Benutzereingaben
HIDEK                  Verstecke die virtuelle Tastatur
HIDEM                  Verstecke den Mauszeiger
KEYEVENT a,b           Wartet auf ein Tastaturereignis
LISTSELECT tit$,list$() Zeigt eine Auswahlbox und wartet auf Benutzereingaben
MENUDEF m$(),proc      Erstellt ein Pull-Down Menu
MENUKILL               Entfernt das Pull-Down Menu
MENUSET n,x            Setzt Wert für Menu-Eintrag
MENU STOP              Schaltet das Pull-Down Menu aus
ONMENU                 Bearbeite Benutzereingaben zum Pull-Down Menu
MENU                   Wartet auf Menu-Ereignisse
MOUSE x,y,k            Liest die Position und Zustand der Maus
MOUSEEVENT ,,,         Warte auf ein Maus-Ereignis
MOTIONEVENT ,,,        Warte darauf dass sich die Maus bewegt
OBJC_ADD t%,o%,c%      Füge Objekt an Objektbaum an
OBJC_DELETE t%,o%      Löscht ein Objekt aus einem Objektbaum
RSRC_LOAD file$        Läd GEM resource Datei
RSRC_FREE              gibt GEM resource Datei wieder frei
SHOWK                  Zeigt die virtuelle Tastatur
SHOWM                  Zeigt den Mauszeiger

20. Funktionen

20.1. Dateiein- und -ausgabefunktionen

d%=DEVICE(file$)     Gibt die Geräte-ID einer Datei zurück
b=EOF(#n)            ergibt TRUE wenn der Dateizeiger das Ende der Datei erreicht hat
b=EXIST(fname$)      ergibt TRUE wenn die Datei existiert
a=FREEFILE()         Gibt eine freie Kanalnummer wenn verfügbar, sonst -1
a$=FSFIRST$(path$,,) Sucht nach der ersten Datei im Pfad
a$=FSNEXT$()         Sucht nach der nächsten Datei
c=INP(#n)            Liest ein Byte aus Datei oder Kanal
c=INP?(#n)           Gibt die Anzahl der Bytes an, die gelesen werden können
a=INP&(#n)           Liest ein Word (16bit) aus Datei oder Kanal
i=INP%(#n)           Liest ein Long Word (32bit) aus Datei oder Kanal
t$=INPUT$(#n,num)    Liest num Bytes aus Datei oder Kanal
ret=IOCTL(#n,d%,)    Führt eine IO-Operation auf Datei oder Kanal aus.
t$=LINEINPUT$(#n)    Liest eine Zeile aus Datei ein
p=LOC(#n)            Gibt die Position des Dateipointers zurück (--> SEEK/RELSEEK)
l=LOF(#n)            Gibt die Länge der Datei zurück
l%=SIZE(file$)       Gibt die Größe einer Datei zurück
t$=TERMINALNAME$(#n) Gibt den Namen des Terminals zurück

20.2. Funktionen für Variablen und Stringverarbeitung

 adr%=ARRPTR(b())      Zeiger auf eine ARRAY Struktur
 a=ASC(t$)             gibt ASCII code des ersten Buchstabens des Strings
 b$=BIN$(a[,n])        Konvertiert Zahl in Binärdarstellung
 t$=CHR$(a)            Konvertiert ASCII code nach String
 a$=DECLOSE$(t$)       Entfernt Anführungszeichen von String
 a=DIM?(a())           Gibt die Anzahl der Elemente in Array
 a$=ENCLOSE$(t$[,p$])  Setzt den String in Anführungszeichen
 f=GLOB(a$,b$[,flags]) TRUE wenn a$ zum Pattern in b$ passt
 t$=HEX$(a[,n])        Konvertiert Zahl in Hexadezimaldarstellung
 t$=INLINE$(a$)        Umwandlung von 6-bit ASCII nach 8-bit binär
 a=INSTR(s1$,s2$[,n])  Liefert TRUE, wenn s2$ in s1$ enthalten ist
 a=TALLY(t$,s$)        Liefert die Anzahl der Vorkommnisse von s$ in t$
 b%=INT(a)             Konvertiert Tagl nach Integer (Ganzzahl)
 t$=LEFT$(a$[,n])      Liefert die linken n Bytes vom String a$
 t$=LEFTOF$(a$,b$)     Liefert linken Teil des Strings a$, geteilt an b$
 l=LEN(t$)             Ergibt die Länge der Zeichenkette/des Strings
 u$=LOWER$(t$)         wandelt String in Kleinbuchstaben
 l=LTEXTLEN(t$)        Ergibt die Breite des LTEXTes in Pixeln
 m$=MID$(t$,s[,l])     Liefert einen Ausschnitt des Strings t$ ab Position s der Länge l
 t$=MKA$(a())          Wandelt ein ganzes Array in einen String
 t$=MKI$(i)            Wandelt eine (16bit) Ganzzahl in einen 2-Byte String
 t$=MKL$(i)            Wandelt eine (32bit) Ganzzahl in einen 4-Byte String
 t$=MKF$(a)            Wandelt eine Gleitkommazahl in einen 4-Byte String
 t$=MKD$(a)            Wandelt eine Gleitkommazahl in einen 8-Byte String
o$=OCT$(d,n)          convert integer d to string with octal number
t$=REPLACE$(a$,s$,r$) replace s$ by r$ in a$
t$=REVERSE$(a$)       Return the reverses of a string
t$=RIGHT$(a$[,n])     returns right n characters of a$
t$=RIGHTOF$(a$,b$)    returns right part of a$ split at b$
a=RINSTR(s1$,s2$[,n]) tests from right if s2$ is contained in s1$
 t$=SPACE$(i)          Ergibt einen String aus i Leerzeichen
 t$=STR$(a[,b,c])      Wandelt eine Zahl in einen String
 t$=STRING$(i,w$)      Ergibt einen String bestehend aus i Kopien von w$
u$=TRIM$(t$)          trim t$
u$=XTRIM$(t$)         trim t$
 u$=UCASE$(t$)         wandelt t$ in Großbuchstaben
 u$=UPPER$(t$)         wandelt t$ in Großbuchstaben
 u$=USING$(a,f$)       formatiert eine Zahldarstellung
 a=VAL(t$)             wandelt String in Zahl, wenn möglich
 i=VAL?(t$)            Liefert die Anzahl der in eine Zahl umwandelbaren Zeichen
 adr%=VARPTR(v)        Liefert Zeiger auf Variableninhalt
u$=WORD$(b$,n)        returns n th word of b$
e=WORT_SEP(t$,d$,m,a$,b$)
                      splits t$ into parts

20.3. Datenkompression und -kodierung

b$=ARID$(a$)     Dekodiert a$ mit order-0 adaptive arithmetic decoding
b$=ARIE$(a$)     Kodiert a$ mit order-0 adaptive arithmetic encoding
b$=BWTD$(a$)     Dekodiert a$ mit inverser Burrows-Wheeler-Transformation
b$=BWTE$(a$)     wendet Burrows-Wheeler-Transformation auf a$ an
c$=COMPRESS$(a$)     Führt verlustfreie Kompression auf Stringinhalt aus
c$=UNCOMPRESS$(a$)   Führt verlustfreie Dekompression aus
c%=CRC(t$[,oc])      Gibt 32 bit Checksummme
e$=ENCRYPT$(t$,key$) Verschlüsselt eine Nachricht mit dem Schlüssel key$
t$=DECRYPT$(e$,key$) Entschlüsselt eine Nachricht mit dem Schlüssel key$
b$=MTFD$(a$)         "Move To Front"-Decodierung
b$=MTFE$(a$)         "Move To Front"-Kodierung
b()=CVA(a$)          Rekonstruiert ein Array aus einem String
b%=CVI(a$)           Wandelt 2-Byte String in eine Zahl
b%=CVL(a$)           Wandelt 4-Byte String in eine Zahl
b=CVS(a$)            Wandelt 4-Byte String in eine Fließkommazahl
b=CVF(a$)            Wandelt 4-Byte String in eine Fließkommazahl
b=CVD(a$)            Wandelt 8-Byte String in eine Fließkommazahl
t$=INLINE$(a$)       wandelt 6-bit ASCII in 8-bit Binärdaten
t$=REVERSE$(a$)      Liest den String rückwärts
b$=RLD$(a$)          "run length" Dekosierung
b$=RLE$(a$)          "run length" Kodierung

20.4. Speicherfunktionen

 adr%=ARRPTR(b())       Zeiger auf eine ARRAY Struktur
i%=DPEEK(adr%)         read word from pointer adr
b%=LPEEK(adr%)         reads long (4 Bytes) from address
adr%=MALLOC(n%)        allocates size bytes of memory
adr%=MSHRINK(adr%,n%) reduces the size of a storage area
d%=PEEK(a%)            reads Byte from address a
adr%=REALLOC(oadr%,n%) changes the size of a storage area
adr%=SHM_ATTACH(id)    attaches the shared memory segment
id=SHM_MALLOC(size,key)returns the identifier of the shared memory segm
adr%=SYM_ADR(#n,s$)    return pointer to symbol from shared object file
 adr%=VARPTR(v)         Zeiger auf den Variableninhalt im Speicher

20.5. Logische und Bit-Funktionen

 c%=AND(a%,b%)    Dasselbe wie c=(a AND b)
 c%=OR(a%,b%)     Dasselbe wie c=(a OR b)
 c%=XOR(a%,b%)    Dasselbe wie c=(a XOR b)
 c%=EQV(a%,b%)    Dasselbe wie c=(a EQV b)
 c%=IMP(a%,b%)    Dasselbe wie c=(a IMP b)
b%=BCHG(x%,bit%) changes the bit of x from 0 to 1 or from 1 to 0
b%=BCLR(x%,bit%) sets the bit of x to zero.
b%=BSET(x%,bit%) sets the bit of x to 1.
b%=BTST(x%,bit%) returns -1 if the bit of x is 1.
b%=BYTE(x%)      same as b=x AND 255
b%=CARD(x%)      same as b=x AND 0xffff
b%=WORD(x%)      same as b=x AND 0xffff
 b%=EVEN(d)       ergibt TRUE, wenn d gerade ist
 b%=ODD(d)        ergibt TRUE, wenn d ungerade ist
b%=GRAY(a)       Gray code. if a<0: inverse Gray code
b%=SHL(a)        Shift bits to left
b%=SHR(a)        Shift bits to right
b%=SWAP(a)       Swaps High and Low words of a

20.6. Mathematische Funktionen

Die Mathematikfunktionsbibliothek enthält einen umfassenden Satz mathematischer Funktionen, einschließlich:

  • trigonometrisch

  • Arc-Trigonometrie

  • hyperbolisch

  • arc-hyperbolisch

  • logarithmisch (zur Basis e und Basis 10)

  • exponentiell (zur Basis e und Basis 10)

  • Verschiedenes (Quadratwurzel, Hoch usw.)

Einige mathematische Funktionen sind in Vektoren und Matrizen definiert.

b=ABS(a)           ergibt den Absolutwert (Betrag) b=|a|
c=ADD(a,b)         Dasselbe wie c=a+b
b=CBRT(a)          ergibt Qubikwurzel von a
a=CEIL(b)          Schneide Nachkommastellen ab
a=CINT(b)          Schneide Nachkommastellen ab (Hinweis: anders als INT() !)
z=COMBIN(n,k)      Anzahl der Kombinationen n aus k
c=DIV(a,b)         Dasselbe wie c=a/b
b()=FFT(a()[,f%])  reelle diskrete Fourier Transformation eines Arrays
a=FIX(b)           Runde die Zahl zur nächsten Ganzzahl
a=FLOOR(b)         Runde die Zahl ab
b=FRAC(a)          Ergibt den Gebochenen Teil (Nachkommaanteil) der Zahl
y=GAMMA(x)         Gamma-Function
y=LGAMMA(x)        Logarithmus der Gamma-Funktion
a=HYPOT(x,y)       Hypotenose
b=INT(a)           Wandelt Zahl in Ganzzahl um
b()=INV(a())       Berechne das Inverse einer Quadratischen Matrix
i=SGN(a)           Ergibt das Vorzeichen von a (-1,0,1)
b=SQR(a)           Quadrtwurzel
b=SQRT(a)          Quadratwurzel
b=TRUNC(a)         Schneide Nachkommastellen ab
b=LN(a)            Natürlicher Logarithmus (zur Basis e)
b=LOG(a)           Natürlicher Logarithmus (zur Basis e)
b=LOG10(a)         Logarithmus (zur Basis 10)
b=LOGB(x)          Logarithmus zur Basis 2
b=LOG1P(x)         Dasselbe wie b=log(1+x), höchste Genauigkait bei Null
c=MOD(a,b)         Dasselbe wie c=(a MOD b)
c=MUL(a,b)         Dasselbe wie c=a*b
b=EXP(a)           Exponentialfunktion
b=EXPM1(a)         Exponentialfunktion minus eins b=EXP(a)-1, höchste Genauigkait bei Null
b=FACT(a)          Fakultät b=a!
a=PRED(x)          Gibt die vorangehende Ganzzahl zu x
a=SUCC(x)          Gibt die nächst größere Ganzzahl zu x
b()=SOLVE(a(),x()) Löst ein lineares Gleichungssystem
z=VARIAT(n,k)      Anzahl der Permutationen von n elements

20.6.1. Winkel

Winkel sind immer Bogenmaß, sowohl für Argumente als auch für Rückgabewerte.

b=RAD(a)     Wandelt Grad in Bogenmaß um
b=DEG(a)     Wandelt Bogenmaß in Grad um

20.6.2. Trigonometrische Funktionen

b=SIN(a)     Sinus
b=COS(a)     Cosinus
b=TAN(a)     Tangens
b=ASIN(a)    Arcus-Sinus
b=ACOS(a)    Arcus-Cosinus
b=ATAN(a)    Arcus-Tangens
b=ATN(a)     Arcus-Tangens
b=ATAN2(a,c) Erweiterter Arcus-Tangens
b=SINH(a)    Hyperbolischer Sinus
b=COSH(a)    Hyperbolischer Cosinus
b=TANH(a)    Hyperbolischer Tangens
b=ASINH(a)   Hyperbolischer Arcus-Sinus
b=ACOSH(a)   Hyperbolischer Arcus-Cosinus
b=ATANH(a)   Hyperbolischer Arcus-Tangens

20.6.3. Zufallszahlen

a=GASDEV(dummy)  ergibt eine Gauß-verteilte Zufallszahl
a=RAND(dummy)    gibt eine ganze Zufallszahl
a=RANDOM(n)      gibt eine ganze Zufallszahl zwische 0 and n
a=RND(dummy)     gibt eine Zufallszahl zwischen 0 und 1
a=SRAND(seed)    Dasselbe wie RANDOMIZE

20.7. Systemfunktionen

 ret%=CALL(adr%[,par]) Ruft eine Maschinencode oder C Funktion auf mit Rückgabewert
 t$=ENV$(n$)           Gibt den Wert einer Umgebungsvariable zurück
 t$=ERR$(i)            Gibt die Fehlermeldung zu einer Fehlernummer
ret=EXEC(adr[,var])   see command EXEC, returns int
i%=FORK()             creates a child process
 d$=JULDATE$(a)        Ergibt Datum aus Julianischem Tag
 a=JULIAN(date$)       Ergibt julianisches Datum
 a$=PARAM$(i)          Liefert das i-te Wort der Kommandozeilenparameter
t$=PRG$(i)            program line
 a=SENSOR(i)           ergibt den Wert des i-ten Sensors
t$=SYSTEM$(n$)        execute shell with command n$
t$=UNIXTIME$(i)       give time$ from TIMER value
d$=UNIXDATE$(i)       give date$ from TIMER value

20.8. Grafik-Funktionen

 c=COLOR_RGB(r,g,b[,a]) Alloziert eine Farbe per rgb-Wert und gibt die Nummer zurück.
a=EVENT?(mask%)        returns TRUE if a graphics event is pending
a=FORM_ALERT(n,t$)     message box with default button n
~FORM_CENTER(adr%,x,y,w,h)
                       centers the object tree on screen
a=FORM_DIAL(,,,,,,,,) complex function for screen preparation
a=FORM_DO(i)           do dialog
 c=GET_COLOR(r,g,b)     Alloziert eine Farbe in der Farbtabelle und gibt die Nummer zurück.
d=OBJC_DRAW(,,,,)      draw object tree
ob=OBJC_FIND(tree,x,y) return object number by coordinates
a=OBJC_OFFSET(t%,o,x,y)calculate absolute object coordinates
 c=POINT(x,y)           Liefert Farbwert des Punkts der Grafik im aktuellen Fenster
 c=PTST(x,y)            Liefert Farbwert des Punkts der Grafik im aktuellen Fenster
 a=RSRC_GADDR(typ,nr)  Liefert Zeiger auf einen Objektbaum

20.9. Sonstige Funktionen

a=EVAL(t$)        Berechne einen Ausdruck in t$
m=MAX(a,b,c,...)  Liefert größten Wert zurück
m=MAX(f())        Liefert größten Wert zurück
m=MIN(a,b,c,...)  Liefert kleinsten Wert zurück
m=MIN(array())    Liefert kleinsten Wert zurück
m=MIN(function()) noch nicht implementiert

20.10. Unterroutinen und Funktionen

Unterroutinen

sind Code-Blöcke, die von anderen Stellen im Programm aufgerufen werden können. Subroutinen können Argumente übernehmen, aber keine Ergebnisse zurückgeben. Sie können auf alle verfügbaren Variablen zugreifen, können aber auch lokale Variablen haben (→ LOCAL). Unterprogramme werden so definiert:

PROCEDURE name(argumentliste)
  ... viele Kommandos
RETURN
Funktionen

sind Code-Blöcke, die von anderen Stellen innerhalb eines Ausdrucks aufgerufen werden können (z.B. a=3*@myfunction(b)). Funktionen können Argumente annehmen und müssen ein Ergebnis zurückgeben. Variablen sind global, sofern sie nicht als lokal deklariert sind. Bei lokalen Variablen haben Änderungen außerhalb einer Funktion keine Auswirkungen innerhalb der Funktion, es sei denn, sie sind explizit in der Funktion angegeben. Funktionsargumente können Variablen und Arrays beliebiger Typen sein. Funktionen können Variablen beliebigen Typs zurückgeben. Standardmäßig werden Argumente nach Wert übergeben. Funktionen können rekursiv ausgeführt werden. Eine Funktion wird definiert durch:

FUNCTION name(argumentliste)
  .. Viele Berechnungen und Kommandos
  RETURN rueckgabewert
ENDFUNCTION

20.11. Fehlermeldungen

X11-Basic kann eine Reihe von internen Fehlern erzeugen, auf die mit einer Nummer (ERR) verwiesen wird (siehe auch ERROR).

Die Bedeutung dieser Fehler und ihres Textausdrucks ist wie folgt:

  0  Division durch 0
  1  Überlauf
  2  Wert nicht Integer  -2147483648 .. 2147483647
  3  Wert nicht Byte  0 .. 255
  4  Wert nicht Wort -32768 .. 32767
  5  Quadratwurzel nur für positive Zahlen
  6  Logarithmen nur für Zahlen größer Null
  7  Unbekannter Fehler
  8  Speicher voll
  9  Funktion oder Befehl ist nicht implemetiert in dieser Version
 10  String zu lang
 11  Argument muß positiv sein
 12  Programm zu lang, Speicher voll -> NEW
 13  Unpassende Typen im Ausdruck
 14 Feld zweimal dimensioniert
 15 Feld nicht dimensioniert
 16 Feldindex zu groß
 17 Dim zu groß
 18 Falsche Anzahl Inizies
 19 Procedure nicht gefunden
 20 Label nicht gefunden
 21 Bei Open nur erlaubt: "I"nput "O"utput "A"ppend "U"pdate
 22 File schon geöffnet
 23 File # falsch
 24 File nicht geöffnet
 25 Falsche Eingabe, keine Zahl
 26 Fileende erreicht EOF
 27 Zu viele Punkte für Polyline/Polyfill
 28 Array muss eindimensional sein
 29 Ungültige Adresse!
 30 Merge - Kein ASCII-File
 31 Merge - Zeile zu lang  - ABBRUCH
 32 ==> Syntax nicht korrekt
 33 Label nicht definiert
 34 Zu wenig Data
 35 Data nicht numerisch
 36 Programmstruktur Fehlerhaft
 37 Diskette/Festplatte voll
 38 Befehl im Direktmodus nicht möglich
 39 Programmfehler. Kein Gosub möglich
 40 Clear nicht möglich in For-Next-Schleifen oder Proceduren
 41 Cont nicht möglich
 42 Zu wenig Parameter
 43 Ausdruck zu komplex
 44 Funktion nicht definiert
 45 Zu viele Parameter
 46 Falscher Parameter, muss Zahl sein
 47 Falscher Parameter, muss String sein
 48 Open "R" - Satzlänge falsch"
 49 Zu viele "R"-files (max. 31)
 50 Kein "R"-file
 51 Parser: Syntax Error <>
 52 Fields größer als Satzlänge
 53 Falsches Grafik-Format
 54 GET/PUT Field-String Länge falsch
 55 GET/PUT Satznummer falsch
 56 Falsche Anzahl Parameter
 57 Variable noch nicht initialisiert
 58 Variable ist vom falschen Typ
 59 Grafik hat falsche Farbtiefe
 60 Sprite-String-Länge falsch
 61 Fehler bei RESERVE
 62 Menu falsch
 63 Reserve falsch
 64 Pointer falsch
65 Field size < 256
66 No VAR-Array
67  ASIN/ACOS wrong
68  Wrong VAR-Type
69  ENDFUNC without RETURN
70  Unknown Error 70
71  Index too large
72  Error in RSRC_LOAD
73  Error in RSRC_FREE
74  Array dimensioning mismatch
75  Stack overflow!
76  Illegal variable name . can not create.
77  Function not defined for complex numbers.
78  Incorrect parameter, must be array
80  Matrix operations only allowed for one or two dimensional arrays
81  Matrices do not have the same order
82  Vector product not defined
83  Matrix product not defined
84  Scalar product not defined
85  Transposition only for two dimensional matrices
86  Matrix must be square
87  Transposition not defined
88  FACT/COMBIN/VARIAT/ROOT not defined
89  Array must be two dimensional
90  Error in Local
91  Error in For
92  Resume (next) not possible: Fatal, For or Local
93  Stack Error
94  Parameter must be float ARRAY
95  Parameter must be ARRAY
96  ARRAY has the wrong type. Can not convert.
97  This operation is not allowed for root window
98  Illegal Window number (0-16)
99  Window does not exist
 100 X11-BASIC Version 1.25 Copyright (c) 1997-2018 Markus Hoffmann
 101 ** 1 - Speicherschutzverletzung
102 ** 2 - Bus Error: peek/poke ?
103 ** 3 - Address error: Dpoke/Dpeek, Lpoke/Lpeek?
104 ** 4 - Illegal Instruction
 105 ** 5 - Division durch Null
106 ** 6 - CHK exception
107 ** 7 - TRAPV exception
108 ** 8 - Privilege Violation
109 ** 9 - Trace exception
 110 ** 10 - Broken pipe : Ausgabeweitergabe abgebrochen
131 * Number of hash collisions exceeds maximum generation counter value.
132 * Wrong medium type
133 * No medium found
134 * Quota exceeded
135 * Remote I/O error
136 * Is a named type file
137 * No XENIX semaphores available
138 * Not a XENIX named type file
139 * Structure needs cleaning
140 * Stale NFS file handle
141 * Operation now in progress
142 * Operation already in progress
143 * No route to host
144 * Host is down
145 * Connection refused
146 * Connection timed out
147 * Too many references: can not splice
148 * Can not send after transport endpoint shutdown
149 * Transport endpoint is not connected
150 * Transport endpoint is already connected
151 * No buffer space available
152 * Connection reset by peer
153 * Software caused connection abort
154 * Network dropped connection because of reset
155 * Network is unreachable
156 * Network is down
157 * Can not assign requested address
158 * Address already in use
159 * Address family not supported by protocol
160 * Protocol family not supported
161 * Operation not supported on transport endpoint
162 * Socket type not supported
163 * Protocol not supported
164 * Protocol not available
165 * Protocol wrong type for socket
166 * Message too long
167 * Destination address required
168 * Socket operation on non-socket
169 * Too many users
170 * Streams pipe error
171 * Interrupted system call should be restarted
172 * Illegal byte sequence
173 * Can not exec a shared library directly
174 * Attempting to link in too many shared libraries
175 * .lib section in a.out corrupted
176 * Accessing a corrupted shared library
177 * Can not access a needed shared library
178 * Remote address changed
179 * File descriptor in bad state
180 * Name not unique on network
181 * Value too large for defined data type
182 * Not a data message
183 * RFS specific error
184 * Try again
185 * Too many symbolic links encountered
186 * File name too long
187 * Resource deadlock would occur
188 * Advertise error
189 * memory page error
190 * no executable
191 * Link has been severed
192 * Object is remote
193 * Math result not representable
194 * Math arg out of domain of func
195 * Cross-device link
196 * Device not a stream
197 * Mount device busy
198 * Block device required
199 * Bad address
200 * No more processes
201 * No children
202 * Exchange full
203 * Interrupted system call
204 * Invalid exchange
205 * Permission denied, you must be super-user
206 * Operation in this channel not possible (any more)
207 * no more files
208 * Link number out of range
209 * Level 3 reset
210 * Illegal Drive identifier
211 * Level 2 not synchronized
212 * Channel number out of range
213 * Identifier removed
214 * No message of desired type
215 * Operation would block
216 * illegal page address
217 * Directory not empty
218 * Function not implemented
219 * Illegal Handle
220 * Access not possible
221 * Too many open files
222 * Path not found
223 * File not found
224 * Broken pipe
225 * Too many links
226 * Read-Only File-System
227 * Illegal seek
228 * No space left on device
229 * File too large
230 * Text file busy
231 * Not a typewriter
232 * Too many open files
233 * File table overflow
234 * Invalid argument
235 * Is a directory
236 * Not a directory
237 * No such device
238 * Cross-device link
239 * File exists
240 * Bad sector (verify)
241 * unknown device
242 * Disk was changed
243 * Permission denied
244 * Not enough core memory
245 * Lesefehler
246 * Schreibfehler
247 * No paper
248 * Sector nicht gefunden
249 * Arg list too long
250 * Seek Error
251 * Bad Request
252 * CRC Fehler: Disk-Prüfsumme falsch
253 * Es gibt keinen solchen Prozess
254 * Zeitüberschreitung
255 * Allgemeiner Eingabe/Ausgabe-Fehler

21. Kommando-Beschreibungen Befehlsreferenz

Dieses Kapitel ist eine Befehlsreferenz zum schnellen Nachschlagen kurzer Erklärungen aller eingebauten X11-Basic-Operatoren, Variablen, Befehle und Funktionen.

Bitte schlagen Sie die Beschreibungen im englischen Orginal-Handbuch nach.

21.1. Syntax-Beispiel

Dieses Handbuch beschreibt die Syntax von BASIC-Befehlen und BASIC-Funktionen in verallgemeinerter Form. Hier ist ein Beispiel:

PRINT [#<device-number>,] <expression> [<,>|<;> [...]]

Die Teile des Befehls, die im Quellcode wörtlich vorkommen müssen (wie im obigen Beispiel PRINT), sind alle in Großbuchstaben geschrieben. Beschreibungen in spitzen Klammern ("<>") sollen nicht wörtlich im Quelltext erscheinen, sondern sind beschreibende Verweise auf das Element, das im Quellcode an dieser Stelle verwendet werden soll, wie eine Variable, ein numerischer Ausdruck usw. Optionale Elemente sind in eckigen Klammern ("[]") aufgeführt. Sie können in der Befehlszeile weggelassen werden. Gegenseitig ausschließende Alternativen sind durch das "|" Zeichen getrennt. Genau eine dieser Alternativen muß in der Befehlszeile erscheinen. Schließlich wird eine sich wiederholende Syntax durch drei Punkte "…​" angezeigt.

Hier sind einige BASIC-Befehlszeilen, die alle der obigen Syntaxvorlage entsprechen:

PRINT x
PRINT #1,2*y
PRINT "result = ";result

22. Häufig gestellte Fragen und Antworten

22.1. Wie leicht ist es, in meine Programme zu hacken?

Nun, zuallererst: es ist möglich. Die grundlegenden Quelldateien (.bas) sind natürlich von jedem Texteditor lesbar und modifizierbar. Der Bytecode kompilierte Code (.b) ist bereits schwieriger zu lesen und fast unmöglich wieder in Quellcode zu konvertieren. Da X11-Basic jedoch Open Source ist, kann jeder, der möchte, in den Quellcode schauen und alle Informationen lesen, die notwendig sind, um den Bytecode zu dekodieren und ihn auch zu modifizieren.

Es ist möglich, aber es erfordert schon einen großen Aufwand. Der in C-Code übersetzte Bytecode könnte auch hier von jemandem geändert werden. Sobald der Bytecode in eine echte Maschinensprache übersetzt ist, ist der Code aber so sicher vor Hackern wie jeder andere Code (was bedeutet, dass es fast keinen Weg zurück gibt).

Selbst wenn Sie den Bytecode in die virtuelle Maschine einbinden, sollte Ihr Programm vor Schnüfflern sicher sein, die wissen ja nicht unbedingt, dass Ihr Programm Bytecode generiert.

Tip

Sie können den Bytecode-Compiler auch anweisen, keine Symboltabelle oder zusätzliche Debuginformationen anzuhängen.

22.2. Brauche ich eine Lizenz, um meine Programme zu verteilen?

Nein. Sie benötigen keine Lizenz, um X11-Basic zu benutzen (es ist kostenlos). Und Sie brauchen definitiv keine Lizenz, um Ihre Programme zu vertreiben oder zu verkaufen. Die einzige Vereinbarung, um die Sie sich sorgen müssen, ist, dass Sie, wenn Sie X11-Basic verwenden, alle direkten und indirekten Konsequenzen aus der Nutzung von X11-Basic übernehmen. Das bedeutet u.a.: Beschimpfen Sie mich nicht, wenn irgendwas nicht so funktioniert, wie Sie es erwarten. X11-Basic kann für jede Aufgabe verwendet werden, egal, ob diese gewinnorientiert ist oder nicht. Ich will es nicht wissen, und Sie brachen mir keinen Cent zu zahlen. Sie müssen nicht einmal erwähnen, dass Ihr Programm mit X11-Basic erstellt wurde (obwohl dies eine nette Geste wäre).

Sie dürfen X11-Basic mit Ihren Programmen bündeln, solange der Benutzer darüber informiert ist dass er nicht X11-Basic kauft oder dafür zahlt, sondern nur Ihr Programm oder Ihre Dienstleistung erwirbt. Wie kann man das machen? Indem Sie nicht einmal erwähnen, dass Ihre Distribution eine Kopie von X11-Basic enthält. Wenn Sie jedoch X11-Basic selbst verteilen oder ändern möchten oder wenn Sie Teile des X11-Basic-Quellcodes einbinden möchten, müssen Sie die GNU-Lizenz beachten.

22.3. Wie schnell ist X11-Basic?

Die Antwort hängt davon ab, wie ein X11-Basic-Programm ausgeführt wird: Es hängt davon ab, ob der Code interpretiert wird, als Bytecode in einer virtuellen Maschine ausgeführt wird oder in eine native Maschinensprache kompiliert wird. Generell finden wir:

  1. X11-Basic-Programme, die vom Interpreter ausgeführt werden, sind langsam,

  2. X11-Basic-Programme kompiliert zu Bytecode, die dann in der virtuellen X11-Basic-Maschine (xbvm) ausgeführt wwerden, sind hingegen ziemlich schnell

  3. X11-Basic Bytecode, der nativ in echte Maschinensprache kompiliert wird, ist noch schneller.

  4. Große Zahlen und Berechnungen mit unendlicher Genauigkeit sind langsam, aber

  5. 64-Bit-Gleitkomma- und komplexe Zahlenberechnungen sowie 32-Bit-Ganzzahlen sind sehr schnell.

Bytecodierte Programme werden immer schneller interpretiert als Skriptsprachen. Der X11-Basic-Compiler kann den X11-Basic-Bytecode in C übersetzen, der dann mithilfe eines beliebigen C-Compilers (vorzugsweise gcc auf UNIX-Systemen) in die native Maschinensprache kompiliert werden kann. Offensichtlich sind Ihre X11-Basic-Programme dann immernoch langsamer als optimierter C/C++ Code, aber es kommt dem schon nahe.

Wenn Sie die höchstmögliche Geschwindigkeit benötigen, können Sie eine separate DLL/ ein "shared Objekt" mit dem zeitkritischen Teil Ihres Codes hinzuladen, der in einer anderen Sprache geschrieben ist (z.B. C oder Assembler).

Ein Geschwindigkeitsvergleich wurde mit dem Whetstone-Benchmark (-→ Whets.bas) durchgeführt. Dies zeigt, dass Bytecode-Programme etwa 19 mal schneller sind als der interpretierte Code und ein nativ kompiliertes Programm etwa 28-mal schneller laufen kann.

22.4. UTF-8 Zeichensatz

Ich habe das letzte Update auf X11-Basic heruntergeladen, aber ich habe ein Problem mit dem UTF-8-Zeichensatz…​ Ich kann den ASCII-Zeichensatz nicht mehr verwenden, besonders den grafischen Teil davon…​ Ich habe ein kleines Spiel gemacht, das es benutzt, jetzt funktioniert es nicht mehr…​ Gibt es eine Möglichkeit, dieses Problem zu beheben?

A

Ja, die gibt es. Alle Zeichen sind immer noch da, aber Sie können nicht mit einem einfachen CHR$() darauf zugreifen. Eine Methode besteht darin, die Zeichen aus einer Unicode-Tabelle wie folgt zu kopieren:

Kopieren Sie aus der Seite http://de.wikipedia.org/wiki/Unicodeblock_Rahmenzeichnung das entsprechende Zeichen z.B.mit der Maus in den Editor. Sie müssen einen UTF-8-fähigen Editor verwenden, z. pico, nano, gedit.

Wenn dies bei Ihnen nicht funktioniert, können Sie das Zeichen auch selbst mit der Unicode-Nummer codieren:

FUNCTION utf8$(unicode%)
  IF unicode%<0x80
    RETURN CHR$(unicode%)
  ELSE IF unicode%<0x800
    RETURN CHR$(0xc0+(unicode%/64 AND 0x1f))+CHR$(0x80+(unicode% AND 0x3f))
  ELSE
    RETURN CHR$(0xe0+(unicode%/64/64 AND 0xf))+CHR$(0x80+(unicode%/64 AND 0x3f))+ \
           CHR$(0x80+(unicode% AND 0x3f))
  ENDIF
ENDFUNCTION

So kann z.B. das Zeichen 0x250C mit @utf8$(0x250C) codiert werden.

22.5. GUI-Designer

Gibt es einen GUI-Designer für die grafischen Benutzeroberflächenfunktionen von X11-Basic?

A

Nun, bisher hat noch niemand einen echten grafischen GUI-Designer geschrieben. Aber das Programm gui2bas kann beim Erstellen von GUI-Formularen helfen. Die Eingabe ist eine sehr einfache ASCII-Datei (.gui), die die Schnittstelle definiert. Bisher werden viele GEM-Objekttypen unterstützt (und sogar ATARI ST .rsc-Dateien können mit dem Programm rsc2gui in .gui-Dateien konvertiert werden).

22.6. Andere

F

Meine alten ANSI-Basisprogramme (mit Zeilennummern) erzeugen viele Fehler im Interpreter. Wie kann ich klassische (ANSI) Basic-Programme ausführen?

A

Classische BASIC-Programme müssen konvertiert werden, bevor sie mit X11-Basic ausgeführt werden können. Mit dem bas2x11basic Konverterprogramm wird der Großteil dieser Konvertierung automatisch durchgeführt.

23. Kompatibilität

23.1. Allgemein

X11-Basic weicht in zahlreichen Aspekten von ANSI BASIC ab. Es unterscheidet sich auch von GfA-Basic (Atari ST), obwohl es versucht, kompatibel zu sein und wirklich ähnlich aussieht:

23.1.1. ELSE IF vs ELSEIF

Dieser Interpreter verwendet die ELSE-IF-Form der Anweisung "else if" mit einem Leerzeichen zwischen ELSE und IF. Im Gegensatz dazu verwendet ANSI BASIC "ELSEIF" und "END IF". Andere Interpreter können auch die Kombination "ELSEIF" und "ENDIF" verwenden.

23.1.2. Lokale Variablen

Lokale Variablen müssen in der Prozedur bzw. Funktion als lokal deklariert werden. Alle anderen Variablen werden als global behandelt.

23.1.3. Call By-Value oder By-Reference

Variablen in einer GOSUB-Anweisung wie in GOSUB test(a) werden "by-value" an die PROCEDURE übergeben: Die Subroutine erhält den Wert, kann aber die Variable, aus der der Wert stammt, nicht ändern. Um die Variable "by-reference" zu übergeben, verwenden Sie das Schlüsselwort VAR wie in GOSUB test(VAR a): Das Unterprogramm erhält dann nicht nur den Wert, sondern auch die Variable selbst und kann sie ändern (weitere Informationen finden Sie in der Dokumentation der GOSUB-Anweisung). Für FUNCTION gelten die gleichen Regeln: VAR in der Parameterliste eines Funktionsaufrufs ermöglicht es einer FUNCTION, einen variablen Parameter "by-reference" zu erhalten. Im Gegensatz dazu übergeben traditionelle BASIC-Interpreter Variablen immer in Parameterlisten "by-reference". Das Problem mit "by-reference"-Parametern ist, dass Sie sich dessen bewusst sein müssen, was innerhalb der Subroutine passiert: Zuweisungen an Parametervariablen innerhalb der Subroutine können die Werte von Variablen in der aufrufenden Zeile verändern.

23.1.4. Zuweisungsoperator

X11-BASIC hat keinen speziellen Zuweisungsoperator, sondern weist dem Gleichheitszeichen zusätzlich diese Funktion zu. Das = Zeichen hat also je nach Kontext eine andere Funktion. Einmal als Vergleichsoperator in Ausdrücken (wie in IF a=2) und zum zweiten als Zuweisungsoperator in Zuweisungen (wie in LET a=1). In einer Zuweisung wird immer das erste Gleichheitszeichen als Zuweisungsoperator betrachtet, alle folgenden als Vergleichsoperator. Hier ist ein Beispiel, das das Ergebnis eines Vergleichs (TRUE oder FALSE) der Variablen <a> zuordnet und somit beide Formen der Verwendung des Gleichheitszeichens zeigt:

a=(b=c)

23.1.5. Zuweisungen zum modifizierbaren l(inks)-Werten

Einige Implementierungen von BASIC erlauben die Verwendung von Funktionen auf der linken Seite von Zuweisungen wie in MID$(a$,5,1)="a". X11-Basic unterstützt diese Syntax nicht, benötigt stattdessen auf der linken Seite solcher Ausdrücke immer eine Variable (einen "modifizierbaren links-Wert").

23.1.6. Die INT()-Funktion

In X11-Basic gibt INT() wahrscheinlich andere Ergebnisse für negative Zahlen und für Zahlen größer als 2147483648 als in anderen Implementationen von BASIC. INT() wird intern als "Cast to Int" implementiert. (Das war schon immer so und ist sehr schnell, und der Compiler besteht darauf.) Dies bedeutet, dass das Argument nicht aus Zahlen bestehen darf, die sich nicht in 32-Bit-Ganzzahlen konvertieren lassen. Der Nachkommateil der Fließkommazahlen wird abgeschnitten (wie in TRUNC()) statt abgerundet (wie bei den meisten anderen BASIC-Dialekten). Wenn Sie ein korrektes Verhalten auch bei negativen Zahlen brauchen, dann sollten Sie lieber FLOOR() anstelle von INT() verwenden

23.1.7. Die DIM-Anweisung

In X11-Basic verhält sich die "DIM"-Anweisung wahrscheinlich anders als in anderen BASIC-Dialekten. DIM in X11-Basic reserviert Speicherplatz für genau die angegebene Anzahl von Indizes. Andere BASIC-Dialekte reservieren einen Speicher für einen Index mehr als angegeben. . Wenn Sie vom Fehler "Feldindex außerhalb des Bereichs" überrascht werden, liegt es wahrscheinlich daran, dass Sie nicht genug Dimensioniert haben.

Zum Beispiel: DIM a(5) reserviert Speicher für genau 5 Werte: a(0), a(1), a(2), a(3) und a(4). a(5) existiert hingegen nicht, und daher erhalten Sie einen Fehler, wenn Sie versuchen, darauf zuzugreifen. Die Art, wie X11-Basic es implementiert, ist logischer und ähnelt C und JAVA. Aber wenn Sie daran gewöhnt sind, dass ein Array mit dem ersten Index 1 (statt 0) beginnt, werden Sie wahrscheinlich ein wenig verwirrt sein.

23.1.8. Die LET-Anweisung

Obwohl es in X11-Basic implementiert ist, hat die Verwendung der LET-Anweisung keinen Vorteil. Im Gegenteil macht die Verwendung von LET Ihr Programm langsamer als nötig. Lassen Sie es einfach weg, benutzen Sie es überhaupt nicht. Zuweisungen können ohne die LET-Anweisung vorgenommen werden.

23.1.9. Die TOS/GEM Implementierung

Da GfA-Basic auf ATARI-ST die integrierten GUI-Funktionen des ATARI ST (TOS/GEM) nutzt, die auf anderen Betriebssystemen nicht verfügbar sind, kann X11-Basic nur bedingt kompatibel sein. GEM-kompatible ALERT-Boxen, Menüs und Objekte werden von X11-Basic unterstützt und können auf ähnliche Weise verwendet werden. Sogar ATARI ST .rsc Dateien können geladen werden. Andere Funktionen wie LINEA-Funktionen, VDISYS-, GEMSYS-, BIOS-, XBIOS- und GEMDOS-Aufrufe sind nicht möglich. Außerdem werden viele andere Dinge nicht implementiert, weil der Autor denkt, dass sie auf UNIX-Plattformen keinen nützlichen Effekt haben. Einige könnten in einer späteren Version von X11-Basic enthalten sein (siehe Liste unten). Da viele GfA-Basic-Programme diese Funktionen nutzen, werden sie modifiziert werden müssen, bevor sie mit X11-Basic ausgeführt werden können.

23.1.10. Die INLINE-Anweisung

Die INLINE-Anweisung wird nicht unterstützt, da der Quellcode X11-Basic-Programme reiner ASCII-Text ist. Eine Alternative wurde aber implementiert. (siehe INLINE$()).

23.1.11. Inkompatible Datentypen

X11-Basic verwendet den Standarddatentyp (ohne Suffix) und den Integer-Datentyp (Suffix %). Dies ist mit den meisten BASIC-Dialekten kompatibel. Der komplexe Datentyp (Suffix ) wird jedoch von den meisten BASIC-Dialekten nicht unterstützt und das Suffix wird manchmal auch für reguläre Float-Variablen verwendet (wie in GFA-Basic).

Das Suffix &, das für große Integer-Variablen verwendet wird, könnte mit der Endung für short int Datentypen bei GFA-BASIC verwechselt werden. Im Allgemeinen werden diese Programme jedoch trotzdem laufen und korrekte Ergebnisse liefern. Die Verwendung der unendlichen Präzisionsroutinen ist nur langsamer.

Spezielle Datentypen für short int und Byte werden von X11-Basic nicht verwendet. Sie waren eigentlich nur bei Computern mit wenig RAM sinnvoll, um etwas Speicher einzusparen. Heute ist das nicht mehr nötig, und der Nutzen solcher Datentypen ist verschwunden. Nehmen Sie stattdessen den long int Datentyp (%).

Note

Die Endung | soll für zukünftige Nutzung reserviert sein.

23.2. GFA-Basic Kompatibilität

TODO

24. GNU Free Documentation License

Der Autor dieser Übersetzung ist:

Hugo Giese jr.

Dies ist eine inoffzielle deutsche Übersetzung der GNU Free Documentation License. Sie ist nicht von der Free Software Foundation herausgegeben und erläutert nicht die Bedingungen der GNU FDL — Dies tut nur der original englische Text der GNU FDL. Dennoch hoffen wir, dass diese Übersetzung mit dazu beiträgt deutschsprachigen Personen das Verstehen der GNU FDL zu erleichtern.

This is an unofficial translation of the GNU Free Documentation License into German. It was not published by the Free Software Foundation, and does not legally state the distribution terms for documentation that uses the GNU FDL—​only the original English text of the GNU FDL does that. However, we hope that this translation will help German speakers understand the GNU FDL better.

Die originale Version der GFDL gibt es unter: http://www.gnu.org/copyleft/fdl.html

GNU Freie Dokumentationslizenz

Version 1.2, November 2002

Copyright © 2000,2001,2002 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Jeder darf diese Lizenzurkunde kopieren und wortwörtliche Kopien davon verteilen, Änderungen daran sind jedoch nicht gestattet.

24.1. Präambel

Der Zweck dieser Lizenz ist es, ein Handbuch, Textbuch oder ein anderes zweckdienliches und nützliches Dokument frei, im Sinne von Freiheit, zu machen; jedermann die Freiheit zu sichern, es zu kopieren und mit oder ohne Änderungen daran, sowohl kommerziell als auch nicht kommerziell weiter zu verbreiten. Weiterhin sichert diese Lizenz einem Autor oder Verleger die Möglichkeit, Anerkennung für seine Arbeit zu erhalten ohne für Änderungen durch Andere verantwortlich gemacht zu werden.

Diese Lizenz ist eine Art des "copyleft", was bedeutet, daß von diesem Dokument abgeleitete Werke ihrerseits in derselben Weise frei sein müssen. Dies vervollständigt die GNU General Public License, die eine "copyleft"-Lizenz ist, und für freie Software entworfen wurde.

Diese Lizenz wurde für Handbücher für freie Software entworfen, denn freie Software braucht freie Dokumentation: Ein freies Programm sollte von Handbüchern begleitet sein, die dieselben Freiheiten bieten, die auch die Software selbst bietet. Diese Lizenz ist aber nicht auf Softwarehandbücher beschränkt; vielmehr kann sie für jede Art von textuellen Werken verwendet werden, unabhängig davon, was das Thema ist, oder ob es als gedrucktes Buch veröffentlicht wurde. Wir empfehlen diese Lizenz prinzipiell für Werke, die als Anleitungen oder Referenzen dienen sollen.

24.2. Anwendbarkeit und Definitionen

Diese Lizenz findet Anwendung auf jedes Handbuch oder andere Werk, unabhängig von dem Medium, auf dem es erscheint, das einen vom Rechteinhaber eingefügten Hinweis enthält, der besagt, daß das Werk unter den Bedingungen dieser Lizenz verbreitet werden darf. Ein solcher Hinweis gewährt eine weltweit gültige, tantiemenfreie und zeitlich unbefristete Lizenz, die es gestattet das Werk, unter den hier festgelegten Bedingungen, zu nutzen. Der Begriff Dokument wird im Folgenden für alle solche Handbücher und Werke verwendet. Jede Person kann Lizenznehmer sein und wird im Folgenden mit Sie angesprochen. Sie akzeptieren diese Lizenz, wenn Sie ein Dokument derart kopieren, verändern oder verteilen, daß Sie gemäß den Gesetzen zum Copyright die Erlaubnis benötigen.

Eine modifizierte Version des Dokumentes steht für jedes Werk, das das Dokument als Ganzes oder in Teilen enthält, sowohl auf Datenträger kopiert, als auch mit Änderungen und/oder in andere Sprachen übersetzt.

Ein zweitrangiger Abschnitt ist ein benannter Anhang oder eine Enleitung des Dokumentes, der sich ausschließlich mit dem Verhältnis des Autors oder Verlegers des Dokumentes zu dem eigentlichen Thema des Dokumentes (oder damit zusammenhängender Dinge) beschäftigt, und der nichts enthält, das direkt zu dem eigentlichen Thema gehört. (Wenn das Dokument beispielweise ein Buch über Mathematik ist, dann darf ein zweitrangiger Abschnitt nichts über Mathematik enthalten). Dies kann eine historische Beziehung zu dem Thema, oder damit zusammenhängender Dinge, oder von gesetzlicher, gesellschaftlicher, philosophischer, ethischer oder politischer Art sein, die das Thema betreffen.

Die unveränderlichen Abschnitte sind benannte zweitrangige Abschnitte, deren Titel als unveränderlicher Abschnitt in dem Lizenhinweis, der das Dokument unter diese Lizenz stellt, aufgeführt sind. Wenn ein Abschnitt nicht in die oben stehende Definition eines zweitrangigen Abschnittes passt, dann ist es nicht erlaubt diesen Bereich als unveränderlichen Bereich zu kennzeichnen.

Umschlagtexte sind bestimmte, kurze Textstücke, die als vorderer Umschlagtext oder als hinterer Umschlagtext in der Notiz benannt werden, die besagt, dass das Dokument unter dieser Lizenz freigegeben ist. Ein vorderer Umschlagtext kann bis zu 5 Worte enthalten, ein hinterer Umschlagtext bis zu 25 Worte.

Eine transparente Kopie des Dokumentes bezeichnet eine maschinenlesbare Kopie, dargestellt in einem Format, dessen Spezifikationen allgemein verfügbar sind, und das geeignet ist das Dokument auf einfache Weise mit einem allgemeinen Texteditor oder (für Bilder, die aus Pixeln bestehen) mit einem allgemeinen Bildberabeitungsprogramm oder (für Zeichnungen) mit einem häufig verfügbaren Zeichenprogramm zu überarbeiten, und das geeignet ist es als Eingabe für Textformatierer zu verwenden, oder als Eingabe für automatische Konvertierungsprogramme, die eine Reihe von unterschiedlichen Formaten erzeugen, die ihrerseits als Eingabe für Textformatierer verwendet werden können. Eine Kopie in ein anderes transparentes Dateiformat dessen Auszeichnung oder das fehlen der Auszeichnungen derart beschaffen sind, nachfolgende Modifikationen durch die Leser zu verhindern oder zu erschweren ist nicht transparent. Ein Bildformat ist nicht transparent, wenn es für eine wesentliche Menge von Text verwendet wird. Eine Kopie, die nicht transparent ist, wird als opak bezeichnet.

Beispiele verwendbarer Formate für transparente Kopien schliessen einfachen ASCII-Text ohne Auszeichnungen, TeX-info Eingabe, LaTeX-Eingabeformat, SGML oder XML, sofern die verwendete DTD öffentlich verfügbar ist, sowie standardkonformes, einfaches HTML, Postscript oder PDF, die für Veränderungen durch Menschen entworfen sind, ein.

Beispiele für transparente Bildformate sind u.a. PNG, XCF und JPG. Opake Formate sind unter anderen solche proprietären Formate, die nur von proprietären Textverarbeitungsprogramm gelesen und bearbeitet werden können, SGML oder XML deren DTD und/oder Verarbeitungswerkzeuge nicht allgemein verfügbar sind, und maschinengeneriertes HTML, PostScript oder PDF, das von manchen Textverarbeitungsprogrammen nur zu Ausgabezwecken erzeugt wird.

Mit Titelseite wird in einem gedruckten Buch die eigentliche Titelseite sowie die direkt darauf folgenden Seiten bezeichnet, die all das in lesbarer Form enthalten, was in dieser Lizenz gefordert ist, dass es auf der Titelseite erscheinen muss. Für Werke, die in Formaten vorliegen, die keine Titelseiten haben, gilt als Titelseite der Text, der der auffälligsten Darstellung des Titels des Werkes direkt folgt, aber noch vor dem Inhalt des Werkes steht.

Ein Abschnitt mit dem Titel xyz bezeichnet einen benannten Unterbereich des Dokumentes, dessen Titel entweder genau xyz ist, oder der xyz in Anführungszeichen enthält, der einem Text folgt, der xyz in eine andere Sprache übersetzt. (Hier steht xyz für einen speziellen Abschnittsnamen, der im Folgenden erwähnt wird wie"Danksagung"(Acknowledgements), "Widmung"(Dedications), "Anmerkung"(Endorsement) oder "Historie"(History).). Den Titel erhalten eines Abschnittes bedeutet, daß beim Modifizieren des Dokumentes dieser Abschnitt mit dem Titel xyz bleibt, wie es in dieser Definition festgelegt ist.

Das Dokument kann direkt hinter der Notiz, die besagt, dass das Dokument unter dieser Lizenz freigegeben ist, Garantieausschlüsse enthalten. Diese Garantieausschlüsse werden so behandelt, als seien sie als Referenzen in diese Lizenz eingeschlossen, allerdings nur um Garantien auszuschliessen: Jede andere Implizierung, die dieser Ausschluss hat ist ungültig und keine Wirkung im Sinne dieser Lizenz.

24.3. Datenträgerkopien

Sie dürfen das Dokument auf jedem Medium sowohl kommerziell als auch nicht kommerziell kopieren und verbreiten, vorausgesetzt, daß diese Lizenz, die Copyright-Hinweise sowie der Lizenzhinweis, der besagt, daß diese Lizenz auf das Dokument anzuwenden ist, in allen Kopien reproduziert wird, und daß keine weiteren Bedingungen jeglicher Art zu denen dieser Lizenz hinzugefügt werden. Sie dürfen in den Kopien, die Sie erstellen oder verbreiten, keinerlei technische Maßnahmen treffen um das Lesen oder das weitere Kopieren zu erschweren oder zu kontrollieren. Dennoch dürfen Sie Gegenleistungen für Kopien akzeptieren. Wenn Sie eine ausreichend große Menge von Kopien verteilen, müssen Sie zusätzlich die bestimmungen von Ziffer 4 beachten. Sie können ausserdem unter denselben Bedingungen, die oben angeführt sind, Kopien verleihen und sie können Kopien auch öffentlich bewerben.

24.4. Kopien in Stückzahlen

Wenn Sie gedruckte Kopien des Dokumentes (oder Kopien auf Medien, die üblicherweise gedruckte Umschläge haben), in einer Stückzahl von mehr als 100 veröffentlichen, und der Lizenzhinweis des Dokumentes Umschlagtexte verlangt, müssen die Kopien in Hüllen verpackt sein, die alle diese Umschlagtexte klar und lesbar enthalten. Die vorderen Umschlagtexte auf dem vorderen Umschlag, die hinteren Umschlagtexte auf dem hinteren Umschlag. Beide Umschläge müssen Sie ausserdem klar und lesbar als den Herausgeber dieser Kopien benennen. Der vordere Umschlag muss den gesamten Titel darstellen, mit allen Worten gleich auffällig und sichtbar. Sie können weiteres Material den Umschlägen hinzufügen. Das Kopieren mit Änderungen, die auf Umschläge begrenzt sind, können, so lange der Titel des Dokuments erhalten bleibt, ansonsten als Datenträgerkopien behandelt werden.

Wenn der vorgeschriebene Text für einen der Umschläge zu umfangreich ist um lesbar zu bleiben, sollten Sie den ersten der aufgelisteten Texte auf den aktuellen Umschlag nehmen (so viel wie vernünftigerweise möglich ist) und den Rest auf direkt angrenzenden Seiten.

Wenn Sie mehr als 100 opake Kopien veröffentlichen oder verbreiten, müssen Sie entweder eine maschinenlesbare, transparente Kopie jeder opaken Kopie beilegen, oder mit bzw. in jeder opaken Kopie eine Computer-Netzwerk Adresse angeben, von wo die allgemeine, netzwerk benutzende Öffentlichkeit, Zugriff zum Download einer kompletten transparenten Kopie über öffentliche Standardnetzwerkprotokolle hat.

Wenn Sie sich für die letztere Möglichkeit entscheiden, müssen Sie mit Beginn der Verbreitung der opaken Kopien in Stückzahlen, zumutbare und vernünftige Schritte unternehmen, um sicher zu stellen, daß die transparenten Kopien mindestens ein Jahr nach der Auslieferung der letzten opaken Kopie (direkt oder über einen Agenten oder Händler) dieser Ausgabe an die Öffentlichkeit, an der genannten Adresse verfügbar bleiben.

Es ist erbeten, aber nicht gefordert, daß Sie ausreichend lange vor der Auslieferung einer grösseren Menge von Kopien, Kontakt mit den Autoren des Dokumentes aufnehmen, um jenen die Möglichkeit zu geben, Ihnen eine aktualisierte Version des Dokumentes zuzuleiten.

24.5. Modifikationen

Unter den obigen Bedingungen unter Ziffer 3 und 4 können Sie modifizierte Versionen kopieren und verbreiten, vorausgesetzt, daß Sie die modifizierte Version unter exakt dieser Lizenz herausgeben, wobei die modifizierte Version die Rolle des Dokumentes einnimmt, und dadurch die weitere Modifikation und Verbreitung an jeden Lizensieren, der eine Kopie davon besitzt. Zusätzlich müssen Sie die folgenden Dinge in der modifizierten Version beachten:

  1. Benutzen Sie auf der Titelseite (und auf Umschlägen, sofern vorhanden) einen Titel, der sich von dem Titel des Dokumentes und von früheren Versionen unterscheidet. (Die früheren Versionen sollten, wenn es welche gibt, in dem Abschnitt Historie aufgelistet werden.) Sie können denselben Titel wie den einer Vorgängerversion verwenden, wenn der ursprüngliche Herausgeber damit einverstanden ist.

  2. Geben Sie auf der Titelseite eine oder mehrere Personen oder Einheiten, die als Autoren auftreten können, als für die Modifikationen verantwortliche Autoren der modifizierten Version, zusammen mit mindestens fünf der ursprünglichen Autoren der Ursprungsversion an (alle vorherige Autoren, wenn es weniger als fünf sind), es sei denn diese befreien Sie von dieser Notwendigkeit.

  3. Geben Sie auf der Titelseite den Namen des Herausgebers als Herausgeber an.

  4. Erhalten Sie alle Copyright-Vermerke des Dokumentes.

  5. Setzen Sie einen passenden Copyright-Vermerk für Ihre Modifikationen direkt hinter die anderen Copyright-Vermerke.

  6. Schliessen Sie direkt hinter den Copyright-Vermerken einen Lizenzhinweis ein, der die öffentliche Erlaubnis erteilt, die modifizierte Version unter den Bedingungen dieser Lizenz zu benutzen, wie es im Anhang weiter unten beschrieben ist.

  7. Erhalten Sie im Copyright-Vermerk die komplette Liste der unveränderlichen Abschnitte und obligatorischen Umschlagtexte, die in dem Lizenzvermerk des Dokumentes aufgeführt sind.

  8. Schliessen Sie eine unveränderte Kopie dieser Lizenz mit ein.

  9. Erhalten Sie den Abschnitt "Historie". Erhalten Sie den Titel und fügen Sie einen Punkt hinzu der mindestens den Titel, das Jahr, die neuen Autoren und Herausgeber, wie sie auf der Titelseite aufgeführt sind, enthält. Sollte es keinen Abschnitt Historie geben, dann erstellen Sie einen, der Titel, Jahr, Autor und Herausgeber des Dokumentes, wie auf der Titelseite angegeben, enthält und fügen Sie einen Punkt hinzu, der die modifizierte Version wie oben dargestellt beschreibt.

  10. Erhalten Sie die Netzwerkadresse, die angegeben wurde, um Zugang zu einer transparenten Kopie zu gewähren, sowie entsprechend angegebene Adressen früherer Versionen, auf denen das Dokument aufbaute. Diese Angaben können in den Abschnitt Historie verschoben werden. Sie können die Netzwerkadresse weglassen, wenn sie sich auf ein Werk bezieht, das mindestens 4 Jahre vor dem Dokument selbst veröffentlicht wurde, oder wenn der ursprüngliche Herausgeber der Version, auf die sich die Adresse bezieht, seine Erlaubnis erteilt.

  11. Erhalten Sie für alle Abschnitt, die als Danksagungen(Acknowledgements) oder Widmungen(Dedications) überschrieben sind, den Titel sowie die Substanz und den Ton aller vom Geber gemachten Danksagungen und/oder Widmungen in diesem Abschnitt.

  12. Erhalten Sie alle unveränderlichen Abschnitte unverändert, sowohl im Titel als auch im Text. Abschnittsnummern oder dergleichen gelten hierbei nicht als Teil des Titels.

  13. Löschen Sie alle Abschnitte, die als Anmerkungen(Endorsements) überschrieben sind. Ein solchen Abschnitt sollte nicht in der modifizierten Version enthalten sein.

  14. Benennen Sie keinen Abschnitt in Anmerkungen um, oder in einen Namen, der in Konflikt mit einem unveränderlichen Abschnitt gerät.

  15. Erhalten Sie alle Garantieausschlüsse.

Wenn die modifizierte Version neue Vorspannabschnitte oder Anhänge enthält, die zweitrangige Abschnitte sein können, und die kein vom Dokument kopiertes Material enthalten, können Sie, nach Ihrem Belieben, einige oder alle diese Abschnitte als unveränderliche Abschnitte in die Lizenzanmerkung der modifizierten Version aufnehmen. Diese Titel müssen sich von allen anderen Titeln unterscheiden.

Sie können einen Abschnitt Anmerkungen anfügen, sofern dieser nichts als Bemerkungen, verschiedener Stellen, zu der modifizierten Version enthält. Beispielsweise Publikumsreaktionen oder eine Mitteilung, daß der Text von einer Organisation als maßgebliche Definition eines Standards geprüft wurde.

Sie können einen Teil mit bis zu fünf Worten als vorderen Umschlagtext und einen mit bis zu 25 Worten als hinteren Umschlagtext an das Ende der Liste mit den Umschlagtexten der modifizierten Version hinzufügen. Nur je ein Teil für den vorderen Umschlagtext und den hinteren Umschlagtext können von jeder Einheit hinzugefügt (oder durch entsprechende Anordnung erstellt) werden.

Wenn das Dokument bereits einen Umschlagtext für denselben Umschlag enthält, das von Ihnen oder der Einheit, in deren Namen Sie tätig sind, bereits früher eingefügt wurde, dürfen Sie keine neue hinzufügen. Sie können aber den alten ersetzen, wenn sie die ausdrückliche Genehmigung des Herausgebers haben, der den früheren Text eingefügt hat.

Der/die Autor(en) und Herausgeber des Dokumentes geben duch diese Lizenz weder implizit noch explizit die Erlaubnis ihren Namen für Werbung in den Anmerkungen der modifizierten Version zu benutzen.

24.6. Dokumente Kombinieren

Sie können mehrere Dokumente, die unter dieser Lizenz freigegeben sind, unter den Bedingungen unter Ziffer 5 für modifizierte Versionen miteinander kombinieren, vorausgesetzt, daß in der Kombination alle unveränderlichen Abschnitte aller Originaldokumente, enthalten sind, und daß Sie diese alle in der Liste der unveränderlichen Abschnitte der Lizenzanmerkung des kombinierten Dokumentes aufführen, sowie alle Garantieausschlüsse erhalten.

Das kombinierte Werk braucht nur eine Kopie dieser Lizenz zu enthalten, und mehrere identische unveränderliche Abschnitte können durch eine einzelne Kopie ersetzt werden. Wenn es mehrere unveränderliche Abschnitte mit unterschiedlichem Inhalt aber gleichem Namen gibt, machen Sie den Namen eindeutig, indem Sie am Ende des Titels, in Anführungszeichen, den Namen des original Autors oder Herausgebers, falls bekannt, oder andernfalls eine eindeutige Nummer anhängen. Machen Sie dasselbe mit den Titeln der Abschnitte in der Liste der unveränderlichen Abschnitte im Lizenzhinweis des kombinierten Werkes.

In der Kombination müssen Sie alle Abschnitte mit dem Titel Historie in den unterschiedlichen Dokumenten zu einem einzelnen Abschnit Historie zusammenführen; entsprechend verfahren Sie mit den Abschnitten Danksagungen und Widmungen. Sie müssen alle Abschnitte mit dem Titel Anmerkungen löschen.

24.7. Sammlungen von Dokumenten

Sie können eine Sammlung von Dokumenten erstellen, bestehend aus diesem Dokument und weiteren, unter dieser Lizenz stehenden Dokumenten, wobei Sie die einzelnen Kopien dieser Lizenz in den verschiedenen Dokumenten durch eine einzelne Kopie, die in der Sammlung enthalten ist, ersetzen, vorausgesetzt, Sie befolgen in allen andern Punkten, für jedes der Dokumente, die Regeln für Datenträgerkopien.

Sie können ein einzelnes Dokument aus einer solchen Sammlung herausziehen und einzeln unter dieser Lizenz verbreiten, vorausgesetzt, Sie fügen eine Kopie dieser Lizenz in das extrahierte Dokument ein, und befolgen ansonsten die Bedingungen dieser Lizenz für Datenträgerkopien.

24.8. Aggregation mit unabhängigen Werken

Eine Zusammenstellung des Werkes, oder von Ableitungen davon, mit anderen, separaten und unabhängigen Dokumenten oder Werken, in oder auf demselben Band eines Speicher- oder Verbreitungsmediums, wird dann eine Aggregation genannt, wenn die Copyrights der Zusammenstellung nicht dazu verwendet werden die Rechte der Benutzer, die für die einzelnen Werke gewährt werden, stärker zu beschränken als dies durch die Lizenzen der einzelnen Werke geschieht. Wenn das Werk in einer Aggregation vorhanden ist, so gilt diese Lizenz nicht für die anderen Werke dieser Aggregation, die keine Ableitung des Dokumentes sind.

Wenn die Bestimmungen für die Umschlagtexte aus Ziffer 4 Anwendung finden, und wenn das Dokument weniger als die Hälfte der gesammten Aggregation ausmacht, dann können die Umschlagtexte auf Seiten gesetzt werden, die das Dokument innerhalb der Aggregation umschliessen, oder auf das elektronische Äquivalent eines Umschlages, wenn das Dokument in elektronischer Form vorliegt. Andernfalls müssen sie auf gedruckten Umschlägen erscheinen, die das gesamte Werk umschliessen.

24.9. Übersetzung

Übersetzungen werden als eine Art von Modifikationen betrachtet. Damit können Sie eine Übersetzung des Dokumentes unter den Bestimmungen von Ziffer 5 verbreiten. Um die unveränderlichen Abschnitte durch eine Übersetzung zu ersetzen, benötigen Sie die spezielle Erlaubnis des Copyright-Inhabers. Sie können allerdings Übersetzungen von einigen oder allen unveränderlichen Abschnitten zu den original Versionen der unveränderlichen Abschnitte hinzufügen. Sie können eine Übersetzung dieser Lizenz und allen Lizenzhinweisen im Dokument sowie allen Garantieausschlüssen hinzufügen, vorausgesetzt, daß Sie ebenso die originale englische Version dieser Lizenz und aller Hinweise und Ausschlüsse beifügen. Sollten die Übersetzung und die Originalversion dieser Lizenz oder eines Hinweises oder Ausschlusses voneinander abweichen, so hat die Originalversion vorrang.

Wenn ein Abschnitt des Dokumentes als Danksagung, Widmungen oder Historie überschrieben ist, so erfordert die Forderung (Ziffer 5) den Titel dieses Abschnittes zuerhalten, die Änderung des aktuellen Titels.

24.10. Abschlussbestimmungen

Sie dürfen dieses Dokument nicht kopieren, verändern, unterlizensieren oder verteilen mit der Ausnahme, daß Sie es ausdrücklich unter dieser Lizenz tun. Jedweder andere Versuch zu kopieren, zu modifizieren, unter zu lizensieren oder zu verbreiten ist unzulässig und führt automatisch zum Entzug der durch diese Lizenz gewährten Rechte. Dennoch verlieren jene Parteien, die von ihnen Kopien oder Rechte unter dieser Lizen erhalten haben, nicht Ihre Rechte, so lange sie sich in völliger Übereinstimmung mit der Lizenz befinden.

24.11. Spätere Überarbeitungen dieser Lizenz

Die Free Software Foundation kann von Zeit zu Zeit neue, überarbeitete Versionen der GNU Free Dokumentation License veröffentlichen. Diese neuen Versionen werden im Geiste gleich bleiben, können sich aber in Details unterscheiden um neuen Problemen oder Besorgnissen gerecht zu werden. Siehe: http://www.gnu.org/copyleft/.

Jede Version dieser Lizenz erhält eine eigene Versionsnummer. Wenn das Dokument bestimmt, daß eine bestimmt numerierte Version oder jede spätere Version dafür gilt, haben Sie die Wahl den Bestimmungen dieser speziell benannten Version zu folgen, oder jeder Version, die später von der Free Software Foundation, nicht als Entwurf, veröffentlicht wurde.

24.12. Anhang: Wie Sie diese Lizenz für Ihre Dokumente verwenden können

Um diese Lizenz in einem Dokument zu verwenden, das sie selbst geschrieben haben, schliessen Sie eine Kopie dieser Lizenz (eine englische Kopie des Originals anm. des Übersetzers) in Ihr Dokument mit ein, und setzen Sie den folgenden Copyright- und Lizenzhinweis gleich hinter die Titelseite:

Copyright (c) YEAR YOUR NAME Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".

Es folgt eine Übersetzung des oben stehenden Hinweises, der nur zur Klarheit hier angegeben ist ! (anm.: des Übersetzers) Copyright Jahr Ihr Name Kopieren, Verbreiten und/oder Modifizieren ist unter den Bedingungen der GNU Free Documentation License, Version 1.2 oder einer späteren Version, veröffentlicht von der Free Software Foundation, erlaubt. Es gibt keine unveränderlichen Abschnitte, keinen vorderen Umschlagtext und keinen hinteren Umschlagtext Eine Kopie des Lizenztextes ist unter dem Titel GNU Free Documentation License enthalten. (Ende der Übersetzung des Lizenzhinweistextes)

Wenn Sie unveränderlichen Abschnitte, vordere und hintere Umschlagtexte haben, ersetzen Sie die Zeile: "Es gibt keine…​…​ Umschlagtext" durch die Folgende: Mit den unveränderlichen Abschnitten: Liste dem den Titeln der unveränderlichen Abschnitte mit dem vorderen Umschlagtext: vorderer Umschlagtext und dem hinteren Umschlagtext: hinterer Umschlagtext

Wenn Sie unveränderliche Abschnitte, aber keine Umschlagtexte oder irgend eine andere Kombination der drei Bereiche haben, mischen Sie die verschiedenen Alternativen, daß sie zu Ihren Anforderungen passen.

Wenn Ihr Dokument nicht-triviale Codebeispiele enthält empfehlen wir diese Beispiele parrallel unter einer freien Softwarelizenz Ihrer Wahl, beispielsweise der GNU General Public License zu lizensieren, um ihren Gebrauch in freier Software zu erlauben.

25. Danksagung

Danke an alle, welche mir geholfen haben, dieses Programmpaket zu realisieren.

Vielen Dank an die Entwickler von GFA-Basic. Dieses BASIC brachte mich in den 1980er Jahren dazu, mit dem Programmieren anzufangen. Viele Ideen und die Syntax der meisten Kommandos wurden von der ATARI ST Implementierung übernommen.

Danke an sourceforge.net dafür, daß sie diesem Projekt eine WEB-Präsenz verleihen.

Besonderer Dank gilt folgenden Leuten, welche mir erst kürzlich geholfen haben:

2013
  • Matthias Vogl (va_copy patch for 64bit version)

  • Eckhard Kruse (for permission to include ballerburg.bas in the samples)

  • Marcos Cruz (beta testing and bug fixing)

  • James V. Fields (beta testing and correcting the manual)

2014
  • John Clemens, Slawomir Donocik, Izidor Cicnapuz, Christian Amler, Marcos Cruz, Charles Rayer, Bill Hoyt, and John Sheales (beta testing and bug fixing)

2015
  • Guillaume Tello, Wanderer, and John Sheales (beta testing and bug fixing)

2016
  • John Sheales (beta testing and bug fixing)

  • bruno xxx (helping with the compilation tutorial for Android)

2017
  • John Sheales (beta testing and bug fixing)

  • David Hall (bug fixing)

  • Emil Schweikerdt (bug fixing)

X11-Basic baut auf einer Vielzahl von (open source) Software auf, welche von vielen Leuten beigesteuert wurde. Erwähnt seien hier nur die Libraries, welche unmittelbar mit dem X11-Basic Paket mitkommen, nämlich:

  • the GNU multiple precision arithmetic library, Version 5.1.3. Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. For details, see: https://gmplib.org/

  • LAPACK (Linear Algebra Package) is a standard software library for numerical linear algebra. For details, see: http://www.netlib.org/lapack/

  • X11-Basic verwendet den lodepng Code für the PNG bitmap graphics support. Copyright © 2005-2013 Lode Vandevenne

  • X11-Basic uses a modified version of the libusb library for accessing the USB-Port

  • X11-Basic verwendet einen MD5-Algorithmus Copyright (c) 2001 von Alexander Peslyak (public domain).

  • X11-Basic verwendet einen sha1-Algorithmus Copyright © 2001-2003 Christophe Devine (GPLv2+)

Daher möchte ich allen für die folgenden Projekte danken:

  • Linux GCC und natürlich alle GNU-Tools.

  • Die Readline-Bibliothek.

  • Die SDL-Bibliothek (Simple Direct Media).

  • Schöpfer des 8x16 Zeichensatzes "spat_a".

  • Die Burrow-Wheeler-Transformation.

  • Und alle anderen von X11-Basic verwendeten Bibliotheken.

Einige Teile von X11-Code basieren auf Software von Drittanbietern:

  • Die Routinen der AES-Benutzerschnittstelle basieren auf OpenGEM.

  • Der FloodFill-Algorithmus basiert auf xxxx.

  • Piktogramme für Mauscursor und Füllmuster basieren auf TOS/ATARI ST.

  • Die adaptive arithmetische Dekodierfunktion Ordnung 0 enthält Quelltext aus dem CACM-Artikel von 1987 von Witten, Neal und Cleary.

Teile dieses Handbuchs (Kapitel CGI-Programmierung) stammen aus oder basieren auf einer Dokumentation, die in den 1990er Jahren verwendet wurde. (Ich hoffe, es war Public Domain oder ähnliches.) Leider habe ich den Link verloren zu seiner Quelle. Wenn Sie Ihre potentielle Quelle kennen, lassen Sie es mich wissen. Dann kann ich es hier zitieren und dem Autor danken.