ArbAsm

ArbAsm is my first language project that got to a usable state.
It is an assembly-styled scripting language for arbitrary precision integer arithmetic, written in C. 'Arbitrary precision' means that the numbers in ArbAsm can have any amount of digits (as long as memory permits).

The interpreter is a single (portable) executable, which can either run a REPL, or run ArbAsm source files directly. Source files are simple text files, with the .aasm extension. Its GitHub page has a description of installation and usage, a lot of sample programs, and even a relatively extensive wiki page.
Here's some ArbAsm code that does a simple benchmark:

set ir, 0              ; `ir` is the general purpose iteration register
set endian, 1          ; This sets the endianness of the interpreter to big endian
set gr1, 30 000 000    ; This is the amount of loops the program will do

push time              ; Saving the value from the time register to the stack
:speedloop             ; A label
    inc ir
    cmp ir, gr1
    Cs jmp "speedloop" ; Does a jump to `speedloop`, if the previous comparison yielded a "smaller than" result

print ir               ; Prints the amount of iterations that were done

sub $0, time           ; Subtracts the current time from the value on top of the stack,
mul $0, 1-             ; which was the time at the start of the loop

trunc $0               ; Removes leading zeroes
print $0               ; Prints the amount of time it took to run in seconds

It originally started as a command line calculator tool, but it ended up growing into a scripting language, wayy outside what it was intended for, so it's very clunky (and too slow) to use for actual programming.

That being said, here are some things I have done with it (most of these can be found in the aformentioned scripts directory):

It also has some quaternion stuff, but for that to really be useful, it needed square roots, for which I couldn't figure out a performant and neat method at the time.

Short language description

The underlying machine model is as following:
There are a couple of general purpose registers that the user has full control over, and a couple of registers that are either read-only, or that have side effects over the operation of the interpreter.
Next to this, there are two stacks: one that you can directly push, pop and index into, and another one that you can use as a sort of 'shunting yard' for the main stack.
There is only one type, the Number (which is a dynamic array of bytes), that can be used as a arbitrary precision integer, a string, or simply as an array of bytes.

Statements have the form of an instruction followed by its arguments, with the destination operand going first (Intel argument ordering).

Broader Context of the project

Arbitrary precision math is a pretty well researched topic (to the point where there are FFT version of multiplication algorithms), but for this project, I hadn't read up on any of that. It's all manual exploration with a noteback and some late nights. Most of my arithmetic operators here have terrible computational complexity, and since it's some of my first C code, it's hard to read and makes a lot of odd decisions. Nevertheless, I'm still proud with how far I was able to go with how limited it all is.