1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
% vim: set spelllang=nl:
\subsection{\texttt{Exec}}
\label{sec:rules:exec}
\begin{quote}
x - Executes the string at the top of the stack as a Smurf program. The stack
and variable store are erased.
\end{quote}
We halen een string van de stack en gebruiken $\parsepgmop$ om dit in een
programma om te zetten. Dit wordt het nieuwe programma om uitgevoerd te worden.
Als de $\stk$ leeg is is deze regel niet toepasbaar, omdat $\pop\stk$ dan niet
gedefinieerd is. Ook is deze regel niet toepasbaar als de gepopte string zelf
geen geldig Smurf-programma is, omdat $\parsepgmop$ dan niet gedefinieerd is.
$$
\begin{prooftree}
\trans
{\pgm'}{\ip}{(\Nil, \emptystore)}
{\ip'}{\op}{\st}
\justifies
\trans
{\StmExec:\pgm}{\ip}{(\stk,\str)}
{\ip'}{\op}{\st}
\using{\rexecns}
\qquad
\text{met\enspace
\parbox{36mm}{$(\var,\stk') = \pop{\stk}$,\\
$\pgm' = \parsepgm{\var'}$.}
}
\end{prooftree}
$$
\medskip
$\parsepgmop$ definiƫren we als volgt, met een hulpfunctie $\parsestrop$:
$$
\parsepgm s =
\begin{cases}
\lambda & \text{als $s=\lambda$}\\
\parsepgm{s'} & \text{als $s=c~s'$ met $c$ whitespace}\\
\parsestr{s'} & \text{als $s=\texttt{"}~s'$} \\
\StmCat:\parsepgm{s'} & \text{als $s=\texttt{+}~s'$} \\
\StmHead:\parsepgm{s'} & \text{als $s=\texttt{h}~s'$} \\
\StmTail:\parsepgm{s'} & \text{als $s=\texttt{t}~s'$} \\
\StmQuotify:\parsepgm{s'} & \text{als $s=\texttt{q}~s'$} \\
\StmPut:\parsepgm{s'} & \text{als $s=\texttt{p}~s'$} \\
\StmGet:\parsepgm{s'} & \text{als $s=\texttt{g}~s'$} \\
\StmInput:\parsepgm{s'} & \text{als $s=\texttt{i}~s'$} \\
\StmOutput:\parsepgm{s'} & \text{als $s=\texttt{o}~s'$} \\
\StmExec:\parsepgm{s'} & \text{als $s=\texttt{x}~s'$} \\
\end{cases}
$$
Het tweede geval van $\parsepgmop$ zorgt ervoor dat een programma-string
bijvoorbeeld spaties mag bevatten, die syntactisch zelf geen betekenis hebben.
Dit is in overeenkomst met de specificatie, maar op zich niet nodig.
$$
\parsestr s =
\begin{cases}
\lambda:\parsepgm{s'} & \text{als $s=\texttt{"}~s'$} \\
\unescape{c}~\parsestr{s'} & \text{als $s=\texttt{\textbackslash}~c~s'$
met $c \in\Char$} \\
c~\parsestr{s'} & \text{als $s=c~s'$ met $c
\in\Char\setminus\{\texttt{"},\texttt{\textbackslash}\}$}\\
\end{cases}
$$
Het tweede geval van $\parsestrop$ zorgt ervoor dat ge-escapete
aanhalingstekens de string niet beƫindigen.
Hierbij gebruiken we $\unescapeop$ om bepaalde karakters te unescapen:
$$
\unescape c =
\begin{cases}
\text{het LF-karakter} & \text{als $c=\texttt{n}$} \\
\texttt{"} & \text{als $c=\texttt{"}$} \\
\texttt{\textbackslash} & \text{als $c=\texttt{\textbackslash}$} \\
\texttt{\textbackslash~$c$} & \text{anderszins}
\end{cases}
$$
Het laatste alternatief geeft aan dat `ongeldige escape sequences' worden
behandeld alsof de backslash er twee keer stond. Dit is in overeenstemming met
het commentaar op de specificatie en met de Perl interpreter: %todo referentie
\begin{quote}
This [the specification] does not specify the behaviour of invalid escape
sequences. The Perl interpreter treats invalid escape sequences as if the
backslash had occured twice - that is, \textbackslash X is treated as
\textbackslash\textbackslash X. For maximum compatibility, Smurf programs
should not rely on this behaviour and should always ensure valid escape
sequences are used.
\end{quote}
|