Compare commits
3 Commits
85bd0b6c9c
...
035b98a602
Author | SHA1 | Date | |
---|---|---|---|
035b98a602 | |||
17f4ebc297 | |||
906e15674e |
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
title: Daniel's Blog
|
||||
description: Daniel Fedorin's personal blog, covering topics such as functional programming, compiler development, and more!
|
||||
---
|
||||
## Hello!
|
||||
Welcome to my blog. Here, I write about various subjects, including (but not limited to)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
title: Compiling a Functional Language Using C++, Part 0 - Intro
|
||||
date: 2019-08-03T01:02:30-07:00
|
||||
tags: ["C and C++", "Functional Languages", "Compilers"]
|
||||
description: "In this first post of a larger series, we embark on a journey of developing a compiler for a lazily evaluated functional language."
|
||||
---
|
||||
During my last academic term, I was enrolled in a compilers course.
|
||||
We had a final project - develop a compiler for a basic Python subset,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
title: Compiling a Functional Language Using C++, Part 1 - Tokenizing
|
||||
date: 2019-08-03T01:02:30-07:00
|
||||
tags: ["C and C++", "Functional Languages", "Compilers"]
|
||||
description: "In this post, we tackle the first component of our compiler: tokenizing."
|
||||
---
|
||||
It makes sense to build a compiler bit by bit, following the stages we outlined in
|
||||
the first post of the series. This is because these stages are essentially a pipeline,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
title: Compiling a Functional Language Using C++, Part 2 - Parsing
|
||||
date: 2019-08-03T01:02:30-07:00
|
||||
tags: ["C and C++", "Functional Languages", "Compilers"]
|
||||
description: "In this post, we combine our compiler's tokenizer with a parser, allowing us to extract structure from input source code."
|
||||
---
|
||||
In the previous post, we covered tokenizing. We learned how to convert an input string into logical segments, and even wrote up a tokenizer to do it according to the rules of our language. Now, it's time to make sense of the tokens, and parse our language.
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
title: Compiling a Functional Language Using C++, Part 3 - Type Checking
|
||||
date: 2019-08-06T14:26:38-07:00
|
||||
tags: ["C and C++", "Functional Languages", "Compilers"]
|
||||
description: "In this post, we allow our compiler to throw away invalid programs, detected using a monomorphic typechecking algorithm."
|
||||
---
|
||||
I think tokenizing and parsing are boring. The thing is, looking at syntax
|
||||
is a pretty shallow measure of how interesting a language is. It's like
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
title: Compiling a Functional Language Using C++, Part 4 - Small Improvements
|
||||
date: 2019-08-06T14:26:38-07:00
|
||||
tags: ["C and C++", "Functional Languages", "Compilers"]
|
||||
description: "In this post, we take a little break from pushing our compiler forward to make some improvements to the code we've written so far."
|
||||
---
|
||||
We've done quite a big push in the previous post. We defined
|
||||
type rules for our language, implemented unification,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
title: Compiling a Functional Language Using C++, Part 5 - Execution
|
||||
date: 2019-08-06T14:26:38-07:00
|
||||
tags: ["C and C++", "Functional Languages", "Compilers"]
|
||||
description: "In this post, we define the rules for a G-machine, the abstract machine that we will target with our compiler."
|
||||
---
|
||||
{{< gmachine_css >}}
|
||||
We now have trees representing valid programs in our language,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
title: Compiling a Functional Language Using C++, Part 6 - Compilation
|
||||
date: 2019-08-06T14:26:38-07:00
|
||||
tags: ["C and C++", "Functional Languages", "Compilers"]
|
||||
description: "In this post, we enable our compiler to convert programs written in our functional language to G-machine instructions."
|
||||
---
|
||||
In the previous post, we defined a machine for graph reduction,
|
||||
called a G-machine. However, this machine is still not particularly
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
title: Compiling a Functional Language Using C++, Part 7 - Runtime
|
||||
date: 2019-08-06T14:26:38-07:00
|
||||
tags: ["C and C++", "Functional Languages", "Compilers"]
|
||||
description: "In this post, we implement the supporting code that will be shared between all executables our compiler will create."
|
||||
---
|
||||
Wikipedia has the following definition for a __runtime__:
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
title: Compiling a Functional Language Using C++, Part 8 - LLVM
|
||||
date: 2019-10-30T22:16:22-07:00
|
||||
tags: ["C and C++", "Functional Languages", "Compilers"]
|
||||
description: "In this post, we enable our compiler to convert G-machine instructions to LLVM IR, which finally allows us to generate working executables."
|
||||
---
|
||||
|
||||
We don't want a compiler that can only generate code for a single
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
title: Compiling a Functional Language Using C++, Part 9 - Garbage Collection
|
||||
date: 2020-02-10T19:22:41-08:00
|
||||
tags: ["C and C++", "Functional Languages", "Compilers"]
|
||||
description: "In this post, we implement a garbage collector that frees memory no longer used by the executables our compiler creates."
|
||||
---
|
||||
|
||||
> "When will you learn? When will you learn that __your actions have consequences?__"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
title: Compiling a Functional Language Using C++, Part 10 - Polymorphism
|
||||
date: 2020-03-25T17:14:20-07:00
|
||||
tags: ["C and C++", "Functional Languages", "Compilers"]
|
||||
description: "In this post, we extend our compiler's typechecking algorithm to implement the Hindley-Milner type system, allowing for polymorphic functions."
|
||||
---
|
||||
|
||||
[In part 8]({{< relref "08_compiler_llvm.md" >}}), we wrote some pretty interesting programs in our little language.
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
title: Compiling a Functional Language Using C++, Part 11 - Polymorphic Data Types
|
||||
date: 2020-04-14T19:05:42-07:00
|
||||
tags: ["C and C++", "Functional Languages", "Compilers"]
|
||||
description: "In this post, we enable our compiler to understand polymorphic data types."
|
||||
---
|
||||
[In part 10]({{< relref "10_compiler_polymorphism.md" >}}), we managed to get our
|
||||
compiler to accept functions that were polymorphically typed. However, a piece
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
title: Compiling a Functional Language Using C++, Part 12 - Let/In and Lambdas
|
||||
date: 2020-04-20T20:15:16-07:00
|
||||
tags: ["C and C++", "Functional Languages", "Compilers"]
|
||||
description: "In this post, we extend our language with let/in expressions and lambda functions."
|
||||
draft: true
|
||||
---
|
||||
|
||||
|
@ -91,15 +92,18 @@ addSingle6 x = 6 + x
|
|||
|
||||
-- ... and so on ...
|
||||
```
|
||||
|
||||
But now, we end up creating several functions with almost identical bodies, with the exception of the free variables themselves. Wouldn't it be better to perform the well-known strategy of reducing code duplication by factoring out parameters, and leaving only instance of the repeated code? We would end up with:
|
||||
|
||||
```Haskell {linenos=table}
|
||||
addToAll n xs = map (addSingle n) xs
|
||||
addSingle n x = n + x
|
||||
```
|
||||
|
||||
Observe that we no longer have the "infinite" number of functions - the infinitude of possible behaviors is created via currying. Also note that `addSingle`
|
||||
{{< sidenote "right" "global-note" "is now declared at the global scope," >}}
|
||||
Wait a moment, didn't we just talk about nested polymorphic definitions, and how they change our typechecking model? If we transform our program into a bunch of global definitions, we don't need to make adjustments to our typechecking. <br><br>
|
||||
This is true, but why should we perform transformations on a malformed program? Typechecking before pulling functions to the global scope will help us save the work, and breaking down one dependency-searching problem (which is \(O(n^3)\) thanks to Warshall's) into smaller, independent problems may even lead to better performance. Furthermore, typechecking before program transformations will help us come up with more helpful error messages.
|
||||
{{< /sidenote >}} and can be transformed into a sequence of instructions just like any other global function. It has been pulled from its `where` (which, by the way, is pretty much equivalent to a `let/in`) to the top level.
|
||||
|
||||
This technique of replacing captured variables with arguments, and pulling closures into the global scope to aid compilation, is called [Lambda Lifting](https://en.wikipedia.org/wiki/Lambda_lifting). Its name is no coincidence - lambda functions need to undergo the same kind of transformation as our nested definitions (unlike nested definitions, though, lambda functions need to be named). This is why they are included in this post together with `let/in`!
|
||||
This technique of replacing captured variables with arguments, and pulling closures into the global scope to aid compilation, is called [Lambda Lifting](https://en.wikipedia.org/wiki/Lambda_lifting). Its name is no coincidence - lambda functions need to undergo the same kind of transformation as our nested definitions (unlike nested definitions, though, lambda functions need to be named). This is why they are included in this post together with `let/in`!
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="theme-color" content="#1dc868" />
|
||||
<meta name="theme-color" content="#1dc868">
|
||||
{{ if .Description }}
|
||||
<meta name="description" content="{{ .Description }}">
|
||||
{{ end }}
|
||||
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inconsolata&family=Raleway&family=Lora&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata&family=Raleway&family=Lora&display=swap" media="screen">
|
||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css" media="screen">
|
||||
{{ $style := resources.Get "scss/style.scss" | resources.ToCSS | resources.Minify }}
|
||||
{{ $sidenotes := resources.Get "scss/sidenotes.scss" | resources.ToCSS | resources.Minify }}
|
||||
{{ $icon := resources.Get "img/favicon.png" }}
|
||||
{{- partial "sidenotes.html" . -}}
|
||||
<link rel="stylesheet" href="{{ $style.Permalink }}">
|
||||
<link rel="stylesheet" href="{{ $sidenotes.Permalink }}">
|
||||
<link rel="stylesheet" href="{{ $style.Permalink }}" media="screen">
|
||||
<link rel="stylesheet" href="{{ $sidenotes.Permalink }}" media="screen">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq" crossorigin="anonymous" media="screen">
|
||||
<link rel="icon" type="image/png" href="{{ $icon.Permalink }}">
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq" crossorigin="anonymous">
|
||||
|
||||
<title>{{ .Title }}</title>
|
||||
</head>
|
||||
|
|
Loading…
Reference in New Issue
Block a user