klass. Basic Standard

darktrym

Fahnenträger
Hallo,
ich beschäftige mich gerade mit Basic und schreibe dafür einen Interpreter in Java. Leider gibt's ja nicht einen Basic Standard sondern Hunderte. Um meinen zu irgendwas kompatibel zu machen, suche ich Referenz evtl auch Beispiele zu den klass. Basic, also kein moderner Schnickschnack. Ich weiß, dass es da ISO Standards gibt, aber die wollen Bares für die Einsichtnahme.:grumble:

Alternativ ein paar Fragen(fürs erste):
  • Strings bearbeiten immer über Funktionen, keine Operatoren vorhanden?
  • Strings und Bearbeitungsfunktionen haben am Ende immer Dollarzeichen im Namen?
  • Gibts implizite Umformungen der Datentypen?
  • nur 2 Datentypen(Float, String), wie wurde Modulo, log. Operatoren, Ganzzahldivision dann umgesetzt?
  • Gibts sowas wie lokale Variablen bspw. in GOSUB(Unterprogrammsprung)?
  • Mehrfachdefinitionen erlaubt?
  • FOR-Schleife Parameter manipulierbar?
  • Überdeckt die Zählvariable in der FOR-Schleife eine globale Variable?
  • Umsetzung andere Schleifen dann über goto?

Mein derzeitiges Basic ist zeilennummerorientiert, soll der komplexitäthalber nur mit klass. Konstrukten arbeiten, also:
LET, GOTO, IF THEN, FOR DO STEP, GOSUB, RETURN, INPUT, PRINT, REM, END usw. und ein paar Builtins.

Zum in Erinnerung schwelgen:
Code:
10 INPUT "What is your name: ", U$
20 PRINT "Hello "; U$
30 INPUT "How many stars do you want: ", N
40 S$ = ""
50 FOR I = 1 TO N
60 S$ = S$ + "*"
70 NEXT I
80 PRINT S$
90 INPUT "Do you want more stars? ", A$
100 IF LEN(A$) = 0 THEN GOTO 90
110 A$ = LEFT$(A$, 1)
120 IF A$ = "Y" OR A$ = "y" THEN GOTO 30
130 PRINT "Goodbye "; U$
140 END

PS: Eine Merkwürdigkeit: PRINT-Parameter werden durch Semikolon getrennt, INPUT-Parameter mit Komma. Und wofür das I hinter NEXT?
 
INPUT geht auch mit Semikolon. In diesem Fall wird immer ein Fragezeichen vor der Eingabe angezeigt. Wird kein Meldetext angegeben, kommt immer ein Fragezeichen. Dies ist schon m.E. bei allen zumindest MBasic, Basic 80, TurboBasic und GFABasic so.


Beim PRINT gibt es auch die Kommatavariante. Bei der Angabe eines Kommas wird quasi in Tabulatorenschritten auf dem Bildschirmen ausgeben: GFABasic 16 Zeichen, MBasic/80 sind es 14 Zeichen.
Für THEN GOTO gibt es auch Alternativen:

IF E=1 THEN 20

auch schon mal so gesehen:

IF E=1 GOTO 20

INT(), STR$(), VAL(), LEN() solltest du m.E. auch noch implementieren.
 
Ohne THEN dürfte C64 Basic sein. Die oben genannten Funktionen sind schon implementiert, die hatte ich zu Builtins gezählt.
Ich vermute mal das NEXT I hat den Zweck sich dem Umweg über den Stack/Speicher zu sparen.
Ich habe hier eine Quelle für ZX81 Basic gefunden, interessant(neben den Zeichensatz) ist hier die int-Funktion:

INT() rundet auf die nächste ganze Zahl ab.
INT( 5.32 ) ergibt 5
INT( -2.3 ) ergibt -3

Da frag' ich mich, was die Leute in den 80igern mit den Listings aus den div. Magazinen, Spielebüchern gemacht haben. Abtippen und anpassen?
 
Um deine Frage zu beantworten: Ja, was sonst?! :)

Mailboxen/BBSen und Internet waren noch nicht in Sicht. Und gute 700-800 DM für ein Floppylaufwerk (1541 für den C64) waren zumindest für Schüler nicht gerade von schlechten Eltern. Selbst wenn man ein Laufwerk hatte, musste man ja ggf. auch noch jemanden kennen, der den Kram schon eingetickert hat :)

Es gab auch Zeitschriften die Listings mit Checksumme je Zeile hatten, damit man keine Tippfehler bei Eingabe mittels entsprechendem Tool macht.

