\documentclass{beamer} \usepackage{amsmath} \usepackage{url} \usepackage{ucs} \usepackage[utf8]{inputenc} \usepackage[ngerman]{babel} % This is a not yet finished (German) talk I'll hold at the next meeting of the % Linux User Group Augsburg (LUGA) (on 2005-08-04). % % Compile to PDF using... % $ pdflatex Anatomie_eines_Compilers_am_Beispiel_von_Pugs.latex % % Feel free to add/change contents (don't forget to add you to the author % list)! % % As this talk is German, the following comments are German, too. % Manual syntax highlighting \newcommand{\synfunc} [1]{\color{blue!50!black}#1\color{black}} \newcommand{\synstr} [1]{\color{red!50!black}#1\color{black}} \newcommand{\synvar} [1]{\color{purple!50!black}#1\color{black}} \newcommand{\synclass} [1]{\color{green!50!black}#1\color{black}} \newcommand{\syncomment}[1]{\color{blue!20!black}#1\color{black}} \newcommand{\syncool} [1]{\color{beamer@blendedblue}#1\color{black}} \newcommand{\synoder} {\ \ \color{black}$\vee$\ \ } \newcommand{\hr} {\rule[4pt]{\textwidth}{0.1pt}\\} \title{Anatomie eines Compilers am Beispiel von Pugs} \author{Ingo Blechschmidt \\\texttt{<iblech@web.de>}} \institute{LUGA} \date{3. August 2005} \usetheme{Warsaw} \usecolortheme{seahorse} \setbeamercovered{transparent} \begin{document} \frame{\titlepage} \section{} \frame{ \frametitle{Inhalt} \tableofcontents } \section{Pugs} \frame[t]{ \frametitle{Pugs} \begin{itemize} \item Pugs: Prototyp des Perl 6-Compilers \item "`Perl 6 ist ja schön und gut, aber das dauert doch noch Jahre, bis es fertig ist!"' \item "`Die Entwickeln doch schon seit Jahren dran!"' \item Nur tote Produkte sind "`fertig"'. \item Seit dem 1. Februar gibt es Pugs. Heute kann man vernünfig in Perl 6 programmieren. \end{itemize} } \subsection{"Ubersicht} \frame[t]{ \frametitle{Pugs} \begin{itemize} \item Ursprünglich Haskell-Projekt von Autrijus Tang "`als Übung"' \item Projektbeginn: 1. Februar 2005 \item Nun 130 Entwickler \item Version 6.2.8: Beinahe Alles (!), mehrere Backends (direkte Ausführung, Kompilierung zu Haskell, zu Perl 5, zu JavaScript, etc.) \end{itemize} } \subsection{Entwicklung} \frame[t]{ \frametitle{Entwicklung} \begin{itemize} \item Test-driven development -- \item Camelfolk: Schreiben von Tests in Perl 6 für noch nicht implementierte Features \\ \texttt{% \ \ \synfunc{is}\ 23 + 42, 64, "\synstr{Einfache Rechnungen funzen.}";\\ \ \\ \ \ \synfunc{my}\ \synvar{@array}\ = <\synstr{a b c}>;\\ \ \ \synfunc{is}\ +\synvar{@array}, 3,\\ \ \ \ \ "\synstr{Unser Array enthält drei Elemente.}"; } \pause \item Lambdafolk: Implementierung dieser Features \item Ergebnis der Zusammenarbeit: \\ Über 7.700 funktionierende Tests \end{itemize} } \subsection{Pl"ane} \frame[t]{ \frametitle{Pläne} \begin{tabbing} Pugs 6.283185aaa \= ... \kill \color{beamer@blendedblue}Pugs 6.0 \> Erstes Release \\ \color{beamer@blendedblue}Pugs 6.2 \> Grundlegende IO- und Kontrollflusselemente, \\\> veränderbare Variablen \\ \color{beamer@blendedblue}Pugs 6.28 \> Klassen \\ \color{beamer@blendedblue}Pugs 6.283 \> Rules und Grammars \\ \color{beamer@blendedblue}Pugs 6.2831 \> Rollen \\ \color{beamer@blendedblue}Pugs 6.28318 \> Makros \\ \color{beamer@blendedblue}Pugs 6.283185 \> Portierung von Pugs von Haskell nach Perl 6 \\ \color{beamer@blendedblue}Pugs $2\pi$ \> Vollendung \end{tabbing} } \subsection{Beteiligungsm"oglichkeiten} \frame[t]{ \frametitle{Beteiligungsmöglichkeiten} \begin{itemize} \item Mailinglisten: \\ \texttt{perl6-language@perl.org}, \\ \texttt{perl6-compiler@perl.org}, \\ \texttt{gmane.comp.lang.perl.perl6.language}, \\ \texttt{gmane.comp.lang.perl.perl6.compiler} \item IRC: \texttt{\#perl6} auf Freenode \item Auch Newbies sehr gern gesehen! \item Schreiben von Tests (Perl 6), Implementierung (Haskell), Schreiben von Dokumentation, Portierung von Perl~5\texttt{|}Python\texttt{|}Ruby\texttt{|}\ldots-Modulen nach Perl 6, \ldots \item Weitere Informationen: \url{http://www.pugscode.org/} \end{itemize} } \section{Compiler} \subsection{Arbeitsschritte} \frame[t]{ \frametitle{Arbeitsschritte} \begin{enumerate} \item Parsen: Umwandlung des Sourcecode in einen Parse Tree \item Kleinere Optimierungen \item Umwandlung des Parse Tree in einen einfacheren Tree \item Größere Optimierungen, Argumentieren über den Code (z.B. Verbot von \texttt{3 = 4} zur Compile-Zeit) \item Umwandlung ins Zielformat \item Kleinere Optimierungen \item Ausgabe \end{enumerate} } \subsection{Beispiel: Perl 6 $\to$ JavaScript-Compiler} \frame[t]{ \frametitle{Beispiel: Perl 6 $\to$ JavaScript-Compiler} \begin{itemize} \item PIL2JS: Spiel-Projekt von mir, Projektbeginn: 16.7.2005 \item $\approx$ 4.000 Zeilen Perl 5, Perl 6 und JavaScript \item "`Perl 6 überall"' (Browser, PDFs, Flash, \ldots) \end{itemize} \vfill\pause \begin{enumerate} \item Einlesen und Parsen von Perl 6 durch Pugs \item Ausgabe von Pugs Intermediate Language (PIL) durch Pugs \item Einlesen des PIL-Trees durch PIL2JS \item Kleinere Umwandlungen \item Ausgabe als JavaScript \end{enumerate} } \section{Perl 6 $\to$ JavaScript} \subsection{Perl 6 $\to$ PIL} \frame[t]{ \frametitle{Parsen von Perl 6-Sourcecode (Perl 6 $\to$ PIL)} \begin{itemize} \item Perl 6 ist eine umfangreiche Sprache. \item Wenn jedes Backend Perl 6 selbst parsen müsste, wäre das viel doppelte Arbeit. \item Stattdessen: Parsen von Perl 6 durch Pugs, Ausgabe des Codes in einer Zwischen-Sprache, Pugs Intermediate Language (PIL) \item Einlesen des PIL durch die einzelnen Backends -- Kümmern ums Parsen unnötig \end{itemize} } \frame[t]{ \frametitle{Beispiel} \texttt{% \syncomment{\# Perl 6:}\\ \synvar{\$foo}\ = 19; \\ \synfunc{say}\ 4 + \synvar{\$foo};\\ } \vfill \texttt{% \syncomment{-- PIL (vereinfacht):}\\ \synfunc{PAssign}\ (\synfunc{PVar}\ "\synvar{\$foo}") (\synfunc{PLit}\ 19)\\ \synfunc{PApp}\ (\synfunc{PVar}\ "\synvar{\&say}") [\\ \ \ \synfunc{PApp}\ (\synfunc{PVar}\ "\synvar{\&infix:<+>}") [\\ \ \ \ \ \synfunc{PLit}\ 4, \synfunc{PVar}\ "\synvar{\$foo}"\\ \ \ ]\\ ] } } \subsection{PIL $\to$ JavaScript} \frame[t]{ \frametitle{Kompilieren des PIL zu JavaScript} \begin{itemize} \item "`Sowohl Perl 6 als auch JavaScript sind Turing-vollständig, wo also liegt das Problem? (:D)"' \item JavaScript: weniger mächtig als Perl 6 \item Also: Herunterkompilation vieler Features erforderlich \end{itemize} } \subsection{Probleme} \frame[t]{ \frametitle{Problem: Signaturen von Subroutinen} \begin{itemize} \item Perl 6: Reiche Möglichkeiten zur Spezifikation von Signaturen (Parameter-Listen; ähnlich wie Ruby oder Python): \texttt{\small% \synfunc{sub}\ \synvar{foo}\ (\synclass{Grtz}\ \synvar{\$grtz}, \synclass{Bool}\ ?\synvar{\$verbose}\ = \synvar{false}) \{...\}\\ \ \\ \syncomment{\# Ok:}\\ \synvar{foo}\ \synvar{\$irgendein\_grtz\_objekt};\\ \synvar{foo}\ \synvar{\$irgendein\_grtz\_objekt}, \synvar{true};\\ \synvar{foo}\ \synvar{\$irgendein\_grtz\_objekt}, :\synstr{verbose};\\ \synvar{foo}\ \synvar{\$irgendein\_grtz\_objekt}, :\synstr{verbose}(\synvar{true});\\ \synvar{foo}\ \synvar{\$irgendein\_grtz\_objekt}, \synstr{verbose}\ => \synvar{true};\\ \ \\ \syncomment{\# Fehler:}\\ \synvar{foo}\ "\synstr{Zu}", <\synstr{viele}>, \synvar{\$parameter};\\ \synvar{foo}(); } \end{itemize} } \frame[t]{ \frametitle{Problem: Signaturen von Subroutinen} \begin{itemize} \item JavaScript (vor Version 2): Weit weniger umfangreiche Möglichkeiten, Ignorieren von zu vielen/zu wenigen Parametern (ähnlich wie PHP): \texttt{% \synfunc{function}\ \synvar{foo}\ (\synvar{grtz}, \synvar{verbose}) \{...\}\\ \ \\ \syncomment{// Ok:}\\ \synvar{foo}(\synvar{irgendein\_grtz\_objekt});\\ \synvar{foo}(\synvar{irgendein\_grtz\_objekt}, \synvar{true});\\ \ \\ \syncomment{// Ebenfalls ok (!):}\\ \synvar{foo}();\\ \synvar{foo}("\synstr{Zu}", \synvar{viele}, \synclass{Para}.\synvar{meter}); } \end{itemize} } \frame[t]{ \frametitle{Problem: Lexikale Variablen} \begin{itemize} \item Perl 6: Lexikale Variablen (wie bei Ruby, Python, C und vielen anderen Sprachen): \texttt{% \{ \synfunc{say}\ \synvar{\$a}\ \}\ \ \ \ \ \ \ \ \ \ \ \ \ \syncomment{\# Fehler}\\ \{ \synfunc{my}\ \synvar{\$a}; \synfunc{say}\ \synvar{\$a}\ \}\ \ \ \ \ \ \syncomment{\# Ok}\\ \{ \synfunc{say}\ \synvar{\$a}; \synfunc{my}\ \synvar{\$a}\ \}\ \ \ \ \ \ \syncomment{\# Fehler}\\ } \item JavaScript (ähnlich wie bei Bash oder PHP): \texttt{% \{ \synfunc{alert}(\synvar{a}) \}\ \ \ \ \ \ \ \ \ \ \ \syncomment{// Fehler}\\ \{ \synfunc{var}\ \synvar{a}; \synfunc{alert}(\synvar{a}) \}\ \ \ \ \syncomment{// Ok}\\ \{ \synfunc{alert}(\synvar{a}); \synfunc{var}\ \synvar{a}\ \}\ \ \ \ \syncomment{// Kein (!) Fehler}\\ } \item Daher, leider: Durchnummerieren aller lexikalen Variablen (\texttt{\synvar{\$a\_1}}, \texttt{\synvar{\$a\_2}}, \ldots) und dann Deklaration als globale JavaScript-Variablen \end{itemize} } \frame[t]{ \frametitle{Problem: Objekt-Metamodell} \begin{block}{Objekt-Metamodell} "`Was ist eine Klasse?"' -- "`Was ist ein Objekt?"' -- "`Ist eine Klasse auch ein Objekt?"' -- \ldots \end{block} \begin{itemize} \item Perl 6: Mächtiges Objekt-Metamodell, mit Features u.a. von Smalltalk und CLOS \item JavaScript: Weniger mächtiges Modell \end{itemize} \vfill \begin{itemize} \item Viele Backends haben dieses Problem. \item Daher: Exzellente Arbeit von Stevan Little: \\ Perl 6-Metamodell für Perl 5, Perl 6, JavaScript, Java, C\#, \ldots \end{itemize} } \frame[t]{ \frametitle{Weitere Probleme} \begin{itemize} \item Firefox: langsame JavaScript-Ausführung \item Wichtiger noch: Ausführung von Seiten-JavaScripts im gleichen Thread wie die UI (Hänger!) \item Aber: Exzellente JavaScript-Implementation \end{itemize} } \frame[t]{ \frametitle{"`Never do any live demos!"'} \begin{itemize} \item Hello, World! \item \texttt{mandel.p6} \item Testsuite \end{itemize} } \section{Fazit} \frame[t]{ \frametitle{Fazit} \begin{itemize} \item Compiler-Schreiben ist leichter als man denkt. :D \item Besonders leicht wird es, wenn einem viel Arbeit abgenommen wird. :) \end{itemize} \setbeamercovered{invisible} \vfill\pause \begin{center} \Huge Join the fun! \\ \normalsize \url{http://www.pugscode.org/} \end{center} } \end{document}
Download