From cafe4b5ca656ab40eab16704694f1a5bb663453a Mon Sep 17 00:00:00 2001 From: Carsten Strotmann Date: Wed, 15 Jul 2020 10:16:59 +0200 Subject: [PATCH] Reformatted Errorhandler Article --- 6502/UltraForth/ERRHANDL/ERRORHANDLER.TXT | 675 ++++++++------------- 6502/UltraForth/README.TXT | 0 {6502/gen6502/vFORTH38 => tools}/fb2fth.py | 0 3 files changed, 238 insertions(+), 437 deletions(-) mode change 100755 => 100644 6502/UltraForth/README.TXT rename {6502/gen6502/vFORTH38 => tools}/fb2fth.py (100%) diff --git a/6502/UltraForth/ERRHANDL/ERRORHANDLER.TXT b/6502/UltraForth/ERRHANDL/ERRORHANDLER.TXT index 0e796ef..19b6875 100644 --- a/6502/UltraForth/ERRHANDL/ERRORHANDLER.TXT +++ b/6502/UltraForth/ERRHANDL/ERRORHANDLER.TXT @@ -2,14 +2,9 @@ ERR.ART Korrektur clv03jul89 Entwurf clv01mar88 -set margins 1 40 -(mit c-t in Kommandozeile) - - Titel: -Behandlung von Ausnahmesituationen in -Forth83 +Behandlung von Ausnahmesituationen in Forth83 Stichworte: @@ -19,194 +14,114 @@ exception handling volksFORTH83 returnstack -Kurzfassung: -Ausgehend von einer Analyse -des Bedrfnisses nach -programmspezifische Fehlerbehandlung -(die insbesondere zum erweiterten -Begriff des 'Exception handling' fhrt) -werden Konzepte aus verschiedenen Programmiersprachen -sowie zu Forth83 vorgeschlagene Konzepte -auf ihre Brauchbarkeit -hin diskutiert. Es folgt eine unter -ultraFORTH83 rev 3.8 auf einem C16 -entwickelte -Lsung des Autors, die abhngig von -der Ausfhrungsebene eine spezielle -mittels FAILS..THEN installierte -Behandlung der Worte ABORT" und ERROR" -gestattet. +Kurzfassung: Ausgehend von einer Analyse des Bedürfnisses nach +programmspezifische Fehlerbehandlung (die insbesondere zum erweiterten +Begriff des 'Exception handling' führt) werden Konzepte aus +verschiedenen Programmiersprachen sowie zu Forth83 vorgeschlagene +Konzepte 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ührungsebene eine spezielle mittels FAILS..THEN +installierte Behandlung der Worte ABORT" und ERROR" gestattet. -o Die derzeitige Fehlerbehandlung - in Forth: ABORT" +* Die derzeitige Fehlerbehandlung in Forth: ABORT" -Im 83er-Standard ist das zentrale Wort -zur Fehlerbehandlung ABORT". Es -gibt den folgenden String als -Fehlernachricht aus, versetzt das System -in einen (einigermaen) definierten -Zustand und ruft das Top-Level-Wort QUIT -auf, das Eingaben von der Tastatur -entgegennimmt und verarbeitet. -Jedes laufende Programm wird also ohne -Rcksicht auf Verluste gestoppt und -gewissermaen Forth neu gestartet. -Eine hnliche Wirkung haben die Worte -ABORT und QUIT. +Im 83er-Standard ist das zentrale Wort zur Fehlerbehandlung ABORT". Es +gibt den folgenden String als Fehlernachricht aus, versetzt das System +in einen (einigermaßen) definierten Zustand und ruft das +Top-Level-Wort QUIT auf, das Eingaben von der Tastatur entgegennimmt +und verarbeitet. Jedes laufende Programm wird also ohne Rücksicht auf +Verluste gestoppt und gewissermaßen Forth neu gestartet. Eine ähnliche +Wirkung haben die Worte ABORT und QUIT. -Im ultraFORTH83/volksFORTH83 gibt es -ein Wort ERROR", das sich von ABORT" nur -dadurch unterscheidet, da der -Datenstack nicht gelscht wird. -Desweiteren enthlt dieses Forth eine -User-Variable ERRORHANDLER, die es -ermglicht, ein anderes Verhalten von -ABORT" und ERROR" zu installieren. +Im ultraFORTH83/volksFORTH83 gibt es ein Wort ERROR", das sich von +ABORT" nur dadurch unterscheidet, daß der Datenstack nicht gelöscht +wird. Desweiteren enthält dieses Forth eine 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 - knnen - -Diese Art der -Fehlerbehandlung -funktioniert zwar meistens recht gut, -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: - - Reservierte Ressourcen - schlieen - - Das Level, auf dem die Behandlung - erfolgt - - Informationen ber den - Fehlerzustand erhalten. - - bersichtliche Behandlung - selten auftretender Ereignisse - - Fehler auch whrend der - Fehlerbehandlung (ohne - Endlosschleifen) + - Reservierte Ressourcen schließen + - Das Level, auf dem die Behandlung erfolgt + - Informationen über den Fehlerzustand erhalten. + - Übersichtliche Behandlung selten auftretender Ereignisse + - Fehler auch während der Fehlerbehandlung (ohne Endlosschleifen) -Hierbei flieen jeweils die Erfahrungen -des Autors mit MS-DOS, Pascal, +Hierbei fließen jeweils die Erfahrungen des Autors mit MS-DOS, Pascal, Modula-2, Fortran und TLC-Lisp mit ein. -o Schlieen von Ressourcen +* Schließen von Ressourcen -Das Wort ABORT" (so es im Quelltext -vorliegt) zeigt bereits da im -Fehlerfalle gewisse Systemressourcen -wieder freigegeben werden mssen. -Zumindest drfte in jedem System der -Return-stack entleert werden, oft auch -der Datenstack, vielleicht werden -sogar gewisse Systemvektoren restauriert -(insb. fr die Standard-Ein/Ausgabe -scheint das geraten). -Falls das Programm gewisse -weitere Ressourcen -reserviert hat, werden sie nicht wieder -frei gegeben. Dies knnte ein geffnetes -File sein, das nicht geschlossen wird; -ein Semaphor, das gelockt bleibt; ein -menartiger Bildschirm, der weiter in -allen Farben des Spektrums blinkt; eine -hoffnungslos verdrehte Schnittstelle -etc.. Am aufflligsten 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 gewnschte -Fehlermeldung "Drucker ausgeschaltet" -heien mag. Dieser Effekt wird in jedem -intelligenten Forth-System natrlich -abgefangen, unter MS-DOS lt er -sich allerdings noch sehr hbsch -beobachten. Die gelockten Semaphore -machen sich allerdings - in seltenen -Fllen - auch unter volksFORTH -bemerkbar. Vllig hoffnungslos wird der -Fall, wenn eine grere -Stand-Alone-Anwendung (z.B. ein -frchterlich kompliziertes Menprogramm) -grade smtliche Systemvektoren -erfolgreich verbogen hat und nun durch -einem jmmerlich kleinen Fehler -(vielleicht einen offengelassener -Diskettenschacht) jh in die -Forth-Hauptschleife geschleudert wird. +Das Wort ABORT" (so es im Quelltext vorliegt) zeigt bereits daß im +Fehlerfalle gewisse Systemressourcen wieder freigegeben werden müssen. +Zumindest dürfte in jedem System der Return-stack entleert werden, oft +auch der Datenstack, vielleicht werden sogar gewisse Systemvektoren +restauriert (insb. für die Standard-Ein/Ausgabe scheint das geraten). +Falls das Programm gewisse weitere Ressourcen 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ü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. -o Auf welcher Programmebene soll der - Fehler behandelt werden? +In diesem Fall wird schon die Ausgabe der ABORT"-Meldung (auf den +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 -wie letzterem wre es sogar denkbar, -den Fehler noch innerhalb der -Systemroutinem (in diesem Fall in der -Block-Lese-Routine des Betriebssystem) -zu beseitigen -(z.B. den Benutzer aufzufordern, doch -bitte den Schacht zu schlieen) und -anschlieend fortzufahren, ohne da -das darberliegende 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 +* Auf welcher Programmebene soll der Fehler behandelt werden? + +In einem Fall wie letzterem wäre es sogar denkbar, den Fehler noch +innerhalb der Systemroutinem (in diesem Fall in der Block-Lese-Routine +des Betriebssystem) zu beseitigen (z.B. den Benutzer aufzufordern, +doch bitte den Schacht zu schließen) und anschließend fortzufahren, +ohne daß das darü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: allgemeiner Fehler. Kaffee in Laufwerk A: (A)bbruch, (W)iederholen, (I)gnorieren ? -beantwortet. Der Benutzer kann sich nun -fr eine der Alternativen entscheiden. -Tippt er 'W', so versucht das System -denselben Zugriff nochmal. Dies ist bei -einem offen gelassenen Schacht ntzlich, -gegen Kaffee hilft es natrlich nicht. -'A' terminiert das laufende Programm und -springt zurck ins Betriebssystem (in -etwa wie unser QUIT). Dies funktioniert -meistens, es sei denn das Betriebssystem -mchte selbst Teile seiner selbst von -der Diskette lesen: Wir bekommen die -beliebte Endlosschleife, bis wir eine -saubere Diskette eingelegt haben. -Die Alternative 'I' ist die hbscheste. -Das System vergit die Operation und -kehrt ins rufende Programm zurck. -Dieses arbeitet brav weiter, bis es -sich an irgendwelchenden Zufallsergebnissen -den Magen verdirbt. Um zum Beispiel -des Men-Programms mit offenen -Kassettenschacht noch ein Wort zu -verlieren: Beim 'W'iederholen ist -natrlich trotz allem der -Bildschirmaufbau im Eimer. Bis hierher -lt sich erstmal formulieren, da -die Fehlerbehandlung lieber auf der -Ebene des Anwenderprogramms erfolgen -sollte. +beantwortet. Der Benutzer kann sich nun für eine der Alternativen +entscheiden. Tippt er 'W', so versucht das System denselben Zugriff +nochmal. Dies ist bei einem offen gelassenen Schacht nützlich, gegen +Kaffee hilft es natürlich nicht. 'A' terminiert das laufende Programm +und springt zurück ins Betriebssystem (in etwa wie unser QUIT). Dies +funktioniert meistens, es sei denn das Betriebssystem möchte selbst +Teile seiner selbst von der Diskette lesen: Wir bekommen die beliebte +Endlosschleife, bis wir eine saubere Diskette eingelegt haben. Die +Alternative 'I' ist die hübscheste. Das System vergißt die Operation +und kehrt ins rufende Programm zurück. Dieses arbeitet brav weiter, +bis es sich an irgendwelchenden Zufallsergebnissen den Magen verdirbt. +Um zum Beispiel des Menü-Programms mit offenen Kassettenschacht noch +ein Wort zu verlieren: Beim 'W'iederholen ist natü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 - Methoden der Fehlerbehandlung - behandeln? +* Warum eigentlich nur Fehler mit Methoden der Fehlerbehandlung behandeln? -Um diesem hbschen Wortspiel Sinn zu -geben, mag ein anderes Beispiel -herhalten. -Ein Programm lese -Daten von einem File, verarbeite sie und -schreibe das Ergebnis auf ein anderes -File. -Es mu somit (wenn es strukturiert sein -mchte) vor dem Lesen jedes einzelnen -Zeichens das Betriebssystem befragen, ob -das File vielleicht schon erschpft ist. -Das ergibt beispielsweise in Pascal -endlose Konstrukte des Strickmusters: +Um diesem hübschen Wortspiel Sinn zu geben, mag ein anderes Beispiel +herhalten. Ein Programm lese Daten von einem File, verarbeite sie und +schreibe das Ergebnis auf ein anderes File. 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 eoLn(input) DO @@ -223,29 +138,20 @@ endlose Konstrukte des Strickmusters: ENDIF; END; -Man verzeihe es mir, wenn ich die -Pascal-Syntax nicht mehr so besonders -gut kann. Das Strickmuster sollte -eigentlich etwas anderes zeigen: In -Pascal erfordert jeder Zugriff eines -Programms (so es sich strukturiert nenn -will) das Abfragen auf End-Of-File und -End-Of-Line. Letzteres ist ntig, da der -Standard leider (?) nicht vorschreibt, -wie EOLn am Fileende aussieht. Soll -innerhalb der groen WHILE-Schleife ein -weiteres Zeichen gelesen werden, so mu -beides erneut geprft werden, da System -rgert sich mit stndigem Abgefrage -herum, der Programmierer mit der -Definition der Routine 'schweinkram', -die ihren Namen i.a. zu Recht trgt. +Man verzeihe es mir, wenn ich die Pascal-Syntax nicht mehr so +besonders gut kann. Das Strickmuster sollte eigentlich etwas anderes +zeigen: In Pascal erfordert jeder Zugriff eines Programms (so es sich +strukturiert nenn will) das Abfragen auf End-Of-File und End-Of-Line. +Letzteres ist nötig, da der Standard leider (?) nicht vorschreibt, wie +EOLn am Fileende aussieht. Soll innerhalb der großen WHILE-Schleife +ein weiteres Zeichen gelesen werden, so muß beides erneut geprü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 -keinerlei Anspruch auf strukturiertes -Programmieren erheben. Das obige -Kuddelmuddel liee sich in Fortran etwa -so umgehen: +Viel einfacher haben es da Sprachen, die keinerlei Anspruch auf +strukturiertes Programmieren erheben. Das obige Kuddelmuddel ließe +sich in Fortran etwa so umgehen: 10 READ (input,char,end=100,err=200) IF char.eq..... THEN @@ -256,60 +162,36 @@ so umgehen: 100 ...... 200 ...... -Die 'end=' und 'err=' Sequenzen sind -verkappte GOTOs. -Hier wird (vllig unstrukturiert) der -Programmflu im Fehlerfall unterbrochen -und an den durch 100 und 200 -gekennzeichneten Stellen fortgesetzt. -Ein hnliches GOTO-Konstrukt bietet auch -Pascal an. Jedes gute Lehrbuch bittet -aber darum es mglichst nie zu benutzen. -Als einzigen tolerierbaren Zweck wird -meist die Fehlerbehandlung angegeben. -Ein sehr treffender Beleg dafr, da -grade dem Vater der strukturierten -Programmierung, Herrn Wirth, die -Fehlerbehandlung Kopfzerbrechen +Die 'end=' und 'err=' Sequenzen sind verkappte GOTOs. Hier wird +(völlig unstrukturiert) der Programmfluß im Fehlerfall unterbrochen +und an den durch 100 und 200 gekennzeichneten Stellen fortgesetzt. Ein +ähnliches GOTO-Konstrukt bietet auch Pascal an. Jedes gute Lehrbuch +bittet aber darum es möglichst nie zu benutzen. Als einzigen +tolerierbaren Zweck wird meist die Fehlerbehandlung angegeben. Ein +sehr treffender Beleg dafür, daß grade dem Vater der strukturierten +Programmierung, Herrn Wirth, die Fehlerbehandlung Kopfzerbrechen bereitet. -Was sollte das nun belegen? Es soll -zeigen, da erstens auch vllig -normale Vorgnge (Ende eines Files) -fehlerbehandelt werden wollen. In diesem -Fall spricht man von -'Ausnahmebehandlung', da dieser -Programmierstil nur fr selten -auftretende Flle sinnvoll ist. Es soll -zweitens zeigen, da eine Erhhung der -Performance und Wartbarkeit aus -sinnvoller Ausnahmebehandlung -entspringt. Denn sicher spart das obige -Fortran-beispiel einigen Code. Dies -spart auch Zeit, da an weniger -Stellen auf Fehler geprft -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 +Was sollte das nun belegen? Es soll zeigen, daß erstens auch völlig +normale Vorgänge (Ende eines Files) fehlerbehandelt werden wollen. In +diesem Fall spricht man von 'Ausnahmebehandlung', da dieser +Programmierstil nur für selten auftretende Fälle sinnvoll ist. Es soll +zweitens zeigen, daß eine Erhöhung der Performance und Wartbarkeit aus +sinnvoller Ausnahmebehandlung entspringt. Denn sicher spart das obige +Fortran-beispiel einigen Code. Dies spart auch Zeit, da an weniger +Stellen auf Fehler geprü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.) -o Ist Ausnahmebehandlung - auf ganz tiefer Ebene verzichtbar ? +* Ist Ausnahmebehandlung auf ganz tiefer Ebene verzichtbar ? -Manchmal mu aber auch eine -Ausnahmebehandlung auf ganz tiefer -Ebene erfolgen. Als Beispiel sei hier -die Ausgabe von Informationen im -Fehlerfall genannt. Hufig mchte der -Benutzer im Fehlerfall wissen, wo der -Fehler aufgetreten ist, wie bestimmte -Variablen aussahen, etc. -Im volksFORTH gibt es ein Wort -UNRAVEL, das die Aufrufhierarchie -ausgibt. -Dies knnte etwa so aussehen: +Manchmal muß aber auch eine Ausnahmebehandlung auf ganz tiefer Ebene +erfolgen. Als Beispiel sei hier die Ausgabe von Informationen im +Fehlerfall genannt. Häufig möchte der Benutzer im Fehlerfall wissen, +wo der 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. Der Fehler geschah in Wort: 0/ @@ -318,82 +200,54 @@ FEHLER divide by Zero AUFGETRETEN. aufgerufen von: EDIT aufgerufen von: L -Derartige POST-MORTEM-DUMPS ermglichen -i.a. ein schnelles Lokalisieren des -Fehlers. Sie enthalten des fteren nicht -nur die Aufrufhierarchie sondern -diverse Register- und Variablen-Inhalte -zum Zeitpunkt des Fehlers (am besten -noch aus allen Unterprogrammen...), -soda sie manchmal den Benutzer eher in -hunderten von Seiten Papier ersticken, -als ihm bei der Fehlersuche zu helfen. -Aber selbst dagegen sind Kruter -gewachsen. Logitech's Modula-2-Compiler -teilt dem Benutzer auer einer sehr -knappen Fehlerbeschreibung nichts mit -und schreibt ersatzweise den kompletten -Systemzustand auf Diskette, wo man ihn -anschlieend 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? +Derartige POST-MORTEM-DUMPS ermöglichen i.a. ein schnelles +Lokalisieren des Fehlers. Sie enthalten des öfteren nicht nur die +Aufrufhierarchie sondern diverse Register- und Variablen-Inhalte zum +Zeitpunkt des Fehlers (am besten noch aus allen Unterprogrammen...), +sodaß sie manchmal den Benutzer eher in hunderten von Seiten Papier +ersticken, als ihm bei der Fehlersuche zu helfen. Aber selbst dagegen +sind Kräuter gewachsen. Logitech's Modula-2-Compiler 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 zurckzukehren: -Zumindest zum Post-Mortem-Debuggen -(=Entlausen aus einem toten -Programm. bertragen: Infos -ber den Fehlerzustand erhalten) -ist es ntig Fehler auf niedrigster -Ebene zu behandeln. +Um wieder zum Faden zurückzukehren: Zumindest zum Post-Mortem-Debuggen +(=Entlausen aus einem toten Programm. Übertragen: Infos über den +Fehlerzustand erhalten) ist es nötig Fehler auf niedrigster Ebene zu +behandeln. -o Mein Wunsch zur Fehlerbehandlung: - Call-with-current-Continuation - (CallCC) +* Mein Wunsch zur Fehlerbehandlung: Call-with-current-Continuation (CallCC) -Die schnste, allgemeinste Art der -Fehlerbehandlung, die ich kenne, ist das -CATCH-THROW-Konstrukt aus TLC-Lisp (von -T.Allen). -Ich habe mir sagen lassen, da sie unter -Zuhilfenahme des -Call-with-current-Continuation-Konzepts -implementiert ist. Daher gefllt mir -dieses auch sehr gut. Da ich CallCC -leider nicht kenne beschrnke ich mich -jetzt aber wieder auf CATCH-THROW. -Es wird in folgender Form benutzt: +Die schönste, allgemeinste Art der Fehlerbehandlung, die ich kenne, +ist das CATCH-THROW-Konstrukt aus TLC-Lisp (von T.Allen). Ich habe mir +sagen lassen, daß sie unter Zuhilfenahme des +Call-with-current-Continuation-Konzepts 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) (exceptionhandler))) -Die Bedeutung ist folgende: Wenn whrend -der Evaluierung (=Ausfhrung auf -LISPisch) von EXPRESSION eine Ausnahme -mit dem Namen NAME auftreten sollte, so -mge bitte sofort EXCEPTIONHANDLER -evaluiert werden. Ansonsten ist der -obige Ausdruck identisch mit: +Die Bedeutung ist folgende: Wenn während der Evaluierung (=Ausführung +auf LISPisch) von EXPRESSION eine Ausnahme mit dem Namen NAME +auftreten sollte, so möge bitte sofort EXCEPTIONHANDLER evaluiert +werden. Ansonsten ist der obige Ausdruck identisch mit: (expression) -Eine Ausnahme tritt dadurch auf, da -eine Funktion (=wort auf -LISPisch) innerhalb -von expression die Funktion +Eine Ausnahme tritt dadurch auf, daß eine Funktion (=wort auf +LISPisch) innerhalb von expression die Funktion (THROW name) aufruft. -Eigentlich ist es verabscheuungswrdig, -von Lisp aus Files zu lesen, da dies dem -funktionalen Programmieren zuwiderluft. -Um aber trotzdem das obige -File-Lese-Beispiel nochmal zu -strapazieren: +Eigentlich ist es verabscheuungswürdig, von Lisp aus Files zu lesen, +da dies dem funktionalen Programmieren zuwiderläuft. Um aber trotzdem +das obige File-Lese-Beispiel nochmal zu strapazieren: (CATCH end-of-file (CATCH end-of-line @@ -410,167 +264,114 @@ strapazieren: ( ...end-of-file-handler..) ) -Dies sieht nicht nur wundervoll aus mit -den vielen Klammern, sondern hat auch -eine Wirkung: wenn READCHAR irgendwann -(THROW end-of-line) oder (THROW -end-of-file) evaluiert, wird einer -unsrer HANDLER aufgerufen. Ob READCHAR -das tut und ob es in Lisp berhaupt eine -Funktion diesen Namens gibt, entzieht -sich leider meiner Kenntnis. -Selbstverstndlich knnen solche handler -geschachtelt werden. Um DOSOMETHING -knnte z.B. ein noch -spezielleren handler -heruminstalliert werden. Eine Ausfhrung -von (THROW name) aktiviert jeweils den -nchstueren (hhergelegenen) handler. -Wenn dieser das ntige getan hat, kann -er beispielsweise erneut (THROW name) -evaluieren, um wiederum den ihm -nchstueren handler zu aktivieren. Das -Spiel lt sich weitertreiben, bis -schlielich der alleruerste (von der -LISP-Interpreter-Schleife) installierte -handler aufgerufen wird, der (hnlich -unserem ABORT") wieder Eingaben von der -Tastatur verarbeitet. Selbstverstndlich -kann jeder handler in der Schlange auch -etwas anderes unternehmen, -beispielsweise die gescheiterte Aktion +Dies sieht nicht nur wundervoll aus mit den vielen Klammern, sondern +hat auch eine Wirkung: wenn READCHAR irgendwann (THROW end-of-line) +oder (THROW end-of-file) evaluiert, wird einer unsrer HANDLER +aufgerufen. Ob READCHAR das tut und ob es in Lisp überhaupt eine +Funktion diesen Namens gibt, entzieht sich leider meiner Kenntnis. +Selbstverständlich können solche handler geschachtelt werden. Um +DOSOMETHING könnte z.B. ein noch spezielleren handler heruminstalliert +werden. Eine Ausführung von (THROW name) aktiviert jeweils den +nächstäußeren (höhergelegenen) handler. 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. -o Zurck zu Forth +* Zurück zu Forth Aus dem gesagten seien noch einmal die -Kernpunkte zusammengefat: -- Fehlerbehandlung soll auf jeder - beliebigen Programmebene mchlich sein +Kernpunkte zusammengefaßt: + +- Fehlerbehandlung soll auf jeder beliebigen Programmebene möchlich + sein - insbesondere auch auf tiefster Ebene -- Die Fehlerbehandlungsroutinen sollen - geschachtelt werden knnen -- Fehlerbehandlar sollen Mglichkeiten - erhalten, nach Bedarf die - fehlerverursachende Routine erneut zu - probieren oder die Ausfhrung dem - nchsthheren - Fehlerbehandler weiterzugeben. -- Das ganze soll so einfach zu benutzen - sein, da Routinen fr selten - auftretende Ereignisse einfach zu - formulieren sind. -- Diese Fehlerbehandlung soll durch das - Standardwort ABORT" aktiviert werden. +- Die Fehlerbehandlungsroutinen sollen geschachtelt werden können +- Fehlerbehandlar sollen Möglichkeiten erhalten, nach Bedarf die + fehlerverursachende Routine erneut zu probieren oder die Ausführung + dem nächsthöheren Fehlerbehandler weiterzugeben. +- 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: -Wo sollen die Informationen ber die -installierten Fehlerbehandlungsroutinen -abgelegt werden? Auf dem Returnstack, da -sich hier am einfachsten eine der -jeweiligen Ausfhrungsebene (Wort) -angelehnte Datenstruktur bilden lt. +Nun wird's konkret: Wo sollen die Informationen über die installierten +Fehlerbehandlungsroutinen abgelegt werden? Auf dem Returnstack, da +sich hier am einfachsten eine der jeweiligen Ausführungsebene (Wort) +angelehnte Datenstruktur bilden läßt. -Wie soll die Syntax aussehen? Es soll -einfach sein, daher Kontrollstrukturen. -Beispielsweise: +Wie soll die Syntax aussehen? Es soll einfach sein, daher +Kontrollstrukturen. Beispielsweise: : name .... FAILS ...errorhandler... THEN .... ; -Die Bedeutung: Es wird ein Wort NAME -definiert. Bei Ausfhrung fhrt NAME -erst aus, installiert -anschlieend einen ERRORHANDLER, fhrt -dann aus und deinstalliert -ERRORHANDLER nach Verlassen des Wortes. -Sollte innerhalb von ein -ABORT" ausgefhrt werden, so wird -ERRORHANDLER ausgefhrt. +Die Bedeutung: Es wird ein Wort NAME definiert. Bei Ausführung führt +NAME erst aus, installiert anschließend einen ERRORHANDLER, +führt dann aus und deinstalliert ERRORHANDLER nach Verlassen +des Wortes. Sollte innerhalb von ein ABORT" ausgeführt +werden, so wird ERRORHANDLER ausgeführt. -Aktivieren des ueren ERRORHANDLERS: -Sollte innerhalb von ERRORHANDLER das -Wort THROW ausgefhrt werden, so wird -die Ausfhrung von ERRORHANDLER beendet -und die nchstuere -Fehlerbehandlungsroutine aktiviert. +Aktivieren des äußeren ERRORHANDLERS: Sollte innerhalb von +ERRORHANDLER das Wort THROW ausgeführt werden, so wird die Ausführung +von ERRORHANDLER beendet und die nächstäußere Fehlerbehandlungsroutine +aktiviert. -Wiederholen der fehlerverursachenden -: Hier wird's kritisch. Im -Gegensatz zu praktisch allen anderen -Sprachen liegen die Parameter auf dem -Datenstack. Vor einer Wiederholung -mssen Daten- und Returnstack repariert -werden. Der Returnstack lt sich -problemlos so manipulieren, da er bei -Aufruf von ERRORHANDLER bereits wieder -im gewnschten Zustand ist. Falls ein -definierter Zustand des Datenstacks -gewmscht wird, mu allerdings ein -spezielles Konstrukt: +Wiederholen der fehlerverursachenden : Hier wird's kritisch. +Im Gegensatz zu praktisch allen anderen Sprachen liegen die Parameter +auf dem Datenstack. Vor einer Wiederholung müssen Daten- und +Returnstack repariert werden. Der Returnstack läßt sich problemlos so +manipulieren, daß er bei Aufruf von ERRORHANDLER bereits wieder im +gewünschten Zustand ist. Falls ein definierter Zustand des Datenstacks +gewümscht wird, muß allerdings ein spezielles Konstrukt: nn #FAILS ..errorhandler.. RETRY -benutzt werden. Die NN obersten -Stackwerte, sowie der Stackpointer -werden gesichert. Falls ERRORHANDLER -aufgerufen werden sollte, wird der Stack -vorher soweit restauriert. Es gilt -natrlich aufzupassen, da sie bis -zur Ausfhrung von RETRY auch dableiben. +benutzt werden. Die NN obersten Stackwerte, sowie der Stackpointer +werden gesichert. Falls ERRORHANDLER aufgerufen werden sollte, wird +der Stack vorher soweit restauriert. Es gilt natürlich aufzupassen, +daß sie bis zur Ausführung von RETRY auch dableiben. -Noch ein weiteres Konstrukt wurde -eingefhrt: +Noch ein weiteres Konstrukt wurde eingeführt: : name .... EXITS ..errorhandler.. throw THEN ... ; -Es trgt der Idee Rechnung, da -ERRORHANDLER des fteren nur installiert -wird, um eine Ressource zu schlieen. -Die Bedeutung: Es wird ein Wort NAME -definiert. Bei Ausfhrung fhrt NAME -erst aus, installiert -anschlieend einen ERRORHANDLER, fhrt -dann aus. ERRORHANDLER wird -im Falle eines Fehlers oder nach -Verlassen des Wortes NAME ausgefhrt. -Es lassen sich also so schne Konstrukte +Es trägt der Idee Rechnung, daß ERRORHANDLER des öfteren nur +installiert wird, um eine Ressource zu schließen. Die Bedeutung: Es +wird ein Wort NAME definiert. Bei Ausführung führt NAME erst +aus, installiert anschließend einen ERRORHANDLER, führt dann +aus. ERRORHANDLER wird im Falle eines Fehlers oder nach Verlassen des +Wortes NAME ausgeführt. Es lassen sich also so schöne Konstrukte bilden wie: : machWas ... - .... - EXITS .... throw THEN - .... - EXITS .... throw THEN + ..<öffne-Gerät1>.. + EXITS .... throw THEN + ..<öffne-Gerät2>.. + EXITS .... throw THEN .... ; -Es werden auf jeden Fall die geffneten -Gerte wieder geschlossen, ob nun ein -Fehler auftritt oder nicht. +Es werden auf jeden Fall die geöffneten Geräte wieder geschlossen, ob +nun ein Fehler auftritt oder nicht. -o Was gibt es noch fr Anstze in Forth +* Was gibt es noch für Ansätze in Forth -Der vorgestellte Ansatz bringt nichts -prinzipiell neues. In ///////Schliesieck -lt sich eine Methode nachlesen, die -sicherlich schneller und einfacher -implementiert ist, allerdings verndert -sie nicht das Verhalten von ABORT", -sondern mu mit einem gesonderten Wort -aufgerufen werden. Auch sichert sie -lediglich den Stackpointer, eventuelle -Parameter mssen also 'zu Fu' -gesichert werden. //////weiter.... -wenn m +Der vorgestellte Ansatz bringt nichts prinzipiell neues. In +///////Schliesieck läßt sich eine Methode nachlesen, die sicherlich +schneller und einfacher implementiert ist, allerdings verändert sie +nicht das Verhalten von ABORT", sondern muß mit einem gesonderten Wort +aufgerufen werden. Auch sichert sie lediglich den Stackpointer, +eventuelle Parameter müssen also 'zu Fuß' gesichert werden. +//////weiter.... wenn m - Schner: statt THROW ein EXIT -nehmen. Was passiert bei exit? -Bitte nicht IF..ELSE..RETRY -Bitte kein FAILS...THEN ohne throw oder -so + chöner: statt THROW ein EXIT nehmen. Was passiert bei exit? Bitte +nicht IF..ELSE..RETRY Bitte kein FAILS...THEN ohne throw oder so Wie rauskriegen, welcher Fehler passiert ist? - \ No newline at end of file diff --git a/6502/UltraForth/README.TXT b/6502/UltraForth/README.TXT old mode 100755 new mode 100644 diff --git a/6502/gen6502/vFORTH38/fb2fth.py b/tools/fb2fth.py similarity index 100% rename from 6502/gen6502/vFORTH38/fb2fth.py rename to tools/fb2fth.py