Finish draft of part 6 of compiler series
This commit is contained in:
parent
df0b819b0e
commit
b27dc19e57
|
@ -409,6 +409,11 @@ looks as follows for `definition_defn`:
|
||||||
|
|
||||||
{{< codelines "C++" "compiler/06/definition.cpp" 44 51 >}}
|
{{< 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
|
Finally, we make a function in our `main.cpp` file to compile
|
||||||
all the definitions:
|
all the definitions:
|
||||||
|
|
||||||
|
@ -450,4 +455,45 @@ in that position, so `x` is pushed onto the stack.
|
||||||
Finally, `+` is pushed, and the application
|
Finally, `+` is pushed, and the application
|
||||||
`(+) x y` is created, which is equivalent to `x+y`.
|
`(+) 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!
|
||||||
|
|
Loading…
Reference in New Issue
Block a user