Bitte nicht an ZX-Basic orientieren, dies war wirklich krude. :)

PS: GFA-Basic war damals mein Lieblings-Basic. Das hatte ein paar schöne Features.
 
Hallo,
Ich kann im wesentlichen nur aus C64-Sicht antworten.
  • Strings bearbeiten immer über Funktionen, keine Operatoren vorhanden?
    Es gab den Operator + zur Stringverkettung: PRINT A$+B$;
  • Strings und Bearbeitungsfunktionen haben am Ende immer Dollarzeichen im Namen?
    Ja.
  • Gibts implizite Umformungen der Datentypen?
    Nur zwischen Float und Integer. Von und nach String dann explizit mit VAL und STR$.
  • nur 2 Datentypen(Float, String), wie wurde Modulo, log. Operatoren, Ganzzahldivision dann umgesetzt?
    Datentyp Integer in der Form X%=1, also mit % analog zu $ für String.
    Modulo gab es nicht, da mußte man tricksen. Logische und Bit-Operatoren waren AND, OR, NOT.
  • Gibts sowas wie lokale Variablen bspw. in GOSUB(Unterprogrammsprung)?
    Nein, alles global!
  • Mehrfachdefinitionen erlaubt?
    Du meinst, X$ und X% und X gleichzeitig nebeneinander? Ja.
  • FOR-Schleife Parameter manipulierbar?
    Ja. Sie ist eine ganz normale Variable.
  • Überdeckt die Zählvariable in der FOR-Schleife eine globale Variable?
    Die Zählvariable IST eine globale Variable.
  • Umsetzung andere Schleifen dann über goto?
    Ja. In "besseren" Basic-Varianten gab es auch WHILE und REPEAT ... UNTIL, aber nicht auf dem C64.

Zu den von Dir erwähnten:
LET, GOTO, IF THEN, FOR DO STEP, GOSUB, RETURN, INPUT, PRINT, REM, END
... kommen noch hinzu:
OPEN und CLOSE, GET, READ und DATA, DIM, CLR, DEF FN und halt viele vordefinierte Funktionen wie SQR, INT, ABS, RND, SGN, SIN, COS, TAN, ATN, LOG, EXP, VAL, STR$, ASC, CHR$, LEFT$, MID$, RIGHT$, LEN, POS, SPC, TAB, FRE usw.
Für GOTO und GOSUB gab es noch ON X GOTO und ON Y GOSUB, eine Art Case-Anweisung.
Weggelassen habe ich Kommandozeilenbefehle wie LOAD, die fast nie in Programmen gebraucht wurden, und maschinenbezogene wie POKE.

Und das I hinter NEXT? Das konnte man auch weglassen, dann schloß man automatisch immer die innerste Schleife. Was das folgende Konstrukt machte, weiß ich nicht mehr sicher; ich glaube, die innere Schleife wurde einfach jedes Mal vergessen:
Code:
10 FOR I=1 to 5
20 FOR J=1 to 7
30 PRINT I,J
40 NEXT I
 
Danke erstmal. Aber bei einigen Dingen muss ich nochmal nachharken:
Ist folgende Ausdruck prinzipiell in einer IF Konstruktion erlaubt: A=(B=C), sprich implizite Boolean Umwandlung in Integer mit dem wieder verglichen wird? Bei MBasic war das wohl(false = 0, true= -1) der Fall.

Zur FOR-Schleife, ich kann also im Schleifenkörper, Laufvariable manipulieren? (Achtung: sinnfreier Beispielcode)
Code:
FOR I=1 TO E STEP K:
I = I + 5
NEXT I
Die bisherigen Implementierungen, die ich gesehen habe(auch meine) lassen das zu für I.
Und nochmal globale Variable, also sind alle Variable von überall sichtbar. Bspw.
Code:
I = 2
FOR I=1 TO 10:
NEXT I
REM I sollte nun 10 sein. Auch ohne erste Zeile wäre die Variable weiterhin sichtbar.

ON X GOTO und ON Y GOSUB müsste mir jemand mal erklären wie das funktioniert und wofür man das braucht. Ich versteh die Konstruktion wie folgt: Eingabe einer Zahl n, Sprung an die Zeilennummer, die in der Liste das n-te Element ist. Analog Gosub nur das man nach RETURN wieder an der alten Stelle + 1 ist.
 
Zuletzt bearbeitet:
Ich hatte einen ZX81 und wenn dieses Basic nicht krude ist, dann weiss ich auch nicht mehr (ja, es gibt noch schlimmeres)
 
