tl - the birth of a riscv64-first toy language

12-07-2026
#programming#language development

One day I was bored, and as a bored programmer might do - I started browsing my Github recommendations, and I stumbled upon a simple toy language which doesn’t use any backends like LLVM or QBE (notable examples).

So I decided to try writing my own. Hence why it is named tl, short for toy language.

It’s written in C++, trying to conform to modern C++ practices, and using C++26, and even if it is in it’s earliest stages, I’ve created a working frontend. A hand-rolled lexer and parser.

In it’s current form, it can lex the simplest of programs, such program looks like:

//
// toy language
//

func double_and_add_one(x: i32) -> i32 {
    return x + 1 * 2;
}

func main(argc: i32) -> i32 {
    println("Hello, world!");

    return 0;
}

And its parsed tree:

Function double_and_add_one
  Parameter x
  Return
    BinaryExpression +
      IdentifierExpression x
      BinaryExpression *
        NumberExpression 1
        NumberExpression 2
Function main
  Parameter argc
  CallExpression
    IdentifierExpression println
    StringExpression Hello, world!
  Return
    NumberExpression 0

I didn’t mention anything about the lexer because it isn’t that notable, but for the AST I have decided to use an std::variant AST, of which for the tree printing demonstrated above I used std::visit.

The coolest part of this little endeavour was the fact that I used ranges and views, of which the only memorable usage is inside the tree visitor, used for joining strings with newlines. Definitely overkill, and I might change it to a simple for-loop, but it was fun to explore a more functional side of C++.