Programming language design and implementation has always been one of my greatest coding passions. For a time in my life, implementing small, unique programming languages was something I did on a weekly basis. I am now at the point in my life where, although I do not design languages with such frequency, I want to look over all that I've done, and chronicle all the languages I've made. Early on, I had a bad habit of not including any relevant code in the main/master branch, but everything in the gh-pages branch.
I've sorted them here chronologically. You can also click on the tags to filter by languages with them (eventually, when I get around to implementing that. Ctrl+F should work in the meantime.):
unimplemented esolang praclang golf
TODO: describe
TODO: describe
TODO: describe
Aka “dash”, not to be confused with the shell. Name apparently chosen by my Witty Younger Self, “Because GitHub won't allow the use of a space.” I suppose I would have named the language a single space were it not for technical limitations.
A language which conceptually could operate under 3 programming paradigms via specifying the command: O
for object-oriented programming, S
for stack-based programming, and T
for tape-based programming (à la Brainfuck). Almost 10 years ago, I'm not sure exactly what I had in mind for the language—beyond the specification of loop instructions, I don't have any information on this language.
TODO: describe
A short-lived experiment into a communally-designed programming language. The idea was that people could open GitHub issues with a feature request for a specific command in the language. I would then implement it and add it to the documentation. Even though one of the commands was also paradigm-switching like - did, it was actually another person's idea. The language is woefully underimplemented.
TODO: describe.
TODO: describe.
TODO: describe.
A basic prototype aiming to provide a more consice format for representing Desmos “programs”. The language is a glorified find-and-replace with some convenience functions.
TODO: describe.
TODO: describe.
TODO: describe
One of my first “proper” esolangs, NTFJ is a stack-based, Turing tarpit. It is roughly equivalent to Etre, which is Turing complete. Here is a truth machine, a program that outputs 0 if given a 0, and repeating 1s if given a 1, along with an explanation:
:*:##~~~~~#@|########@|($~^)
: pop top of stack and push twice
popping from an empty stack yields the input
stack: [48, 48] (for '0') or [49, 49] (for '1')
* output top of stack (truth machine outputs once)
: duplicate again
##~~~~~#@ push byte 0b11000001 (=193)
| bitwise NAND with input
for '0' (48):
00110000
AND 11000001 = 00000000
NOT = 11111111 = 255
for '1' (49):
00110001
AND 11000001 = 00000001
NOT = 11111110 = 254
stack: [48, 255] or [49, 254]
########@ push byte 0b11111111 (=255)
| bitwise NAND with the last value
for '0' (255), 255 NAND 255 = 0
for '1' (254):
11111110
AND 11111111 = 11111110
NOT = 00000001
( ) if top of stack is 1:
$ drop top of stack
stack: [49]
~ push 0
^ jump to that command in the program
My first attempt at a practical language (praclang), as well as infix interpretation. Pretty dysfunctional and buggy, but it works alright.
a <- 3; b = 5; disp a, b, a + b, a..b, a .+ "40", inv a; disp <> + a
will prompt the user for input (say, (x=>x*3)(40)
, as it foolishly evaluates the prompt), and output 3
5
8
3
4
5
43
0.3333333333333333
123
Yes, the semicolons are necessary; this language does not support lines terminated by newlines, only semicolons.
TODO: describe.
A strange language. Commands are series of consecutive parenthetical characters (one of (){}
), with optional []
characters in between. Each command has a corresponding “mode”, which is calculated by reading the command left-to-right, and keep track of a running accumulator which increases by 1 for each character, but [
will instead double and add 1, and ]
will double and subtract 1. Thus, )))
has a mode of 3, (](
has a mode of 4, and }}}}}[
has a mode of 9.
The language operates on two registers, termed LEFT and RIGHT. At all times, one is “focused” and the other is “unfocused”. The LEFT register is focused initially. Commands are executed based on the first character of the command.
(
increases the focused register by the command's mode.)
increases the unfocused register by command's mode.{
focuses on the LEFT register if the command's mode is even, otherwise focuses on the RIGHT register.}
breaks into one of 14 subcommands, depending on the exact value of the command's mode. With each description, I have included the shortest way to invoke this command.
}
sets the focused register to the Unicode value of the first byte in the prompt()
. This command didn't work in the original implementation since it failed to call prompt
.}}
sets the focused register to the numeric value of the prompt()
. This command didn't work in the original implementation since it failed to call prompt
, also it did the same thing as when the mode was 1.}]
appends the focused register as a character to the output buffer.}]}
appends the focused register as a number to the output buffer.}}]
skips the next command if the focused register is nonzero.}}]}
sets the instruction pointer to the value of the unfocused register.}]]
sets the instruction pointer to the value of the unfocused register if and only if the focused register is nonzero.}]]}
adds the unfocused register to the focused register.}}][
multiples the focused register by the unfocused register.}}][}
divides the focused register by the unfocused register.}}]]
subtracts the unfocused register from the focused register.}}]]}
increments the focused register.}]][
decrements the focused register.}]][}
outputs the output buffer and clears its contents. I added this command (6/29/2024) after changing the behavior of the output buffer commands to not output every time a character was appended.This language, as implemented, is not Turing complete, as it has finite memory cells (native JavaScript floating point numbers), and even if it used Bignums, it would not be reducible to, say, 3-cell brainfuck, due to only having 2 values, or really only 1 value if you use the unfocused register to simulate looping.
Here is a program that outputs Hello, World!
:
(]]]((]](}}}(]]][}}}(]]}}} }}}(]}}}{(][][](}}}{{}}]] }}]](][[}}}(]][]]}}}(][]](}}}(]}}}{(]]]]](}}}{{}}]](][]]][(}}}{}}]](]][[}}}
TODO: describe
TODO: describe
TODO: describe
TODO: describe
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe. Fork of Jelly.
An extended version of J. Basically just a preprocessor.
TODO: describe.
TODO: describe. Entry for the 2017 PPCG Time Capsule.
A simple infix language using shunt.js
. Entry for the 2017 PPCG Time Capsule.
TODO: describe.
TODO: describe.
TODO: describe. Successor to Chaîne.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe.
TODO: describe
A simple, functional language, similar to J, but woefully underimplemented. Try input 1,2,3,4
and code +/
. Only implements addition (+
), division (%
), reverse (~
), and insertion (/
). Exact date unknown since it is only a JSFiddle without a corresponding repository, or any frame of reference.
A simple, functional language, similar to J, but less woefully underimplemented. Seems to support more complex expressions, like (i.5) + 2 * i.5
. Once again, no confident date, as it is just a JSFiddle.