mirror of
https://github.com/forth-ev/VolksForth.git
synced 2024-11-25 10:30:57 +00:00
Reformatted Errorhandler Article
This commit is contained in:
parent
449712dcce
commit
cafe4b5ca6
@ -2,14 +2,9 @@ ERR.ART
|
|||||||
Korrektur clv03jul89
|
Korrektur clv03jul89
|
||||||
Entwurf clv01mar88
|
Entwurf clv01mar88
|
||||||
|
|
||||||
set margins 1 40
|
|
||||||
(mit c-t in Kommandozeile)
|
|
||||||
|
|
||||||
|
|
||||||
Titel:
|
Titel:
|
||||||
|
|
||||||
Behandlung von Ausnahmesituationen in
|
Behandlung von Ausnahmesituationen in Forth83
|
||||||
Forth83
|
|
||||||
|
|
||||||
Stichworte:
|
Stichworte:
|
||||||
|
|
||||||
@ -19,194 +14,114 @@ exception handling
|
|||||||
volksFORTH83
|
volksFORTH83
|
||||||
returnstack
|
returnstack
|
||||||
|
|
||||||
Kurzfassung:
|
Kurzfassung: Ausgehend von einer Analyse des Bedürfnisses nach
|
||||||
Ausgehend von einer Analyse
|
programmspezifische Fehlerbehandlung (die insbesondere zum erweiterten
|
||||||
des Bed<65>rfnisses nach
|
Begriff des 'Exception handling' führt) werden Konzepte aus
|
||||||
programmspezifische Fehlerbehandlung
|
verschiedenen Programmiersprachen sowie zu Forth83 vorgeschlagene
|
||||||
(die insbesondere zum erweiterten
|
Konzepte auf ihre Brauchbarkeit hin diskutiert. Es folgt eine unter
|
||||||
Begriff des 'Exception handling' f<>hrt)
|
ultraFORTH83 rev 3.8 auf einem C16 entwickelte Lösung des Autors, die
|
||||||
werden Konzepte aus verschiedenen Programmiersprachen
|
abhängig von der Ausführungsebene eine spezielle mittels FAILS..THEN
|
||||||
sowie zu Forth83 vorgeschlagene Konzepte
|
installierte Behandlung der Worte ABORT" und ERROR" gestattet.
|
||||||
auf ihre Brauchbarkeit
|
|
||||||
hin diskutiert. Es folgt eine unter
|
|
||||||
ultraFORTH83 rev 3.8 auf einem C16
|
|
||||||
entwickelte
|
|
||||||
L”sung des Autors, die abh„ngig von
|
|
||||||
der Ausf<73>hrungsebene eine spezielle
|
|
||||||
mittels FAILS..THEN installierte
|
|
||||||
Behandlung der Worte ABORT" und ERROR"
|
|
||||||
gestattet.
|
|
||||||
|
|
||||||
o Die derzeitige Fehlerbehandlung
|
* Die derzeitige Fehlerbehandlung in Forth: ABORT"
|
||||||
in Forth: ABORT"
|
|
||||||
|
|
||||||
Im 83er-Standard ist das zentrale Wort
|
Im 83er-Standard ist das zentrale Wort zur Fehlerbehandlung ABORT". Es
|
||||||
zur Fehlerbehandlung ABORT". Es
|
gibt den folgenden String als Fehlernachricht aus, versetzt das System
|
||||||
gibt den folgenden String als
|
in einen (einigermaßen) definierten Zustand und ruft das
|
||||||
Fehlernachricht aus, versetzt das System
|
Top-Level-Wort QUIT auf, das Eingaben von der Tastatur entgegennimmt
|
||||||
in einen (einigermaáen) definierten
|
und verarbeitet. Jedes laufende Programm wird also ohne Rücksicht auf
|
||||||
Zustand und ruft das Top-Level-Wort QUIT
|
Verluste gestoppt und gewissermaßen Forth neu gestartet. Eine ähnliche
|
||||||
auf, das Eingaben von der Tastatur
|
Wirkung haben die Worte ABORT und QUIT.
|
||||||
entgegennimmt und verarbeitet.
|
|
||||||
Jedes laufende Programm wird also ohne
|
|
||||||
R<EFBFBD>cksicht auf Verluste gestoppt und
|
|
||||||
gewissermaáen Forth neu gestartet.
|
|
||||||
Eine „hnliche Wirkung haben die Worte
|
|
||||||
ABORT und QUIT.
|
|
||||||
|
|
||||||
Im ultraFORTH83/volksFORTH83 gibt es
|
Im ultraFORTH83/volksFORTH83 gibt es ein Wort ERROR", das sich von
|
||||||
ein Wort ERROR", das sich von ABORT" nur
|
ABORT" nur dadurch unterscheidet, daß der Datenstack nicht gelöscht
|
||||||
dadurch unterscheidet, daá der
|
wird. Desweiteren enthält dieses Forth eine User-Variable
|
||||||
Datenstack nicht gel”scht wird.
|
ERRORHANDLER, die es ermöglicht, ein anderes Verhalten von ABORT" und
|
||||||
Desweiteren enth„lt dieses Forth eine
|
ERROR" zu installieren.
|
||||||
User-Variable ERRORHANDLER, die es
|
|
||||||
erm”glicht, ein anderes Verhalten von
|
|
||||||
ABORT" und ERROR" zu installieren.
|
|
||||||
|
|
||||||
|
* Was soll eine Fehlerbehandlung können
|
||||||
|
|
||||||
o Was soll eine Fehlerbehandlung
|
Diese Art der Fehlerbehandlung funktioniert zwar meistens recht gut,
|
||||||
k”nnen
|
wirft aber einige Probleme auf. Im folgenden wird versucht, folgende
|
||||||
|
|
||||||
Diese Art der
|
|
||||||
Fehlerbehandlung
|
|
||||||
funktioniert zwar meistens recht gut,
|
|
||||||
wirft aber einige Probleme auf.
|
|
||||||
Im folgenden wird versucht, folgende
|
|
||||||
Stichworte zu diskutieren:
|
Stichworte zu diskutieren:
|
||||||
|
|
||||||
- Reservierte Ressourcen
|
- Reservierte Ressourcen schließen
|
||||||
schlieáen
|
- Das Level, auf dem die Behandlung erfolgt
|
||||||
- Das Level, auf dem die Behandlung
|
- Informationen über den Fehlerzustand erhalten.
|
||||||
erfolgt
|
- Übersichtliche Behandlung selten auftretender Ereignisse
|
||||||
- Informationen <20>ber den
|
- Fehler auch während der Fehlerbehandlung (ohne Endlosschleifen)
|
||||||
Fehlerzustand erhalten.
|
|
||||||
- šbersichtliche Behandlung
|
|
||||||
selten auftretender Ereignisse
|
|
||||||
- Fehler auch w„hrend der
|
|
||||||
Fehlerbehandlung (ohne
|
|
||||||
Endlosschleifen)
|
|
||||||
|
|
||||||
Hierbei flieáen jeweils die Erfahrungen
|
Hierbei fließen jeweils die Erfahrungen des Autors mit MS-DOS, Pascal,
|
||||||
des Autors mit MS-DOS, Pascal,
|
|
||||||
Modula-2, Fortran und TLC-Lisp mit ein.
|
Modula-2, Fortran und TLC-Lisp mit ein.
|
||||||
|
|
||||||
o Schlieáen von Ressourcen
|
* Schließen von Ressourcen
|
||||||
|
|
||||||
Das Wort ABORT" (so es im Quelltext
|
Das Wort ABORT" (so es im Quelltext vorliegt) zeigt bereits daß im
|
||||||
vorliegt) zeigt bereits daá im
|
Fehlerfalle gewisse Systemressourcen wieder freigegeben werden müssen.
|
||||||
Fehlerfalle gewisse Systemressourcen
|
Zumindest dürfte in jedem System der Return-stack entleert werden, oft
|
||||||
wieder freigegeben werden m<>ssen.
|
auch der Datenstack, vielleicht werden sogar gewisse Systemvektoren
|
||||||
Zumindest d<>rfte in jedem System der
|
restauriert (insb. für die Standard-Ein/Ausgabe scheint das geraten).
|
||||||
Return-stack entleert werden, oft auch
|
Falls das Programm gewisse weitere Ressourcen reserviert hat, werden
|
||||||
der Datenstack, vielleicht werden
|
sie nicht wieder frei gegeben. Dies könnte ein geöffnetes File sein,
|
||||||
sogar gewisse Systemvektoren restauriert
|
das nicht geschlossen wird; ein Semaphor, das gelockt bleibt; ein
|
||||||
(insb. f<>r die Standard-Ein/Ausgabe
|
menüartiger Bildschirm, der weiter in allen Farben des Spektrums
|
||||||
scheint das geraten).
|
blinkt; eine hoffnungslos verdrehte Schnittstelle etc.. Am
|
||||||
Falls das Programm gewisse
|
auffälligsten ist eine z.B. auf den Drucker umgeleitete
|
||||||
weitere Ressourcen
|
Standardausgabe, wenn sie von ABORT" nicht restauriert wird.
|
||||||
reserviert hat, werden sie nicht wieder
|
|
||||||
frei gegeben. Dies k”nnte ein ge”ffnetes
|
|
||||||
File sein, das nicht geschlossen wird;
|
|
||||||
ein Semaphor, das gelockt bleibt; ein
|
|
||||||
men<EFBFBD>artiger Bildschirm, der weiter in
|
|
||||||
allen Farben des Spektrums blinkt; eine
|
|
||||||
hoffnungslos verdrehte Schnittstelle
|
|
||||||
etc.. Am auff„lligsten ist eine z.B. auf
|
|
||||||
den Drucker umgeleitete Standardausgabe,
|
|
||||||
wenn sie von ABORT" nicht restauriert
|
|
||||||
wird.
|
|
||||||
In diesem Fall wird schon die Ausgabe
|
|
||||||
der ABORT"-Meldung (auf den Drucker)
|
|
||||||
fehlschlagen, insb. wenn die gew<65>nschte
|
|
||||||
Fehlermeldung "Drucker ausgeschaltet"
|
|
||||||
heiáen mag. Dieser Effekt wird in jedem
|
|
||||||
intelligenten Forth-System nat<61>rlich
|
|
||||||
abgefangen, unter MS-DOS l„át er
|
|
||||||
sich allerdings noch sehr h<>bsch
|
|
||||||
beobachten. Die gelockten Semaphore
|
|
||||||
machen sich allerdings - in seltenen
|
|
||||||
F„llen - auch unter volksFORTH
|
|
||||||
bemerkbar. V”llig hoffnungslos wird der
|
|
||||||
Fall, wenn eine grӇere
|
|
||||||
Stand-Alone-Anwendung (z.B. ein
|
|
||||||
f<EFBFBD>rchterlich kompliziertes Men<65>programm)
|
|
||||||
grade s„mtliche Systemvektoren
|
|
||||||
erfolgreich verbogen hat und nun durch
|
|
||||||
einem j„mmerlich kleinen Fehler
|
|
||||||
(vielleicht einen offengelassener
|
|
||||||
Diskettenschacht) j„h in die
|
|
||||||
Forth-Hauptschleife geschleudert wird.
|
|
||||||
|
|
||||||
o Auf welcher Programmebene soll der
|
In diesem Fall wird schon die Ausgabe der ABORT"-Meldung (auf den
|
||||||
Fehler behandelt werden?
|
Drucker) fehlschlagen, insb. wenn die gewünschte Fehlermeldung
|
||||||
|
"Drucker ausgeschaltet" heißen mag. Dieser Effekt wird in jedem
|
||||||
|
intelligenten Forth-System natürlich abgefangen, unter MS-DOS läßt er
|
||||||
|
sich allerdings noch sehr hübsch beobachten. Die gelockten Semaphore
|
||||||
|
machen sich allerdings - in seltenen Fällen - auch unter volksFORTH
|
||||||
|
bemerkbar. Völlig hoffnungslos wird der Fall, wenn eine größere
|
||||||
|
Stand-Alone-Anwendung (z.B. ein fürchterlich kompliziertes
|
||||||
|
Menüprogramm) grade sämtliche Systemvektoren erfolgreich verbogen hat
|
||||||
|
und nun durch einem jämmerlich kleinen Fehler (vielleicht einen
|
||||||
|
offengelassener Diskettenschacht) jäh in die Forth-Hauptschleife
|
||||||
|
geschleudert wird.
|
||||||
|
|
||||||
In einem Fall
|
* Auf welcher Programmebene soll der Fehler behandelt werden?
|
||||||
wie letzterem w„re es sogar denkbar,
|
|
||||||
den Fehler noch innerhalb der
|
In einem Fall wie letzterem wäre es sogar denkbar, den Fehler noch
|
||||||
Systemroutinem (in diesem Fall in der
|
innerhalb der Systemroutinem (in diesem Fall in der Block-Lese-Routine
|
||||||
Block-Lese-Routine des Betriebssystem)
|
des Betriebssystem) zu beseitigen (z.B. den Benutzer aufzufordern,
|
||||||
zu beseitigen
|
doch bitte den Schacht zu schließen) und anschließend fortzufahren,
|
||||||
(z.B. den Benutzer aufzufordern, doch
|
ohne daß das darüberliegende Programm etwas bemerkt. Derartiges kann
|
||||||
bitte den Schacht zu schlieáen) und
|
sogar MS-DOS. Alle Fehler die in Zusammenhang mit Diskettenlaufwerkern
|
||||||
anschlieáend fortzufahren, ohne daá
|
stehen werden noch innerhalb des Betriebssystems mit einer Meldung der
|
||||||
das dar<61>berliegende Programm etwas
|
|
||||||
bemerkt. Derartiges kann sogar MS-DOS.
|
|
||||||
Alle Fehler die
|
|
||||||
in Zusammenhang mit Diskettenlaufwerkern
|
|
||||||
stehen werden noch innerhalb des
|
|
||||||
Betriebssystems mit einer Meldung der
|
|
||||||
Form:
|
Form:
|
||||||
|
|
||||||
allgemeiner Fehler. Kaffee in Laufwerk A:
|
allgemeiner Fehler. Kaffee in Laufwerk A:
|
||||||
(A)bbruch, (W)iederholen, (I)gnorieren ?
|
(A)bbruch, (W)iederholen, (I)gnorieren ?
|
||||||
|
|
||||||
beantwortet. Der Benutzer kann sich nun
|
beantwortet. Der Benutzer kann sich nun für eine der Alternativen
|
||||||
f<EFBFBD>r eine der Alternativen entscheiden.
|
entscheiden. Tippt er 'W', so versucht das System denselben Zugriff
|
||||||
Tippt er 'W', so versucht das System
|
nochmal. Dies ist bei einem offen gelassenen Schacht nützlich, gegen
|
||||||
denselben Zugriff nochmal. Dies ist bei
|
Kaffee hilft es natürlich nicht. 'A' terminiert das laufende Programm
|
||||||
einem offen gelassenen Schacht n<>tzlich,
|
und springt zurück ins Betriebssystem (in etwa wie unser QUIT). Dies
|
||||||
gegen Kaffee hilft es nat<61>rlich nicht.
|
funktioniert meistens, es sei denn das Betriebssystem möchte selbst
|
||||||
'A' terminiert das laufende Programm und
|
Teile seiner selbst von der Diskette lesen: Wir bekommen die beliebte
|
||||||
springt zur<75>ck ins Betriebssystem (in
|
Endlosschleife, bis wir eine saubere Diskette eingelegt haben. Die
|
||||||
etwa wie unser QUIT). Dies funktioniert
|
Alternative 'I' ist die hübscheste. Das System vergißt die Operation
|
||||||
meistens, es sei denn das Betriebssystem
|
und kehrt ins rufende Programm zurück. Dieses arbeitet brav weiter,
|
||||||
m”chte selbst Teile seiner selbst von
|
bis es sich an irgendwelchenden Zufallsergebnissen den Magen verdirbt.
|
||||||
der Diskette lesen: Wir bekommen die
|
Um zum Beispiel des Menü-Programms mit offenen Kassettenschacht noch
|
||||||
beliebte Endlosschleife, bis wir eine
|
ein Wort zu verlieren: Beim 'W'iederholen ist natürlich trotz allem
|
||||||
saubere Diskette eingelegt haben.
|
der Bildschirmaufbau im Eimer. Bis hierher läßt sich erstmal
|
||||||
Die Alternative 'I' ist die h<>bscheste.
|
formulieren, daß die Fehlerbehandlung lieber auf der Ebene des
|
||||||
Das System vergiát die Operation und
|
Anwenderprogramms erfolgen sollte.
|
||||||
kehrt ins rufende Programm zur<75>ck.
|
|
||||||
Dieses arbeitet brav weiter, bis es
|
|
||||||
sich an irgendwelchenden Zufallsergebnissen
|
|
||||||
den Magen verdirbt. Um zum Beispiel
|
|
||||||
des Men<65>-Programms mit offenen
|
|
||||||
Kassettenschacht noch ein Wort zu
|
|
||||||
verlieren: Beim 'W'iederholen ist
|
|
||||||
nat<EFBFBD>rlich trotz allem der
|
|
||||||
Bildschirmaufbau im Eimer. Bis hierher
|
|
||||||
l„át sich erstmal formulieren, daá
|
|
||||||
die Fehlerbehandlung lieber auf der
|
|
||||||
Ebene des Anwenderprogramms erfolgen
|
|
||||||
sollte.
|
|
||||||
|
|
||||||
o Warum eigentlich nur Fehler mit
|
* Warum eigentlich nur Fehler mit Methoden der Fehlerbehandlung behandeln?
|
||||||
Methoden der Fehlerbehandlung
|
|
||||||
behandeln?
|
|
||||||
|
|
||||||
Um diesem h<>bschen Wortspiel Sinn zu
|
Um diesem hübschen Wortspiel Sinn zu geben, mag ein anderes Beispiel
|
||||||
geben, mag ein anderes Beispiel
|
herhalten. Ein Programm lese Daten von einem File, verarbeite sie und
|
||||||
herhalten.
|
schreibe das Ergebnis auf ein anderes File. Es muß somit (wenn es
|
||||||
Ein Programm lese
|
strukturiert sein möchte) vor dem Lesen jedes einzelnen Zeichens das
|
||||||
Daten von einem File, verarbeite sie und
|
Betriebssystem befragen, ob das File vielleicht schon erschöpft ist.
|
||||||
schreibe das Ergebnis auf ein anderes
|
Das ergibt beispielsweise in Pascal endlose Konstrukte des
|
||||||
File.
|
Strickmusters:
|
||||||
Es muá somit (wenn es strukturiert sein
|
|
||||||
m”chte) vor dem Lesen jedes einzelnen
|
|
||||||
Zeichens das Betriebssystem befragen, ob
|
|
||||||
das File vielleicht schon ersch”pft ist.
|
|
||||||
Das ergibt beispielsweise in Pascal
|
|
||||||
endlose Konstrukte des Strickmusters:
|
|
||||||
|
|
||||||
WHILE not eof(input) DO
|
WHILE not eof(input) DO
|
||||||
WHILE not eoLn(input) DO
|
WHILE not eoLn(input) DO
|
||||||
@ -223,29 +138,20 @@ endlose Konstrukte des Strickmusters:
|
|||||||
ENDIF;
|
ENDIF;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
Man verzeihe es mir, wenn ich die
|
Man verzeihe es mir, wenn ich die Pascal-Syntax nicht mehr so
|
||||||
Pascal-Syntax nicht mehr so besonders
|
besonders gut kann. Das Strickmuster sollte eigentlich etwas anderes
|
||||||
gut kann. Das Strickmuster sollte
|
zeigen: In Pascal erfordert jeder Zugriff eines Programms (so es sich
|
||||||
eigentlich etwas anderes zeigen: In
|
strukturiert nenn will) das Abfragen auf End-Of-File und End-Of-Line.
|
||||||
Pascal erfordert jeder Zugriff eines
|
Letzteres ist nötig, da der Standard leider (?) nicht vorschreibt, wie
|
||||||
Programms (so es sich strukturiert nenn
|
EOLn am Fileende aussieht. Soll innerhalb der großen WHILE-Schleife
|
||||||
will) das Abfragen auf End-Of-File und
|
ein weiteres Zeichen gelesen werden, so muß beides erneut geprüft
|
||||||
End-Of-Line. Letzteres ist n”tig, da der
|
werden, daß System ärgert sich mit ständigem Abgefrage herum, der
|
||||||
Standard leider (?) nicht vorschreibt,
|
Programmierer mit der Definition der Routine 'schweinkram', die ihren
|
||||||
wie EOLn am Fileende aussieht. Soll
|
Namen i.a. zu Recht trägt.
|
||||||
innerhalb der groáen WHILE-Schleife ein
|
|
||||||
weiteres Zeichen gelesen werden, so muá
|
|
||||||
beides erneut gepr<70>ft werden, daá System
|
|
||||||
„rgert sich mit st„ndigem Abgefrage
|
|
||||||
herum, der Programmierer mit der
|
|
||||||
Definition der Routine 'schweinkram',
|
|
||||||
die ihren Namen i.a. zu Recht tr„gt.
|
|
||||||
|
|
||||||
Viel einfacher haben es da Sprachen, die
|
Viel einfacher haben es da Sprachen, die keinerlei Anspruch auf
|
||||||
keinerlei Anspruch auf strukturiertes
|
strukturiertes Programmieren erheben. Das obige Kuddelmuddel ließe
|
||||||
Programmieren erheben. Das obige
|
sich in Fortran etwa so umgehen:
|
||||||
Kuddelmuddel lieáe sich in Fortran etwa
|
|
||||||
so umgehen:
|
|
||||||
|
|
||||||
10 READ (input,char,end=100,err=200)
|
10 READ (input,char,end=100,err=200)
|
||||||
IF char.eq..... THEN
|
IF char.eq..... THEN
|
||||||
@ -256,60 +162,36 @@ so umgehen:
|
|||||||
100 ...<fileEnde behandeln>...
|
100 ...<fileEnde behandeln>...
|
||||||
200 ...<sonstige Fehler behandeln>...
|
200 ...<sonstige Fehler behandeln>...
|
||||||
|
|
||||||
Die 'end=' und 'err=' Sequenzen sind
|
Die 'end=' und 'err=' Sequenzen sind verkappte GOTOs. Hier wird
|
||||||
verkappte GOTOs.
|
(völlig unstrukturiert) der Programmfluß im Fehlerfall unterbrochen
|
||||||
Hier wird (v”llig unstrukturiert) der
|
und an den durch 100 und 200 gekennzeichneten Stellen fortgesetzt. Ein
|
||||||
Programmfluá im Fehlerfall unterbrochen
|
ähnliches GOTO-Konstrukt bietet auch Pascal an. Jedes gute Lehrbuch
|
||||||
und an den durch 100 und 200
|
bittet aber darum es möglichst nie zu benutzen. Als einzigen
|
||||||
gekennzeichneten Stellen fortgesetzt.
|
tolerierbaren Zweck wird meist die Fehlerbehandlung angegeben. Ein
|
||||||
Ein „hnliches GOTO-Konstrukt bietet auch
|
sehr treffender Beleg dafür, daß grade dem Vater der strukturierten
|
||||||
Pascal an. Jedes gute Lehrbuch bittet
|
Programmierung, Herrn Wirth, die Fehlerbehandlung Kopfzerbrechen
|
||||||
aber darum es m”glichst nie zu benutzen.
|
|
||||||
Als einzigen tolerierbaren Zweck wird
|
|
||||||
meist die Fehlerbehandlung angegeben.
|
|
||||||
Ein sehr treffender Beleg daf<61>r, daá
|
|
||||||
grade dem Vater der strukturierten
|
|
||||||
Programmierung, Herrn Wirth, die
|
|
||||||
Fehlerbehandlung Kopfzerbrechen
|
|
||||||
bereitet.
|
bereitet.
|
||||||
|
|
||||||
Was sollte das nun belegen? Es soll
|
Was sollte das nun belegen? Es soll zeigen, daß erstens auch völlig
|
||||||
zeigen, daá erstens auch v”llig
|
normale Vorgänge (Ende eines Files) fehlerbehandelt werden wollen. In
|
||||||
normale Vorg„nge (Ende eines Files)
|
diesem Fall spricht man von 'Ausnahmebehandlung', da dieser
|
||||||
fehlerbehandelt werden wollen. In diesem
|
Programmierstil nur für selten auftretende Fälle sinnvoll ist. Es soll
|
||||||
Fall spricht man von
|
zweitens zeigen, daß eine Erhöhung der Performance und Wartbarkeit aus
|
||||||
'Ausnahmebehandlung', da dieser
|
sinnvoller Ausnahmebehandlung entspringt. Denn sicher spart das obige
|
||||||
Programmierstil nur f<>r selten
|
Fortran-beispiel einigen Code. Dies spart auch Zeit, da an weniger
|
||||||
auftretende F„lle sinnvoll ist. Es soll
|
Stellen auf Fehler geprüft werden muß. Und ich kann es besser lesen.
|
||||||
zweitens zeigen, daá eine Erh”hung der
|
(Zur Frage der Lesbarkeit steht mir als Nicht-Informatiker kein
|
||||||
Performance und Wartbarkeit aus
|
allgemeines Urteil zu. Die 'ich'-Form spart mir hier sicher wieder
|
||||||
sinnvoller Ausnahmebehandlung
|
|
||||||
entspringt. Denn sicher spart das obige
|
|
||||||
Fortran-beispiel einigen Code. Dies
|
|
||||||
spart auch Zeit, da an weniger
|
|
||||||
Stellen auf Fehler gepr<70>ft
|
|
||||||
werden muá. Und ich kann es besser
|
|
||||||
lesen. (Zur Frage der Lesbarkeit steht
|
|
||||||
mir als Nicht-Informatiker kein
|
|
||||||
allgemeines Urteil zu. Die
|
|
||||||
'ich'-Form spart mir hier sicher wieder
|
|
||||||
einigen Streit mit Helge und Gerd.)
|
einigen Streit mit Helge und Gerd.)
|
||||||
|
|
||||||
o Ist Ausnahmebehandlung
|
* Ist Ausnahmebehandlung auf ganz tiefer Ebene verzichtbar ?
|
||||||
auf ganz tiefer Ebene verzichtbar ?
|
|
||||||
|
|
||||||
Manchmal muá aber auch eine
|
Manchmal muß aber auch eine Ausnahmebehandlung auf ganz tiefer Ebene
|
||||||
Ausnahmebehandlung auf ganz tiefer
|
erfolgen. Als Beispiel sei hier die Ausgabe von Informationen im
|
||||||
Ebene erfolgen. Als Beispiel sei hier
|
Fehlerfall genannt. Häufig möchte der Benutzer im Fehlerfall wissen,
|
||||||
die Ausgabe von Informationen im
|
wo der Fehler aufgetreten ist, wie bestimmte Variablen aussahen, etc.
|
||||||
Fehlerfall genannt. H„ufig m”chte der
|
Im volksFORTH gibt es ein Wort UNRAVEL, das die Aufrufhierarchie
|
||||||
Benutzer im Fehlerfall wissen, wo der
|
ausgibt. Dies könnte etwa so aussehen:
|
||||||
Fehler aufgetreten ist, wie bestimmte
|
|
||||||
Variablen aussahen, etc.
|
|
||||||
Im volksFORTH gibt es ein Wort
|
|
||||||
UNRAVEL, das die Aufrufhierarchie
|
|
||||||
ausgibt.
|
|
||||||
Dies k”nnte etwa so aussehen:
|
|
||||||
|
|
||||||
FEHLER divide by Zero AUFGETRETEN.
|
FEHLER divide by Zero AUFGETRETEN.
|
||||||
Der Fehler geschah in Wort: 0/
|
Der Fehler geschah in Wort: 0/
|
||||||
@ -318,82 +200,54 @@ FEHLER divide by Zero AUFGETRETEN.
|
|||||||
aufgerufen von: EDIT
|
aufgerufen von: EDIT
|
||||||
aufgerufen von: L
|
aufgerufen von: L
|
||||||
|
|
||||||
Derartige POST-MORTEM-DUMPS erm”glichen
|
Derartige POST-MORTEM-DUMPS ermöglichen i.a. ein schnelles
|
||||||
i.a. ein schnelles Lokalisieren des
|
Lokalisieren des Fehlers. Sie enthalten des öfteren nicht nur die
|
||||||
Fehlers. Sie enthalten des ”fteren nicht
|
Aufrufhierarchie sondern diverse Register- und Variablen-Inhalte zum
|
||||||
nur die Aufrufhierarchie sondern
|
Zeitpunkt des Fehlers (am besten noch aus allen Unterprogrammen...),
|
||||||
diverse Register- und Variablen-Inhalte
|
sodaß sie manchmal den Benutzer eher in hunderten von Seiten Papier
|
||||||
zum Zeitpunkt des Fehlers (am besten
|
ersticken, als ihm bei der Fehlersuche zu helfen. Aber selbst dagegen
|
||||||
noch aus allen Unterprogrammen...),
|
sind Kräuter gewachsen. Logitech's Modula-2-Compiler teilt dem
|
||||||
sodaá sie manchmal den Benutzer eher in
|
Benutzer außer einer sehr knappen Fehlerbeschreibung nichts mit und
|
||||||
hunderten von Seiten Papier ersticken,
|
schreibt ersatzweise den kompletten Systemzustand auf Diskette, wo man
|
||||||
als ihm bei der Fehlersuche zu helfen.
|
ihn anschließend mit einem Post-Mortem-Debug-Programm umgraben kann.
|
||||||
Aber selbst dagegen sind Kr„uter
|
Es frage mich bitte niemand, was passiert, wenn die Diskette voll war.
|
||||||
gewachsen. Logitech's Modula-2-Compiler
|
Ruft der Fehler dann einen erneuten Post-Mortem-Dump hervor?
|
||||||
teilt dem Benutzer auáer einer sehr
|
|
||||||
knappen Fehlerbeschreibung nichts mit
|
|
||||||
und schreibt ersatzweise den kompletten
|
|
||||||
Systemzustand auf Diskette, wo man ihn
|
|
||||||
anschlieáend mit einem
|
|
||||||
Post-Mortem-Debug-Programm umgraben
|
|
||||||
kann. Es frage mich bitte niemand, was
|
|
||||||
passiert, wenn die Diskette voll war.
|
|
||||||
Ruft der Fehler dann einen erneuten
|
|
||||||
Post-Mortem-Dump hervor?
|
|
||||||
|
|
||||||
Um wieder zum Faden zur<75>ckzukehren:
|
Um wieder zum Faden zurückzukehren: Zumindest zum Post-Mortem-Debuggen
|
||||||
Zumindest zum Post-Mortem-Debuggen
|
(=Entlausen aus einem toten Programm. Übertragen: Infos über den
|
||||||
(=Entlausen aus einem toten
|
Fehlerzustand erhalten) ist es nötig Fehler auf niedrigster Ebene zu
|
||||||
Programm. šbertragen: Infos
|
behandeln.
|
||||||
<EFBFBD>ber den Fehlerzustand erhalten)
|
|
||||||
ist es n”tig Fehler auf niedrigster
|
|
||||||
Ebene zu behandeln.
|
|
||||||
|
|
||||||
o Mein Wunsch zur Fehlerbehandlung:
|
* Mein Wunsch zur Fehlerbehandlung: Call-with-current-Continuation (CallCC)
|
||||||
Call-with-current-Continuation
|
|
||||||
(CallCC)
|
|
||||||
|
|
||||||
Die sch”nste, allgemeinste Art der
|
Die schönste, allgemeinste Art der Fehlerbehandlung, die ich kenne,
|
||||||
Fehlerbehandlung, die ich kenne, ist das
|
ist das CATCH-THROW-Konstrukt aus TLC-Lisp (von T.Allen). Ich habe mir
|
||||||
CATCH-THROW-Konstrukt aus TLC-Lisp (von
|
sagen lassen, daß sie unter Zuhilfenahme des
|
||||||
T.Allen).
|
Call-with-current-Continuation-Konzepts implementiert ist. Daher
|
||||||
Ich habe mir sagen lassen, daá sie unter
|
gefällt mir dieses auch sehr gut. Da ich CallCC leider nicht kenne
|
||||||
Zuhilfenahme des
|
beschränke ich mich jetzt aber wieder auf CATCH-THROW. Es wird in
|
||||||
Call-with-current-Continuation-Konzepts
|
folgender Form benutzt:
|
||||||
implementiert ist. Daher gef„llt mir
|
|
||||||
dieses auch sehr gut. Da ich CallCC
|
|
||||||
leider nicht kenne beschr„nke ich mich
|
|
||||||
jetzt aber wieder auf CATCH-THROW.
|
|
||||||
Es wird in folgender Form benutzt:
|
|
||||||
|
|
||||||
(CATCH name ((expression)
|
(CATCH name ((expression)
|
||||||
(exceptionhandler)))
|
(exceptionhandler)))
|
||||||
|
|
||||||
Die Bedeutung ist folgende: Wenn w„hrend
|
Die Bedeutung ist folgende: Wenn während der Evaluierung (=Ausführung
|
||||||
der Evaluierung (=Ausf<73>hrung auf
|
auf LISPisch) von EXPRESSION eine Ausnahme mit dem Namen NAME
|
||||||
LISPisch) von EXPRESSION eine Ausnahme
|
auftreten sollte, so möge bitte sofort EXCEPTIONHANDLER evaluiert
|
||||||
mit dem Namen NAME auftreten sollte, so
|
werden. Ansonsten ist der obige Ausdruck identisch mit:
|
||||||
m”ge bitte sofort EXCEPTIONHANDLER
|
|
||||||
evaluiert werden. Ansonsten ist der
|
|
||||||
obige Ausdruck identisch mit:
|
|
||||||
|
|
||||||
(expression)
|
(expression)
|
||||||
|
|
||||||
Eine Ausnahme tritt dadurch auf, daá
|
Eine Ausnahme tritt dadurch auf, daß eine Funktion (=wort auf
|
||||||
eine Funktion (=wort auf
|
LISPisch) innerhalb von expression die Funktion
|
||||||
LISPisch) innerhalb
|
|
||||||
von expression die Funktion
|
|
||||||
|
|
||||||
(THROW name)
|
(THROW name)
|
||||||
|
|
||||||
aufruft.
|
aufruft.
|
||||||
|
|
||||||
Eigentlich ist es verabscheuungsw<73>rdig,
|
Eigentlich ist es verabscheuungswürdig, von Lisp aus Files zu lesen,
|
||||||
von Lisp aus Files zu lesen, da dies dem
|
da dies dem funktionalen Programmieren zuwiderläuft. Um aber trotzdem
|
||||||
funktionalen Programmieren zuwiderl„uft.
|
das obige File-Lese-Beispiel nochmal zu strapazieren:
|
||||||
Um aber trotzdem das obige
|
|
||||||
File-Lese-Beispiel nochmal zu
|
|
||||||
strapazieren:
|
|
||||||
|
|
||||||
(CATCH end-of-file
|
(CATCH end-of-file
|
||||||
(CATCH end-of-line
|
(CATCH end-of-line
|
||||||
@ -410,167 +264,114 @@ strapazieren:
|
|||||||
( ...end-of-file-handler..)
|
( ...end-of-file-handler..)
|
||||||
)
|
)
|
||||||
|
|
||||||
Dies sieht nicht nur wundervoll aus mit
|
Dies sieht nicht nur wundervoll aus mit den vielen Klammern, sondern
|
||||||
den vielen Klammern, sondern hat auch
|
hat auch eine Wirkung: wenn READCHAR irgendwann (THROW end-of-line)
|
||||||
eine Wirkung: wenn READCHAR irgendwann
|
oder (THROW end-of-file) evaluiert, wird einer unsrer HANDLER
|
||||||
(THROW end-of-line) oder (THROW
|
aufgerufen. Ob READCHAR das tut und ob es in Lisp überhaupt eine
|
||||||
end-of-file) evaluiert, wird einer
|
Funktion diesen Namens gibt, entzieht sich leider meiner Kenntnis.
|
||||||
unsrer HANDLER aufgerufen. Ob READCHAR
|
Selbstverständlich können solche handler geschachtelt werden. Um
|
||||||
das tut und ob es in Lisp <20>berhaupt eine
|
DOSOMETHING könnte z.B. ein noch spezielleren handler heruminstalliert
|
||||||
Funktion diesen Namens gibt, entzieht
|
werden. Eine Ausführung von (THROW name) aktiviert jeweils den
|
||||||
sich leider meiner Kenntnis.
|
nächstäußeren (höhergelegenen) handler. Wenn dieser das nötige getan
|
||||||
Selbstverst„ndlich k”nnen solche handler
|
hat, kann er beispielsweise erneut (THROW name) evaluieren, um
|
||||||
geschachtelt werden. Um DOSOMETHING
|
wiederum den ihm nächstäußeren handler zu aktivieren. Das Spiel läßt
|
||||||
k”nnte z.B. ein noch
|
sich weitertreiben, bis schließlich der alleräußerste (von der
|
||||||
spezielleren handler
|
LISP-Interpreter-Schleife) installierte handler aufgerufen wird, der
|
||||||
heruminstalliert werden. Eine Ausf<73>hrung
|
(ähnlich unserem ABORT") wieder Eingaben von der Tastatur verarbeitet.
|
||||||
von (THROW name) aktiviert jeweils den
|
Selbstverständlich kann jeder handler in der Schlange auch etwas
|
||||||
n„chst„uáeren (h”hergelegenen) handler.
|
anderes unternehmen, beispielsweise die gescheiterte Aktion
|
||||||
Wenn dieser das n”tige getan hat, kann
|
|
||||||
er beispielsweise erneut (THROW name)
|
|
||||||
evaluieren, um wiederum den ihm
|
|
||||||
n„chst„uáeren handler zu aktivieren. Das
|
|
||||||
Spiel l„át sich weitertreiben, bis
|
|
||||||
schlieálich der aller„uáerste (von der
|
|
||||||
LISP-Interpreter-Schleife) installierte
|
|
||||||
handler aufgerufen wird, der („hnlich
|
|
||||||
unserem ABORT") wieder Eingaben von der
|
|
||||||
Tastatur verarbeitet. Selbstverst„ndlich
|
|
||||||
kann jeder handler in der Schlange auch
|
|
||||||
etwas anderes unternehmen,
|
|
||||||
beispielsweise die gescheiterte Aktion
|
|
||||||
wiederholen.
|
wiederholen.
|
||||||
|
|
||||||
o Zur<75>ck zu Forth
|
* Zurück zu Forth
|
||||||
|
|
||||||
Aus dem gesagten seien noch einmal die
|
Aus dem gesagten seien noch einmal die
|
||||||
Kernpunkte zusammengefaát:
|
Kernpunkte zusammengefaßt:
|
||||||
- Fehlerbehandlung soll auf jeder
|
|
||||||
beliebigen Programmebene m”chlich sein
|
- Fehlerbehandlung soll auf jeder beliebigen Programmebene möchlich
|
||||||
|
sein
|
||||||
- insbesondere auch auf tiefster Ebene
|
- insbesondere auch auf tiefster Ebene
|
||||||
- Die Fehlerbehandlungsroutinen sollen
|
- Die Fehlerbehandlungsroutinen sollen geschachtelt werden können
|
||||||
geschachtelt werden k”nnen
|
- Fehlerbehandlar sollen Möglichkeiten erhalten, nach Bedarf die
|
||||||
- Fehlerbehandlar sollen M”glichkeiten
|
fehlerverursachende Routine erneut zu probieren oder die Ausführung
|
||||||
erhalten, nach Bedarf die
|
dem nächsthöheren Fehlerbehandler weiterzugeben.
|
||||||
fehlerverursachende Routine erneut zu
|
- Das ganze soll so einfach zu benutzen sein, daß Routinen für selten
|
||||||
probieren oder die Ausf<73>hrung dem
|
auftretende Ereignisse einfach zu formulieren sind.
|
||||||
n„chsth”heren
|
- Diese Fehlerbehandlung soll durch das Standardwort ABORT" aktiviert
|
||||||
Fehlerbehandler weiterzugeben.
|
werden.
|
||||||
- Das ganze soll so einfach zu benutzen
|
|
||||||
sein, daá Routinen f<>r selten
|
|
||||||
auftretende Ereignisse einfach zu
|
|
||||||
formulieren sind.
|
|
||||||
- Diese Fehlerbehandlung soll durch das
|
|
||||||
Standardwort ABORT" aktiviert werden.
|
|
||||||
|
|
||||||
Nun wird's konkret:
|
Nun wird's konkret: Wo sollen die Informationen über die installierten
|
||||||
Wo sollen die Informationen <20>ber die
|
Fehlerbehandlungsroutinen abgelegt werden? Auf dem Returnstack, da
|
||||||
installierten Fehlerbehandlungsroutinen
|
sich hier am einfachsten eine der jeweiligen Ausführungsebene (Wort)
|
||||||
abgelegt werden? Auf dem Returnstack, da
|
angelehnte Datenstruktur bilden läßt.
|
||||||
sich hier am einfachsten eine der
|
|
||||||
jeweiligen Ausf<73>hrungsebene (Wort)
|
|
||||||
angelehnte Datenstruktur bilden l„át.
|
|
||||||
|
|
||||||
Wie soll die Syntax aussehen? Es soll
|
Wie soll die Syntax aussehen? Es soll einfach sein, daher
|
||||||
einfach sein, daher Kontrollstrukturen.
|
Kontrollstrukturen. Beispielsweise:
|
||||||
Beispielsweise:
|
|
||||||
|
|
||||||
: name ..<clause1>..
|
: name ..<clause1>..
|
||||||
FAILS ...errorhandler... THEN
|
FAILS ...errorhandler... THEN
|
||||||
..<clause2>.. ;
|
..<clause2>.. ;
|
||||||
|
|
||||||
Die Bedeutung: Es wird ein Wort NAME
|
Die Bedeutung: Es wird ein Wort NAME definiert. Bei Ausführung führt
|
||||||
definiert. Bei Ausf<73>hrung f<>hrt NAME
|
NAME erst <clause1> aus, installiert anschließend einen ERRORHANDLER,
|
||||||
erst <clause1> aus, installiert
|
führt dann <clause2> aus und deinstalliert ERRORHANDLER nach Verlassen
|
||||||
anschlieáend einen ERRORHANDLER, f<>hrt
|
des Wortes. Sollte innerhalb von <clause2> ein ABORT" ausgeführt
|
||||||
dann <clause2> aus und deinstalliert
|
werden, so wird ERRORHANDLER ausgeführt.
|
||||||
ERRORHANDLER nach Verlassen des Wortes.
|
|
||||||
Sollte innerhalb von <clause2> ein
|
|
||||||
ABORT" ausgef<65>hrt werden, so wird
|
|
||||||
ERRORHANDLER ausgef<65>hrt.
|
|
||||||
|
|
||||||
Aktivieren des „uáeren ERRORHANDLERS:
|
Aktivieren des äußeren ERRORHANDLERS: Sollte innerhalb von
|
||||||
Sollte innerhalb von ERRORHANDLER das
|
ERRORHANDLER das Wort THROW ausgeführt werden, so wird die Ausführung
|
||||||
Wort THROW ausgef<65>hrt werden, so wird
|
von ERRORHANDLER beendet und die nächstäußere Fehlerbehandlungsroutine
|
||||||
die Ausf<73>hrung von ERRORHANDLER beendet
|
aktiviert.
|
||||||
und die n„chst„uáere
|
|
||||||
Fehlerbehandlungsroutine aktiviert.
|
|
||||||
|
|
||||||
Wiederholen der fehlerverursachenden
|
Wiederholen der fehlerverursachenden <clause2>: Hier wird's kritisch.
|
||||||
<clause2>: Hier wird's kritisch. Im
|
Im Gegensatz zu praktisch allen anderen Sprachen liegen die Parameter
|
||||||
Gegensatz zu praktisch allen anderen
|
auf dem Datenstack. Vor einer Wiederholung müssen Daten- und
|
||||||
Sprachen liegen die Parameter auf dem
|
Returnstack repariert werden. Der Returnstack läßt sich problemlos so
|
||||||
Datenstack. Vor einer Wiederholung
|
manipulieren, daß er bei Aufruf von ERRORHANDLER bereits wieder im
|
||||||
m<EFBFBD>ssen Daten- und Returnstack repariert
|
gewünschten Zustand ist. Falls ein definierter Zustand des Datenstacks
|
||||||
werden. Der Returnstack l„át sich
|
gewümscht wird, muß allerdings ein spezielles Konstrukt:
|
||||||
problemlos so manipulieren, daá er bei
|
|
||||||
Aufruf von ERRORHANDLER bereits wieder
|
|
||||||
im gew<65>nschten Zustand ist. Falls ein
|
|
||||||
definierter Zustand des Datenstacks
|
|
||||||
gew<EFBFBD>mscht wird, muá allerdings ein
|
|
||||||
spezielles Konstrukt:
|
|
||||||
|
|
||||||
nn #FAILS ..errorhandler.. RETRY
|
nn #FAILS ..errorhandler.. RETRY
|
||||||
|
|
||||||
benutzt werden. Die NN obersten
|
benutzt werden. Die NN obersten Stackwerte, sowie der Stackpointer
|
||||||
Stackwerte, sowie der Stackpointer
|
werden gesichert. Falls ERRORHANDLER aufgerufen werden sollte, wird
|
||||||
werden gesichert. Falls ERRORHANDLER
|
der Stack vorher soweit restauriert. Es gilt natürlich aufzupassen,
|
||||||
aufgerufen werden sollte, wird der Stack
|
daß sie bis zur Ausführung von RETRY auch dableiben.
|
||||||
vorher soweit restauriert. Es gilt
|
|
||||||
nat<EFBFBD>rlich aufzupassen, daá sie bis
|
|
||||||
zur Ausf<73>hrung von RETRY auch dableiben.
|
|
||||||
|
|
||||||
Noch ein weiteres Konstrukt wurde
|
Noch ein weiteres Konstrukt wurde eingeführt:
|
||||||
eingef<EFBFBD>hrt:
|
|
||||||
|
|
||||||
: name ..<clause1>..
|
: name ..<clause1>..
|
||||||
EXITS ..errorhandler.. throw THEN
|
EXITS ..errorhandler.. throw THEN
|
||||||
..<clause2>. ;
|
..<clause2>. ;
|
||||||
|
|
||||||
Es tr„gt der Idee Rechnung, daá
|
Es trägt der Idee Rechnung, daß ERRORHANDLER des öfteren nur
|
||||||
ERRORHANDLER des ”fteren nur installiert
|
installiert wird, um eine Ressource zu schließen. Die Bedeutung: Es
|
||||||
wird, um eine Ressource zu schlieáen.
|
wird ein Wort NAME definiert. Bei Ausführung führt NAME erst <clause1>
|
||||||
Die Bedeutung: Es wird ein Wort NAME
|
aus, installiert anschließend einen ERRORHANDLER, führt dann <clause2>
|
||||||
definiert. Bei Ausf<73>hrung f<>hrt NAME
|
aus. ERRORHANDLER wird im Falle eines Fehlers oder nach Verlassen des
|
||||||
erst <clause1> aus, installiert
|
Wortes NAME ausgeführt. Es lassen sich also so schöne Konstrukte
|
||||||
anschlieáend einen ERRORHANDLER, f<>hrt
|
|
||||||
dann <clause2> aus. ERRORHANDLER wird
|
|
||||||
im Falle eines Fehlers oder nach
|
|
||||||
Verlassen des Wortes NAME ausgef<65>hrt.
|
|
||||||
Es lassen sich also so sch”ne Konstrukte
|
|
||||||
bilden wie:
|
bilden wie:
|
||||||
|
|
||||||
: machWas ...
|
: machWas ...
|
||||||
..<”ffne-Ger„t1>..
|
..<öffne-Gerät1>..
|
||||||
EXITS ..<schlieáe-Ger„t1>.. throw THEN
|
EXITS ..<schließe-Gerät1>.. throw THEN
|
||||||
..<”ffne-Ger„t2>..
|
..<öffne-Gerät2>..
|
||||||
EXITS ..<schlieáe-Ger„t2>.. throw THEN
|
EXITS ..<schließe-Gerät2>.. throw THEN
|
||||||
.... ;
|
.... ;
|
||||||
|
|
||||||
Es werden auf jeden Fall die ge”ffneten
|
Es werden auf jeden Fall die geöffneten Geräte wieder geschlossen, ob
|
||||||
Ger„te wieder geschlossen, ob nun ein
|
nun ein Fehler auftritt oder nicht.
|
||||||
Fehler auftritt oder nicht.
|
|
||||||
|
|
||||||
o Was gibt es noch f<>r Ans„tze in Forth
|
* Was gibt es noch für Ansätze in Forth
|
||||||
|
|
||||||
Der vorgestellte Ansatz bringt nichts
|
Der vorgestellte Ansatz bringt nichts prinzipiell neues. In
|
||||||
prinzipiell neues. In ///////Schliesieck
|
///////Schliesieck läßt sich eine Methode nachlesen, die sicherlich
|
||||||
l„át sich eine Methode nachlesen, die
|
schneller und einfacher implementiert ist, allerdings verändert sie
|
||||||
sicherlich schneller und einfacher
|
nicht das Verhalten von ABORT", sondern muß mit einem gesonderten Wort
|
||||||
implementiert ist, allerdings ver„ndert
|
aufgerufen werden. Auch sichert sie lediglich den Stackpointer,
|
||||||
sie nicht das Verhalten von ABORT",
|
eventuelle Parameter müssen also 'zu Fuß' gesichert werden.
|
||||||
sondern muá mit einem gesonderten Wort
|
//////weiter.... wenn m
|
||||||
aufgerufen werden. Auch sichert sie
|
|
||||||
lediglich den Stackpointer, eventuelle
|
|
||||||
Parameter m<>ssen also 'zu Fuá'
|
|
||||||
gesichert werden. //////weiter....
|
|
||||||
wenn m
|
|
||||||
|
|
||||||
Sch”ner: statt THROW ein EXIT
|
chöner: statt THROW ein EXIT nehmen. Was passiert bei exit? Bitte
|
||||||
nehmen. Was passiert bei exit?
|
nicht IF..ELSE..RETRY Bitte kein FAILS...THEN ohne throw oder so
|
||||||
Bitte nicht IF..ELSE..RETRY
|
|
||||||
Bitte kein FAILS...THEN ohne throw oder
|
|
||||||
so
|
|
||||||
|
|
||||||
Wie rauskriegen, welcher Fehler passiert ist?
|
Wie rauskriegen, welcher Fehler passiert ist?
|
||||||
|
|
0
6502/UltraForth/README.TXT
Executable file → Normal file
0
6502/UltraForth/README.TXT
Executable file → Normal file
Loading…
Reference in New Issue
Block a user