What happens when you stop using programming languages and decide to build one?
That was the question that led me to start NexPro β an experimental programming language that I'm building from scratch to understand how programming languages actually work internally.
π GitHub: https://github.com/probal2005/NexPro
NexPro is still in its early stages, but it already has the foundations of a real language implementation: lexical analysis, parsing, an AST, interpretation, runtime components, a CLI, and tests.
This article explains why I started NexPro, how the architecture works, what the syntax looks like, and where I want to take the project next.
π§ Why Build Another Programming Language?
There are already hundreds of programming languages.
So why build another one?
For me, the goal wasn't to replace Python, JavaScript, Rust, or any existing language.
The goal was to understand what actually happens between this:
say "Hello NexPro!"
and the computer executing it.
When we write code, we usually think:
Source Code β Output
But internally, there is a lot more happening.
A simplified language implementation looks more like:
Source Code
β
βΌ
Lexer
β
βΌ
Tokens
β
βΌ
Parser
β
βΌ
AST
β
βΌ
Interpreter
β
βΌ
Runtime
β
βΌ
Output
I wanted to build every major part myself.
That's how NexPro started.
π What Is NexPro?
NexPro is an experimental programming language designed around simple and readable syntax.
The project currently lives on GitHub:
π https://github.com/probal2005/NexPro
The language uses the .pa extension for source files.
For example:
name = "Probal"
city = "Kolkata"
say name
say city
The idea is intentionally simple:
code β easy to read β easy to understand β easy to execute
NexPro isn't trying to compete with established languages yet.
Right now, it is a learning project, language-design experiment, and open-source project that I want to grow over time.
ποΈ NexPro Architecture
One of the most interesting parts of this project is understanding how the individual components communicate.
The current architecture can be represented like this:
βββββββββββββββββββββββ
β NexPro Source β
β (.pa) β
ββββββββββββ¬βββββββββββ
β
βΌ
βββββββββββββββββββββββ
β Lexer β
β Source β Tokens β
ββββββββββββ¬βββββββββββ
β
βΌ
βββββββββββββββββββββββ
β Parser β
β Tokens β Structure β
ββββββββββββ¬βββββββββββ
β
βΌ
βββββββββββββββββββββββ
β AST β
β Program Structure β
ββββββββββββ¬βββββββββββ
β
βΌ
βββββββββββββββββββββββ
β Interpreter β
β Execute the AST β
ββββββββββββ¬βββββββββββ
β
βΌ
βββββββββββββββββββββββ
β Runtime β
β Values & Execution β
ββββββββββββ¬βββββββββββ
β
βΌ
βββββββββββββββββββββββ
β Output β
βββββββββββββββββββββββ
Each component has a specific responsibility.
π 1. The Lexer
The first step is lexical analysis.
The lexer reads the raw source code and converts it into tokens.
For example:
say "Hello NexPro!"
can conceptually become:
SAY
STRING("Hello NexPro!")
EOF
For a variable assignment:
name = "Probal"
the lexer needs to recognize things such as:
IDENTIFIER(name)
ASSIGN(=)
STRING("Probal")
This is the first major transformation:
Characters
β
Tokens
The lexer doesn't need to understand the complete meaning of the program.
Its job is to identify the building blocks.
π³ 2. The Parser
Once the lexer produces tokens, the parser takes over.
The parser answers a different question:
"How are these tokens structured?"
For example:
name = "Probal"
is not just three independent pieces.
It represents an assignment.
Conceptually, the parser can construct something similar to:
Assignment
βββ Variable: name
βββ Value
βββ String: "Probal"
This structured representation becomes part of the Abstract Syntax Tree, or AST.
π² 3. The AST
The AST is one of the most important concepts in a programming language.
Instead of executing raw text directly, NexPro represents the program as structured nodes.
For example:
say 10 + 20
could conceptually become:
Say
β
Binary
/ \
10 20
The advantage is that the interpreter doesn't need to repeatedly analyze the original source text.
It works with a structured representation of the program.
βοΈ 4. The Interpreter
After the AST has been created, the interpreter walks through it and executes the nodes.
For example:
name = "Probal"
say name
The interpreter can conceptually perform:
1. Create variable "name"
2. Store "Probal"
3. Find variable "name"
4. Retrieve its value
5. Send the value to output
So the overall process becomes:
Source
β
Lexer
β
Tokens
β
Parser
β
AST
β
Interpreter
β
Runtime
β
Output
This pipeline is the heart of NexPro.
π§ͺ A Small NexPro Program
Here's a simple example:
name = "Probal"
city = "Kolkata"
say name
say city
The expected output is:
Probal
Kolkata
The important thing isn't the complexity of this program.
The important thing is everything happening underneath it.
β Expressions
NexPro is also moving toward expression evaluation.
For example:
a = 10
b = 20
say a + b
Conceptually, the parser can represent the expression as:
+
/ \
a b
The interpreter then resolves:
a β 10
b β 20
10 + 20 β 30
and produces:
30
This is where a programming language starts becoming more interesting.
π» Running NexPro
The project is designed around a CLI.
A NexPro program can be executed with:
nexpro run examples/hello.pa
For example:
say "Hello NexPro!"
produces:
Hello NexPro!
The CLI acts as the interface between the developer and the language implementation.
Instead of manually calling the lexer, parser, and interpreter, the developer simply runs a NexPro program.
π Project Structure
The repository is organized around the language implementation itself.
The current project structure includes:
NexPro/
β
βββ nexpro/
β βββ __init__.py
β βββ cli.py
β βββ lexer.py
β βββ parser.py
β βββ interpreter.py
β βββ runtime.py
β βββ tokens.py
β βββ ast.py
β βββ errors.py
β βββ __version__.py
β
βββ examples/
β βββ hello.pa
β βββ variables.pa
β
βββ tests/
β
βββ README.md
βββ LICENSE
βββ pyproject.toml
The GitHub repository currently exposes the main examples, nexpro, and tests directories alongside the project configuration and documentation.
The implementation itself is written in Python.
That choice was deliberate.
Python lets me focus on language implementation concepts without spending most of my time dealing with low-level memory management.
π§© Why Python?
A natural question is:
"If you're creating a programming language, why implement it in Python?"
Because the current goal is learning and experimentation.
Python gives me useful building blocks:
- Easy string manipulation
- Dictionaries for environments
- Classes for AST nodes
- Exceptions for error handling
- Simple testing
- Fast iteration
For an early interpreter, this makes development much faster.
Later, I may explore implementing parts of NexPro in another language for performance.
π‘οΈ Error Handling
A programming language isn't complete if it only handles valid programs.
It also needs to explain invalid programs.
For example:
name =
shouldn't simply crash with an obscure Python traceback.
Eventually, NexPro should provide language-level errors such as:
NexPro Syntax Error
Line 1:
name =
Expected a value after '='.
Good error messages are a major part of good developer experience.
Improving NexPro's error system is therefore an important part of the roadmap.
π§ͺ Testing the Language
Programming languages are particularly sensitive to regressions.
A small lexer change can break parsing.
A parser change can break the interpreter.
An AST change can affect multiple features.
That's why NexPro includes a test suite.
The goal is to test individual components such as:
Source Code
β
βΌ
Lexer
β
βββ Token tests
β
βΌ
Parser
β
βββ AST tests
β
βΌ
Interpreter
β
βββ Execution tests
As the language grows, I want the test suite to grow with it.
πΊοΈ NexPro Roadmap
NexPro is still early.
There is a lot left to build.
My current roadmap looks roughly like this:
NexPro
β
ββββββββββββββββΌβββββββββββββββ
β β β
βΌ βΌ βΌ
Language Tooling Runtime
β β β
ββ if/else ββ REPL ββ Types
ββ loops ββ Formatter ββ Collections
ββ functions ββ VS Code ββ Modules
ββ arrays ββ Debugger ββ Standard Library
ββ objects
Near-term goals
if / else- Loops
- Functions
- More operators
- Arrays / collections
- Better error messages
- More comprehensive tests
- Improved runtime
Medium-term goals
- REPL
- Modules
- Standard library
- File operations
- Better CLI tooling
- Formatter
- Documentation
- VS Code syntax highlighting
Long-term goals
I'd like to explore:
- A more powerful type system
- Package management
- Faster execution
- Bytecode or compilation
- Debugging tools
- Language server support
- Cross-platform distribution
- A proper developer ecosystem
Some of these are deliberately ambitious.
The roadmap will evolve as the language evolves.
π¬ What I'm Learning From Building NexPro
Building a programming language has changed how I think about programming.
Before starting NexPro, concepts like:
Lexer
Parser
AST
Interpreter
Runtime
could feel abstract.
Now they feel much more concrete.
When I write:
say "Hello"
I can think about the entire journey:
"say"
β
Token
β
Parser
β
SayNode
β
Interpreter
β
Runtime
β
Hello
That mental model is probably the most valuable thing I've gained from this project.
π§ NexPro Is Not Finished
I want to be very clear about this.
NexPro is not a production-ready programming language.
It's an evolving project.
There will be:
- Bugs
- Design changes
- Breaking changes
- Missing features
- Experiments that don't work
- Architectural decisions that will probably need to be revisited
And that's okay.
That's part of building a language from scratch.
π€ I Want Developer Feedback
This project is now at the point where feedback from other developers could be extremely valuable.
If you are interested in:
- Programming languages
- Compilers
- Interpreters
- Lexers
- Parsers
- ASTs
- Language design
- Python
- Developer tooling
- Open source
I'd love to hear your thoughts.
Especially:
What would you change about the language design?
Which feature should I build next?
Does the architecture make sense?
What am I overlooking?
Would you be interested in contributing?
β Contribute to NexPro
If you'd like to experiment with it, check out the repository:
π GitHub: https://github.com/probal2005/NexPro
You can:
β Star the project
π Open an issue
π‘ Suggest a feature
π§ Submit a pull request
π§ͺ Experiment with the language
π Improve the documentation
Even a small suggestion can influence the direction of the project.
π Final Thoughts
NexPro started with a simple question:
"Can I build a programming language myself?"
The answer so far is:
Yes β but building one teaches you how much there is to learn.
A programming language isn't just syntax.
It's a pipeline:
SOURCE CODE
β
βΌ
LEXER
β
βΌ
TOKENS
β
βΌ
PARSER
β
βΌ
AST
β
βΌ
INTERPRETER
β
βΌ
RUNTIME
β
βΌ
OUTPUT
And NexPro is my attempt to understand and build that pipeline from the ground up.
It's still early.
But that's what makes it exciting.
If you're interested in programming languages, I'd love for you to take a look at NexPro and tell me what you think.
Repository: https://github.com/probal2005/NexPro
Let's see how far this little language can go. π
Top comments (0)