{ "cells": [ { "cell_type": "markdown", "id": "26524732-e864-4158-a826-9e0772f14cac", "metadata": { "jp-MarkdownHeadingCollapsed": true }, "source": [ "## Motivation\n", "For many years, C++ used to be my favourite language for performance-critical applications. I find Python much more convenient for many use cases, but I have always enjoyed employing zero-cost abstractions and writing generic code that can be compiled to optimal assembly.\n", "\n", "However, C++ has a number of downsides, such as\n", "* problems that arise from [undefined bahaviour](https://en.cppreference.com/w/c/language/behavior) in the code,[1](#fn:undefined-behavior)\n", "* all the baggage it carries due to its backwards compatibility with almost all C++ code and much of the C code that has ever been written.\n", "A consequence is that C++ is more cumbersome and error-prone to use than more modern languages, and that developers are less productive than they could be.\n", "\n", "Rust tries to address these issues and enable excellent performance at the same time, so I decided that I should give it a try a few years ago. I started playing around with it for [Advent of Code](https://adventofcode.com/) problems, enjoyed it a lot, and wondered what practice project I could try next.\n", "\n", "\n", "\n", "A non-trivial practive project for any programming language is to implement an interpreter. [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) is the simplest language that I can think of, so a Brainfuck interpreter is what I implemented some time ago. Recently, I've improved it a bit and decided to write down the steps that I took.\n", "\n", "Readers who have some experience with Rust will find this post easier to follow, but it does not assume any prior Rust knowledge. It does not aim to explain every concept in great detail though. If you want to know more, you can find a good introduction in [*The Rust Programming Language*](https://doc.rust-lang.org/book/)." ] }, { "cell_type": "markdown", "id": "de08b6aa-8cc8-43f9-9974-a9e740397c3d", "metadata": {}, "source": [ "## Brainfuck\n", "You can read a lot about Brainfuck in its [Wikipedia article](https://en.wikipedia.org/wiki/Brainfuck). Its most important aspects are:\n", "* Brainfuck code operates on memory which is organized as a one-dimensional array of byte cells. I like to call it *tape* because it resembles the tape of a [Turing machine](https://en.wikipedia.org/wiki/Turing_machine).\n", "\n", " Besides the tape itself, there is a *data pointer* which points to the current cell.\n", " \n", "* There are eight instructions, which are represented by a single character each.\n", "\n", "
instruction | \n", "effect | \n", "
---|---|
- | \n", "decrement the byte inside the current cell by one | \n", "
+ | \n", "increment the byte inside the current cell by one | \n", "
< | \n", "decrement the data pointer by one, such that it points one cell further to the left | \n", "
> | \n", "increment the data pointer by one, such that it points one cell further to the right | \n", "
. | \n", "output the byte in the current cell to standard output | \n", "
, | \n", "read a byte from standard input and store it in the current cell | \n", "
[ | \n", "loop start: if the byte in the current cell is zero, jump to the instruction after the matching ']' instruction, otherwise, go to the next instruction | \n", "
] | \n", "loop end: if the byte in the current cell is non-zero, jump to the instruction after the matching '[' instruction, otherwise, go to the next instruction | \n", "