The Project

In this project, I am going to create various virtual computers from scratch and build programming languages, data structures, and algorithms on top of them.

The Goal

I want to learn about how computers and programming languages work. I think an interesting way to do this will be to build it all from scratch. At the end of the project, I will have a variety of working languages, including a lot of machinery that we don’t often have to think about with modern tools.

Limitations

I am imposing some limitations that I think will make this experience more informative, unique, and interesting. These are:

The Tools

I am going to start out using a tool called Digital to build and simulate the circuitry. While I think a physical circuit would be neat, I want to be able to preserve a history of the circuit in a useable and shareable form.

Screenshot of
Digital

Outside of Digital, I am allowed to use a text editor to write notes so that they can be shared and kept in version control along side the computer.

Past Experience

I have some idea of how a computer physically functions. In college, I was exposed to some basic hardware architecture, worked with x86 assembly, and wrote code in C, including things like a memory allocator. I have a good understanding of the stack, and the basics of how it works in hardware. I also know that there are decades of development in this space, and that there are many complexities that I don’ understand at all, and many I don’t even know about.

In college, I created a very basic simulated computer that could execute a small instruction set. I had friends that were in a class and I was interested from the moment I heard about it. That project had similarities to this in that I didn’t have very much information and just followed my intuition, and that made it exciting.

Since then, I have tinkered with little virtual computers, but nothing with the ambitions of this project, and without the focus on software. I will take some learnings from those experiments into this project, and try to avoid some the problems I have faced in the past.

Points of Interest

There are various topics that I know about that I look forward to learning more about. I have included some of them below, and a bit of what I know (or think I know) about them.

ABIs

Application Binary Interfaces, the lower level sibling of APIs. I have heard of them, and my general understanding is that they are an agreement about how hardware like registers and the stack will be used, in particular with regards to function calling. I don’t even know all of the concepts that are covered by an ABI, and this is certainly one of the concepts that I want to do actual research on later, comparing my solution that what exists today and through history.

Bootstrapping

My understanding of bootstrapping is that you can use a tool, in this case I am thinking about a compiler, to create itself. Each version that you create will be slightly more powerful than the last, thanks to the fact that more power allows you to build a more complicated tool.

In the case of this project, I am expecting to start by hand-converting assembly like instructions into my machine instructions. Using that, I will build a program that can convert assembly instructions into machine instructions. At each level, I will be able to improve the language by building its compiler in itself until I can build an even more complicated language, at which point the process repeats.

Data Structures and Algorithms

I took a data structures and algorithms course in college. It was fun, and I truly enjoyed learning about and creating them. This project is going to allow me to go through that process again, because I will have to create all of them that I use from scratch. This is one of those things that could be fundamentally different if I used modern tools. While I likely would want to implement them at some point, I would have them from the get go in a modern language, which would allow me to solve problems significantly easier than if I am limited to my simulation.

Multiple Architectures

Over the course of the project, I would like to experiment with different ways to build the hardware. Right now, this mainly revolves around instructions, like how complicated an individual instruction is, how instructions are represented, or how immediate data is handled.

Having multiple architectures will also let me experiment with making higher level languages that compile to various instruction sets. Maybe I will even be able to look at creating some kind of JVM like tool that allows one program to execute on multiple computers without being compiled for each, or creating an intermediate language that allows more complex languages to be compiled to various architectures easily.