Week 6: On Finding New Approaches
April 13, 2023
In the blog post for Week 4 I spoke on the difference between “rule-based”, and AI based translation of programming languages, especially within the context of my own project. These past two weeks I started working on this rule-based BrainF to Piet translation program.
At first, I did most of this manually, meaning the program would also output a png Piet image on its own. But soon after I discovered a Piet assembler and compiler hosted on this website https://www.toothycat.net/wiki/wiki.pl?MoonShadow/Piet. With the assembler, I could pass in a text file of Piet instructions, and have it output a valid Piet image, saving myself from a lot of work. Another appealing feature was its ability to control “tracks,” where each track was a segment of Piet code, and these tracks could be jumped between. This was appealing because of BrainF’s implementation of loops, which I believed could be mapped onto the assembler’s concept of tracks. Because of these features, I scrapped the work I had on the direct BrainF-to-Piet converter, and started working on a program that would convert from BrainF to a text file containing these instructions for the assembler, and then into Piet.
I worked on this for a bit, before running into issues when thinking how I’d implement the BrainF loops. As a recap, the only loop operations in BrainF come from these two characters, [ and ]. If the interpreter encounters “[” and the cell currently being pointed to has a non-zero value, then the following code up to the corresponding “]” is executed. If the cell has a zero value, the segment is skipped over, otherwise it repeats until the cell is 0. Using this as a general loop can be frustrating in practice, but it is extensible enough to cover many cases. While working on the program, I assumed that the assembler would be able to jump from one track to any other track in the output Piet. Under this assumption I started working on a system where most of the BrainF code would be translated to Piet in a straight line of pixels, but on encountering “[” the program would tell the assembler to jump to a new track, where the code inside the loop would execute. Since BrainF can have nested loops, the assembler would also have to jump from track to track, and then backtrack until it gets to the main line of code. Originally I assumed the assembler was capable of doing this, but upon encountering some errors and looking further into the documentation, I realized that the track system is more limited than I originally thought. The “main” line of code I spoke about can be called track 1. According to the documentation track 1 can jump to any other track in the image, and any track can jump back to track 1, but tracks can’t jump directly from one to another without first going through track 1. So track 2 can’t jump to track 3. This threw a wrench into my plans for implementing loops.
Because of this, I decided to again shift, but into using the compiler listed on the website. The compiler is even more extensive, and its input is a “C-like high level language,” meaning if-statements, and loops are built right in, simplifying the process even more. The compiler takes in this high-level language, and spits out code that the assembler can understand, and the assembler can then output a functioning Piet image. After creating a new program to work with the compiler, I ran into another issue, but one that was outside my expectations.
Both the Piet assembler and compiler are written in a language called Perl, which is a standard scripting language. Most of the original work I did in setting this up was on a Mac Laptop, which has Perl built in. I didn’t have any issues with this Perl interpreter, and the compiler and assembler ended up working correctly for a sample fizzbuzz program found here https://www.toothycat.net/~sham/fizzbuzz.script. This created the image below:
Upon testing this with npiet, the Piet interpreter, I got the results expected from this program. Later in the day I tried setting up the same thing on my primary environment, which is a Windows computer. Perl isn’t packaged natively with Windows, so I had to install another implementation. Upon running the compiler and assembler on the same fizzbuzz script, this output was produced: (scaled up in reference to the previous image)
Clearly this is significantly smaller than the previous output, and the colors are all messed up. There are a few parts where there should be vertical white lines, but instead these are blue and red lines. Something is going wrong, but the only explanation I can think of is that there is some built-in Perl graphics library used to create these images by the assembler, and its functioning differently on macOS and Windows systems. To fix this, it seems like I’d have to dig within the Perl interpreter, and the Piet assembler to see what is going wrong. But since these cogs still work in the other environment it seems its better to just treat this as an annoyance and not something I should spend time fixing.
Because of this issue, and even the previous circumstance of significantly switching around my plans for the rule-based BrainF to Piet translation, I’ve realized a trend in the way I feel about these approaches. It seems that once I started working on the translator, I felt confident that it would be easy to complete, but over time I started doubting this judgement more. This then led to taking another approach, which I assumed would be significantly easier. But over time I realize that this would be only slightly less difficult. This process has repeated, and might repeat again, until I settle on an approach I feel comfortable with.