% Content-encoding: UTF-8 \documentclass[ngerman]{article} \usepackage[utf8]{inputenc} \usepackage{multicol} % \usepackage{babel} \usepackage{xspace} \setcounter{secnumdepth}{0} \setcounter{tocdepth}{0} \usepackage{german} %\newcommand{\code}[1]{\texttt{#1}} %\newcommand{\ret}{\textsf{$<$ret$>$}\xspace} %\newcommand{\ret}{$\hookleftarrow$\xspace} \renewcommand{\reftextbefore}{auf der vorherigen Seite} \renewcommand{\reftextfacebefore}{auf der gegenüberliegenden Seite} \renewcommand{\reftextafter}{auf der nächsten Seite} \renewcommand{\reftextfaceafter}{auf der gegenüberliegenden Seite} \renewcommand{\reftextfaraway}[1]{auf Seite \pageref{#1}} \renewcommand{\figurename}{Abbildung} \title{IF-ELSE-THEN etc. als Colon-Definition ohne Assembler und ohne immediate} \ifx\shorttitle\undefined\else \shorttitle{IF-ELSE-THEN in high level} \fi \author{Fred Behringer} \begin{document} \maketitle Dieser Artikel kann als Fortsetzung von [FB-4] betrachtet werden. Es wird gezeigt, dass auch die Konstrukte if-then, if-else-then, begin-until und begin-while-repeat ohne Assembler, mit den einfachsten Primitives aus [WS09] und ohne die Immediate-Eigenschaft als Colon-Definitionen aufgebaut werden können. \begin{multicols}{2} Seien \verb|aaa| und \verb|bbb| Forth-Worte beliebiger Bauart. Als Beispiel darf ich \begin{verbatim} : aaa 4 . 5 . 6 . ; : bbb 7 . 8 . 9 . ; \end{verbatim} verwenden. Selbstverständlich lässt sich beispielsweise die Konstruktion \verb|if aaa else bbb then| bilden und verwenden - aber nicht interpretativ! Also irgendwie nur wie folgt: \begin{verbatim} : www if aaa else bbb then ; \end{verbatim} Dabei ist es möglich, auf die klammernden Worte \verb|aaa| und \verb|bbb| zu verzichten. Also auch: \begin{verbatim} : www if 4 . 5 . 6 . else 7 . 8 . 9 . then ; \end{verbatim} zu schreiben. Soweit die übliche Forth-Syntax (Weiteres beispielsweise zum ANS-Forth-Standard siehe [AF94]). Solche Konstruktionen sind ein typisches Beispiel für die Verwendung von Immediate-Worten, also von Worten, die schon während der Compilation ausgeführt werden (ausgeführt werden müssen). Dabei ist es für Rückwärtssprünge der Art von begin-again gar nicht nötig, das Sprungziel schon während der Compilation zur Verfügung zu haben. Compiliert wird \glqq{}von links nach rechts\grqq{} und man kann sich erlauben, das Rückwärts-Ziel erst unmittelbar vor der Ausführung der \verb|begin|-\verb|again|-Konstruktion einzubringen. Das heißt, man braucht für diesen Zweck gar kein Immediate-Wort. Von dieser Erkenntnis habe ich für begin-again zum ersten Mal bei Coos Haak [CH93] Notiz genommen. Ähnliches gilt für den Einbau von Assembler-Befehlen. Mit anderen Worten, \verb|begin|-\verb|again| kann rein in High-Level-Forth konstruiert werden. Ich habe in [FB-4] versucht, diesen Gedanken auszudehnen, und mir die Frage gestellt, ob es in Forth vielleicht sogar möglich ist, ganz ohne Immediate-Worte auszukommen. Etwas schwieriger als bei Rückwärtssprüngen ist es bei Vorwärtssprüngen. Wann soll der Sprungziel-Parameter eingebaut werden (Einpass-Compilation von links nach rechts)? Zur Ausführungszeit (Runtime) ist es zu spät. Man braucht ja die Sprungweite zum Beispiel bei \verb|if|-\verb|then| schon gleich am Anfang der Konstruktion, wenn \verb|if| noch in Bearbeitung ist und der Sprung gegebenenfalls ausgeführt werden soll. Wenn ich nun aber das Mark des Kontroll-Gerüstes \verb|if|-\verb|else| in ein klamerndes Wort stecke, also wenn ich \verb|if aaa else| schreibe (Ähnliches bei \verb|else bbb then| usw.), dann sieht die Situation anders aus. Die Wirkungsweise mit Klammerwort ist genau dieselbe wie ohne. Im Gegenteil, man kann ja auch mit dem herkömmlichen \verb|if|-\verb|else|-\verb|then| die eben genannte Klammerung durch Hüllworte einführen, ohne dass sich am Geschehen etwas ändert! Aber mit dem Wort \verb|aaa| steht sofort, gleich zu Anfang der Ausführung (Runtime), schon unmittelbar nach der Compilation, das Sprungziel, bezogen auf www, zur Verfügung, nämlich auf dem Returnstack als Adresse hinter \verb|aaa| in der aufrufenden Colon-Definition, hier \verb|www|. Ich bin in [FB-4] davon ausgegangen, und tue das auch hier wieder, dass ein Compilator (Colon-Compiler) in Aktion treten darf, dass aber im Übrigen, ausgehend von einer beschränkten Zahl von Primitives, nur solche Worte (strikt als Colon-Definitionen) zum Aufbau des Systems zur Verfügung stehen, die zum jeweiligen Zeitpunkt schon definiert sind. Das Ganze läuft irgendwie auf eine Münchhausen-artige inkrementelle Metacompilation ohne expliziten Metacompiler hinaus. Ich erhebe im vorliegenden Artikel, im Listing zumindest ab dem Wort \verb|if|, folgende Modifikationsforderung an die Forth-Syntax: \begin{verbatim} : ww1 if aaa then ; : ww2 if aaa else bbb then ; : ww3 begin ccc while ddd repeat ; \end{verbatim} \verb|aaa bbb ccc ddd| sind ausführbare Forth-Worte. Alles, was \glqq{}normalerweise\grqq{} zwischen \verb|if| und \verb|then| steht, muss in ein solches Forth-Wort, ich will es Hüllwort nennen, gepackt sein. Entsprechendes gelte für die Strukturpaare \verb|if|-\verb|else| und \verb|else|-\verb|then| und \verb|while|-\verb|repeat|. Im Innern eines solchen Strukturpaares darf jeweils nur immer ein einziges Hüllwort stehen. Das Hüllwort darf leer bleiben, es muss aber (als Worthülse) vorhanden sein. (Das Wort noop könnte beispielsweise als leeres Hüllwort dienen.) Zwischen \verb|begin| und \verb|while| ist kein Hüllwort nötig, zwischen \verb|begin| und \verb|until| auch nicht, zur Abrundung kann es aber auch dort gesetzt werden. Gleiches gilt für das schon in [FB-4] behandelte \verb|begin|-\verb|again| aus [CH93]. Zum Austesten verwende ich Turbo-Forth in der 16-Bit-Ausführung. Aus [FB-4] verwende ich ein paar Worte, die ich im Listing ohne Kommentar hier noch einmal anführe. Ich mache davon Gebrauch, dass ich in Forth (in Turbo-Forth auf jeden Fall) jedes Wort beliebig oft in den Quelltext schreiben kann, ohne dass das den Programmablauf prinzipiell stört. Die Beschaffung der Primitives ist nicht Untersuchungsgegenstand der vorliegenden Arbeit. Selbstverständlich beschaffe ich mir (für die Beispiele und für Testzwecke) sämtliche benötigten Primitives (für die relevanten Textstellen sind das \verb|dup| \verb|r@| \verb|r>| \verb|>r| \verb|drop| \verb|d+| \verb|-| \verb|+| \verb|swap|) über den in Turbo-Forth eingebauten Assembler. Mit anderen Worten: Zum Ausprobieren lege ich nicht nur den Colon-Compiler, sondern das gesamte Turbo-Forth-Basissystem zu Grunde. Sollte ich dabei unbeabsichtigt über das Ziel hinausgeschossen sein, bitte ich freundlich um Hinweise. \end{multicols} \section*{Literatur} \begin{tabular}{lp{8cm}} {}[AF94] & ANS-Forth-Standard: The American National Standard for the Forth language (ANSI X3J14:1994).\\ \\ {}[CH93] & Haak, Coos: 'Lusstructuren maken zonder IMMEDIATE'. Vijgeblad 43 (1993), S.10. Auch unter http://www.forth.hccnet.nl/vijgebladarchief/ - 118k .\\ \\ {}[FB-1] & Behringer, Fred: Über Flags in Forth. Vierte Dimension 1/2011, S.33-34.\\ \\ {}[FB-4] & Behringer, Fred: Kontrollstrukturen als Colon-Definitionen und ohne die Immediate-Eigenschaft?. Vierte Dimension 4/2011, S. 35-40.\\ \\ {}[WS09] & Stricker, Willi: Minimaler Basis-Befehlssatz für ein Forth-System. Vierte Dimension 3/2009, S.15-17. \end{tabular} \section*{Listing} \listinginput[1]{1}{2012-01/LIST12-1.TXT} \vfill %Abbildung: DanglingElse \begin{figure*}[h] \begin{center} \includegraphics[width=0.7\textwidth]{2012-01/DanglingElse} %\caption{\label{Bild1}Zu welchen Sprachen gehören die Schreibweisen?} \end{center} \end{figure*} \vfill \end{document}