Pogo Devlog (15 Part Series)
1 Compiling Python to Go (Pogo Pt:1)
2 Creating a Target (Pogo Pt: 2)
… 11 more parts…
3 Defining the Tokens (Pogo Pt: 3)
4 Lexing the Source (Pogo Pt: 4)
5 Upgrading Tokens (Pogo Pt: 5)
6 Parsing Python (Pogo Pt: 6)
7 Creating Python’s AST (Pogo Pt:7)
8 Finally, Golang from Python (Pogo Pt:8)
9 Semantic Analysis (Pogo Pt:9)
10 Implementing Functions (Pogo Pt:10)
11 Line Numbers in Errors (Pogo Pt:11)
12 Validating Function Parameters (Pogo Pt:12)
13 Calling Functions (Pogo Pt:13)
14 Returning From Functions (Pogo Pt:14)
15 Compiler Cleanup (Pogo Pt:15)
Introduction
I have started a new project called Pogo, which will transpile Python code into Golang code. Since this is such an interesting topic I decided to track my development here, as following along with the process could be either entertaining or educational for everyone.
Why?
When starting a new project, a great question to ask is why? Sometimes the answer is as simple as doing it for the experience, and a project like this is perfect for experience.
Another reason I have is performance. Python can be notoriously slow due to its interpreted nature, however, by utilizing Go that effect can be mitigated. Since Go is a compiled language this should drastically improve performance.
Furthermore, being about to bounce your Python prototype into Go can be extremely useful for development. For example, say you want to have a startup, and you create a Python prototype. That prototype might be extremely fast to type up, however, it probably isn’t efficient, or useful in the long run. Therefore, by transpiling to Go this prototype is not wasted.
Lastly, is interoperability. This will not occur from this project, but may be a future sight, where Python code and Go code are easier to use together. This also allows you to write functions quickly in Python, then compile them to Go, which in some cases (not all) is a lot easier and simpler.
Why Golang?
This is an important question, as I could’ve chosen a language that doesn’t rely on a garbage collector. The first reason is I don’t know Rust. Secondly, Go is quite modern, making it a better option than the C family, closer to Python, and a more relevant option. Lastly, since I will be documenting my progress, a passionate individual would be able to recreate this process for any other language (within reason (or not)).
Typing
To start this project I had one issue, in Python, types are dynamic (but still exist), while Go has static typing. Luckily, in both languages, typing is important and isn’t completely thrown out the window.
To compile Python to Go, we need to draw some similarities between the languages, specifically in the typing system. Both Python and Go have the int
type, however, Go also has int8
, int16
, int32
, int64
, and the unsigned variants of these types. Furthermore, Python has str
, while Go has string
, which is a small difference, but should still be considered.
Type Annotations
A feature I didn’t like before comes in to save the day, Python’s type annotations. I didn’t like these annotations since this is valid code.
<span>x</span><span>:</span> <span>int</span> <span>=</span> <span>"</span><span>What even</span><span>"</span><span>x</span><span>:</span> <span>int</span> <span>=</span> <span>"</span><span>What even</span><span>"</span>x: int = "What even"
Enter fullscreen mode Exit fullscreen mode
So I never bothered, but in this case, this is the perfect way to assimilate Python into Go.
What if we want to make an int8
? We can’t, we only have int
in Python, so we need to add it. We can create a class in another file that we will import into Python, so that when we compile, Pogo knows that we are using an int8
not an int
.
<span>class</span> <span>int8</span><span>(</span><span>int</span><span>):</span><span>pass</span><span>class</span> <span>int8</span><span>(</span><span>int</span><span>):</span><span>pass</span>class int8(int):pass
Enter fullscreen mode Exit fullscreen mode
We don’t need anything in this class at the moment, we just need it to exist. Now we can import the types we have made and use them!
<span># The file we will use to hold all the types we make </span><span>from</span> <span>GoType</span> <span>import</span> <span>*</span><span>r</span><span>:</span> <span>int8</span> <span>=</span> <span>128</span><span>g</span><span>:</span> <span>int8</span> <span>=</span> <span>64</span><span>b</span><span>:</span> <span>int8</span> <span>=</span> <span>0</span><span># The file we will use to hold all the types we make </span><span>from</span> <span>GoType</span> <span>import</span> <span>*</span> <span>r</span><span>:</span> <span>int8</span> <span>=</span> <span>128</span> <span>g</span><span>:</span> <span>int8</span> <span>=</span> <span>64</span> <span>b</span><span>:</span> <span>int8</span> <span>=</span> <span>0</span># The file we will use to hold all the types we make from GoType import * r: int8 = 128 g: int8 = 64 b: int8 = 0
Enter fullscreen mode Exit fullscreen mode
Next
In the next post I will be looking at equivalence between Python code and Go code, so we know what to expect when we Pogo Python code. Properly defining our end point like we did with our start point today will greatly help us in creating a bridge between the two.
Pogo Devlog (15 Part Series)
1 Compiling Python to Go (Pogo Pt:1)
2 Creating a Target (Pogo Pt: 2)
… 11 more parts…
3 Defining the Tokens (Pogo Pt: 3)
4 Lexing the Source (Pogo Pt: 4)
5 Upgrading Tokens (Pogo Pt: 5)
6 Parsing Python (Pogo Pt: 6)
7 Creating Python’s AST (Pogo Pt:7)
8 Finally, Golang from Python (Pogo Pt:8)
9 Semantic Analysis (Pogo Pt:9)
10 Implementing Functions (Pogo Pt:10)
11 Line Numbers in Errors (Pogo Pt:11)
12 Validating Function Parameters (Pogo Pt:12)
13 Calling Functions (Pogo Pt:13)
14 Returning From Functions (Pogo Pt:14)
15 Compiler Cleanup (Pogo Pt:15)
暂无评论内容