About Me
I have graduated with a Bachelor's degree in Computer Engineering from Assumption University around the end of 2024.
Projects
Golox: The Tree-Walk Interpreter
Feb 28, 2024One day, I woke up and had the idea of writing a programming language from scratch. To me, this has always been one of the darkest corners of computer science—a place where all the magic happens. I decided to gather my courage and search for a book on writing programming languages. That's when I came across Crafting Interpreters.
Minimal Sqlite in C
Feb 28, 2024A minimal clone of SQLite built in C, exploring B-Tree data structures and database internals.
Read More →Mini-projects
There are many insightful experiments that are too small to include in a résumé. This section highlights them.
Q-learning on a crawling robot
June, 2024

Q-learning is a reinforcement learning technique that learns through trial and error. I applied it to a crawling robot simulation to optimize its forward movement. I then adjusted the floor’s coefficient of friction and demonstrated that the robot adapted its strategy accordingly—lifting its body higher on high-friction surfaces to reduce contact and minimize resistance.
View code on GitHubMinimal Pratt Parser in Go
Mar 1, 2025While reading Chapter 17 of Crafting Interpreter , I realized I didn't fully understand the compiler concepts in the chapter. The author anticipated this and linked his article: Pratt Parsers: Parsing Made Easy .
AST representation of ((-x) - y) - (5 * y)
.
LOAD x NEGATE LOAD y SUBTRACT LOAD 5 LOAD y MULTIPLY SUBTRACT
Generated bytecode for ((-x) - y) - (5 * y)
.
Generic stack implementation in C
March, 2025We aim to implement a generic stack in C that can handle different data types. Unlike languages like C++ (which has templates) or Java (which has generics), C does not provide built-in generic containers. This means we must manually implement a generic-type stack. There are two common approaches:
Approach | Description | ✅ Pros | ❌ Cons |
---|---|---|---|
Approach 1: _Generic Macros |
Uses the _Generic keyword to select the correct function/type at compile time. |
|
|
Approach 2: void * Pointers |
Stores elements as raw memory, allowing different types to be stored dynamically. |
|
|
In this mini-project, we will go with approach 2, using void pointer. While this approach require runtime check so slightly inefficient. However, it is slightly more flexible and we could extend this to support dynamic stack.