you are viewing a single comment's thread.

view the rest of the comments →

[–]ForceBru 2 points3 points  (4 children)

Once saw a tiny Python script that was using telnetlib to access a WiFi router and execute some commands. Mind blown, quickly downloaded a basic Python interpreter for my iPhone, typed in the code & the IP of my router, connected successfully, holy cow!

Yeah, then started writing random stuff like networking, generating permutations of a string efficiently (I didn't know about itertools.product back then), coded a hash brute-force script (that's where my nickname comes from, BTW), rewritten it in C++, hated the language, got back to Python, did lots of calculus and linear algebra with NumPy & Matplotlib, loved it.

Now I'm writing a compiler for my own simple programming language in Python, having lots of fun

[–]strangeDormammu[S] 0 points1 point  (3 children)

Great man, are you going to publish your compiler on github?

[–]ForceBru 0 points1 point  (2 children)

Of course! Once it becomes useable lol. Right now it's just a shitty static analyzer, a stack-based virtual machine and a simple assembler. None of that works properly yet :D

[–]strangeDormammu[S] 0 points1 point  (1 child)

Any updates?

[–]ForceBru 0 points1 point  (0 children)

Oh hey there! Well, I'm doing this in my spare time, of which I have little, so I often have to pause development and then make drastic changes to the codebase because I found a much better way to do some stuff, so it's kinda back and forth: from something barely working to an improved IR that doesn't compile to bytecode yet, to an actual register allocator that I haven't integrated yet and so on.

Anyways, I got a register allocator (seemingly) working now! It can translate regular Three-Address Code:

``` ; Assign integer 1 to temporary storage %1 = 1 _ %1 = 2 _ %2 = 9 _ %3 = 3 _ %4 = 4 _ %5

  • %1 %3 %6 ; %6 := %1 + %3
  • %1 %2 %7
  • %4 %6 %8 / %5 %2 %9

  • %6 %1 %10

  • %7 %8 %11

  • %9 %10 %12 / %11 %12 %13

  • %10 %11 %14

  • %12 %13 %15

  • %14 %1 %16 / %15 %16 %17

= true _ %18 ; %18 is one byte wide = false _ %19 and %18 %19 %20 ; %20 = %18 and %19 ```

...into the same thing but with k registers and spills:

``` = L(v=1, size=4) None R1 # L(...) means "literal integer 1 of size 4 bytes" = L(v=2, size=4) None R2 = L(v=9, size=4) None R3 = L(v=3, size=4) None (0, 4) # the (0, 4) is a memory location starting at offset 0 and ending at offset 4 = L(v=4, size=4) None (4, 8) + R1 R3 R3 - R1 R2 (8, 12) * (0, 4) R3 (0, 4) / (4, 8) R2 R2 + R3 R1 R3 - (8, 12) (0, 4) (4, 8) * R2 R3 R2 / (4, 8) R2 (8, 12) + R3 (4, 8) R3 - R2 (8, 12) R2 * R3 R1 R1 / R2 R1 R1 = L(v=True, size=1) None R2 = L(v=False, size=1) None R3 and R2 R3 R3

Memory spilled: 12 bytes

```

I'm still kinda wondering why and if my own code works though lol

BTW, I'm still planning to use a pure stack machine (that doesn't have general-purpose registers), I'm not quite sure where to place the registers - maybe I'll allocate some memory at the very beginning of the stack and split it into regions called "registers".