% vim: set spelllang=nl:
\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. De
semantiekregel voor dit syntaxelement zag er als volgt uit:
\therheadns

Aangezien \CI{pop} en \CI{head} allebei een \CI{Maybe} opleveren, kunnen we de
resultaten gemakkelijk monadisch \emph{bind}en. Vervolgens wordt de stack
geüpdatet 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$ en $\StmQuotify$ gaan op
soortgelijke wijze. De commando's $\StmPut$ en $\StmGet$ hebben als enige
verschil dat ze ook op de store werken. Ook $\StmInput$ en $\StmOutput$ kunnen
op eenzelfde manier worden geschreven, afgezien van het feit dat de IO-toestand
en -functies gebruikt moeten worden.

Alleen $\StmExec$ behoeft nadere toelichting. Bij dit syntaxelement 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.
