Switch more posts to work with KaTeX and the latex macro
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -17,9 +17,10 @@ compiles to the instructions \\(i\\)".
|
||||
|
||||
To follow our route from the typechecking, let's start
|
||||
with compiling expressions that are numbers. It's pretty easy:
|
||||
$$
|
||||
\\mathcal{C} ⟦n⟧ = [\\text{PushInt} \\; n]
|
||||
$$
|
||||
|
||||
{{< latex >}}
|
||||
\mathcal{C} ⟦n⟧ = [\text{PushInt} \; n]
|
||||
{{< /latex >}}
|
||||
|
||||
Here, we compiled a number expression to a list of
|
||||
instructions with only one element - PushInt.
|
||||
@@ -30,9 +31,9 @@ we informally stated in the previous chapter, since
|
||||
the thing we're applying has to be on top,
|
||||
we want to compile it last:
|
||||
|
||||
$$
|
||||
\\mathcal{C} ⟦e\_1 \\; e\_2⟧ = \\mathcal{C} ⟦e\_2⟧ ⧺ \\mathcal{C} ⟦e\_1⟧ ⧺ [\\text{MkApp}]
|
||||
$$
|
||||
{{< latex >}}
|
||||
\mathcal{C} ⟦e_1 \; e_2⟧ = \mathcal{C} ⟦e_2⟧ ⧺ \mathcal{C} ⟦e_1⟧ ⧺ [\text{MkApp}]
|
||||
{{< /latex >}}
|
||||
|
||||
Here, we used the \\(⧺\\) operator to represent the concatenation of two
|
||||
lists. Otherwise, this should be pretty intutive - we first run the instructions
|
||||
@@ -59,14 +60,15 @@ but their addresses are incremented by \\(n\\)". We now pass \\(\\rho\\)
|
||||
in to \\(\\mathcal{C}\\) together with the expression \\(e\\). Let's
|
||||
rewrite our first two rules. For numbers:
|
||||
|
||||
$$
|
||||
\\mathcal{C} ⟦n⟧ \\; \\rho = [\\text{PushInt} \\; n]
|
||||
$$
|
||||
{{< latex >}}
|
||||
\mathcal{C} ⟦n⟧ \; \rho = [\text{PushInt} \; n]
|
||||
{{< /latex >}}
|
||||
|
||||
For function application:
|
||||
$$
|
||||
\\mathcal{C} ⟦e\_1 \\; e\_2⟧ \\; \\rho = \\mathcal{C} ⟦e\_2⟧ \\; \\rho ⧺ \\mathcal{C} ⟦e\_1⟧ \\; \\rho^{+1} ⧺ [\\text{MkApp}]
|
||||
$$
|
||||
|
||||
{{< latex >}}
|
||||
\mathcal{C} ⟦e_1 \; e_2⟧ \; \rho = \mathcal{C} ⟦e_2⟧ \; \rho \; ⧺ \;\mathcal{C} ⟦e_1⟧ \; \rho^{+1} \; ⧺ \; [\text{MkApp}]
|
||||
{{< /latex >}}
|
||||
|
||||
Notice how in that last rule, we passed in \\(\\rho^{+1}\\) when compiling the function's expression. This is because
|
||||
the result of running the instructions for \\(e\_2\\) will have left on the stack the function's parameter. Whatever
|
||||
@@ -74,17 +76,18 @@ was at the top of the stack (and thus, had index 0), is now the second element f
|
||||
same is true for all other things that were on the stack. So, we increment the environment accordingly.
|
||||
|
||||
With the environment, the variable rule is simple:
|
||||
$$
|
||||
\\mathcal{C} ⟦x⟧ \\; \\rho = [\\text{Push} \\; (\\rho \\; x)]
|
||||
$$
|
||||
|
||||
{{< latex >}}
|
||||
\mathcal{C} ⟦x⟧ \; \rho = [\text{Push} \; (\rho \; x)]
|
||||
{{< /latex >}}
|
||||
|
||||
One more thing. If we run across a function name, we want to
|
||||
use PushGlobal rather than Push. Defining \\(f\\) to be a name
|
||||
of a global function, we capture this using the following rule:
|
||||
|
||||
$$
|
||||
\\mathcal{C} ⟦f⟧ \\; \\rho = [\\text{PushGlobal} \\; f]
|
||||
$$
|
||||
{{< latex >}}
|
||||
\mathcal{C} ⟦f⟧ \; \rho = [\text{PushGlobal} \; f]
|
||||
{{< /latex >}}
|
||||
|
||||
Now it's time for us to compile case expressions, but there's a bit of
|
||||
an issue - our case expressions branches don't map one-to-one with
|
||||
@@ -118,13 +121,13 @@ It's helpful to define compiling a single branch of a case expression
|
||||
separately. For a branch in the form \\(t \\; x\_1 \\; x\_2 \\; ... \\; x\_n \\rightarrow \text{body}\\),
|
||||
we define a compilation scheme \\(\\mathcal{A}\\) as follows:
|
||||
|
||||
$$
|
||||
\\begin{align}
|
||||
\\mathcal{A} ⟦t \\; x\_1 \\; ... \\; x\_n \\rightarrow \text{body}⟧ \\; \\rho & =
|
||||
t \\rightarrow [\\text{Split} \\; n] \\; ⧺ \\; \\mathcal{C}⟦\\text{body}⟧ \\; \\rho' \\; ⧺ \\; [\\text{Slide} \\; n] \\\\\\
|
||||
\text{where} \\; \\rho' &= \\rho^{+n}[x\_1 \\rightarrow 0, ..., x\_n \\rightarrow n - 1]
|
||||
\\end{align}
|
||||
$$
|
||||
{{< latex >}}
|
||||
\begin{aligned}
|
||||
\mathcal{A} ⟦t \; x_1 \; ... \; x_n \rightarrow \text{body}⟧ \; \rho & =
|
||||
t \rightarrow [\text{Split} \; n] \; ⧺ \; \mathcal{C}⟦\text{body}⟧ \; \rho' \; ⧺ \; [\text{Slide} \; n] \\
|
||||
\text{where} \; \rho' &= \rho^{+n}[x_1 \rightarrow 0, ..., x_n \rightarrow n - 1]
|
||||
\end{aligned}
|
||||
{{< /latex >}}
|
||||
|
||||
First, we run Split - the node on the top of the stack is a packed constructor,
|
||||
and we want access to its member variables, since they can be referenced by
|
||||
@@ -145,10 +148,10 @@ Next, we want to evaluate it (since we need a packed value, not a graph,
|
||||
to read the tag). Finally, we perform a jump depending on the tag. This
|
||||
is captured by the following rule:
|
||||
|
||||
$$
|
||||
\\mathcal{C} ⟦\\text{case} \\; e \\; \\text{of} \\; \\text{alt}_1 ... \\text{alt}_n⟧ \\; \\rho =
|
||||
\\mathcal{C} ⟦e⟧ \\; \\rho \\; ⧺ [\\text{Eval}, \\text{Jump} \\; [\\mathcal{A} ⟦\\text{alt}_1⟧ \; \\rho, ..., \\mathcal{A} ⟦\\text{alt}_n⟧ \; \\rho]]
|
||||
$$
|
||||
{{< latex >}}
|
||||
\mathcal{C} ⟦\text{case} \; e \; \text{of} \; \text{alt}_1 ... \text{alt}_n⟧ \; \rho =
|
||||
\mathcal{C} ⟦e⟧ \; \rho \; ⧺ [\text{Eval}, \text{Jump} \; [\mathcal{A} ⟦\text{alt}_1⟧ \; \rho, ..., \mathcal{A} ⟦\text{alt}_n⟧ \; \rho]]
|
||||
{{< /latex >}}
|
||||
|
||||
This works because \\(\\mathcal{A}\\) creates not only instructions,
|
||||
but also a tag mapping. We simply populate our Jump instruction such mappings
|
||||
|
||||
Reference in New Issue
Block a user