Danke erstmal. Aber bei einigen Dingen muss ich nochmal nachharken:
Ist folgende Ausdruck prinzipiell in einer IF Konstruktion erlaubt: A=(B=C), sprich implizite Boolean Umwandlung in Integer mit dem wieder verglichen wird? Bei MBasic war das wohl(false = 0, true= -1) der Fall.
Nachhaken reicht schon, nachharken ist nicht nötig. :)
Es gibt keine Boolean-Typen, Vergleichsoperatoren sind nur in der IF-Anweisung erlaubt und werden als Teil deren interpretiert. A=(B=C) ergibt einen Syntax error.
Zur FOR-Schleife, ich kann also im Schleifenkörper, Laufvariable manipulieren?
Ja, ganz beliebig. Dein Beispielcode würde funktionieren. Sobald Du die Variable größer-gleich dem Endwert setzt, erfolgt kein weiterer Durchlauf.
Und nochmal globale Variable, also sind alle Variable von überall sichtbar. Bspw.
Code:
I = 2
FOR I=1 TO 10:
NEXT I
Ja. Am Ende ist hier aber I=11, weil es noch einmal inkrementiert wird, um dann festzustellen, daß der Endwert überschritten ist.

Das mit ON N GOTO hast Du richtig verstanden. ON N GOTO 40,50,60 springt also zu Zeile 60, wenn N=3 ist. Ist N nicht 1, 2 oder 3, wird die Anweisung ignoriert.
 
So 'n Sch***. Folgende Dinge sind bei Basic Programmierern üblich gewesen:

Code:
PRINT "BALA" Z5
Man beachte den fehlenden Separator.

Code:
IF a < = 5 THEN GOTO 23
Erstaunlich, Leerzeichen im Operator. Offensichtlich kann man alle Leerzeichen weglassen. Der Interpreter muss das abkönnen.

Aber der Klassiker:
Code:
363 LET Z4=Z5 
364 LET Z5=0
Variablennutzung bevor man deklariert hat.

PS: Optionale Schlüsselwörter sind auch ganz nett.
 
Code:
IF a < = 5 THEN GOTO 23
Erstaunlich, Leerzeichen im Operator. Offensichtlich kann man alle Leerzeichen weglassen. Der Interpreter muss das abkönnen.
Ja, richtig. Jedes zusätzliche Leerzeichen im Programmcode hat den C64 bei der Interpretation meßbar verlangsamt. Die Anweisung mit "THEN GOTO" lief übrigens dann am schnellsten, wenn man nicht THEN, sondern GOTO weggelassen hat. In Basic-Tokens waren Leerzeichen aber nicht zulässig, also so etwas wie T HEN.
Aber der Klassiker:
Code:
363 LET Z4=Z5 
364 LET Z5=0
Variablennutzung bevor man deklariert hat.
Deklariert wurden Variablen sowieso nicht. Eine Variable war in dem Moment definiert, in dem ihr ein Wert zugewiesen wurde. Undefinierte Variablen waren null bzw. leerer String. Das erinnert ein wenig an die Shellvariablen der Bash.
PS: Optionale Schlüsselwörter sind auch ganz nett.
Du meinst damit LET und die Sache mit THEN GOTO, also Tokens, die man einfach weglassen kann?
 
Ja, Schlüsselwörter die keiner braucht, Leerzeichen die man weglassen kann, unterschied. Parametertrenner oder einfach mal weglassen. Die Krönung aber Printparameter ankündigen und dann keinen folgen lassen.

Ein weiteres Hightlight:
830 IF L>13 THEN L=L-14:R=1:GOTO 830

Erlaubt? Sehr wahrscheinlich soll das wohl als Block interpretiert werden der am Zeilenende aufhört.

Auch gibts solche tollen Varianten von IFs:
Code:
615 IF B(M)=1 THEN IF M<>6 THEN IF M<>13 THEN IF B(12-M)<>0 THEN 625

--
Mal zur Abwechslung ein informationstheoret. Problem.
Ich steh' grad auf dem Schlauch. AND ist sowohl logisch als auch ein binärer Operator.
Meine Logik/Grammatik kommt damit, zu Recht, nicht klar. Bspw. wird folgende Zeile fehlerhaft interpretiert:

Code:
IF A=B AND B=C THEN GOTO 10

Hier kann nur das logische AND verwendet werden, wird aber nicht, weil eine condition aus expression vergleichoperator expression besteht. Da der Interpreter nicht weiß wann die rechte expression aufhört kommts zum Syntaxfehler.
 
