From pressing Run to receiving output
Blan is a small interpreted language written in C++17, connected to a Go
execution service and a Next.js playground. A hand-written lexer and
recursive-descent parser build an AST, and a tree-walking evaluator runs it.
The language has variables, numbers, strings, booleans, arithmetic,
comparisons, short-circuit and/or, if / else-if / else, while loops, and
printing. It has no functions yet.
The interesting part is the service around the interpreter: how a submitted program becomes a job, when a result can be reused, and how the browser gets it back.
Follow a cache miss
- The Go API (Gin) hashes the submitted source and checks StrataKV for stored output.
- On a miss, the job goes into a queue served by three worker goroutines.
- A worker writes the program to a temporary
.blfile and runs the interpreter with a three-second timeout. - Successful output is cached, and the browser polls the job status to get the result.
The queue holds up to 100 pending jobs. When it is full, new requests block until there is room. It does not reject overload.
Keep storage responsibilities separate
StrataKV stores execution results. SQLite (through GORM) stores accounts and saved snippets, which need a JWT. The backend switched from MySQL to SQLite in October 2026. It pins an older, pre-v2 StrataKV revision, so the recovery and batch features in the StrataKV notes are not part of this integration yet.
The playground has a Monaco editor with Blan syntax highlighting, file upload, locally saved drafts, and shows when a result came from the cache.
Current limits
Job state lives in memory and is lost when the backend restarts. Cache keys include the source but not the interpreter version, so changing the interpreter needs a way to invalidate old results. The timeout limits run time. It is not a sandbox: there are no per-job memory or CPU limits.
The compile endpoint needs no login and has no rate limiting yet. The backend is deployed on Railway, and I don't promise it is always up.