My Previous Programming Languages

Published Tuesday, June 12, 2018 · 2309 words, 12 minute read.

Welcome to the first edition of Language Design with Jadon! I’m a kid who wants to make another programming language. I mostly have zero clue what I’m doing, except for my extensive readings of type theory and the many langauges I’ve learned over the years. Let’s hope that’s enough!

First, some background. I’ve made a lot of languages over the last couple of years, greatly varying in quality. Of my (currently) 231 repositories on GitHub, here are some examples of languages I’ve made.

Toy languages

  • flow (November 2014) An insanely simple language that contained recursive expression parsing and an echo builtin. As my first language, it was a small toy project, but something that really got my feet off the ground. It was implemented in Python.

    in "Enter a number:" @i
    echo "I'm adding three to your number!"
    @a = 3 + @i
    echo @a
    echo "I'm multiplying it by two!"
    @a = 2 * @a
    echo @a
    echo "I'm subtracting it by four!"
    @a = 0 + @a - 4
    echo @a
    echo "I'm dividing it by two!"
    @a = 0 + @a / 2
    echo @a
    echo "I'm subtracting the original number!"
    @a = 0 + @a - @i
    echo "The Answer is always one!"
    echo @a
    
  • Voop (December 2014) “a Volatile Object Orientated Programming Language”, whatever that means. It looks like I only started the parser. It was implemented in Java.

  • fql (February 2015) “Flexible Query Language (A replacement to the boring SQL)”. Pretty terrible “translator” that replaced simple words. (Somehow these are getting worse.) It was implemented in Java.

    select all from table where column equals 1
    /* translates to */
    SELECT * FROM table WHERE column = 1;
    
  • cod (April 2015) Deadfish interpreter with extensions. It was my first project in C, and my first dive into esoteric languages (where I stayed for a while). Here are the commands in the language:

    Deadfish Commands:

    • i - Increment value by 1
    • d - Decrement value by 1
    • s - Square value
    • o - Output ASCII value

    cod Commands:

    • b - Binary Two’s Complement the value
    • q - Square root the value
    • r - Right shift value
    • l - Left shift value
    • & - Turn value into the value’s pointer
    • n - Print number
    • e - Erase the value
    • 4 - Decrement the value to zero, while printing each ASCII value along the way
    • 5 - Do the same as 4, except reset the value to it’s original number afterwards
    • 6 - Do the same as 4, except go upwards to the square of the value
  • fvm (May 2015) The Flower Virtual Machine is a register based bytecode VM that was originally implemented in C and was translated to D in October of 2015. Here’s an excerpt from the instruction set:

    Value Name Syntax Description
    0x0 loadi loadi <#> Loads byte into register
    0x1 loads loads Loads string into register
    0x2 loadf loadf Loads string as float into register
         
    0xa printc printc Prints register as character
    0xb printn printn Prints register as number
    0xc input input Load string from stdin into register
    0xd call call Call routine
    0xe routinestart routinestart Start routine named str
    0xf routineend routineend Ends routine
  • owk (June 2015) An esoteric language that compiled to fvm bytecode (okay this is actually pretty cool). It contained some basic language concepts like variables and functions, and included some… weird… syntax. It was implemented in Java.

    1='H';2='e';3='l';4='l';5='o';6=' '
    7='W';8='o';9='r';a='l';b='d'
    p1;p2;p3;p4;p5;p6;p7;p8;p9;pa;pb;
    
    #Adds the values of registers a & f and stores it in register e
    e < a+f
    #Multiplies the values of registers 2 & d and stores it in register f
    f< 2*d
    #Mods the values of registers 8 & 6 and stores it in register 1
    1 < 8 % 6
    #Transfers the value of register e into register f
    f < e
    
    #Negative c
    f < -c
    #NOT c
    e < !c
    #Two's complement c
    d < ~c
    
    square:λx.x*x
    add:λx.λy.x+y
    math:λx.λy.x*x+y*y;
    f=math(e,d)
    
  • lamb (June 2015) Very similar to owk, but it only provided functions. (It looks like it was made on the same day!) It compiles to JavaScript and had implementaions in Java and JavaScript.

    hello:Hello World
    power:λx.λy.Math.pow(x,y) 
    
  • refract (July 2015) “2D, stack-based, esoteric language based off ><>, GolfScript, Portal, and a bunch of other languages”. It contains a full wiki too! It was implemented in Java.

    “multiple stacks”

    123453[r2[r]]rnnnnn;
    

    “fibonacci”

    0:n84*o1:nv
    n:[email protected]@:o*48<
    

    “block hello world”

    {"hello world"r}h {o}phv
                       p;?m<
    

