Skip to main content

A command line tool written in Python

Project description

███████╗ ██████╗  ██████╗ 
██╔════╝██╔════╝ ██╔════╝ 
█████╗  ██║  ███╗██║  ███╗
██╔══╝  ██║   ██║██║   ██║
███████╗╚██████╔╝╚██████╔╝
╚══════╝ ╚═════╝  ╚═════╝ 

A programming language I am building from scratch — to understand how programming languages actually work.

Install  ·  Quick Start  ·  Architecture  ·  Testing  ·  Docs  ·  Contributing


📖 About

EggLang is a small programming language I am building from scratch. I didn't use any existing interpreter, framework, or language toolkit. Every part of it — from reading the code to running it — I built myself.

I made this project so I could really learn how programming languages work, not just use them.

What I learned to build

  • How to break code into tokens (lexing)
  • How to turn tokens into structure (parsing)
  • How to build an AST (a tree that stores the code's logic)
  • How to run that tree (runtime)
  • How to manage variables and scope (environments)

Why I made this

I'm not trying to make EggLang production-ready. I just wanted to build a real language, step by step, and understand every part of it myself.


🚀 Installation

I published EggLang on PyPI, so you can install it with:

pip install egglang

⚡ Quick Start

Once it's installed, you can run any EggLang file like this:

egg run file.egg

No setup, no config file. Just point it at a .egg file and it runs.


💡 Why I Made This

I built EggLang to learn, by actually doing it:

🧩 How a programming language is designed
🔄 How source code turns into something the computer can run
⚙️ How an interpreter works on the inside
🗂️ How variables and memory are stored and managed
🔁 How functions, loops, and expressions actually run

This project is my journey from just using programming languages to understanding and building one myself.


🏗 How EggLang Works (Architecture)

I built EggLang as a simple pipeline. Each step passes its work to the next one:

┌───────────────┐
│  Source Code  │
└───────┬───────┘
        ▼
┌───────────────┐
│     Lexer     │   breaks code into tokens
└───────┬───────┘
        ▼
┌───────────────┐
│    Parser     │   turns tokens into structure
└───────┬───────┘
        ▼
┌───────────────┐
│      AST      │   a tree that stores the code's logic
└───────┬───────┘
        ▼
┌───────────────┐
│  Interpreter  │   walks the tree and runs it
└───────┬───────┘
        ▼
┌───────────────┐
│    Runtime    │   keeps track of values while running
└───────────────┘
Stage What it does
Lexer Turns raw code into tokens
Parser Turns tokens into a structured form
AST Stores the program's logic as a tree
Interpreter Runs the AST, one node at a time
Runtime Keeps track of values while the program runs

🧠 How I Built the Interpreter

I have a class called Interpreter, and inside it, every type of AST node has its own method that knows how to run that specific piece of code. So a loop node knows how to run loops, a function-call node knows how to run function calls, and so on.

  • ✅ Running expressions
  • ✅ Running statements
  • ✅ Calling functions
  • ✅ Handling return values
  • ✅ Running loops
  • ✅ Managing variables
  • ✅ Handling runtime errors
  • ✅ Looking up variables in nested scopes

🔗 How Scope Works

I built EggLang's scope system using environments that are chained together. Each environment stores:

  • Variables
  • Functions
  • A link to its parent environment

Because of this chain, I get global variables, function-local variables, nested scopes, and the ability to look up a variable through parent environments.

Global Environment
        │
        ▼
Function Environment
        │
        ▼
Nested Block Environment

When the code asks for a variable, EggLang looks in the current environment first. If it's not there, it moves up to the parent environment, and keeps going until it finds it.


🔧 How Functions Work

When a function is called, I create a brand new environment just for that call. The arguments get stored as variables inside this new environment. Then I run every line inside the function using that environment. Once the function returns a value, I throw away that environment, so it's ready to be used again next time.


⚠️ How I Handle Errors

I built a custom error system so debugging is easier. Whenever something goes wrong, I show:

  • 🏷️ What kind of error it is
  • 📝 A clear error message
  • 📍 Where it happened, including the exact line

🧪 Testing

I have a Tests/ folder with a bunch of tests I wrote to check that everything actually works. They cover:

  • Variables
  • Functions
  • for loops
  • while loops

The hardest test I made combines everything together — 20 programs that use multiple features at once, and all of them run correctly.

Some of my tests are extreme on purpose. I wanted to push the interpreter as hard as I could, to make sure the lexer, parser, AST, and interpreter can all handle it.


📚 Documentation

I wrote a few docs if you want to go deeper:

Document What's inside
📘 Syntax Guide How to write EggLang code
🧬 Language Features Everything EggLang can do
🏛 Architecture Details How I designed it internally
🥚 Code Examples Real EggLang programs you can read and run

📱 I Built This on My Phone

I made EggLang using only an Android phone. No laptop, no desktop, no external keyboard.

My setup

  • 📝 Acode — my code editor
  • 🐧 Alpine Linux — my terminal environment
  • ⌨️ The on-screen phone keyboard
  • 📴 No computer involved, at all

The numbers

  • Around 1,500 lines of code
  • Every line — lexer, parser, AST, interpreter, runtime — typed by hand on my phone
  • Every bug, I found and fixed on a small screen

If you've ever complained about coding on a small laptop screen, try building a language on a phone. I think EggLang proves that the only thing you really need is patience.


🌱 What I Learned

Building EggLang taught me a lot about:

compilers and interpreters · recursion · data structures · tree traversal · runtime design · software architecture

Before EggLang, I tried building another language, but that one was more of an experiment: egg v1.

After I learned more, I rebuilt EggLang from scratch with a proper design — my own lexer, parser, AST, interpreter, and runtime.

The hardest part for me was building the Parser and the AST. Designing a tree structure that correctly represents code was something I had never done before, and I had to learn a lot of new concepts to get it right.


🗺 What's Next

Things I want to add in the future:

  • A standard library
  • A module system
  • Better debugging tools
  • More advanced data structures
  • Performance improvements

🤝 Contributing

Right now, EggLang needs a CLI editor, and I'd love help building it.

I've set aside a Shell/ folder just for this, so you can work there without touching the core interpreter.

Feel free to explore EggLang, try it out, and send improvements my way. 🚀



✍️ About Me

I'm Adib, and I built EggLang to really understand how programming languages work — not just use them.


** Thanks for checking out EggLang**

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

egglang-0.2.0.tar.gz (22.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

egglang-0.2.0-py3-none-any.whl (24.8 kB view details)

Uploaded Python 3

File details

Details for the file egglang-0.2.0.tar.gz.

File metadata

  • Download URL: egglang-0.2.0.tar.gz
  • Upload date:
  • Size: 22.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for egglang-0.2.0.tar.gz
Algorithm Hash digest
SHA256 f6041b658ad020791860823f4ebcbe9f3da9e98af8fb22fe654a0c5f7faba22e
MD5 9b728e7ad5eb84772868a0ad242bd9b7
BLAKE2b-256 4257e51e808f593b3cf6196df76989c5b03a5a0f7dbd30bed085159fde417279

See more details on using hashes here.

File details

Details for the file egglang-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: egglang-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 24.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for egglang-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2780c6fe1f72b137a6045047d2b47f35d5089600ae2b10d3d5dbd787a7e210ee
MD5 c54e8e802543589f8cb9b6d1d46c3b08
BLAKE2b-256 9f2b0b281dc79146ccb4fcf4cb40ae8d40a5a6bf4097da3e83e9b62b59982ccc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page