From b27dc19e5703db9cedd7280b77e9c4d0eefbc9b7 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 10 Oct 2019 18:00:13 -0700 Subject: [PATCH] Finish draft of part 6 of compiler series --- content/blog/06_compiler_semantics.md | 48 ++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/content/blog/06_compiler_semantics.md b/content/blog/06_compiler_semantics.md index c6f60de..a991796 100644 --- a/content/blog/06_compiler_semantics.md +++ b/content/blog/06_compiler_semantics.md @@ -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!