tl - the birth of a riscv64-first toy language
12-07-2026One 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++.