summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
m---------CleanSmurf0
-rw-r--r--clean.sty74
-rw-r--r--cleansmurf.tex123
-rw-r--r--org.tex5
-rw-r--r--refs.tex3
-rw-r--r--werkstuk.tex4
7 files changed, 210 insertions, 2 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..5ebd18b
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "CleanSmurf"]
+ path = CleanSmurf
+ url = https://github.com/camilstaps/CleanSmurf
diff --git a/CleanSmurf b/CleanSmurf
new file mode 160000
+Subproject d8297fec19292c544a32a474500eca49552215d
diff --git a/clean.sty b/clean.sty
new file mode 100644
index 0000000..c933773
--- /dev/null
+++ b/clean.sty
@@ -0,0 +1,74 @@
+\usepackage{listings}
+
+\lstdefinelanguage{Clean}{%
+ alsoletter={ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_`1234567890},
+ alsoletter={~!@\#$\%^\&*-+=?<>:|\\.},
+ morekeywords={generic,implementation,definition,dynamic,module,import,from,where,in,of,case,let,infix,infixr,infixl,class,instance,with,if,derive},
+ sensitive=true,
+ morecomment=[l]{//},
+ morecomment=[n]{/*}{*/},
+ morestring=[b]",
+ morestring=[b]',
+ emptylines=1,
+ basicstyle=\small,
+ identifierstyle=\ttfamily,
+ commentstyle=\itshape,
+ keywordstyle=\bfseries,
+ stringstyle=\ttfamily,
+ numbers=none,
+ showstringspaces=false,
+ basewidth=0.45em,
+ columns=[c]fixed,
+ keepspaces=true,
+ breaklines=false,
+ tabsize=4,
+ texcl=true,
+ escapeinside={(\#}{\#)},
+ literate=%
+ % Basic Clean constructs
+ {\\}{{$\lambda\:$}}1
+ {A.}{{$\forall\;\,$}}1
+ {E.}{{$\exists\;\,$}}1
+ {>}{{$>$}}1
+ {<}{{$<$}}1
+ {`}{{\texttt{'}}}1
+ {<=}{{$\leq$}}1
+ {>=}{{$\geq$}}1
+ {<>}{{$\neq$}}1
+ {-->}{{$\Rightarrow$}}2
+ {->}{{$\rightarrow$}}2
+ {<-}{{$\leftarrow$}}1
+ {=}{{$=$}}1
+ {~}{{$\sim$}}1
+ {*}{{$\star$}}1
+ %{\#}{{$\sharp$}}1
+ {\{|}{{$\{\!|\!$}}1
+ {|\}}{{$\!|\!\}$}}1
+ {:=}{{$:=$}}2
+ {=:}{{$\>=:$}}3
+ {==}{{$==$}}2
+ {++}{{$+\!\!+$}}2
+ {+++}{{$+\!\!\!\!+\!\!\!\!+$}}2
+ {:==}{{$:==$}}3
+ {\{|*|\}}{{$\{\!|\!\!\star\!\!|\!\}$}}3
+ %
+ % Basic iTask constructs
+ {>||>}{{$\triangleright\triangleright$}}2
+ {>>=}{{\texttt{>>=}}}3
+ {>>|}{{\texttt{>>|}}}3
+ {?>>}{{\texttt{?>>}}}3
+ {!>>}{{\texttt{!>>}}}3
+ {-||-}{{\texttt{-||-}}}4
+ {.||.}{{\texttt{.||.}}}4
+ {.&&.}{{\texttt{.\&\&.}}}4
+}
+
+\newcommand{\CleanInline}[1]{\lstinline[language=Clean]¦#1¦}
+\newcommand{\CI}[1]{\CleanInline{#1}}
+
+\lstdefinestyle{numbers}{numbers=left, stepnumber=1, numberstyle=\tiny, numbersep=5pt}
+
+\lstnewenvironment{CleanCode}{\lstset{language=Clean,identifierstyle=\ttfamily}}{}
+\lstnewenvironment{CleanCodeN}{\lstset{language=Clean,style=numbers}}{}
+\lstnewenvironment{CleanCodeB}{\lstset{language=Clean,frame=single}}{}
+\lstnewenvironment{CleanCodeNB}{\lstset{language=Clean,style=numbers,frame=single}}{}
diff --git a/cleansmurf.tex b/cleansmurf.tex
new file mode 100644
index 0000000..24011bf
--- /dev/null
+++ b/cleansmurf.tex
@@ -0,0 +1,123 @@
+% vim: set spelllang=nl:
+\section{CleanSmurf}
+\label{sec:cleansmurf}
+
+Semantiekregels vertalen zich uiterst gemakkelijk naar een implementatie van
+een interpreter in een functionele taal. \emph{CleanSmurf}~\cite{cleansmurf} is
+een interpreter voor Smurf, geschreven in Clean, dat onze semantiekregels
+volgt. Omdat het de semantiekregels volgt, was het niet lastig dit uit te
+breiden naar een programma dat een afleidingsboom genereert. In dit hoofdstuk
+beschrijven we de globale opzet van dit programma.
+
+\subsection{Types}
+\label{sec:cleansmurf:types}
+Het programma houdt de expressieve syntax uit \autoref{sec:def:syn} aan. Het
+type \CI{Stm} is dus:
+
+\lstinputlisting[firstline=15,lastline=20]{CleanSmurf/Smurf.dcl}
+
+We gebruiken lijsten als stacks en implementeren de store met behulp van een
+tabel van naam-waarde paren:
+
+\lstinputlisting[firstline=22,lastline=27]{CleanSmurf/Smurf.dcl}
+
+Ten slotte definiëren we transities. Aangezien alle semantiekregels hooguit één
+premisse hebben, kunnen we een afleidingsboom als lijstje transities zien:
+
+\lstinputlisting[firstline=35,lastline=36]{CleanSmurf/Smurf.dcl}
+
+Met deze definities kunnen we een \CI{step :: Program State -> Maybe (Program,
+State)} definiëren. Dit komt bijna overeen met de structuur van transities. We
+moeten een \CI{Program} teruggeven, omdat we slechts één stap zetten. Wat dit
+betreft lijken de regels van \emph{CleanSmurf} meer op regels in structurele
+operationele semantiek. We hebben al laten zien dat deze regels erg veel lijken
+op die in natuurlijke semantiek.
+
+Het type van \CI{step} neemt nog geen Input/Output mee. We maken er een
+overloaded functie van, zodat hij voor meerdere inputmethodes kan worden
+gebruikt. Het uiteindelijke type is:
+
+\lstinputlisting[firstline=56,lastline=56]{CleanSmurf/Smurf.dcl}
+
+Hoe dit precies werkt is niet belangrijk voor de beschrijving hier. Het derde
+argument, van type \CI{io}, is de `IO-toestand'. Het vierde argument, van type
+\CI{IO io}, omvat een input-functie die strings oplevert (gegeven de
+IO-toestand) en een output-functie die strings opneemt (in de IO-toestand).
+
+\medskip
+Verder definiëren we een aantal hulpfuncties:
+
+\lstinputlisting[firstline=232,lastline=245]{CleanSmurf/Smurf.icl}
+
+De partiële functies zijn hier gesimuleerd met het \CI{Maybe}-type. Dit laat
+ons monadische operatoren gebruiken in het uitwerken van de interpreter.
+
+\subsection{Semantiekregels}
+\label{sec:cleansmurf:regels}
+Iedere semantiekregel vertaalt min of meer direct naar een functiealternatief
+voor \CI{step}. Echter, omdat we geen \CI{run}- maar een \CI{step}-functie
+schrijven, moeten we compositie expliciet maken.
+
+Als voorbeeld zullen we de implementatie van $\StmHead$ bekijken. Aangezien
+\CI{pop} en \CI{head} allebei een \CI{Maybe} opleveren, kunnen we de resultaten
+gemakkelijk binden. Vervolgens wordt de stack geüpdate en wordt de rest van het
+programma (\CI{p}) teruggegeven. De IO-toestand wordt zonder gebruik
+doorgegeven. Het vierde argument hebben we niet nodig en kan dus worden
+genegeerd.
+
+\lstinputlisting[firstline=213,lastline=215]{CleanSmurf/Smurf.icl}
+
+Andere regels, voor $\StmPush$, $\StmTail$, $\StmCat$, $\StmQuotify$ en ook
+$\StmPut$ en $\StmGet$ gaan op soortgelijke wijze. Ook $\StmInput$ en
+$\StmOutput$ kunnen op dezelfde manier worden geschreven, afgezien van het feit
+dat de IO-toestand en -functies gebruikt moeten worden.
+
+In het geval van $\StmExec$ kunnen we handig gebruik maken van het feit dat
+\CI{step} een nieuw programma oplevert:
+
+\lstinputlisting[firstline=228,lastline=230]{CleanSmurf/Smurf.icl}
+
+Zoals te zien wordt een nieuwe toestand gemaakt (\CI{zero}) waarin dit nieuwe
+programma (\CI{p}) wordt uitgevoerd. De compositie \CI{parse o fromString}
+parseert een String van de stack en levert een \CI{Maybe Program} op. Dus ook
+deze wat afwijkende regel levert geen problemen op.
+
+\subsection{Afleidingsbomen}
+Door herhaaldelijk gebruik te maken van \CI{step} kunnen we gemakkelijk een
+afleidingsboom genereren. We maken hierbij gebruik van een aantal handige
+eigenschappen van afleidingsbomen voor Smurf:
+
+\begin{itemize}
+ \item Alle semantiekregels hebben ten hoogste één premisse, waardoor we een
+ boom als lijst van transities kunnen representeren.
+ \item Ieder commando heeft precies één regel. Hierdoor is aan het eerste
+ statement van een programma te herkennen welke regel wordt toegepast. Dit
+ hoeven we dus niet in de types \CI{Transition} en \CI{DerivationTree} op te
+ slaan.
+ \item Doordat condities van de semantiekregels enkel afhangen van de
+ linkerkant van de conclusie (het programma, de input en de toestand), en
+ deze informatie beschikbaar is op het moment dat de boom gemaakt wordt,
+ hoeven we geen backtracking toe te passen. Wanneer het niet lukt de regel
+ die bij het eerste commando van het programma hoort toe te passen, weten we
+ zeker dat er geen afleidingsboom bestaat.
+\end{itemize}
+
+De functie \CI{tree} is als volgt geïmplementeerd:
+
+\lstinputlisting[firstline=274]{CleanSmurf/Smurf.icl}
+
+Bij het genereren van bomen leggen we de input van te voren vast in een lijst.
+We slaan de output op in een andere lijst. Dit is wat het type \CI{ListIO}
+inhoudt --- de implementatie hiervan is irrelevant hier.
+
+Het eerste dat \CI{tree} doet is het berekenen van de volgende stap. Lukt dat
+niet (\CI{isNothing mbPgmSt}), dan kunnen we ook geen boom maken.
+
+Omdat \CI{step} voor een leeg programma een nieuw leeg programma oplevert,
+moeten we in deze functie controleren of het nieuwe programma leeg is. Is dit
+het geval, dan zetten we de $\lambda$-regel zelf in de boom als \CI{([],
+io.input, st) --> (io.input, [], st)}.
+
+Is dit niet het geval, dan maken we recursief een boom voor de premisse
+(\CI{tree pgm st io iof}). Lukt dit niet, dan kunnen we geen boom maken.
+Anders, dan voegen we de boom en de transitie gevonden met \CI{step} samen.
diff --git a/org.tex b/org.tex
index a13f0ae..8314a86 100644
--- a/org.tex
+++ b/org.tex
@@ -10,8 +10,9 @@ specificatie \cite{safalra}, waarbij we dingen verhelderen en ongedefinieerd
gedrag definiëren. In \autoref{sec:sos} laten we zien wat voor regels we zouden
moeten gebruiken als we structurele operationele semantiek zouden gebruiken. In
\autoref{sec:analyse} bekijken we een stuk code aan de hand van de
-gedefinieerde regels.
+gedefinieerde regels. Hierbij gebruiken we \emph{CleanSmurf}, een zelfgemaakt
+programma dat \LaTeX-afleidingsbomen voor Smurfprogramma's kan genereren. Dit
+programma wordt in \autoref{sec:cleansmurf} toegelicht.
\autoref{sec:planning} bevat een planning voor het afwerken van het werkstuk,
die uiteindelijk verwijderd zal worden.
-
diff --git a/refs.tex b/refs.tex
index ae7da71..653cf2b 100644
--- a/refs.tex
+++ b/refs.tex
@@ -5,5 +5,8 @@
\bibitem{esolang:prog} Smurf --- Reversing input on Esolang,
\url{http://esolangs.org/wiki/Smurf#Reversing_input}. Opgehaald 27 mei 2016.
+
+ \bibitem{cleansmurf} \emph{CleanSmurf} --- Smurf interpreter in Clean,
+ \url{https://github.com/camilstaps/CleanSmurf}. Opgehaald 10 juni 2016.
\end{thebibliography}
diff --git a/werkstuk.tex b/werkstuk.tex
index 3822d51..b7a3e8f 100644
--- a/werkstuk.tex
+++ b/werkstuk.tex
@@ -20,6 +20,9 @@
\usepackage{syntax}
\usepackage{thmtools}
+\usepackage{clean}
+\lstset{language=Clean,breaklines,tabsize=2,xleftmargin=\parindent}
+
% Eigen packages
\usepackage{smurf}
@@ -50,6 +53,7 @@
\input{rules}
\input{sosexamp}
\input{analyse}
+\input{cleansmurf}
\input{planning}
\input{refs}