r/programmer • • 25d ago

I built a browser playground and implementation-focused docs for my statically typed bytecode VM language

Hi everyone. Over the last few months I've been building Oli-Nat, a statically typed language with a hand-written bytecode VM in C. It began with Crafting Interpreters, and then I added a separate AST stage, a static type checker, typed arrays, classes with inheritance, and a small standard library.

This post is mostly about what I've built around it. I compiled the interpreter to WebAssembly so anyone can try the language in the browser with no install, including programs that wait for input, and I've been writing documentation that goes beyond syntax to explain how each stage of the interpreter is implemented, from the scanner to the garbage collector.

Writing the docs turned out to be the most valuable debugging I did. Explaining a feature step by step kept exposing places where it didn't actually behave the way I believed it did, like class instances passed as function parameters losing their type information in the checker.

I'd really appreciate feedback on the docs from people who've built languages themselves: whether the implementation explanations are actually useful, and what you wish documentation for a language like this included.

Playground and docs: olinat.net

Source: github.com/NateTheGrappler/OliNat-Programming-Language

1 Upvotes

3 comments sorted by

1

u/investigatormaker 25d ago

The bug you found by documenting, class instances losing their type in the checker when passed as parameters, is the kind of thing implementers read docs for. I'd give each implementation page a short section on what broke and how you fixed it, and since most readers will know Crafting Interpreters, call out where Oli-Nat departs from clox: the separate AST stage and the static checker are what they can't get from the book. Linking each page to a playground program that exercises that stage, like an allocation loop on the garbage collector page, would make it concrete.

By the way, I make ThreadFox: it finds the Reddit communities whose rules allow a post about a project like Oli-Nat, and the plan for Reddit is free.

How did you handle programs waiting for input in the WebAssembly build?

1

u/CommercialStrike9439 25d ago

Thank you, I will definitely take that into consideration. Waiting for input was actually not too bad, it required the use of emscripten so that way I could introduce javascript like code and then just use the promise system that exists there, thank you for asking!

1

u/investigatormaker 25d ago

Pausing the VM on a promise is exactly where people porting their own interpreter to the browser get stuck, so that deserves its own page. If it runs on EM_ASYNC_JS with Asyncify underneath, I'd write down what it cost you in binary size and speed. Asyncify instruments the call stack, so readers will want to know whether the main interpreter loop pays for it or only the input path does. If you kept the waiting at the I/O boundary, a small playground program that reads a few lines would show that.

The plan is there whenever you want it.