I have many other toy languages, but these are the more interesting ones. Now we can view some better languages I made.


Good(ish) languages

o (July 2015 - November 2016)

My first big language. The only esoteric language good enough to put on a resume. The original interpreter was written in Java and it was rewritten in obfuscated C in October of 2015 with massive help from Ryan Gonzalez. A Web IDE is available online and was written in Python & CoffeeScript. It was designed for CodeGolf, and it was great at it (until other languages came out that completely abused encoding tables).

“hello world”

"Hello, World! 

“factorial”

H,;]*

“fibonacci”

0J;1Kpj{K:VJ+:KpV:J;}d

“Count from 1 to n in Negabinary and Negaquaternary” (I don’t even..)

j){n.2_bo4_bo' o}d

lang-kotlin-antlr-compiler (August 2016 - June 2017)

I completely gave up on naming things, but this is one of the best compilers I’ve made. Written in Kotlin using ANTLR to generate the parser, the language targeted the LLVM. It supports global variables, functions, classes, methods, “automatic memory management”, type inference, FFI, modules, etc. It can be considered the “first version” of my language.

import std.io

@extern rand() : Int32 0

let initialAccountId = 7 + 11

class Account
    var id : Int32

    setId(i : Int32)
        id = i,
        id
;

incrementId(a : Account, amount : Int32)
    a.id = a.id + amount

main ()
    let account = new Account(),
    let i = account.setId(initialAccountId),
    printInt(i),
    incrementId(account, rand()),
    printInt(account.id),
    0
genComplexExpressionsInWhileLoop (a, z, y, x, w : Int32)
    var i = 0,
    var sum = 0,
    while i < a
        var v = 42 + x,
        let u = 45 * 7 - 16 + 11 + v * 67 + 124 - (w * 4) / 5,
        v = v * 2 - z,
        var t = 1,
        if z < 10
            t = v * z + 24 - 15 + y
        else
            t = v - 7 + 8 + 8 - z
        ;
        let l = 74 * 3 - v + z * x - w,
        i = 5 + u * z * v + t * 2 * l
    ;
    let r = sum * i,
    r
import std.io

fac (n)
    var r = 0,
    if n <=1
        r = 1
    else
        r = n * fac(n - 1)
    ;
    r

inc (a)
    a + 1

main ()
    var i = 1,
    while (i < 11)
        printInt(fac(i)),
        i = inc(i)
    ;
    0

This language quickly became too difficult to maintain because of poor design decisions of the internal structure made early on (no IR for example; doing AST resolution and generating LLVM IR in one pass is quite complex).

f2 (November 2016 - April 2017)

This time using an IR pass and a better AST, I created a language that had a focus on memory management, and how it can be handled better. It contains a Heap to Stack allocation algorithm which is actually pretty nice (imo). This is also going towards what my language will be.

struct X {
  a : Int32
}

struct Y {
  x : X
}

f :: X -> Int32
f x = x.a.

g :: Int32 -> X
g a = X{a}.

h :: Int32 -> Int32
h a = let x = X{a},
      x.a.

i :: Int32 -> Y
i a = Y{X{a}}.

j :: Int32 -> Int32
j a = let x = X{a},
      let y = Y{x},
      let w = y.x,
      w.a.
struct X {
  a : Int32
}

box :: Int32 -> X
box a = X{a}. -- memory is allocated here

f :: Int32 -> Int32
f i = let x = box(i),
      let a = firstThing(x),
      let b = secondThing(x),
      let c = thirdThing(x), -- memory is freed after this call
      a + b + c.

I quickly ran into problems with name resolution and modules, which I believe to have solved with my last blog post and in f3.

You may notice that all of these repositories are just pieces of languages. lang-kotlin-antlr-compiler was my first attempt at generating LLVM IR for an OOP language with Type Inference, f2 contains the language IR, and f3 contains the name resolution code. I’ll eventually merge everything into one language, but it’s good to have to algorithms and such written down and tested.

Whelp, this has been a rundown of my previous languages. Hopefully next time I come back with something worthwhile!