Hey Y'all,
I've been writing a blog series on the fundamentals of computing, logic gates, binary, memory, that sort of thing, and every post had circuit diagrams in it. For a long time these were static SVGs I drew by hand, then a TypeScript renderer I kept hacking on, but neither could simulate anything. The drawings were just drawings.
Trying to fix this problem, I wrote a language called circ that lets you describe digital circuits and compiles them to WebAssembly modules that run in the browser. Right now it lives scattered across the series, every interactive circuit you see in those posts is a .circ file.
It's a small language. There are only six primitives (input, output, and, not, wire, led), and the familiar gates you'd expect to be built in (or, nand, xor, nor, xnor) are themselves written in .circ and live inside the compiler as embedded files. The standard library is just more of the language, which makes me very happy.
The compiler is written in Zig and uses langlang for the PEG parser. At build time the simulation runtime is compiled to wasm32-freestanding and embedded into the CLI, and when you compile a circuit the resolved topology gets serialized into a custom WASM section and spliced onto that prebuilt blob. Each compiled circuit ends up as a single self-contained .wasm file, no toolchain required to run it. From the same .circ file you can also get an ASCII schematic via --preview and a truth table via --truth-table in Markdown, CSV, or JSON.
I just published a letter introducing the language: link to blog. The language has a site with the full reference at circ-lang.org, and the source is on GitHub: link to repo.
I'd love any feedback you have, especially on the surface syntax. I've been the only user for a while now, and I'm sure there are sharp edges I've stopped being able to see.
Thanks for reading 😊
Top comments (0)