QtBrain

What?

This project is a result of me taking the excellent Mobile Linux Development with Qt at the Haaga-Helia University of Applied Sciences (the course itself was actually Symbio's handiwork.) During the intensive 5 day course many people criticized C++ for being too complicated and difficult to use. It has somewhere around 80 keywords and operators and the syntax is, undeniably, a bit hairy. So, logically, if a language with many keywords and a complicated syntax is seen as difficult to use, a language with less keywords and smaller syntax has to be easier. Right? So how does a Turing-complete programming language that only has eight (8) commands and a very simple syntax sound? This is how the idea of making an IDE got born in the first place.

You can find all downloadable material (source, mainly) at the end of the page in the Attachments section. This project is also on GitHub.

The software is strictly alpha quality, and is licensed under a slightly modified 2-clause BSD license.

And at this point I'm going to have to take some time to apologize profusely for swearing on this page, but I can't really help it since the language in question is called...

Brainfuck

The ultimate minimalist language, originally designed by Urban Müller in 1993. Brainfuck (BF for short) has 8 commands (detailed below), an instruction pointer (IP) and a data pointer (DP). The commands are executed sequentially (except when jumping, of course) and when the IP moves past the last command the program terminates. The DP points to a memory consisting of 65 536 signed 1-byte cells.

Here's a list of the commands:

What could be easier? Only 8 commands, and the only syntax you have to remember is to balance your square brackets! Brainfuck just has to be easy.

Examples

To prove how easy Brainfuck is, I'll give you a few example programs (some of these are from the Wikipedia article).

Clear cell

[-]

What could be easier than that? It just continuously decrements whatever the DP points to until it's set to 0.

Clear previous cells

[ [-]< ]

This clears a cell and moves the DP back until it encounters a 0 cell. Easy as pie.

Echo

,[.,]

Simply echoes whatever the user types. Don't tell me that's not simpler than any language you know.

Copy value of memory cell 0 to cell 1

>[-]>[-]<<[->+>+<<]>>[-<<+>>]<<

Wow, that's only like 31 characters.

Hello World!

++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

"Hello world" in a 111 measly characters.

QtBrain

Even though you clearly don't need an IDE for a language as simple as this, I decided to come up with one anyhow. How about a screenshot? Everybody loves screenshots!

Using the IDE

The IDE is very simple at the moment, but it does have a couple of very nifty features. Everything that's not a Brainfuck command (ie. one of + - < > [ ] , . and QtBrain's special % which I'll talk about later) is simply ignored, so you can comment your code quite easily. Undo/Redo is supported with the standard Ctrl-Z / Shift-Ctrl-Z (no menu item yet), and you can save and open Brainfuck programs through the File menu.

Syntax highlighting

The IDE has simplistic syntax highlighting of [ ] blocks (shown in different green shades for different levels of embedding). If you have an extra ] hanging around, it and everything after it will conveniently be highlighted in red so you can spot and ERADICATE your little mistake. No-one needs to find out. Ever.

"Compiling" the program

Instead of a run-of-the-mill interpreter, QtBrain has a somewhat convoluted system of running Brainfuck code: the code is translated to a simple instruction set, "Brainfuck Bytecode" if you will and then fed to a virtual machine (ok, it's an interpreter, but humor me). The original purpose was to make a program that "compiles" Brainfuck into this bytecode and an Arduino program which interprets this bytecode (mainly because I can fit a standard Brainfuck instruction into 3 bits instead of the 8+ that characters normally use).

So, to actually run your program you have to load it into the VM first, which is done by poking at the Load button on the toolbar, or the Load menu item in the VM menu.

If you forgot to balance your braces, the compiler will complain loudly and you'll get an informative dialog:

Conveniently enough, you don't have to go hunting around for position 472 yourself since the editor moves the cursor to where the compiler thinks the problem lies and the syntax highlighter will show you the error of your ways.

Running Brainfuck programs

So you've gotten your program to compile and now you're ready to embrace madness and actually run it. Here's what the Execution tab of QtBrain looks like:

All in all, it's pretty simple. Things start out it debugging mode, which means that you'll be able to see the instruction pointer moving around your code and you have a snapshot of 9 cells of memory near the data pointer. If you click on Run, the VM will start stepping through your program one instruction at a time. You can change the delay between steps with the Run tick delay slider. Note that setting the delay to 0 and leaving debugging mode will suck up some serious CPU cycles currently due to QLabel::setText().

Poking Step will cause the VM to go into single-step mode, so you'll have to press Step every time you want to execute the next command.

Reset will reset the state of the VM by clearing the memory and setting IP and DP to 0. The program will stay loaded, however.

Pressing Clear in the VM menu will also clear the program.

Input

Inputting data to the VM is done with the Input buffer text field. When there's nothing in the buffer and the VM needs input, the field will turn a nice red color:

When you want to provide input, just type as many characters as you want and then press Enter to send the text to the VM.

Breakpoints

You can set breakpoints by putting % characters in your code. Breakpoints make the VM drop out of run mode and stop in its tracks. The GUI will automatically switch to debugging mode when a breakpoint is encountered:

How QtBrain works

It has 3 major components: the GUI (duh), the VM and the compiler. Both the VM and the compiler have their own threads, and the GUI communicates with them using Qt's signals and slots mechanism. The GUI code is, quite frankly, an unholy mess at the moment (whatever you do, don't look at the syntax highlighter), but the compiler and VM are at least moderately readable.

The VM is basically a state machine (something state diagram-ish is included in the download), and state transitions are done by either sending the VM a signal or by some internal event subclassed from QEvent. For example pressing, say, Run in the GUI will send a toggleRunSig signal to the VM, and when the VM's input buffer is empty an InputBufferEmpty event is posted. Using Qt's excellent state machine framework made designing the VM a whole lot easier, since all I have to do to control the VM is to send it signals and the state transitions handle all the internal logic like not letting the user get away from the empty input buffer state without actually inputting something.

There are some redundancies in the VM and compiler code, mostly because of time constraints and changing my plans three times per day.

Feel free to experiment and look at the source if you feel like losing your mind.