Zuletzt bearbeitet:
Ja, Schlüsselwörter die keiner braucht, Leerzeichen die man weglassen kann, unterschied. Parametertrenner oder einfach mal weglassen. Die Krönung aber Printparameter ankündigen und dann keinen folgen lassen.

Nicht umsonst hat Basic keinen guten Ruf :) Man konnte es zwar leicht lernen, aber auch viel Falsch machen. Mit den besser werdenen Editoren (meist mitgeliefert inkl. Syntaxcheck beim Eingeben) wurde es dann besser.

Ein weiteres Hightlight:

Code:
830 IF L>13 THEN L=L-14:R=1:GOTO 830

Erlaubt? Sehr wahrscheinlich soll das wohl als Block interpretiert werden der am Zeilenende aufhört.

Auch gibts solche tollen Varianten von IFs:
Code:
615 IF B(M)=1 THEN IF M<>6 THEN IF M<>13 THEN IF B(12-M)<>0 THEN 625

Mangels Blockfunktionen, war dies leider notwendig. Blöcke mit GOTOs zu realisieren, war kaum wartbar, zumal wenn die Zeilennummern sehr eng ausgelegt waren und man später noch größerere Portitionen Code unterbringen musste... Zeilenbasic war schon wirklich *Sch***e*. Da mussten die Doppelpunkte herhalten. Letzteres Basic kannte wohl AND nicht?! (kein Scherz! :) )

Es bietet sich vllt an, einen Standalone Converter(-> Bytecode) zu bauen, um sich beim Interpreter nur mit halbwegs sauberem Code rumschlagen zu müssen.
 
Zuletzt bearbeitet:
Ja, Schlüsselwörter die keiner braucht, Leerzeichen die man weglassen kann, unterschied. Parametertrenner oder einfach mal weglassen.
Der weggelassene Parametertrenner im PRINT ist IMO eine Schlamperei im Interpreter. Ob Du das unbedingt umsetzen mußt ...
Die Krönung aber Printparameter ankündigen und dann keinen folgen lassen.
Das verstehe ich nicht. Meinst Du einen blanken PRINT-Befehl ohne Parameter? Nun, das ist dasselbe wie ein blanker echo-Befehl in der Bash. Was ist so schlimm daran?
Code:
830 IF L>13 THEN L=L-14:R=1:GOTO 830
Sehr wahrscheinlich soll das wohl als Block interpretiert werden der am Zeilenende aufhört.
Nein. Zumindest auf dem C64 gibt es keine Blöcke. Das IF-Konstrukt endet am ersten Doppelpunkt. R=1 usw. wird auf jeden Fall ausgeführt. Die Zeile ergibt eine Endlosschleife.
Code:
615 IF B(M)=1 THEN IF M<>6 THEN IF M<>13 THEN IF B(12-M)<>0 THEN 625
Das gibt es in jeder Programmiersprache, aber es ist natürlich ein dummes Konstrukt.
Code:
IF A=B AND B=C THEN GOTO 10
Hier kann nur das logische AND verwendet werden, wird aber nicht, weil eine condition aus expression vergleichoperator expression besteht. Da der Interpreter nicht weiß wann die rechte expression aufhört kommts zum Syntaxfehler.
Ebenso wie das Gleichheitszeichen hat auch der Operator AND innerhalb von IF eine Sonderbedeutung. Dein Interpreter muß ihn dort grundsätzlich als logischen Operator betrachten. Ob wenigstens ein AND innerhalb von Klammern als binäres AND akzeptiert wird, weiß ich jetzt nicht mehr, aber außerhalb von Klammern ist es im IF ein logischer Operator. Basta!
Kontextabhängige Interpretation ist unfein, da stimme ich Dir schon zu. :)
 
Mangels Blockfunktionen, war dies leider notwendig. Blöcke mit GOTOs zu realisieren, war kaum wartbar, zumal wenn die Zeilennummern sehr eng ausgelegt waren und man später noch größerere Portitionen Code unterbringen musste... Zeilenbasic war schon wirklich *Sch***e*.
Bei QBasic gab’s dafür glücklicherweise SUBs.
 
Jupp, das Problem hatte sich mit dem Wegfallen der Zeilennummerierung bei diversen Basics dann gegeben... TurboBasic, QBasic, GFA, Omikron und wie sie dann alle hiessen. Da kam dann bei mir aber auch die Zeit, um auf C -> TurboC umzusteigen.
 
Zurück
Oben