docs -> doc
lol
This commit is contained in:
104
doc/build/html/_sources/commentary/gm.rst.txt
vendored
Normal file
104
doc/build/html/_sources/commentary/gm.rst.txt
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
The *G-Machine*
|
||||
===============
|
||||
|
||||
**********
|
||||
Motivation
|
||||
**********
|
||||
|
||||
Our initial model, the *Template Instantiator* (TI) was a very
|
||||
straightforward solution to compilation, but its core design has a major
|
||||
Achilles' heel, being that Compilation is interleaved with evaluation -- The
|
||||
heap nodes for supercombinators hold uninstantiated expressions, i.e. raw ASTs
|
||||
straight from the parser. When a supercombinator is found on the stack during
|
||||
evaluation, the template expression is instantiated (compiled) on the spot.
|
||||
|
||||
.. math::
|
||||
\transrule
|
||||
{ a_0 : a_1 : \ldots : a_n : s
|
||||
& d
|
||||
& h
|
||||
\begin{bmatrix}
|
||||
a_0 : \mathtt{NSupercomb} \; [x_1,\ldots,x_n] \; e
|
||||
\end{bmatrix}
|
||||
& g
|
||||
}
|
||||
{ a_n : s
|
||||
& d
|
||||
& h'
|
||||
& g
|
||||
\\
|
||||
& \SetCell[c=3]{c}
|
||||
\text{where } h' = \mathtt{instantiateU} \; e \; a_n \; h \; g
|
||||
}
|
||||
|
||||
The process of instantiating a supercombinator goes something like this
|
||||
|
||||
1. Augment the environment with bindings to the arguments.
|
||||
|
||||
2. Using the local augmented environment, instantiate the supercombinator body
|
||||
on the heap.
|
||||
|
||||
3. Remove the nodes applying the supercombinator to its arguments from the
|
||||
stack.
|
||||
|
||||
4. Push the address to the newly instantiated body onto the stack.
|
||||
|
||||
.. literalinclude:: /../../src/TI.hs
|
||||
:dedent:
|
||||
:start-after: -- >> [ref/scStep]
|
||||
:end-before: -- << [ref/scStep]
|
||||
:caption: src/TI.hs
|
||||
|
||||
Instantiating the supercombinator's body in this way is the root of our
|
||||
Achilles' heel. Traversing a tree structure is a very non-linear task unfit for
|
||||
an assembly target. The goal of our new G-Machine is to compile a *linear
|
||||
sequence of instructions* which instantiate the expression at execution.
|
||||
|
||||
**************************
|
||||
Trees and Vines, in Theory
|
||||
**************************
|
||||
|
||||
WIP.
|
||||
|
||||
**************************
|
||||
Evaluation: Slurping Vines
|
||||
**************************
|
||||
|
||||
WIP.
|
||||
|
||||
Laziness
|
||||
--------
|
||||
|
||||
WIP.
|
||||
|
||||
* Instead of :code:`Slide (n+1); Unwind`, do :code:`Update n; Pop n; Unwind`
|
||||
|
||||
****************************
|
||||
Compilation: Squashing Trees
|
||||
****************************
|
||||
|
||||
WIP.
|
||||
|
||||
Notice that we do not keep a (local) environment at run-time. The environment
|
||||
only exists at compile-time to map local names to stack indices. When compiling
|
||||
a supercombinator, the arguments are enumerated from zero (the top of the
|
||||
stack), and passed to :code:`compileR` as an environment.
|
||||
|
||||
.. literalinclude:: /../../src/GM.hs
|
||||
:dedent:
|
||||
:start-after: -- >> [ref/compileSc]
|
||||
:end-before: -- << [ref/compileSc]
|
||||
:caption: src/GM.hs
|
||||
|
||||
Of course, variables being indexed relative to the top of the stack means that
|
||||
they will become inaccurate the moment we push or pop the stack a single time.
|
||||
The way around this is quite simple: simply offset the stack when w
|
||||
|
||||
.. literalinclude:: /../../src/GM.hs
|
||||
:dedent:
|
||||
:start-after: -- >> [ref/compileC]
|
||||
:end-before: -- << [ref/compileC]
|
||||
:caption: src/GM.hs
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user