DEV Community

Cover image for I made my own Programming Language
Lex
Lex

Posted on

I made my own Programming Language

I'm a Python developer through and through. I love the ecosystem, the community, the whole deal. But my hands... my hands have muscle memory. They want to type curly braces {}. They miss for (let i = 0; ...) loops.

So, like any reasonable developer, I decided to fix this minor personal annoyance by doing something completely unreasonable: I built my own programming language.

Meet Glorp.

It's my weird little passion project. It's a statically-typed, curly-brace language that doesn't try to take over the world. Instead, it does one thing: it transpiles your code into clean, modern Python. The idea was simple: get a syntax that feels like a comfy mix of C/JavaScript, but keep the entire, massive power of the Python runtime.

Let me show you what it looks like.

GitHub logo LecSUSOff / glorp

Glorp programming languange

Glorp 🦉

A simple, statically-typed language with built-in reactivity.

License: MIT PRs Welcome

Glorp combines the safety of static types with a clean, modern syntax. Its killer feature is the watch keyword, allowing you to build reactive, event-driven applications with zero boilerplate.

For better experience, join our Discord community

Also, read the Documentation


Core Features

  • Simple & Clean Syntax: Write readable code, free from clutter.
  • 🔒 Static Typing: Catch errors before you run, not after.
  • Built-in Reactivity: Use watch to create code that magically responds to data changes.

🚀 Getting Started

Get up and running in less than a minute.

1. Download

Grab the latest glorp executable from the Releases page.

2. Install

Place the downloaded file in a directory and add it to your system's PATH. This allows you to run glorp from anywhere.

3. Verify

Open a new terminal and check that it's working:

glorp --version
Enter fullscreen mode Exit fullscreen mode

Hello, Glorp!

Let's…




So What's the Vibe?

I basically just cherry-picked features I personally like and glued them together.

First, the basics. You declare variables with let, and you have to give them a type (Int, Str, Bool, etc.). This has saved me from dumb mistakes more times than I can count.

// This just feels right to me.
let Int my_age = 30
let Str name = "Alex"
let List numbers = [1, 2, 3]
Enter fullscreen mode Exit fullscreen mode

Functions can be written the classic C-style way with braces, or you can use a short arrow syntax for one-liners. Every function gets automatically wrapped with typeguard at runtime, because I believe in types but I'm also lazy and like when the computer checks them for me.

// A full function
fn Str greet(Str name) {
  => "Hello, " + name + "!"
}

// A quick one-liner
fn Int add(Int a, Int b) => a + b

// Like in many compiled languages, the program starts in Main()
fn Null Main() {
    out(greet("World"))
    out(add(5, 10))
}
Enter fullscreen mode Exit fullscreen mode

The control flow is probably the biggest reason I started this. No more elif or counting spaces. Just good old-fashioned if/else, while, and a for loop that makes sense to my C-wired brain.

// This just feels less cluttered to me.
for let Int i = 0 to 10 {
  out(i)
}
Enter fullscreen mode Exit fullscreen mode

The "Aha!" Moment: Reactive watch

This is the feature where I really started having fun. I wanted to play with some basic reactive ideas. The watch keyword lets you attach a block of code to a variable that runs only when its value changes.

// Set up a watcher on 'counter'
watch Int counter = 0 -> {
  out("The counter changed! It's now: " + counter)
}

counter = 1 // prints "The counter changed! It's now: 1"
counter = 2 // prints "The counter changed! It's now: 2"
counter = 2 // ...crickets. The value is the same, so the code doesn't run.
Enter fullscreen mode Exit fullscreen mode

Under the hood, this is a fun little hack using a Python wrapper class with a custom setter. When you assign a new value, the setter intercepts it, compares it to the old value, and calls your handler function if they're different. Simple, but surprisingly useful for quick UI updates or logging.

How the Sausage is Made

There's no dark magic here. It's just two brilliant Python libraries doing all the heavy lifting:

  1. Lark: This thing is a beast. You write a grammar file that defines the "shape" of your language (e.g., "a function starts with fn, then a type, then a name..."). Lark takes your .glorp file and chews it up into a structured tree.
  2. Transformer: Then, I walk that tree. For every piece of the grammar, like an if_stmnt, I have a Python method that takes the bits and pieces (the condition, the body) and just spits out the equivalent Python code as a string: f"if {condition}:\n {body}".

I stitch all those strings together, and a final nerdy touch: I use Python's linecache module to fake the filename. This means if your Glorp code crashes, the Python traceback points you to the correct line in your .glorp source file, not the generated mess.

Sharing Code with glorppkg

Once I had something working, I realized it'd be fun to share code. So I hacked together glorppkg, a super simple command-line tool to upload and download modules from a central server (which is just a tiny Flask app running on a free tier).

You can upload your masterpiece:
glorppkg upload my_awesome_lib

And your friends can download it:
glorppkg get my_awesome_lib

So, Wanna Play?

Look, Glorp isn't going to replace Python. It's not the next big thing. It's a personal project born from a love of programming and a specific taste in syntax. It was an incredible learning experience, and it's just plain fun to use.

If any of this sounds interesting to you, I'd be thrilled for you to check it out.

Thanks for letting me share my weird little project with you. I can't wait to see if anyone else builds something cool (or silly) with it.

Top comments (0)