Finish draft of part 6 of compiler series

This commit is contained in:
Danila Fedorin 2019-10-10 18:00:13 -07:00
parent df0b819b0e
commit b27dc19e57

View File

@ -409,6 +409,11 @@ looks as follows for `definition_defn`:
{{< codelines "C++" "compiler/06/definition.cpp" 44 51 >}}
Notice that we terminate the function with Update. This
will turn the `ast_app` node that served as the "root"
of the application into an indirection to the value that we have computed.
In essense, this is how we can lazily evaluate expressions.
Finally, we make a function in our `main.cpp` file to compile
all the definitions:
@ -450,4 +455,45 @@ in that position, so `x` is pushed onto the stack.
Finally, `+` is pushed, and the application
`(+) x y` is created, which is equivalent to `x+y`.
{{< todo >}}Backport bugfix in case's typecheck{{< /todo >}}
Let's also take a look at a case expression program:
{{< rawblock "compiler/06/examples/works3.txt" >}}
The result of the compilation is as follows:
```
Push(0)
Eval()
Jump(
Split()
PushInt(0)
Slide(0)
Split()
Push(1)
PushGlobal(length)
MkApp()
PushInt(1)
PushGlobal(+)
MkApp()
MkApp()
Slide(2)
)
Update(1)
```
We push the first (and only) parameter onto the stack. We then make
sure it's evaluated, and perform case analysis: if the list
is `Nil`, we simply push the number 0 onto the stack. If it's
a concatenation of some `x` and another lists `xs`, we
push `xs` and `length` onto the stack, make the application
(`length xs`), push the 1, and finally apply `+` to the result.
This all makes sense!
With this, we've been able to compile our expressions and functions
into G-machine code. We're not done, however - our computers
aren't G-machines. We'll need to compile our G-machine code to
__machine code__ (we will use LLVM for this), implement the
__runtime__, and develop a __garbage collector__. We'll
tackle the first of these in the next post - see you there!